@poulles/worktree-dashboard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 gpoulles
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # @poulles/worktree-dashboard
2
+
3
+ A local dashboard for monitoring and managing your git worktrees with Claude Code agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @poulles/worktree-dashboard
9
+ ```
10
+
11
+ Or run it directly without installing:
12
+
13
+ ```bash
14
+ npx @poulles/worktree-dashboard
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ worktree-dashboard [options]
21
+ ```
22
+
23
+ | Flag | Default | Description |
24
+ |------|---------|-------------|
25
+ | `--port <number>` | `3333` | Port to listen on |
26
+ | `--logo <path>` | — | Path to a local image file, embedded as base64 |
27
+ | `--title <string>` | `"Worktree Dashboard"` | Title shown in the header |
28
+ | `--worktrees <path>` | `.claude/worktrees` | Path to the worktrees folder |
29
+ | `--config <path>` | `.worktree-dashboard.json` | Path to a config file |
30
+
31
+ ## Config file
32
+
33
+ Create `.worktree-dashboard.json` in your project root. CLI flags override these values.
34
+
35
+ ```json
36
+ {
37
+ "port": 3333,
38
+ "logo": "./logo.png",
39
+ "title": "My Dashboard",
40
+ "worktrees": ".claude/worktrees"
41
+ }
42
+ ```
43
+
44
+ ## Running dev servers per worktree
45
+
46
+ Add a `run` block to start a project script (e.g. `ng serve`) from each worktree, with a different port per worktree so they can run side by side.
47
+
48
+ ```json
49
+ {
50
+ "run": {
51
+ "scripts": ["start"],
52
+ "command": "npm run {script} -- --port {port}",
53
+ "basePort": 4200
54
+ }
55
+ }
56
+ ```
57
+
58
+ | Field | Default | Description |
59
+ |-------|---------|-------------|
60
+ | `scripts` | `["start"]` | Allowlist of `package.json` scripts that may be started. Only scripts that exist in a worktree's `package.json` are shown. |
61
+ | `command` | `npm run {script} -- --port {port}` | Command template. `{script}` and `{port}` are substituted before running. |
62
+ | `basePort` | `4200` | Port for the first worktree; each subsequent worktree gets `basePort + index`, skipping ports already in use. |
63
+
64
+ When `run` is configured, each worktree card gets a **Start** control. Starting a script launches it in the worktree directory with the assigned port (also exported as the `PORT` env var) and shows a clickable `localhost:<port>` link. **Stop** terminates the process group. Processes are also stopped when the dashboard shuts down.
65
+
66
+ For an Angular worktree, the default command runs `ng serve --port 4201`, `4202`, … one per worktree. Frameworks that read the `PORT` env var (Next.js, Create React App) work with a simpler `"command": "npm run {script}"`.
67
+
68
+ ## Worktree templates
69
+
70
+ Templates let you turn a repetitive setup into a one-click flow: pick a **Type** in the
71
+ "New worktree" dialog, fill in a field (e.g. a review ID), and the dashboard creates the
72
+ worktree and opens VS Code with Claude already started on a predefined prompt.
73
+
74
+ Add a `templates` array to your config:
75
+
76
+ ```json
77
+ {
78
+ "templates": [
79
+ {
80
+ "id": "review",
81
+ "label": "Review (ADO)",
82
+ "fields": [
83
+ { "key": "id", "label": "ADO Review ID", "placeholder": "12345" }
84
+ ],
85
+ "name": "review-{id}",
86
+ "branch": "review/{id}",
87
+ "prompt": "You are doing a peer review for Azure DevOps review #{id}.\nSummarize the changes on this branch, look for correctness, security, and style issues, and list anything that needs the author's attention."
88
+ }
89
+ ]
90
+ }
91
+ ```
92
+
93
+ `{key}` placeholders in `name`, `branch`, and `prompt` are replaced with the values you
94
+ type. On create, the dashboard writes two files into the new worktree:
95
+
96
+ - `CLAUDE_TASK.md` — the interpolated prompt.
97
+ - `.vscode/tasks.json` — a `folderOpen` task that runs `claude` against that prompt.
98
+
99
+ > **First run:** VS Code asks once to trust the folder and to *Allow Automatic Tasks*.
100
+ > After you allow it, future template worktrees launch Claude automatically. Both files are
101
+ > left untracked in the worktree — add them to a global gitignore if you'd rather not see
102
+ > them in the changed-files list.
103
+
104
+ ## How it works
105
+
106
+ The dashboard reads from `~/.claude/projects/` — the JSONL session files written by Claude Code as it runs agents in each worktree. It parses these files to determine the current status of each agent (working, thinking, waiting, done, idle) and surfaces the last tool used, last file touched, and last message.
107
+
108
+ Each worktree card links to VS Code so you can jump straight to the relevant file.
109
+
110
+ ## Requirements
111
+
112
+ - Node.js 18+
113
+ - git
114
+ - VS Code with `code` on PATH
115
+
116
+ ## WSL
117
+
118
+ On Windows Subsystem for Linux the browser opens automatically via `explorer.exe`.
119
+
120
+ ## License
121
+
122
+ MIT
package/bin/cli.mjs ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { resolve, join } from 'path';
4
+ import { spawn } from 'child_process';
5
+ import { createServer } from '../src/server.mjs';
6
+
7
+ const VERSION = '0.1.0';
8
+
9
+ function parseArgs(argv) {
10
+ const args = {};
11
+ for (let i = 0; i < argv.length; i++) {
12
+ if (argv[i] === '--port' && argv[i + 1]) args.port = parseInt(argv[++i], 10);
13
+ else if (argv[i] === '--logo' && argv[i + 1]) args.logo = argv[++i];
14
+ else if (argv[i] === '--title' && argv[i + 1]) args.title = argv[++i];
15
+ else if (argv[i] === '--worktrees' && argv[i + 1]) args.worktrees = argv[++i];
16
+ else if (argv[i] === '--config' && argv[i + 1]) args.configPath = argv[++i];
17
+ }
18
+ return args;
19
+ }
20
+
21
+ function loadFileConfig(configPath) {
22
+ const filePath = configPath || join(process.cwd(), '.worktree-dashboard.json');
23
+ if (existsSync(filePath)) {
24
+ try {
25
+ return JSON.parse(readFileSync(filePath, 'utf8'));
26
+ } catch (e) {
27
+ console.error(`Warning: failed to parse config file: ${e.message}`);
28
+ }
29
+ }
30
+ return {};
31
+ }
32
+
33
+ function normalizeRunConfig(run) {
34
+ if (!run) return null;
35
+ return {
36
+ scripts: Array.isArray(run.scripts) && run.scripts.length ? run.scripts : ['start'],
37
+ command: typeof run.command === 'string' ? run.command : 'npm run {script} -- --port {port}',
38
+ basePort: Number.isInteger(run.basePort) ? run.basePort : 4200,
39
+ };
40
+ }
41
+
42
+ function loadLogo(logoPath) {
43
+ if (!logoPath) return null;
44
+ const resolved = resolve(process.cwd(), logoPath);
45
+ if (!existsSync(resolved)) return null;
46
+ const ext = resolved.split('.').pop().toLowerCase();
47
+ const mimeMap = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', svg: 'image/svg+xml', webp: 'image/webp' };
48
+ const mime = mimeMap[ext] || 'image/png';
49
+ const data = readFileSync(resolved).toString('base64');
50
+ return `data:${mime};base64,${data}`;
51
+ }
52
+
53
+ function openBrowser(url) {
54
+ try {
55
+ const procVersion = readFileSync('/proc/version', 'utf8').toLowerCase();
56
+ if (procVersion.includes('microsoft')) {
57
+ spawn('explorer.exe', [url], { detached: true, stdio: 'ignore' });
58
+ return;
59
+ }
60
+ } catch {}
61
+ const platform = process.platform;
62
+ if (platform === 'darwin') {
63
+ spawn('open', [url], { detached: true, stdio: 'ignore' });
64
+ } else {
65
+ spawn('xdg-open', [url], { detached: true, stdio: 'ignore' });
66
+ }
67
+ }
68
+
69
+ function main() {
70
+ const cliArgs = parseArgs(process.argv.slice(2));
71
+ const fileConfig = loadFileConfig(cliArgs.configPath);
72
+
73
+ const config = {
74
+ port: cliArgs.port ?? fileConfig.port ?? 3333,
75
+ title: cliArgs.title ?? fileConfig.title ?? 'Worktree Dashboard',
76
+ worktrees: cliArgs.worktrees ?? fileConfig.worktrees ?? '.claude/worktrees',
77
+ logo: loadLogo(cliArgs.logo ?? fileConfig.logo),
78
+ run: normalizeRunConfig(fileConfig.run),
79
+ templates: fileConfig.templates ?? [],
80
+ cwd: process.cwd(),
81
+ version: VERSION,
82
+ };
83
+
84
+ const server = createServer(config);
85
+ server.listen(config.port, '127.0.0.1', () => {
86
+ const url = `http://localhost:${config.port}`;
87
+ console.log(`\n 🌳 Worktree Dashboard is up and running! (v${VERSION})`);
88
+ console.log(`\n Open it in your browser: ${url}`);
89
+ console.log(` Keeping an eye on ${config.worktrees}/ for you.`);
90
+ console.log('\n All set — press Ctrl+C whenever you want to stop.\n');
91
+ openBrowser(url);
92
+ });
93
+
94
+ process.on('SIGINT', () => {
95
+ console.log('\n 👋 Thanks for stopping by — shutting down. See you next time!\n');
96
+ server.close();
97
+ process.exit(0);
98
+ });
99
+ }
100
+
101
+ main();
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@poulles/worktree-dashboard",
3
+ "version": "0.1.0",
4
+ "description": "A local dashboard for monitoring and managing git worktrees with Claude Code agents",
5
+ "type": "module",
6
+ "bin": {
7
+ "worktree-dashboard": "./bin/cli.mjs"
8
+ },
9
+ "files": ["bin", "src"],
10
+ "engines": { "node": ">=18" },
11
+ "keywords": ["claude-code", "worktree", "git", "dashboard", "developer-tools"],
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/gpoulles/worktree-dashboard.git"
16
+ },
17
+ "bugs": { "url": "https://github.com/gpoulles/worktree-dashboard/issues" },
18
+ "homepage": "https://github.com/gpoulles/worktree-dashboard#readme",
19
+ "publishConfig": { "access": "public" }
20
+ }