{"id":47639506,"url":"https://github.com/block/wt","last_synced_at":"2026-04-02T00:41:52.034Z","repository":{"id":333011886,"uuid":"1135889836","full_name":"block/wt","owner":"block","description":"A set of command line tools to help working with Bazel + IntelliJ-based AI worktrees in large codebases","archived":false,"fork":false,"pushed_at":"2026-03-22T07:00:36.000Z","size":760,"stargazers_count":5,"open_issues_count":5,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-22T18:14:12.562Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/block.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-16T18:31:02.000Z","updated_at":"2026-03-22T07:00:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/block/wt","commit_stats":null,"previous_names":["block/wt"],"tags_count":4,"template":false,"template_full_name":"block/oss-project-template","purl":"pkg:github/block/wt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/block","download_url":"https://codeload.github.com/block/wt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fwt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31147881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-29T14:13:29.672Z","status":"ssl_error","status_checked_at":"2026-03-29T14:12:29.244Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-04-02T00:41:50.893Z","updated_at":"2026-04-02T00:41:52.024Z","avatar_url":"https://github.com/block.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Worktree Toolkit\n\n[![Tests](https://github.com/block/wt/actions/workflows/test.yml/badge.svg)](https://github.com/block/wt/actions/workflows/test.yml)\n[![ShellCheck](https://github.com/block/wt/actions/workflows/lint.yml/badge.svg)](https://github.com/block/wt/actions/workflows/lint.yml)\n[![Plugin Build](https://github.com/block/wt/actions/workflows/plugin-build.yml/badge.svg)](https://github.com/block/wt/actions/workflows/plugin-build.yml)\n\nA streamlined workflow for developing in large Bazel + IntelliJ monorepos using Git worktrees.\n\nEnables instant IntelliJ context switching between worktrees—no re-imports, no re-indexing—and scales to support parallel development by humans and AI agents alike.\n\n## Overview\n\nGit worktrees let you work on multiple branches in parallel, but IntelliJ treats each worktree as a separate project, requiring expensive Bazel syncs and index rebuilds every time you switch to a new worktree.\n\nThis toolkit makes IntelliJ context switching **instant** by:\n\n- **Symlink trick**: IntelliJ always opens the same path; switching worktrees looks like a branch checkout → incremental refresh in seconds, not minutes\n- **Metadata vault**: IDE project metadata (`.ijwb`, `.idea`, `.vscode`, etc.) is stored externally and automatically installed into every new worktree—no manual IDE setup needed\n- **Safe worktree management**: Automatic stash/restore, branch creation, and cleanup of merged branches\n- **Parallel development at scale**: Works for humans and AI agents alike\n\n📊 See the [presentation slides](presentation/slides.pdf) for a visual walkthrough.\n\n## Quick Start\n\n```bash\n# Install (interactive prompts for configuration)\n./install.sh\n\n# Reload shell\nsource ~/.zshrc\n\n# Use\nwt help\n```\n\nThe installer will:\n1. Copy the toolkit to `~/.wt/`\n2. Add sourcing to your shell rc file\n3. Prompt for workspace paths (main repo, worktrees, metadata vault)\n4. Create required directories\n5. Optionally migrate existing repo to worktree structure\n6. Optionally export project metadata to the vault\n7. Optionally set up a nightly cron job to refresh Bazel IDE metadata\n\n## Workflow\n\n### Initial Setup\n\nThe directory structure expected (controlled by environment variables, can be overwritten):\n\n```\n~/Development/\n├── java -\u003e java-master          # Symlink (IntelliJ opens this)\n├── java-master/                 # Main repository\n├── java-worktrees/              # Worktrees go here\n└── idea-project-files/          # Project metadata vault\n```\n\n### Full Workflow Diagram\n\n```\n                      ┌─────────────────────────────────────────────┐\n                      │   External Project Metadata Vault           │\n                      │  ~/Development/idea-project-files           │\n                      │    (IDE configs: .ijwb, .idea, etc.)        │\n                      └──────────▲───────────────┬──────────────────┘\n                                 │               │\n                                 │               │\n           ┌──wt metadata-export─┘               └──wt metadata-import─┐\n           │                                                           │\n┌──────────┴───────────────────────┐                     ┌─────────────▼──────────────────────┐\n│   Main Repository                │                     │    Worktrees                       │\n│ ~/Development/java-master        │       wt add        │ ~/Development/java-worktrees/...   │\n│  • master branch                 │ ──────────────────► │  • feature/foo                     │\n│  • safe stash/pull/restore       │(calls metadata-imp) │  • bugfix/bar                      │\n│  • never removed                 │                     │  • agent-task-123                  │\n└───────────────┬──────────────────┘                     └─────────┬──────────────────────────┘\n                │                                                  │\n             wt switch                                          wt remove\n                │                                                  │\n    ┌───────────▼──────────────────┐                     ┌─────────▼────────────┐\n    │ Stable IntelliJ Project Dir  │                     │  Safe cleanup with   │\n    │ ~/Development/java           │                     │  confirmation prompt │\n    │ (symlink updated per switch) │                     └──────────────────────┘\n    └───────────▲──────────────────┘\n                │ \n          IntelliJ auto-refresh\n                │\n     ┌──────────▼───────────────────┐\n     │ IntelliJ loads worktree      │\n     │ instantly (no import needed) │\n     └──────────────────────────────┘\n```\n\n\n### Creating Worktrees\n\n```bash\n# Existing branch\nwt add feature/foo\n\n# New branch (from latest master)\nwt add -b feature/foo\n```\n\nWhen creating with `-b`, the script:\n1. Stashes uncommitted changes\n2. Switches to master, pulls latest\n3. Creates branch + worktree\n4. Imports project metadata from vault\n5. Restores original state\n\n### Switching Worktrees\n\n```bash\n# Interactive\nwt switch\n\n# Direct\nwt switch ~/Development/java-worktrees/feature/foo\n```\n\nUpdates the symlink so IntelliJ instantly loads the new worktree.\n\n### Navigation\n\n```bash\n# Interactive cd\nwt cd\n\n# Direct cd\nwt cd ~/Development/java-worktrees/feature/foo\n```\n\n### Listing Worktrees\n\n```bash\nwt list\n```\n\nShows all worktrees with status indicators:\n- `*` = Currently linked worktree\n- `[main]` = Main repository root\n- `[linked]` = Active symlink target\n- `[dirty]` = Has uncommitted changes\n- `[↑N]` / `[↓N]` = Commits ahead/behind upstream\n\n### Removing Worktrees\n\n```bash\n# Interactive\nwt remove\n\n# Direct (with confirmation)\nwt remove ~/Development/java-worktrees/feature/foo\n\n# Skip confirmation (unless uncommitted changes exist)\nwt remove -y ~/Development/java-worktrees/feature/foo\n\n# Remove all worktrees with branches merged into base branch\nwt remove --merged\n\n# Auto-remove merged without prompts (skips worktrees with uncommitted changes)\nwt remove --merged -y\n```\n\nSafety features:\n- Warns if the worktree is currently linked (symlink will be switched to main repo)\n- Warns if there are uncommitted changes (shows summary)\n- Always prompts for confirmation if uncommitted changes exist, even with `-y`\n- `--merged` mode: automatically finds and removes all worktrees whose branches are merged\n\n### Managing Project Metadata\n\n```bash\n# Export metadata from main repo to vault (run after setting up new IDE projects)\nwt metadata-export\n\n# Import metadata into a worktree (interactive selection if target omitted)\nwt metadata-import\nwt metadata-import ~/Development/java-worktrees/feature/foo\n\n# Skip confirmation prompts (useful in scripts)\nwt metadata-export -y\nwt metadata-import -y ~/Development/java-worktrees/feature/foo\n```\n\n### Refreshing Stale Bazel IDE Metadata (Cron Job)\n\nWhen most development work is done in worktrees, the Bazel IDE directories (`.ijwb`, `.aswb`, `.clwb`) in the main repository can become stale (targets files don't reflect new Bazel targets).\n\nThe `lib/wt-metadata-refresh` script is designed to run as a cron job to keep metadata current.\n\n**Note:** When IntelliJ has `derive_targets_from_directories: true` in `.bazelproject` (the default), it queries Bazel fresh on every sync. The `targets-*` file serves as a cache for initial project imports and may improve import speed.\n\n**Note:** The installer (`install.sh`) offers to set up this cron job automatically (default: yes).\n\nTo set it up manually:\n\n```bash\n# Create log directory\nmkdir -p ~/.wt/logs\n\n# Edit crontab\ncrontab -e\n\n# Add this line to run nightly at 2am (uses login shell for full PATH):\n0 2 * * * /bin/zsh -lc '~/.wt/lib/wt-metadata-refresh' \u003e\u003e ~/.wt/logs/metadata-refresh.log 2\u003e\u00261\n```\n\nYou can also run the script manually:\n\n```bash\n# Refresh all Bazel IDE directories and re-export to vault\n~/.wt/lib/wt-metadata-refresh\n\n# Preview what would be refreshed (dry run)\n~/.wt/lib/wt-metadata-refresh --dry-run\n\n# Refresh targets files only (skip re-export step)\n~/.wt/lib/wt-metadata-refresh --no-export\n```\n\nThe refresh script:\n- Uses `bazel query` to regenerate `targets/targets-*` files in each Bazel IDE directory\n- Supports all Bazel patterns configured in WT_METADATA_PATTERNS (`.ijwb`, `.aswb`, `.clwb`)\n- Parses `.bazelproject` to determine which directories to include in the query\n- Preserves existing targets file hashes (IntelliJ may reference them)\n- Re-exports all metadata to the vault (including non-Bazel patterns)\n- Logs timestamped output for monitoring\n- Returns exit codes: 0=success, 1=error, 2=partial success\n\n\n## Configuration: Environment Variables\nThe scripts rely on a few environment variables to know where your\nmain repository, worktrees, and IntelliJ metadata live.\n\nThese environment variables are set in `wt-common` with built-in defaults.\nIf set in your shell configuration, they take precedence over the built-in defaults.\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `WT_MAIN_REPO_ROOT` | `~/Development/java-master` | Main repository root |\n| `WT_WORKTREES_BASE` | `~/Development/java-worktrees` | Where worktrees are created |\n| `WT_IDEA_FILES_BASE` | `~/Development/idea-project-files` | IntelliJ metadata vault |\n| `WT_ACTIVE_WORKTREE` | `~/Development/java` | Symlink to active worktree |\n| `WT_BASE_BRANCH` | `master` | Default branch for new worktrees |\n\n### WT_MAIN_REPO_ROOT\nPath to your primary git repository clone.\n\n**Default:** `~/Development/java-master`\n\n```bash\nexport WT_MAIN_REPO_ROOT=\"$HOME/Development/java-master\"\n```\n\nUsed by:\n- wt-add (for stash/restore \u0026 base branch operations)\n- wt-choose (listing worktrees)\n- wt-switch (default symlink target)\n- wt-remove (safety check to prevent removing main repo)\n\n\n### WT_WORKTREES_BASE\nDirectory where new worktrees are created by default.\n\n**Default:** `~/Development/java-worktrees`\n\n```bash\nexport WT_WORKTREES_BASE=\"$HOME/Development/java-worktrees\"\n```\n\n\n### WT_IDEA_FILES_BASE\nCanonical metadata vault storing project metadata (IDE configs, etc.).\n\n**Default:** `~/Development/idea-project-files`\n\n```bash\nexport WT_IDEA_FILES_BASE=\"$HOME/Development/idea-project-files\"\n```\n\nUsed by:\n- wt-metadata-import\n- wt-metadata-export\n- wt-metadata-refresh\n- wt-add (when installing metadata)\n\n\n### WT_ACTIVE_WORKTREE\nSymlink path that points to the currently active worktree. This is where IntelliJ should open the project.\n\n**Default:** `~/Development/java`\n\n```bash\nexport WT_ACTIVE_WORKTREE=\"$HOME/Development/java\"\n```\n\nUsed by:\n- wt-switch (updates this symlink)\n- wt-remove (warns if removing the linked worktree)\n\n\n### WT_BASE_BRANCH\nName of the mainline branch to branch from.\n\n**Default:** `master`\n\n```bash\nexport WT_BASE_BRANCH=\"master\"\n```\n\n## Presentation\n\nA 10-minute overview presentation is available in the `presentation/` directory:\n\n- `slides.md` — Marp markdown source\n- `slides.pdf` — Generated PDF\n\nTo regenerate the PDF from the markdown:\n\n```bash\nnpx @marp-team/marp-cli presentation/slides.md -o presentation/slides.pdf\n```\n\n## Directory Structure\n\n```\nwt/\n├── wt.sh                    # Entry point (source this)\n├── presentation/            # Overview slides\n├── bin/                     # Executable commands\n│   ├── wt-add\n│   ├── wt-cd\n│   ├── wt-list\n│   ├── wt-remove\n│   ├── wt-switch\n│   ├── wt-metadata-import\n│   └── wt-metadata-export\n├── lib/                     # Shared libraries\n│   ├── wt-common            # Configuration and helpers\n│   ├── wt-choose            # Interactive worktree selection\n│   ├── wt-help              # Help text for wt command\n│   ├── wt-completion        # Shell completion for wt command\n│   └── wt-metadata-refresh  # Cron script to refresh Bazel IDE metadata\n├── completion/              # Shell completions for wt-* scripts\n│   ├── wt.zsh\n│   └── wt.bash\n├── install.sh\n└── README.md\n```\n\n## Individual Scripts\n\nYou can also run the underlying scripts directly:\n\n```bash\nwt-add, wt-switch, wt-remove, wt-list, wt-cd, wt-metadata-export, wt-metadata-import\n```\n\nThese are located in `bin/` and work identically to the `wt` subcommands.\n\nThe `lib/wt-metadata-refresh` script is designed for cron jobs and can be run directly from its location.\n\n## Project Resources\n\n| Resource                       | Description                |\n| ------------------------------ | -------------------------- |\n| [CODEOWNERS](./CODEOWNERS)     | Project lead(s)            |\n| [GOVERNANCE.md](./GOVERNANCE.md) | Project governance       |\n| [LICENSE](./LICENSE)           | Apache License, Version 2.0 |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock%2Fwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblock%2Fwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock%2Fwt/lists"}