Path Access
Workflow code can read the same resolved absolute worktree path that Smithers uses for task execution:ctx.worktreePath(taskOrWorktreeId) when a task descriptor or explicit <Worktree id>
has rendered. Use ctx.resolveWorktreePath(pathProp) for the same string passed to
<Worktree path={...}>, including on the first render before descriptor lookups exist.
Both APIs use the graph resolver, so they match the path Smithers gives worker tasks.
Notes
- Descendants inherit
worktreeIdand absoluteworktreePathascwd. - Do not pin a
cwdon an agent used inside a<Worktree>. A worker agent’s working directory resolves asagent.cwd ?? worktreePath ?? repoRoot, so an explicitcwd(e.g.new ClaudeCodeAgent({ cwd: process.cwd() })) OVERRIDES the worktree, so the agent then reads and writes the repo root instead of the isolated worktree. Its branch stays empty and a downstream merge/land step has nothing to merge. Leave agentcwdunset and let<Worktree>supply it. Likewise, helpers that touch a worktree’s files must usectx.worktreePath(...)orctx.resolveWorktreePath(...); never reconstruct paths withprocess.cwd(),import.meta.dir,../.., or fallback candidate lists. - jj-backed worktrees include colocated git metadata, so git-native CLI agents such as Codex
resolve the worktree directory as their repository root. Do not compensate by setting an
agent
cwd; that defeats the worktree isolation above. - jj continuously snapshots a worktree’s working copy onto its bookmark. A compute
<Task>(or helper) that detects changes withgit status --porcelaincan see a clean tree and skip its work, because jj has already committed the working-copy edits to the bookmark, andgit checkoutorgit restoreof a file in the worktree won’t stick for the same reason (jj re-materializes it). Detect a worktree’s changes by diffing against its base branch (jj diff --from <baseBranch> --to @, orgit diff <baseBranch>...HEAD), not by git’s dirty-state, and let the merge/land step operate on the committed bookmark rather than re-runninggit add/git commit. - Innermost
<Worktree>wins when nested; duplicate ids are rejected. - Empty/whitespace
pathis rejected at render time. - A relative
pathresolves against the launch root, not the workflow file’s directory. The launch root is--root(if given), else the nearest ancestor of the operator working directory that contains a.smithers/package, else the operator working directory. It is neverdirname(workflowFile);workflowPathis threaded through render separately and is not used as the path base. A relativepathlikewt-alands beside wherever you ranbunx smithers-orchestrator up <path>from, which can differ from where the workflow source lives. Smithers emits a one-time warning for relative worktree paths showing the base and resolved absolute path. Pass an absolutepath(for example/tmp/smithers/wt-a) when you need a deterministic location, and read back the resolved location withctx.worktreePath(...)orctx.resolveWorktreePath(...)rather than reconstructing it.