@adamancyzhang/claude-orchestrator 0.2.8 → 0.3.1
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/README.md +179 -186
- package/dist/cli/commands.d.ts +13 -20
- package/dist/cli/commands.js +171 -288
- package/dist/cli/commands.js.map +1 -1
- package/dist/config.d.ts +25 -11
- package/dist/config.js +49 -13
- package/dist/config.js.map +1 -1
- package/dist/index.js +122 -215
- package/dist/index.js.map +1 -1
- package/dist/leader/decision-engine.d.ts +35 -0
- package/dist/leader/decision-engine.js +102 -0
- package/dist/leader/decision-engine.js.map +1 -0
- package/dist/leader/event-bus.d.ts +11 -0
- package/dist/leader/event-bus.js +21 -0
- package/dist/leader/event-bus.js.map +1 -0
- package/dist/leader/index.d.ts +7 -0
- package/dist/leader/index.js +96 -0
- package/dist/leader/index.js.map +1 -0
- package/dist/leader/monitor.d.ts +14 -0
- package/dist/leader/monitor.js +55 -0
- package/dist/leader/monitor.js.map +1 -0
- package/dist/leader/orchestrator.d.ts +14 -0
- package/dist/leader/orchestrator.js +83 -0
- package/dist/leader/orchestrator.js.map +1 -0
- package/dist/leader/recovery.d.ts +11 -0
- package/dist/leader/recovery.js +61 -0
- package/dist/leader/recovery.js.map +1 -0
- package/dist/leader/state.d.ts +24 -0
- package/dist/leader/state.js +122 -0
- package/dist/leader/state.js.map +1 -0
- package/dist/leader/task-generator.d.ts +34 -0
- package/dist/leader/task-generator.js +93 -0
- package/dist/leader/task-generator.js.map +1 -0
- package/dist/leader/tui.d.ts +5 -0
- package/dist/leader/tui.js +136 -0
- package/dist/leader/tui.js.map +1 -0
- package/dist/leader/watcher.d.ts +18 -0
- package/dist/leader/watcher.js +89 -0
- package/dist/leader/watcher.js.map +1 -0
- package/dist/models/schemas.d.ts +111 -100
- package/dist/models/schemas.js +54 -45
- package/dist/models/schemas.js.map +1 -1
- package/dist/modules/message-router.d.ts +2 -2
- package/dist/modules/message-router.js +10 -16
- package/dist/modules/message-router.js.map +1 -1
- package/dist/modules/registry.js +3 -3
- package/dist/modules/registry.js.map +1 -1
- package/dist/modules/task-queue.d.ts +4 -1
- package/dist/modules/task-queue.js +114 -10
- package/dist/modules/task-queue.js.map +1 -1
- package/dist/skills/CLAUDE.md +155 -0
- package/dist/skills/claude-code-developer/SKILL.md +325 -0
- package/dist/skills/claude-orchestrator/SKILL.md +180 -0
- package/dist/skills/task-acceptance/SKILL.md +201 -0
- package/dist/skills/task-execution/SKILL.md +142 -0
- package/dist/skills/task-planning/SKILL.md +188 -0
- package/dist/skills/task-review/SKILL.md +220 -0
- package/dist/skills/task-traceability/SKILL.md +154 -0
- package/dist/skills/task-verification/SKILL.md +194 -0
- package/dist/templates/leader-decide.md +59 -0
- package/dist/templates/leader-decompose.md +69 -0
- package/dist/templates/worker-accept.md +46 -0
- package/dist/templates/worker-build.md +45 -0
- package/dist/templates/worker-plan.md +43 -0
- package/dist/templates/worker-review.md +46 -0
- package/dist/templates/worker-verify.md +47 -0
- package/dist/utils/exec.d.ts +8 -0
- package/dist/utils/exec.js +45 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/worker/watcher.d.ts +19 -0
- package/dist/worker/watcher.js +152 -0
- package/dist/worker/watcher.js.map +1 -0
- package/dist/zk/client.d.ts +5 -5
- package/dist/zk/client.js +16 -26
- package/dist/zk/client.js.map +1 -1
- package/dist/zk/paths.d.ts +9 -9
- package/dist/zk/paths.js +4 -5
- package/dist/zk/paths.js.map +1 -1
- package/dist/zk/watcher.d.ts +0 -2
- package/dist/zk/watcher.js +0 -3
- package/dist/zk/watcher.js.map +1 -1
- package/package.json +3 -6
- package/dist/modules/context-store.d.ts +0 -10
- package/dist/modules/context-store.js +0 -25
- package/dist/modules/context-store.js.map +0 -1
- package/dist/modules/message-watcher.d.ts +0 -12
- package/dist/modules/message-watcher.js +0 -133
- package/dist/modules/message-watcher.js.map +0 -1
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -490
- package/dist/server.js.map +0 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
function taskLinkToRole(link) {
|
|
2
|
+
const map = {
|
|
3
|
+
plan: "planner",
|
|
4
|
+
build: "builder",
|
|
5
|
+
verify: "verifier",
|
|
6
|
+
review: "reviewer",
|
|
7
|
+
accept: "accepter",
|
|
8
|
+
};
|
|
9
|
+
return map[link] ?? link;
|
|
10
|
+
}
|
|
11
|
+
export class LeaderState {
|
|
12
|
+
workers = [];
|
|
13
|
+
pendingTasks = [];
|
|
14
|
+
claimedTasks = [];
|
|
15
|
+
completedTasks = [];
|
|
16
|
+
events = [];
|
|
17
|
+
leaderName = "";
|
|
18
|
+
leaderInstanceId = "";
|
|
19
|
+
cacheDir = "";
|
|
20
|
+
apply(event) {
|
|
21
|
+
const time = new Date().toLocaleTimeString();
|
|
22
|
+
switch (event.type) {
|
|
23
|
+
case "worker_joined": {
|
|
24
|
+
const inst = event.instance;
|
|
25
|
+
if (!inst)
|
|
26
|
+
return;
|
|
27
|
+
this.workers.push({
|
|
28
|
+
id: event.instanceId ?? inst.id,
|
|
29
|
+
name: inst.name,
|
|
30
|
+
presetRole: inst.role,
|
|
31
|
+
currentRole: null,
|
|
32
|
+
status: inst.status,
|
|
33
|
+
currentTaskId: inst.current_task_id ?? null,
|
|
34
|
+
});
|
|
35
|
+
this.events.push({ timestamp: time, message: `${inst.name} joined (${inst.role})` });
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case "worker_left":
|
|
39
|
+
this.workers = this.workers.filter(w => w.id !== event.instanceId);
|
|
40
|
+
this.events.push({ timestamp: time, message: `${event.name} left` });
|
|
41
|
+
break;
|
|
42
|
+
case "worker_status_changed": {
|
|
43
|
+
const w = this.workers.find(w => w.id === event.instanceId);
|
|
44
|
+
if (w) {
|
|
45
|
+
w.status = event.status;
|
|
46
|
+
w.currentTaskId = event.currentTaskId ?? null;
|
|
47
|
+
if (!w.currentTaskId)
|
|
48
|
+
w.currentRole = null;
|
|
49
|
+
}
|
|
50
|
+
this.events.push({ timestamp: time, message: `${event.name}: ${event.status}` });
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case "task_created": {
|
|
54
|
+
const task = event.task;
|
|
55
|
+
if (task)
|
|
56
|
+
this.pendingTasks.push(task);
|
|
57
|
+
this.events.push({ timestamp: time, message: `Task created: ${task?.title ?? event.taskId}` });
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case "task_claimed": {
|
|
61
|
+
const t = this.pendingTasks.find(t => t.id === event.taskId);
|
|
62
|
+
if (t) {
|
|
63
|
+
t.status = "claimed";
|
|
64
|
+
this.claimedTasks.push(t);
|
|
65
|
+
this.pendingTasks = this.pendingTasks.filter(t => t.id !== event.taskId);
|
|
66
|
+
}
|
|
67
|
+
// Derive currentRole from the task's link
|
|
68
|
+
const w = this.workers.find(w => w.id === event.instanceId);
|
|
69
|
+
if (w) {
|
|
70
|
+
const taskLink = t?.link ?? event.link ?? null;
|
|
71
|
+
w.currentRole = taskLink ? taskLinkToRole(taskLink) : null;
|
|
72
|
+
w.currentTaskId = event.taskId ?? null;
|
|
73
|
+
w.status = "busy";
|
|
74
|
+
}
|
|
75
|
+
this.events.push({ timestamp: time, message: `Task ${event.taskId} claimed by ${event.instanceId}` });
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case "task_completed": {
|
|
79
|
+
this.claimedTasks = this.claimedTasks.filter(t => t.id !== event.taskId);
|
|
80
|
+
if (event.task)
|
|
81
|
+
this.completedTasks.push(event.task);
|
|
82
|
+
// Clear currentRole for the worker
|
|
83
|
+
const w = this.workers.find(w => w.id === event.instanceId);
|
|
84
|
+
if (w) {
|
|
85
|
+
w.currentRole = null;
|
|
86
|
+
w.status = "idle";
|
|
87
|
+
w.currentTaskId = null;
|
|
88
|
+
}
|
|
89
|
+
this.events.push({ timestamp: time, message: `Task ${event.taskId} completed` });
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "task_blocked":
|
|
93
|
+
this.events.push({ timestamp: time, message: `Task ${event.taskId} blocked: ${event.reason}` });
|
|
94
|
+
break;
|
|
95
|
+
case "task_failed":
|
|
96
|
+
this.claimedTasks = this.claimedTasks.filter(t => t.id !== event.taskId);
|
|
97
|
+
{
|
|
98
|
+
const w = this.workers.find(w => w.id === event.instanceId);
|
|
99
|
+
if (w) {
|
|
100
|
+
w.currentRole = null;
|
|
101
|
+
w.status = "idle";
|
|
102
|
+
w.currentTaskId = null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
this.events.push({ timestamp: time, message: `Task ${event.taskId} failed: ${event.reason}` });
|
|
106
|
+
break;
|
|
107
|
+
case "task_recovered":
|
|
108
|
+
this.events.push({ timestamp: time, message: `Task ${event.taskId} recovered → ${event.newTaskId} (retry ${event.retryCount})` });
|
|
109
|
+
break;
|
|
110
|
+
case "message_received":
|
|
111
|
+
this.events.push({ timestamp: time, message: `Message from ${event.from}: ${event.content?.slice(0, 60)}...` });
|
|
112
|
+
break;
|
|
113
|
+
case "message_processed":
|
|
114
|
+
this.events.push({ timestamp: time, message: `Message ${event.msgId} processed` });
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
// Keep event log to last 100 entries
|
|
118
|
+
if (this.events.length > 100)
|
|
119
|
+
this.events.shift();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/leader/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ZkClient } from "../zk/client.js";
|
|
2
|
+
import { TaskQueue } from "../modules/task-queue.js";
|
|
3
|
+
interface ChainTaskDef {
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
criteria: string;
|
|
7
|
+
priority: number;
|
|
8
|
+
}
|
|
9
|
+
interface ChainDef {
|
|
10
|
+
chain_id: string;
|
|
11
|
+
chain_title: string;
|
|
12
|
+
tasks: {
|
|
13
|
+
plan: ChainTaskDef | null;
|
|
14
|
+
build: ChainTaskDef;
|
|
15
|
+
verify: ChainTaskDef;
|
|
16
|
+
review: ChainTaskDef;
|
|
17
|
+
accept: ChainTaskDef;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare class TaskGenerator {
|
|
21
|
+
private zk;
|
|
22
|
+
private taskQueue;
|
|
23
|
+
private command;
|
|
24
|
+
private cacheDir;
|
|
25
|
+
private leaderInstanceId;
|
|
26
|
+
private template;
|
|
27
|
+
private templatePath;
|
|
28
|
+
constructor(zk: ZkClient, taskQueue: TaskQueue, command: string, cacheDir: string, leaderInstanceId: string, templatePath?: string);
|
|
29
|
+
private loadTemplate;
|
|
30
|
+
decompose(requirement: string, teamStatus: object): Promise<ChainDef[]>;
|
|
31
|
+
private pushChain;
|
|
32
|
+
private parseOutput;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { expandHomeDir } from "../config.js";
|
|
4
|
+
import { execAndCapture } from "../utils/exec.js";
|
|
5
|
+
export class TaskGenerator {
|
|
6
|
+
zk;
|
|
7
|
+
taskQueue;
|
|
8
|
+
command;
|
|
9
|
+
cacheDir;
|
|
10
|
+
leaderInstanceId;
|
|
11
|
+
template = null;
|
|
12
|
+
templatePath;
|
|
13
|
+
constructor(zk, taskQueue, command, cacheDir, leaderInstanceId, templatePath) {
|
|
14
|
+
this.zk = zk;
|
|
15
|
+
this.taskQueue = taskQueue;
|
|
16
|
+
this.command = command;
|
|
17
|
+
this.cacheDir = cacheDir;
|
|
18
|
+
this.leaderInstanceId = leaderInstanceId;
|
|
19
|
+
this.templatePath = templatePath ?? path.join(process.cwd(), ".claude-orchestrator", "agents", "leader-decompose.md");
|
|
20
|
+
}
|
|
21
|
+
async loadTemplate() {
|
|
22
|
+
if (this.template)
|
|
23
|
+
return this.template;
|
|
24
|
+
try {
|
|
25
|
+
this.template = await fs.promises.readFile(this.templatePath, "utf-8");
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error(`Decompose template not found at ${this.templatePath}. Run setup first.`);
|
|
29
|
+
}
|
|
30
|
+
return this.template;
|
|
31
|
+
}
|
|
32
|
+
async decompose(requirement, teamStatus) {
|
|
33
|
+
const template = await this.loadTemplate();
|
|
34
|
+
const prompt = template
|
|
35
|
+
.replace("{{team_status}}", JSON.stringify(teamStatus, null, 2))
|
|
36
|
+
.replace("{{content}}", requirement);
|
|
37
|
+
const uniqueKey = `decompose-${Date.now().toString(36)}`;
|
|
38
|
+
const resolvedCacheDir = expandHomeDir(path.join(this.cacheDir, this.leaderInstanceId));
|
|
39
|
+
const logPath = path.join(resolvedCacheDir, `${uniqueKey}.log`);
|
|
40
|
+
const { stdout } = await execAndCapture(this.command, prompt, logPath);
|
|
41
|
+
const chains = this.parseOutput(stdout);
|
|
42
|
+
for (const chain of chains) {
|
|
43
|
+
await this.pushChain(chain, resolvedCacheDir);
|
|
44
|
+
}
|
|
45
|
+
return chains;
|
|
46
|
+
}
|
|
47
|
+
async pushChain(chain, resolvedCacheDir) {
|
|
48
|
+
const taskLinks = [];
|
|
49
|
+
if (chain.tasks.plan)
|
|
50
|
+
taskLinks.push({ link: "plan", def: chain.tasks.plan });
|
|
51
|
+
taskLinks.push({ link: "build", def: chain.tasks.build });
|
|
52
|
+
taskLinks.push({ link: "verify", def: chain.tasks.verify });
|
|
53
|
+
taskLinks.push({ link: "review", def: chain.tasks.review });
|
|
54
|
+
taskLinks.push({ link: "accept", def: chain.tasks.accept });
|
|
55
|
+
for (const { link, def } of taskLinks) {
|
|
56
|
+
const task = await this.taskQueue.push(def.title, def.description, def.priority, "", undefined, undefined, null, link, chain.chain_id);
|
|
57
|
+
const docPath = path.join(resolvedCacheDir, "tasks", `${task.id}.md`);
|
|
58
|
+
await fs.promises.mkdir(path.dirname(docPath), { recursive: true });
|
|
59
|
+
await fs.promises.writeFile(docPath, `# ${def.title}\n\n` +
|
|
60
|
+
`**Link**: ${link}\n` +
|
|
61
|
+
`**Chain**: ${chain.chain_id}\n` +
|
|
62
|
+
`**Priority**: ${def.priority}\n\n` +
|
|
63
|
+
`## Description\n\n${def.description}\n\n` +
|
|
64
|
+
`## Completion Criteria\n\n${def.criteria}\n`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
parseOutput(output) {
|
|
68
|
+
let cleaned = output
|
|
69
|
+
.replace(/```json\s*/g, "")
|
|
70
|
+
.replace(/```\s*/g, "")
|
|
71
|
+
.trim();
|
|
72
|
+
try {
|
|
73
|
+
const parsed = JSON.parse(cleaned);
|
|
74
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
const results = [];
|
|
78
|
+
const matches = cleaned.match(/\{[\s\S]*?\}(?=\s*\{|\s*$)/g);
|
|
79
|
+
if (matches) {
|
|
80
|
+
for (const m of matches) {
|
|
81
|
+
try {
|
|
82
|
+
results.push(JSON.parse(m));
|
|
83
|
+
}
|
|
84
|
+
catch { /* skip */ }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (results.length === 0)
|
|
88
|
+
throw new Error("Failed to parse Claude output as task chain JSON");
|
|
89
|
+
return results;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=task-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-generator.js","sourceRoot":"","sources":["../../src/leader/task-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const ESC = "\x1b";
|
|
2
|
+
const CLEAR = `${ESC}[2J${ESC}[0;0H`;
|
|
3
|
+
const HIDE_CURSOR = `${ESC}[?25l`;
|
|
4
|
+
const SHOW_CURSOR = `${ESC}[?25h`;
|
|
5
|
+
const RESET = `${ESC}[0m`;
|
|
6
|
+
const BOLD = `${ESC}[1m`;
|
|
7
|
+
const DIM = `${ESC}[2m`;
|
|
8
|
+
const RED = `${ESC}[31m`;
|
|
9
|
+
const GREEN = `${ESC}[32m`;
|
|
10
|
+
const YELLOW = `${ESC}[33m`;
|
|
11
|
+
const BLUE = `${ESC}[34m`;
|
|
12
|
+
const MAGENTA = `${ESC}[35m`;
|
|
13
|
+
const CYAN = `${ESC}[36m`;
|
|
14
|
+
function padRight(s, n) {
|
|
15
|
+
const visible = s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
16
|
+
return s + " ".repeat(Math.max(0, n - visible.length));
|
|
17
|
+
}
|
|
18
|
+
function truncate(s, n) {
|
|
19
|
+
if (s.length <= n)
|
|
20
|
+
return s;
|
|
21
|
+
return s.slice(0, n - 1) + "…";
|
|
22
|
+
}
|
|
23
|
+
function box(width, ...lines) {
|
|
24
|
+
const top = `${DIM}┌${"─".repeat(width - 2)}┐${RESET}\n`;
|
|
25
|
+
const bottom = `${DIM}└${"─".repeat(width - 2)}┘${RESET}`;
|
|
26
|
+
let body = "";
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
body += `${DIM}│${RESET}${padRight(line, width - 2)}${DIM}│${RESET}\n`;
|
|
29
|
+
}
|
|
30
|
+
return top + body + bottom;
|
|
31
|
+
}
|
|
32
|
+
function workerStatusColor(status) {
|
|
33
|
+
if (status === "idle")
|
|
34
|
+
return GREEN;
|
|
35
|
+
if (status === "busy")
|
|
36
|
+
return YELLOW;
|
|
37
|
+
return DIM;
|
|
38
|
+
}
|
|
39
|
+
export class LeaderTui {
|
|
40
|
+
render(state) {
|
|
41
|
+
const cols = process.stdout.columns || 120;
|
|
42
|
+
const rows = process.stdout.rows || 30;
|
|
43
|
+
const halfW = Math.floor((cols - 4) / 2);
|
|
44
|
+
let out = CLEAR + HIDE_CURSOR;
|
|
45
|
+
// ── Team Panel (top) ──
|
|
46
|
+
const teamWidth = cols - 2;
|
|
47
|
+
const teamLines = [];
|
|
48
|
+
teamLines.push(` ${BOLD}TEAM${RESET}`);
|
|
49
|
+
teamLines.push(` ${DIM}${"─".repeat(teamWidth - 4)}${RESET}`);
|
|
50
|
+
if (state.workers.length === 0) {
|
|
51
|
+
teamLines.push(` ${DIM}No workers online${RESET}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const header = `${BOLD}${padRight("Name", 14)}${padRight("Preset", 12)}${padRight("Current Role", 16)}${padRight("Status", 8)}Current Task${RESET}`;
|
|
55
|
+
teamLines.push(` ${header}`);
|
|
56
|
+
for (const w of state.workers.slice(0, 8)) {
|
|
57
|
+
const statusColored = `${workerStatusColor(w.status)}${padRight(w.status, 7)}${RESET}`;
|
|
58
|
+
const currentRole = w.currentRole ?? `${DIM}(idle)${RESET}`;
|
|
59
|
+
const cross = w.currentRole && w.currentRole !== w.presetRole ? `${MAGENTA}◀←${RESET} ` : "";
|
|
60
|
+
const line = ` ${padRight(truncate(w.name, 13), 14)}${padRight(w.presetRole, 12)}${cross}${padRight(currentRole, 16)}${statusColored}${truncate(w.currentTaskId ?? "-", teamWidth - 54)}`;
|
|
61
|
+
teamLines.push(line);
|
|
62
|
+
}
|
|
63
|
+
if (state.workers.length > 8) {
|
|
64
|
+
teamLines.push(` ${DIM}... and ${state.workers.length - 8} more${RESET}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const teamBoxH = teamLines.length + 2;
|
|
68
|
+
out += box(teamWidth, ...teamLines);
|
|
69
|
+
// ── Task Panels (middle, side by side) ──
|
|
70
|
+
// Left: Pending
|
|
71
|
+
const pendLines = [];
|
|
72
|
+
pendLines.push(` ${BOLD}PENDING${RESET}`);
|
|
73
|
+
pendLines.push(` ${DIM}${"─".repeat(halfW - 4)}${RESET}`);
|
|
74
|
+
const pendTasks = state.pendingTasks.slice(0, 10);
|
|
75
|
+
if (pendTasks.length === 0) {
|
|
76
|
+
pendLines.push(` ${DIM}No pending tasks${RESET}`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
for (const t of pendTasks) {
|
|
80
|
+
const title = truncate(t.title ?? "", halfW - 16);
|
|
81
|
+
const prio = t.priority === 0 ? `${RED}HIGH${RESET}` :
|
|
82
|
+
t.priority === 1 ? `${YELLOW}MED${RESET}` : `${DIM}LOW${RESET}`;
|
|
83
|
+
const link = t.link ? `${CYAN}[${t.link.charAt(0).toUpperCase() + t.link.slice(1)}]${RESET} ` : "";
|
|
84
|
+
pendLines.push(` ${link}${prio} ${title}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Right: In Progress
|
|
88
|
+
const progLines = [];
|
|
89
|
+
progLines.push(` ${BOLD}IN PROGRESS${RESET}`);
|
|
90
|
+
progLines.push(` ${DIM}${"─".repeat(halfW - 4)}${RESET}`);
|
|
91
|
+
const progTasks = state.claimedTasks.slice(0, 10);
|
|
92
|
+
if (progTasks.length === 0) {
|
|
93
|
+
progLines.push(` ${DIM}No tasks in progress${RESET}`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
for (const t of progTasks) {
|
|
97
|
+
const title = truncate(t.title ?? "", halfW - 10);
|
|
98
|
+
const who = truncate(t.claimed_by?.slice(0, 8) ?? "?", 8);
|
|
99
|
+
progLines.push(` ${BLUE}${who}${RESET} ${title}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Pad both to same height
|
|
103
|
+
const taskH = Math.max(pendLines.length, progLines.length) + 2;
|
|
104
|
+
while (pendLines.length < taskH - 2)
|
|
105
|
+
pendLines.push("");
|
|
106
|
+
while (progLines.length < taskH - 2)
|
|
107
|
+
progLines.push("");
|
|
108
|
+
const leftBox = box(halfW, ...pendLines).split("\n");
|
|
109
|
+
const rightBox = box(halfW, ...progLines).split("\n");
|
|
110
|
+
for (let i = 0; i < leftBox.length; i++) {
|
|
111
|
+
out += leftBox[i] + " " + rightBox[i] + "\n";
|
|
112
|
+
}
|
|
113
|
+
// ── Event Log (bottom) ──
|
|
114
|
+
const remainingH = rows - teamBoxH - (taskH + 2) - 3;
|
|
115
|
+
const logH = Math.max(remainingH, 5);
|
|
116
|
+
const logLines = [];
|
|
117
|
+
logLines.push(` ${BOLD}EVENT LOG${RESET}`);
|
|
118
|
+
logLines.push(` ${DIM}${"─".repeat(cols - 4)}${RESET}`);
|
|
119
|
+
const events = state.events.slice(-(logH - 3));
|
|
120
|
+
for (const e of events) {
|
|
121
|
+
logLines.push(` ${DIM}${e.timestamp}${RESET} ${e.message}`);
|
|
122
|
+
}
|
|
123
|
+
while (logLines.length < logH - 1)
|
|
124
|
+
logLines.push("");
|
|
125
|
+
out += box(cols - 2, ...logLines);
|
|
126
|
+
// ── Footer ──
|
|
127
|
+
const idShort = state.leaderInstanceId.slice(0, 8);
|
|
128
|
+
const footer = `${DIM}Leader: ${state.leaderName} | Instance: ${idShort} | CACHE_DIR: ${state.cacheDir} | Press Ctrl+C to stop${RESET}`;
|
|
129
|
+
out += `\n${footer}`;
|
|
130
|
+
process.stdout.write(out);
|
|
131
|
+
}
|
|
132
|
+
destroy() {
|
|
133
|
+
process.stdout.write(SHOW_CURSOR + CLEAR);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../../src/leader/tui.ts"],"names":[],"mappings":"AAEA,MAAM,GAAG,GAAG,MAAM,CAAC;AACnB,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC;AACrC,MAAM,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC;AAClC,MAAM,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC;AAElC,MAAM,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC;AAC1B,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;AACzB,MAAM,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC;AACxB,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;AACzB,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC;AAC3B,MAAM,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC;AAC5B,MAAM,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC;AAC1B,MAAM,OAAO,GAAG,GAAG,GAAG,MAAM,CAAC;AAC7B,MAAM,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC;AAE1B,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACjC,CAAC;AAED,SAAS,GAAG,CAAC,KAAa,EAAE,GAAG,KAAe;IAC5C,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;IACzD,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;IAC1D,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,IAAI,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;AAC7B,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACrC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,SAAS;IACpB,MAAM,CAAC,KAAkB;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzC,IAAI,GAAG,GAAG,KAAK,GAAG,WAAW,CAAC;QAE9B,yBAAyB;QACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC;QAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,oBAAoB,KAAK,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC;YACpJ,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;YAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;gBACvF,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,GAAG,GAAG,SAAS,KAAK,EAAE,CAAC;gBAC5D,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7F,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,IAAI,GAAG,EAAE,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC;gBAC1L,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,WAAW,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACtC,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC;QAEpC,2CAA2C;QAC3C,gBAAgB;QAChB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,UAAU,KAAK,EAAE,CAAC,CAAC;QAC1C,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,mBAAmB,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAe,IAAI,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;gBAC5D,MAAM,IAAI,GAAI,CAAC,CAAC,QAAmB,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC;oBACpD,CAAC,CAAC,QAAmB,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC;gBACzF,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAK,CAAC,CAAC,IAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAI,CAAC,CAAC,IAAe,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3H,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,cAAc,KAAK,EAAE,CAAC,CAAC;QAC9C,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,uBAAuB,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAe,IAAI,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;gBAC5D,MAAM,GAAG,GAAG,QAAQ,CAAE,CAAC,CAAC,UAAqB,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;gBACtE,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,SAAS,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAExD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QAC/C,CAAC;QAED,2BAA2B;QAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,QAAQ,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC,CAAC;QAC3C,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;QAElC,eAAe;QACf,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,GAAG,GAAG,WAAW,KAAK,CAAC,UAAU,gBAAgB,OAAO,iBAAiB,KAAK,CAAC,QAAQ,0BAA0B,KAAK,EAAE,CAAC;QACxI,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC;QAErB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ZkClient } from "../zk/client.js";
|
|
2
|
+
import { LeaderEventBus } from "./event-bus.js";
|
|
3
|
+
import type { DecisionEngine } from "./decision-engine.js";
|
|
4
|
+
export declare class LeaderWatcher {
|
|
5
|
+
private zk;
|
|
6
|
+
private eventBus;
|
|
7
|
+
private leaderInstanceId;
|
|
8
|
+
private command;
|
|
9
|
+
private cacheDir;
|
|
10
|
+
private decisionEngine?;
|
|
11
|
+
private inFlight;
|
|
12
|
+
private stopped;
|
|
13
|
+
constructor(zk: ZkClient, eventBus: LeaderEventBus, leaderInstanceId: string, command: string, cacheDir: string, decisionEngine?: DecisionEngine | undefined);
|
|
14
|
+
start(): Promise<void>;
|
|
15
|
+
private watchLoop;
|
|
16
|
+
private processMessage;
|
|
17
|
+
stop(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import * as paths from "../zk/paths.js";
|
|
3
|
+
import { MessageSchema } from "../models/schemas.js";
|
|
4
|
+
import { execWithTee } from "../utils/exec.js";
|
|
5
|
+
import { expandHomeDir } from "../config.js";
|
|
6
|
+
export class LeaderWatcher {
|
|
7
|
+
zk;
|
|
8
|
+
eventBus;
|
|
9
|
+
leaderInstanceId;
|
|
10
|
+
command;
|
|
11
|
+
cacheDir;
|
|
12
|
+
decisionEngine;
|
|
13
|
+
inFlight = new Set();
|
|
14
|
+
stopped = false;
|
|
15
|
+
constructor(zk, eventBus, leaderInstanceId, command, cacheDir, decisionEngine) {
|
|
16
|
+
this.zk = zk;
|
|
17
|
+
this.eventBus = eventBus;
|
|
18
|
+
this.leaderInstanceId = leaderInstanceId;
|
|
19
|
+
this.command = command;
|
|
20
|
+
this.cacheDir = cacheDir;
|
|
21
|
+
this.decisionEngine = decisionEngine;
|
|
22
|
+
}
|
|
23
|
+
async start() {
|
|
24
|
+
await this.zk.mkdirp(paths.messageDirPath(this.leaderInstanceId));
|
|
25
|
+
this.watchLoop();
|
|
26
|
+
}
|
|
27
|
+
async watchLoop() {
|
|
28
|
+
if (this.stopped)
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
const children = await this.zk.watchMessageDir(this.leaderInstanceId, (newChildren) => {
|
|
32
|
+
for (const cid of newChildren)
|
|
33
|
+
this.processMessage(cid);
|
|
34
|
+
this.watchLoop();
|
|
35
|
+
});
|
|
36
|
+
for (const cid of children)
|
|
37
|
+
await this.processMessage(cid);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
if (!this.stopped)
|
|
41
|
+
setTimeout(() => this.watchLoop(), 1000);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async processMessage(msgId) {
|
|
45
|
+
if (this.inFlight.has(msgId) || this.stopped)
|
|
46
|
+
return;
|
|
47
|
+
const data = await this.zk.getMessage(this.leaderInstanceId, msgId);
|
|
48
|
+
if (!data)
|
|
49
|
+
return;
|
|
50
|
+
const msg = MessageSchema.parse({ ...data, id: msgId });
|
|
51
|
+
if (msg.read)
|
|
52
|
+
return;
|
|
53
|
+
this.inFlight.add(msgId);
|
|
54
|
+
const fromLabel = msg.from_name || msg.from_instance?.slice(0, 8) || "unknown";
|
|
55
|
+
const uniqueKey = `msg-${msgId}-${Date.now().toString(36)}`;
|
|
56
|
+
this.eventBus.emit({
|
|
57
|
+
type: "message_received",
|
|
58
|
+
from: fromLabel,
|
|
59
|
+
content: msg.content,
|
|
60
|
+
msgId,
|
|
61
|
+
});
|
|
62
|
+
const resolvedCacheDir = expandHomeDir(this.cacheDir);
|
|
63
|
+
const logPath = path.join(resolvedCacheDir, this.leaderInstanceId, `${uniqueKey}.log`);
|
|
64
|
+
// Use DecisionEngine for Worker completion reports (messages with link field)
|
|
65
|
+
if (this.decisionEngine && msg.link) {
|
|
66
|
+
await this.decisionEngine.evaluate(msg, {
|
|
67
|
+
teamStatus: {},
|
|
68
|
+
taskQueues: {},
|
|
69
|
+
chainStatus: {},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
await execWithTee(this.command, msg.content, logPath);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
msg.read = true;
|
|
77
|
+
await this.zk.updateMessage(this.leaderInstanceId, msgId, msg);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// best effort
|
|
81
|
+
}
|
|
82
|
+
this.inFlight.delete(msgId);
|
|
83
|
+
this.eventBus.emit({ type: "message_processed", msgId, logPath });
|
|
84
|
+
}
|
|
85
|
+
stop() {
|
|
86
|
+
this.stopped = true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/leader/watcher.ts"],"names":[],"mappings":"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"}
|