@cestoliv/wt 0.1.0-pr1.f956696 → 0.1.0-pr5.g8fa13c6
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 +47 -6
- package/SKILL.md +126 -0
- package/dist/agent-UUA7YKTS.js +330 -0
- package/dist/{create-42OYRFQF.js → chunk-D4BVSTNE.js} +30 -8
- package/dist/{chunk-25JVZOCI.js → chunk-FSARWOCW.js} +26 -7
- package/dist/{chunk-HIGP6FSR.js → chunk-IQWENLPW.js} +2 -0
- package/dist/cli.js +19 -6
- package/dist/{config-FRLXDMRY.js → config-OSNYQCZL.js} +6 -2
- package/dist/create-55SXEUZV.js +11 -0
- package/dist/{list-Q7CFJ66L.js → list-HO42YAEG.js} +3 -3
- package/dist/skill-CRAP2ALY.js +9 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -20,12 +20,10 @@ npm install -g @cestoliv/wt
|
|
|
20
20
|
|
|
21
21
|
### Pre-release builds
|
|
22
22
|
|
|
23
|
-
Add the `publish-dev` label to a PR to publish that branch
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
npm install -g @cestoliv/wt@dev
|
|
28
|
-
```
|
|
23
|
+
Add the `publish-dev` label to a PR to publish that branch as a unique,
|
|
24
|
+
pinned prerelease version (e.g. `0.1.0-pr12.gabc1234`). The exact install
|
|
25
|
+
command is posted as a comment on the PR. There is no rolling `dev` channel —
|
|
26
|
+
each build is a distinct version you install explicitly.
|
|
29
27
|
|
|
30
28
|
## Quick Start
|
|
31
29
|
|
|
@@ -33,7 +31,10 @@ npm install -g @cestoliv/wt@dev
|
|
|
33
31
|
# Inside any git repo
|
|
34
32
|
wt # Browse worktrees
|
|
35
33
|
wt create my-feat # Create a new worktree and open it in your IDE
|
|
34
|
+
wt agent my-feat 'Plan the feature' # Create + auto-start an AI agent in Zed (macOS)
|
|
36
35
|
wt config # Edit config in $EDITOR
|
|
36
|
+
wt config --path # Print config file path
|
|
37
|
+
wt skill # Print skill file (for AI agents)
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
## Usage
|
|
@@ -80,10 +81,48 @@ What happens:
|
|
|
80
81
|
|
|
81
82
|
Run outside a repo to pick from registered repos via an interactive picker.
|
|
82
83
|
|
|
84
|
+
### Start an AI agent — `wt agent <branch> <plan_prompt>` (macOS + Zed)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
wt agent feat/login 'Read the codebase, then propose a plan for login.'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Creates the worktree exactly like `wt create`, then auto-starts an AI agent
|
|
91
|
+
(default `claude --permission-mode plan`) in Zed's integrated terminal,
|
|
92
|
+
pre-filled with your prompt and left interactive for you to take over.
|
|
93
|
+
|
|
94
|
+
How it works:
|
|
95
|
+
|
|
96
|
+
1. Writes a temporary `.zed/tasks.json` running `<agent_command> '<plan_prompt>'`.
|
|
97
|
+
2. Ensures a global Zed keymap chord (`agent_trigger_chord`) spawns that task.
|
|
98
|
+
3. Opens Zed, then presses the chord via `osascript`.
|
|
99
|
+
4. Removes the temporary task afterwards, leaving the repo clean.
|
|
100
|
+
|
|
101
|
+
**Requirements:** macOS, Zed, and **Accessibility** permission for the app that
|
|
102
|
+
runs `wt` (Zed itself, when run from its integrated terminal). If it isn't
|
|
103
|
+
granted yet, `wt agent` detects this, opens *System Settings → Privacy &
|
|
104
|
+
Security → Accessibility* for you, and waits — grant it (you may need to quit and
|
|
105
|
+
reopen the app), confirm, and `wt` retries automatically. On other platforms (or
|
|
106
|
+
when `ide` is not `zed`), the worktree is still created and opened, but the agent
|
|
107
|
+
is not auto-started.
|
|
108
|
+
|
|
109
|
+
> Tip: trust the parent directory of your worktrees in Claude once (open it and
|
|
110
|
+
> accept the trust prompt) so every worktree created beneath it is trusted
|
|
111
|
+
> automatically and the agent starts hands-free.
|
|
112
|
+
|
|
83
113
|
### Edit config — `wt config`
|
|
84
114
|
|
|
85
115
|
Opens the config file in `$EDITOR`.
|
|
86
116
|
|
|
117
|
+
```bash
|
|
118
|
+
wt config # Open in editor
|
|
119
|
+
wt config --path # Print the config file path only
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Print skill file — `wt skill`
|
|
123
|
+
|
|
124
|
+
Prints the bundled skill documentation to stdout. Useful for piping to AI agents or copying into a project.
|
|
125
|
+
|
|
87
126
|
## Configuration
|
|
88
127
|
|
|
89
128
|
Config is stored at `~/Library/Preferences/wt-nodejs/config.json` (macOS).
|
|
@@ -111,6 +150,8 @@ Config is stored at `~/Library/Preferences/wt-nodejs/config.json` (macOS).
|
|
|
111
150
|
| `base_branch` | `"origin/main"` | Branch new worktrees are created from |
|
|
112
151
|
| `worktree_path` | `"../"` | Where worktrees are placed (relative to repo) |
|
|
113
152
|
| `setup_commands` | `[]` | Commands to run in new worktrees |
|
|
153
|
+
| `agent_command` | `"claude --permission-mode plan"` | Command `wt agent` runs in Zed (prompt appended) |
|
|
154
|
+
| `agent_trigger_chord` | `"ctrl-shift-cmd-c"` | Zed keymap chord `wt agent` installs/presses |
|
|
114
155
|
| `repo_overrides` | `{}` | Per-repo overrides for any of the above |
|
|
115
156
|
|
|
116
157
|
## License
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wt-worktree-manager
|
|
3
|
+
description: 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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# wt — Git Worktree Manager
|
|
7
|
+
|
|
8
|
+
`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.
|
|
9
|
+
|
|
10
|
+
## Commands
|
|
11
|
+
|
|
12
|
+
### `wt` (no subcommand)
|
|
13
|
+
|
|
14
|
+
Launch the interactive TUI. Shows worktrees for the current repo (repo mode) or all registered repos (global mode, when run outside a repo).
|
|
15
|
+
|
|
16
|
+
**Keybindings in the TUI:**
|
|
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
|
|
24
|
+
|
|
25
|
+
### `wt create [branch]`
|
|
26
|
+
|
|
27
|
+
Create a new worktree. If `branch` is omitted, prompts interactively.
|
|
28
|
+
|
|
29
|
+
The worktree is created as a sibling directory to the repo: `<parent>/<repo-name>-<branch-name>`.
|
|
30
|
+
|
|
31
|
+
After creation, `wt` runs any configured `setup_commands` and opens the worktree in your IDE.
|
|
32
|
+
|
|
33
|
+
### `wt agent <branch> <plan_prompt>`
|
|
34
|
+
|
|
35
|
+
Create a worktree (same as `wt create`) **and** auto-start an AI agent in Zed's
|
|
36
|
+
integrated terminal, pre-filled with `<plan_prompt>` and left interactive for
|
|
37
|
+
you to take over.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
wt agent feature/login 'Read the codebase, then propose a plan for login.'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
It writes a temporary `.zed/tasks.json` running
|
|
44
|
+
`<agent_command> '<plan_prompt>'`, ensures a global Zed keymap chord
|
|
45
|
+
(`agent_trigger_chord`) spawns that task, opens Zed, presses the chord via
|
|
46
|
+
`osascript`, then removes the temporary task so the repo is left clean.
|
|
47
|
+
|
|
48
|
+
**macOS + Zed only.** Requires Accessibility permission for the app that runs
|
|
49
|
+
`wt` (Zed itself, when run from its integrated terminal). If it isn't granted,
|
|
50
|
+
`wt agent` opens the *Privacy & Security → Accessibility* settings pane and waits
|
|
51
|
+
for you to grant it and confirm, then retries automatically. On other platforms
|
|
52
|
+
(or when `ide` is not `zed`) the worktree is still created and opened, but the
|
|
53
|
+
agent is not auto-started.
|
|
54
|
+
|
|
55
|
+
### `wt config`
|
|
56
|
+
|
|
57
|
+
Open the global config file in `$EDITOR` (defaults to `nano`).
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
wt config # open in editor
|
|
61
|
+
wt config --path # print config file path only
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `wt skill`
|
|
65
|
+
|
|
66
|
+
Print this skill file to stdout. Useful for piping to agents or copying to a project.
|
|
67
|
+
|
|
68
|
+
## Configuration
|
|
69
|
+
|
|
70
|
+
Config is stored as JSON. Get the path with `wt config --path`.
|
|
71
|
+
|
|
72
|
+
### Schema
|
|
73
|
+
|
|
74
|
+
| Key | Type | Default | Description |
|
|
75
|
+
| ---------------- | ---------- | --------------- | ------------------------------------------------------------------------- |
|
|
76
|
+
| `worktree_path` | `string` | `"../"` | Where to place new worktrees, relative to the repo root |
|
|
77
|
+
| `base_branch` | `string` | `"origin/main"` | Branch to base new worktrees on |
|
|
78
|
+
| `setup_commands` | `string[]` | `[]` | Commands to run in a new worktree after creation (e.g. `["npm install"]`) |
|
|
79
|
+
| `ide` | `string` | `"zed"` | IDE command to open worktrees with |
|
|
80
|
+
| `ide_open_args` | `string[]` | `["-n"]` | Arguments passed to the IDE command |
|
|
81
|
+
| `agent_command` | `string` | `"claude --permission-mode plan"` | Command `wt agent` runs in Zed; `<plan_prompt>` is appended single-quoted |
|
|
82
|
+
| `agent_trigger_chord` | `string` | `"ctrl-shift-cmd-c"` | Zed keymap chord `wt agent` installs/presses to spawn the agent task |
|
|
83
|
+
| `repos` | `string[]` | `[]` | Registered repo paths (auto-populated on first use) |
|
|
84
|
+
| `repo_overrides` | `object` | `{}` | Per-repo config overrides (see below) |
|
|
85
|
+
|
|
86
|
+
### Per-repo overrides
|
|
87
|
+
|
|
88
|
+
Override any field (`worktree_path`, `base_branch`, `setup_commands`, `ide`, `ide_open_args`, `agent_command`, `agent_trigger_chord`) for a specific repo:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"base_branch": "origin/main",
|
|
93
|
+
"ide": "zed",
|
|
94
|
+
"repo_overrides": {
|
|
95
|
+
"/path/to/my-repo": {
|
|
96
|
+
"base_branch": "origin/develop",
|
|
97
|
+
"setup_commands": ["npm install", "npm run build"]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Common workflows
|
|
104
|
+
|
|
105
|
+
### Create a worktree for a new feature
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cd /path/to/repo
|
|
109
|
+
wt create feature/my-branch
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Configure setup commands for a repo
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
wt config
|
|
116
|
+
# Then add to the JSON:
|
|
117
|
+
# "repo_overrides": {
|
|
118
|
+
# "/path/to/repo": {
|
|
119
|
+
# "setup_commands": ["npm install"]
|
|
120
|
+
# }
|
|
121
|
+
# }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Browse all worktrees across repos
|
|
125
|
+
|
|
126
|
+
Run `wt` from any directory outside a git repo to see worktrees from all registered repos.
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
prepareWorktree
|
|
4
|
+
} from "./chunk-D4BVSTNE.js";
|
|
5
|
+
import {
|
|
6
|
+
openIde
|
|
7
|
+
} from "./chunk-FSARWOCW.js";
|
|
8
|
+
import "./chunk-IQWENLPW.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/agent.ts
|
|
11
|
+
import * as clack from "@clack/prompts";
|
|
12
|
+
import pc from "picocolors";
|
|
13
|
+
|
|
14
|
+
// src/lib/zed.ts
|
|
15
|
+
import { spawn } from "child_process";
|
|
16
|
+
import {
|
|
17
|
+
copyFileSync,
|
|
18
|
+
existsSync,
|
|
19
|
+
mkdirSync,
|
|
20
|
+
readdirSync,
|
|
21
|
+
readFileSync,
|
|
22
|
+
rmSync,
|
|
23
|
+
writeFileSync
|
|
24
|
+
} from "fs";
|
|
25
|
+
import { homedir } from "os";
|
|
26
|
+
import { dirname, join } from "path";
|
|
27
|
+
var AGENT_TASK_LABEL = "wt: agent";
|
|
28
|
+
function buildAgentTask(agentCommand, prompt, label) {
|
|
29
|
+
const escaped = prompt.replace(/'/g, "'\\''");
|
|
30
|
+
return {
|
|
31
|
+
label,
|
|
32
|
+
command: `${agentCommand} '${escaped}'`,
|
|
33
|
+
cwd: "$ZED_WORKTREE_ROOT",
|
|
34
|
+
use_new_terminal: true,
|
|
35
|
+
allow_concurrent_runs: false,
|
|
36
|
+
reveal: "always",
|
|
37
|
+
reveal_target: "dock",
|
|
38
|
+
shell: "system"
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function upsertTask(tasks, task) {
|
|
42
|
+
const idx = tasks.findIndex((t) => t.label === task.label);
|
|
43
|
+
if (idx === -1) return [...tasks, task];
|
|
44
|
+
const next = [...tasks];
|
|
45
|
+
next[idx] = task;
|
|
46
|
+
return next;
|
|
47
|
+
}
|
|
48
|
+
function removeTask(tasks, label) {
|
|
49
|
+
return tasks.filter((t) => t.label !== label);
|
|
50
|
+
}
|
|
51
|
+
function buildKeymapBinding(chord, label) {
|
|
52
|
+
return {
|
|
53
|
+
context: "Workspace",
|
|
54
|
+
bindings: { [chord]: ["task::Spawn", { task_name: label }] }
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function upsertKeymapBinding(keymap, chord, label) {
|
|
58
|
+
const target = buildKeymapBinding(chord, label);
|
|
59
|
+
const targetValue = JSON.stringify(target.bindings[chord]);
|
|
60
|
+
const already = keymap.some(
|
|
61
|
+
(e) => e.context === "Workspace" && e.bindings != null && JSON.stringify(e.bindings[chord]) === targetValue
|
|
62
|
+
);
|
|
63
|
+
if (already) return keymap;
|
|
64
|
+
return [...keymap, target];
|
|
65
|
+
}
|
|
66
|
+
var MODIFIER_MAP = {
|
|
67
|
+
ctrl: "control down",
|
|
68
|
+
control: "control down",
|
|
69
|
+
shift: "shift down",
|
|
70
|
+
cmd: "command down",
|
|
71
|
+
command: "command down",
|
|
72
|
+
super: "command down",
|
|
73
|
+
alt: "option down",
|
|
74
|
+
opt: "option down",
|
|
75
|
+
option: "option down"
|
|
76
|
+
};
|
|
77
|
+
function parseChord(chord) {
|
|
78
|
+
const parts = chord.split("-").map((p) => p.trim().toLowerCase()).filter(Boolean);
|
|
79
|
+
if (parts.length === 0) {
|
|
80
|
+
throw new Error(`Invalid chord: "${chord}"`);
|
|
81
|
+
}
|
|
82
|
+
const key = parts[parts.length - 1];
|
|
83
|
+
const modifiers = parts.slice(0, -1).map((m) => {
|
|
84
|
+
const mapped = MODIFIER_MAP[m];
|
|
85
|
+
if (!mapped) {
|
|
86
|
+
throw new Error(`Unknown modifier "${m}" in chord "${chord}"`);
|
|
87
|
+
}
|
|
88
|
+
return mapped;
|
|
89
|
+
});
|
|
90
|
+
return { key, modifiers };
|
|
91
|
+
}
|
|
92
|
+
function buildOsascript(chord, opts = {}) {
|
|
93
|
+
const { loadDelay = 3, activateDelay = 0.8 } = opts;
|
|
94
|
+
const { key, modifiers } = parseChord(chord);
|
|
95
|
+
const using = modifiers.length > 0 ? ` using {${modifiers.join(", ")}}` : "";
|
|
96
|
+
return [
|
|
97
|
+
`delay ${loadDelay}`,
|
|
98
|
+
'tell application "Zed" to activate',
|
|
99
|
+
`delay ${activateDelay}`,
|
|
100
|
+
`tell application "System Events" to keystroke "${key}"${using}`
|
|
101
|
+
].join("\n");
|
|
102
|
+
}
|
|
103
|
+
function readTasks(tasksPath) {
|
|
104
|
+
try {
|
|
105
|
+
const parsed = JSON.parse(readFileSync(tasksPath, "utf8"));
|
|
106
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
107
|
+
} catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function writeAgentTask(worktreePath, task) {
|
|
112
|
+
const zedDir = join(worktreePath, ".zed");
|
|
113
|
+
const tasksPath = join(zedDir, "tasks.json");
|
|
114
|
+
const createdDir = !existsSync(zedDir);
|
|
115
|
+
if (createdDir) mkdirSync(zedDir, { recursive: true });
|
|
116
|
+
const createdFile = !existsSync(tasksPath);
|
|
117
|
+
const existing = createdFile ? [] : readTasks(tasksPath);
|
|
118
|
+
const next = upsertTask(existing, task);
|
|
119
|
+
writeFileSync(tasksPath, `${JSON.stringify(next, null, 2)}
|
|
120
|
+
`);
|
|
121
|
+
return { createdDir, createdFile };
|
|
122
|
+
}
|
|
123
|
+
function cleanupAgentTask(worktreePath, label, created) {
|
|
124
|
+
const zedDir = join(worktreePath, ".zed");
|
|
125
|
+
const tasksPath = join(zedDir, "tasks.json");
|
|
126
|
+
if (existsSync(tasksPath)) {
|
|
127
|
+
const next = removeTask(readTasks(tasksPath), label);
|
|
128
|
+
if (next.length === 0 && created.createdFile) {
|
|
129
|
+
rmSync(tasksPath, { force: true });
|
|
130
|
+
} else {
|
|
131
|
+
writeFileSync(tasksPath, `${JSON.stringify(next, null, 2)}
|
|
132
|
+
`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (created.createdDir && existsSync(zedDir)) {
|
|
136
|
+
try {
|
|
137
|
+
if (readdirSync(zedDir).length === 0) {
|
|
138
|
+
rmSync(zedDir, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function stripJsonComments(text) {
|
|
145
|
+
return text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
146
|
+
}
|
|
147
|
+
function defaultKeymapPath() {
|
|
148
|
+
return join(homedir(), ".config", "zed", "keymap.json");
|
|
149
|
+
}
|
|
150
|
+
function ensureKeymap(chord, label, keymapPath = defaultKeymapPath()) {
|
|
151
|
+
const binding = buildKeymapBinding(chord, label);
|
|
152
|
+
const exists = existsSync(keymapPath);
|
|
153
|
+
let keymap = [];
|
|
154
|
+
if (exists) {
|
|
155
|
+
const raw = readFileSync(keymapPath, "utf8");
|
|
156
|
+
let parsed;
|
|
157
|
+
try {
|
|
158
|
+
parsed = JSON.parse(stripJsonComments(raw));
|
|
159
|
+
} catch {
|
|
160
|
+
process.stderr.write(
|
|
161
|
+
`
|
|
162
|
+
Warning: could not parse ${keymapPath}; not modifying it. Add this binding manually:
|
|
163
|
+
${JSON.stringify(binding, null, 2)}
|
|
164
|
+
`
|
|
165
|
+
);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
if (!Array.isArray(parsed)) {
|
|
169
|
+
process.stderr.write(
|
|
170
|
+
`
|
|
171
|
+
Warning: ${keymapPath} is not a JSON array; not modifying it. Add this binding manually:
|
|
172
|
+
${JSON.stringify(binding, null, 2)}
|
|
173
|
+
`
|
|
174
|
+
);
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
keymap = parsed;
|
|
178
|
+
}
|
|
179
|
+
const next = upsertKeymapBinding(keymap, chord, label);
|
|
180
|
+
if (exists && next === keymap) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
if (exists) {
|
|
184
|
+
try {
|
|
185
|
+
copyFileSync(keymapPath, `${keymapPath}.bak`);
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
mkdirSync(dirname(keymapPath), { recursive: true });
|
|
190
|
+
}
|
|
191
|
+
writeFileSync(keymapPath, `${JSON.stringify(next, null, 2)}
|
|
192
|
+
`);
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
var ACCESSIBILITY_SETTINGS_URL = "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility";
|
|
196
|
+
function defaultRunner(script) {
|
|
197
|
+
return new Promise((resolve) => {
|
|
198
|
+
const child = spawn("osascript", ["-e", script], {
|
|
199
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
200
|
+
});
|
|
201
|
+
let stderr = "";
|
|
202
|
+
child.stderr?.on("data", (d) => {
|
|
203
|
+
stderr += d.toString();
|
|
204
|
+
});
|
|
205
|
+
child.on("error", (err) => resolve({ code: null, stderr: err.message }));
|
|
206
|
+
child.on("close", (code) => resolve({ code, stderr }));
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function isAccessibilityError(stderr) {
|
|
210
|
+
return /\b1002\b/.test(stderr) || /-1719\b/.test(stderr) || /not allowed to send keystrokes/i.test(stderr) || /not allowed assistive access/i.test(stderr);
|
|
211
|
+
}
|
|
212
|
+
async function triggerChord(chord, opts = {}) {
|
|
213
|
+
if (process.platform !== "darwin") {
|
|
214
|
+
return { ok: false, reason: "unsupported" };
|
|
215
|
+
}
|
|
216
|
+
const { runner = defaultRunner, loadDelay, activateDelay } = opts;
|
|
217
|
+
const { code, stderr } = await runner(
|
|
218
|
+
buildOsascript(chord, { loadDelay, activateDelay })
|
|
219
|
+
);
|
|
220
|
+
if (code === 0) return { ok: true };
|
|
221
|
+
if (isAccessibilityError(stderr)) {
|
|
222
|
+
return { ok: false, reason: "accessibility", message: stderr.trim() };
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
ok: false,
|
|
226
|
+
reason: "error",
|
|
227
|
+
message: stderr.trim() || `osascript exited with code ${code}`
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function defaultOpen(url) {
|
|
231
|
+
const child = spawn("open", [url], { detached: true, stdio: "ignore" });
|
|
232
|
+
child.on("error", () => {
|
|
233
|
+
});
|
|
234
|
+
child.unref();
|
|
235
|
+
}
|
|
236
|
+
function openAccessibilitySettings(open = defaultOpen) {
|
|
237
|
+
if (process.platform !== "darwin") return;
|
|
238
|
+
open(ACCESSIBILITY_SETTINGS_URL);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/commands/agent.ts
|
|
242
|
+
var CLEANUP_DELAY_MS = 2e3;
|
|
243
|
+
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
244
|
+
async function createAgentWorktree(branch, planPrompt, options = {}) {
|
|
245
|
+
const prepared = await prepareWorktree(branch, options);
|
|
246
|
+
if (!prepared) return;
|
|
247
|
+
const { config, worktreePath } = prepared;
|
|
248
|
+
if (config.ide !== "zed") {
|
|
249
|
+
console.warn(
|
|
250
|
+
pc.yellow(
|
|
251
|
+
`\u26A0 Agent auto-start requires Zed (ide is "${config.ide}"). Opening without starting the agent.`
|
|
252
|
+
)
|
|
253
|
+
);
|
|
254
|
+
if (config.ide) {
|
|
255
|
+
await openIde(config.ide, config.ide_open_args, worktreePath);
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (!config.agent_command) {
|
|
260
|
+
console.error(
|
|
261
|
+
pc.red("No agent_command configured. Set it with `wt config`.")
|
|
262
|
+
);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const task = buildAgentTask(
|
|
266
|
+
config.agent_command,
|
|
267
|
+
planPrompt,
|
|
268
|
+
AGENT_TASK_LABEL
|
|
269
|
+
);
|
|
270
|
+
const created = writeAgentTask(worktreePath, task);
|
|
271
|
+
ensureKeymap(config.agent_trigger_chord, AGENT_TASK_LABEL);
|
|
272
|
+
const opened = await openIde("zed", config.ide_open_args, worktreePath);
|
|
273
|
+
if (!opened) {
|
|
274
|
+
console.error(pc.red("\u2717 Could not open Zed."));
|
|
275
|
+
cleanupAgentTask(worktreePath, AGENT_TASK_LABEL, created);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
console.log(pc.green("\u2713 Opened Zed"));
|
|
279
|
+
console.log(pc.dim("Starting agent in Zed\u2026"));
|
|
280
|
+
let result = await triggerChord(config.agent_trigger_chord);
|
|
281
|
+
while (!result.ok && result.reason === "accessibility" && process.stdin.isTTY) {
|
|
282
|
+
console.warn(
|
|
283
|
+
pc.yellow(
|
|
284
|
+
"\u26A0 macOS Accessibility permission is required to send the keystroke that starts the agent."
|
|
285
|
+
)
|
|
286
|
+
);
|
|
287
|
+
openAccessibilitySettings();
|
|
288
|
+
const proceed = await clack.confirm({
|
|
289
|
+
message: "Grant Accessibility to the app running wt (e.g. Zed) in the panel that opened, then confirm to retry. (If that app was already running, you may need to quit and reopen it for the grant to take effect.)"
|
|
290
|
+
});
|
|
291
|
+
if (clack.isCancel(proceed) || !proceed) break;
|
|
292
|
+
result = await triggerChord(config.agent_trigger_chord, {
|
|
293
|
+
loadDelay: 0,
|
|
294
|
+
activateDelay: 0.5
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
if (!result.ok) {
|
|
298
|
+
reportTriggerFailure(result, config.agent_trigger_chord);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
console.log(pc.green("\u2713 Agent started"));
|
|
302
|
+
await delay(CLEANUP_DELAY_MS);
|
|
303
|
+
cleanupAgentTask(worktreePath, AGENT_TASK_LABEL, created);
|
|
304
|
+
}
|
|
305
|
+
function reportTriggerFailure(result, chord) {
|
|
306
|
+
if (result.reason === "unsupported") {
|
|
307
|
+
console.warn(
|
|
308
|
+
pc.yellow(
|
|
309
|
+
`\u26A0 Agent auto-start is only supported on macOS. The worktree and Zed are open; press ${chord} in Zed to start the agent.`
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (result.reason === "accessibility") {
|
|
315
|
+
console.warn(
|
|
316
|
+
pc.yellow(
|
|
317
|
+
`\u26A0 Agent not started (Accessibility not granted). In Zed, press ${chord} to start it manually.`
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
console.warn(
|
|
323
|
+
pc.yellow(
|
|
324
|
+
`\u26A0 Could not auto-start the agent${result.message ? `: ${result.message}` : ""}. In Zed, press ${chord} to start it manually.`
|
|
325
|
+
)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
export {
|
|
329
|
+
createAgentWorktree
|
|
330
|
+
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
addWorktree,
|
|
4
4
|
branchExists,
|
|
5
|
+
fetchRemote,
|
|
5
6
|
getRegisteredRepos,
|
|
6
7
|
getRepoRoot,
|
|
7
8
|
openIde,
|
|
@@ -9,11 +10,11 @@ import {
|
|
|
9
10
|
resolveWorktreePath,
|
|
10
11
|
runBranchInput,
|
|
11
12
|
runRepoPicker
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-FSARWOCW.js";
|
|
13
14
|
import {
|
|
14
15
|
createStore,
|
|
15
16
|
getEffectiveConfig
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-IQWENLPW.js";
|
|
17
18
|
|
|
18
19
|
// src/commands/create.ts
|
|
19
20
|
import { existsSync } from "fs";
|
|
@@ -48,7 +49,7 @@ function runCommand(command, cwd) {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
// src/commands/create.ts
|
|
51
|
-
async function
|
|
52
|
+
async function prepareWorktree(branch, options = {}) {
|
|
52
53
|
const {
|
|
53
54
|
cwd = process.cwd(),
|
|
54
55
|
store = createStore(),
|
|
@@ -66,7 +67,7 @@ async function createWorktree(branch, options = {}) {
|
|
|
66
67
|
"No repos registered. cd into a repo and run wt create to get started."
|
|
67
68
|
)
|
|
68
69
|
);
|
|
69
|
-
return;
|
|
70
|
+
return null;
|
|
70
71
|
}
|
|
71
72
|
if (!process.stdin.isTTY) {
|
|
72
73
|
console.error(
|
|
@@ -77,25 +78,38 @@ async function createWorktree(branch, options = {}) {
|
|
|
77
78
|
process.exit(1);
|
|
78
79
|
}
|
|
79
80
|
const picked = await repoPicker(repos);
|
|
80
|
-
if (!picked) return;
|
|
81
|
+
if (!picked) return null;
|
|
81
82
|
repoRoot = picked;
|
|
82
83
|
if (!branch) {
|
|
83
84
|
const entered = await branchInput(repoRoot);
|
|
84
|
-
if (!entered) return;
|
|
85
|
+
if (!entered) return null;
|
|
85
86
|
branch = entered;
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
if (!repoRoot) return;
|
|
89
|
+
if (!repoRoot) return null;
|
|
89
90
|
if (!branch) {
|
|
90
91
|
const input = await clack.text({
|
|
91
92
|
message: "Branch name:",
|
|
92
93
|
validate: (v) => !v || v.length === 0 ? "Required" : void 0
|
|
93
94
|
});
|
|
94
|
-
if (clack.isCancel(input)) return;
|
|
95
|
+
if (clack.isCancel(input)) return null;
|
|
95
96
|
branch = input;
|
|
96
97
|
}
|
|
97
98
|
registerRepo(repoRoot, store);
|
|
98
99
|
const config = getEffectiveConfig(repoRoot, store);
|
|
100
|
+
const parts = config.base_branch.split("/", 2);
|
|
101
|
+
if (parts.length === 2) {
|
|
102
|
+
const remote = parts[0];
|
|
103
|
+
try {
|
|
104
|
+
fetchRemote(repoRoot, remote);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.warn(
|
|
107
|
+
pc.yellow(
|
|
108
|
+
`\u26A0 Could not fetch from ${remote} \u2014 using local state${err instanceof Error ? ` (${err.message})` : ""}`
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
99
113
|
const worktreePath = resolveWorktreePath(
|
|
100
114
|
repoRoot,
|
|
101
115
|
config.worktree_path,
|
|
@@ -124,6 +138,12 @@ async function createWorktree(branch, options = {}) {
|
|
|
124
138
|
process.exit(1);
|
|
125
139
|
}
|
|
126
140
|
}
|
|
141
|
+
return { repoRoot, worktreePath, config };
|
|
142
|
+
}
|
|
143
|
+
async function createWorktree(branch, options = {}) {
|
|
144
|
+
const prepared = await prepareWorktree(branch, options);
|
|
145
|
+
if (!prepared) return;
|
|
146
|
+
const { config, worktreePath } = prepared;
|
|
127
147
|
if (config.ide) {
|
|
128
148
|
const opened = await openIde(
|
|
129
149
|
config.ide,
|
|
@@ -135,6 +155,8 @@ async function createWorktree(branch, options = {}) {
|
|
|
135
155
|
}
|
|
136
156
|
}
|
|
137
157
|
}
|
|
158
|
+
|
|
138
159
|
export {
|
|
160
|
+
prepareWorktree,
|
|
139
161
|
createWorktree
|
|
140
162
|
};
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createStore,
|
|
4
4
|
getGlobalConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IQWENLPW.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/git.ts
|
|
8
8
|
import { execFileSync } from "child_process";
|
|
9
|
-
import { realpathSync } from "fs";
|
|
9
|
+
import { existsSync, realpathSync, rmSync } from "fs";
|
|
10
10
|
import path from "path";
|
|
11
11
|
function getRepoRoot(cwd = process.cwd()) {
|
|
12
12
|
try {
|
|
@@ -75,11 +75,22 @@ function addWorktree(repoRoot, worktreePath, branch, baseBranch) {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
function removeWorktree(repoRoot, worktreePath, force = false) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
try {
|
|
79
|
+
execFileSync(
|
|
80
|
+
"git",
|
|
81
|
+
["worktree", "remove", ...force ? ["--force"] : [], worktreePath],
|
|
82
|
+
{ cwd: repoRoot, stdio: "pipe" }
|
|
83
|
+
);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (!force) throw err;
|
|
86
|
+
if (existsSync(worktreePath)) {
|
|
87
|
+
rmSync(worktreePath, { recursive: true, force: true });
|
|
88
|
+
}
|
|
89
|
+
execFileSync("git", ["worktree", "prune"], {
|
|
90
|
+
cwd: repoRoot,
|
|
91
|
+
stdio: "pipe"
|
|
92
|
+
});
|
|
93
|
+
}
|
|
83
94
|
}
|
|
84
95
|
function listWorktreeDirtyFiles(worktreePath) {
|
|
85
96
|
try {
|
|
@@ -113,6 +124,13 @@ function branchExists(repoRoot, branch) {
|
|
|
113
124
|
return false;
|
|
114
125
|
}
|
|
115
126
|
}
|
|
127
|
+
function fetchRemote(repoRoot, remote = "origin") {
|
|
128
|
+
execFileSync("git", ["fetch", remote], {
|
|
129
|
+
cwd: repoRoot,
|
|
130
|
+
stdio: "pipe",
|
|
131
|
+
timeout: 3e4
|
|
132
|
+
});
|
|
133
|
+
}
|
|
116
134
|
function resolveWorktreePath(repoRoot, worktreePath, branch) {
|
|
117
135
|
const repoName = path.basename(repoRoot);
|
|
118
136
|
const safeBranch = branch.replace(/\//g, "-");
|
|
@@ -480,6 +498,7 @@ export {
|
|
|
480
498
|
removeWorktree,
|
|
481
499
|
listWorktreeDirtyFiles,
|
|
482
500
|
branchExists,
|
|
501
|
+
fetchRemote,
|
|
483
502
|
resolveWorktreePath,
|
|
484
503
|
openIde,
|
|
485
504
|
registerRepo,
|
package/dist/cli.js
CHANGED
|
@@ -3,16 +3,29 @@
|
|
|
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.1.0").action(async () => {
|
|
7
|
-
const { runList } = await import("./list-
|
|
6
|
+
program.name("wt").description("Git worktree manager").version("0.1.0-pr5.g8fa13c6").action(async () => {
|
|
7
|
+
const { runList } = await import("./list-HO42YAEG.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-
|
|
11
|
+
const { createWorktree } = await import("./create-55SXEUZV.js");
|
|
12
12
|
await createWorktree(branch);
|
|
13
13
|
});
|
|
14
|
-
program.command("
|
|
15
|
-
const {
|
|
16
|
-
|
|
14
|
+
program.command("agent <branch> <plan_prompt>").description("Create a worktree and auto-start an AI agent in Zed (macOS)").action(async (branch, planPrompt) => {
|
|
15
|
+
const { createAgentWorktree } = await import("./agent-UUA7YKTS.js");
|
|
16
|
+
await createAgentWorktree(branch, planPrompt);
|
|
17
|
+
});
|
|
18
|
+
program.command("config").description("Open the config file in $EDITOR").option("--path", "Print the config file path and exit").action(async (options) => {
|
|
19
|
+
if (options.path) {
|
|
20
|
+
const { printConfigPath } = await import("./config-OSNYQCZL.js");
|
|
21
|
+
printConfigPath();
|
|
22
|
+
} else {
|
|
23
|
+
const { openConfig } = await import("./config-OSNYQCZL.js");
|
|
24
|
+
openConfig();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
program.command("skill").description("Print the wt skill file to stdout").action(async () => {
|
|
28
|
+
const { printSkill } = await import("./skill-CRAP2ALY.js");
|
|
29
|
+
printSkill();
|
|
17
30
|
});
|
|
18
31
|
await program.parseAsync(process.argv);
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createStore
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IQWENLPW.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/config.ts
|
|
7
7
|
import { spawn } from "child_process";
|
|
8
8
|
function getConfigPath(store = createStore()) {
|
|
9
9
|
return store.path;
|
|
10
10
|
}
|
|
11
|
+
function printConfigPath(store = createStore()) {
|
|
12
|
+
console.log(store.path);
|
|
13
|
+
}
|
|
11
14
|
function openConfig(store = createStore()) {
|
|
12
15
|
const configPath = store.path;
|
|
13
16
|
console.log(`Config: ${configPath}`);
|
|
@@ -21,5 +24,6 @@ function openConfig(store = createStore()) {
|
|
|
21
24
|
}
|
|
22
25
|
export {
|
|
23
26
|
getConfigPath,
|
|
24
|
-
openConfig
|
|
27
|
+
openConfig,
|
|
28
|
+
printConfigPath
|
|
25
29
|
};
|
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
registerRepo,
|
|
9
9
|
removeWorktree,
|
|
10
10
|
runInteractiveList
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FSARWOCW.js";
|
|
12
12
|
import {
|
|
13
13
|
createStore,
|
|
14
14
|
getEffectiveConfig
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IQWENLPW.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/list.ts
|
|
18
18
|
import * as clack from "@clack/prompts";
|
|
@@ -93,7 +93,7 @@ ${dirty.map((f) => ` ${f}`).join("\n")}`
|
|
|
93
93
|
},
|
|
94
94
|
onCreate: async () => {
|
|
95
95
|
if (repoRoot) {
|
|
96
|
-
const { createWorktree } = await import("./create-
|
|
96
|
+
const { createWorktree } = await import("./create-55SXEUZV.js");
|
|
97
97
|
await createWorktree(void 0, { cwd: repoRoot, store });
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -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 / `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\n### `wt agent <branch> <plan_prompt>`\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.\'\n```\n\nIt writes a temporary `.zed/tasks.json` running\n`<agent_command> \'<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\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| `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"` | Command `wt agent` runs in Zed; `<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`, `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.1.0-
|
|
3
|
+
"version": "0.1.0-pr5.g8fa13c6",
|
|
4
4
|
"description": "Fast, interactive TUI to browse, create, open, and delete git worktrees across repos.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"wt": "./dist/cli.js"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
-
"dist"
|
|
17
|
+
"dist",
|
|
18
|
+
"SKILL.md"
|
|
18
19
|
],
|
|
19
20
|
"publishConfig": {
|
|
20
21
|
"access": "public"
|