tmux-ide 2.1.2 → 2.1.4
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/dashboard/out/404/index.html +1 -1
- package/dashboard/out/404.html +1 -1
- package/dashboard/out/__next.__PAGE__.txt +1 -1
- package/dashboard/out/__next._full.txt +1 -1
- package/dashboard/out/__next._head.txt +1 -1
- package/dashboard/out/__next._index.txt +1 -1
- package/dashboard/out/__next._tree.txt +1 -1
- package/dashboard/out/_next/static/chunks/{422e1bb4d41ce5ba.js → aae0253c73fba984.js} +1 -1
- package/dashboard/out/_not-found/__next._full.txt +1 -1
- package/dashboard/out/_not-found/__next._head.txt +1 -1
- package/dashboard/out/_not-found/__next._index.txt +1 -1
- package/dashboard/out/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dashboard/out/_not-found/__next._not-found.txt +1 -1
- package/dashboard/out/_not-found/__next._tree.txt +1 -1
- package/dashboard/out/_not-found/index.html +1 -1
- package/dashboard/out/_not-found/index.txt +1 -1
- package/dashboard/out/index.html +1 -1
- package/dashboard/out/index.txt +1 -1
- package/dashboard/out/project/__fallback/__next._full.txt +2 -2
- package/dashboard/out/project/__fallback/__next._head.txt +1 -1
- package/dashboard/out/project/__fallback/__next._index.txt +1 -1
- package/dashboard/out/project/__fallback/__next._tree.txt +1 -1
- package/dashboard/out/project/__fallback/__next.project.$d$name.__PAGE__.txt +2 -2
- package/dashboard/out/project/__fallback/__next.project.$d$name.txt +1 -1
- package/dashboard/out/project/__fallback/__next.project.txt +1 -1
- package/dashboard/out/project/__fallback/index.html +1 -1
- package/dashboard/out/project/__fallback/index.txt +2 -2
- package/package.json +1 -1
- package/src/init.ts +78 -11
- package/src/launch.ts +121 -13
- package/src/lib/daemon.ts +7 -1
- package/src/lib/orchestrator.ts +3 -2
- package/src/stop.ts +9 -0
- package/templates/skills/backend.md +13 -0
- package/templates/skills/frontend.md +13 -0
- package/templates/skills/general-worker.md +13 -0
- package/templates/skills/researcher.md +9 -0
- package/templates/skills/reviewer.md +12 -0
- /package/dashboard/out/_next/static/{hKfaRIxA4e3yTmkv1VUnK → Tl1KoIH7mHCyjo5KtXqQ0}/_buildManifest.js +0 -0
- /package/dashboard/out/_next/static/{hKfaRIxA4e3yTmkv1VUnK → Tl1KoIH7mHCyjo5KtXqQ0}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/out/_next/static/{hKfaRIxA4e3yTmkv1VUnK → Tl1KoIH7mHCyjo5KtXqQ0}/_ssgManifest.js +0 -0
package/package.json
CHANGED
package/src/init.ts
CHANGED
|
@@ -30,25 +30,85 @@ function copyTemplateSkills(targetDir: string): string[] {
|
|
|
30
30
|
return created;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function
|
|
33
|
+
function scaffoldLibraryStubs(dir: string): string[] {
|
|
34
34
|
const created: string[] = [];
|
|
35
|
-
const skillsDir = join(dir, ".tmux-ide", "skills");
|
|
36
|
-
created.push(...copyTemplateSkills(skillsDir));
|
|
37
|
-
|
|
38
35
|
const libraryDir = join(dir, ".tmux-ide", "library");
|
|
39
36
|
if (!existsSync(libraryDir)) {
|
|
40
37
|
mkdirSync(libraryDir, { recursive: true });
|
|
41
38
|
created.push(libraryDir);
|
|
42
39
|
}
|
|
43
40
|
|
|
41
|
+
const archPath = join(libraryDir, "architecture.md");
|
|
42
|
+
if (!existsSync(archPath)) {
|
|
43
|
+
writeFileSync(
|
|
44
|
+
archPath,
|
|
45
|
+
"# Architecture\n\n<!-- Describe your project's architecture here. This context is injected into agent dispatch prompts. -->\n",
|
|
46
|
+
);
|
|
47
|
+
created.push(archPath);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const learningsPath = join(libraryDir, "learnings.md");
|
|
51
|
+
if (!existsSync(learningsPath)) {
|
|
52
|
+
writeFileSync(
|
|
53
|
+
learningsPath,
|
|
54
|
+
"# Learnings\n\n<!-- Task summaries are automatically appended here by the orchestrator. -->\n",
|
|
55
|
+
);
|
|
56
|
+
created.push(learningsPath);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return created;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function scaffoldValidationContract(dir: string): string[] {
|
|
63
|
+
const created: string[] = [];
|
|
64
|
+
const tasksDir = join(dir, ".tasks");
|
|
65
|
+
if (!existsSync(tasksDir)) {
|
|
66
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const contractPath = join(tasksDir, "validation-contract.md");
|
|
70
|
+
if (!existsSync(contractPath)) {
|
|
71
|
+
writeFileSync(
|
|
72
|
+
contractPath,
|
|
73
|
+
"# Validation Contract\n\n<!-- Define assertions that the validator agent will verify. Example: -->\n<!-- - VAL-001: All tests pass -->\n<!-- - VAL-002: No TypeScript errors -->\n<!-- - VAL-003: Lint passes with zero warnings -->\n",
|
|
74
|
+
);
|
|
75
|
+
created.push(contractPath);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return created;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function scaffoldAgentsMd(dir: string, name: string): string[] {
|
|
82
|
+
const created: string[] = [];
|
|
44
83
|
const agentsTemplatePath = resolve(__dirname, "..", "templates", "AGENTS.md");
|
|
45
84
|
if (existsSync(agentsTemplatePath)) {
|
|
46
85
|
const agentsPath = join(dir, "AGENTS.md");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
86
|
+
if (!existsSync(agentsPath)) {
|
|
87
|
+
const content = readFileSync(agentsTemplatePath, "utf-8").replace(/{{name}}/g, name);
|
|
88
|
+
writeFileSync(agentsPath, content);
|
|
89
|
+
created.push(agentsPath);
|
|
90
|
+
}
|
|
50
91
|
}
|
|
92
|
+
return created;
|
|
93
|
+
}
|
|
51
94
|
|
|
95
|
+
function isTeamTemplate(templateName: string): boolean {
|
|
96
|
+
return templateName === "missions" || templateName.startsWith("agent-team");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function scaffoldTeamWorkspace(dir: string, name: string): string[] {
|
|
100
|
+
const created: string[] = [];
|
|
101
|
+
created.push(...scaffoldLibraryStubs(dir));
|
|
102
|
+
created.push(...scaffoldValidationContract(dir));
|
|
103
|
+
created.push(...scaffoldAgentsMd(dir, name));
|
|
104
|
+
return created;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function scaffoldMissionsWorkspace(dir: string, name: string): string[] {
|
|
108
|
+
const created: string[] = [];
|
|
109
|
+
const skillsDir = join(dir, ".tmux-ide", "skills");
|
|
110
|
+
created.push(...copyTemplateSkills(skillsDir));
|
|
111
|
+
created.push(...scaffoldTeamWorkspace(dir, name));
|
|
52
112
|
return created;
|
|
53
113
|
}
|
|
54
114
|
|
|
@@ -76,10 +136,17 @@ export async function init({
|
|
|
76
136
|
const tmpPath = configPath + ".tmp";
|
|
77
137
|
writeFileSync(tmpPath, content);
|
|
78
138
|
renameSync(tmpPath, configPath);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
139
|
+
let created: string[];
|
|
140
|
+
if (template === "missions") {
|
|
141
|
+
created = scaffoldMissionsWorkspace(dir, name);
|
|
142
|
+
} else if (isTeamTemplate(template)) {
|
|
143
|
+
created = [
|
|
144
|
+
...copyTemplateSkills(join(dir, ".tmux-ide", "skills")),
|
|
145
|
+
...scaffoldTeamWorkspace(dir, name),
|
|
146
|
+
];
|
|
147
|
+
} else {
|
|
148
|
+
created = copyTemplateSkills(join(dir, ".tmux-ide", "skills"));
|
|
149
|
+
}
|
|
83
150
|
|
|
84
151
|
if (json) {
|
|
85
152
|
console.log(JSON.stringify({ created: true, template, name, paths: created }));
|
package/src/launch.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { resolve, dirname, join } from "node:path";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
|
-
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
6
6
|
import { readConfig, getSessionName } from "./lib/yaml-io.ts";
|
|
7
7
|
import { computeSizes, toSplitPercents } from "./lib/sizes.ts";
|
|
8
8
|
import { outputError } from "./lib/output.ts";
|
|
@@ -183,7 +183,9 @@ function runBeforeHook(command: string | undefined, dir: string): void {
|
|
|
183
183
|
async function waitForDaemon(port: number, maxAttempts = 30, delayMs = 100): Promise<boolean> {
|
|
184
184
|
for (let i = 0; i < maxAttempts; i++) {
|
|
185
185
|
try {
|
|
186
|
-
const res = await fetch(`http://localhost:${port}/health
|
|
186
|
+
const res = await fetch(`http://localhost:${port}/health`, {
|
|
187
|
+
signal: AbortSignal.timeout(1000),
|
|
188
|
+
});
|
|
187
189
|
if (res.ok) return true;
|
|
188
190
|
} catch {
|
|
189
191
|
// Not ready yet
|
|
@@ -233,6 +235,21 @@ export async function launch(
|
|
|
233
235
|
const daemonAlive = await isDaemonAlive(commandCenterPort);
|
|
234
236
|
if (!daemonAlive) {
|
|
235
237
|
console.log("Daemon not responding — restarting...");
|
|
238
|
+
|
|
239
|
+
// Clean up any orphaned daemon processes from previous runs
|
|
240
|
+
try {
|
|
241
|
+
execSync(`pkill -f "daemon-watchdog.ts ${session}" 2>/dev/null || true`, {
|
|
242
|
+
stdio: "ignore",
|
|
243
|
+
});
|
|
244
|
+
execSync(`pkill -f "daemon.ts ${session}" 2>/dev/null || true`, { stdio: "ignore" });
|
|
245
|
+
} catch {
|
|
246
|
+
// Best-effort cleanup
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Brief wait for orphaned processes to release the port
|
|
250
|
+
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
251
|
+
await sleep(500);
|
|
252
|
+
|
|
236
253
|
const monitorScript = resolve(
|
|
237
254
|
dirname(fileURLToPath(import.meta.url)),
|
|
238
255
|
"lib",
|
|
@@ -322,6 +339,18 @@ export async function launch(
|
|
|
322
339
|
// Store config hash for drift detection on re-launch
|
|
323
340
|
setSessionVariable(session, "@config_hash", configHash(config));
|
|
324
341
|
|
|
342
|
+
// Clean up any orphaned daemon processes from previous runs
|
|
343
|
+
try {
|
|
344
|
+
execSync(`pkill -f "daemon-watchdog.ts ${session}" 2>/dev/null || true`, { stdio: "ignore" });
|
|
345
|
+
execSync(`pkill -f "daemon.ts ${session}" 2>/dev/null || true`, { stdio: "ignore" });
|
|
346
|
+
} catch {
|
|
347
|
+
// Best-effort cleanup
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Brief wait for orphaned processes to release the port
|
|
351
|
+
const sleepAsync = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
352
|
+
await sleepAsync(500);
|
|
353
|
+
|
|
325
354
|
// Start background daemon watchdog (command center + session monitor)
|
|
326
355
|
const monitorScript = resolve(
|
|
327
356
|
dirname(fileURLToPath(import.meta.url)),
|
|
@@ -376,10 +405,22 @@ export function buildMasterAgentPrompt(config: IdeConfig): string {
|
|
|
376
405
|
.map((p: Pane) => p.title)
|
|
377
406
|
.filter(Boolean);
|
|
378
407
|
|
|
379
|
-
|
|
408
|
+
const isMissionsMode = config.orchestrator?.dispatch_mode === "missions";
|
|
409
|
+
|
|
410
|
+
const milestonesSection = isMissionsMode
|
|
411
|
+
? `
|
|
412
|
+
## Milestones
|
|
413
|
+
Milestones gate execution — tasks in M2 won't dispatch until M1 is validated.
|
|
414
|
+
- tmux-ide milestone create "title" --sequence N
|
|
415
|
+
- tmux-ide milestone list --json
|
|
416
|
+
- tmux-ide mission plan-complete (activates milestones, starts dispatch)
|
|
417
|
+
`
|
|
418
|
+
: "";
|
|
419
|
+
|
|
420
|
+
return `You are the Lead Agent for this tmux-ide session.
|
|
380
421
|
|
|
381
422
|
## Your role
|
|
382
|
-
You coordinate a team of coding agents. The human gives you high-level goals, and you break them into structured tasks that your teammates execute.
|
|
423
|
+
You coordinate a team of coding agents. The human gives you high-level goals, and you break them into structured tasks that your teammates execute. You plan, delegate, and review — you do not implement.
|
|
383
424
|
|
|
384
425
|
## Your teammates
|
|
385
426
|
${teammatePanes.map((t) => `- ${t}`).join("\n")}
|
|
@@ -388,21 +429,38 @@ ${teammatePanes.map((t) => `- ${t}`).join("\n")}
|
|
|
388
429
|
- tmux-ide mission set "title" --description "..."
|
|
389
430
|
- tmux-ide goal create "title" --priority N --acceptance "criteria"
|
|
390
431
|
- tmux-ide goal list --json
|
|
391
|
-
- tmux-ide task create "title" --goal NN --priority N
|
|
432
|
+
- tmux-ide task create "title" --goal NN --priority N --specialty "type" --fulfills "VAL-001,VAL-002"
|
|
392
433
|
- tmux-ide task list --json
|
|
393
434
|
- tmux-ide task show NNN --json (shows full mission→goal→task context)
|
|
394
435
|
- tmux-ide task done NNN --proof "what was accomplished"
|
|
395
436
|
- tmux-ide goal done NN
|
|
396
437
|
|
|
397
438
|
## How it works
|
|
398
|
-
1.
|
|
399
|
-
2.
|
|
400
|
-
3.
|
|
401
|
-
4.
|
|
402
|
-
5.
|
|
403
|
-
6.
|
|
439
|
+
1. Set the mission: tmux-ide mission set "title" --description "..."
|
|
440
|
+
2. Create goals with acceptance criteria
|
|
441
|
+
3. Create tasks under goals — use --specialty to hint agent type, --fulfills to link validation assertions
|
|
442
|
+
4. The orchestrator automatically dispatches unassigned tasks to idle teammates
|
|
443
|
+
5. Teammates work in the project directory
|
|
444
|
+
6. When teammates finish, they run tmux-ide task done
|
|
445
|
+
7. You get notified and review their work
|
|
446
|
+
8. You report progress to the human
|
|
447
|
+
${milestonesSection}
|
|
448
|
+
## Validation contracts
|
|
449
|
+
Define acceptance criteria in .tasks/validation-contract.md using assertion IDs:
|
|
450
|
+
**VAL-001**: All tests pass
|
|
451
|
+
**VAL-002**: No TypeScript errors
|
|
452
|
+
Link tasks to assertions: tmux-ide task create "title" --fulfills "VAL-001,VAL-002"
|
|
453
|
+
After a milestone's tasks complete, the Validator agent automatically verifies assertions.
|
|
454
|
+
|
|
455
|
+
## Knowledge library
|
|
456
|
+
- .tmux-ide/library/architecture.md — project context injected into agent prompts
|
|
457
|
+
- .tmux-ide/library/learnings.md — auto-appended by orchestrator after task completion
|
|
458
|
+
- AGENTS.md — project boundaries injected into all agent prompts
|
|
459
|
+
Update architecture.md when the project structure changes significantly.
|
|
404
460
|
|
|
405
461
|
## Important
|
|
462
|
+
- Do NOT use --assign when creating tasks — the orchestrator handles dispatch automatically
|
|
463
|
+
- Use --specialty to hint which agent type should pick it up
|
|
406
464
|
- Focus on PLANNING and REVIEWING, not implementing
|
|
407
465
|
- Break work into small, clear tasks (one per teammate)
|
|
408
466
|
- Each task should be completable independently
|
|
@@ -460,6 +518,22 @@ The \`--proof\` flag accepts either a plain string (stored as \`notes\`) or a JS
|
|
|
460
518
|
### Task Dependencies
|
|
461
519
|
|
|
462
520
|
Use \`--depends "001,002"\` to declare that a task depends on other tasks. The orchestrator will not dispatch a task until all its dependencies are complete.
|
|
521
|
+
|
|
522
|
+
### Milestones
|
|
523
|
+
|
|
524
|
+
\`\`\`bash
|
|
525
|
+
tmux-ide milestone create "title" --sequence N
|
|
526
|
+
tmux-ide milestone list [--json]
|
|
527
|
+
tmux-ide mission plan-complete # activate milestones and start dispatch
|
|
528
|
+
\`\`\`
|
|
529
|
+
|
|
530
|
+
### Validation
|
|
531
|
+
|
|
532
|
+
\`\`\`bash
|
|
533
|
+
tmux-ide validate show [--json]
|
|
534
|
+
tmux-ide validate assert VAL-001 --status passing --evidence "what you verified"
|
|
535
|
+
tmux-ide validate coverage [--json]
|
|
536
|
+
\`\`\`
|
|
463
537
|
`;
|
|
464
538
|
|
|
465
539
|
export function ensureTaskDocs(dir: string): void {
|
|
@@ -467,9 +541,43 @@ export function ensureTaskDocs(dir: string): void {
|
|
|
467
541
|
|
|
468
542
|
if (existsSync(claudeMdPath)) {
|
|
469
543
|
const content = readFileSync(claudeMdPath, "utf-8");
|
|
470
|
-
if (content.includes(TASK_DOCS_MARKER))
|
|
471
|
-
|
|
544
|
+
if (!content.includes(TASK_DOCS_MARKER)) {
|
|
545
|
+
writeFileSync(claudeMdPath, content + TASK_DOCS_SECTION);
|
|
546
|
+
}
|
|
472
547
|
} else {
|
|
473
548
|
writeFileSync(claudeMdPath, `# Project\n${TASK_DOCS_SECTION}`);
|
|
474
549
|
}
|
|
550
|
+
|
|
551
|
+
// Ensure library directory and stubs exist
|
|
552
|
+
const libraryDir = join(dir, ".tmux-ide", "library");
|
|
553
|
+
if (!existsSync(libraryDir)) {
|
|
554
|
+
mkdirSync(libraryDir, { recursive: true });
|
|
555
|
+
}
|
|
556
|
+
const archPath = join(libraryDir, "architecture.md");
|
|
557
|
+
if (!existsSync(archPath)) {
|
|
558
|
+
writeFileSync(
|
|
559
|
+
archPath,
|
|
560
|
+
"# Architecture\n\n<!-- Describe your project architecture here. This is injected into agent dispatch prompts. -->\n",
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
const learningsPath = join(libraryDir, "learnings.md");
|
|
564
|
+
if (!existsSync(learningsPath)) {
|
|
565
|
+
writeFileSync(
|
|
566
|
+
learningsPath,
|
|
567
|
+
"# Learnings\n\n<!-- Task summaries are automatically appended here by the orchestrator. -->\n",
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Ensure .tasks/ directory and validation contract stub
|
|
572
|
+
const tasksDir = join(dir, ".tasks");
|
|
573
|
+
if (!existsSync(tasksDir)) {
|
|
574
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
575
|
+
}
|
|
576
|
+
const contractPath = join(tasksDir, "validation-contract.md");
|
|
577
|
+
if (!existsSync(contractPath)) {
|
|
578
|
+
writeFileSync(
|
|
579
|
+
contractPath,
|
|
580
|
+
"# Validation Contract\n\n<!-- Define assertions for the validator agent. Example: -->\n<!-- - VAL-001: All tests pass -->\n<!-- - VAL-002: No TypeScript errors -->\n",
|
|
581
|
+
);
|
|
582
|
+
}
|
|
475
583
|
}
|
package/src/lib/daemon.ts
CHANGED
|
@@ -12,8 +12,14 @@ import { execFileSync } from "node:child_process";
|
|
|
12
12
|
import { existsSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { createServer, type Server } from "node:http";
|
|
15
|
+
import { createRequire } from "node:module";
|
|
15
16
|
import { computePortPanes, computeAgentStates } from "./session-monitor.ts";
|
|
16
17
|
|
|
18
|
+
// Anchor bare-specifier resolution to this file so dependencies like
|
|
19
|
+
// @hono/node-server resolve from tmux-ide's own node_modules regardless
|
|
20
|
+
// of the process's working directory.
|
|
21
|
+
const _require = createRequire(import.meta.url);
|
|
22
|
+
|
|
17
23
|
/** Remove dispatch files older than 24 hours */
|
|
18
24
|
function cleanupDispatchFiles(dir: string): void {
|
|
19
25
|
const dispatchDir = join(dir, ".tasks", "dispatch");
|
|
@@ -246,7 +252,7 @@ let httpServer: Server | null = null;
|
|
|
246
252
|
async function startCommandCenter(): Promise<void> {
|
|
247
253
|
try {
|
|
248
254
|
const { createApp } = await import("../command-center/server.ts");
|
|
249
|
-
const { getRequestListener } = await import("@hono/node-server");
|
|
255
|
+
const { getRequestListener } = await import(_require.resolve("@hono/node-server"));
|
|
250
256
|
const { AuthService } = await import("./auth/auth-service.ts");
|
|
251
257
|
const { AuthConfigSchema } = await import("./auth/types.ts");
|
|
252
258
|
const { TunnelManager } = await import("./tunnels/manager.ts");
|
package/src/lib/orchestrator.ts
CHANGED
|
@@ -236,8 +236,9 @@ export function buildTaskPrompt(dir: string, task: Task, config?: OrchestratorCo
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// 4. Skill context
|
|
239
|
-
|
|
240
|
-
const
|
|
239
|
+
{
|
|
240
|
+
const skillName = task.specialty ?? "general-worker";
|
|
241
|
+
const skill = loadSkill(dir, skillName);
|
|
241
242
|
if (skill?.body) {
|
|
242
243
|
prompt += `## Your Role: ${skill.name}\n`;
|
|
243
244
|
prompt += `${skill.body}\n\n`;
|
package/src/stop.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
2
3
|
import { getSessionName } from "./lib/yaml-io.ts";
|
|
3
4
|
import { outputError } from "./lib/output.ts";
|
|
4
5
|
import { killSession, stopSessionMonitor } from "./lib/tmux.ts";
|
|
@@ -13,6 +14,14 @@ export async function stop(
|
|
|
13
14
|
// Stop the session monitor before killing the session
|
|
14
15
|
stopSessionMonitor(session);
|
|
15
16
|
|
|
17
|
+
// Kill any orphaned daemon processes for this session
|
|
18
|
+
try {
|
|
19
|
+
execSync(`pkill -f "daemon-watchdog.ts ${session}" 2>/dev/null || true`, { stdio: "ignore" });
|
|
20
|
+
execSync(`pkill -f "daemon.ts ${session}" 2>/dev/null || true`, { stdio: "ignore" });
|
|
21
|
+
} catch {
|
|
22
|
+
// Best-effort cleanup
|
|
23
|
+
}
|
|
24
|
+
|
|
16
25
|
const result = killSession(session);
|
|
17
26
|
|
|
18
27
|
if (result.stopped) {
|
|
@@ -21,6 +21,19 @@ You are a backend development specialist.
|
|
|
21
21
|
4. Verify behavior against acceptance criteria
|
|
22
22
|
5. Report the result, evidence, and any operational concerns
|
|
23
23
|
|
|
24
|
+
## Context
|
|
25
|
+
|
|
26
|
+
Your dispatch prompt includes relevant excerpts from the knowledge library (.tmux-ide/library/) and AGENTS.md. Use these for architectural decisions.
|
|
27
|
+
|
|
28
|
+
## After Completion
|
|
29
|
+
|
|
30
|
+
When you finish, the orchestrator will:
|
|
31
|
+
|
|
32
|
+
- Notify the lead with your proof and summary
|
|
33
|
+
- Run any configured after-run hooks (e.g., linting)
|
|
34
|
+
- Auto-dispatch the next available task
|
|
35
|
+
- Append your summary to the learnings library
|
|
36
|
+
|
|
24
37
|
## Completion Protocol
|
|
25
38
|
|
|
26
39
|
When done, run:
|
|
@@ -21,6 +21,19 @@ You are a frontend development specialist.
|
|
|
21
21
|
4. Run relevant tests or validation checks
|
|
22
22
|
5. Report what changed, what you verified, and any follow-up risks
|
|
23
23
|
|
|
24
|
+
## Context
|
|
25
|
+
|
|
26
|
+
Your dispatch prompt includes relevant excerpts from the knowledge library (.tmux-ide/library/) and AGENTS.md. Use these for architectural decisions.
|
|
27
|
+
|
|
28
|
+
## After Completion
|
|
29
|
+
|
|
30
|
+
When you finish, the orchestrator will:
|
|
31
|
+
|
|
32
|
+
- Notify the lead with your proof and summary
|
|
33
|
+
- Run any configured after-run hooks (e.g., linting)
|
|
34
|
+
- Auto-dispatch the next available task
|
|
35
|
+
- Append your summary to the learnings library
|
|
36
|
+
|
|
24
37
|
## Completion Protocol
|
|
25
38
|
|
|
26
39
|
When done, run:
|
|
@@ -21,6 +21,19 @@ You are a general-purpose development agent.
|
|
|
21
21
|
4. Verify all tests pass
|
|
22
22
|
5. Report completion with proof and a summary of key learnings
|
|
23
23
|
|
|
24
|
+
## Context
|
|
25
|
+
|
|
26
|
+
You are a general-purpose agent. Your dispatch prompt includes mission, goal, and task context along with relevant library excerpts. Follow the task description closely.
|
|
27
|
+
|
|
28
|
+
## After Completion
|
|
29
|
+
|
|
30
|
+
When you finish, the orchestrator will:
|
|
31
|
+
|
|
32
|
+
- Notify the lead with your proof and summary
|
|
33
|
+
- Run any configured after-run hooks (e.g., linting)
|
|
34
|
+
- Auto-dispatch the next available task
|
|
35
|
+
- Append your summary to the learnings library
|
|
36
|
+
|
|
24
37
|
## Completion Protocol
|
|
25
38
|
|
|
26
39
|
When done, run:
|
|
@@ -67,3 +67,12 @@ Your proof should include:
|
|
|
67
67
|
- The most important findings
|
|
68
68
|
- Why they matter
|
|
69
69
|
- The exact next action you recommend
|
|
70
|
+
|
|
71
|
+
## After Completion
|
|
72
|
+
|
|
73
|
+
When you finish, the orchestrator will:
|
|
74
|
+
|
|
75
|
+
- Notify the lead with your proof and summary
|
|
76
|
+
- Run any configured after-run hooks
|
|
77
|
+
- Auto-dispatch the next available task
|
|
78
|
+
- Append your summary to the learnings library
|
|
@@ -28,3 +28,15 @@ tmux-ide validate assert <ASSERT_ID> --status failing --evidence "what's wrong"
|
|
|
28
28
|
tmux-ide validate assert <ASSERT_ID> --status blocked --evidence "why it's blocked"
|
|
29
29
|
|
|
30
30
|
The orchestrator will detect your results and advance the milestone automatically.
|
|
31
|
+
|
|
32
|
+
If you find issues beyond the validation contract:
|
|
33
|
+
tmux-ide task update <TASK_ID> --discovered-issues "description of issue"
|
|
34
|
+
|
|
35
|
+
## After Completion
|
|
36
|
+
|
|
37
|
+
When you finish, the orchestrator will:
|
|
38
|
+
|
|
39
|
+
- Notify the lead with your proof and summary
|
|
40
|
+
- Run any configured after-run hooks (e.g., linting)
|
|
41
|
+
- Auto-dispatch the next available task
|
|
42
|
+
- Append your summary to the learnings library
|
|
File without changes
|
|
File without changes
|
/package/dashboard/out/_next/static/{hKfaRIxA4e3yTmkv1VUnK → Tl1KoIH7mHCyjo5KtXqQ0}/_ssgManifest.js
RENAMED
|
File without changes
|