{"id":51149890,"url":"https://github.com/codethread/wktree","last_synced_at":"2026-06-26T05:04:15.643Z","repository":{"id":365998481,"uuid":"1272585708","full_name":"codethread/wktree","owner":"codethread","description":"cli to handle git worktrees","archived":false,"fork":false,"pushed_at":"2026-06-19T19:10:36.000Z","size":113,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T21:11:30.188Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codethread.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-17T18:51:20.000Z","updated_at":"2026-06-19T19:10:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/codethread/wktree","commit_stats":null,"previous_names":["codethread/wktree"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/codethread/wktree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codethread%2Fwktree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codethread%2Fwktree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codethread%2Fwktree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codethread%2Fwktree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codethread","download_url":"https://codeload.github.com/codethread/wktree/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codethread%2Fwktree/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34803680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-26T05:04:11.621Z","updated_at":"2026-06-26T05:04:15.622Z","avatar_url":"https://github.com/codethread.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wktree\n\n`wktree` is a deterministic git worktree manager. It creates, finds, prepares, finishes, and removes worktrees using one consistent contract for humans, shell/tmux wrappers, scripts, and agents.\n\nIt is useful when you want predictable worktree paths, safe cleanup, JSON output, optional fixed worktree pools, and repeatable setup for local files such as `.env`.\n\n## Install\n\nRequirements: git and Bun.\n\n### Homebrew\n\nTap this repository directly, then install the latest tagged release:\n\n```bash\nbrew tap codethread/wktree https://github.com/codethread/wktree\nbrew install codethread/wktree/wktree\n```\n\nOr as one shell command:\n\n```bash\nbrew tap codethread/wktree https://github.com/codethread/wktree \u0026\u0026 brew install codethread/wktree/wktree\n```\n\nThis installs a small `wktree` launcher that runs the tagged TypeScript CLI with Homebrew's Bun. Because the CLI is installed from source instead of distributed as a downloaded macOS executable, it avoids Developer ID signing/notarization friction.\n\nTo upgrade to the newest tagged release after the formula is updated:\n\n```bash\nbrew update\nbrew upgrade wktree\n```\n\n### Build from source\n\n```bash\nmake\n```\n\n`make` runs `bun install` and `bun run build`. The build writes:\n\n```text\n~/.local/bin/wktree\n```\n\nMake sure `~/.local/bin` is on your `PATH`.\n\nAfter installing, use the built-in help for the full command reference:\n\n```bash\nwktree --help\nwktree add --help\nwktree config explain --help\n```\n\n## How it works\n\n`wktree` resolves one checkout as the **canonical root** for a repository. That root is protected and anchors config lookup, default-branch policy, generated paths, and safety checks.\n\nNormal worktrees are created beside the root:\n\n```text\n\u003ccanonical-root\u003e__\u003cbranch-name-with-/encoded-as--\u003e\n```\n\nPooled repositories reuse fixed slots instead:\n\n```text\n\u003ccanonical-root\u003e__feat1\n\u003ccanonical-root\u003e__feat2\n...\n```\n\nThere is no app database. Current state comes from git worktree metadata, filesystem paths, and config. Tmux integration consumes emitted path/session data; it is not the source of truth.\n\n## Basic use\n\nFrom any path inside a repository worktree set:\n\n```bash\nwktree root\nwktree add --branch feature/example\nwktree list\nwktree path --branch feature/example\nwktree remove --branch feature/example\n```\n\nFor scripts and agents, prefer JSON where available and branch on the payload `kind`:\n\n```bash\nwktree add --branch feature/example --json\nwktree list --json\nwktree finish --json\n```\n\nIf `add --json` returns `post_create_script_path`, run that script with bash before treating the worktree as ready.\n\nUse this to see what config applies to the current repository:\n\n```bash\nwktree config explain --json\n```\n\n## Config\n\nConfig is optional. Without it, `wktree` still creates deterministic sibling worktrees.\n\nConfig is read from:\n\n```text\n${XDG_CONFIG_HOME:-~/.config}/ct-worktrees/trees.toml\n```\n\nResolution order:\n\n1. built-in defaults;\n2. matching `[[rule]]` entries in file order;\n3. exact `[[project]]` entry for the canonical root.\n\nLater layers override earlier ones.\n\n### Schema\n\n```toml\n[defaults.add]\npolicy = \"origin_default\" # \"origin_default\" | \"fresh_canonical\"\n\n[defaults.finish]\nenabled = true\nstrategy = \"ff_only\"      # \"ff_only\" | \"rebase_ff\" | \"squash\" | \"merge_commit\"\npush = false\nremove_worktree = false\ndelete_branch = false\n\n[[rule]]\nroot_glob = \"~/dev/projects/**\"   # required for rules; leading ~/ supported\ncommand = \"bun install\"           # optional bash snippet\npre_remote_check = \"test -f .env\" # optional bash snippet\n\n[rule.add]\npolicy = \"fresh_canonical\"\n\n[rule.finish]\nenabled = true\nstrategy = \"squash\"\npush = true\nremove_worktree = true\ndelete_branch = true\n\n[[project]]\nroot = \"~/dev/projects/example\"   # required for projects\nname = \"example\"                  # optional; defaults to basename(root)\ncommand = \"bun install\"           # required for pools/copy unless inherited from a rule\npre_remote_check = \"test -f .env\" # optional\npool_size = 3                      # optional; enables fixed slots\ncopy_mode_default = \"copy\"        # optional: \"copy\" | \"symlink\"; default \"copy\"\ncopy = [                           # optional\n  \".env\",\n  { from = \"~/shared/tooling\", to = \".tooling\", mode = \"symlink\" },\n  { from = \".claude\", to = [\".claude\", \".pi/claude\"], mode = \"copy\" },\n]\n\n[project.add]\npolicy = \"origin_default\"\n\n[project.finish]\nenabled = true\nstrategy = \"ff_only\"\npush = false\nremove_worktree = false\ndelete_branch = false\n```\n\nNotes:\n\n- `command` and `pre_remote_check` run under bash.\n- `command` receives `WK_ROOT` and `WK_CREATED`.\n- `origin_default` starts default-base work from `origin/\u003cdefault\u003e` without mutating the canonical root.\n- `fresh_canonical` fetches, requires a clean canonical root on the default branch, fast-forwards it, then starts work from that fresh local branch.\n- `copy` destinations are always worktree-relative. String entries copy from the canonical root to the same relative path.\n- `delete_branch = true` requires `remove_worktree = true` in the same effective finish policy.\n\n## Examples\n\n### Personal defaults\n\n```toml\n[defaults.add]\npolicy = \"origin_default\"\n\n[[rule]]\nroot_glob = \"~/dev/projects/**\"\ncommand = '''\nif [[ -f bun.lock ]]; then\n  bun install\nelif [[ -f package-lock.json ]]; then\n  npm install\nelse\n  echo \"wktree: no known install step\"\nfi\n'''\n```\n\n### Strict work repos\n\n```toml\n[[rule]]\nroot_glob = \"~/work/**\"\npre_remote_check = \"test -f .envrc || { echo 'missing .envrc' \u003e\u00262; exit 1; }\"\n\n[rule.add]\npolicy = \"fresh_canonical\"\n```\n\n### Expensive repo with a pool\n\n```toml\n[[project]]\nname = \"big-app\"\nroot = \"~/dev/projects/big-app\"\npool_size = 4\ncommand = \"bun install\"\ncopy = [\".env\"]\n```\n\n```bash\nwktree ensure --cwd ~/dev/projects/big-app\nwktree status --cwd ~/dev/projects/big-app\n```\n\n### Finish and clean up\n\n```toml\n[[project]]\nname = \"library\"\nroot = \"~/dev/projects/library\"\n\n[project.finish]\nstrategy = \"squash\"\npush = true\nremove_worktree = true\ndelete_branch = true\n```\n\nFrom a non-canonical worktree:\n\n```bash\nwktree finish --json\n```\n\n## Nushell wrapper\n\nThe TypeScript CLI is the source of truth. `nu/wktree/` provides human-friendly `wk` commands and tmux switching around the same engine.\n\n## Development\n\n```bash\nbun test tests\nbun run typecheck\nbun run check\n```\n\nThe durable design contract lives in [`devflow/specs/git-worktrees.md`](./devflow/specs/git-worktrees.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodethread%2Fwktree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodethread%2Fwktree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodethread%2Fwktree/lists"}