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.
- package/bin/cli.js +4 -216
- package/bin/cli.ts +536 -0
- package/package.json +27 -14
- package/src/__tests__/support.ts +186 -0
- package/src/attach.ts +20 -0
- 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.ts +248 -0
- 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.ts +212 -0
- 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.ts +76 -0
- 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.ts +100 -0
- 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.ts +36 -0
- 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.ts +27 -0
- package/src/ls.test.ts +76 -0
- package/src/ls.ts +40 -0
- 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/dist/attach.d.ts +0 -3
- package/dist/attach.js +0 -14
- package/dist/config.d.ts +0 -5
- package/dist/config.js +0 -269
- package/dist/detect.d.ts +0 -15
- package/dist/detect.js +0 -228
- package/dist/doctor.d.ts +0 -3
- package/dist/doctor.js +0 -66
- package/dist/init.d.ts +0 -4
- package/dist/init.js +0 -67
- package/dist/inspect.d.ts +0 -54
- package/dist/inspect.js +0 -118
- package/dist/launch.d.ts +0 -22
- package/dist/launch.js +0 -174
- package/dist/lib/dot-path.d.ts +0 -2
- package/dist/lib/dot-path.js +0 -17
- package/dist/lib/errors.d.ts +0 -29
- package/dist/lib/errors.js +0 -37
- package/dist/lib/launch-plan.d.ts +0 -6
- package/dist/lib/launch-plan.js +0 -40
- package/dist/lib/output.d.ts +0 -9
- package/dist/lib/output.js +0 -65
- package/dist/lib/session-monitor.d.ts +0 -12
- package/dist/lib/session-monitor.js +0 -160
- package/dist/lib/session-options.d.ts +0 -13
- package/dist/lib/session-options.js +0 -85
- package/dist/lib/sizes.d.ts +0 -16
- package/dist/lib/sizes.js +0 -36
- package/dist/lib/tmux.d.ts +0 -42
- package/dist/lib/tmux.js +0 -225
- package/dist/lib/yaml-io.d.ts +0 -10
- package/dist/lib/yaml-io.js +0 -24
- package/dist/ls.d.ts +0 -3
- package/dist/ls.js +0 -35
- package/dist/restart.d.ts +0 -4
- package/dist/restart.js +0 -13
- package/dist/status.d.ts +0 -3
- package/dist/status.js +0 -29
- package/dist/stop.d.ts +0 -3
- package/dist/stop.js +0 -21
- package/dist/types.d.ts +0 -41
- package/dist/types.js +0 -1
- package/dist/validate.d.ts +0 -4
- 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
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
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 {};
|