Worktrees
View SourceFnord supports git worktrees for isolating file changes during edit-mode conversations. Each conversation can be bound to its own worktree so edits happen on a separate branch without touching the main working tree.
How it works
In edit mode (--edit) on a git repository, fnord enforces worktree usage.
The coordinator is instructed to create a worktree before making any file changes, and file edit tools refuse to write without one.
All edits happen on an isolated branch — your working tree is never modified directly.
For non-git projects, edits are applied directly to the source files.
At the end of the session, you decide what to do with the changes: inspect the diff, merge into your current branch, or leave them in the worktree for later.
With --yes, fnord-managed worktrees skip the interactive review and attempt the same merge-and-cleanup flow automatically.
The worktree is associated with the conversation and persisted in conversation metadata, so resuming the conversation (--follow) reuses the same worktree.
File paths in UI output (tool notes, edit approval dialogs) are displayed relative to the source root, with the branch name shown in parentheses on edit approvals.
The --worktree flag
fnord ask -q "refactor the config module" --edit --worktree /path/to/existing/worktree
--worktree / -W PATH overrides the project source root for the current run.
PATH must be an existing directory - this flag does not create worktrees.
If the conversation already has a worktree association (from a prior run), --worktree is rejected to prevent conflicting state.
Conversation-bound worktrees
When the AI creates a worktree via the coordinator tool:
- A new git worktree is created under
~/.fnord/projects/<project>/worktrees/<conversation-id>/ - The worktree metadata (path, branch, base branch) is persisted to the conversation
- The project root override is set for the session
- All subsequent file operations target the worktree
On resume (--follow), fnord:
- Detects the stored worktree association
- Verifies the worktree directory still exists
- Recreates it from the stored metadata if it was deleted
- Sets the project root override automatically
Initializing fresh worktrees
Many projects need a one-time setup step before tooling works in a fresh worktree (fetching dependencies, building artifacts, etc.). Fnord doesn't run any language-specific commands itself, but git's post-checkout hook runs automatically when git worktree add creates a new working tree, which is exactly the moment fnord creates a worktree.
The cleanest way to wire this up is to check a post-checkout hook into the repository under a versioned hooks directory, then point git at it:
mkdir -p .githooks
cat > .githooks/post-checkout <<'EOF'
#!/bin/sh
# Runs after `git checkout` and `git worktree add`. Add any project-specific
# setup commands here (fetch dependencies, build initial artifacts, etc.).
EOF
chmod +x .githooks/post-checkout
git config core.hooksPath .githooks
The hook receives three arguments: previous HEAD, new HEAD, and a flag (1 for branch checkout, 0 for file checkout). Use $3 = 1 to limit setup to branch/worktree checkouts.
Each contributor only needs to run git config core.hooksPath .githooks once after cloning. From then on, every git worktree add (including the ones fnord creates) runs the hook automatically.
Committing changes
The coordinator is nudged to commit its worktree changes at two points:
- Inline with validation: after each code-modifying tool use, if uncommitted changes exist, a system message reminds the AI to commit via the
git_worktree_toolcommit action. - Dedicated step: a
:commit_worktreestep runs after task checking, before finalization. It loops up to 3 times if changes remain uncommitted.
The AI can commit normally or use wip: true for incomplete work, which prefixes the message with WIP:.
As a last resort, maybe_auto_commit in the ask command commits any remaining changes after the coordinator finishes.
Post-session review
After the coordinator finishes in a fnord-managed worktree, the user is prompted to:
- Inspect changes: view the diff between the worktree branch and its base
- Merge: merge the branch into whatever is checked out in the actual project root
- Clean up: delete the worktree directory and local branch
With --yes, the post-session review is skipped and fnord attempts the same merge-and-cleanup flow automatically.
Forking conversations with worktrees
When forking a conversation (--fork / -F) that has an associated worktree, the user is prompted:
- Reuse existing worktree (default): the forked conversation shares the original worktree
- Create new worktree: worktree metadata is stripped; the coordinator will create a fresh one
- No worktree: worktree metadata is stripped; no worktree is created
In non-interactive mode, the default (reuse) is applied.
CLI management
The fnord worktrees command provides direct management:
fnord worktrees list
fnord worktrees create --conversation <uuid>
fnord worktrees create --conversation <uuid> --branch feature-name
fnord worktrees view --conversation <uuid>
fnord worktrees delete --conversation <uuid>
fnord worktrees merge --conversation <uuid>
list
Lists fnord-managed worktrees in a formatted table with columns: Conversation, Branch, Status, Dirty, Size, Path.
Only worktrees under the default fnord-managed path are shown (not user-created external worktrees).
create
Creates a new conversation-scoped worktree.
--conversation / -c UUID- conversation id (required)--branch / -b NAME- branch name (optional, auto-generated if omitted)
view
Prints a colorized diff of a conversation's worktree against its fork point.
--conversation / -c UUID- conversation id (required)
Useful for reviewing changes before running merge or delete, without leaving the shell.
delete
Removes a conversation's worktree. Checks for uncommitted and unmerged changes before deleting.
--conversation / -c UUID- conversation id (required)
If the worktree has uncommitted changes, prompts for confirmation before force-deleting. If the worktree branch has unmerged commits, warns and prompts before proceeding. On deletion, worktree metadata is stripped from the conversation so follow-up runs no longer treat the conversation as bound to the removed worktree.
merge
Interactive review, merge, and cleanup of a conversation's worktree.
--conversation / -c UUID- conversation id (required)
Walks through the same inspect/merge/cleanup flow as the post-session review.
Conversation deletion
When deleting conversations (fnord conversations --prune), fnord checks each conversation for an associated worktree. If one exists on disk, the user is prompted about cleanup with status information (dirty/unmerged/clean).
Design notes
-Wis strictly an existing-directory override, never a creation hint- One worktree per conversation - the coordinator enforces this
- Worktree recreation preserves the originally stored path
- The worktree tool is only available in edit mode on git repositories
- The
git_worktree_toolcreate action derives project and conversation from the active session; only branch is user-specified - The
git_worktree_toolcommit action only works in fnord-managed worktrees