| name | deep-student-tauri-lab |
| description | Manage Deep Student Tauri desktop test instances through the repo-local tauri-lab CLI. Use when Codex needs to create, start, stop, restart, lease, inspect, or clean up one or many Deep Student Tauri app windows for Computer Use testing, parallel subagents, cloud sync simulations, or local E2E debugging. |
Deep Student Tauri Lab
Use this skill to operate the repo-local tauri-lab manager in the current Deep Student checkout.
Rules
- Treat
tauri-lab as the control plane. Do not launch Deep Student test instances with generic open -n.
- Use exact
computer-use app paths returned by tauri-lab; never target the generic Deep Student app name when multiple builds exist.
- Prefer pools and leases for parallel testing. One Codex agent should own one leased instance.
- For multi-agent cloud sync testing, create 10-15 instances for normal work and lease 2-3 instances per subagent. The local stress run on 2026-05-30 reached 64 simultaneous instances with metrics ready and Computer Use control still working, so 10-15 is a safe default on the current machine.
- The parent agent assigns leases. Subagents must not browse the global app list and pick windows themselves; they may only operate instance ids and exact
.app paths explicitly assigned to their owner.
- Before a subagent uses Computer Use, run
agent targets --owner ... or agent verify ...; if verification fails, do not touch the window.
- For long-running subagent tests, the parent must not impose an active timeout just because a subagent is quiet. Cloud sync and real UI flows can legitimately run for about an hour. The parent should sleep or poll passively, give subagents enough time to finish, and only investigate when the user asks, the subagent reports failure, the process exits, or objective evidence shows the assigned app/fixture is gone.
- Use
--wait --metrics before driving UI so the app has finished Tauri/backend startup.
- Stop test instances before finishing unless the user asks to keep them running.
- Read backend, stderr, frontend, and daemon logs before guessing why an instance failed.
- Use
evidence snapshot after meaningful UI actions or failures so another Codex window can resume with logs, slot state, SQLite summaries, metrics, and credential presence.
- Use built-in assertions for post-UI checks instead of hand-rolled shell commands when they cover the case.
- After editing
dstu-test/scripts/tauri-lab.mjs, restart the daemon before trusting new behavior: npm run tauri-lab -- service restart --json. The daemon runs detached and otherwise keeps the old script in memory.
- Prefer the default short display names generated by
tauri-lab for Deep Student instances. Long display names can be truncated in macOS window metadata and cause Computer Use cgWindowNotFound; pass --display-name only when a scenario explicitly needs it.
Quick Start
cd <deep-student-repo>
npm run tauri-lab -- service start --json
npm run tauri-lab -- service status --json
npm run tauri-lab -- project register deep-student \
--cwd "$PWD" \
--source-app "src-tauri/target/debug/bundle/macos/Deep Student.app" \
--json
If the service was already running before a tauri-lab.mjs edit, restart it:
npm run tauri-lab -- service restart --json
Create a pool for parallel agents:
npm run tauri-lab -- pool create deep-student codex-sync --count 12 --json
npm run tauri-lab -- pool start codex-sync --concurrency 4 --wait --metrics --timeout 45 --json
For five parallel cloud-sync subagents, use 15 instances so each agent can own up to three devices:
npm run tauri-lab -- pool create deep-student codex-sync-15 --count 15 --json
npm run tauri-lab -- pool start codex-sync-15 --concurrency 4 --wait --metrics --timeout 90 --json
When test data should be preloaded, create or apply a data image before starting instances:
npm run tauri-lab -- image create lh-shell-seed \
--from-instance learning-apps-05-05 \
--scope home \
--description "Learning Hub folder/note seed" \
--json
npm run tauri-lab -- instance create deep-student lh-smoke-01 \
--id lh-smoke-01 \
--image lh-shell-seed \
--json
npm run tauri-lab -- pool create deep-student lh-lifecycle-05 \
--count 5 \
--image lh-shell-seed \
--json
Claim one instance for the current agent:
npm run tauri-lab -- agent checkout codex-sync \
--owner codex-agent-sync-1 \
--purpose "cloud sync regression" \
--ttl 7200 \
--start --wait --metrics \
--json
Pass the returned target.app path to Computer Use.
When an agent needs multiple devices, call agent checkout once per device using the same --owner and a purpose that names the role, such as writer, reader, or restore-target. Share only the instance ids, app paths, metrics addresses, and WebDAV fixture id with the subagent; do not share another agent's leased windows.
Before spawning subagents, save or paste an assignment table with:
- owner
- scenario
- leased instance ids
- exact Computer Use app paths
- WebDAV root/prefix
Ask each subagent to echo its assignment before operating. If a subagent sees an app path not in its assignment, it must ignore it.
Each subagent should verify its own assignment before the first Computer Use call:
npm run tauri-lab -- agent targets --owner codex-agent-sync-1 --json
npm run tauri-lab -- agent verify codex-sync-01 \
--owner codex-agent-sync-1 \
--app "<exact target.app path returned by tauri-lab>" \
--require-running \
--json
Use agent targets instead of computer-use list when a subagent needs to rediscover its own windows after context compaction.
Long-running parent coordination rule:
- Spawn subagents with exact assignments and enough detail to operate independently.
- After spawning, the parent may run lightweight passive checks such as
lease audit, pool status, and fixture status, but must not kill or close subagents for slow progress.
- A quiet subagent is not a stuck subagent. Treat long cloud-sync scenarios as normal until completion, explicit failure, user interruption, or hard external evidence such as a missing process, stopped fixture, or failed lease verification.
- If status is needed, ask the subagent for a progress update or inspect evidence/logs without touching its assigned windows.
For daemon persistence across future logins, install the macOS LaunchAgent when needed:
npm run tauri-lab -- service install --json
npm run tauri-lab -- service install --start --json
If a detached daemon is already running, install --start leaves it alone and installs the agent for future sessions.
Inspection
List app targets:
npm run tauri-lab -- computer-use list --json
npm run tauri-lab -- computer-use target codex-sync-01 --json
Read logs:
npm run tauri-lab -- logs codex-sync-01 --kind backend --tail 200
npm run tauri-lab -- logs codex-sync-01 --kind stderr --tail 200
npm run tauri-lab -- logs codex-sync-01 --kind frontend --tail 200
npm run tauri-lab -- logs daemon --kind daemon --tail 200
List reusable data images:
npm run tauri-lab -- image list --json
npm run tauri-lab -- image inspect lh-shell-seed --json
Capture a resumable evidence bundle:
npm run tauri-lab -- evidence snapshot codex-sync-01 --tail 300 --json
The returned path contains:
- instance status and Computer Use target
- backend/stderr/frontend log tails
- metrics text when reachable
- slot state
- SQLite table/count summary
- cloud credential file presence
Assertions
Use assertions only after a real UI action has been performed through Computer Use:
npm run tauri-lab -- assert slot codex-sync-01 --active slotA --pending null --json
npm run tauri-lab -- assert credential codex-sync-01 --cloud-storage present --json
npm run tauri-lab -- assert sqlite codex-sync-01 \
--slot active \
--db chat_v2 \
--query "select count(*) from chat_v2_sessions;" \
--equals 6 \
--json
Treat nonzero assertion exit codes as product or test-state failures until logs prove otherwise.
WebDAV Fixture
Start local cloud storage when Docker Desktop is running:
npm run tauri-lab -- fixture webdav start sync-webdav \
--username ds-test \
--password ds-pass \
--root deep-student-e2e \
--json
Use endpoint, username, and root from status; get the password only with the explicit credentials command:
npm run tauri-lab -- fixture webdav status sync-webdav --json
npm run tauri-lab -- fixture webdav credentials sync-webdav --json
npm run tauri-lab -- fixture webdav tree sync-webdav --json
npm run tauri-lab -- assert webdav-tree sync-webdav --contains "data_governance/manifests/e2e-device-a.json" --json
If Docker is not running, the fixture command fails fast with a Docker daemon error; start Docker before retrying.
For high-concurrency cloud-sync matrices, snapshot fixture health at the start,
mid-run, and final aggregation:
npm run tauri-lab -- fixture webdav status sync-webdav --json
npm run tauri-lab -- fixture webdav tree sync-webdav --json
du -sh "$HOME/Library/Application Support/tauri-lab/fixtures/sync-webdav/webdav-root"
Do not let subagents stop or restart a shared fixture. If a fixture is found
stopped, record the status and evidence first; restart only when the parent has
made fixture restart part of the test plan.
Data Images
Use data images to avoid rebuilding test state through the UI on every run. A home image copies the instance HOME, including app data, first-run state, local WebKit state, and test configuration. An app-data image copies only Library/Application Support/com.deepstudent.app and is smaller, but may not preserve first-run UI state.
Create images from stopped instances by default. Use --live only for quick smoke seeds where a potentially mid-write SQLite snapshot is acceptable.
npm run tauri-lab -- image create sync-configured-a \
--from-instance sync-e2e-15-01 \
--scope home \
--description "WebDAV configured upload device" \
--json
npm run tauri-lab -- image apply sync-configured-a \
--to-instance sync-e2e-15-02 \
--force \
--json
When applying a home image to a different bundle id, tauri-lab rewrites bundle-id-scoped HOME directory names so copied WebKit state can follow the target app bundle. Apply images only to stopped instances; start with --wait --metrics afterward.
Recommended image families:
lh-empty-accepted: agreement accepted, no resources.
lh-shell-seed: folders, notes, recent/search/tab data.
lh-doc-preview-seed: imported markdown/text/csv/pdf/doc fixtures.
lh-exam-one-question: one synthetic question ready for practice lifecycle.
sync-webdav-configured: cloud sync settings and credentials ready for sync tests.
Check pool health:
npm run tauri-lab -- pool status codex-sync --json
npm run tauri-lab -- instance list --json
npm run tauri-lab -- lease list --json
npm run tauri-lab -- lease audit --json
Use lease audit --json as the parent coordination check and agent verify ... --owner ... --app ... as the subagent preflight check. Before a subagent starts UI actions, verify its assigned instance ids are leased to its owner. After it finishes, verify no two active leases point to the same app target and no subagent reports using an unassigned app path.
For high-concurrency health checks, prefer summarized JSON instead of pasting every instance into the thread:
npm run tauri-lab -- computer-use list --json
ps -axo pid,rss,pcpu,command | rg '/tauri-lab/apps/.*Contents/MacOS/deep-student'
Cleanup
Stop fixtures separately from app instances:
npm run tauri-lab -- fixture webdav stop sync-webdav --json
Release a leased instance:
npm run tauri-lab -- agent release codex-sync-01 --owner codex-agent-sync-1 --json
npm run tauri-lab -- lease clear --pool codex-sync --json
Stop one pool or everything:
npm run tauri-lab -- pool stop codex-sync --concurrency 4 --json
npm run tauri-lab -- instance stop-all --json
npm run tauri-lab -- service stop --with-instances --json
After a large pool run, confirm cleanup:
ps -axo pid,ppid,command | rg 'tauri-lab|dstu-stress|codex-sync'
Only the inspection command itself should remain.
Failure Handling
- If
pool start reports a wait failure, immediately read --kind stderr, --kind backend, and --kind frontend for that instance.
- If a UI action fails, run
evidence snapshot before restart or cleanup.
- If a process is alive but registry says stopped, suspect a registry race or stale pid; use
ps/lsof, stop with service stop --with-instances, then kill only the specific leftover test pids if necessary.
- If Computer Use opens the wrong app, compare
computer-use target path and bundle id against get_app_state.
- If startup is slow, rerun with lower
--concurrency and a higher --timeout.
- If Computer Use slows under many windows, reduce active testing to 10-15 leased instances; keep larger pools for capacity smoke tests, not detailed UI workflows.
Scale Notes
Observed on 2026-05-30 in the local Deep Student checkout:
- 16, 20, 24, 32, 40, 48, 56, and 64 simultaneous instances started successfully.
- Every added instance reached metrics ready with conservative
--concurrency 2.
- Computer Use could target and click the last instance at 64 using the exact
.app path.
- 64 instances showed no swap I/O and near-idle CPU in the sampled state.
Use this as a capacity lower bound, not a guarantee for every machine. For real cloud sync coverage, prefer 5 subagents x 2-3 devices instead of one huge manual run.
References
Read references/commands.md for command recipes and JSON fields.