@loompad/cli 0.1.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 (177) hide show
  1. package/ARCHITECTURE.md +211 -0
  2. package/CHANGELOG.md +470 -0
  3. package/LICENSE +21 -0
  4. package/README.md +630 -0
  5. package/dist/adapters/base.d.ts +71 -0
  6. package/dist/adapters/base.js +187 -0
  7. package/dist/adapters/base.js.map +1 -0
  8. package/dist/adapters/bridges/antigravity.d.ts +53 -0
  9. package/dist/adapters/bridges/antigravity.js +106 -0
  10. package/dist/adapters/bridges/antigravity.js.map +1 -0
  11. package/dist/adapters/bridges/cdp.d.ts +82 -0
  12. package/dist/adapters/bridges/cdp.js +222 -0
  13. package/dist/adapters/bridges/cdp.js.map +1 -0
  14. package/dist/adapters/bridges/gui-chat.d.ts +113 -0
  15. package/dist/adapters/bridges/gui-chat.js +498 -0
  16. package/dist/adapters/bridges/gui-chat.js.map +1 -0
  17. package/dist/adapters/bridges/kiro.d.ts +19 -0
  18. package/dist/adapters/bridges/kiro.js +22 -0
  19. package/dist/adapters/bridges/kiro.js.map +1 -0
  20. package/dist/adapters/bridges/profiles.d.ts +82 -0
  21. package/dist/adapters/bridges/profiles.js +125 -0
  22. package/dist/adapters/bridges/profiles.js.map +1 -0
  23. package/dist/adapters/claude-code.d.ts +26 -0
  24. package/dist/adapters/claude-code.js +209 -0
  25. package/dist/adapters/claude-code.js.map +1 -0
  26. package/dist/adapters/codex.d.ts +51 -0
  27. package/dist/adapters/codex.js +291 -0
  28. package/dist/adapters/codex.js.map +1 -0
  29. package/dist/adapters/echo.d.ts +20 -0
  30. package/dist/adapters/echo.js +79 -0
  31. package/dist/adapters/echo.js.map +1 -0
  32. package/dist/adapters/grok.d.ts +61 -0
  33. package/dist/adapters/grok.js +217 -0
  34. package/dist/adapters/grok.js.map +1 -0
  35. package/dist/adapters/index.d.ts +9 -0
  36. package/dist/adapters/index.js +33 -0
  37. package/dist/adapters/index.js.map +1 -0
  38. package/dist/adapters/opencode.d.ts +64 -0
  39. package/dist/adapters/opencode.js +426 -0
  40. package/dist/adapters/opencode.js.map +1 -0
  41. package/dist/cli/common.d.ts +11 -0
  42. package/dist/cli/common.js +40 -0
  43. package/dist/cli/common.js.map +1 -0
  44. package/dist/cli/doctor.d.ts +12 -0
  45. package/dist/cli/doctor.js +181 -0
  46. package/dist/cli/doctor.js.map +1 -0
  47. package/dist/cli/index.d.ts +8 -0
  48. package/dist/cli/index.js +641 -0
  49. package/dist/cli/index.js.map +1 -0
  50. package/dist/cli/tui-model.d.ts +73 -0
  51. package/dist/cli/tui-model.js +312 -0
  52. package/dist/cli/tui-model.js.map +1 -0
  53. package/dist/cli/tui.d.ts +15 -0
  54. package/dist/cli/tui.js +451 -0
  55. package/dist/cli/tui.js.map +1 -0
  56. package/dist/cli/ui.d.ts +10 -0
  57. package/dist/cli/ui.js +135 -0
  58. package/dist/cli/ui.js.map +1 -0
  59. package/dist/core/ades.d.ts +79 -0
  60. package/dist/core/ades.js +130 -0
  61. package/dist/core/ades.js.map +1 -0
  62. package/dist/core/baton.d.ts +37 -0
  63. package/dist/core/baton.js +92 -0
  64. package/dist/core/baton.js.map +1 -0
  65. package/dist/core/brain-extract.d.ts +111 -0
  66. package/dist/core/brain-extract.js +248 -0
  67. package/dist/core/brain-extract.js.map +1 -0
  68. package/dist/core/brain-index.d.ts +128 -0
  69. package/dist/core/brain-index.js +338 -0
  70. package/dist/core/brain-index.js.map +1 -0
  71. package/dist/core/brain.d.ts +214 -0
  72. package/dist/core/brain.js +425 -0
  73. package/dist/core/brain.js.map +1 -0
  74. package/dist/core/claude-cli.d.ts +12 -0
  75. package/dist/core/claude-cli.js +47 -0
  76. package/dist/core/claude-cli.js.map +1 -0
  77. package/dist/core/distill.d.ts +19 -0
  78. package/dist/core/distill.js +88 -0
  79. package/dist/core/distill.js.map +1 -0
  80. package/dist/core/eventlog.d.ts +43 -0
  81. package/dist/core/eventlog.js +211 -0
  82. package/dist/core/eventlog.js.map +1 -0
  83. package/dist/core/git.d.ts +203 -0
  84. package/dist/core/git.js +460 -0
  85. package/dist/core/git.js.map +1 -0
  86. package/dist/core/logbook.d.ts +59 -0
  87. package/dist/core/logbook.js +118 -0
  88. package/dist/core/logbook.js.map +1 -0
  89. package/dist/core/memory.d.ts +34 -0
  90. package/dist/core/memory.js +124 -0
  91. package/dist/core/memory.js.map +1 -0
  92. package/dist/core/notify.d.ts +11 -0
  93. package/dist/core/notify.js +30 -0
  94. package/dist/core/notify.js.map +1 -0
  95. package/dist/core/projection.d.ts +20 -0
  96. package/dist/core/projection.js +96 -0
  97. package/dist/core/projection.js.map +1 -0
  98. package/dist/core/registry.d.ts +76 -0
  99. package/dist/core/registry.js +147 -0
  100. package/dist/core/registry.js.map +1 -0
  101. package/dist/core/router.d.ts +42 -0
  102. package/dist/core/router.js +99 -0
  103. package/dist/core/router.js.map +1 -0
  104. package/dist/core/routes.d.ts +93 -0
  105. package/dist/core/routes.js +399 -0
  106. package/dist/core/routes.js.map +1 -0
  107. package/dist/core/search.d.ts +63 -0
  108. package/dist/core/search.js +0 -0
  109. package/dist/core/search.js.map +1 -0
  110. package/dist/core/setup.d.ts +70 -0
  111. package/dist/core/setup.js +250 -0
  112. package/dist/core/setup.js.map +1 -0
  113. package/dist/core/suggestions.d.ts +15 -0
  114. package/dist/core/suggestions.js +38 -0
  115. package/dist/core/suggestions.js.map +1 -0
  116. package/dist/core/worktree.d.ts +32 -0
  117. package/dist/core/worktree.js +83 -0
  118. package/dist/core/worktree.js.map +1 -0
  119. package/dist/daemon/app-page.d.ts +32 -0
  120. package/dist/daemon/app-page.js +6363 -0
  121. package/dist/daemon/app-page.js.map +1 -0
  122. package/dist/daemon/auth.d.ts +51 -0
  123. package/dist/daemon/auth.js +135 -0
  124. package/dist/daemon/auth.js.map +1 -0
  125. package/dist/daemon/board.d.ts +117 -0
  126. package/dist/daemon/board.js +202 -0
  127. package/dist/daemon/board.js.map +1 -0
  128. package/dist/daemon/brand-icons.d.ts +29 -0
  129. package/dist/daemon/brand-icons.js +44 -0
  130. package/dist/daemon/brand-icons.js.map +1 -0
  131. package/dist/daemon/client.d.ts +127 -0
  132. package/dist/daemon/client.js +237 -0
  133. package/dist/daemon/client.js.map +1 -0
  134. package/dist/daemon/geist-font.d.ts +10 -0
  135. package/dist/daemon/geist-font.js +783 -0
  136. package/dist/daemon/geist-font.js.map +1 -0
  137. package/dist/daemon/guards.d.ts +18 -0
  138. package/dist/daemon/guards.js +40 -0
  139. package/dist/daemon/guards.js.map +1 -0
  140. package/dist/daemon/linear.d.ts +59 -0
  141. package/dist/daemon/linear.js +117 -0
  142. package/dist/daemon/linear.js.map +1 -0
  143. package/dist/daemon/push.d.ts +22 -0
  144. package/dist/daemon/push.js +58 -0
  145. package/dist/daemon/push.js.map +1 -0
  146. package/dist/daemon/runtime.d.ts +299 -0
  147. package/dist/daemon/runtime.js +1016 -0
  148. package/dist/daemon/runtime.js.map +1 -0
  149. package/dist/daemon/server.d.ts +125 -0
  150. package/dist/daemon/server.js +1728 -0
  151. package/dist/daemon/server.js.map +1 -0
  152. package/dist/daemon/tasks.d.ts +153 -0
  153. package/dist/daemon/tasks.js +264 -0
  154. package/dist/daemon/tasks.js.map +1 -0
  155. package/dist/daemon/terminals.d.ts +82 -0
  156. package/dist/daemon/terminals.js +372 -0
  157. package/dist/daemon/terminals.js.map +1 -0
  158. package/dist/index.d.ts +20 -0
  159. package/dist/index.js +20 -0
  160. package/dist/index.js.map +1 -0
  161. package/dist/sdk.d.ts +17 -0
  162. package/dist/sdk.js +17 -0
  163. package/dist/sdk.js.map +1 -0
  164. package/dist/types.d.ts +236 -0
  165. package/dist/types.js +18 -0
  166. package/dist/types.js.map +1 -0
  167. package/docs/SETUP.md +265 -0
  168. package/docs/adapters.md +132 -0
  169. package/docs/design-system.md +245 -0
  170. package/docs/img/board-linear.png +0 -0
  171. package/docs/img/board-projects.png +0 -0
  172. package/docs/img/brain.png +0 -0
  173. package/docs/img/settings.png +0 -0
  174. package/docs/img/workspace.png +0 -0
  175. package/docs/integration-notes.md +76 -0
  176. package/docs/proposals/brain.md +262 -0
  177. package/package.json +84 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/cli/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The ADEs Loom knows how to drive, in one list.
3
+ *
4
+ * This exists because "which agents are real" used to be answered in three
5
+ * places at once: a hardcoded probe pair in the daemon, a hardcoded pair in
6
+ * defaultAgentConfigs, and a set of logos in the web app that agreed with
7
+ * neither. The UI shipped Codex and Kiro marks for kinds `loom` would reject.
8
+ * One list, and the answer is the same everywhere.
9
+ *
10
+ * An entry here is a claim that Loom can actually drive the thing. If it can't
11
+ * yet, it doesn't get a row — a logo is not an integration.
12
+ */
13
+ import type { AgentConfig } from "../types.js";
14
+ export interface AdeSpec {
15
+ /** The agent kind, as written in .loom/config.json. */
16
+ kind: string;
17
+ /** Human name, for docs and UI. */
18
+ label: string;
19
+ /**
20
+ * adapter — can hold the baton and run a turn headless.
21
+ * bridge — a GUI app Loom drives over the DevTools protocol; needs the app
22
+ * running with a debugging port, so it is never auto-added.
23
+ */
24
+ tier: "adapter" | "bridge";
25
+ /** Is it usable on this machine right now? */
26
+ probe: () => Promise<boolean>;
27
+ /**
28
+ * Common model values this ADE's CLI accepts, as the model picker's
29
+ * suggestions. Not exhaustive and not the truth about what's installed —
30
+ * the picker always offers "Default" (no --model, the CLI's own choice) and
31
+ * a custom field, so a stale entry here is a convenience that went out of
32
+ * date, never a wall. Empty for bridges: a GUI app picks its own model in its
33
+ * own window, and Loom doesn't get a flag.
34
+ */
35
+ models?: string[];
36
+ }
37
+ /**
38
+ * Preference order matters: the first three adapters found get the canonical
39
+ * planner/executor/reviewer roles that the default "ship" route is built from.
40
+ */
41
+ export declare const ADES: AdeSpec[];
42
+ /** Which kinds can hold the baton. */
43
+ export declare function adapterKinds(): string[];
44
+ /**
45
+ * Probe every adapter on this machine, in parallel.
46
+ *
47
+ * Bridges are excluded on purpose: they need their GUI launched with a
48
+ * debugging port, so "installed" tells you nothing about "drivable", and a
49
+ * new project should not be born holding an agent that can't answer.
50
+ */
51
+ export declare function detectAdes(): Promise<Record<string, boolean>>;
52
+ /** Default "ship" pipeline over whichever of planner/executor/reviewer exist. */
53
+ export declare function buildDefaultRoutes(agents: AgentConfig[]): Record<string, string[]> | undefined;
54
+ /**
55
+ * The agents a new project starts with: the ADEs actually installed here, and
56
+ * nothing else.
57
+ *
58
+ * It used to fall back to an `echo` agent when it found none. echo is a test
59
+ * double — it replies with your own message and reports a made-up $0.001 — so
60
+ * a machine without claude or opencode got a project whose "agent" faked every
61
+ * turn, presented as a detected ADE. Better an empty roster and an honest "no
62
+ * ADEs found". (echo is still a registered kind; you can ask for it by name in
63
+ * .loom/config.json. It just isn't handed to anyone who didn't.)
64
+ *
65
+ * **Every agent's role is its own kind, and that isn't a placeholder.**
66
+ *
67
+ * This used to hand out planner / executor / reviewer by detection order, so
68
+ * Claude Code became "the planner" and OpenCode became "the executor" because
69
+ * of where they sat in a list in this file. Nobody decided that. It read like a
70
+ * recommendation Loom had earned, it was an accident of iteration order, and it
71
+ * quietly shaped how people used their own agents.
72
+ *
73
+ * A role is a job you define. Loom doesn't know which of your agents should
74
+ * plan, and pretending it does is worse than saying nothing — so the default
75
+ * describes rather than assigns ("codex" is codex), and you rename it to the
76
+ * job you actually have. The rail's agent picker does that; so does
77
+ * POST /api/projects/:id/agents/:agentId/role.
78
+ */
79
+ export declare function defaultAgentConfigs(availability: Record<string, boolean>): AgentConfig[];
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The ADEs Loom knows how to drive, in one list.
3
+ *
4
+ * This exists because "which agents are real" used to be answered in three
5
+ * places at once: a hardcoded probe pair in the daemon, a hardcoded pair in
6
+ * defaultAgentConfigs, and a set of logos in the web app that agreed with
7
+ * neither. The UI shipped Codex and Kiro marks for kinds `loom` would reject.
8
+ * One list, and the answer is the same everywhere.
9
+ *
10
+ * An entry here is a claim that Loom can actually drive the thing. If it can't
11
+ * yet, it doesn't get a row — a logo is not an integration.
12
+ */
13
+ import { cliAvailable } from "../adapters/base.js";
14
+ import { codexBin } from "../adapters/codex.js";
15
+ import { grokBin } from "../adapters/grok.js";
16
+ /**
17
+ * Preference order matters: the first three adapters found get the canonical
18
+ * planner/executor/reviewer roles that the default "ship" route is built from.
19
+ */
20
+ export const ADES = [
21
+ {
22
+ kind: "claude-code",
23
+ label: "Claude Code",
24
+ tier: "adapter",
25
+ // The CLI takes short aliases as well as full ids; the aliases don't go
26
+ // stale when a new snapshot ships, which the full ids do.
27
+ models: ["opus", "sonnet", "haiku"],
28
+ probe: () => cliAvailable("claude"),
29
+ },
30
+ {
31
+ kind: "codex",
32
+ label: "Codex",
33
+ tier: "adapter",
34
+ models: ["gpt-5-codex", "gpt-5", "o4-mini"],
35
+ // The CLI ships inside Codex.app as well as on PATH; a Mac with the app and
36
+ // an empty PATH is the common case.
37
+ probe: async () => {
38
+ const bin = codexBin();
39
+ return bin ? cliAvailable(bin) : false;
40
+ },
41
+ },
42
+ {
43
+ kind: "opencode",
44
+ label: "OpenCode",
45
+ tier: "adapter",
46
+ // opencode wants provider/model, and which providers exist is that install's
47
+ // business — so these are examples, and the custom field is the real path.
48
+ models: ["anthropic/claude-sonnet-4", "openai/gpt-5", "google/gemini-2.5-pro"],
49
+ probe: () => cliAvailable("opencode"),
50
+ },
51
+ {
52
+ kind: "grok-code",
53
+ label: "Grok Code",
54
+ tier: "adapter",
55
+ models: ["grok-code-fast-1", "grok-4"],
56
+ probe: async () => {
57
+ const bin = grokBin();
58
+ return bin ? cliAvailable(bin) : false;
59
+ },
60
+ },
61
+ {
62
+ kind: "antigravity",
63
+ label: "Antigravity",
64
+ tier: "bridge",
65
+ // Presence is decided by the debugging port, not by a file on disk: an
66
+ // installed-but-closed Antigravity is not something Loom can drive.
67
+ probe: async () => false,
68
+ },
69
+ {
70
+ kind: "kiro",
71
+ label: "Kiro",
72
+ tier: "bridge",
73
+ probe: async () => false,
74
+ },
75
+ ];
76
+ /** Which kinds can hold the baton. */
77
+ export function adapterKinds() {
78
+ return ADES.filter((a) => a.tier === "adapter").map((a) => a.kind);
79
+ }
80
+ /**
81
+ * Probe every adapter on this machine, in parallel.
82
+ *
83
+ * Bridges are excluded on purpose: they need their GUI launched with a
84
+ * debugging port, so "installed" tells you nothing about "drivable", and a
85
+ * new project should not be born holding an agent that can't answer.
86
+ */
87
+ export async function detectAdes() {
88
+ const adapters = ADES.filter((a) => a.tier === "adapter");
89
+ const results = await Promise.all(adapters.map((a) => a.probe().catch(() => false)));
90
+ const out = {};
91
+ adapters.forEach((a, i) => (out[a.kind] = results[i] ?? false));
92
+ return out;
93
+ }
94
+ /** Default "ship" pipeline over whichever of planner/executor/reviewer exist. */
95
+ export function buildDefaultRoutes(agents) {
96
+ const order = ["planner", "executor", "reviewer"];
97
+ const steps = order.filter((role) => agents.some((a) => a.role === role));
98
+ return steps.length >= 2 ? { ship: steps } : undefined;
99
+ }
100
+ /**
101
+ * The agents a new project starts with: the ADEs actually installed here, and
102
+ * nothing else.
103
+ *
104
+ * It used to fall back to an `echo` agent when it found none. echo is a test
105
+ * double — it replies with your own message and reports a made-up $0.001 — so
106
+ * a machine without claude or opencode got a project whose "agent" faked every
107
+ * turn, presented as a detected ADE. Better an empty roster and an honest "no
108
+ * ADEs found". (echo is still a registered kind; you can ask for it by name in
109
+ * .loom/config.json. It just isn't handed to anyone who didn't.)
110
+ *
111
+ * **Every agent's role is its own kind, and that isn't a placeholder.**
112
+ *
113
+ * This used to hand out planner / executor / reviewer by detection order, so
114
+ * Claude Code became "the planner" and OpenCode became "the executor" because
115
+ * of where they sat in a list in this file. Nobody decided that. It read like a
116
+ * recommendation Loom had earned, it was an accident of iteration order, and it
117
+ * quietly shaped how people used their own agents.
118
+ *
119
+ * A role is a job you define. Loom doesn't know which of your agents should
120
+ * plan, and pretending it does is worse than saying nothing — so the default
121
+ * describes rather than assigns ("codex" is codex), and you rename it to the
122
+ * job you actually have. The rail's agent picker does that; so does
123
+ * POST /api/projects/:id/agents/:agentId/role.
124
+ */
125
+ export function defaultAgentConfigs(availability) {
126
+ return adapterKinds()
127
+ .filter((kind) => availability[kind])
128
+ .map((kind) => ({ id: kind, kind, role: kind }));
129
+ }
130
+ //# sourceMappingURL=ades.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ades.js","sourceRoot":"","sources":["../../src/core/ades.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The baton = the write lock. Exactly one adapter per project may hold it;
3
+ * holding it is what authorizes edits to the shared working tree.
4
+ *
5
+ * Handoffs are explicit (the user confirms in the surface). The active agent
6
+ * is interruptible: a confirmed handoff interrupts an in-flight turn.
7
+ */
8
+ import type { EventLog } from "./eventlog.js";
9
+ export declare class NotHolderError extends Error {
10
+ readonly agentId: string;
11
+ readonly holder: string | null;
12
+ constructor(agentId: string, holder: string | null);
13
+ }
14
+ export declare class BatonManager {
15
+ private projectDir;
16
+ private log;
17
+ constructor(projectDir: string, log: EventLog);
18
+ holder(): string | null;
19
+ holderSince(): number | undefined;
20
+ /** First acquisition (no current holder). Logged as a handoff from nobody. */
21
+ acquire(agentId: string): void;
22
+ /**
23
+ * Move the baton. Caller is responsible for interrupting the current
24
+ * holder and injecting the projection — see ProjectRuntime.handoff().
25
+ */
26
+ handoff(to: string, meta?: Record<string, unknown>): {
27
+ from: string | null;
28
+ };
29
+ release(agentId: string): void;
30
+ /** Throws NotHolderError unless agentId currently holds the baton. */
31
+ assertHolder(agentId: string): void;
32
+ /**
33
+ * Clear a holder unconditionally — used when the persisted holder no
34
+ * longer exists in the project config (agent removed/renamed).
35
+ */
36
+ forceClear(reason?: string): void;
37
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The baton = the write lock. Exactly one adapter per project may hold it;
3
+ * holding it is what authorizes edits to the shared working tree.
4
+ *
5
+ * Handoffs are explicit (the user confirms in the surface). The active agent
6
+ * is interruptible: a confirmed handoff interrupts an in-flight turn.
7
+ */
8
+ import { readProjectState, writeProjectState } from "./registry.js";
9
+ export class NotHolderError extends Error {
10
+ agentId;
11
+ holder;
12
+ constructor(agentId, holder) {
13
+ super(holder
14
+ ? `agent "${agentId}" does not hold the baton (holder: "${holder}")`
15
+ : `no agent holds the baton`);
16
+ this.agentId = agentId;
17
+ this.holder = holder;
18
+ this.name = "NotHolderError";
19
+ }
20
+ }
21
+ export class BatonManager {
22
+ projectDir;
23
+ log;
24
+ constructor(projectDir, log) {
25
+ this.projectDir = projectDir;
26
+ this.log = log;
27
+ }
28
+ holder() {
29
+ return readProjectState(this.projectDir).holder;
30
+ }
31
+ holderSince() {
32
+ return readProjectState(this.projectDir).holderSince;
33
+ }
34
+ /** First acquisition (no current holder). Logged as a handoff from nobody. */
35
+ acquire(agentId) {
36
+ const state = readProjectState(this.projectDir);
37
+ if (state.holder === agentId)
38
+ return;
39
+ if (state.holder && state.holder !== agentId) {
40
+ throw new NotHolderError(agentId, state.holder);
41
+ }
42
+ state.holder = agentId;
43
+ state.holderSince = Date.now();
44
+ writeProjectState(this.projectDir, state);
45
+ this.log.append({ kind: "handoff", payload: { from: null, to: agentId } });
46
+ }
47
+ /**
48
+ * Move the baton. Caller is responsible for interrupting the current
49
+ * holder and injecting the projection — see ProjectRuntime.handoff().
50
+ */
51
+ handoff(to, meta = {}) {
52
+ const state = readProjectState(this.projectDir);
53
+ const from = state.holder;
54
+ if (from === to)
55
+ return { from };
56
+ state.holder = to;
57
+ state.holderSince = Date.now();
58
+ writeProjectState(this.projectDir, state);
59
+ this.log.append({ kind: "handoff", payload: { from, to, ...meta } });
60
+ return { from };
61
+ }
62
+ release(agentId) {
63
+ const state = readProjectState(this.projectDir);
64
+ if (state.holder !== agentId)
65
+ return;
66
+ state.holder = null;
67
+ delete state.holderSince;
68
+ writeProjectState(this.projectDir, state);
69
+ this.log.append({ kind: "handoff", payload: { from: agentId, to: null } });
70
+ }
71
+ /** Throws NotHolderError unless agentId currently holds the baton. */
72
+ assertHolder(agentId) {
73
+ const holder = this.holder();
74
+ if (holder !== agentId)
75
+ throw new NotHolderError(agentId, holder);
76
+ }
77
+ /**
78
+ * Clear a holder unconditionally — used when the persisted holder no
79
+ * longer exists in the project config (agent removed/renamed).
80
+ */
81
+ forceClear(reason = "holder removed") {
82
+ const state = readProjectState(this.projectDir);
83
+ if (!state.holder)
84
+ return;
85
+ const from = state.holder;
86
+ state.holder = null;
87
+ delete state.holderSince;
88
+ writeProjectState(this.projectDir, state);
89
+ this.log.append({ kind: "handoff", payload: { from, to: null, reason } });
90
+ }
91
+ }
92
+ //# sourceMappingURL=baton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baton.js","sourceRoot":"","sources":["../../src/core/baton.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Phase 2 — learning from a turn.
3
+ *
4
+ * Phases 0 and 1 gave the brain units and retrieval, both deterministic. This is
5
+ * where memories start arriving on their own: when an agent finishes a turn, an
6
+ * ADE reads the transcript and proposes what to remember, reconciled against
7
+ * what's already known.
8
+ *
9
+ * The shape is mem0's, adapted (see docs/proposals/brain.md):
10
+ * - retrieve the candidates a new fact might collide with (phase 1);
11
+ * - show them to the extractor INTEGER-MAPPED, never by real id — a
12
+ * hallucinated "7" is detectable and droppable; a hallucinated uuid is
13
+ * silent corruption (mem0 main.py:889);
14
+ * - the extractor returns ADD / UPDATE / FORGET / NONE;
15
+ * - every ADD/UPDATE must quote the span it came from, and that span is
16
+ * verified IN CODE to appear in the turn — the cheapest hallucination guard
17
+ * there is, and the one mem0 doesn't have.
18
+ *
19
+ * The LLM is injected as an `engine` (a prompt → text function), so all of the
20
+ * logic here — mapping, parsing, evidence-checking, applying — is pure and
21
+ * tested without a model. The default engine is the logged-in Claude CLI, the
22
+ * same no-API-key path distill.ts already uses.
23
+ */
24
+ import type { Brain, Memory, MemoryKind } from "./brain.js";
25
+ /** One thing the extractor decided to do. Ids here are the INTEGER map keys. */
26
+ export type ExtractOp = {
27
+ op: "ADD";
28
+ text: string;
29
+ kind: MemoryKind;
30
+ entities?: string[];
31
+ confidence?: number;
32
+ evidence: string;
33
+ } | {
34
+ op: "UPDATE";
35
+ id: string;
36
+ text: string;
37
+ confidence?: number;
38
+ evidence: string;
39
+ } | {
40
+ op: "FORGET";
41
+ id: string;
42
+ reason: string;
43
+ } | {
44
+ op: "NONE";
45
+ };
46
+ /** A retrieved memory, presented to the extractor under a throwaway integer id. */
47
+ export interface Candidate {
48
+ intId: string;
49
+ memory: Memory;
50
+ }
51
+ export interface ExtractResult {
52
+ added: Memory[];
53
+ updated: Memory[];
54
+ forgotten: string[];
55
+ /** Ops thrown out, with why — surfaced so a bad extractor is visible, not silent. */
56
+ dropped: Array<{
57
+ op: ExtractOp;
58
+ reason: string;
59
+ }>;
60
+ }
61
+ /**
62
+ * Does the quoted span actually appear in the turn?
63
+ *
64
+ * The whole anti-hallucination guarantee rests on this one check. Whitespace is
65
+ * normalised (the model reflows), but the words have to be there. A short quote
66
+ * is too easy to satisfy by accident, so anything under a few characters is
67
+ * rejected outright.
68
+ */
69
+ export declare function evidenceInTurn(evidence: string, turn: string): boolean;
70
+ export declare const EXTRACT_SYSTEM = "You extract durable engineering memory from one agent turn in a software project.\n\nReturn ONLY facts that will still matter next week: constraints reality imposes, decisions and why, conventions this repo follows, plain facts about how things are, and \u2014 most valuable \u2014 failures (what was tried and did not work, so nobody burns the time again). Skip chit-chat, restated instructions, and anything true only for this minute.\n\nYou are given EXISTING memories, each under an integer id. Use them ONLY to avoid duplicates and to correct what's now wrong:\n- ADD a new memory when the turn reveals something not already known.\n- UPDATE an existing memory (by its integer id) when the turn shows it was incomplete or has changed. Keep the id.\n- FORGET an existing memory (by its integer id) when the turn shows it is now false.\n- Otherwise NONE.\n\nRules, strictly:\n- Every ADD and UPDATE MUST include \"evidence\": a short verbatim quote FROM THE TURN that the memory is based on. If you can't quote it from the turn, don't write it.\n- Each memory is ONE self-contained sentence that reads true with no surrounding context.\n- Use ONLY the integer ids shown for UPDATE/FORGET. Never invent an id.\n- kind is one of: constraint, decision, convention, fact, failure.\n\nRespond with JSON only, no prose:\n{\"ops\":[{\"op\":\"ADD\",\"text\":\"...\",\"kind\":\"failure\",\"evidence\":\"...\",\"confidence\":0.9},{\"op\":\"UPDATE\",\"id\":\"2\",\"text\":\"...\",\"evidence\":\"...\"},{\"op\":\"FORGET\",\"id\":\"5\",\"reason\":\"...\"},{\"op\":\"NONE\"}]}";
71
+ export declare function buildExtractionPrompt(turn: string, candidates: Candidate[]): string;
72
+ /** Pull the ops array out of the engine's reply, tolerantly. */
73
+ export declare function parseExtraction(response: string): ExtractOp[];
74
+ export interface ApplyOpts {
75
+ /** Who's learning this — an agent id, or "brain" for the extractor itself. */
76
+ by: string;
77
+ eventId: number;
78
+ chat?: string;
79
+ }
80
+ /**
81
+ * Apply the extractor's ops to the brain, dropping anything that fails a guard.
82
+ *
83
+ * The guards, in order: an ADD/UPDATE with no verifiable evidence span is a
84
+ * hallucination and is dropped; an UPDATE/FORGET whose integer id isn't in the
85
+ * candidate set is a hallucinated reference and is dropped; a real id maps back
86
+ * to its uuid before touching the store.
87
+ */
88
+ export declare function applyExtraction(brain: Brain, ops: ExtractOp[], turn: string, candidates: Candidate[], opts: ApplyOpts): ExtractResult;
89
+ export type ExtractEngine = (prompt: {
90
+ system: string;
91
+ user: string;
92
+ }) => Promise<string>;
93
+ export interface ExtractFromTurnOpts {
94
+ engine: ExtractEngine;
95
+ /** Who ran the turn — the memories are attributed to them. */
96
+ agentId: string;
97
+ chat?: string;
98
+ /** Files the turn touched — sharpens candidate retrieval. */
99
+ files?: string[];
100
+ /** How many existing memories to show the extractor as collision candidates. */
101
+ candidateLimit?: number;
102
+ eventId?: number;
103
+ }
104
+ /**
105
+ * Learn from one turn: retrieve candidates, ask the engine, apply the ops.
106
+ *
107
+ * Non-throwing by contract — a broken or slow extractor must never be able to
108
+ * take down the turn that triggered it (the same rule distill.ts follows). Any
109
+ * failure returns an empty result.
110
+ */
111
+ export declare function extractFromTurn(brain: Brain, turn: string, opts: ExtractFromTurnOpts): Promise<ExtractResult>;