@ogpoyraz/wtx 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # wtx
2
+
3
+ Multi-repo git worktree manager built for parallel development — human or AI.
4
+
5
+ Create isolated worktrees across every repo you maintain, with working dependencies, synced env files, deterministic ports, and one-command hand-off to coding agents like Claude Code, Codex, OpenCode, or Cursor.
6
+
7
+ ```
8
+ $ wtx create feat/auth --agent claude
9
+
10
+ my-api
11
+ ◌ Fetching origin/main...
12
+ ✓ Worktree created → ~/Repos/my-api-wt/feat/auth
13
+ ✓ Synced .env
14
+ ✓ Safely linked 214 packages
15
+ ✓ Done — agent spawned in tmux session wtx-my-api-feat-auth
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Why not plain `git worktree`?
21
+
22
+ `git worktree add` gives you a directory — no dependencies, no `.env`, no port-conflict solution, no cleanup discipline. Every wrapper solves one slice.
23
+
24
+ | | git worktree | single-repo managers | wtx |
25
+ |---|---|---|---|
26
+ | Multi-repo in one command | – | – | ✓ |
27
+ | Working deps after create | manual | hooks only | adapters + safe links |
28
+ | `.env` sync from main | manual | some | ✓ |
29
+ | Parallel dev-server ports | collide | – | deterministic `{port}` |
30
+ | Safe removal (dirty guards) | none | varies | boundary-checked |
31
+ | Spawn coding agents | – | some | ✓ tmux-aware |
32
+ | MCP server for agents | – | – | ✓ |
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ npm install -g @ogpoyraz/wtx
38
+ ```
39
+
40
+ ### Shell integration
41
+
42
+ Add to `~/.zshrc`, `~/.bashrc`, or your fish config:
43
+
44
+ ```bash
45
+ eval "$(wtx init zsh)" # or bash, or fish
46
+ ```
47
+
48
+ This enables `wtx cd <repo> <branch>` to change directories in your current shell.
49
+
50
+ ### First run
51
+
52
+ Run any command without a config and `wtx` walks you through setup: it scans common dev directories for git repos, lets you pick which ones to manage, and writes `~/.config/wtx/config.json`. Prefer manual? `wtx config init` starts the same wizard; non-interactive shells print exact steps instead.
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ ```bash
59
+ # create a worktree (deps + sync_files handled automatically)
60
+ wtx create ogp/my-feature --repo my-frontend
61
+
62
+ # hand it to a coding agent
63
+ wtx create ogp/my-feature --repo my-frontend --agent claude --prompt "add OAuth login"
64
+
65
+ # list everything across all repos
66
+ wtx ls
67
+
68
+ # rebase onto main when origin moves
69
+ wtx rebase ogp/my-feature
70
+
71
+ # remove when merged — refuses dirty worktrees unless forced
72
+ wtx remove ogp/my-feature
73
+ ```
74
+
75
+ If origin already has a branch with that name owned by someone else, `wtx` warns and creates your own branch from base instead of tracking theirs. Use `--track` to adopt theirs, or `--local` when local and remote diverged.
76
+
77
+ ---
78
+
79
+ ## Commands
80
+
81
+ | Command | Args | Flags | Description |
82
+ |---|---|---|---|
83
+ | `create` | `<branch>` | `--repo`, `--base`, `--open`, `--ide`, `--track`, `--local`, `--agent <name>`, `--prompt <text>` | Create worktree(s), sync files, prepare deps, optionally spawn an agent |
84
+ | `pull` | `<pr-link>` | `--repo` | Fetch a GitHub PR and create its worktree |
85
+ | `remove` | `<branch>` | `--repo`, `--force`, `--yes` | Remove worktree(s), clean empty dirs |
86
+ | `prune` | | `--repo`, `--force`, `--yes` | Remove worktrees whose PR has merged |
87
+ | `open` | `<branch>` | `--repo`, `--ide` | Open worktree in IDE |
88
+ | `rebase` | `<branch>` | `--repo` | Fetch base remote main, rebase worktree onto it |
89
+ | `fetch` | | `--repo` | Fetch main for each repo |
90
+ | `sync` | `<branch>` | `--repo` | Re-copy sync files, run post-sync hooks |
91
+ | `deps` | `[branch]` | `--repo`, `--install`, `--symlink`, `--json` | Inspect or switch dependency strategy |
92
+ | `ls` | | `--repo`, `--pr`, `--json` | List all worktrees with clean/dirty state |
93
+ | `status` | `<branch>` | `--repo`, `--json` | Ahead/behind, dirty files, rebase state, deps strategy |
94
+ | `prs` | | `--repo`, `--json`, `--all` | Pull request status across worktrees |
95
+ | `exec` | `<branch> <command...>` | `--repo` | Run a command inside a worktree (`WTX_PORT` injected) |
96
+ | `terminal` | | | Interactive worktree dashboard (requires Bun) |
97
+ | `mcp` | | | Run MCP server exposing worktree tools over stdio |
98
+ | `cd` | `<repo> <branch>` | | cd into worktree (requires shell integration) |
99
+ | `history` | | `--limit`, `--json`, `--source` | Show recent action history (`~/.local/state/wtx/history.jsonl`) |
100
+ | `config init/show/set/add-repo/remove-repo` | | | Manage `~/.config/wtx/config.json` |
101
+ | `skill list/show/path` | | | Agent skill files for opencode/cursor/claude |
102
+ | `init` | `<bash\|zsh\|fish>` | | Output shell wrapper for eval |
103
+
104
+ **Global flags:** `--verbose`, `--dry-run`, `-q/--quiet`, `-v/--version`, `-h/--help`.
105
+
106
+ `--repo` accepts comma-separated values or repeats. Omit it to target all configured repos, or run inside a managed repo to auto-scope. Destructive commands (`remove`, `prune`) ask for confirmation on interactive terminals; scripts pass `--yes` or set `WTX_YES=1`.
107
+
108
+ ---
109
+
110
+ ## Configuration
111
+
112
+ Config lives at `~/.config/wtx/config.json`.
113
+
114
+ ```json
115
+ {
116
+ "version": 1,
117
+ "root": "~/Repos",
118
+ "postfix": "-wt",
119
+ "ide": "cursor",
120
+ "default_main_branch": "main",
121
+ "user": "ogp",
122
+ "ports": { "min": 4100, "max": 4999 },
123
+ "agents": {
124
+ "claude": { "command": "claude" },
125
+ "reviewer": { "command": "opencode --model ollama/qwen3" }
126
+ },
127
+ "repos": {
128
+ "my-frontend": {
129
+ "main_branch": "auto",
130
+ "sync_files": [".env", ".env.local"],
131
+ "post_create": ["wtx deps"],
132
+ "post_sync": ["wtx deps"],
133
+ "deps": { "manager": "auto", "strategy": "auto" }
134
+ },
135
+ "my-api": {
136
+ "main_branch": "auto",
137
+ "sync_files": [".env"],
138
+ "post_create": ["wtx deps", "docker compose up -d db"]
139
+ },
140
+ "my-go-service": {
141
+ "main_branch": "main"
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### Fields
148
+
149
+ | Field | Default | Description |
150
+ |---|---|---|
151
+ | `root` | required | Base directory where repos live. `~` expanded. |
152
+ | `postfix` | `"-wt"` | Worktree directory suffix (`<repo><postfix>/<branch>`) |
153
+ | `ide` | `"cursor"` | Default IDE for `wtx open` |
154
+ | `default_main_branch` | `"main"` | Fallback when auto-detection fails |
155
+ | `user` | `null` | Your forge handle; enables ownership detection |
156
+ | `ports.min` / `ports.max` | `4100` / `4999` | Range used by `{port}` isolation |
157
+ | `agents.<name>.command` | – | Shell command template for `--agent`; `{wt}`, `{branch}`, `{repo}` expanded |
158
+ | `repos.<name>.main_branch` | `"auto"` | Auto-detects via `git symbolic-ref` |
159
+ | `repos.<name>.fetch_main_on_create` | `true` | Fetch before creating so branches start fresh |
160
+ | `repos.<name>.sync_files` | `[]` | Files copied from main checkout on create and sync |
161
+ | `repos.<name>.post_create` / `post_sync` | `[]` | Hook commands; failures fail the command with a rerun hint |
162
+ | `repos.<name>.deps.manager` | `"auto"` | Force a manager: `npm` `bun` `pnpm` `yarn` `go` `python` `cargo` |
163
+ | `repos.<name>.deps.strategy` | `"auto"` | `auto` `link` `symlink` `install` `off` — see below |
164
+ | `repos.<name>.pr` | `true` | Skip PR lookups for this repo |
165
+ | `repos.<name>.forge` / `pr_repo` | `"auto"` / `null` | GitHub Enterprise and fork workflows |
166
+
167
+ ### Template variables
168
+
169
+ In `post_create`, `post_sync`, and agent commands:
170
+
171
+ | Variable | Expands to |
172
+ |---|---|
173
+ | `{root}` `{repo}` `{branch}` `{postfix}` | identity fields |
174
+ | `{main}` / `{wt}` | absolute main checkout / worktree paths |
175
+ | `{port}` | deterministic collision-free port for this worktree |
176
+
177
+ Hooks also receive `WTX_PORT` as an environment variable, as does `wtx exec`. Ports hash `repo+branch` into the configured range and probe collisions against every active worktree — two branches can run dev servers simultaneously without conflict, and the same branch always gets the same port.
178
+
179
+ ---
180
+
181
+ ## Dependency syncing
182
+
183
+ `wtx deps` keeps worktree dependencies working without duplicating installs. Each ecosystem gets its own adapter; detection is lockfile-based and overridable per repo via `deps.manager`.
184
+
185
+ **Supported today:** npm, bun, pnpm, yarn (Node) · Go (`go mod download`) · Python (`uv sync`; venvs are never symlinked — shebang paths make that unsafe) · Cargo (build cache shared through worktree-local `.cargo/config.toml` pointing at main's `target/`).
186
+
187
+ ### Strategies
188
+
189
+ | `deps.strategy` | Behavior |
190
+ |---|---|
191
+ | `auto` | Definitions match main → safe link; differ → install; only some workspaces changed → targeted install |
192
+ | `link` | Force safe linking |
193
+ | `symlink` | Legacy whole-directory symlink (⚠ installs inside the worktree mutate main's `node_modules`) |
194
+ | `install` | Always a real install in the worktree |
195
+ | `off` | Leave dependencies alone |
196
+
197
+ ### Safe linking (the `auto` default)
198
+
199
+ When manifests match main, wtx creates a **real** `node_modules` directory in the worktree containing per-package symlinks into main's tree (scoped packages traversed, `.bin` linked). Package-manager operations inside the worktree replace links, never main's files — an `npm install` in one branch cannot damage another checkout. If replacing an existing directory fails mid-way, the original is restored rather than left missing.
200
+
201
+ Monorepos: `workspaces` globs (including `**`) and `pnpm-workspace.yaml` are parsed; when only some workspaces changed, installs target just those (`-w` / `--filter`). Yarn falls back to a full install.
202
+
203
+ Inspect any worktree with `wtx deps <branch>`, or add `--json` for machine output. States include `symlinked`, `linked-packages`, `installed`, `broken`, `external`, and `shared-target` — broken and external states come with repair instructions.
204
+
205
+ ---
206
+
207
+ ## AI agents
208
+
209
+ ### Spawn an agent into a fresh worktree
210
+
211
+ ```bash
212
+ wtx create feat/auth --repo my-api --agent claude --prompt "implement OAuth login"
213
+ ```
214
+
215
+ The full pipeline runs first — create, sync files, prepare dependencies — then the agent launches inside the worktree. With tmux installed it runs in a detached named session (attach hint printed); otherwise directly. If post-create hooks fail, the agent is not spawned: fix with `wtx sync` instead of burning agent tokens on a broken tree. Define custom agents under `agents.<name>` in config.
216
+
217
+ ### MCP server
218
+
219
+ Expose worktrees to MCP-capable clients (Claude Code, OpenCode, Cursor):
220
+
221
+ ```json
222
+ {
223
+ "mcpServers": {
224
+ "wtx": { "command": "wtx", "args": ["mcp"] }
225
+ }
226
+ }
227
+ ```
228
+
229
+ Tools: `list_worktrees`, `worktree_status`, `create_worktree`, `remove_worktree`, `rebase_worktree`. All operations are scoped to configured repos; `remove_worktree` requires `confirm: true`, plus `force: true` for dirty worktrees.
230
+
231
+ ### Skill files
232
+
233
+ ```bash
234
+ wtx skill show opencode > ~/.config/opencode/commands/wtx.md
235
+ wtx skill show cursor > .cursor/rules/wtx.mdc
236
+ wtx skill show claude >> CLAUDE.md
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Pull request workflow
242
+
243
+ Read-only PR visibility and lifecycle automation via the [GitHub CLI](https://cli.github.com/) — `wtx` stores no tokens.
244
+
245
+ ```bash
246
+ $ wtx prs
247
+
248
+ my-frontend
249
+ #42 ogp/my-feature CONFLICTED · awaiting review checks 3/3 ✓ 2d ago
250
+ #43 ogp/fix-token IN_REVIEW checks 2/3 ✓ 5h ago @alice
251
+
252
+ ⚠ 2 open PRs across 1 repo — 1 needs attention
253
+ ```
254
+
255
+ Every PR gets one ranked display state (`CONFLICTED`, `CI_FAILING`, `CHANGES_REQUESTED`, ...). Merged and closed PRs surface in `wtx ls --pr` and `wtx status`, so stale worktrees are recognizable at a glance.
256
+
257
+ ```bash
258
+ wtx pull https://github.com/OGPoyraz/wtx/pull/11 # PR → worktree in one command
259
+ wtx prune # remove worktrees whose PR merged
260
+ ```
261
+
262
+ Lookups degrade gracefully: if `gh` is missing or unauthenticated you get a warning and everything else keeps working. Fork workflows are covered by `forge` / `pr_repo`.
263
+
264
+ ---
265
+
266
+ ## Terminal dashboard
267
+
268
+ `wtx terminal` opens a full-screen dashboard across all configured repos (requires the [Bun](https://bun.sh) runtime).
269
+
270
+ | Key | Action |
271
+ |---|---|
272
+ | `/` | Fuzzy-filter entries by branch, repo, PR, owner |
273
+ | `Space` | Multi-select for batch operations |
274
+ | `R` / `D` / `s` | Batch rebase / remove / sync selection |
275
+ | `n` | Create worktree |
276
+ | `b` | Rebase selected |
277
+ | `a` | Spawn coding agent in selected worktree |
278
+ | `H` | Action history (recent actions across CLI and dashboard) |
279
+ | `o` | Open in IDE |
280
+ | `c` | Edit configuration |
281
+ | `?` / `q` | Help / quit |
282
+
283
+ Actions show inline progress — `creating worktree` next to the repo header, `deleting` / `rebasing` / `syncing` next to the branch — while the dashboard is busy. Input is locked until the operation (and its refresh) finishes; on failure a log modal opens with the captured output. Destructive ones confirm first.
284
+
285
+ ---
286
+
287
+ ## Scripting
288
+
289
+ Machine-readable output where it matters: `wtx ls --json`, `wtx status <branch> --json`, `wtx deps <branch> --json`, `wtx prs --json`. Combine with `-q` to suppress progress lines, and preview anything destructive with `--dry-run` — including planned deletions and hook commands.
290
+
291
+ ### Action history
292
+
293
+ Mutating commands (`create`, `remove`, `rebase`, `sync`, `pull`, ...) are recorded to `~/.local/state/wtx/history.jsonl` — whether you ran them from your shell or from inside `wtx terminal` (entries are tagged with their source). Inspect with `wtx history --limit 50 --json --source terminal`, or press `H` in the dashboard. The file rotates automatically at ~5 MB, keeping the newest entries.
294
+
295
+ ---
296
+
297
+ ## License
298
+
299
+ MIT
@@ -0,0 +1,268 @@
1
+ #compdef wtx
2
+
3
+ _wtx_get_repos() {
4
+ local config_file
5
+ if [ -n "$XDG_CONFIG_HOME" ]; then
6
+ config_file="${XDG_CONFIG_HOME}/wtx/config.json"
7
+ else
8
+ config_file="${HOME}/.config/wtx/config.json"
9
+ fi
10
+ if [ -f "$config_file" ]; then
11
+ if command -v jq >/dev/null 2>&1; then
12
+ jq -r '.repos | keys[]' "$config_file" 2>/dev/null
13
+ else
14
+ grep -E '^ "[^"]+":' "$config_file" 2>/dev/null | sed 's/^ "//; s/":.*//'
15
+ fi
16
+ fi
17
+ }
18
+
19
+ _wtx_repos() {
20
+ local repos
21
+ repos=($(_wtx_get_repos))
22
+ _describe 'repo' repos
23
+ }
24
+
25
+ _wtx_branches() {
26
+ local config_file root postfix branches
27
+ if [ -n "$XDG_CONFIG_HOME" ]; then
28
+ config_file="${XDG_CONFIG_HOME}/wtx/config.json"
29
+ else
30
+ config_file="${HOME}/.config/wtx/config.json"
31
+ fi
32
+ branches=()
33
+ if [ -f "$config_file" ] && command -v jq >/dev/null 2>&1; then
34
+ root=$(jq -r '.root' "$config_file" 2>/dev/null)
35
+ root="${root/#\~/$HOME}"
36
+ for repo in $(jq -r '.repos | keys[]' "$config_file" 2>/dev/null); do
37
+ if [ -d "${root}/${repo}" ]; then
38
+ branches+=($(git -C "${root}/${repo}" worktree list --porcelain 2>/dev/null | \
39
+ grep '^branch refs/heads/' | sed 's|^branch refs/heads/||'))
40
+ fi
41
+ done
42
+ fi
43
+ _describe 'branch' branches
44
+ }
45
+
46
+ _wtx() {
47
+ local context state line
48
+ typeset -A opt_args
49
+
50
+ _arguments -C \
51
+ '1: :->subcommand' \
52
+ '*::: :->args'
53
+
54
+ case $state in
55
+ subcommand)
56
+ _values 'wtx command' \
57
+ 'config[Manage configuration]' \
58
+ 'create[Create worktrees]' \
59
+ 'remove[Remove worktrees]' \
60
+ 'prune[Remove worktrees with merged PRs]' \
61
+ 'open[Open worktree in IDE]' \
62
+ 'rebase[Fetch and rebase vs main]' \
63
+ 'pull[Fetch a PR and create its worktree]' \
64
+ 'fetch[Fetch origin main]' \
65
+ 'sync[Re-copy sync files and run post_sync]' \
66
+ 'deps[Manage node_modules strategy]' \
67
+ 'ls[List worktrees with status]' \
68
+ 'cd[Change directory to worktree]' \
69
+ 'status[Show worktree status]' \
70
+ 'prs[Show pull request status across worktrees]' \
71
+ 'init[Output shell integration code]' \
72
+ 'skill[Manage AI agent skills]' \
73
+ 'mcp[Run MCP server exposing worktree tools]' \
74
+ 'exec[Execute commands across worktrees]'
75
+ ;;
76
+
77
+ args)
78
+ case ${line[1]} in
79
+ config) _wtx_config ;;
80
+ skill) _wtx_skill ;;
81
+ init) _values 'shell' 'bash' 'zsh' 'fish' ;;
82
+ create)
83
+ _arguments \
84
+ ':branch:' \
85
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
86
+ '--base[Base ref]:ref:(main master develop dev)' \
87
+ {-o,--open}'[Open worktree(s) in IDE after creation]' \
88
+ '--ide[IDE to open with]:editor:(cursor code vscode idea webstorm zed vim nvim emacs)' \
89
+ '--track[Track remote branch even if it belongs to someone else]' \
90
+ '--agent[AI agent to delegate work to]:agent:' \
91
+ '--prompt[Prompt for AI agent]:prompt:' \
92
+ {-q,--quiet}'[Suppress output]' \
93
+ '--verbose[Show git commands]' \
94
+ '--dry-run[Show what would happen]'
95
+ ;;
96
+ remove)
97
+ _arguments \
98
+ ':branch:_wtx_branches' \
99
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
100
+ {-f,--force}'[Force removal]' \
101
+ {-y,--yes}'[Skip confirmation prompt]' \
102
+ {-q,--quiet}'[Suppress output]' \
103
+ '--verbose[Show git commands]' \
104
+ '--dry-run[Show what would happen]'
105
+ ;;
106
+ prune)
107
+ _arguments \
108
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
109
+ {-f,--force}'[Force removal]' \
110
+ {-y,--yes}'[Skip confirmation prompt]' \
111
+ {-q,--quiet}'[Suppress output]' \
112
+ '--verbose[Show git commands]' \
113
+ '--dry-run[Show what would happen]'
114
+ ;;
115
+ open)
116
+ _arguments \
117
+ ':branch:_wtx_branches' \
118
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
119
+ '--ide[IDE to open with]:editor:(cursor code vscode idea webstorm zed vim nvim emacs)' \
120
+ {-q,--quiet}'[Suppress output]' \
121
+ '--verbose[Show git commands]' \
122
+ '--dry-run[Show what would happen]'
123
+ ;;
124
+ rebase)
125
+ _arguments \
126
+ ':branch:_wtx_branches' \
127
+ '--repo[Target specific repo(s)]:repo:_wtx_repos' \
128
+ {-q,--quiet}'[Suppress output]' \
129
+ '--verbose[Show git commands]' \
130
+ '--dry-run[Show what would happen]'
131
+ ;;
132
+ pull)
133
+ _arguments \
134
+ ':pr-link:' \
135
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
136
+ {-q,--quiet}'[Suppress output]' \
137
+ '--verbose[Show git commands]' \
138
+ '--dry-run[Show what would happen]'
139
+ ;;
140
+ fetch)
141
+ _arguments \
142
+ '--repo[Target specific repo(s)]:repo:_wtx_repos' \
143
+ {-q,--quiet}'[Suppress output]' \
144
+ '--verbose[Show git commands]' \
145
+ '--dry-run[Show what would happen]'
146
+ ;;
147
+ sync)
148
+ _arguments \
149
+ ':branch:_wtx_branches' \
150
+ '--repo[Target specific repo(s)]:repo:_wtx_repos' \
151
+ {-q,--quiet}'[Suppress output]' \
152
+ '--verbose[Show git commands]' \
153
+ '--dry-run[Show what would happen]'
154
+ ;;
155
+ deps)
156
+ _arguments \
157
+ '::branch:_wtx_branches' \
158
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
159
+ '--install[Switch to independent node_modules]' \
160
+ '--symlink[Switch to symlinked node_modules]' \
161
+ '--json[Output machine-readable JSON]' \
162
+ {-q,--quiet}'[Suppress output]' \
163
+ '--verbose[Show git commands]' \
164
+ '--dry-run[Show what would happen]'
165
+ ;;
166
+ ls)
167
+ _arguments \
168
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
169
+ '--pr[Include pull request status column]' \
170
+ '--json[Output machine-readable JSON]' \
171
+ {-q,--quiet}'[Suppress output]' \
172
+ '--verbose[Show git commands]' \
173
+ '--dry-run[Show what would happen]'
174
+ ;;
175
+ cd)
176
+ _arguments \
177
+ ':repo:_wtx_repos' \
178
+ ':branch:_wtx_branches'
179
+ ;;
180
+ status)
181
+ _arguments \
182
+ ':branch:_wtx_branches' \
183
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
184
+ '--json[Output machine-readable JSON]' \
185
+ {-q,--quiet}'[Suppress output]' \
186
+ '--verbose[Show git commands]' \
187
+ '--dry-run[Show what would happen]'
188
+ ;;
189
+ prs)
190
+ _arguments \
191
+ {-r,--repo}'[Target specific repo(s)]:repo:_wtx_repos' \
192
+ '--json[Output machine-readable JSON]' \
193
+ '--all[Include drafts and closed/merged PRs]' \
194
+ {-q,--quiet}'[Suppress output]' \
195
+ '--verbose[Show git commands]' \
196
+ '--dry-run[Show what would happen]'
197
+ ;;
198
+ esac
199
+ ;;
200
+ esac
201
+ }
202
+
203
+ _wtx_config() {
204
+ local context state line
205
+ typeset -A opt_args
206
+
207
+ _arguments -C \
208
+ '1: :->config_subcommand' \
209
+ '*::: :->args'
210
+
211
+ case $state in
212
+ config_subcommand)
213
+ _values 'config subcommand' \
214
+ 'init[Initialize configuration]' \
215
+ 'show[Show current configuration]' \
216
+ 'set[Set a configuration key]' \
217
+ 'add-repo[Add or update a repo]' \
218
+ 'remove-repo[Remove a repo]'
219
+ ;;
220
+ args)
221
+ case ${line[1]} in
222
+ set)
223
+ _arguments \
224
+ ':key:(root postfix ide default_main_branch)' \
225
+ ':value:'
226
+ ;;
227
+ add-repo)
228
+ _arguments \
229
+ ':name:' \
230
+ '--sync-files[Files to sync]:files:' \
231
+ '--post-create[Post-create commands]:cmds:' \
232
+ '--post-sync[Post-sync commands]:cmds:'
233
+ ;;
234
+ remove-repo)
235
+ _arguments \
236
+ ':repo:_wtx_repos'
237
+ ;;
238
+ esac
239
+ ;;
240
+ esac
241
+ }
242
+
243
+ _wtx_skill() {
244
+ local context state line
245
+ typeset -A opt_args
246
+
247
+ _arguments -C \
248
+ '1: :->skill_subcommand' \
249
+ '*::: :->args'
250
+
251
+ case $state in
252
+ skill_subcommand)
253
+ _values 'skill subcommand' \
254
+ 'show[Show skill content]' \
255
+ 'path[Show skill file path]' \
256
+ 'list[List available skills]'
257
+ ;;
258
+ args)
259
+ case ${line[1]} in
260
+ show|path)
261
+ _values 'skill' 'opencode' 'cursor' 'claude'
262
+ ;;
263
+ esac
264
+ ;;
265
+ esac
266
+ }
267
+
268
+ _wtx "$@"