Concepts
Understanding how ws works under the hood.
Git Worktrees
A git worktree is a linked copy of your repository that shares the same .git directory but has its own working tree and branch. This means multiple worktrees can exist simultaneously without interfering with each other.
ws uses worktrees to give each AI agent its own isolated workspace:
your-repo/ # Your main working directory
.workstreams/trees/
add-tests/ # Worktree on branch ws/add-tests
dark-mode/ # Worktree on branch ws/dark-mode
fix-types/ # Worktree on branch ws/fix-typesEach worktree:
- Has its own branch (
ws/<name>) - Can be based on any ref (
base_branchin config) - Is fully isolated — changes in one don't affect others
- Shares git history with the main repo
Parallel Execution
When you run ws run, all workstreams execute simultaneously:
- Worktree creation is serialized (one at a time) to avoid git lock races
- Agent execution is fully parallel — all agents start as soon as their worktree is ready
- Each agent runs in its own process with its worktree as the working directory
wsusesPromise.allSettled()so one failure doesn't stop others
ws run
├─ create worktree: add-tests (serialized)
├─ create worktree: dark-mode (serialized)
├─ create worktree: fix-types (serialized)
│
├─ run agent: add-tests ──────────────────────► done ✓
├─ run agent: dark-mode ─────────────────► done ✓
└─ run agent: fix-types ────────────────────────────► done ✓State Management
ws tracks the state of every workstream across runs. State is persisted in two places:
.workstreams/state.json— main project state (run history, editor preference).workstreams/logs/<name>.log— per-workstream state markers appended to log files
Each workstream goes through a lifecycle:
ready → queued → running → success / failed| Status | Meaning |
|---|---|
ready | Has a prompt, hasn't been run yet |
queued | Scheduled to run in the current batch |
running | Agent is actively working |
success | Agent completed without errors |
failed | Agent exited with an error |
workspace | No prompt — manual workspace only |
Session Capture
When using Claude as the agent, ws captures the session ID from Claude's stream-json output. This enables resuming the same Claude session later with new instructions — the agent retains full context of what it did before.
Review & Resume Loop
The core workflow is an iterative loop:
- Run — agents produce changes
- Review — browse diffs, add inline comments
- Resume — send comments back to the agent as instructions
- Repeat — until the code is right
- Merge — squash-merge the result
Comments and pending prompts are stored in .workstreams/comments/ and .workstreams/pending-prompts/. They're automatically included when resuming and cleared on success.
Branches
All workstream branches follow the naming convention ws/<name>:
ws/add-testsws/dark-modews/fix-types
On merge, changes are squash-merged into your current branch. The worktree and branch are cleaned up by default (use --no-cleanup to keep them).