@moberg_hr/work-tree 1.5.0 → 1.5.1
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 +158 -52
- package/dist/bin.js +578 -500
- package/dist/bin.js.map +1 -1
- package/dist/wd-bin.js +572 -494
- package/dist/wd-bin.js.map +1 -1
- package/dist/web/assets/index-8WP9kHU6.css +1 -0
- package/dist/web/assets/index-C5ddmssO.js +106 -0
- package/dist/web/assets/index-C5ddmssO.js.map +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +3 -3
- package/dist/web/assets/index-Quf37ngR.css +0 -1
- package/dist/web/assets/index-vD0svqIi.js +0 -106
- package/dist/web/assets/index-vD0svqIi.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
### One terminal. Every branch. Every repo. Every Claude session.
|
|
6
6
|
|
|
7
|
-
**A cross-platform TypeScript CLI that turns git worktrees into a parallel-development cockpit. Spin up isolated workspaces per branch across one or many repos, auto-launch Claude Code, and orchestrate everything — PRs, Jira issues,
|
|
7
|
+
**A cross-platform TypeScript CLI that turns git worktrees into a parallel-development cockpit. Spin up isolated workspaces per branch across one or many repos, auto-launch Claude Code (or any AI CLI), and orchestrate everything — PRs, Jira issues, local tasks, diffs, and reviews — from a terminal dashboard or a single browser tab.**
|
|
8
8
|
|
|
9
|
-
[](https://github.com/moberghr/cli-work-tree-manager/releases)
|
|
10
10
|
[](https://moberghr.github.io/cli-work-tree-manager/)
|
|
11
11
|
[](https://nodejs.org/)
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
|
|
14
14
|
**[moberghr.github.io/cli-work-tree-manager](https://moberghr.github.io/cli-work-tree-manager/)** — the Work website.
|
|
15
15
|
|
|
16
|
-
[Quick Start](#quick-start) · [Why Work](#why-work) · [Commands](#commands) · [Dashboard](#interactive-dashboard) · [Groups](#groups-multi-repo-worktrees) · [Diff review (`wd`)](#diff-review-wd) · [Architecture](#architecture) · [FAQ](#faq)
|
|
16
|
+
[Quick Start](#quick-start) · [Why Work](#why-work) · [Commands](#commands) · [Dashboard](#interactive-dashboard) · [Browser (`work web`)](#browser-dashboard-work-web) · [Fleet](#fleet-commands-run--broadcast) · [Groups](#groups-multi-repo-worktrees) · [Diff review (`wd`)](#diff-review-wd) · [Architecture](#architecture) · [FAQ](#faq)
|
|
17
17
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
@@ -31,8 +31,10 @@ Work is the missing layer between `git worktree` and your AI assistant. Every br
|
|
|
31
31
|
| Three terminals, three editors, three lost contexts | One TUI: sessions, PRs, Jira, tasks — keyboard-driven, mouse-aware |
|
|
32
32
|
| "Which directory was that branch in again?" | `work resume` — recent sessions sorted by last access, one keystroke to re-enter |
|
|
33
33
|
| Multi-repo features = multiple `git worktree add` invocations and a hand-merged CLAUDE.md | `work tree mygroup feature/x` — every repo cloned in lockstep, combined CLAUDE.md generated automatically |
|
|
34
|
-
| Stale worktrees pile up after PRs merge | `work prune` —
|
|
34
|
+
| Stale worktrees pile up after PRs merge | `work prune` (interactive) / `work sync` (one-shot) — remove worktrees whose branches landed on main |
|
|
35
35
|
| Jira ticket → branch name → worktree → Claude prompt = manual every time | Select a Jira issue in the dash → branch slug auto-generated → worktree created → planning prompt sent to Claude |
|
|
36
|
+
| Same chore (`npm test`, rebase) in five worktrees, one terminal at a time | `work run --all npm test` / `work broadcast --all "rebase onto main"` — fan out across the fleet |
|
|
37
|
+
| Diffs and reviews scattered across terminals and editor tabs | `wd` / `work web` — every diff and review in one browser, comments routed back to the live AI session |
|
|
36
38
|
|
|
37
39
|
---
|
|
38
40
|
|
|
@@ -49,14 +51,14 @@ npm link
|
|
|
49
51
|
# 2. First-time setup — interactive
|
|
50
52
|
work init
|
|
51
53
|
|
|
52
|
-
# 3. Create a worktree and launch
|
|
54
|
+
# 3. Create a worktree and launch your AI tool
|
|
53
55
|
work tree api feature/login
|
|
54
56
|
|
|
55
|
-
# 4. Open the dashboard
|
|
57
|
+
# 4. Open the dashboard (terminal TUI, or `work web` for the browser)
|
|
56
58
|
work dash
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
`work init` walks you through the worktrees root, your repo aliases, and tab-completion installation. Everything else is one keystroke away from the dashboard.
|
|
61
|
+
`work init` walks you through the worktrees root, your repo aliases, your AI command, and tab-completion installation. Everything else is one keystroke away from the dashboard.
|
|
60
62
|
|
|
61
63
|
### Prerequisites
|
|
62
64
|
|
|
@@ -64,9 +66,9 @@ work dash
|
|
|
64
66
|
|:---|:---|:---|
|
|
65
67
|
| **Node.js 18+** | yes | Runtime |
|
|
66
68
|
| **Git** | yes | Worktree operations |
|
|
67
|
-
| **[Claude Code CLI](https://claude.ai/code)** | recommended |
|
|
68
|
-
| **[GitHub CLI (`gh`)](https://cli.github.com/)** | optional | PR pane in dashboard |
|
|
69
|
-
| **[Atlassian CLI (`acli`)](https://developer.atlassian.com/cloud/acli/)** | optional | Jira pane in dashboard |
|
|
69
|
+
| **[Claude Code CLI](https://claude.ai/code)** | recommended | Default AI tool auto-launched on `work tree`; group CLAUDE.md generation. Any other CLI works too — set `aiCommand` in config. |
|
|
70
|
+
| **[GitHub CLI (`gh`)](https://cli.github.com/)** | optional | PR pane in the dashboard / `work web` |
|
|
71
|
+
| **[Atlassian CLI (`acli`)](https://developer.atlassian.com/cloud/acli/)** | optional | Jira pane in the dashboard / `work web` |
|
|
70
72
|
|
|
71
73
|
---
|
|
72
74
|
|
|
@@ -75,15 +77,21 @@ work dash
|
|
|
75
77
|
```
|
|
76
78
|
work init # Interactive first-time setup
|
|
77
79
|
work tree|t <target> <branch> [flags] # Create or switch to a worktree
|
|
80
|
+
work tree --here # Infer target+branch from the current worktree
|
|
78
81
|
work remove <target> <branch> [--force] # Remove a worktree
|
|
79
82
|
work list [target] # List worktrees
|
|
80
83
|
work status [target] [branch] [--prune] # Show worktree merge/dirty status
|
|
81
84
|
work recent [count] # List recent sessions
|
|
82
85
|
work resume [--unsafe] # Resume a recent session
|
|
83
86
|
work dash [--unsafe] # Interactive TUI dashboard
|
|
84
|
-
work
|
|
87
|
+
work web [--stop] [--no-open] # Browser dashboard (singleton; all sessions in one tab)
|
|
88
|
+
work prune [--force] # Remove merged worktrees (interactive)
|
|
89
|
+
work sync [--dry-run] [--force] [--include-squash] # Fetch all repos + prune merged worktrees (non-interactive)
|
|
85
90
|
work completion [--install] # Shell completions
|
|
86
91
|
|
|
92
|
+
work run <cmd...> [--target <a>] [--all] [--parallel] # Run a shell command across worktrees
|
|
93
|
+
work broadcast <prompt> [--target <a>] [--all] # Queue a prompt to every live AI session
|
|
94
|
+
|
|
87
95
|
work todo # List open tasks
|
|
88
96
|
work todo add|done|undo|edit|rm <args> # Manage tasks
|
|
89
97
|
work todo --all # Include completed tasks
|
|
@@ -91,13 +99,14 @@ work todo --all # Include completed tasks
|
|
|
91
99
|
work config add|remove|list|show|edit # Manage repos
|
|
92
100
|
work config group add|remove|regen <args> # Manage multi-repo groups
|
|
93
101
|
|
|
94
|
-
wd # PR-style diff in your browser (
|
|
95
|
-
wd --
|
|
96
|
-
wd --
|
|
102
|
+
wd # PR-style diff in your browser (live server)
|
|
103
|
+
wd --branch # Open the "Since branch" tab by default
|
|
104
|
+
wd --static # Self-contained HTML file (no server)
|
|
105
|
+
wd --stop # Stop the background server for this scope
|
|
97
106
|
wd -c # Interactive review with streaming comments
|
|
98
107
|
```
|
|
99
108
|
|
|
100
|
-
`work tree` flags: `--base <branch>` (branch from a specific base), `--open` (open
|
|
109
|
+
`work tree` flags: `--here` (infer target+branch from cwd), `--base <branch>` (branch from a specific base), `--open` (open the configured editor), `--unsafe` (skip AI-tool permission checks), `--prompt "..."` / `--prompt-file <path>` (send an initial prompt), `--jira-key <KEY>` (link a Jira issue to the session), `--setup-only` (create the worktree without launching the AI tool).
|
|
101
110
|
|
|
102
111
|
### Branch resolution order
|
|
103
112
|
|
|
@@ -170,6 +179,57 @@ A keyboard-driven terminal UI built with [Ink](https://github.com/vadimdemedes/i
|
|
|
170
179
|
|
|
171
180
|
---
|
|
172
181
|
|
|
182
|
+
## Browser Dashboard (`work web`)
|
|
183
|
+
|
|
184
|
+
Prefer a browser to the terminal? `work web` brings the dashboard — every session, its diff, its review comments, and a live terminal — into a single tab.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
work web # start (or re-attach to) the dashboard, opens the browser
|
|
188
|
+
work web --no-open # start without opening a browser
|
|
189
|
+
work web --stop # shut the dashboard down
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
- **Singleton** — one process per user, tracked by `~/.work/web.pid` + `~/.work/web.url`. A second `work web` re-uses the running one instead of spawning a duplicate; the port is chosen deterministically from the configured `portRange` (default `3000–3099`) with a liveness probe so it survives restarts and avoids collisions.
|
|
193
|
+
- **Every session in one place** — the sidebar lists all worktree sessions with activity badges (active / idle / stale) and per-session comment/draft counts, reactive to `work tree` / `work remove` anywhere on the machine.
|
|
194
|
+
- **Per-session tabs** — a **Diff** tab (Uncommitted vs HEAD, plus "Since branch"), a **Comments** review tab, and a live **Terminal** tab (a `node-pty` Claude session, same as the TUI).
|
|
195
|
+
- **Top panes** — PRs (via `gh`), Jira (via `acli`), and Tasks — with create / sync / rebase / open-in-editor actions wired to `POST /api/worktrees` and friends.
|
|
196
|
+
- **One server, every `wd` scope** — every `wd` and `wd -c` invocation registers as a *scope* on this server (addressable at `/diff/<hash>` and `/review/<hash>`) instead of spawning its own port. A dozen reviews share one process and one set of tabs.
|
|
197
|
+
- **Hook bridge to live Claude** — on startup `work web` installs `UserPromptSubmit` and `Stop` command hooks in `~/.claude/settings.json` (removed on shutdown). Drop a comment on a line and any Claude running in that worktree picks it up on its next turn — no copy-paste.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Fleet Commands (`run` / `broadcast`)
|
|
202
|
+
|
|
203
|
+
Once you have several worktrees open, you often want to do *one thing* to *all of them*. Two commands fan out across the fleet.
|
|
204
|
+
|
|
205
|
+
### `work run` — a command in every worktree
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
work run npm test # run in EVERY worktree (requires --all)
|
|
209
|
+
work run --all npm test # explicit confirmation for the whole fleet
|
|
210
|
+
work run --target api npm run build # only worktrees for the `api` alias
|
|
211
|
+
work run --target api --branch feat/x … # narrow to a single branch
|
|
212
|
+
work run --all --parallel --jobs 6 … # run concurrently, up to 6 at a time
|
|
213
|
+
work run --all --halt-on-error npm test # sequential: stop after the first failure
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- **Blast-radius guardrail** — a bare `work run <cmd>` with no `--target` refuses to run until you pass `--all`. Narrow with `--target <alias>` (and optionally `--branch`).
|
|
217
|
+
- **Sequential by default** — output streams through transparently. With `--parallel`, output is captured and re-emitted line-by-line with a `[target/branch]` prefix so concurrent logs stay attributable; `--jobs` (default 4) caps concurrency with a worker pool.
|
|
218
|
+
- **Ctrl-C tears the whole fleet down** — in-flight children are killed and the pool stops dequeuing rather than orphaning subprocesses. Exit code is non-zero if any worktree failed.
|
|
219
|
+
- The command runs through `sh -c` (POSIX) / `cmd.exe /c` (Windows); your command string is the intentional payload — Work never interpolates paths or branch names into a shell string itself.
|
|
220
|
+
|
|
221
|
+
### `work broadcast` — a prompt to every live AI session
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
work broadcast --all "rebase onto main and resolve conflicts"
|
|
225
|
+
work broadcast --target api "run the test suite and fix failures"
|
|
226
|
+
echo "long prompt…" | work broadcast --all - # read the prompt from stdin
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`broadcast` queues your prompt to each matching session and the session picks it up on its **next turn** via the same `UserPromptSubmit` hook `work web` uses — so it works even when you're not looking at that terminal. The same `--all` guardrail applies: broadcasting to every session requires an explicit `--all` or a narrowing `--target`. Delivery is lazy and crash-safe — the prompt is written to each session's comment store under a file lock, so a concurrent `work web` write can't clobber it.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
173
233
|
## Groups (Multi-Repo Worktrees)
|
|
174
234
|
|
|
175
235
|
When a feature spans several repositories — say a backend API change that ships with a frontend update — Work treats them as a single unit.
|
|
@@ -203,23 +263,33 @@ The combined `CLAUDE.md` is produced by invoking the Claude CLI to merge each re
|
|
|
203
263
|
A second binary, **`wd`**, ships alongside `work` and gives you a GitHub-PR-style diff view in your browser — for the current worktree, or for every repo in a group.
|
|
204
264
|
|
|
205
265
|
```bash
|
|
206
|
-
wd #
|
|
207
|
-
wd --
|
|
208
|
-
wd --stop # stop the watcher for this scope
|
|
209
|
-
wd -c # interactive review: leave comments inline, stream to stdout
|
|
266
|
+
wd # live diff server: renders the current diff, refresh to see edits
|
|
267
|
+
wd --branch # open the "Since branch" tab by default (PR-style vs the parent branch)
|
|
210
268
|
wd main # diff vs an explicit ref
|
|
211
|
-
wd --
|
|
269
|
+
wd --static # write a self-contained HTML file (no server, survives the CLI)
|
|
270
|
+
wd --stop # stop the background server for this scope
|
|
271
|
+
wd -c # interactive review: leave comments inline, stream to stdout
|
|
212
272
|
```
|
|
213
273
|
|
|
214
274
|
`wd` resolves the scope from your `cwd`: inside a single-repo worktree it diffs that repo; inside a group worktree (root or any sub-repo) it diffs every repo in the group and renders one tab per repo. Untracked files are included as synthesized "new file" diffs without touching your git index.
|
|
215
275
|
|
|
216
|
-
|
|
276
|
+
**One server, every scope.** If a `work web` dashboard is running, `wd` and `wd -c` register as a *scope* on it and open `/diff/<hash>` or `/review/<hash>` — no new process, no extra port. When `work web` isn't up, `wd` falls back to spawning its own detached daemon (state under `~/.work/diffs/<scope-hash>.{pid,url}`). Either way the live page reloads itself over SSE when files change.
|
|
277
|
+
|
|
278
|
+
### Modes
|
|
217
279
|
|
|
218
280
|
| Mode | What it does |
|
|
219
281
|
|:---|:---|
|
|
220
|
-
| `wd` |
|
|
221
|
-
| `wd --
|
|
222
|
-
| `wd -c` |
|
|
282
|
+
| `wd` (default) | **Live server.** Prefers a running `work web`; otherwise spawns a detached daemon. Refresh the browser to pick up saved-file changes (chokidar + SSE, per-repo dirty tracking). Stop with `wd --stop`. `--server` / `--watch` are kept as back-compat aliases. |
|
|
283
|
+
| `wd --static` | Renders a fully self-contained HTML file to `~/.work/diffs/<scope-hash>.html` (bundle + diff JSON inlined), opens via `file://`, and exits. No server, no live reload — survives the CLI. |
|
|
284
|
+
| `wd -c` | **Interactive review.** Click any line number to drop an inline comment; each comment streams to stdout as a markdown marker as it's saved. Blocks until you click "Done & Send" (or Ctrl+C). |
|
|
285
|
+
|
|
286
|
+
### Reading the diff
|
|
287
|
+
|
|
288
|
+
- **Uncommitted vs Since branch** — toggle between the working-tree diff and the full PR-style diff against the branch this worktree was forked from.
|
|
289
|
+
- **Checkpoints + range diff** — `wd` automatically snapshots each repo's working tree (including untracked files) as it watches, holding the snapshots alive behind `refs/wd/<scope>/<n>` refs. A checkpoint strip lets you diff between any two points in time — "what changed since I started", or between checkpoint #2 and #5 — not just against a static ref.
|
|
290
|
+
- **Coverage badges** — if a `coverage/lcov.info` (or `lcov.info`) is present, each file shows its line-coverage percentage. The badge is de-emphasized and flagged when the source has been edited since the coverage report was written, so you don't trust stale numbers.
|
|
291
|
+
- **Reviewed-hunk checkboxes** — tick individual hunks as you review them. The state is keyed on a content hash of the hunk (not line numbers), so it survives live reloads and unrelated edits elsewhere in the file, and persists per-scope in `localStorage`.
|
|
292
|
+
- **Word-level intra-line diff**, npm-bundled syntax highlighting, auto-collapsed large/migration files, and a file-tree sidebar with per-file viewed checkboxes.
|
|
223
293
|
|
|
224
294
|
### Interactive review (`wd -c`)
|
|
225
295
|
|
|
@@ -234,14 +304,15 @@ id: 1df977d4...
|
|
|
234
304
|
|
|
235
305
|
Other features in review mode:
|
|
236
306
|
|
|
307
|
+
- **Markdown comments** — both your comments and Claude's replies render as formatted markdown (code blocks, lists, links), not raw text.
|
|
237
308
|
- **Live reload** via SSE — the page refreshes itself when files change; reloads are deferred while you're composing so your draft isn't lost.
|
|
238
309
|
- **Threaded replies** — a wrapping process can POST replies via `${URL}/api/comments` with `parentId` and `author: 'claude'`; they render inline under the original comment with distinct styling.
|
|
310
|
+
- **Drafts & submit** — stage multiple comments as drafts, then submit them in one batch (GitHub-style).
|
|
239
311
|
- **Outdated detection** — the line's raw content is captured at compose time; if the file changes underneath, the comment is dimmed with an "outdated" badge.
|
|
240
312
|
- **General comments** — a top-of-page composer for review notes that aren't tied to any line.
|
|
241
|
-
- **
|
|
242
|
-
- **Stable file path** — `~/.work/diffs/<scope-hash>.html` — keep one tab open across `wd`, `wd --watch`, and `wd -c` invocations.
|
|
313
|
+
- **Stable scope hash** — keep one tab open across repeated `wd` / `wd -c` invocations for the same worktree.
|
|
243
314
|
|
|
244
|
-
|
|
315
|
+
When running standalone (no `work web`), the live URL is published to `~/.work/diffs/latest-review.url` so any local tool can find it without scraping stdout. A ready-made Claude Code skill ships with the repo at `.claude/skills/wd-review/SKILL.md` — drop it into `~/.claude/skills/` and say *"review my changes with wd"* in any Claude session to drive the loop.
|
|
245
316
|
|
|
246
317
|
---
|
|
247
318
|
|
|
@@ -263,11 +334,37 @@ Stored at `~/.work/config.json`:
|
|
|
263
334
|
"*.Development.json",
|
|
264
335
|
"*.Local.json",
|
|
265
336
|
".claude/settings.local.json"
|
|
337
|
+
],
|
|
338
|
+
"aiCommand": "claude",
|
|
339
|
+
"editor": "code",
|
|
340
|
+
"portRange": { "start": 3000, "end": 3099 },
|
|
341
|
+
"notifications": false,
|
|
342
|
+
"statusHooks": [
|
|
343
|
+
{ "on": "needs_input", "command": "afplay /System/Library/Sounds/Glass.aiff" }
|
|
266
344
|
]
|
|
267
345
|
}
|
|
268
346
|
```
|
|
269
347
|
|
|
270
|
-
|
|
348
|
+
| Key | Purpose |
|
|
349
|
+
|:---|:---|
|
|
350
|
+
| `worktreesRoot` | Parent directory for every worktree. |
|
|
351
|
+
| `repos` | Alias → repo path. |
|
|
352
|
+
| `groups` | Group name → list of repo aliases. |
|
|
353
|
+
| `copyFiles` | Glob patterns copied into every new worktree — the canonical use is local dev settings (`appsettings.Development.json`, `.env.local`, `.claude/settings.local.json`) that are gitignored but needed to run the app. |
|
|
354
|
+
| `aiCommand` | The AI CLI to auto-launch (default `claude`). Set it to any other tool; per-tool flag names live under `aiCommandFlags`. |
|
|
355
|
+
| `editor` | Editor command for `--open` / "open in editor" (default `code`). |
|
|
356
|
+
| `portRange` | Port window `work web` allocates from (default `3000`–`3099`). |
|
|
357
|
+
| `notifications` | Opt-in desktop notification when a session goes idle or needs input. |
|
|
358
|
+
| `statusHooks` | Run your own shell command on a session status change — see below. |
|
|
359
|
+
|
|
360
|
+
Edit via `work config edit`, or manage repos/groups via the `work config …` subcommands.
|
|
361
|
+
|
|
362
|
+
### Notifications & status hooks
|
|
363
|
+
|
|
364
|
+
When a background AI session finishes its turn (`idle`) or blocks waiting on you (`needs_input`), Work can let you know:
|
|
365
|
+
|
|
366
|
+
- **`notifications: true`** — fires a native desktop notification (macOS `osascript`, Linux `notify-send`, Windows BurntToast/balloon best-effort). Repeated alerts within one idle period are de-duplicated; submitting a new prompt re-arms it.
|
|
367
|
+
- **`statusHooks`** — the general form. Each entry is `{ "on": "idle" | "needs_input", "command": "..." }`. The command runs (with the session directory as cwd) on that transition, with `WORK_SESSION` and `WORK_STATUS` in its environment — use it for sounds, Slack pings, or anything scriptable.
|
|
271
368
|
|
|
272
369
|
### Session tracking
|
|
273
370
|
|
|
@@ -275,16 +372,17 @@ Every `work tree` invocation upserts a row into `~/.work/history.json` keyed by
|
|
|
275
372
|
|
|
276
373
|
- **`work status`** — joins history with live `git status` to show merge state, dirty trees, unpushed commits, and last-access timestamps.
|
|
277
374
|
- **`work recent`** — sessions sorted by last touched.
|
|
278
|
-
- **`work resume`** — interactive picker; one keystroke to re-enter the worktree and continue the prior
|
|
279
|
-
-
|
|
375
|
+
- **`work resume`** — interactive picker; one keystroke to re-enter the worktree and continue the prior AI conversation.
|
|
376
|
+
- **`work prune` / `work sync`** — `prune` interactively removes worktrees whose branches landed on `main`/`master`; `work sync` does the same non-interactively after fetching every repo in parallel (`--dry-run` to preview, `--force` to include dirty/unpushed trees, `--include-squash` to also catch squash-merged branches).
|
|
377
|
+
- **Dashboard reactivity** — `fs.watch` on `history.json` means a `work tree` in another terminal shows up in the running dashboard (TUI and `work web`) immediately.
|
|
280
378
|
|
|
281
379
|
---
|
|
282
380
|
|
|
283
381
|
## Architecture
|
|
284
382
|
|
|
285
383
|
```
|
|
286
|
-
bin.ts → cli.ts (yargs router) → commands/{tree,remove,list,status,recent,prune,
|
|
287
|
-
wd-bin.ts → forwards argv to
|
|
384
|
+
bin.ts → cli.ts (yargs router) → commands/{tree,remove,list,status,recent,prune,sync,
|
|
385
|
+
wd-bin.ts → forwards argv to `diff` dash,web,config,init,todo,run,broadcast,diff,hook}.ts
|
|
288
386
|
│
|
|
289
387
|
▼
|
|
290
388
|
core/worktree.ts ← high-level setup / teardown
|
|
@@ -295,29 +393,36 @@ wd-bin.ts → forwards argv to the `diff` command (the `wd` binary shim)
|
|
|
295
393
|
├── core/tasks.ts ← local task persistence
|
|
296
394
|
├── core/pr.ts ← GitHub PR fetching (gh)
|
|
297
395
|
├── core/jira.ts ← Jira issue fetching (acli)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
core/
|
|
396
|
+
├── core/fleet.ts ← run/broadcast session selection
|
|
397
|
+
├── core/broadcast.ts ← queue a prompt to live sessions
|
|
398
|
+
├── core/notifier.ts ← desktop notifications
|
|
399
|
+
├── core/status-hooks.ts ← user shell hooks on status change
|
|
400
|
+
└── core/port-allocator.ts← deterministic free-port pick
|
|
401
|
+
|
|
402
|
+
Diff / review stack ← `wd` + `work web`
|
|
403
|
+
├── diff-pipeline.ts ← computeDiff(): git diff + untracked + lcov
|
|
301
404
|
├── diff-parse.ts ← unified-diff parser
|
|
302
|
-
├──
|
|
303
|
-
├──
|
|
304
|
-
├──
|
|
305
|
-
|
|
405
|
+
├── checkpoint.ts ← per-scope working-tree snapshots
|
|
406
|
+
├── lcov.ts ← coverage parsing (cached)
|
|
407
|
+
├── diff-server.ts ← shared Hono server (chokidar + SSE)
|
|
408
|
+
├── comment-*.ts ← review comment model + file store
|
|
409
|
+
├── scope-manager.ts ← in-memory scope registry
|
|
410
|
+
└── static-renderer.ts ← self-contained HTML (`wd --static`)
|
|
306
411
|
|
|
307
412
|
web/src/ ← React SPA (Vite → dist/web/)
|
|
308
413
|
├── apps/ReviewApp.tsx ← single-scope view (wd / wd -c)
|
|
309
414
|
├── apps/DashboardApp.tsx ← multi-session view (work web)
|
|
310
|
-
└── components/ ← Diff/, Review/, Sidebar/
|
|
415
|
+
└── components/ ← Diff/, Review/, Sidebar/, Terminal/
|
|
416
|
+
|
|
417
|
+
core/web-server.ts ← `work web` dashboard (Hono + SSE + WS)
|
|
418
|
+
├── scope-routes / panes-routes / worktree-routes / *-comment-routes
|
|
419
|
+
├── pty-pool.ts ← per-session Claude PTY pool
|
|
420
|
+
└── command-hook-installer.ts ← UserPromptSubmit/Stop hooks
|
|
311
421
|
|
|
312
|
-
tui-ink/ ← Ink/React TUI
|
|
313
|
-
|
|
314
|
-
├── Sidebar.tsx ← session list, PR pane
|
|
315
|
-
├── TerminalPane.tsx ← xterm renderer
|
|
316
|
-
└── StatusBar.tsx
|
|
422
|
+
tui-ink/ ← Ink/React TUI (`work dash`)
|
|
423
|
+
└── App / Sidebar / TerminalPane / StatusBar
|
|
317
424
|
|
|
318
|
-
tui/
|
|
319
|
-
├── session.ts ← node-pty + @xterm/headless
|
|
320
|
-
└── hooks.ts ← Claude Code lifecycle events
|
|
425
|
+
tui/session.ts ← node-pty + @xterm/headless (shared)
|
|
321
426
|
```
|
|
322
427
|
|
|
323
428
|
### Design principles
|
|
@@ -373,7 +478,8 @@ work-tree/
|
|
|
373
478
|
│ ├── bin.ts # Entry point (chalk forcing, shebang)
|
|
374
479
|
│ ├── cli.ts # yargs router
|
|
375
480
|
│ ├── commands/ # CLI command handlers
|
|
376
|
-
│ ├── core/ # Shared operations (worktree, git, history, …)
|
|
481
|
+
│ ├── core/ # Shared operations (worktree, git, history, diff, web, …)
|
|
482
|
+
│ ├── web/ # React SPA — diff/review UI + work web dashboard (Vite → dist/web/)
|
|
377
483
|
│ ├── tui-ink/ # Ink/React TUI dashboard
|
|
378
484
|
│ ├── tui/ # PTY sessions and hook server
|
|
379
485
|
│ ├── completions/ # Dynamic tab-completion handler
|
|
@@ -389,7 +495,7 @@ work-tree/
|
|
|
389
495
|
|
|
390
496
|
## Unsafe Mode & Debug Logging
|
|
391
497
|
|
|
392
|
-
`--unsafe` on `work tree`, `work resume`, or `work dash` passes `--dangerously-skip-permissions`
|
|
498
|
+
`--unsafe` on `work tree`, `work resume`, or `work dash` passes the AI tool's skip-permissions flag (`--dangerously-skip-permissions` for Claude Code; configurable per tool via `aiCommandFlags`) — useful in trusted, sandboxed worktrees, dangerous everywhere else. Use deliberately.
|
|
393
499
|
|
|
394
500
|
All CLI output and internal debug messages stream to `~/.work/debug.log` with timestamps. Auto-rotates at 5 MB. The first place to look when worktree creation, group CLAUDE.md generation, or hook delivery misbehaves.
|
|
395
501
|
|
|
@@ -436,7 +542,7 @@ Pick a Jira issue in the dash, choose the target project, and Work invokes Claud
|
|
|
436
542
|
<details>
|
|
437
543
|
<summary><b>Can I use my own AI assistant instead of Claude Code?</b></summary>
|
|
438
544
|
|
|
439
|
-
|
|
545
|
+
Yes. Set `aiCommand` in `~/.work/config.json` to any CLI (and adjust `aiCommandFlags` for that tool's unsafe / resume / prompt-file flag names). Work will launch it on `work tree` and embed it in the dashboard terminal the same way. Claude Code remains the default and the only tool with first-class group `CLAUDE.md` generation and the review hook bridge.
|
|
440
546
|
</details>
|
|
441
547
|
|
|
442
548
|
---
|
|
@@ -449,7 +555,7 @@ MIT — see [LICENSE](LICENSE).
|
|
|
449
555
|
|
|
450
556
|
<div align="center">
|
|
451
557
|
|
|
452
|
-
**Work — Git Worktree Manager** v1.
|
|
558
|
+
**Work — Git Worktree Manager** v1.5.0 · [Moberg d.o.o.](https://www.moberg.hr)
|
|
453
559
|
|
|
454
560
|
Built for engineers who run more than one branch at a time.
|
|
455
561
|
|