tmux-ide 1.3.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.
Files changed (236) hide show
  1. package/bin/cli.js +4 -216
  2. package/bin/cli.ts +536 -0
  3. package/package.json +27 -14
  4. package/src/__tests__/support.ts +186 -0
  5. package/src/attach.ts +20 -0
  6. package/src/cli.test.ts +314 -0
  7. package/src/command-center/discovery.test.ts +265 -0
  8. package/src/command-center/discovery.ts +296 -0
  9. package/src/command-center/index.ts +31 -0
  10. package/src/command-center/schemas.ts +57 -0
  11. package/src/command-center/server.test.ts +818 -0
  12. package/src/command-center/server.ts +1426 -0
  13. package/src/config-cli.test.ts +86 -0
  14. package/src/config.test.ts +205 -0
  15. package/src/config.ts +313 -0
  16. package/src/detect.test.ts +142 -0
  17. package/src/detect.ts +248 -0
  18. package/src/dispatch.ts +102 -0
  19. package/src/doctor.test.ts +119 -0
  20. package/src/doctor.ts +167 -0
  21. package/src/init.test.ts +101 -0
  22. package/src/init.ts +144 -0
  23. package/src/inspect.test.ts +67 -0
  24. package/src/inspect.ts +212 -0
  25. package/src/integration.test.ts.skip +276 -0
  26. package/src/js-yaml.d.ts +10 -0
  27. package/src/launch.test.ts +222 -0
  28. package/src/launch.ts +494 -0
  29. package/src/lib/auth/auth-service.test.ts +178 -0
  30. package/src/lib/auth/auth-service.ts +227 -0
  31. package/src/lib/auth/middleware.test.ts +119 -0
  32. package/src/lib/auth/middleware.ts +56 -0
  33. package/src/lib/auth/types.ts +13 -0
  34. package/src/lib/authorship.test.ts +242 -0
  35. package/src/lib/authorship.ts +280 -0
  36. package/src/lib/cast/recorder.test.ts +127 -0
  37. package/src/lib/cast/recorder.ts +148 -0
  38. package/src/lib/daemon-watchdog.ts +102 -0
  39. package/src/lib/daemon.ts +417 -0
  40. package/src/lib/dot-path.test.ts +66 -0
  41. package/src/lib/dot-path.ts +17 -0
  42. package/src/lib/errors.ts +44 -0
  43. package/src/lib/event-log.test.ts +189 -0
  44. package/src/lib/event-log.ts +237 -0
  45. package/src/lib/github-pr.ts +182 -0
  46. package/src/lib/hq/client.test.ts +154 -0
  47. package/src/lib/hq/client.ts +142 -0
  48. package/src/lib/hq/mdns.test.ts +54 -0
  49. package/src/lib/hq/mdns.ts +88 -0
  50. package/src/lib/hq/registry.test.ts +237 -0
  51. package/src/lib/hq/registry.ts +145 -0
  52. package/src/lib/hq/types.ts +44 -0
  53. package/src/lib/ipc/socket-protocol.test.ts +126 -0
  54. package/src/lib/ipc/socket-protocol.ts +324 -0
  55. package/src/lib/launch-plan.test.ts +119 -0
  56. package/src/lib/launch-plan.ts +90 -0
  57. package/src/lib/log.test.ts +39 -0
  58. package/src/lib/log.ts +71 -0
  59. package/src/lib/metrics.test.ts +213 -0
  60. package/src/lib/metrics.ts +345 -0
  61. package/src/lib/orchestrator.test.ts +2358 -0
  62. package/src/lib/orchestrator.ts +1792 -0
  63. package/src/lib/output.ts +76 -0
  64. package/src/lib/plan-store.test.ts +148 -0
  65. package/src/lib/plan-store.ts +131 -0
  66. package/src/lib/research.test.ts +208 -0
  67. package/src/lib/research.ts +475 -0
  68. package/src/lib/round-trip.test.ts +341 -0
  69. package/src/lib/session-monitor.test.ts +152 -0
  70. package/src/lib/session-monitor.ts +282 -0
  71. package/src/lib/session-options.test.ts +146 -0
  72. package/src/lib/session-options.ts +100 -0
  73. package/src/lib/shell.test.ts +20 -0
  74. package/src/lib/shell.ts +8 -0
  75. package/src/lib/sizes.test.ts +73 -0
  76. package/src/lib/sizes.ts +36 -0
  77. package/src/lib/skill-registry.test.ts +134 -0
  78. package/src/lib/skill-registry.ts +86 -0
  79. package/src/lib/slugify.test.ts +35 -0
  80. package/src/lib/slugify.ts +10 -0
  81. package/src/lib/task-store.ts +352 -0
  82. package/src/lib/tmux.test.ts +500 -0
  83. package/src/lib/tmux.ts +372 -0
  84. package/src/lib/token-tracker.test.ts +102 -0
  85. package/src/lib/token-tracker.ts +70 -0
  86. package/src/lib/tunnels/cloudflare.test.ts +73 -0
  87. package/src/lib/tunnels/cloudflare.ts +254 -0
  88. package/src/lib/tunnels/manager.test.ts +63 -0
  89. package/src/lib/tunnels/manager.ts +132 -0
  90. package/src/lib/tunnels/ngrok.test.ts +94 -0
  91. package/src/lib/tunnels/ngrok.ts +261 -0
  92. package/src/lib/tunnels/tailscale.test.ts +103 -0
  93. package/src/lib/tunnels/tailscale.ts +1048 -0
  94. package/src/lib/tunnels/types.ts +44 -0
  95. package/src/lib/validation.test.ts +289 -0
  96. package/src/lib/validation.ts +123 -0
  97. package/src/lib/webhook.ts +51 -0
  98. package/src/lib/workflow-store.ts +209 -0
  99. package/src/lib/ws-v3/protocol.test.ts +127 -0
  100. package/src/lib/ws-v3/protocol.ts +160 -0
  101. package/src/lib/yaml-io.test.ts +125 -0
  102. package/src/lib/yaml-io.ts +27 -0
  103. package/src/ls.test.ts +76 -0
  104. package/src/ls.ts +40 -0
  105. package/src/metrics-cli.ts +177 -0
  106. package/src/notify.ts +85 -0
  107. package/src/orchestrator-status.ts +228 -0
  108. package/src/plan.ts +117 -0
  109. package/src/postinstall.test.ts +79 -0
  110. package/src/remote.test.ts +115 -0
  111. package/src/remote.ts +148 -0
  112. package/src/restart.ts +24 -0
  113. package/src/schemas/domain.ts +422 -0
  114. package/src/schemas/ide-config.ts +148 -0
  115. package/src/schemas/index.ts +53 -0
  116. package/src/send.test.ts +70 -0
  117. package/src/send.ts +181 -0
  118. package/src/skill.test.ts +114 -0
  119. package/src/skill.ts +138 -0
  120. package/src/status.ts +66 -0
  121. package/src/stop.test.ts +176 -0
  122. package/src/stop.ts +47 -0
  123. package/src/task.test.ts +1466 -0
  124. package/src/task.ts +1143 -0
  125. package/src/tunnel.test.ts +80 -0
  126. package/src/tunnel.ts +133 -0
  127. package/src/types.ts +15 -0
  128. package/src/ui/index.ts +32 -0
  129. package/src/ui/terminal/index.ts +9 -0
  130. package/src/ui/types.ts +91 -0
  131. package/src/ui/web/base.css +80 -0
  132. package/src/ui/web/components/Box.tsx +59 -0
  133. package/src/ui/web/components/Input.tsx +32 -0
  134. package/src/ui/web/components/ScrollBox.tsx +60 -0
  135. package/src/ui/web/components/Text.tsx +28 -0
  136. package/src/ui/web/hooks.ts +106 -0
  137. package/src/ui/web/index.ts +27 -0
  138. package/src/ui/web/render.ts +77 -0
  139. package/src/ui/web/utils/color.test.ts +93 -0
  140. package/src/ui/web/utils/color.ts +27 -0
  141. package/src/validate.test.ts +385 -0
  142. package/src/validate.ts +217 -0
  143. package/src/widgets/changes/index.tsx +576 -0
  144. package/src/widgets/config/index.tsx +440 -0
  145. package/src/widgets/costs/index.tsx +216 -0
  146. package/src/widgets/explorer/breadcrumbs.tsx +77 -0
  147. package/src/widgets/explorer/footer.tsx +20 -0
  148. package/src/widgets/explorer/header.tsx +23 -0
  149. package/src/widgets/explorer/index.tsx +408 -0
  150. package/src/widgets/explorer/tree-model.test.ts +214 -0
  151. package/src/widgets/explorer/tree-model.ts +103 -0
  152. package/src/widgets/explorer/tree.tsx +156 -0
  153. package/src/widgets/lib/config-model.ts +116 -0
  154. package/src/widgets/lib/files.test.ts +103 -0
  155. package/src/widgets/lib/files.ts +88 -0
  156. package/src/widgets/lib/git.test.ts +151 -0
  157. package/src/widgets/lib/git.ts +88 -0
  158. package/src/widgets/lib/pane-comms.test.ts +178 -0
  159. package/src/widgets/lib/pane-comms.ts +192 -0
  160. package/src/widgets/lib/theme.ts +151 -0
  161. package/src/widgets/lib/watcher.ts +50 -0
  162. package/src/widgets/mission-control/activity-feed.tsx +59 -0
  163. package/src/widgets/mission-control/agent-panel.tsx +132 -0
  164. package/src/widgets/mission-control/command-bar.tsx +63 -0
  165. package/src/widgets/mission-control/index.tsx +751 -0
  166. package/src/widgets/mission-control/task-panel.tsx +238 -0
  167. package/src/widgets/preview/index.tsx +415 -0
  168. package/src/widgets/resolve.ts +40 -0
  169. package/src/widgets/setup/agent-naming.tsx +112 -0
  170. package/src/widgets/setup/config-tree.tsx +238 -0
  171. package/src/widgets/setup/detect-panel.tsx +72 -0
  172. package/src/widgets/setup/field-editor.tsx +265 -0
  173. package/src/widgets/setup/footer.tsx +107 -0
  174. package/src/widgets/setup/index.tsx +340 -0
  175. package/src/widgets/setup/layout-picker.tsx +96 -0
  176. package/src/widgets/setup/orchestrator-panel.tsx +200 -0
  177. package/src/widgets/setup/review-panel.tsx +140 -0
  178. package/src/widgets/setup/setup-model.test.ts +303 -0
  179. package/src/widgets/setup/setup-model.ts +188 -0
  180. package/src/widgets/tasks/index.tsx +129 -0
  181. package/src/widgets/tasks/task-detail.tsx +309 -0
  182. package/src/widgets/tasks/task-form.tsx +193 -0
  183. package/src/widgets/tasks/task-list.tsx +205 -0
  184. package/src/widgets/tasks/task-model.test.ts +473 -0
  185. package/src/widgets/tasks/task-model.ts +157 -0
  186. package/templates/AGENTS.md +20 -0
  187. package/templates/missions.yml +41 -0
  188. package/templates/skills/backend.md +30 -0
  189. package/templates/skills/frontend.md +30 -0
  190. package/templates/skills/general-worker.md +30 -0
  191. package/templates/skills/researcher.md +69 -0
  192. package/templates/skills/reviewer.md +30 -0
  193. package/dist/attach.d.ts +0 -3
  194. package/dist/attach.js +0 -14
  195. package/dist/config.d.ts +0 -5
  196. package/dist/config.js +0 -269
  197. package/dist/detect.d.ts +0 -15
  198. package/dist/detect.js +0 -228
  199. package/dist/doctor.d.ts +0 -3
  200. package/dist/doctor.js +0 -66
  201. package/dist/init.d.ts +0 -4
  202. package/dist/init.js +0 -67
  203. package/dist/inspect.d.ts +0 -54
  204. package/dist/inspect.js +0 -118
  205. package/dist/launch.d.ts +0 -22
  206. package/dist/launch.js +0 -174
  207. package/dist/lib/dot-path.d.ts +0 -2
  208. package/dist/lib/dot-path.js +0 -17
  209. package/dist/lib/errors.d.ts +0 -29
  210. package/dist/lib/errors.js +0 -37
  211. package/dist/lib/launch-plan.d.ts +0 -6
  212. package/dist/lib/launch-plan.js +0 -40
  213. package/dist/lib/output.d.ts +0 -9
  214. package/dist/lib/output.js +0 -65
  215. package/dist/lib/session-monitor.d.ts +0 -12
  216. package/dist/lib/session-monitor.js +0 -160
  217. package/dist/lib/session-options.d.ts +0 -13
  218. package/dist/lib/session-options.js +0 -85
  219. package/dist/lib/sizes.d.ts +0 -16
  220. package/dist/lib/sizes.js +0 -36
  221. package/dist/lib/tmux.d.ts +0 -42
  222. package/dist/lib/tmux.js +0 -225
  223. package/dist/lib/yaml-io.d.ts +0 -10
  224. package/dist/lib/yaml-io.js +0 -24
  225. package/dist/ls.d.ts +0 -3
  226. package/dist/ls.js +0 -35
  227. package/dist/restart.d.ts +0 -4
  228. package/dist/restart.js +0 -13
  229. package/dist/status.d.ts +0 -3
  230. package/dist/status.js +0 -29
  231. package/dist/stop.d.ts +0 -3
  232. package/dist/stop.js +0 -21
  233. package/dist/types.d.ts +0 -41
  234. package/dist/types.js +0 -1
  235. package/dist/validate.d.ts +0 -4
  236. package/dist/validate.js +0 -172
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: backend
3
+ specialties: [backend, api, database, server]
4
+ role: teammate
5
+ description: Backend development specialist
6
+ ---
7
+
8
+ You are a backend development specialist.
9
+
10
+ ## Capabilities
11
+
12
+ - Implement API endpoints and server-side workflows
13
+ - Design or update database interactions and data models
14
+ - Improve backend correctness, performance, and operational safety
15
+
16
+ ## Workflow
17
+
18
+ 1. Read the assigned task and surrounding system context
19
+ 2. Identify the affected API, database, or server paths
20
+ 3. Implement the change with focused tests
21
+ 4. Verify behavior against acceptance criteria
22
+ 5. Report the result, evidence, and any operational concerns
23
+
24
+ ## Completion Protocol
25
+
26
+ When done, run:
27
+ tmux-ide task done <TASK_ID> --proof "what changed and how you verified it" --summary "backend outcome"
28
+
29
+ If you find out-of-scope issues, report them:
30
+ tmux-ide task update <TASK_ID> --discovered-issues "description of issue"
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: frontend
3
+ specialties: [frontend, react, css, ui, components]
4
+ role: teammate
5
+ description: Frontend development specialist
6
+ ---
7
+
8
+ You are a frontend development specialist.
9
+
10
+ ## Capabilities
11
+
12
+ - Build and refine components and user interfaces
13
+ - Implement styling, layout, and interaction details
14
+ - Manage client-side state and data flow cleanly
15
+
16
+ ## Workflow
17
+
18
+ 1. Read the assigned task and any linked context
19
+ 2. Inspect the existing UI patterns and conventions
20
+ 3. Implement the smallest coherent change
21
+ 4. Run relevant tests or validation checks
22
+ 5. Report what changed, what you verified, and any follow-up risks
23
+
24
+ ## Completion Protocol
25
+
26
+ When done, run:
27
+ tmux-ide task done <TASK_ID> --proof "what changed and how you verified it" --summary "frontend outcome"
28
+
29
+ If you find out-of-scope issues, report them:
30
+ tmux-ide task update <TASK_ID> --discovered-issues "description of issue"
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: general-worker
3
+ specialties: []
4
+ role: teammate
5
+ description: General-purpose development agent
6
+ ---
7
+
8
+ You are a general-purpose development agent.
9
+
10
+ ## Capabilities
11
+
12
+ - Read, write, and refactor code across the full stack
13
+ - Run tests and fix failures
14
+ - Follow project conventions and style guides
15
+
16
+ ## Workflow
17
+
18
+ 1. Read the task description and any linked context
19
+ 2. Plan your approach before writing code
20
+ 3. Implement the solution with tests
21
+ 4. Verify all tests pass
22
+ 5. Report completion with proof and a summary of key learnings
23
+
24
+ ## Completion Protocol
25
+
26
+ When done, run:
27
+ tmux-ide task done <TASK_ID> --proof "what you accomplished" --summary "key learnings for future tasks"
28
+
29
+ If you discover out-of-scope issues, note them:
30
+ tmux-ide task update <TASK_ID> --discovered-issues "description of issue"
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: researcher
3
+ specialties: [research, audit, analysis]
4
+ role: researcher
5
+ description: Continuous internal auditing agent
6
+ ---
7
+
8
+ You are the continuous internal auditing agent.
9
+
10
+ ## Mission
11
+
12
+ Surface useful findings early without stalling delivery. Prefer high-signal observations, concrete evidence, and actionable next steps over broad commentary.
13
+
14
+ ## Workflows
15
+
16
+ ### codebase-analysis
17
+
18
+ - Map the current implementation shape
19
+ - Identify hidden coupling, missing boundaries, and drift from stated mission goals
20
+ - Recommend the smallest set of follow-up tasks that materially reduce risk
21
+
22
+ ### code-review
23
+
24
+ - Review recent changes for correctness, regressions, and weak assumptions
25
+ - Prioritize concrete defects and missing tests
26
+ - Avoid style-only feedback unless it affects maintainability or safety
27
+
28
+ ### architecture-audit
29
+
30
+ - Check whether the current design still matches the mission and milestone plan
31
+ - Flag structural risks, brittle ownership boundaries, and missing operational constraints
32
+ - Write durable findings suitable for `.tmux-ide/library/architecture.md`
33
+
34
+ ### test-coverage
35
+
36
+ - Evaluate whether tests cover the real behavior and failure modes
37
+ - Highlight blind spots, flaky areas, and missing assertions
38
+ - Recommend specific tests, not generic “add coverage” advice
39
+
40
+ ### contract-audit
41
+
42
+ - Compare implementation and tasks against the validation contract
43
+ - Look for unclaimed assertions, weak evidence, and ambiguous acceptance criteria
44
+ - Call out contract drift explicitly
45
+
46
+ ### incident-analysis
47
+
48
+ - Investigate retry clusters, stalls, or recurring failure patterns
49
+ - Focus on root causes, enabling constraints, and the best remediation path
50
+ - Prefer decompositions that reduce repeated agent failure
51
+
52
+ ### issue-triage
53
+
54
+ - Assess newly discovered issues for severity, scope, and urgency
55
+ - Recommend whether to fix now, defer, or isolate with a separate task
56
+ - Provide the clearest next action for the lead agent
57
+
58
+ ## Reporting Protocol
59
+
60
+ When you finish, record the result on your assigned task:
61
+
62
+ `tmux-ide task done <TASK_ID> --proof "findings, evidence, severity, next actions" --summary "short research takeaway"`
63
+
64
+ Your proof should include:
65
+
66
+ - What you inspected
67
+ - The most important findings
68
+ - Why they matter
69
+ - The exact next action you recommend
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: reviewer
3
+ specialties: [review, validation]
4
+ role: validator
5
+ description: Code review and validation agent
6
+ ---
7
+
8
+ You are a code review and validation agent.
9
+
10
+ ## Capabilities
11
+
12
+ - Review code changes for correctness, security, and style
13
+ - Run test suites and verify assertions
14
+ - Verify that implementation matches acceptance criteria
15
+
16
+ ## Workflow
17
+
18
+ 1. Read the validation contract at .tasks/validation-contract.md
19
+ 2. For each assertion, verify the implementation satisfies it
20
+ 3. Run relevant tests or manual checks
21
+ 4. Report each assertion's status
22
+
23
+ ## Assertion Reporting
24
+
25
+ For each assertion:
26
+ tmux-ide validate assert <ASSERT_ID> --status passing --evidence "what you verified"
27
+ tmux-ide validate assert <ASSERT_ID> --status failing --evidence "what's wrong"
28
+ tmux-ide validate assert <ASSERT_ID> --status blocked --evidence "why it's blocked"
29
+
30
+ The orchestrator will detect your results and advance the milestone automatically.
package/dist/attach.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare function attach(targetDir: string | undefined, { json: _json }?: {
2
- json?: boolean;
3
- }): Promise<void>;
package/dist/attach.js DELETED
@@ -1,14 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { getSessionName } from "./lib/yaml-io.js";
3
- import { outputError } from "./lib/output.js";
4
- import { attachSession, getSessionState } from "./lib/tmux.js";
5
- export async function attach(targetDir, { json: _json } = {}) {
6
- const dir = resolve(targetDir ?? ".");
7
- const { name: session } = getSessionName(dir);
8
- const state = getSessionState(session);
9
- if (!state.running) {
10
- outputError(`Session "${session}" is not running. Start it with: tmux-ide`, "NOT_RUNNING");
11
- return;
12
- }
13
- attachSession(session);
14
- }
package/dist/config.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export declare function config(targetDir: string | null, { json, action, args }?: {
2
- json?: boolean;
3
- action?: string;
4
- args?: string[];
5
- }): Promise<void>;
package/dist/config.js DELETED
@@ -1,269 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { readConfig, writeConfig } from "./lib/yaml-io.js";
3
- import { setByPath } from "./lib/dot-path.js";
4
- import { outputError } from "./lib/output.js";
5
- /**
6
- * Read config safely (read-only, no write). Returns config or undefined on error.
7
- */
8
- function readConfigSafe(dir) {
9
- let cfg;
10
- try {
11
- ({ config: cfg } = readConfig(dir));
12
- }
13
- catch (e) {
14
- outputError(`Cannot read ide.yml: ${e.message}`, "READ_ERROR");
15
- return;
16
- }
17
- return cfg;
18
- }
19
- /**
20
- * Read config, validate it's an object, run mutator, then write back.
21
- * Returns the mutator's return value, or undefined on error.
22
- */
23
- function withConfig(dir, mutator) {
24
- const cfg = readConfigSafe(dir);
25
- if (cfg === undefined)
26
- return;
27
- if (!isConfigObject(cfg)) {
28
- outputError("Invalid ide.yml: config root must be an object", "INVALID_CONFIG");
29
- return;
30
- }
31
- const result = mutator(cfg);
32
- writeConfig(dir, cfg);
33
- return result;
34
- }
35
- export async function config(targetDir, { json, action, args } = {}) {
36
- const dir = resolve(targetDir ?? ".");
37
- switch (action) {
38
- case "dump":
39
- return dumpConfig(dir, { json });
40
- case "set":
41
- return setConfig(dir, args ?? [], { json });
42
- case "add-pane":
43
- return addPane(dir, args ?? [], { json });
44
- case "remove-pane":
45
- return removePane(dir, args ?? [], { json });
46
- case "add-row":
47
- return addRow(dir, args ?? [], { json });
48
- case "enable-team":
49
- return enableTeam(dir, args ?? [], { json });
50
- case "disable-team":
51
- return disableTeam(dir, { json });
52
- default:
53
- return dumpConfig(dir, { json });
54
- }
55
- }
56
- function dumpConfig(dir, { json }) {
57
- const cfg = readConfigSafe(dir);
58
- if (cfg === undefined)
59
- return;
60
- if (json) {
61
- console.log(JSON.stringify(cfg, null, 2));
62
- }
63
- else {
64
- console.log(JSON.stringify(cfg, null, 2));
65
- }
66
- }
67
- function setConfig(dir, args, { json }) {
68
- const [dotpath, ...rest] = args;
69
- if (!dotpath || rest.length === 0) {
70
- outputError("Usage: tmux-ide config set <dotpath> <value>", "USAGE");
71
- return;
72
- }
73
- let value = rest.join(" ");
74
- if (value === "true")
75
- value = true;
76
- else if (value === "false")
77
- value = false;
78
- else if (/^\d+$/.test(value))
79
- value = parseInt(value);
80
- withConfig(dir, (cfg) => {
81
- setByPath(cfg, dotpath, value);
82
- });
83
- if (json) {
84
- console.log(JSON.stringify({ ok: true, path: dotpath, value }, null, 2));
85
- }
86
- else {
87
- console.log(`Set ${dotpath} = ${JSON.stringify(value)}`);
88
- }
89
- }
90
- function addPane(dir, args, { json }) {
91
- const { row, title, command, size } = parseNamedArgs(args);
92
- if (row === undefined) {
93
- outputError("Usage: tmux-ide config add-pane --row <N> --title <T> [--command <C>] [--size <S>]", "USAGE");
94
- return;
95
- }
96
- const rowIdx = parseIndex(row);
97
- if (rowIdx == null) {
98
- outputError(`Invalid row index "${row}"`, "USAGE");
99
- return;
100
- }
101
- const pane = {};
102
- if (title)
103
- pane.title = title;
104
- if (command)
105
- pane.command = command;
106
- if (size)
107
- pane.size = size;
108
- withConfig(dir, (cfg) => {
109
- if (!Array.isArray(cfg.rows)) {
110
- outputError("Invalid ide.yml: 'rows' must be an array", "INVALID_CONFIG");
111
- }
112
- if (!cfg.rows[rowIdx]) {
113
- outputError(`Row ${rowIdx} does not exist`, "INVALID_ROW");
114
- }
115
- if (!Array.isArray(cfg.rows[rowIdx].panes)) {
116
- outputError(`Invalid ide.yml: row ${rowIdx} panes must be an array`, "INVALID_CONFIG");
117
- }
118
- cfg.rows[rowIdx].panes.push(pane);
119
- });
120
- if (json) {
121
- console.log(JSON.stringify({ ok: true, row: rowIdx, pane }, null, 2));
122
- }
123
- else {
124
- console.log(`Added pane "${title ?? "untitled"}" to row ${rowIdx}`);
125
- }
126
- }
127
- function removePane(dir, args, { json }) {
128
- const { row, pane } = parseNamedArgs(args);
129
- if (row === undefined || pane === undefined) {
130
- outputError("Usage: tmux-ide config remove-pane --row <N> --pane <M>", "USAGE");
131
- return;
132
- }
133
- const rowIdx = parseIndex(row);
134
- const paneIdx = parseIndex(pane);
135
- if (rowIdx == null || paneIdx == null) {
136
- outputError("Usage: tmux-ide config remove-pane --row <N> --pane <M>", "USAGE");
137
- return;
138
- }
139
- let removed;
140
- withConfig(dir, (cfg) => {
141
- if (!Array.isArray(cfg.rows)) {
142
- outputError("Invalid ide.yml: 'rows' must be an array", "INVALID_CONFIG");
143
- }
144
- if (!Array.isArray(cfg.rows[rowIdx]?.panes)) {
145
- outputError(`Invalid ide.yml: row ${rowIdx} panes must be an array`, "INVALID_CONFIG");
146
- }
147
- if (!cfg.rows[rowIdx].panes[paneIdx]) {
148
- outputError(`Pane ${paneIdx} in row ${rowIdx} does not exist`, "INVALID_PANE");
149
- }
150
- removed = cfg.rows[rowIdx].panes.splice(paneIdx, 1)[0];
151
- });
152
- if (json) {
153
- console.log(JSON.stringify({ ok: true, row: rowIdx, pane: paneIdx, removed }, null, 2));
154
- }
155
- else {
156
- console.log(`Removed pane ${paneIdx} ("${removed?.title ?? "untitled"}") from row ${rowIdx}`);
157
- }
158
- }
159
- function addRow(dir, args, { json }) {
160
- const { size } = parseNamedArgs(args);
161
- let rowIdx;
162
- withConfig(dir, (cfg) => {
163
- if (cfg.rows !== undefined && !Array.isArray(cfg.rows)) {
164
- outputError("Invalid ide.yml: 'rows' must be an array", "INVALID_CONFIG");
165
- }
166
- const row = { panes: [{ title: "Shell" }] };
167
- if (size)
168
- row.size = size;
169
- cfg.rows = cfg.rows ?? [];
170
- cfg.rows.push(row);
171
- rowIdx = cfg.rows.length - 1;
172
- });
173
- if (json) {
174
- console.log(JSON.stringify({ ok: true, row: rowIdx, size: size ?? null }, null, 2));
175
- }
176
- else {
177
- console.log(`Added row ${rowIdx}${size ? ` (${size})` : ""}`);
178
- }
179
- }
180
- function enableTeam(dir, args, { json }) {
181
- const { name } = parseNamedArgs(args);
182
- let teamName;
183
- let result;
184
- withConfig(dir, (cfg) => {
185
- if (cfg.rows !== undefined && !Array.isArray(cfg.rows)) {
186
- outputError("Invalid ide.yml: 'rows' must be an array", "INVALID_CONFIG");
187
- }
188
- teamName = name ?? cfg.name ?? "my-team";
189
- cfg.team = { name: teamName };
190
- let leadAssigned = false;
191
- for (const row of cfg.rows ?? []) {
192
- for (const pane of row.panes ?? []) {
193
- if (pane.command === "claude" || pane.role === "lead" || pane.role === "teammate") {
194
- if (!leadAssigned) {
195
- pane.role = "lead";
196
- leadAssigned = true;
197
- }
198
- else {
199
- pane.role = "teammate";
200
- }
201
- }
202
- }
203
- }
204
- if (!leadAssigned) {
205
- delete cfg.team;
206
- outputError("Cannot enable agent team: no Claude panes found", "INVALID_CONFIG");
207
- }
208
- result = { team: cfg.team, roles: summarizeRoles(cfg) };
209
- });
210
- if (json) {
211
- console.log(JSON.stringify({ ok: true, ...result }, null, 2));
212
- }
213
- else {
214
- console.log(`Enabled agent team "${teamName}"`);
215
- }
216
- }
217
- function disableTeam(dir, { json }) {
218
- withConfig(dir, (cfg) => {
219
- if (cfg.rows !== undefined && !Array.isArray(cfg.rows)) {
220
- outputError("Invalid ide.yml: 'rows' must be an array", "INVALID_CONFIG");
221
- }
222
- delete cfg.team;
223
- for (const row of cfg.rows ?? []) {
224
- if (!Array.isArray(row?.panes))
225
- continue;
226
- for (const pane of row.panes) {
227
- delete pane.role;
228
- delete pane.task;
229
- }
230
- }
231
- });
232
- if (json) {
233
- console.log(JSON.stringify({ ok: true, disabled: true }, null, 2));
234
- }
235
- else {
236
- console.log("Disabled agent team");
237
- }
238
- }
239
- function summarizeRoles(cfg) {
240
- const roles = [];
241
- for (let i = 0; i < (cfg.rows ?? []).length; i++) {
242
- for (let j = 0; j < (cfg.rows[i].panes ?? []).length; j++) {
243
- const p = cfg.rows[i].panes[j];
244
- if (p.role) {
245
- roles.push({ row: i, pane: j, title: p.title ?? null, role: p.role });
246
- }
247
- }
248
- }
249
- return roles;
250
- }
251
- function parseNamedArgs(args) {
252
- const result = {};
253
- for (let i = 0; i < args.length; i++) {
254
- if (args[i].startsWith("--") && i + 1 < args.length) {
255
- const key = args[i].slice(2);
256
- result[key] = args[i + 1];
257
- i++;
258
- }
259
- }
260
- return result;
261
- }
262
- function isConfigObject(value) {
263
- return value != null && typeof value === "object" && !Array.isArray(value);
264
- }
265
- function parseIndex(value) {
266
- if (!/^\d+$/.test(String(value)))
267
- return null;
268
- return Number.parseInt(value, 10);
269
- }
package/dist/detect.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { IdeConfig } from "./types.ts";
2
- interface DetectedStack {
3
- packageManager: string | null;
4
- frameworks: string[];
5
- devCommand: string | null;
6
- language: string | null;
7
- reasons: string[];
8
- }
9
- export declare function detectStack(dir: string): DetectedStack;
10
- export declare function suggestConfig(dir: string, detected: DetectedStack): IdeConfig;
11
- export declare function detect(targetDir: string | undefined, { json, write }?: {
12
- json?: boolean;
13
- write?: boolean;
14
- }): Promise<void>;
15
- export {};