intercomm-aimfp 0.4.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 (59) hide show
  1. package/README.md +353 -0
  2. package/dist/claude-tui.d.ts +7 -0
  3. package/dist/claude-tui.d.ts.map +1 -0
  4. package/dist/claude-tui.js +55 -0
  5. package/dist/claude-tui.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +144 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +14 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +44 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/db.d.ts +9 -0
  15. package/dist/db.d.ts.map +1 -0
  16. package/dist/db.js +117 -0
  17. package/dist/db.js.map +1 -0
  18. package/dist/fs-wrapper.d.ts +3 -0
  19. package/dist/fs-wrapper.d.ts.map +1 -0
  20. package/dist/fs-wrapper.js +9 -0
  21. package/dist/fs-wrapper.js.map +1 -0
  22. package/dist/git-wrapper.d.ts +11 -0
  23. package/dist/git-wrapper.d.ts.map +1 -0
  24. package/dist/git-wrapper.js +44 -0
  25. package/dist/git-wrapper.js.map +1 -0
  26. package/dist/mcp-entry.d.ts +3 -0
  27. package/dist/mcp-entry.d.ts.map +1 -0
  28. package/dist/mcp-entry.js +8 -0
  29. package/dist/mcp-entry.js.map +1 -0
  30. package/dist/mcp-server.d.ts +2 -0
  31. package/dist/mcp-server.d.ts.map +1 -0
  32. package/dist/mcp-server.js +557 -0
  33. package/dist/mcp-server.js.map +1 -0
  34. package/dist/orchestrate.d.ts +52 -0
  35. package/dist/orchestrate.d.ts.map +1 -0
  36. package/dist/orchestrate.js +226 -0
  37. package/dist/orchestrate.js.map +1 -0
  38. package/dist/protocol.d.ts +3 -0
  39. package/dist/protocol.d.ts.map +1 -0
  40. package/dist/protocol.js +33 -0
  41. package/dist/protocol.js.map +1 -0
  42. package/dist/store.d.ts +26 -0
  43. package/dist/store.d.ts.map +1 -0
  44. package/dist/store.js +186 -0
  45. package/dist/store.js.map +1 -0
  46. package/dist/task-contract.d.ts +4 -0
  47. package/dist/task-contract.d.ts.map +1 -0
  48. package/dist/task-contract.js +111 -0
  49. package/dist/task-contract.js.map +1 -0
  50. package/dist/tmux-wrapper.d.ts +17 -0
  51. package/dist/tmux-wrapper.d.ts.map +1 -0
  52. package/dist/tmux-wrapper.js +66 -0
  53. package/dist/tmux-wrapper.js.map +1 -0
  54. package/dist/types.d.ts +92 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +56 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +35 -0
  59. package/system-prompt.md +245 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrate.d.ts","sourceRoot":"","sources":["../src/orchestrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,226 @@
1
+ // Multi-agent lifecycle sequences — the glue that retires spawn/scan/kill-workers.sh.
2
+ //
3
+ // This module SEQUENCES IO: it composes the tmux/git wrappers (raw IO), the pure
4
+ // claude-tui dialog decisions, the config path helpers, and the store registry
5
+ // into the operations the master drives (spawn / wake / scan / approve / teardown).
6
+ // It owns no pure logic of its own beyond pacing — dialog detection/keystrokes
7
+ // live in claude-tui, path math in config, persistence in store. Functions return
8
+ // plain report data; mcp-server formats it into tool results.
9
+ import { execSync } from "node:child_process";
10
+ import { dirname } from "node:path";
11
+ import { worktreePath } from "./config.js";
12
+ import { ensureDir } from "./fs-wrapper.js";
13
+ import { addWorktree, removeWorktree } from "./git-wrapper.js";
14
+ import * as tmux from "./tmux-wrapper.js";
15
+ import { detectPaneState, clearKeystrokes, isBlocking, isBooted, } from "./claude-tui.js";
16
+ import * as store from "./store.js";
17
+ // --- Private pacing helpers (untracked) ---
18
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
19
+ // Type a literal line into a pane and submit it. Claude Code's TUI needs a second
20
+ // Enter to actually send (the first just inserts a newline), so callers targeting
21
+ // the chat box pass doubleEnter=true; a shell prompt uses a single Enter.
22
+ const typeLine = async (target, text, doubleEnter = false) => {
23
+ tmux.sendKeys(target, [text], true);
24
+ await sleep(400);
25
+ tmux.sendKeys(target, ["Enter"]);
26
+ if (doubleEnter) {
27
+ await sleep(400);
28
+ tmux.sendKeys(target, ["Enter"]);
29
+ }
30
+ };
31
+ // --- Pure-ish helpers ---
32
+ // The first `count` free `<prefix>-N` session names (N from 1), skipping any that
33
+ // tmux already has. IO: probes tmux.hasSession.
34
+ export const pickSessionNames = (prefix, count) => {
35
+ const chosen = [];
36
+ let n = 1;
37
+ while (chosen.length < count) {
38
+ const name = `${prefix}-${n}`;
39
+ if (!tmux.hasSession(name).ok)
40
+ chosen.push(name);
41
+ n += 1;
42
+ }
43
+ return chosen;
44
+ };
45
+ // The register prompt pushed to a freshly-booted worker (ported from
46
+ // spawn-workers.sh wake_prompt). Pure string assembly.
47
+ export const wakePromptText = (session, worktrees) => {
48
+ const wt = worktrees
49
+ ? " You are in your OWN git worktree (isolated checkout, detached HEAD) — if your task lists required_directives, run the AIMFP git tools (e.g. git_create_branch) INSIDE this worktree and report your branch name back to the master via intercomm_send."
50
+ : "";
51
+ return (`You are an InterComm AIMFP worker running in tmux session '${session}'. ` +
52
+ `Do NOT interact with the user — all communication goes through InterComm to the master. ` +
53
+ `Steps: (1) Call intercomm_register() to get your worker id. ` +
54
+ `(2) Call intercomm_send(to: "master", type: "status", message: "registered as <your worker id> in tmux session ${session}") so the master can map you. ` +
55
+ `(3) Call intercomm_read() to get your task and begin. If there is no task yet, stop and wait — the master will wake you.${wt}`);
56
+ };
57
+ // The wake prompt pushed to the MASTER when a worker escalates (worker -> master,
58
+ // the inverse of wakePromptText). The persisted `question` on the bus is the source
59
+ // of truth; this text only nudges the master to DRAIN the bus (so a missed/garbled
60
+ // wake is still recovered), confer with the user when needsUser, then answer + wake
61
+ // the worker. Pure string assembly.
62
+ export const escalationWakeText = (fromId, kind, needsUser, message) => {
63
+ const verb = kind === "decision" ? "needs a DECISION" : "has a QUESTION";
64
+ const user = needsUser
65
+ ? " It is flagged needs_user — confer with the USER before answering."
66
+ : "";
67
+ return (`InterComm escalation from ${fromId}: it ${verb}. ` +
68
+ `Call intercomm_read to drain the bus, then reply via ` +
69
+ `intercomm_send(to: "${fromId}", type: "answer", message: ...) and ` +
70
+ `intercomm_wake("${fromId}", ...) to resume it.${user} ` +
71
+ `(Escalated message: ${message})`);
72
+ };
73
+ // Resolve a worker id OR a raw tmux target to a tmux target string. A registered
74
+ // instance's stored tmux_target wins; otherwise the input is treated as a session
75
+ // name (covers freshly-spawned workers that have not registered yet). IO: store read.
76
+ export const resolveTarget = (idOrTarget) => {
77
+ const inst = store.getInstance(idOrTarget);
78
+ return inst && inst.tmuxTarget ? inst.tmuxTarget : idOrTarget;
79
+ };
80
+ // --- Sequences ---
81
+ // Bounded dialog-clear loop: repeatedly capture the pane, and while it sits on a
82
+ // clearable first-run/permission dialog, send the keystrokes claude-tui prescribes.
83
+ // Returns as soon as the pane has booted (ready/running) or the deadline passes —
84
+ // it never waits on the worker REGISTERING (that stays async / no-poll).
85
+ export const clearDialogs = async (target, deadlineMs) => {
86
+ const start = Date.now();
87
+ let state = "idle";
88
+ while (Date.now() - start < deadlineMs) {
89
+ const cap = tmux.capturePane(target);
90
+ state = cap.ok ? detectPaneState(cap.stdout) : "idle";
91
+ if (isBooted(state))
92
+ return state;
93
+ if (isBlocking(state)) {
94
+ for (const group of clearKeystrokes(state)) {
95
+ tmux.sendKeys(target, group);
96
+ await sleep(800);
97
+ }
98
+ }
99
+ else {
100
+ await sleep(700);
101
+ }
102
+ }
103
+ return state;
104
+ };
105
+ // Spawn `count` workers in detached tmux sessions, non-blocking. Per worker:
106
+ // optionally provision an isolated git worktree (registered + bootstrapped),
107
+ // launch claude with INTERCOMM_DB_ROOT pinned to the shared root, clear first-run
108
+ // dialogs within the bounded window, then (if wake) push the register prompt.
109
+ // Returns one report per session; workers self-register asynchronously afterward.
110
+ export const spawnWorkers = async (opts) => {
111
+ const names = pickSessionNames(opts.prefix, opts.count);
112
+ const reports = [];
113
+ // Launch phase: create each session + start claude (sequential, stable order).
114
+ const launched = [];
115
+ for (const session of names) {
116
+ let launchDir = opts.root;
117
+ let worktree = "";
118
+ if (opts.worktrees) {
119
+ const path = worktreePath(opts.root, session);
120
+ ensureDir(dirname(path));
121
+ const res = addWorktree(opts.root, path, opts.worktreeBase);
122
+ // Reuse an existing checkout if `add` failed because it is already there.
123
+ if (res.ok || tmux.hasSession(session).ok === false) {
124
+ store.upsertWorktree(session, path, opts.worktreeBase);
125
+ worktree = path;
126
+ launchDir = path;
127
+ if (opts.bootstrap) {
128
+ try {
129
+ execSync(opts.bootstrap, { cwd: path, stdio: "ignore", shell: "/bin/bash" });
130
+ }
131
+ catch { /* best effort — a failed bootstrap should not abort the spawn */ }
132
+ }
133
+ }
134
+ }
135
+ tmux.newSession(session, launchDir);
136
+ const envPrefix = `INTERCOMM_DB_ROOT='${opts.root}' `;
137
+ await typeLine(session, `${envPrefix}${opts.claudeCmd} --permission-mode ${opts.permMode}`);
138
+ launched.push({ session, worktree });
139
+ }
140
+ // Boot phase: clear dialogs + wake each (sequential, so registration order is stable).
141
+ for (const { session, worktree } of launched) {
142
+ const state = await clearDialogs(session, opts.readyTimeoutMs);
143
+ const ready = isBooted(state);
144
+ let woken = false;
145
+ if (opts.wake && ready) {
146
+ await typeLine(session, wakePromptText(session, opts.worktrees), true);
147
+ woken = true;
148
+ }
149
+ reports.push({ session, state, ready, woken, worktree });
150
+ }
151
+ return reports;
152
+ };
153
+ // Push a prompt to a single worker pane (master -> worker). Symmetric to the
154
+ // designed escalate (worker -> master). Resolves the target, verifies the pane
155
+ // still exists, then types + submits with the TUI double-Enter.
156
+ export const wakeWorker = async (idOrTarget, message) => {
157
+ const target = resolveTarget(idOrTarget);
158
+ const session = target.split(":")[0] ?? target;
159
+ if (!tmux.hasSession(session).ok)
160
+ return { resolved: false, woke: false, target };
161
+ await typeLine(target, message, true);
162
+ return { resolved: true, woke: true, target };
163
+ };
164
+ // Poll every `<prefix>-` session once and classify its pane. The master uses this
165
+ // to find workers frozen on a permission dialog (which cannot report over the bus).
166
+ export const scanWorkers = (prefix) => {
167
+ const list = tmux.listSessions();
168
+ if (!list.ok)
169
+ return [];
170
+ return tmux.splitLines(list.stdout)
171
+ .filter((s) => s.startsWith(`${prefix}-`))
172
+ .map((session) => {
173
+ const cap = tmux.capturePane(session);
174
+ const state = cap.ok ? detectPaneState(cap.stdout) : "idle";
175
+ return { session, state, needsAttention: isBlocking(state) };
176
+ });
177
+ };
178
+ // Clear one worker's blocking dialog (trust / MCP-approval / bypass / permission).
179
+ // Captures before + after so the caller can report whether the block actually lifted.
180
+ export const approveWorker = async (idOrTarget, deadlineMs) => {
181
+ const target = resolveTarget(idOrTarget);
182
+ const session = target.split(":")[0] ?? target;
183
+ const first = tmux.capturePane(session);
184
+ if (!first.ok) {
185
+ return { target, resolved: false, before: "idle", after: "idle", cleared: false };
186
+ }
187
+ const before = detectPaneState(first.stdout);
188
+ const after = await clearDialogs(session, deadlineMs);
189
+ const cleared = isBlocking(before) && !isBlocking(after);
190
+ return { target, resolved: true, before, after, cleared };
191
+ };
192
+ // Tear down every `<prefix>-` worker in one shot: kill the tmux sessions, remove
193
+ // their git worktrees (when in worktree mode) and mark them removed, then REAP the
194
+ // instance rows so a never-run exit-cleanup cannot leave stale active=1 drift.
195
+ export const teardownWorkers = (root, prefix, worktrees) => {
196
+ const list = tmux.listSessions();
197
+ const sessions = list.ok
198
+ ? tmux.splitLines(list.stdout).filter((s) => s.startsWith(`${prefix}-`))
199
+ : [];
200
+ const killed = [];
201
+ for (const s of sessions) {
202
+ if (tmux.killSession(s).ok)
203
+ killed.push(s);
204
+ }
205
+ const worktreesRemoved = [];
206
+ if (worktrees) {
207
+ for (const wt of store.getAllWorktrees()) {
208
+ if (wt.status === "removed" || !killed.includes(wt.workerId))
209
+ continue;
210
+ if (removeWorktree(root, wt.path, true).ok) {
211
+ store.markWorktreeRemoved(wt.workerId);
212
+ worktreesRemoved.push(wt.workerId);
213
+ }
214
+ }
215
+ }
216
+ // Reap any registered instance whose session we just killed (id == session name).
217
+ const reaped = [];
218
+ for (const inst of store.getAllInstances()) {
219
+ if (killed.includes(inst.id)) {
220
+ store.reapInstance(inst.id);
221
+ reaped.push(inst.id);
222
+ }
223
+ }
224
+ return { killed, worktreesRemoved, reaped };
225
+ };
226
+ //# sourceMappingURL=orchestrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../src/orchestrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const protocolPath: () => string;
2
+ export declare const loadProtocol: () => string;
3
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,YAAY,QAAO,MACsC,CAAC;AAKvE,eAAO,MAAM,YAAY,QAAO,MAY/B,CAAC"}
@@ -0,0 +1,33 @@
1
+ // InterComm coordination-protocol loader.
2
+ //
3
+ // The master/worker protocol is delivered to every connected instance via the
4
+ // MCP server's `instructions` field (mirroring how AIMFP injects its rules) and
5
+ // re-readable on demand via the intercomm_get_protocol tool. This module is the
6
+ // single in-repo source: it loads system-prompt.md, the canonical protocol text.
7
+ //
8
+ // The path is resolved RELATIVE TO THIS MODULE (import.meta.url), never the cwd,
9
+ // so it works whether the server runs from src/, dist/, or an installed
10
+ // node_modules copy — system-prompt.md sits one level above the module dir in
11
+ // every layout (package.json must ship it via "files").
12
+ import { fileURLToPath } from "node:url";
13
+ import { dirname, join } from "node:path";
14
+ import { readTextFile } from "./fs-wrapper.js";
15
+ const PROTOCOL_SOURCE = "system-prompt.md";
16
+ // On-disk path to the protocol source, anchored to this module's location.
17
+ export const protocolPath = () => join(dirname(fileURLToPath(import.meta.url)), "..", PROTOCOL_SOURCE);
18
+ // Load the protocol text. Read on each call (no mutable cache — called once at
19
+ // startup and rarely thereafter). Degrades to a clear fallback rather than
20
+ // throwing, so a missing/unreadable source can never crash server bootstrap.
21
+ export const loadProtocol = () => {
22
+ try {
23
+ return readTextFile(protocolPath());
24
+ }
25
+ catch {
26
+ return ("InterComm AIMFP coordination protocol unavailable — the protocol source " +
27
+ `(${PROTOCOL_SOURCE}) could not be read. Register with intercomm_register, ` +
28
+ "and coordinate strictly through InterComm (master controls workers; " +
29
+ "workers never interact with the user). Reinstall the package to restore " +
30
+ "the full protocol.");
31
+ }
32
+ };
33
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,EAAE;AACF,iFAAiF;AACjF,wEAAwE;AACxE,8EAA8E;AAC9E,wDAAwD;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE,CACvC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;AAEvE,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CACL,0EAA0E;YAC1E,IAAI,eAAe,yDAAyD;YAC5E,sEAAsE;YACtE,0EAA0E;YAC1E,oBAAoB,CACrB,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Instance, Message, MessageType, Role, Worktree, WorktreeStatus } from "./types.js";
2
+ export declare const nowMs: () => number;
3
+ export declare const isStale: (lastActive: number, now?: number) => boolean;
4
+ export declare const formatMessageForDisplay: (msg: Message) => string;
5
+ export declare const formatInstanceForDisplay: (inst: Instance, worktree?: Worktree | undefined) => string;
6
+ export declare const findLowestAvailableWorkerName: (instances: readonly Instance[]) => string;
7
+ export declare const registerInstance: (id: string, role: Role, sessionId: string, tmuxTarget?: string) => Instance;
8
+ export declare const touchInstance: (id: string, tmuxTarget?: string) => void;
9
+ export declare const setInstanceTmuxTarget: (id: string, target: string) => void;
10
+ export declare const deactivateInstance: (id: string) => void;
11
+ export declare const deactivateAll: () => void;
12
+ export declare const reapInstance: (id: string) => void;
13
+ export declare const getInstance: (id: string) => Instance | undefined;
14
+ export declare const getAllInstances: () => readonly Instance[];
15
+ export declare const getActiveMaster: () => Instance | undefined;
16
+ export declare const registerAs: (role: Role, sessionId: string, tmuxTarget?: string) => Instance;
17
+ export declare const insertMessage: (fromId: string, toId: string, type: MessageType, content: string) => Message;
18
+ export declare const readNewMessages: (instanceId: string, readAll?: boolean) => readonly Message[];
19
+ export declare const formatWorktreeForDisplay: (wt: Worktree) => string;
20
+ export declare const upsertWorktree: (workerId: string, path: string, base: string) => Worktree;
21
+ export declare const getWorktree: (workerId: string) => Worktree | undefined;
22
+ export declare const getAllWorktrees: () => readonly Worktree[];
23
+ export declare const setWorktreeStatus: (workerId: string, status: WorktreeStatus, branch?: string) => void;
24
+ export declare const markWorktreeRemoved: (workerId: string) => void;
25
+ export declare const clearOldMessages: (keep: number) => number;
26
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EAER,OAAO,EAEP,WAAW,EACX,IAAI,EAEJ,QAAQ,EAER,cAAc,EACf,MAAM,YAAY,CAAC;AAOpB,eAAO,MAAM,KAAK,QAAO,MAAoB,CAAC;AAE9C,eAAO,MAAM,OAAO,GAAI,YAAY,MAAM,EAAE,MAAK,MAAgB,KAAG,OAC7B,CAAC;AAExC,eAAO,MAAM,uBAAuB,GAAI,KAAK,OAAO,KAAG,MACqE,CAAC;AAE7H,eAAO,MAAM,wBAAwB,GACnC,MAAM,QAAQ,EACd,WAAW,QAAQ,GAAG,SAAS,KAC9B,MAaF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,WAAW,SAAS,QAAQ,EAAE,KAAG,MAa9E,CAAC;AAIF,eAAO,MAAM,gBAAgB,GAC3B,IAAI,MAAM,EACV,MAAM,IAAI,EACV,WAAW,MAAM,EACjB,aAAY,MAAW,KACtB,QAaF,CAAC;AAOF,eAAO,MAAM,aAAa,GAAI,IAAI,MAAM,EAAE,aAAa,MAAM,KAAG,IAW/D,CAAC;AAMF,eAAO,MAAM,qBAAqB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,KAAG,IAElE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,KAAG,IAE/C,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,IAEhC,CAAC;AAMF,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,KAAG,IAGzC,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,KAAG,QAAQ,GAAG,SAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,SAAS,QAAQ,EAE3B,CAAC;AAE1B,eAAO,MAAM,eAAe,QAAO,QAAQ,GAAG,SAO7C,CAAC;AAIF,eAAO,MAAM,UAAU,GACrB,MAAM,IAAI,EACV,WAAW,MAAM,EACjB,aAAY,MAAW,KACtB,QASF,CAAC;AAIF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,MAAM,WAAW,EACjB,SAAS,MAAM,KACd,OAaF,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,YAAY,MAAM,EAClB,UAAS,OAAe,KACvB,SAAS,OAAO,EAgClB,CAAC;AAIF,eAAO,MAAM,wBAAwB,GAAI,IAAI,QAAQ,KAAG,MAIvD,CAAC;AAOF,eAAO,MAAM,cAAc,GACzB,UAAU,MAAM,EAChB,MAAM,MAAM,EACZ,MAAM,MAAM,KACX,QAyBF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,KAAG,QAAQ,GAAG,SAMzD,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,SAAS,QAAQ,EAE3B,CAAC;AAK1B,eAAO,MAAM,iBAAiB,GAC5B,UAAU,MAAM,EAChB,QAAQ,cAAc,EACtB,SAAS,MAAM,KACd,IAaF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,KAAG,IAEtD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAc/C,CAAC"}
package/dist/store.js ADDED
@@ -0,0 +1,186 @@
1
+ // Core logic — SQLite-backed operations for all CRUD
2
+ // Pure logic + IO operations via db.ts
3
+ import { randomUUID } from "node:crypto";
4
+ import { instanceFromRow, messageFromRow, worktreeFromRow } from "./types.js";
5
+ import { STALE_THRESHOLD_MS } from "./config.js";
6
+ import { execute, queryOne, queryAll } from "./db.js";
7
+ // --- Pure helpers ---
8
+ export const nowMs = () => Date.now();
9
+ export const isStale = (lastActive, now = nowMs()) => now - lastActive > STALE_THRESHOLD_MS;
10
+ export const formatMessageForDisplay = (msg) => `[${new Date(msg.ts).toLocaleTimeString()}] (${msg.type}) ${msg.fromId} → ${msg.toId}: ${msg.content} [msg_id: ${msg.id}]`;
11
+ export const formatInstanceForDisplay = (inst, worktree) => {
12
+ const status = inst.active && !isStale(inst.lastActive) ? "active" : "inactive";
13
+ const seen = new Date(inst.lastActive).toLocaleTimeString();
14
+ // Surface the id <-> tmux-session <-> worktree mapping explicitly: InterComm ids are
15
+ // assigned in registration order and are DECOUPLED from the tmux session name (a
16
+ // worker-1 id can live in tmux session worker-4), which makes manual tmux/log
17
+ // inspection error-prone. tmuxTarget is the routing-truth; worktree (when present)
18
+ // ties the id to its on-disk checkout + branch.
19
+ const tmux = inst.tmuxTarget ? `, tmux: ${inst.tmuxTarget}` : "";
20
+ const wt = worktree
21
+ ? `, worktree: ${worktree.path}${worktree.branch ? ` @ ${worktree.branch}` : ""}`
22
+ : "";
23
+ return ` ${inst.id} [${inst.role}] — ${status} (last active: ${seen}, session: ${inst.sessionId.slice(0, 8)}${tmux}${wt})`;
24
+ };
25
+ export const findLowestAvailableWorkerName = (instances) => {
26
+ const usedNumbers = instances
27
+ .filter((i) => i.role === "worker" && i.active)
28
+ .map((i) => {
29
+ const match = i.id.match(/^worker-(\d+)$/);
30
+ return match ? parseInt(match[1], 10) : -1;
31
+ })
32
+ .filter((n) => n >= 0);
33
+ const usedSet = new Set(usedNumbers);
34
+ let n = 1;
35
+ while (usedSet.has(n))
36
+ n++;
37
+ return `worker-${n}`;
38
+ };
39
+ // --- IO: Instance operations ---
40
+ export const registerInstance = (id, role, sessionId, tmuxTarget = "") => {
41
+ const now = nowMs();
42
+ execute(`INSERT OR REPLACE INTO instances (id, role, active, last_active, registered_at, session_id, tmux_target)
43
+ VALUES (?, ?, 1, ?, ?, ?, ?)`, id, role, now, now, sessionId, tmuxTarget);
44
+ return { id, role, active: true, lastActive: now, registeredAt: now, sessionId, tmuxTarget };
45
+ };
46
+ // Touch last_active on every authenticated tool call. When a non-empty tmuxTarget
47
+ // is supplied (a tmux-backed instance re-resolving its OWN pane), refresh the
48
+ // stored tmux_target in the same write so a moved/renamed pane stays wakeable —
49
+ // this is what keeps the master's wake target fresh for worker escalations
50
+ // (Phase 2.5b P1-b). Off-tmux callers pass '' / nothing and only last_active moves.
51
+ export const touchInstance = (id, tmuxTarget) => {
52
+ if (tmuxTarget) {
53
+ execute(`UPDATE instances SET last_active = ?, tmux_target = ? WHERE id = ?`, nowMs(), tmuxTarget, id);
54
+ }
55
+ else {
56
+ execute(`UPDATE instances SET last_active = ? WHERE id = ?`, nowMs(), id);
57
+ }
58
+ };
59
+ // Unconditionally set (or clear, with '') an instance's stored tmux_target.
60
+ // Distinct from touchInstance's refresh (which ignores '') so a failed escalation
61
+ // wake can DOWNGRADE the master to message-only by clearing a pane that no longer
62
+ // resolves (Phase 2.5b P1-b clear-on-failure).
63
+ export const setInstanceTmuxTarget = (id, target) => {
64
+ execute(`UPDATE instances SET tmux_target = ? WHERE id = ?`, target, id);
65
+ };
66
+ export const deactivateInstance = (id) => {
67
+ execute(`UPDATE instances SET active = 0 WHERE id = ?`, id);
68
+ };
69
+ export const deactivateAll = () => {
70
+ execute(`UPDATE instances SET active = 0`);
71
+ };
72
+ // Hard-remove an instance row and its read cursor. deactivate only flips active=0
73
+ // (preserving the worker-N slot); reap fully frees the name. teardown reaps killed
74
+ // workers so a best-effort exit-cleanup that never ran cannot leave a stale
75
+ // active=1 row that drifts the next worker's auto-assigned number (note #31).
76
+ export const reapInstance = (id) => {
77
+ execute(`DELETE FROM instances WHERE id = ?`, id);
78
+ execute(`DELETE FROM read_cursors WHERE instance_id = ?`, id);
79
+ };
80
+ export const getInstance = (id) => {
81
+ const row = queryOne(`SELECT * FROM instances WHERE id = ?`, id);
82
+ return row ? instanceFromRow(row) : undefined;
83
+ };
84
+ export const getAllInstances = () => queryAll(`SELECT * FROM instances ORDER BY registered_at`)
85
+ .map(instanceFromRow);
86
+ export const getActiveMaster = () => {
87
+ const now = nowMs();
88
+ const row = queryOne(`SELECT * FROM instances WHERE role = 'master' AND active = 1 AND last_active > ?`, now - STALE_THRESHOLD_MS);
89
+ return row ? instanceFromRow(row) : undefined;
90
+ };
91
+ // --- IO: Registration ---
92
+ export const registerAs = (role, sessionId, tmuxTarget = "") => {
93
+ if (role === "master") {
94
+ deactivateAll();
95
+ return registerInstance("master", "master", sessionId, tmuxTarget);
96
+ }
97
+ const allInstances = getAllInstances();
98
+ const workerName = findLowestAvailableWorkerName(allInstances);
99
+ return registerInstance(workerName, "worker", sessionId, tmuxTarget);
100
+ };
101
+ // --- IO: Message operations ---
102
+ export const insertMessage = (fromId, toId, type, content) => {
103
+ const id = randomUUID();
104
+ const ts = nowMs();
105
+ execute(`INSERT INTO messages (id, from_id, to_id, type, content, ts) VALUES (?, ?, ?, ?, ?, ?)`, id, fromId, toId, type, content, ts);
106
+ return { id, fromId, toId, type, content, ts };
107
+ };
108
+ export const readNewMessages = (instanceId, readAll = false) => {
109
+ const cursor = readAll
110
+ ? 0
111
+ : (queryOne(`SELECT * FROM read_cursors WHERE instance_id = ?`, instanceId)?.last_read_seq ?? 0);
112
+ const rows = queryAll(`SELECT rowid AS seq, * FROM messages
113
+ WHERE (to_id = ? OR to_id = 'all')
114
+ AND from_id != ?
115
+ AND rowid > ?
116
+ ORDER BY rowid`, instanceId, instanceId, cursor);
117
+ // Advance cursor to the highest rowid seen. rowid is monotonic per insert, so
118
+ // same-millisecond messages can no longer slip past a `ts >` boundary.
119
+ if (rows.length > 0) {
120
+ const maxSeq = rows[rows.length - 1].seq;
121
+ execute(`INSERT OR REPLACE INTO read_cursors (instance_id, last_read_seq) VALUES (?, ?)`, instanceId, maxSeq);
122
+ }
123
+ touchInstance(instanceId);
124
+ return rows.map(messageFromRow);
125
+ };
126
+ // --- Pure helpers: worktrees ---
127
+ export const formatWorktreeForDisplay = (wt) => {
128
+ const seen = new Date(wt.updatedAt).toLocaleTimeString();
129
+ const branch = wt.branch || "(detached — no branch yet)";
130
+ return ` ${wt.workerId} [${wt.status}] — ${branch} @ ${wt.path} (base: ${wt.base}, updated: ${seen})`;
131
+ };
132
+ // --- IO: Worktree operations ---
133
+ // Record an isolated worktree for a worker. Idempotent on worker_id (re-spawn
134
+ // replaces the row). branch starts empty — the worker reports it back later
135
+ // (Phase 2), at which point the master fills it via setWorktreeStatus.
136
+ export const upsertWorktree = (workerId, path, base) => {
137
+ const now = nowMs();
138
+ execute(`INSERT INTO worktrees (worker_id, branch, path, base, status, created_at, updated_at)
139
+ VALUES (?, '', ?, ?, 'active', ?, ?)
140
+ ON CONFLICT(worker_id) DO UPDATE SET
141
+ path = excluded.path,
142
+ base = excluded.base,
143
+ status = 'active',
144
+ updated_at = excluded.updated_at`, workerId, path, base, now, now);
145
+ return {
146
+ workerId,
147
+ branch: "",
148
+ path,
149
+ base,
150
+ status: "active",
151
+ createdAt: now,
152
+ updatedAt: now,
153
+ };
154
+ };
155
+ export const getWorktree = (workerId) => {
156
+ const row = queryOne(`SELECT * FROM worktrees WHERE worker_id = ?`, workerId);
157
+ return row ? worktreeFromRow(row) : undefined;
158
+ };
159
+ export const getAllWorktrees = () => queryAll(`SELECT * FROM worktrees ORDER BY created_at`)
160
+ .map(worktreeFromRow);
161
+ // Update lifecycle status, optionally also recording the branch the worker
162
+ // reported (its AIMFP aimfp-worker-N-NNN branch). branch is only overwritten
163
+ // when a non-empty value is supplied, so status-only updates preserve it.
164
+ export const setWorktreeStatus = (workerId, status, branch) => {
165
+ execute(`UPDATE worktrees
166
+ SET status = ?,
167
+ branch = CASE WHEN ? <> '' THEN ? ELSE branch END,
168
+ updated_at = ?
169
+ WHERE worker_id = ?`, status, branch ?? "", branch ?? "", nowMs(), workerId);
170
+ };
171
+ export const markWorktreeRemoved = (workerId) => {
172
+ setWorktreeStatus(workerId, "removed");
173
+ };
174
+ export const clearOldMessages = (keep) => {
175
+ // Count total messages
176
+ const countRow = queryOne(`SELECT COUNT(*) as cnt FROM messages`);
177
+ const total = countRow?.cnt ?? 0;
178
+ if (total <= keep)
179
+ return 0;
180
+ const toDelete = total - keep;
181
+ execute(`DELETE FROM messages WHERE id IN (
182
+ SELECT id FROM messages ORDER BY ts ASC LIMIT ?
183
+ )`, toDelete);
184
+ return toDelete;
185
+ };
186
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { TaskContract, ParsedTaskContract } from "./types.js";
2
+ export declare const buildTaskContract: (contract: TaskContract) => string;
3
+ export declare const parseTaskContract: (content: string) => ParsedTaskContract;
4
+ //# sourceMappingURL=task-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-contract.d.ts","sourceRoot":"","sources":["../src/task-contract.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AA4DpB,eAAO,MAAM,iBAAiB,GAAI,UAAU,YAAY,KAAG,MAQvD,CAAC;AAKL,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,KAAG,kBAgDnD,CAAC"}