tmux-ide 1.2.1 → 2.0.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/bin/cli.js +4 -216
- package/bin/cli.ts +536 -0
- package/package.json +33 -14
- package/src/__tests__/support.ts +186 -0
- package/src/{attach.js → attach.ts} +7 -4
- package/src/cli.test.ts +314 -0
- package/src/command-center/discovery.test.ts +265 -0
- package/src/command-center/discovery.ts +296 -0
- package/src/command-center/index.ts +31 -0
- package/src/command-center/schemas.ts +57 -0
- package/src/command-center/server.test.ts +818 -0
- package/src/command-center/server.ts +1426 -0
- package/src/config-cli.test.ts +86 -0
- package/src/config.test.ts +205 -0
- package/src/config.ts +313 -0
- package/src/detect.test.ts +142 -0
- package/src/{detect.js → detect.ts} +31 -15
- package/src/dispatch.ts +102 -0
- package/src/doctor.test.ts +119 -0
- package/src/doctor.ts +167 -0
- package/src/init.test.ts +101 -0
- package/src/init.ts +144 -0
- package/src/inspect.test.ts +67 -0
- package/src/{inspect.js → inspect.ts} +95 -10
- package/src/integration.test.ts.skip +276 -0
- package/src/js-yaml.d.ts +10 -0
- package/src/launch.test.ts +222 -0
- package/src/launch.ts +494 -0
- package/src/lib/auth/auth-service.test.ts +178 -0
- package/src/lib/auth/auth-service.ts +227 -0
- package/src/lib/auth/middleware.test.ts +119 -0
- package/src/lib/auth/middleware.ts +56 -0
- package/src/lib/auth/types.ts +13 -0
- package/src/lib/authorship.test.ts +242 -0
- package/src/lib/authorship.ts +280 -0
- package/src/lib/cast/recorder.test.ts +127 -0
- package/src/lib/cast/recorder.ts +148 -0
- package/src/lib/daemon-watchdog.ts +102 -0
- package/src/lib/daemon.ts +417 -0
- package/src/lib/dot-path.test.ts +66 -0
- package/src/lib/dot-path.ts +17 -0
- package/src/lib/errors.ts +44 -0
- package/src/lib/event-log.test.ts +189 -0
- package/src/lib/event-log.ts +237 -0
- package/src/lib/github-pr.ts +182 -0
- package/src/lib/hq/client.test.ts +154 -0
- package/src/lib/hq/client.ts +142 -0
- package/src/lib/hq/mdns.test.ts +54 -0
- package/src/lib/hq/mdns.ts +88 -0
- package/src/lib/hq/registry.test.ts +237 -0
- package/src/lib/hq/registry.ts +145 -0
- package/src/lib/hq/types.ts +44 -0
- package/src/lib/ipc/socket-protocol.test.ts +126 -0
- package/src/lib/ipc/socket-protocol.ts +324 -0
- package/src/lib/launch-plan.test.ts +119 -0
- package/src/lib/launch-plan.ts +90 -0
- package/src/lib/log.test.ts +39 -0
- package/src/lib/log.ts +71 -0
- package/src/lib/metrics.test.ts +213 -0
- package/src/lib/metrics.ts +345 -0
- package/src/lib/orchestrator.test.ts +2358 -0
- package/src/lib/orchestrator.ts +1792 -0
- package/src/lib/{output.js → output.ts} +18 -10
- package/src/lib/plan-store.test.ts +148 -0
- package/src/lib/plan-store.ts +131 -0
- package/src/lib/research.test.ts +208 -0
- package/src/lib/research.ts +475 -0
- package/src/lib/round-trip.test.ts +341 -0
- package/src/lib/session-monitor.test.ts +152 -0
- package/src/lib/session-monitor.ts +282 -0
- package/src/lib/session-options.test.ts +146 -0
- package/src/lib/{session-options.js → session-options.ts} +11 -6
- package/src/lib/shell.test.ts +20 -0
- package/src/lib/shell.ts +8 -0
- package/src/lib/sizes.test.ts +73 -0
- package/src/lib/{sizes.js → sizes.ts} +4 -4
- package/src/lib/skill-registry.test.ts +134 -0
- package/src/lib/skill-registry.ts +86 -0
- package/src/lib/slugify.test.ts +35 -0
- package/src/lib/slugify.ts +10 -0
- package/src/lib/task-store.ts +352 -0
- package/src/lib/tmux.test.ts +500 -0
- package/src/lib/tmux.ts +372 -0
- package/src/lib/token-tracker.test.ts +102 -0
- package/src/lib/token-tracker.ts +70 -0
- package/src/lib/tunnels/cloudflare.test.ts +73 -0
- package/src/lib/tunnels/cloudflare.ts +254 -0
- package/src/lib/tunnels/manager.test.ts +63 -0
- package/src/lib/tunnels/manager.ts +132 -0
- package/src/lib/tunnels/ngrok.test.ts +94 -0
- package/src/lib/tunnels/ngrok.ts +261 -0
- package/src/lib/tunnels/tailscale.test.ts +103 -0
- package/src/lib/tunnels/tailscale.ts +1048 -0
- package/src/lib/tunnels/types.ts +44 -0
- package/src/lib/validation.test.ts +289 -0
- package/src/lib/validation.ts +123 -0
- package/src/lib/webhook.ts +51 -0
- package/src/lib/workflow-store.ts +209 -0
- package/src/lib/ws-v3/protocol.test.ts +127 -0
- package/src/lib/ws-v3/protocol.ts +160 -0
- package/src/lib/yaml-io.test.ts +125 -0
- package/src/lib/{yaml-io.js → yaml-io.ts} +5 -4
- package/src/ls.test.ts +76 -0
- package/src/{ls.js → ls.ts} +4 -4
- package/src/metrics-cli.ts +177 -0
- package/src/notify.ts +85 -0
- package/src/orchestrator-status.ts +228 -0
- package/src/plan.ts +117 -0
- package/src/postinstall.test.ts +79 -0
- package/src/remote.test.ts +115 -0
- package/src/remote.ts +148 -0
- package/src/restart.ts +24 -0
- package/src/schemas/domain.ts +422 -0
- package/src/schemas/ide-config.ts +148 -0
- package/src/schemas/index.ts +53 -0
- package/src/send.test.ts +70 -0
- package/src/send.ts +181 -0
- package/src/skill.test.ts +114 -0
- package/src/skill.ts +138 -0
- package/src/status.ts +66 -0
- package/src/stop.test.ts +176 -0
- package/src/stop.ts +47 -0
- package/src/task.test.ts +1466 -0
- package/src/task.ts +1143 -0
- package/src/tunnel.test.ts +80 -0
- package/src/tunnel.ts +133 -0
- package/src/types.ts +15 -0
- package/src/ui/index.ts +32 -0
- package/src/ui/terminal/index.ts +9 -0
- package/src/ui/types.ts +91 -0
- package/src/ui/web/base.css +80 -0
- package/src/ui/web/components/Box.tsx +59 -0
- package/src/ui/web/components/Input.tsx +32 -0
- package/src/ui/web/components/ScrollBox.tsx +60 -0
- package/src/ui/web/components/Text.tsx +28 -0
- package/src/ui/web/hooks.ts +106 -0
- package/src/ui/web/index.ts +27 -0
- package/src/ui/web/render.ts +77 -0
- package/src/ui/web/utils/color.test.ts +93 -0
- package/src/ui/web/utils/color.ts +27 -0
- package/src/validate.test.ts +385 -0
- package/src/validate.ts +217 -0
- package/src/widgets/changes/index.tsx +576 -0
- package/src/widgets/config/index.tsx +440 -0
- package/src/widgets/costs/index.tsx +216 -0
- package/src/widgets/explorer/breadcrumbs.tsx +77 -0
- package/src/widgets/explorer/footer.tsx +20 -0
- package/src/widgets/explorer/header.tsx +23 -0
- package/src/widgets/explorer/index.tsx +408 -0
- package/src/widgets/explorer/tree-model.test.ts +214 -0
- package/src/widgets/explorer/tree-model.ts +103 -0
- package/src/widgets/explorer/tree.tsx +156 -0
- package/src/widgets/lib/config-model.ts +116 -0
- package/src/widgets/lib/files.test.ts +103 -0
- package/src/widgets/lib/files.ts +88 -0
- package/src/widgets/lib/git.test.ts +151 -0
- package/src/widgets/lib/git.ts +88 -0
- package/src/widgets/lib/pane-comms.test.ts +178 -0
- package/src/widgets/lib/pane-comms.ts +192 -0
- package/src/widgets/lib/theme.ts +151 -0
- package/src/widgets/lib/watcher.ts +50 -0
- package/src/widgets/mission-control/activity-feed.tsx +59 -0
- package/src/widgets/mission-control/agent-panel.tsx +132 -0
- package/src/widgets/mission-control/command-bar.tsx +63 -0
- package/src/widgets/mission-control/index.tsx +751 -0
- package/src/widgets/mission-control/task-panel.tsx +238 -0
- package/src/widgets/preview/index.tsx +415 -0
- package/src/widgets/resolve.ts +40 -0
- package/src/widgets/setup/agent-naming.tsx +112 -0
- package/src/widgets/setup/config-tree.tsx +238 -0
- package/src/widgets/setup/detect-panel.tsx +72 -0
- package/src/widgets/setup/field-editor.tsx +265 -0
- package/src/widgets/setup/footer.tsx +107 -0
- package/src/widgets/setup/index.tsx +340 -0
- package/src/widgets/setup/layout-picker.tsx +96 -0
- package/src/widgets/setup/orchestrator-panel.tsx +200 -0
- package/src/widgets/setup/review-panel.tsx +140 -0
- package/src/widgets/setup/setup-model.test.ts +303 -0
- package/src/widgets/setup/setup-model.ts +188 -0
- package/src/widgets/tasks/index.tsx +129 -0
- package/src/widgets/tasks/task-detail.tsx +309 -0
- package/src/widgets/tasks/task-form.tsx +193 -0
- package/src/widgets/tasks/task-list.tsx +205 -0
- package/src/widgets/tasks/task-model.test.ts +473 -0
- package/src/widgets/tasks/task-model.ts +157 -0
- package/templates/AGENTS.md +20 -0
- package/templates/missions.yml +41 -0
- package/templates/skills/backend.md +30 -0
- package/templates/skills/frontend.md +30 -0
- package/templates/skills/general-worker.md +30 -0
- package/templates/skills/researcher.md +69 -0
- package/templates/skills/reviewer.md +30 -0
- package/src/config.js +0 -341
- package/src/doctor.js +0 -91
- package/src/init.js +0 -73
- package/src/launch.js +0 -245
- package/src/lib/dot-path.js +0 -16
- package/src/lib/errors.js +0 -35
- package/src/lib/launch-plan.js +0 -49
- package/src/lib/session-monitor.js +0 -179
- package/src/lib/tmux.js +0 -237
- package/src/restart.js +0 -16
- package/src/status.js +0 -35
- package/src/stop.js +0 -25
- package/src/validate.js +0 -154
package/bin/cli.ts
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { resolve, dirname } from "node:path";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
import { launch } from "../src/launch.ts";
|
|
9
|
+
import { init } from "../src/init.ts";
|
|
10
|
+
import { stop } from "../src/stop.ts";
|
|
11
|
+
import { attach } from "../src/attach.ts";
|
|
12
|
+
import { ls } from "../src/ls.ts";
|
|
13
|
+
import { doctor } from "../src/doctor.ts";
|
|
14
|
+
import { status } from "../src/status.ts";
|
|
15
|
+
import { inspect } from "../src/inspect.ts";
|
|
16
|
+
import { validate } from "../src/validate.ts";
|
|
17
|
+
import { detect } from "../src/detect.ts";
|
|
18
|
+
import { config } from "../src/config.ts";
|
|
19
|
+
import { restart } from "../src/restart.ts";
|
|
20
|
+
import { taskCommand } from "../src/task.ts";
|
|
21
|
+
import { send } from "../src/send.ts";
|
|
22
|
+
import { IdeError } from "../src/lib/errors.ts";
|
|
23
|
+
import { printCommandError } from "../src/lib/output.ts";
|
|
24
|
+
|
|
25
|
+
const { positionals, values } = parseArgs({
|
|
26
|
+
allowPositionals: true,
|
|
27
|
+
strict: false,
|
|
28
|
+
options: {
|
|
29
|
+
json: { type: "boolean" },
|
|
30
|
+
row: { type: "string" },
|
|
31
|
+
pane: { type: "string" },
|
|
32
|
+
title: { type: "string" },
|
|
33
|
+
command: { type: "string" },
|
|
34
|
+
size: { type: "string" },
|
|
35
|
+
write: { type: "boolean" },
|
|
36
|
+
template: { type: "string" },
|
|
37
|
+
name: { type: "string" },
|
|
38
|
+
verbose: { type: "boolean", default: false },
|
|
39
|
+
help: { type: "boolean", short: "h" },
|
|
40
|
+
version: { type: "boolean", short: "v" },
|
|
41
|
+
// task command flags
|
|
42
|
+
description: { type: "string", short: "d" },
|
|
43
|
+
acceptance: { type: "string" },
|
|
44
|
+
priority: { type: "string", short: "p" },
|
|
45
|
+
status: { type: "string", short: "s" },
|
|
46
|
+
assign: { type: "string", short: "a" },
|
|
47
|
+
goal: { type: "string", short: "g" },
|
|
48
|
+
tags: { type: "string", short: "t" },
|
|
49
|
+
proof: { type: "string" },
|
|
50
|
+
depends: { type: "string" },
|
|
51
|
+
pr: { type: "boolean" },
|
|
52
|
+
specialty: { type: "string" },
|
|
53
|
+
milestone: { type: "string" },
|
|
54
|
+
fulfills: { type: "string" },
|
|
55
|
+
summary: { type: "string" },
|
|
56
|
+
sequence: { type: "string" },
|
|
57
|
+
evidence: { type: "string" },
|
|
58
|
+
port: { type: "string" },
|
|
59
|
+
// tunnel command flags
|
|
60
|
+
provider: { type: "string" },
|
|
61
|
+
domain: { type: "string" },
|
|
62
|
+
authtoken: { type: "string" },
|
|
63
|
+
// setup command flags
|
|
64
|
+
edit: { type: "boolean" },
|
|
65
|
+
wizard: { type: "boolean" },
|
|
66
|
+
// remote command flags
|
|
67
|
+
url: { type: "string" },
|
|
68
|
+
"hq-url": { type: "string" },
|
|
69
|
+
// send command flags
|
|
70
|
+
to: { type: "string" },
|
|
71
|
+
"no-enter": { type: "boolean" },
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const knownCommands = new Set([
|
|
76
|
+
"start",
|
|
77
|
+
"init",
|
|
78
|
+
"stop",
|
|
79
|
+
"attach",
|
|
80
|
+
"restart",
|
|
81
|
+
"ls",
|
|
82
|
+
"doctor",
|
|
83
|
+
"status",
|
|
84
|
+
"inspect",
|
|
85
|
+
"validate",
|
|
86
|
+
"detect",
|
|
87
|
+
"config",
|
|
88
|
+
"mission",
|
|
89
|
+
"milestone",
|
|
90
|
+
"goal",
|
|
91
|
+
"task",
|
|
92
|
+
"research",
|
|
93
|
+
"plan",
|
|
94
|
+
"skill",
|
|
95
|
+
"metrics",
|
|
96
|
+
"setup",
|
|
97
|
+
"send",
|
|
98
|
+
"dispatch",
|
|
99
|
+
"notify",
|
|
100
|
+
"orchestrator",
|
|
101
|
+
"settings",
|
|
102
|
+
"command-center",
|
|
103
|
+
"tunnel",
|
|
104
|
+
"remote",
|
|
105
|
+
"help",
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
// --version / -v
|
|
109
|
+
if (values.version) {
|
|
110
|
+
const pkg = await import("../package.json");
|
|
111
|
+
console.log(`tmux-ide v${pkg.version}`);
|
|
112
|
+
process.exit(0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (values.verbose) {
|
|
116
|
+
globalThis.__tmuxIdeVerbose = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const ALIASES: Record<string, string> = {
|
|
120
|
+
t: "task",
|
|
121
|
+
g: "goal",
|
|
122
|
+
m: "mission",
|
|
123
|
+
ms: "milestone",
|
|
124
|
+
orch: "orchestrator",
|
|
125
|
+
o: "orchestrator",
|
|
126
|
+
met: "metrics",
|
|
127
|
+
};
|
|
128
|
+
const firstPositional = positionals[0];
|
|
129
|
+
const resolved = ALIASES[firstPositional] ?? firstPositional;
|
|
130
|
+
const hasKnownCommand = resolved ? knownCommands.has(resolved) : false;
|
|
131
|
+
const command = hasKnownCommand ? resolved : "start";
|
|
132
|
+
const startTargetDir = hasKnownCommand ? positionals[1] : firstPositional;
|
|
133
|
+
const json = values.json ?? false;
|
|
134
|
+
|
|
135
|
+
const noColor = "NO_COLOR" in process.env;
|
|
136
|
+
const bold = (s: string) => (noColor ? s : `\x1b[1m${s}\x1b[22m`);
|
|
137
|
+
const cyan = (s: string) => (noColor ? s : `\x1b[36m${s}\x1b[39m`);
|
|
138
|
+
const dim = (s: string) => (noColor ? s : `\x1b[2m${s}\x1b[22m`);
|
|
139
|
+
|
|
140
|
+
if (values.help) {
|
|
141
|
+
printHelp();
|
|
142
|
+
process.exit(0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function printHelp() {
|
|
146
|
+
console.log(`${bold("tmux-ide")} — Terminal IDE powered by tmux
|
|
147
|
+
|
|
148
|
+
${bold("Usage:")}
|
|
149
|
+
${cyan("tmux-ide")} ${dim("Launch IDE from ide.yml")}
|
|
150
|
+
${cyan("tmux-ide <path>")} ${dim("Launch from a specific directory")}
|
|
151
|
+
${cyan("tmux-ide setup")} ${dim("Interactive TUI setup wizard")}
|
|
152
|
+
${cyan("tmux-ide setup --edit")} ${dim("Open config tree editor")}
|
|
153
|
+
${cyan("tmux-ide settings")} ${dim("Interactive TUI config manager")}
|
|
154
|
+
${cyan("tmux-ide init")} [--template] ${dim("Scaffold a new ide.yml (auto-detects stack)")}
|
|
155
|
+
${cyan("tmux-ide stop")} ${dim("Kill the current IDE session")}
|
|
156
|
+
${cyan("tmux-ide restart")} ${dim("Stop and relaunch the IDE session")}
|
|
157
|
+
${cyan("tmux-ide attach")} ${dim("Reattach to a running session")}
|
|
158
|
+
${cyan("tmux-ide ls")} ${dim("List all tmux sessions")}
|
|
159
|
+
${cyan("tmux-ide status")} [--json] ${dim("Show session status")}
|
|
160
|
+
${cyan("tmux-ide inspect")} [--json] ${dim("Show effective config and runtime state")}
|
|
161
|
+
${cyan("tmux-ide doctor")} ${dim("Check system requirements")}
|
|
162
|
+
${cyan("tmux-ide validate")} [--json] ${dim("Validate ide.yml")}
|
|
163
|
+
${cyan("tmux-ide detect")} [--json] ${dim("Detect project stack")}
|
|
164
|
+
${cyan("tmux-ide detect --write")} ${dim("Detect and write ide.yml")}
|
|
165
|
+
${cyan("tmux-ide config")} [--json] ${dim("Dump config as JSON")}
|
|
166
|
+
${cyan("tmux-ide config set")} <path> <value>
|
|
167
|
+
${cyan("tmux-ide config add-pane")} --row <N> --title <T> [--command <C>]
|
|
168
|
+
${cyan("tmux-ide config remove-pane")} --row <N> --pane <M>
|
|
169
|
+
${cyan("tmux-ide config add-row")} [--size <percent>]
|
|
170
|
+
${cyan("tmux-ide config enable-team")} [--name <N>] ${dim("Enable agent teams")}
|
|
171
|
+
${cyan("tmux-ide config disable-team")} ${dim("Disable agent teams")}
|
|
172
|
+
|
|
173
|
+
${bold("Pane Messaging:")}
|
|
174
|
+
${cyan("tmux-ide send")} <target> <message> ${dim("Send message to a pane")}
|
|
175
|
+
${cyan("tmux-ide send")} --to <name> <message> ${dim("Target by name, title, role, or ID")}
|
|
176
|
+
${cyan("tmux-ide send")} <target> --no-enter msg ${dim("Send text without pressing Enter")}
|
|
177
|
+
|
|
178
|
+
${bold("Dispatch:")}
|
|
179
|
+
${cyan("tmux-ide dispatch")} <id> [--json] ${dim("Print task context to stdout")}
|
|
180
|
+
${cyan("tmux-ide notify")} <message> [--json] ${dim("Send notification to lead pane")}
|
|
181
|
+
|
|
182
|
+
${bold("Orchestrator:")}
|
|
183
|
+
${cyan("tmux-ide orchestrator")} [--json] ${dim("Show orchestrator status")}
|
|
184
|
+
${cyan("tmux-ide orch")} ${dim("Alias for orchestrator")}
|
|
185
|
+
|
|
186
|
+
${bold("Task Management:")}
|
|
187
|
+
${cyan("tmux-ide mission set")} "title" ${dim("Set the project mission")}
|
|
188
|
+
${cyan("tmux-ide mission show")} ${dim("Show current mission")}
|
|
189
|
+
${cyan("tmux-ide goal list")} ${dim("List goals")}
|
|
190
|
+
${cyan("tmux-ide goal create")} "title" ${dim("Create a goal")}
|
|
191
|
+
${cyan("tmux-ide goal show")} <id> ${dim("Show goal with tasks")}
|
|
192
|
+
${cyan("tmux-ide task list")} [--status X --goal Y] ${dim("List tasks")}
|
|
193
|
+
${cyan("tmux-ide task create")} "title" [--goal id] ${dim("Create a task")}
|
|
194
|
+
${cyan("tmux-ide task claim")} <id> [--assign name] ${dim("Claim a task")}
|
|
195
|
+
${cyan("tmux-ide task done")} <id> [--proof "..."] ${dim("Complete a task")}
|
|
196
|
+
${cyan("tmux-ide task show")} <id> ${dim("Show task with full context")}
|
|
197
|
+
${cyan("tmux-ide research status")} ${dim("Show research agent state")}
|
|
198
|
+
${cyan("tmux-ide research trigger")} <type> ${dim("Manually dispatch a research task")}
|
|
199
|
+
|
|
200
|
+
${bold("Flags:")}
|
|
201
|
+
${cyan("--json")} ${dim("Output as JSON (all commands)")}
|
|
202
|
+
${cyan("--template <name>")} ${dim("Use specific template for init")}
|
|
203
|
+
${cyan("--write")} ${dim("Write detected config to ide.yml")}
|
|
204
|
+
${cyan("--verbose")} ${dim("Log all tmux commands (or set TMUX_IDE_DEBUG=1)")}
|
|
205
|
+
${cyan("-h, --help")} ${dim("Show usage")}
|
|
206
|
+
${cyan("-v, --version")} ${dim("Show version number")}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
switch (command) {
|
|
211
|
+
case "start":
|
|
212
|
+
await launch(startTargetDir, { json });
|
|
213
|
+
break;
|
|
214
|
+
|
|
215
|
+
case "init":
|
|
216
|
+
await init({ template: values.template, json });
|
|
217
|
+
break;
|
|
218
|
+
|
|
219
|
+
case "stop":
|
|
220
|
+
await stop(positionals[1], { json });
|
|
221
|
+
break;
|
|
222
|
+
|
|
223
|
+
case "attach":
|
|
224
|
+
await attach(positionals[1], { json });
|
|
225
|
+
break;
|
|
226
|
+
|
|
227
|
+
case "restart":
|
|
228
|
+
await restart(positionals[1], { json });
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
case "ls":
|
|
232
|
+
await ls({ json });
|
|
233
|
+
break;
|
|
234
|
+
|
|
235
|
+
case "doctor":
|
|
236
|
+
await doctor({ json });
|
|
237
|
+
break;
|
|
238
|
+
|
|
239
|
+
case "status":
|
|
240
|
+
await status(positionals[1], { json });
|
|
241
|
+
break;
|
|
242
|
+
|
|
243
|
+
case "inspect":
|
|
244
|
+
await inspect(positionals[1], { json });
|
|
245
|
+
break;
|
|
246
|
+
|
|
247
|
+
case "validate": {
|
|
248
|
+
const valSub = positionals[1];
|
|
249
|
+
if (
|
|
250
|
+
valSub === "assert" ||
|
|
251
|
+
valSub === "show" ||
|
|
252
|
+
valSub === "report" ||
|
|
253
|
+
valSub === "coverage" ||
|
|
254
|
+
valSub === "help"
|
|
255
|
+
) {
|
|
256
|
+
await taskCommand(null, {
|
|
257
|
+
json,
|
|
258
|
+
action: "validate",
|
|
259
|
+
sub: valSub,
|
|
260
|
+
args: positionals.slice(2),
|
|
261
|
+
values: {
|
|
262
|
+
status: values.status,
|
|
263
|
+
evidence: values.evidence,
|
|
264
|
+
assign: values.assign,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
} else {
|
|
268
|
+
await validate(valSub, { json });
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
case "detect":
|
|
274
|
+
await detect(positionals[1], { json, write: values.write });
|
|
275
|
+
break;
|
|
276
|
+
|
|
277
|
+
case "config": {
|
|
278
|
+
const sub = positionals[1];
|
|
279
|
+
let action = "dump";
|
|
280
|
+
let configArgs: string[] = [];
|
|
281
|
+
|
|
282
|
+
if (sub === "set") {
|
|
283
|
+
action = "set";
|
|
284
|
+
configArgs = positionals.slice(2);
|
|
285
|
+
} else if (sub === "add-pane") {
|
|
286
|
+
action = "add-pane";
|
|
287
|
+
configArgs = [];
|
|
288
|
+
if (values.row !== undefined) configArgs.push("--row", values.row);
|
|
289
|
+
if (values.title !== undefined) configArgs.push("--title", values.title);
|
|
290
|
+
if (values.command !== undefined) configArgs.push("--command", values.command);
|
|
291
|
+
if (values.size !== undefined) configArgs.push("--size", values.size);
|
|
292
|
+
} else if (sub === "remove-pane") {
|
|
293
|
+
action = "remove-pane";
|
|
294
|
+
configArgs = [];
|
|
295
|
+
if (values.row !== undefined) configArgs.push("--row", values.row);
|
|
296
|
+
if (values.pane !== undefined) configArgs.push("--pane", values.pane);
|
|
297
|
+
} else if (sub === "add-row") {
|
|
298
|
+
action = "add-row";
|
|
299
|
+
configArgs = [];
|
|
300
|
+
if (values.size !== undefined) configArgs.push("--size", values.size);
|
|
301
|
+
} else if (sub === "enable-team") {
|
|
302
|
+
action = "enable-team";
|
|
303
|
+
configArgs = [];
|
|
304
|
+
if (values.name !== undefined) configArgs.push("--name", values.name);
|
|
305
|
+
} else if (sub === "disable-team") {
|
|
306
|
+
action = "disable-team";
|
|
307
|
+
configArgs = [];
|
|
308
|
+
} else if (sub === "edit") {
|
|
309
|
+
const scriptPath = resolve(__dirname, "../src/widgets/setup/index.tsx");
|
|
310
|
+
execFileSync("bun", [scriptPath, "--dir=" + resolve(startTargetDir || "."), "--edit"], {
|
|
311
|
+
stdio: "inherit",
|
|
312
|
+
});
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
await config(null, { json, action, args: configArgs });
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
case "mission": {
|
|
321
|
+
const sub = positionals[1];
|
|
322
|
+
await taskCommand(null, {
|
|
323
|
+
json,
|
|
324
|
+
action: "mission",
|
|
325
|
+
sub,
|
|
326
|
+
args: positionals.slice(2),
|
|
327
|
+
values: { description: values.description },
|
|
328
|
+
});
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
case "milestone": {
|
|
333
|
+
const sub = positionals[1];
|
|
334
|
+
await taskCommand(null, {
|
|
335
|
+
json,
|
|
336
|
+
action: "milestone",
|
|
337
|
+
sub,
|
|
338
|
+
args: positionals.slice(2),
|
|
339
|
+
values: {
|
|
340
|
+
description: values.description,
|
|
341
|
+
status: values.status,
|
|
342
|
+
sequence: values.sequence,
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
case "goal": {
|
|
349
|
+
const sub = positionals[1];
|
|
350
|
+
await taskCommand(null, {
|
|
351
|
+
json,
|
|
352
|
+
action: "goal",
|
|
353
|
+
sub,
|
|
354
|
+
args: positionals.slice(2),
|
|
355
|
+
values: {
|
|
356
|
+
description: values.description,
|
|
357
|
+
acceptance: values.acceptance,
|
|
358
|
+
priority: values.priority,
|
|
359
|
+
status: values.status,
|
|
360
|
+
specialty: values.specialty,
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
case "task": {
|
|
367
|
+
const sub = positionals[1];
|
|
368
|
+
await taskCommand(null, {
|
|
369
|
+
json,
|
|
370
|
+
action: "task",
|
|
371
|
+
sub,
|
|
372
|
+
args: positionals.slice(2),
|
|
373
|
+
values: {
|
|
374
|
+
title: values.title,
|
|
375
|
+
description: values.description,
|
|
376
|
+
priority: values.priority,
|
|
377
|
+
status: values.status,
|
|
378
|
+
assign: values.assign,
|
|
379
|
+
goal: values.goal,
|
|
380
|
+
tags: values.tags,
|
|
381
|
+
proof: values.proof,
|
|
382
|
+
depends: values.depends,
|
|
383
|
+
pr: values.pr,
|
|
384
|
+
specialty: values.specialty,
|
|
385
|
+
milestone: values.milestone,
|
|
386
|
+
fulfills: values.fulfills,
|
|
387
|
+
summary: values.summary,
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
case "research": {
|
|
394
|
+
const sub = positionals[1];
|
|
395
|
+
await taskCommand(null, {
|
|
396
|
+
json,
|
|
397
|
+
action: "research",
|
|
398
|
+
sub,
|
|
399
|
+
args: positionals.slice(2),
|
|
400
|
+
values: {},
|
|
401
|
+
});
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
case "plan": {
|
|
406
|
+
const { planCommand } = await import("../src/plan.ts");
|
|
407
|
+
await planCommand(null, {
|
|
408
|
+
json,
|
|
409
|
+
sub: positionals[1],
|
|
410
|
+
args: positionals.slice(2),
|
|
411
|
+
values: { status: values.status },
|
|
412
|
+
});
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
case "skill": {
|
|
417
|
+
const { skillCommand } = await import("../src/skill.ts");
|
|
418
|
+
await skillCommand(null, {
|
|
419
|
+
json,
|
|
420
|
+
sub: positionals[1],
|
|
421
|
+
args: positionals.slice(2),
|
|
422
|
+
});
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
case "metrics": {
|
|
427
|
+
const { metricsCommand } = await import("../src/metrics-cli.ts");
|
|
428
|
+
await metricsCommand(null, {
|
|
429
|
+
json,
|
|
430
|
+
sub: positionals[1],
|
|
431
|
+
});
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
case "setup": {
|
|
436
|
+
const scriptPath = resolve(__dirname, "../src/widgets/setup/index.tsx");
|
|
437
|
+
const setupArgs = [scriptPath, "--dir=" + resolve(startTargetDir || ".")];
|
|
438
|
+
if (positionals[1] === "--edit" || values.edit) setupArgs.push("--edit");
|
|
439
|
+
if (positionals[1] === "--wizard" || values.wizard) setupArgs.push("--wizard");
|
|
440
|
+
execFileSync("bun", setupArgs, { stdio: "inherit" });
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
case "send": {
|
|
445
|
+
const target = values.to ?? positionals[1];
|
|
446
|
+
const messageStart = values.to ? 1 : 2;
|
|
447
|
+
let message = positionals.slice(messageStart).join(" ");
|
|
448
|
+
if (!message && !process.stdin.isTTY) {
|
|
449
|
+
const { readFileSync } = await import("node:fs");
|
|
450
|
+
message = readFileSync(0, "utf-8").trim();
|
|
451
|
+
}
|
|
452
|
+
await send(null, { json, to: target, message, noEnter: values["no-enter"] });
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
case "dispatch": {
|
|
457
|
+
const { dispatch: dispatchCmd } = await import("../src/dispatch.ts");
|
|
458
|
+
const taskId = positionals[1];
|
|
459
|
+
await dispatchCmd(null, { taskId, json });
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
case "notify": {
|
|
464
|
+
const { notify: notifyCmd } = await import("../src/notify.ts");
|
|
465
|
+
const notifyMessage = positionals.slice(1).join(" ");
|
|
466
|
+
await notifyCmd(null, { message: notifyMessage || undefined, json });
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
case "orchestrator": {
|
|
471
|
+
const { orchestratorStatus } = await import("../src/orchestrator-status.ts");
|
|
472
|
+
await orchestratorStatus(positionals[1], { json });
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
case "settings": {
|
|
477
|
+
const scriptPath = resolve(__dirname, "../src/widgets/config/index.tsx");
|
|
478
|
+
execFileSync("bun", [scriptPath, "--dir=" + resolve(startTargetDir || ".")], {
|
|
479
|
+
stdio: "inherit",
|
|
480
|
+
});
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
case "tunnel": {
|
|
485
|
+
const { tunnelCommand } = await import("../src/tunnel.ts");
|
|
486
|
+
await tunnelCommand(null, {
|
|
487
|
+
json,
|
|
488
|
+
sub: positionals[1],
|
|
489
|
+
args: positionals.slice(2),
|
|
490
|
+
values: {
|
|
491
|
+
provider: values.provider,
|
|
492
|
+
port: values.port,
|
|
493
|
+
domain: values.domain,
|
|
494
|
+
authtoken: values.authtoken,
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
case "remote": {
|
|
501
|
+
const { remoteCommand } = await import("../src/remote.ts");
|
|
502
|
+
await remoteCommand(null, {
|
|
503
|
+
json,
|
|
504
|
+
sub: positionals[1],
|
|
505
|
+
args: positionals.slice(2),
|
|
506
|
+
values: {
|
|
507
|
+
url: values.url,
|
|
508
|
+
"hq-url": values["hq-url"],
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
case "command-center": {
|
|
515
|
+
const { startCommandCenter } = await import("../src/command-center/index.ts");
|
|
516
|
+
await startCommandCenter({ port: parseInt(values.port ?? "4000") });
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
case "help":
|
|
521
|
+
printHelp();
|
|
522
|
+
break;
|
|
523
|
+
|
|
524
|
+
default:
|
|
525
|
+
throw new IdeError(`Unknown command: ${command}\nRun "tmux-ide help" for usage.`, {
|
|
526
|
+
code: "USAGE",
|
|
527
|
+
exitCode: 1,
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
} catch (error) {
|
|
531
|
+
if (error instanceof IdeError) {
|
|
532
|
+
printCommandError(error, { json });
|
|
533
|
+
} else {
|
|
534
|
+
throw error;
|
|
535
|
+
}
|
|
536
|
+
}
|
package/package.json
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tmux-ide",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Turn any project into a tmux-powered terminal IDE with a simple ide.yml",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"tmux-ide": "bin/cli.
|
|
7
|
+
"tmux-ide": "bin/cli.ts"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
11
|
-
"src
|
|
12
|
-
"!src/**/*.test.js",
|
|
11
|
+
"src",
|
|
13
12
|
"scripts",
|
|
14
13
|
"skill",
|
|
15
14
|
"templates"
|
|
16
15
|
],
|
|
17
16
|
"scripts": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"test
|
|
22
|
-
"
|
|
17
|
+
"build": "tsc --noEmit",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"dev": "bun bin/cli.ts",
|
|
20
|
+
"test": "bun test",
|
|
21
|
+
"test:unit": "bun test src/ --ignore 'src/integration.test.ts'",
|
|
22
|
+
"test:integration": "bun test src/integration.test.ts",
|
|
23
|
+
"lint": "eslint bin scripts src",
|
|
23
24
|
"lint:workspace": "turbo run lint",
|
|
24
25
|
"format": "prettier --write .",
|
|
25
26
|
"format:check": "prettier --check .",
|
|
@@ -27,9 +28,9 @@
|
|
|
27
28
|
"typecheck:workspace": "turbo run typecheck",
|
|
28
29
|
"docs:build": "turbo run build --filter=@tmux-ide/docs",
|
|
29
30
|
"pack:check": "npm pack --dry-run --cache /tmp/tmux-ide-npm-cache > /dev/null",
|
|
30
|
-
"check": "pnpm run lint:workspace && pnpm run format:check && pnpm run test:unit && pnpm run docs:build && pnpm run pack:check",
|
|
31
|
-
"prepublishOnly": "pnpm run check",
|
|
31
|
+
"check": "pnpm run lint:workspace && pnpm run format:check && pnpm run typecheck && pnpm run test:unit && pnpm run docs:build && pnpm run pack:check",
|
|
32
32
|
"postinstall": "node scripts/postinstall.js",
|
|
33
|
+
"test:dashboard": "cd dashboard && pnpm test",
|
|
33
34
|
"docs": "turbo run dev --filter=@tmux-ide/docs"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"developer-tools"
|
|
41
42
|
],
|
|
42
43
|
"engines": {
|
|
43
|
-
"
|
|
44
|
+
"bun": ">=1.0"
|
|
44
45
|
},
|
|
45
46
|
"repository": {
|
|
46
47
|
"type": "git",
|
|
@@ -53,13 +54,31 @@
|
|
|
53
54
|
"license": "MIT",
|
|
54
55
|
"packageManager": "pnpm@10.21.0",
|
|
55
56
|
"dependencies": {
|
|
56
|
-
"
|
|
57
|
+
"@hono/node-server": "^1.19.11",
|
|
58
|
+
"@hono/zod-validator": "^0.7.6",
|
|
59
|
+
"@opentui/core": "^0.1.88",
|
|
60
|
+
"@opentui/core-darwin-arm64": "^0.1.88",
|
|
61
|
+
"@opentui/solid": "^0.1.88",
|
|
62
|
+
"@parcel/watcher": "^2.5.6",
|
|
63
|
+
"@types/ws": "^8.18.1",
|
|
64
|
+
"hono": "^4.12.8",
|
|
65
|
+
"ignore": "^7.0.5",
|
|
66
|
+
"js-yaml": "^4.1.1",
|
|
67
|
+
"node-pty": "1.2.0-beta.12",
|
|
68
|
+
"solid-js": "^1.9.11",
|
|
69
|
+
"ws": "^8.20.0",
|
|
70
|
+
"zod": "^4.3.6"
|
|
57
71
|
},
|
|
58
72
|
"devDependencies": {
|
|
59
73
|
"@eslint/js": "^10.0.1",
|
|
74
|
+
"@tsconfig/bun": "^1.0.10",
|
|
75
|
+
"@types/node": "^25.5.0",
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
77
|
+
"@typescript-eslint/parser": "^8.57.1",
|
|
60
78
|
"eslint": "^10.0.3",
|
|
61
79
|
"globals": "^17.4.0",
|
|
62
80
|
"prettier": "^3.8.1",
|
|
63
|
-
"turbo": "^2.3.3"
|
|
81
|
+
"turbo": "^2.3.3",
|
|
82
|
+
"typescript": "^5.9.3"
|
|
64
83
|
}
|
|
65
84
|
}
|