Skip to content

[Feature]: Create worktrees outside the repository tree to avoid duplicate CLAUDE.md discovery #213

@forketyfork

Description

@forketyfork

Status Quo

Worktrees are created at <repo-root>/.architect/<name> via buildCreateWorktreeCommand() in src/app/worktree.zig. This nests worktrees inside the repository directory tree. When an agent (e.g., Claude Code) runs in a worktree and walks up the directory tree to discover project configuration, it finds the root repository's CLAUDE.md in addition to the worktree's own copy, resulting in duplicate instructions.

There is currently no configuration option for the worktree location. The .architect/ path is hardcoded in worktree.zig (lines 46-48) and runtime.zig (line 1761). Discovery of existing worktrees uses collectFromGitMetadata() in worktree_overlay.zig, which reads from git's internal worktree tracking — this is already location-agnostic.

Additionally, new worktrees lack project-local state that is typically gitignored: .env, .envrc.local, tool trust files, etc. Users must manually copy these files and run setup commands (e.g., direnv allow) in every new worktree. There is no post-creation initialization mechanism.

Objectives

Agents running in worktrees should not encounter the parent repository's configuration files. By creating worktrees outside the repo directory tree, the upward directory walk stops before reaching the root repo, eliminating duplicate CLAUDE.md (or similar) discovery. The location should be configurable, with a sensible default that works without user intervention.

New worktrees should also be bootstrapped automatically — running project setup scripts to install dependencies, copy local config files, or approve tools like direnv — so they are ready to use immediately after creation.

User Flow

Trigger: User presses Cmd+0 in the worktree overlay and enters a worktree name.

  1. Architect resolves the worktree target directory from configuration (default: ~/.architect-worktrees/<repo-name>/<worktree-name>).
  2. git worktree add <target> -b <name> runs, creating the worktree outside the repo tree.
  3. The shell cds into the new worktree directory.
  4. If init_command is configured, it runs. Otherwise, if a well-known init script exists in the new worktree (script/setup or .architect-init.sh), it runs automatically.
  5. Existing worktrees (including legacy ones under .architect/) continue to appear in the Cmd+T dropdown via git metadata discovery.

Result: New worktrees are filesystem-independent from the parent repo, fully bootstrapped, and ready for use. Agents running in them see only the worktree's own project files when traversing upward.

Scope

In scope:

  • New [worktree] section in config.toml with directory and init_command options
  • Default worktree path: ~/.architect-worktrees/<repo-name>/<worktree-name>
  • Post-creation init: run configured init_command, or auto-detect script/setup / .architect-init.sh
  • Update buildCreateWorktreeCommand() to use an absolute target path and append the init command
  • Update runtime.zig CreateWorktree handler to compute the correct new_path
  • Backwards compatibility: existing worktrees under .architect/ remain visible and switchable

Out of scope:

  • Migrating existing .architect/ worktrees to the new location
  • Changing worktree discovery logic (already location-agnostic via git metadata)
  • Changing worktree removal logic (already uses absolute paths)
  • Changes to .architect/diff_comments.json or other .architect/ state storage
  • Symlink management for individual files (users can handle this in their init script)

Implementation Plan

Affected Modules

  • src/config.zig: Add WorktreeConfig struct with directory and init_command fields
  • src/app/worktree.zig: Update buildCreateWorktreeCommand() to accept an absolute target path and append init command logic
  • src/app/runtime.zig: Resolve the worktree target directory and init command from config when handling CreateWorktree, pass them to the build function, and compute the correct new_path
  • src/ui/types.zig: Extend CreateWorktreeAction to carry the resolved target path
  • docs/configuration.md: Document the new [worktree] section

Tasks

  1. Add WorktreeConfig struct to src/config.zig with directory: ?[]const u8 = null and init_command: ?[]const u8 = null; wire it into Configsrc/config.zig
  2. Add a helper that resolves the effective worktree base directory: if config.worktree.directory is set, use it (expanding ~); otherwise derive ~/.architect-worktrees/<repo-name>/ from the repo root — src/app/worktree.zig
  3. Update buildCreateWorktreeCommand() to accept a full absolute target path instead of constructing .architect/<name>src/app/worktree.zig
  4. Add init command logic to buildCreateWorktreeCommand(): if init_command is provided, append && <init_command>; otherwise append a shell snippet that runs script/setup or .architect-init.sh if either exists — src/app/worktree.zig
  5. Update CreateWorktree handler in runtime.zig to resolve the target directory and init command from config, pass them to the command builder, and compute new_path correctly — src/app/runtime.zig
  6. Add [worktree] section to the default config template comment — src/config.zig
  7. Update docs/configuration.md with the new [worktree] section
  8. Update docs/ARCHITECTURE.md if the worktree creation flow description changes
  9. Update README.md to mention configurable worktree location and init scripts

New Dependencies

None

Acceptance Criteria

  • New worktrees are created at ~/.architect-worktrees/<repo-name>/<worktree-name> by default
  • Setting [worktree] directory = "/custom/path" overrides the base location
  • Setting [worktree] init_command = "script/setup" runs that command after worktree creation
  • When no init_command is configured, script/setup or .architect-init.sh runs automatically if present in the new worktree
  • Existing worktrees under .architect/ still appear in the dropdown and can be switched to / removed
  • zig build and zig build test pass
  • just lint passes
  • Documentation updated

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions