@cestoliv/wt 0.4.0 → 0.4.1-pr19.g680264b

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 CHANGED
@@ -90,12 +90,22 @@ MY-PROJECT
90
90
  feat/dashboard ~/dev/my-project-feat-dashboard
91
91
  wip: add chart component (1d ago)
92
92
 
93
- ↕ navigate · Enter open · D delete · C create · Q quit
93
+ ↕ navigate · Enter open · D delete · C create · A agent · Q quit
94
94
  ```
95
95
 
96
96
  Type to fuzzy-filter branches instantly. Inside a repo it shows that repo's
97
- worktrees (and `C` creates one); run it outside any repo to browse worktrees
98
- across all registered repos.
97
+ worktrees; run it outside any repo ("home") to browse worktrees across all
98
+ registered repos.
99
+
100
+ `C` creates a worktree and `A` creates one and starts an AI agent in it — both
101
+ work from anywhere and are step-by-step wizards. Run from home and they first
102
+ prompt for the repo, then the branch (`C` stops there); `A` adds a plan prompt
103
+ and a permission mode — **worktree (repo → branch) → plan prompt → permission
104
+ mode**. Pressing `Esc` steps back to the previous question (answers preserved),
105
+ or back to the list from the first step. After creating, the list **refreshes
106
+ and stays open** (preserving your search and cursor) instead of exiting — only
107
+ `Enter` and `Q`/`Esc` leave the TUI. Note that `a`/`c`/`d` are command keys, so
108
+ they can't be typed into the search box.
99
109
 
100
110
  ## Create — `wt create [branch]`
101
111
 
package/SKILL.md CHANGED
@@ -15,12 +15,31 @@ Launch the interactive TUI. Shows worktrees for the current repo (repo mode) or
15
15
 
16
16
  **Keybindings in the TUI:**
17
17
 
18
- - Arrow keys / `j`/`k` — navigate
19
- - `Enter` — open worktree in IDE
20
- - `d` — delete worktree
21
- - `c` — create new worktree (repo mode only)
22
- - `/`search
23
- - `q` / `Esc` — quit
18
+ - Arrow keys — navigate
19
+ - `Enter` — open worktree in IDE (exits the TUI)
20
+ - `D` — delete worktree
21
+ - `C` — create a new worktree (works in both repo and global mode)
22
+ - `A`create a worktree and start an AI agent in it (works in both modes)
23
+ - type to search · `Backspace` — edit search
24
+ - `Q` / `Esc` — quit
25
+
26
+ `C` and `A` are step-by-step wizards. In global mode (run from outside a repo /
27
+ "home") they start by prompting for the repo (picker), then the branch; in repo
28
+ mode the repo is fixed so they start at the branch. `A` then adds two more
29
+ steps:
30
+
31
+ - `C` — **worktree (repo → branch)**
32
+ - `A` — **worktree (repo → branch) → plan prompt → permission mode**
33
+
34
+ Pressing `Esc` at any step goes back to the previous step (your earlier answers
35
+ are preserved); pressing `Esc` on the first step returns to the list.
36
+
37
+ After a create or agent action the TUI **refreshes and stays open** on the list
38
+ (your search and cursor are preserved) rather than exiting — only `Enter` (open)
39
+ and `Q`/`Esc` exit.
40
+
41
+ Because `a`/`A`, `c`/`C`, and `d`/`D` are reserved as command keys, those
42
+ letters can't be typed into the search box.
24
43
 
25
44
  ### `wt create [branch]`
26
45
 
@@ -3,8 +3,8 @@ import {
3
3
  openConfiguredIde,
4
4
  prepareWorktree,
5
5
  promptExistingWorktree
6
- } from "./chunk-ASVHQXDJ.js";
7
- import "./chunk-E2IOE23G.js";
6
+ } from "./chunk-QGSJG72F.js";
7
+ import "./chunk-GHYUCETL.js";
8
8
  import "./chunk-FNAMNRUH.js";
9
9
 
10
10
  // src/commands/agent.ts
@@ -538,5 +538,6 @@ function reportTriggerFailure(result, chord) {
538
538
  );
539
539
  }
540
540
  export {
541
+ VALID_MODES,
541
542
  createAgentWorktree
542
543
  };
@@ -253,37 +253,56 @@ function shortenPath(p) {
253
253
  const home = process.env.HOME ?? "";
254
254
  return home && p.startsWith(home) ? `~${p.slice(home.length)}` : p;
255
255
  }
256
- function renderList(items, selectedIndex, query, mode) {
257
- const lines = [];
256
+ function buildListLayout(items, selectedIndex, query, mode) {
257
+ const header = [];
258
258
  if (mode === "global") {
259
- lines.push(
259
+ header.push(
260
260
  pc.dim("\u2139 Not in a git repository \u2014 showing all registered worktrees")
261
261
  );
262
- lines.push("");
262
+ header.push("");
263
263
  }
264
- lines.push(pc.cyan(`> ${query}_`));
265
- lines.push("");
264
+ header.push(pc.cyan(`> ${query}_`));
265
+ const body = [];
266
+ const itemSpans = [];
266
267
  const groups = groupByRepo(items);
267
268
  let i = 0;
268
269
  for (const [repoPath, groupItems] of groups) {
269
- lines.push(pc.bold(path2.basename(repoPath).toUpperCase()));
270
+ body.push(pc.bold(path2.basename(repoPath).toUpperCase()));
270
271
  for (const item of groupItems) {
272
+ const start = body.length;
271
273
  const cursor = i === selectedIndex ? pc.cyan("\u25B6") : " ";
272
274
  const branchLabel = item.isCurrent ? pc.dim(`${item.branch} (current)`) : pc.white(item.branch);
273
275
  const pathLabel = pc.dim(shortenPath(item.path));
274
- lines.push(` ${cursor} ${branchLabel} ${pathLabel}`);
276
+ body.push(` ${cursor} ${branchLabel} ${pathLabel}`);
275
277
  if (item.lastCommit) {
276
- lines.push(` ${pc.dim(item.lastCommit)}`);
278
+ body.push(` ${pc.dim(item.lastCommit)}`);
277
279
  }
280
+ itemSpans[i] = { start, end: body.length - 1 };
278
281
  i++;
279
282
  }
280
283
  }
281
- lines.push("");
282
- const createHint = mode === "repo" ? " \xB7 C create" : "";
283
- lines.push(
284
- pc.dim(`\u2195 navigate \xB7 Enter open \xB7 D delete${createHint} \xB7 Q quit`)
285
- );
286
- return lines.join("\n");
284
+ const footer = [
285
+ pc.dim("\u2195 navigate \xB7 Enter open \xB7 D delete \xB7 C create \xB7 A agent \xB7 Q quit")
286
+ ];
287
+ return { header, body, footer, itemSpans };
288
+ }
289
+ function clampScroll(offset, span, viewportHeight, bodyLength) {
290
+ const maxOffset = Math.max(0, bodyLength - viewportHeight);
291
+ let next = offset;
292
+ if (span.start < next) next = span.start;
293
+ if (span.end >= next + viewportHeight) next = span.end - viewportHeight + 1;
294
+ return Math.max(0, Math.min(next, maxOffset));
295
+ }
296
+ function composeView(layout, offset, viewportHeight) {
297
+ const { header, body, footer } = layout;
298
+ const visible = body.slice(offset, offset + viewportHeight);
299
+ while (visible.length < viewportHeight) visible.push("");
300
+ const topSlot = offset > 0 ? pc.dim(" \u2191 more") : "";
301
+ const bottomSlot = offset + viewportHeight < body.length ? pc.dim(" \u2193 more") : "";
302
+ return [...header, topSlot, ...visible, bottomSlot, ...footer].join("\n");
303
+ }
304
+ function fixedHeight(layout) {
305
+ return layout.header.length + layout.footer.length + 2;
287
306
  }
288
307
  function setupRawMode() {
289
308
  process.stdin.setRawMode(true);
@@ -311,12 +330,12 @@ function renderRepoPicker(repos, selectedIndex, query) {
311
330
  lines.push(pc.dim("\u2195 navigate \xB7 Enter select \xB7 Q quit"));
312
331
  return lines.join("\n");
313
332
  }
314
- async function runRepoPicker(repos) {
333
+ async function runRepoPicker(repos, initialRepo) {
315
334
  const filterRepos = (all, q) => q ? all.filter(
316
335
  (p) => path2.basename(p).toLowerCase().includes(q.toLowerCase())
317
336
  ) : all;
318
337
  let query = "";
319
- let selectedIndex = 0;
338
+ let selectedIndex = initialRepo ? Math.max(0, repos.indexOf(initialRepo)) : 0;
320
339
  let filtered = repos;
321
340
  const render = () => {
322
341
  process.stdout.write("\x1B[2J\x1B[H");
@@ -388,8 +407,8 @@ function renderBranchInput(repoName, branch, error) {
388
407
  lines.push(pc.dim("Enter confirm \xB7 Esc cancel"));
389
408
  return lines.join("\n");
390
409
  }
391
- async function runBranchInput(repoRoot) {
392
- let branch = "";
410
+ async function runBranchInput(repoRoot, initial = "") {
411
+ let branch = initial;
393
412
  let error;
394
413
  const repoName = path2.basename(repoRoot);
395
414
  const render = () => {
@@ -432,13 +451,35 @@ async function runBranchInput(repoRoot) {
432
451
  process.stdin.on("data", onData);
433
452
  });
434
453
  }
454
+ async function runWizard(steps) {
455
+ let i = 0;
456
+ while (i < steps.length) {
457
+ if (await steps[i]()) {
458
+ i++;
459
+ } else if (--i < 0) {
460
+ return false;
461
+ }
462
+ }
463
+ return true;
464
+ }
435
465
  async function runInteractiveList(allItems, mode, handlers) {
436
466
  let query = "";
437
467
  let selectedIndex = 0;
468
+ let scrollOffset = 0;
438
469
  let filtered = allItems;
439
470
  const render = () => {
471
+ const rows = process.stdout.rows ?? 24;
472
+ const layout = buildListLayout(filtered, selectedIndex, query, mode);
473
+ const viewport = Math.max(1, rows - fixedHeight(layout));
474
+ const span = layout.itemSpans[selectedIndex] ?? { start: 0, end: 0 };
475
+ scrollOffset = clampScroll(
476
+ scrollOffset,
477
+ span,
478
+ viewport,
479
+ layout.body.length
480
+ );
440
481
  process.stdout.write("\x1B[2J\x1B[H");
441
- process.stdout.write(renderList(filtered, selectedIndex, query, mode));
482
+ process.stdout.write(composeView(layout, scrollOffset, viewport));
442
483
  };
443
484
  setupRawMode();
444
485
  render();
@@ -447,11 +488,13 @@ async function runInteractiveList(allItems, mode, handlers) {
447
488
  const attachListener = () => {
448
489
  if (!listenerActive) {
449
490
  process.stdin.on("data", onData);
491
+ process.stdout.on("resize", render);
450
492
  listenerActive = true;
451
493
  }
452
494
  };
453
495
  const detachListener = () => {
454
496
  process.stdin.removeListener("data", onData);
497
+ process.stdout.removeListener("resize", render);
455
498
  listenerActive = false;
456
499
  };
457
500
  const onData = async (key) => {
@@ -499,25 +542,42 @@ async function runInteractiveList(allItems, mode, handlers) {
499
542
  render();
500
543
  }
501
544
  } else if (key === "c" || key === "C") {
502
- if (mode === "repo") {
503
- detachListener();
504
- cleanupRawMode();
505
- await handlers.onCreate();
506
- resolve();
507
- } else {
508
- process.stdout.write(
509
- pc.dim("\ncd into a repo first to create a worktree.\n")
510
- );
511
- }
545
+ detachListener();
546
+ cleanupRawMode();
547
+ await handlers.onCreate();
548
+ allItems = await handlers.refreshItems();
549
+ filtered = filterItems(allItems, query);
550
+ selectedIndex = Math.min(
551
+ selectedIndex,
552
+ Math.max(0, filtered.length - 1)
553
+ );
554
+ setupRawMode();
555
+ attachListener();
556
+ render();
557
+ } else if (key === "a" || key === "A") {
558
+ detachListener();
559
+ cleanupRawMode();
560
+ await handlers.onAgent();
561
+ allItems = await handlers.refreshItems();
562
+ filtered = filterItems(allItems, query);
563
+ selectedIndex = Math.min(
564
+ selectedIndex,
565
+ Math.max(0, filtered.length - 1)
566
+ );
567
+ setupRawMode();
568
+ attachListener();
569
+ render();
512
570
  } else if (key === "\x7F") {
513
571
  query = query.slice(0, -1);
514
572
  filtered = filterItems(allItems, query);
515
573
  selectedIndex = 0;
574
+ scrollOffset = 0;
516
575
  render();
517
576
  } else if (key.length === 1 && key >= " ") {
518
577
  query += key;
519
578
  filtered = filterItems(allItems, query);
520
579
  selectedIndex = 0;
580
+ scrollOffset = 0;
521
581
  render();
522
582
  }
523
583
  } catch (err) {
@@ -546,5 +606,6 @@ export {
546
606
  runCommands,
547
607
  runRepoPicker,
548
608
  runBranchInput,
609
+ runWizard,
549
610
  runInteractiveList
550
611
  };
@@ -13,7 +13,7 @@ import {
13
13
  runCommands,
14
14
  runRepoPicker,
15
15
  setUpstreamTracking
16
- } from "./chunk-E2IOE23G.js";
16
+ } from "./chunk-GHYUCETL.js";
17
17
  import {
18
18
  createStore,
19
19
  getEffectiveConfig
package/dist/cli.js CHANGED
@@ -3,12 +3,12 @@
3
3
  // src/cli.ts
4
4
  import { Command } from "commander";
5
5
  var program = new Command();
6
- program.name("wt").description("Git worktree manager").version("0.4.0").action(async () => {
7
- const { runList } = await import("./list-HIKXMDHJ.js");
6
+ program.name("wt").description("Git worktree manager").version("0.4.1-pr19.g680264b").action(async () => {
7
+ const { runList } = await import("./list-XHV4ODXW.js");
8
8
  await runList();
9
9
  });
10
10
  program.command("create [branch]").description("Create a new worktree").action(async (branch) => {
11
- const { createWorktree } = await import("./create-YBHDJOP5.js");
11
+ const { createWorktree } = await import("./create-XKF574AL.js");
12
12
  await createWorktree(branch);
13
13
  });
14
14
  program.command("agent <branch> <plan_prompt>").description("Create a worktree and auto-start an AI agent in Zed (macOS)").option(
@@ -17,21 +17,21 @@ program.command("agent <branch> <plan_prompt>").description("Create a worktree a
17
17
  "plan"
18
18
  ).action(
19
19
  async (branch, planPrompt, options) => {
20
- const { createAgentWorktree } = await import("./agent-WO3XIT4H.js");
20
+ const { createAgentWorktree } = await import("./agent-Z3YCY245.js");
21
21
  await createAgentWorktree(branch, planPrompt, { mode: options.mode });
22
22
  }
23
23
  );
24
24
  program.command("config").description("Open the config file in $EDITOR").option("--path", "Print the config file path and exit").action(async (options) => {
25
25
  if (options.path) {
26
- const { printConfigPath } = await import("./config-DBM7HJE4.js");
26
+ const { printConfigPath } = await import("./config-RFATE2PF.js");
27
27
  printConfigPath();
28
28
  } else {
29
- const { openConfig } = await import("./config-DBM7HJE4.js");
29
+ const { openConfig } = await import("./config-RFATE2PF.js");
30
30
  openConfig();
31
31
  }
32
32
  });
33
33
  program.command("skill").description("Print the wt skill file to stdout").action(async () => {
34
- const { printSkill } = await import("./skill-FEUVQMK6.js");
34
+ const { printSkill } = await import("./skill-MVKLVB5V.js");
35
35
  printSkill();
36
36
  });
37
37
  await program.parseAsync(process.argv);
@@ -19,6 +19,7 @@ function openConfig(cwd) {
19
19
  process.exit(1);
20
20
  });
21
21
  child.on("close", (code) => process.exit(code ?? 0));
22
+ return child;
22
23
  }
23
24
  export {
24
25
  openConfig,
@@ -4,8 +4,8 @@ import {
4
4
  openConfiguredIde,
5
5
  prepareWorktree,
6
6
  promptExistingWorktree
7
- } from "./chunk-ASVHQXDJ.js";
8
- import "./chunk-E2IOE23G.js";
7
+ } from "./chunk-QGSJG72F.js";
8
+ import "./chunk-GHYUCETL.js";
9
9
  import "./chunk-FNAMNRUH.js";
10
10
  export {
11
11
  createWorktree,
@@ -7,9 +7,12 @@ import {
7
7
  openIde,
8
8
  registerRepo,
9
9
  removeWorktree,
10
+ runBranchInput,
10
11
  runCommands,
11
- runInteractiveList
12
- } from "./chunk-E2IOE23G.js";
12
+ runInteractiveList,
13
+ runRepoPicker,
14
+ runWizard
15
+ } from "./chunk-GHYUCETL.js";
13
16
  import {
14
17
  createStore,
15
18
  getEffectiveConfig
@@ -18,6 +21,28 @@ import {
18
21
  // src/commands/list.ts
19
22
  import * as clack from "@clack/prompts";
20
23
  import pc from "picocolors";
24
+ function buildWorktreeSteps(repoRoot, store, state) {
25
+ const steps = [];
26
+ if (!repoRoot) {
27
+ const repos = getRegisteredRepos(store);
28
+ steps.push(async () => {
29
+ const picked = await runRepoPicker(repos, state.pickedRepo);
30
+ if (!picked) return false;
31
+ state.pickedRepo = picked;
32
+ return true;
33
+ });
34
+ }
35
+ steps.push(async () => {
36
+ const entered = await runBranchInput(
37
+ state.pickedRepo,
38
+ state.branch ?? ""
39
+ );
40
+ if (!entered) return false;
41
+ state.branch = entered;
42
+ return true;
43
+ });
44
+ return steps;
45
+ }
21
46
  async function prepareListItems(options = {}) {
22
47
  const { cwd = process.cwd(), store = createStore() } = options;
23
48
  let repoRoot = null;
@@ -124,10 +149,52 @@ ${dirty.map((f) => ` ${f}`).join("\n")}`
124
149
  }
125
150
  },
126
151
  onCreate: async () => {
127
- if (repoRoot) {
128
- const { createWorktree } = await import("./create-YBHDJOP5.js");
129
- await createWorktree(void 0, { cwd: repoRoot, store });
130
- }
152
+ const state = { pickedRepo: repoRoot ?? void 0 };
153
+ const steps = buildWorktreeSteps(repoRoot, store, state);
154
+ if (!await runWizard(steps)) return;
155
+ if (state.pickedRepo === void 0 || state.branch === void 0) return;
156
+ const { createWorktree } = await import("./create-XKF574AL.js");
157
+ await createWorktree(state.branch, { cwd: state.pickedRepo, store });
158
+ },
159
+ onAgent: async () => {
160
+ const { createAgentWorktree, VALID_MODES } = await import("./agent-Z3YCY245.js");
161
+ const state = {
162
+ pickedRepo: repoRoot ?? void 0,
163
+ mode: "plan"
164
+ };
165
+ const steps = buildWorktreeSteps(repoRoot, store, state);
166
+ steps.push(async () => {
167
+ const entered = await clack.text({
168
+ message: "Plan prompt for the agent:",
169
+ initialValue: state.plan,
170
+ validate: (v) => !v || v.length === 0 ? "Required" : void 0
171
+ });
172
+ if (clack.isCancel(entered)) return false;
173
+ state.plan = entered;
174
+ return true;
175
+ });
176
+ steps.push(async () => {
177
+ const chosen = await clack.select({
178
+ message: "Permission mode:",
179
+ initialValue: state.mode,
180
+ options: VALID_MODES.map((m) => ({ value: String(m), label: m }))
181
+ });
182
+ if (clack.isCancel(chosen)) return false;
183
+ state.mode = chosen;
184
+ return true;
185
+ });
186
+ if (!await runWizard(steps)) return;
187
+ if (state.pickedRepo === void 0 || state.branch === void 0 || state.plan === void 0)
188
+ return;
189
+ await createAgentWorktree(state.branch, state.plan, {
190
+ cwd: state.pickedRepo,
191
+ store,
192
+ mode: state.mode
193
+ });
194
+ },
195
+ refreshItems: async () => {
196
+ const refreshed = await prepareListItems({ cwd, store });
197
+ return refreshed.items;
131
198
  }
132
199
  });
133
200
  }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/skill.ts
4
+ function printSkill() {
5
+ console.log('---\nname: wt-worktree-manager\ndescription: Use the wt CLI to create, browse, open, and delete git worktrees across repos. Use when the user asks to manage worktrees, create isolated branches, or configure worktree defaults.\n---\n\n# wt \u2014 Git Worktree Manager\n\n`wt` is a CLI for managing git worktrees. It provides an interactive TUI to browse, create, open in your IDE, and delete worktrees across multiple repos.\n\n## Commands\n\n### `wt` (no subcommand)\n\nLaunch the interactive TUI. Shows worktrees for the current repo (repo mode) or all registered repos (global mode, when run outside a repo).\n\n**Keybindings in the TUI:**\n\n- Arrow keys \u2014 navigate\n- `Enter` \u2014 open worktree in IDE (exits the TUI)\n- `D` \u2014 delete worktree\n- `C` \u2014 create a new worktree (works in both repo and global mode)\n- `A` \u2014 create a worktree and start an AI agent in it (works in both modes)\n- type to search \xB7 `Backspace` \u2014 edit search\n- `Q` / `Esc` \u2014 quit\n\n`C` and `A` are step-by-step wizards. In global mode (run from outside a repo /\n"home") they start by prompting for the repo (picker), then the branch; in repo\nmode the repo is fixed so they start at the branch. `A` then adds two more\nsteps:\n\n- `C` \u2014 **worktree (repo \u2192 branch)**\n- `A` \u2014 **worktree (repo \u2192 branch) \u2192 plan prompt \u2192 permission mode**\n\nPressing `Esc` at any step goes back to the previous step (your earlier answers\nare preserved); pressing `Esc` on the first step returns to the list.\n\nAfter a create or agent action the TUI **refreshes and stays open** on the list\n(your search and cursor are preserved) rather than exiting \u2014 only `Enter` (open)\nand `Q`/`Esc` exit.\n\nBecause `a`/`A`, `c`/`C`, and `d`/`D` are reserved as command keys, those\nletters can\'t be typed into the search box.\n\n### `wt create [branch]`\n\nCreate a new worktree. If `branch` is omitted, prompts interactively.\n\nThe worktree is created as a sibling directory to the repo: `<parent>/<repo-name>-<branch-name>`.\n\nAfter creation, `wt` runs any configured `setup_commands` and opens the worktree in your IDE.\n\nIf the worktree path already exists, `wt create` doesn\'t error \u2014 it prompts you\nto **open it in the IDE** or **quit**. (In a non-interactive shell it errors\nwith a non-zero exit instead of prompting.)\n\n### `wt agent <branch> <plan_prompt> [--mode <mode>]`\n\nCreate a worktree (same as `wt create`) **and** auto-start an AI agent in Zed\'s\nintegrated terminal, pre-filled with `<plan_prompt>` and left interactive for\nyou to take over.\n\n```bash\nwt agent feature/login \'Read the codebase, then propose a plan for login.\'\nwt agent feature/fix \'Fix the bug in payment processing\' --mode auto\nwt agent refactor/api \'Refactor the API layer\' --mode default\n```\n\nThe `--mode` flag sets Claude Code\'s permission mode (defaults to `plan`):\n\n- `default` \u2014 Standard interactive mode with approval for each action\n- `acceptEdits` \u2014 Allow file changes but keep command execution controlled\n- `plan` \u2014 Architecture-first mode with no surprise mutations (default)\n- `auto` \u2014 Claude\'s safety model makes decisions instead of prompting\n- `dontAsk` \u2014 Minimal interruptions in trusted environments\n- `bypassPermissions` \u2014 Skip all permission checks (dangerous, CI/sandbox only)\n\nIt writes a temporary `.zed/tasks.json` running\n`<agent_command> --permission-mode <mode> \'<plan_prompt>\'`, ensures a global Zed keymap chord\n(`agent_trigger_chord`) spawns that task, opens Zed, presses the chord via\n`osascript`, then removes the temporary task so the repo is left clean.\n\n**macOS + Zed only.** Requires Accessibility permission for the app that runs\n`wt` (Zed itself, when run from its integrated terminal). If it isn\'t granted,\n`wt agent` opens the _Privacy & Security \u2192 Accessibility_ settings pane and waits\nfor you to grant it and confirm, then retries automatically. On other platforms\n(or when `ide` is not `zed`) the worktree is still created and opened, but the\nagent is not auto-started.\n\nOver SSH it still works, provided the same user has an active graphical login on\nthe Mac: the keystroke is run inside the GUI session via Launch Services\n(`open -a Terminal` briefly flashes a Terminal window). Grant Accessibility to\nTerminal (not Zed) the first time. With no one logged in graphically there is\nnothing to drive, so it falls back to the manual "press the chord in Zed"\nmessage.\n\nIf the worktree path already exists, `wt agent` prompts you to **open it in the\nIDE**, **open it and start the agent**, or **quit** \u2014 instead of erroring. (In a\nnon-interactive shell it errors with a non-zero exit instead of prompting.)\n\n### `wt config`\n\nOpen the global config file in `$EDITOR` (defaults to `nano`).\n\n```bash\nwt config # open in editor\nwt config --path # print config file path only\n```\n\n### `wt skill`\n\nPrint this skill file to stdout. Useful for piping to agents or copying to a project.\n\n## Configuration\n\nConfig is stored as JSON. Get the path with `wt config --path`.\n\n### Schema\n\n| Key | Type | Default | Description |\n| --------------------- | ---------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `worktree_path` | `string` | `"../"` | Where to place new worktrees, relative to the repo root |\n| `base_branch` | `string` | `"origin/main"` | Branch to base new worktrees on |\n| `setup_commands` | `string[]` | `[]` | Commands to run in a new worktree after creation (e.g. `["npm install"]`) |\n| `teardown_commands` | `string[]` | `[]` | Commands to run in a worktree just before it is deleted (e.g. `["docker compose down -v"]`); on failure you are prompted whether to delete anyway |\n| `ide` | `string` | `"zed"` | IDE command to open worktrees with |\n| `ide_open_args` | `string[]` | `["-n"]` | Arguments passed to the IDE command |\n| `agent_command` | `string` | `"claude --permission-mode plan"` | Base command `wt agent` runs in Zed; any `--permission-mode` flag is replaced by the `--mode` option (defaults to `plan`), then `<plan_prompt>` is appended single-quoted |\n| `agent_trigger_chord` | `string` | `"ctrl-shift-cmd-c"` | Zed keymap chord `wt agent` installs/presses to spawn the agent task |\n| `repos` | `string[]` | `[]` | Registered repo paths (auto-populated on first use) |\n| `repo_overrides` | `object` | `{}` | Per-repo config overrides (see below) |\n\n### Per-repo overrides\n\nOverride any field (`worktree_path`, `base_branch`, `setup_commands`, `teardown_commands`, `ide`, `ide_open_args`, `agent_command`, `agent_trigger_chord`) for a specific repo:\n\n```json\n{\n "base_branch": "origin/main",\n "ide": "zed",\n "repo_overrides": {\n "/path/to/my-repo": {\n "base_branch": "origin/develop",\n "setup_commands": ["npm install", "npm run build"]\n }\n }\n}\n```\n\n## Common workflows\n\n### Create a worktree for a new feature\n\n```bash\ncd /path/to/repo\nwt create feature/my-branch\n```\n\n### Configure setup commands for a repo\n\n```bash\nwt config\n# Then add to the JSON:\n# "repo_overrides": {\n# "/path/to/repo": {\n# "setup_commands": ["npm install"]\n# }\n# }\n```\n\n### Browse all worktrees across repos\n\nRun `wt` from any directory outside a git repo to see worktrees from all registered repos.\n');
6
+ }
7
+ export {
8
+ printSkill
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cestoliv/wt",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-pr19.g680264b",
4
4
  "description": "Fast, interactive TUI to browse, create, open, and delete git worktrees across repos.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/commands/skill.ts
4
- function printSkill() {
5
- console.log('---\nname: wt-worktree-manager\ndescription: Use the wt CLI to create, browse, open, and delete git worktrees across repos. Use when the user asks to manage worktrees, create isolated branches, or configure worktree defaults.\n---\n\n# wt \u2014 Git Worktree Manager\n\n`wt` is a CLI for managing git worktrees. It provides an interactive TUI to browse, create, open in your IDE, and delete worktrees across multiple repos.\n\n## Commands\n\n### `wt` (no subcommand)\n\nLaunch the interactive TUI. Shows worktrees for the current repo (repo mode) or all registered repos (global mode, when run outside a repo).\n\n**Keybindings in the TUI:**\n\n- Arrow keys / `j`/`k` \u2014 navigate\n- `Enter` \u2014 open worktree in IDE\n- `d` \u2014 delete worktree\n- `c` \u2014 create new worktree (repo mode only)\n- `/` \u2014 search\n- `q` / `Esc` \u2014 quit\n\n### `wt create [branch]`\n\nCreate a new worktree. If `branch` is omitted, prompts interactively.\n\nThe worktree is created as a sibling directory to the repo: `<parent>/<repo-name>-<branch-name>`.\n\nAfter creation, `wt` runs any configured `setup_commands` and opens the worktree in your IDE.\n\nIf the worktree path already exists, `wt create` doesn\'t error \u2014 it prompts you\nto **open it in the IDE** or **quit**. (In a non-interactive shell it errors\nwith a non-zero exit instead of prompting.)\n\n### `wt agent <branch> <plan_prompt> [--mode <mode>]`\n\nCreate a worktree (same as `wt create`) **and** auto-start an AI agent in Zed\'s\nintegrated terminal, pre-filled with `<plan_prompt>` and left interactive for\nyou to take over.\n\n```bash\nwt agent feature/login \'Read the codebase, then propose a plan for login.\'\nwt agent feature/fix \'Fix the bug in payment processing\' --mode auto\nwt agent refactor/api \'Refactor the API layer\' --mode default\n```\n\nThe `--mode` flag sets Claude Code\'s permission mode (defaults to `plan`):\n\n- `default` \u2014 Standard interactive mode with approval for each action\n- `acceptEdits` \u2014 Allow file changes but keep command execution controlled\n- `plan` \u2014 Architecture-first mode with no surprise mutations (default)\n- `auto` \u2014 Claude\'s safety model makes decisions instead of prompting\n- `dontAsk` \u2014 Minimal interruptions in trusted environments\n- `bypassPermissions` \u2014 Skip all permission checks (dangerous, CI/sandbox only)\n\nIt writes a temporary `.zed/tasks.json` running\n`<agent_command> --permission-mode <mode> \'<plan_prompt>\'`, ensures a global Zed keymap chord\n(`agent_trigger_chord`) spawns that task, opens Zed, presses the chord via\n`osascript`, then removes the temporary task so the repo is left clean.\n\n**macOS + Zed only.** Requires Accessibility permission for the app that runs\n`wt` (Zed itself, when run from its integrated terminal). If it isn\'t granted,\n`wt agent` opens the _Privacy & Security \u2192 Accessibility_ settings pane and waits\nfor you to grant it and confirm, then retries automatically. On other platforms\n(or when `ide` is not `zed`) the worktree is still created and opened, but the\nagent is not auto-started.\n\nOver SSH it still works, provided the same user has an active graphical login on\nthe Mac: the keystroke is run inside the GUI session via Launch Services\n(`open -a Terminal` briefly flashes a Terminal window). Grant Accessibility to\nTerminal (not Zed) the first time. With no one logged in graphically there is\nnothing to drive, so it falls back to the manual "press the chord in Zed"\nmessage.\n\nIf the worktree path already exists, `wt agent` prompts you to **open it in the\nIDE**, **open it and start the agent**, or **quit** \u2014 instead of erroring. (In a\nnon-interactive shell it errors with a non-zero exit instead of prompting.)\n\n### `wt config`\n\nOpen the global config file in `$EDITOR` (defaults to `nano`).\n\n```bash\nwt config # open in editor\nwt config --path # print config file path only\n```\n\n### `wt skill`\n\nPrint this skill file to stdout. Useful for piping to agents or copying to a project.\n\n## Configuration\n\nConfig is stored as JSON. Get the path with `wt config --path`.\n\n### Schema\n\n| Key | Type | Default | Description |\n| --------------------- | ---------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `worktree_path` | `string` | `"../"` | Where to place new worktrees, relative to the repo root |\n| `base_branch` | `string` | `"origin/main"` | Branch to base new worktrees on |\n| `setup_commands` | `string[]` | `[]` | Commands to run in a new worktree after creation (e.g. `["npm install"]`) |\n| `teardown_commands` | `string[]` | `[]` | Commands to run in a worktree just before it is deleted (e.g. `["docker compose down -v"]`); on failure you are prompted whether to delete anyway |\n| `ide` | `string` | `"zed"` | IDE command to open worktrees with |\n| `ide_open_args` | `string[]` | `["-n"]` | Arguments passed to the IDE command |\n| `agent_command` | `string` | `"claude --permission-mode plan"` | Base command `wt agent` runs in Zed; any `--permission-mode` flag is replaced by the `--mode` option (defaults to `plan`), then `<plan_prompt>` is appended single-quoted |\n| `agent_trigger_chord` | `string` | `"ctrl-shift-cmd-c"` | Zed keymap chord `wt agent` installs/presses to spawn the agent task |\n| `repos` | `string[]` | `[]` | Registered repo paths (auto-populated on first use) |\n| `repo_overrides` | `object` | `{}` | Per-repo config overrides (see below) |\n\n### Per-repo overrides\n\nOverride any field (`worktree_path`, `base_branch`, `setup_commands`, `teardown_commands`, `ide`, `ide_open_args`, `agent_command`, `agent_trigger_chord`) for a specific repo:\n\n```json\n{\n "base_branch": "origin/main",\n "ide": "zed",\n "repo_overrides": {\n "/path/to/my-repo": {\n "base_branch": "origin/develop",\n "setup_commands": ["npm install", "npm run build"]\n }\n }\n}\n```\n\n## Common workflows\n\n### Create a worktree for a new feature\n\n```bash\ncd /path/to/repo\nwt create feature/my-branch\n```\n\n### Configure setup commands for a repo\n\n```bash\nwt config\n# Then add to the JSON:\n# "repo_overrides": {\n# "/path/to/repo": {\n# "setup_commands": ["npm install"]\n# }\n# }\n```\n\n### Browse all worktrees across repos\n\nRun `wt` from any directory outside a git repo to see worktrees from all registered repos.\n');
6
- }
7
- export {
8
- printSkill
9
- };