{"_id":"@abhi-arya1/wt","_rev":"9-f2ebd56c60456a1ece4cb79a6bf05a38","name":"@abhi-arya1/wt","dist-tags":{"latest":"0.0.9"},"versions":{"0.0.1":{"name":"@abhi-arya1/wt","version":"0.0.1","_id":"@abhi-arya1/wt@0.0.1","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"c944a2b85e04a18472a1ca69997c6c7769f1ad06","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.1.tgz","fileCount":3,"integrity":"sha512-5uwuVRnOHSvTx3bzwXGwl4bgsiD77Q9DbmqNx+6Tj8HLruMwibMe/Z/GJBMsSbEUXw0BhyTD0XUHZXClhLvfag==","signatures":[{"sig":"MEQCIGHAIb4OmyAcJQiwY2Yr754BY4b8sDEbn07ljcPc1njOAiBoupfBVg8xQoj9JBspVhhkh0yu/x+PFk6ewh3gALxiMA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171074},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"a739b13385f7d2758f0b7464c939373500bd6645","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target node --outdir ./dist --banner '#!/usr/bin/env node' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.1_1770546467086_0.08003855823218275","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@abhi-arya1/wt","version":"0.0.2","_id":"@abhi-arya1/wt@0.0.2","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"5f631a0384e72c4dcbd254157f113a32e95979b3","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.2.tgz","fileCount":3,"integrity":"sha512-rWiTqs+fgXfd4U6m94qkTJSZ7y8hSq0154k2rcJIwQTp8nwSkXQXNrZaFpGUejfVr0pHFO3uc43S7qy7YsI8bA==","signatures":[{"sig":"MEUCIQDETlW3M0Wu4XwlTSP3+2WCbhXpLo+EYeJwUqd6EvPRvwIgMWXJaYtBpUHvfuE6Ke+xP5QA0TNWb6r2k+cMZ3qV6UQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171715},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"03090c200aee751c56f8846d37805eaa82d48765","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.2_1770546964354_0.8107743101434701","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@abhi-arya1/wt","version":"0.0.3","_id":"@abhi-arya1/wt@0.0.3","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"a7f4f61952f1f85ff7276a565d321f27e5d67a0d","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.3.tgz","fileCount":3,"integrity":"sha512-VbGPckUnu4doPvrufdvGoad268bgG24X2Ip50ERPz9QU7dMlEjMrQGqPYp6LPe0fh6wQKGX7oILXNU7OjNK2ZA==","signatures":[{"sig":"MEQCIF1vAMabjtOaaxjf0ygwO9zXj6dZd04nh4tWupeXidx7AiBh4GMjvrA7Z7GEsl//P9GsxE3yM0mjOPAI9u5xvguTBg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173307},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"d4e62ae3b041dd6a28b9a4b3fa74ce21c86d660f","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.3_1770547826015_0.37068206446833596","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@abhi-arya1/wt","version":"0.0.4","_id":"@abhi-arya1/wt@0.0.4","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"d1e85573bc004ce1c10f59bc293285e7b68c3fce","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.4.tgz","fileCount":3,"integrity":"sha512-ELLL+8K2rnkPFs6EcUEJnAeYAjSYBfyKLFLoQpX+wEFdVfh+s6BwuRvRDVUeX7Qfh0uzWNaMnUA3+P1TMpUmEw==","signatures":[{"sig":"MEUCIQDNsvXQ1djzL+riVVlpMrgmB03zKExFV92WWDp857jMXQIgaSgvjg+yn5R1/U/dwLp+3KUMrah0yITFHzHfZTEmXuU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173307},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"c3a098d91b1541d2655bdb179771e839c6b03a14","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.4_1770547887082_0.7519425247950613","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@abhi-arya1/wt","version":"0.0.5","_id":"@abhi-arya1/wt@0.0.5","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"47943ebeb59cf3d41cf9ea3af8b78c432c6a4c9a","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.5.tgz","fileCount":3,"integrity":"sha512-mNsjV65ZccYz2HJlHLjCPqtg3081fv4/WcgSlhQqV3A8BGWzrtHSz+dRic07lAIyY+bgvU7/8Z91wJnfS1KafQ==","signatures":[{"sig":"MEYCIQDXLWIR9cJQp/dpoZSY7syQQ3dbVf0h1Hf7h6Qqz3K64AIhAMkhousdSn2wV/Ws87wPNuNjB7Ncm1hG/rmEdDDhsHRD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":176790},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"e8220daa8092151cc230ec98070c722242ac5e4a","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.5_1770550341541_0.21173702184911014","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@abhi-arya1/wt","version":"0.0.6","_id":"@abhi-arya1/wt@0.0.6","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"9269e3d78c548442df6c3559c3a4cad51bba3437","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.6.tgz","fileCount":4,"integrity":"sha512-r2saYtRAyF9F90d23z5ysuHO7SKuUAX/PL6Znjyx8Q1NA9uw4rsrEpxo1cZPJEEbLhEEXC2bJ+urEDkjgUQ8EA==","signatures":[{"sig":"MEUCIQDlnbItZ8MZw7t10wMoq2jaghNEPYpykCmF9GgDWIDM3gIgfM2Y7TJm95vcmkoVa7b17qFy4eNMCxxlCWX1e0O8Xag=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":177999},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"63af2867f91fbb3ba75380352905ac1b1e56cd5c","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.6_1770578939303_0.2944216635651795","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@abhi-arya1/wt","version":"0.0.7","_id":"@abhi-arya1/wt@0.0.7","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"03fc9f5798ba24b579dd82d32479173e79179d70","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.7.tgz","fileCount":4,"integrity":"sha512-/ztjrL10HdyckGuCstNUR6zLSJGfUrO3V5XrLhB/M/k3ntveq13zInOTpCqUzzwb9I5EBbMB1iEpt0fyfz5a4w==","signatures":[{"sig":"MEQCIGNukQUGmuSAsL6ItrSH5WOe3tD6frVLP2k4oAkulPUcAiAeupADReTceEK2iZyogPsdP/q3BYjKSGrr9Zk1XSta3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":183148},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"31d2280326380da5df11ee10e3ffdc089217126e","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","nanospinner":"^1.2.2","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.7_1770629560595_0.3751989021886255","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@abhi-arya1/wt","version":"0.0.8","_id":"@abhi-arya1/wt@0.0.8","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"bin":{"wt":"dist/index.js"},"dist":{"shasum":"628e87693847d8fd4bde1a765960c51f1e9613eb","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.8.tgz","fileCount":4,"integrity":"sha512-EFitanePDyr6dY8qCYPNv4r9+iNJW2SsTV+c0dBCvPsExNtmCCxKxcKDjR+h9kPRH6k1usQK+PrtRxNUAaG2Kg==","signatures":[{"sig":"MEYCIQDl2ENRDfOfX6bSOh4RuDfmY1qWX0cn/h7JdMGxwq9KGwIhAIFwvkpbsYsNInYNCm8rLJgSM9bN55kiVAjULzBtcQI5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":183148},"main":"./dist/index.js","type":"module","module":"index.ts","gitHead":"2a6864fbe8d5969ff57d5cc995de1b7136e7204d","scripts":{"dev":"bun run ./src/index.ts","build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js"},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"_npmVersion":"10.8.2","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"ms":"^2.1.3","chalk":"^5.6.2","nanoid":"^5.1.6","commander":"^14.0.3","nanospinner":"^1.2.2","proper-lockfile":"^4.1.2","@inquirer/prompts":"^8.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ms":"^2.1.0","@types/bun":"latest","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/wt_0.0.8_1770629642685_0.5967437177822761","host":"s3://npm-registry-packages-npm-production"}},"0.0.9":{"name":"@abhi-arya1/wt","version":"0.0.9","description":"Git worktree sandboxes, locally or on remote hosts over SSH.","module":"index.ts","type":"module","bin":{"wt":"dist/index.js"},"main":"./dist/index.js","scripts":{"build":"bun build ./src/index.ts --minify --target bun --outdir ./dist --banner '#!/usr/bin/env bun' && chmod +x ./dist/index.js","dev":"bun run ./src/index.ts"},"devDependencies":{"@types/bun":"latest","@types/ms":"^2.1.0","@types/proper-lockfile":"^4.1.4"},"peerDependencies":{"typescript":"^5"},"dependencies":{"@inquirer/prompts":"^8.2.0","chalk":"^5.6.2","commander":"^14.0.3","ms":"^2.1.3","nanoid":"^5.1.6","nanospinner":"^1.2.2","proper-lockfile":"^4.1.2"},"_id":"@abhi-arya1/wt@0.0.9","gitHead":"7e7c15a39fd4beaea859c064ffd6887391368f12","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-TtYNfdxKfwuSFgOMsOlV1CiVfk9UJEiXfSHC8gpHyOyf1YALReqWV3pQH9bHEMevoTTi14aBA0nhJzTa6L1CXw==","shasum":"9edd3a31a9a38a6e962866ad0d7b66bf019b7d1b","tarball":"https://registry.npmjs.org/@abhi-arya1/wt/-/wt-0.0.9.tgz","fileCount":4,"unpackedSize":186755,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC37tIW0/3tf5gkYwuRW+pdtBZrO2VZAdiNgdVuEM8dwAiACXudfRP5Ju83gQSLEtG02bp+4XVbJD6NFPNxe+8I7tg=="}]},"_npmUser":{"name":"abhi-arya1","email":"abhi@opennote.me"},"directories":{},"maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wt_0.0.9_1770630307251_0.78894615907697"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-08T10:27:46.971Z","modified":"2026-02-09T09:45:07.509Z","0.0.1":"2026-02-08T10:27:47.243Z","0.0.2":"2026-02-08T10:36:04.512Z","0.0.3":"2026-02-08T10:50:26.170Z","0.0.4":"2026-02-08T10:51:27.247Z","0.0.5":"2026-02-08T11:32:21.727Z","0.0.6":"2026-02-08T19:28:59.433Z","0.0.7":"2026-02-09T09:32:40.742Z","0.0.8":"2026-02-09T09:34:02.818Z","0.0.9":"2026-02-09T09:45:07.395Z"},"description":"Git worktree sandboxes, locally or on remote hosts over SSH.","maintainers":[{"name":"abhi-arya1","email":"abhi@opennote.me"}],"readme":"# wt\n\nRun `git worktree` sandboxes, locally or on remote hosts over SSH, with minimal setup.\n\n`wt` clones your repo into a bare mirror, then spins up isolated worktrees you can enter, run commands in, and throw away when you're done. Works on your machine or any box you can SSH into, with SSH keys, agents, environments, and more included.\n\n```\nwt\n├── host\n│   ├── add [name]\n│   ├── ls\n│   ├── check <name>\n│   ├── rm <name>\n│   ├── map <name> <localPort> <hostPort>\n│   └── unmap <name> <localPort>\n├── up [name]\n├── local [name]\n├── rename <old> <new>\n├── enter <name>\n├── run <name> <cmd>\n├── sessions\n├── gc\n├── doctor\n├── bootstrap\n├── ls\n├── rm <name>\n└── status <name>\n```\n\n## Install\n\n```bash\n# with any package manager, but bun is recommended\nbun install -g @abhi-arya1/wt\n```\n\nRequires [Bun](https://bun.sh) (v1.3.3+). You can also build a standalone binary with `bun build --compile` if you prefer — no runtime needed, but the binary will be larger.\n\n### From source\n\n```bash\ngit clone https://github.com/abhi-arya1/wt.git && cd wt\nbun install\nbun run build\nbun link\n```\n\nOr just run it directly during development:\n\n```bash\nbun run dev -- <command>\n```\n\n## Quick start\n\n### Local sandbox\n\nYou're in a git repo. You want an isolated copy to mess around in without touching your working tree.\n\n```bash\nwt local my-experiment --enter\n# you're now in a worktree at .wt/sandboxes/my-experiment\n# type `exit` to leave the sandbox shell\n\n# or just let it pick the name from your current branch\nwt local --enter\n# sandbox named after your current branch\n```\n\n### Remote sandbox\n\nYou have a server you can SSH into. Register it as a host, then spin up sandboxes there.\n\n```bash\nwt host add prod-box --ssh user@10.0.0.5 --root /srv/wt\nwt up my-feature --host prod-box --enter\n```\n\n### Clean up\n\n```bash\nwt rm my-experiment       # remove a specific sandbox\nwt gc                     # remove all sandboxes older than 7 days\nwt gc --older-than 1d     # more aggressive\nwt gc --dry-run           # see what would get deleted\n```\n\n### Agent Usage \n\nIf you are using an agent to make sandboxes for multiple agents to work within them, you can install `wt` then give agents the [`SKILL.md`](./SKILL.md) file. This will allow them to understand usage of `wt` and create sandboxes on your behalf.\n\n## Guides\n\n### Setting up a remote host from scratch\n\n1. Make sure the remote box has `git` installed and your SSH key is authorized.\n\n2. Add the host:\n\n```bash\nwt host add myserver --ssh me@myserver.com --root /home/me/wt-sandboxes\n```\n\nThis registers the host and runs a connectivity check. If it passes, you're good.\n\n3. Check what's installed on the remote:\n\n```bash\nwt bootstrap --host myserver --tmux --agents claude,opencode\n```\n\nThis tells you what's present and what's missing. It doesn't install anything -- just reports.\n\n4. Verify everything works:\n\n```bash\nwt doctor --host myserver\n```\n\n5. Create a sandbox from any local git repo:\n\n```bash\ncd ~/projects/my-app\nwt up test-sandbox --host myserver --enter\n```\n\nYou're now in a shell on `myserver` inside a worktree of your repo. `.env` files from your local directory get copied over automatically.\n\n6. Run commands without entering:\n\n```bash\nwt run test-sandbox -- make build\nwt run test-sandbox -- bun test\n```\n\n7. Use tmux for persistent sessions:\n\n```bash\nwt enter test-sandbox --tmux\n# detach with ctrl-b d, reattach later with the same command\n```\n\n### Running multiple sandboxes for parallel work\n\nSay you need to test three branches at once.\n\n```bash\nwt up --branch feature/auth\nwt up --branch feature/payments\nwt up --branch fix/header-bug\n\nwt ls\n# NAME         HOST   REF       CREATED\n# auth         local  a1b2c3d4  2/8/2026\n# payments     local  e5f6g7h8  2/8/2026\n# header-bug   local  i9j0k1l2  2/8/2026\n\nwt run auth -- bun test\nwt run payments -- bun test\nwt run header-bug -- bun test\n\n# rename one if you want\nwt rename auth login-revamp\n\n# done, clean up\nwt rm login-revamp\nwt rm payments\nwt rm header-bug\n```\n\n### SSH keys and identity files\n\nUse `-i` to point at a specific key when adding a host, and `-p` for a non-standard port:\n\n```bash\nwt host add mybox --ssh deploy@10.0.0.5 --root /srv/wt -i ~/.ssh/id_mybox -p 2222\n```\n\nThese are stored in config and used for every SSH and SCP operation to that host. If you don't pass `-i`, wt uses whatever OpenSSH picks from your agent or default key.\n\n### Private repos on remote hosts\n\nWhen you run `wt up --host myserver`, wt tells the **remote** to `git clone --bare --mirror <origin>`. That means the remote host needs access to your git remote (e.g. GitHub). For private repos, you have two options:\n\n**Option 1: SSH agent forwarding (recommended)**\n\nAdd `ForwardAgent yes` for the host in your `~/.ssh/config`:\n\n```\nHost myserver\n    HostName 10.0.0.5\n    User deploy\n    ForwardAgent yes\n```\n\nNow your local SSH keys are available on the remote when wt runs git commands. No keys need to be deployed on the server.\n\n**Option 2: Deploy a key on the remote**\n\nAdd an SSH key on the remote host and register it as a deploy key with your git provider (e.g. GitHub deploy keys). This works without agent forwarding but means the remote has standing access to the repo.\n\n### Hosts behind firewalls and jump hosts\n\nwt doesn't have explicit jump host flags, but it passes the SSH target directly to OpenSSH, so anything in your `~/.ssh/config` is honored. To reach a host behind a bastion:\n\n```\nHost bastion\n    HostName bastion.example.com\n    User ops\n\nHost internal-box\n    HostName 10.0.1.50\n    User deploy\n    ProxyJump bastion\n    ForwardAgent yes\n```\n\nThen register it using the alias:\n\n```bash\nwt host add internal-box --ssh internal-box --root /srv/wt\n```\n\nwt will connect through the bastion transparently. The same applies to `ProxyCommand`, custom `ControlMaster` settings, or any other OpenSSH config directives.\n\n### Pushing and creating PRs from a sandbox\n\nSandboxes are regular git worktrees — standard git commands work as expected. Push branches and create PRs the same way you normally would:\n\n```bash\nwt enter my-sandbox\n\ngit checkout -b my-feature\n# make changes\ngit add .\ngit commit -m \"my changes\"\ngit push -u origin my-feature\n\n# create a PR with the GitHub CLI\ngh pr create --title \"My feature\" --body \"Description of changes\"\n```\n\nYou can also do this without entering the sandbox:\n\n```bash\nwt run my-sandbox -- git push -u origin my-feature\nwt run my-sandbox -- gh pr create --title \"My feature\" --body \"Description\"\n```\n\n**Note:** Because `wt` uses `git clone --bare --mirror`, the mirror fetches all remote refs including GitHub's internal PR refs (`refs/pull/*/head`). A plain `git push` with no arguments may try to push these back and produce harmless `remote rejected` errors. To avoid this, push specific branches explicitly (`git push origin my-branch`) or set `git config --global push.default current`.\n\n### Using with tmux sessions\n\nEvery sandbox can have a tmux session tied to it. Sessions are named `wt-<sandboxId>`.\n\n```bash\nwt enter my-sandbox --tmux      # creates or reattaches to tmux session\nwt sessions                     # list all wt-managed tmux sessions\nwt sessions --host prod-box     # list sessions on a remote host\n```\n\n## Command reference\n\n### `wt up [name]`\n\nCreate a sandbox worktree on a host. If `name` is omitted, it defaults to the branch name from `-b` / `--ref`, or the current branch. When `-b` is not provided, the sandbox stays on the same branch you're currently on.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Target host (defaults to configured default, falls back to `local`) |\n| `-b, --branch <name>` | Create or use a branch with this name |\n| `-r, --ref <ref>` | Git ref to check out (branch, tag, or sha that must exist) |\n| `-e, --enter` | Enter the sandbox after creating it |\n| `--tmux` | Use tmux when entering (implies `--enter`) |\n| `--json` | JSON output |\n\n### `wt local [name]`\n\nShorthand for `wt up [name]` on the local host. Same options minus `--host`.\n\n| Flag | Description |\n|---|---|\n| `-b, --branch <name>` | Create or use a branch with this name |\n| `-r, --ref <ref>` | Git ref to check out (branch, tag, or sha that must exist) |\n| `-e, --enter` | Enter the sandbox after creating it |\n| `--tmux` | Use tmux when entering (implies `--enter`) |\n| `--json` | JSON output |\n\n### `wt rename <old> <new>`\n\nRename a sandbox.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n### `wt enter <name>`\n\nOpen a shell inside a sandbox.\n\n| Flag | Description |\n|---|---|\n| `--tmux` | Use a tmux session instead of a plain shell |\n| `--json` | Print sandbox record as JSON without entering |\n\n### `wt run <name> <cmd...>`\n\nRun a command inside a sandbox. Streams output by default.\n\n| Flag | Description |\n|---|---|\n| `--json` | Capture stdout/stderr and return as JSON (must come before `--`) |\n| `--quiet` | Suppress non-error output (must come before `--`) |\n\nNote: flags for `wt run` itself go **before** `--`. Everything after `--` is passed to the command.\n\n```bash\nwt run my-sandbox --json -- git log --oneline -5\n```\n\n### `wt ls`\n\nList all sandboxes.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Filter by host |\n| `--json` | JSON output |\n\n### `wt rm <name>`\n\nRemove a sandbox. Deletes the worktree directory, metadata, and config entry. Prunes the mirror's worktree references.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n### `wt status <name>`\n\nShow sandbox details: host, ref, path, age, whether the directory exists, and whether a tmux session is active.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n### `wt sessions`\n\nList active `wt-*` tmux sessions.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Target host |\n| `--json` | JSON output |\n\n### `wt gc`\n\nGarbage-collect stale sandboxes. A sandbox is stale if it's older than the threshold or its directory no longer exists.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Target host (omit for all hosts) |\n| `--older-than <dur>` | Age threshold, e.g. `7d`, `24h`, `1w` (default: `7d`) |\n| `--dry-run` | Preview what would be deleted |\n| `--json` | JSON output |\n\n### `wt doctor`\n\nCheck that git, bun/node, and tmux are available on a host.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Target host |\n| `--json` | JSON output |\n\n### `wt bootstrap`\n\nCheck host readiness. Reports what's installed and what's missing. Does not install anything.\n\n| Flag | Description |\n|---|---|\n| `-H, --host <name>` | Target host |\n| `--tmux` | Include tmux in checks |\n| `--agents <list>` | Comma-separated agent CLIs to check (e.g. `claude,opencode`) |\n| `--json` | JSON output |\n\n### `wt host add [name]`\n\nRegister or update a remote host.\n\n| Flag | Description |\n|---|---|\n| `-s, --ssh <target>` | SSH target (alias, `user@host`, or `ssh://user@host:port`) |\n| `-r, --root <path>` | Remote base directory (absolute path) |\n| `-d, --default` | Set as default host |\n| `-p, --port <n>` | SSH port |\n| `-i, --identity <path>` | Path to SSH identity file |\n| `-t, --connect-timeout <s>` | Connection timeout in seconds (default: 10) |\n| `-l, --labels <k=v,...>` | Comma-separated key=value labels |\n| `--no-check` | Skip connectivity check |\n| `--json` | JSON output |\n\n### `wt host ls`\n\nList all configured hosts.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n### `wt host check <name>`\n\nTest SSH connectivity and capabilities of a host.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n### `wt host rm <name>`\n\nRemove a host.\n\n| Flag | Description |\n|---|---|\n| `-y, --yes` | Skip confirmation prompt |\n| `--json` | JSON output |\n\n### `wt host map <name> <localPort> <hostPort>`\n\nAdd a port mapping to a host. When you SSH into the host (via `wt enter`, `wt up --enter`, etc.), the mapping is applied as `-L localPort:localhost:hostPort`, forwarding traffic from your local port to the remote port.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n```bash\n# Forward local port 3000 to remote port 8080\nwt host map myserver 3000 8080\n\n# Now when you enter a sandbox, localhost:3000 reaches the remote's port 8080\nwt enter my-sandbox\ncurl localhost:3000  # hits remote:8080\n```\n\nMappings are stored in config and persist across restarts. If a mapping for the same local port already exists, it is updated.\n\n### `wt host unmap <name> <localPort>`\n\nRemove a port mapping from a host.\n\n| Flag | Description |\n|---|---|\n| `--json` | JSON output |\n\n```bash\nwt host unmap myserver 3000\n```\n\n## How it works\n\n`wt` creates a bare mirror of your repo, then uses `git worktree add` to spin up isolated checkouts. Each sandbox gets its own directory and metadata file.\n\n```\n.wt/                          # local root (inside your repo)\n  mirrors/\n    <repoId>.git/             # bare mirror\n  sandboxes/\n    <name>/                   # worktree checkout\n  meta/\n    <sandboxId>.json          # sandbox metadata\n```\n\nRemote hosts use the same layout under the configured `root` path (e.g. `/srv/wt`). All remote operations go over SSH.\n\nConfig lives at `~/.config/wt/config.json` and stores hosts and sandbox records. Every structured command supports `--json` for scripting.\n\n## JSON output\n\nEvery command that produces structured output supports `--json`. Errors in JSON mode return:\n\n```json\n{\n  \"ok\": false,\n  \"error\": \"what went wrong\"\n}\n```\n\nThis makes it straightforward to compose `wt` with other tools, scripts, or agents.\n\n## Future Plans \n\nUnsure if this will be added, but I'd like to add: \n- Cloud provider abstractions (AWS, Fly.io, etc.)\n- Automatic download for sandbox dependencies \n- Better observability, error handling, cleanup, and devex\n","readmeFilename":"README.md"}