coterie 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 (203) hide show
  1. package/README.md +137 -0
  2. package/dist/adapters/base.d.ts +56 -0
  3. package/dist/adapters/base.d.ts.map +1 -0
  4. package/dist/adapters/base.js +176 -0
  5. package/dist/adapters/base.js.map +1 -0
  6. package/dist/adapters/claudeCode.d.ts +11 -0
  7. package/dist/adapters/claudeCode.d.ts.map +1 -0
  8. package/dist/adapters/claudeCode.js +65 -0
  9. package/dist/adapters/claudeCode.js.map +1 -0
  10. package/dist/adapters/codex.d.ts +10 -0
  11. package/dist/adapters/codex.d.ts.map +1 -0
  12. package/dist/adapters/codex.js +51 -0
  13. package/dist/adapters/codex.js.map +1 -0
  14. package/dist/adapters/cursor.d.ts +16 -0
  15. package/dist/adapters/cursor.d.ts.map +1 -0
  16. package/dist/adapters/cursor.js +47 -0
  17. package/dist/adapters/cursor.js.map +1 -0
  18. package/dist/adapters/fake.d.ts +19 -0
  19. package/dist/adapters/fake.d.ts.map +1 -0
  20. package/dist/adapters/fake.js +41 -0
  21. package/dist/adapters/fake.js.map +1 -0
  22. package/dist/adapters/index.d.ts +11 -0
  23. package/dist/adapters/index.d.ts.map +1 -0
  24. package/dist/adapters/index.js +11 -0
  25. package/dist/adapters/index.js.map +1 -0
  26. package/dist/adapters/stream.d.ts +6 -0
  27. package/dist/adapters/stream.d.ts.map +1 -0
  28. package/dist/adapters/stream.js +20 -0
  29. package/dist/adapters/stream.js.map +1 -0
  30. package/dist/chat/configs.d.ts +18 -0
  31. package/dist/chat/configs.d.ts.map +1 -0
  32. package/dist/chat/configs.js +71 -0
  33. package/dist/chat/configs.js.map +1 -0
  34. package/dist/chat/doctor.d.ts +16 -0
  35. package/dist/chat/doctor.d.ts.map +1 -0
  36. package/dist/chat/doctor.js +43 -0
  37. package/dist/chat/doctor.js.map +1 -0
  38. package/dist/chat/finalizer.d.ts +25 -0
  39. package/dist/chat/finalizer.d.ts.map +1 -0
  40. package/dist/chat/finalizer.js +52 -0
  41. package/dist/chat/finalizer.js.map +1 -0
  42. package/dist/chat/preflight.d.ts +37 -0
  43. package/dist/chat/preflight.d.ts.map +1 -0
  44. package/dist/chat/preflight.js +115 -0
  45. package/dist/chat/preflight.js.map +1 -0
  46. package/dist/chat/render.d.ts +21 -0
  47. package/dist/chat/render.d.ts.map +1 -0
  48. package/dist/chat/render.js +113 -0
  49. package/dist/chat/render.js.map +1 -0
  50. package/dist/chat/repl.d.ts +9 -0
  51. package/dist/chat/repl.d.ts.map +1 -0
  52. package/dist/chat/repl.js +275 -0
  53. package/dist/chat/repl.js.map +1 -0
  54. package/dist/chat/trace.d.ts +29 -0
  55. package/dist/chat/trace.d.ts.map +1 -0
  56. package/dist/chat/trace.js +132 -0
  57. package/dist/chat/trace.js.map +1 -0
  58. package/dist/chat/transcript.d.ts +15 -0
  59. package/dist/chat/transcript.d.ts.map +1 -0
  60. package/dist/chat/transcript.js +39 -0
  61. package/dist/chat/transcript.js.map +1 -0
  62. package/dist/cli.d.ts +5 -0
  63. package/dist/cli.d.ts.map +1 -0
  64. package/dist/cli.js +134 -0
  65. package/dist/cli.js.map +1 -0
  66. package/dist/config.d.ts +2 -0
  67. package/dist/config.d.ts.map +1 -0
  68. package/dist/config.js +52 -0
  69. package/dist/config.js.map +1 -0
  70. package/dist/core/annotation.d.ts +22 -0
  71. package/dist/core/annotation.d.ts.map +1 -0
  72. package/dist/core/annotation.js +45 -0
  73. package/dist/core/annotation.js.map +1 -0
  74. package/dist/core/compile.d.ts +3 -0
  75. package/dist/core/compile.d.ts.map +1 -0
  76. package/dist/core/compile.js +9 -0
  77. package/dist/core/compile.js.map +1 -0
  78. package/dist/core/executor.d.ts +32 -0
  79. package/dist/core/executor.d.ts.map +1 -0
  80. package/dist/core/executor.js +73 -0
  81. package/dist/core/executor.js.map +1 -0
  82. package/dist/core/json.d.ts +9 -0
  83. package/dist/core/json.d.ts.map +1 -0
  84. package/dist/core/json.js +49 -0
  85. package/dist/core/json.js.map +1 -0
  86. package/dist/core/llm/base.d.ts +9 -0
  87. package/dist/core/llm/base.d.ts.map +1 -0
  88. package/dist/core/llm/base.js +3 -0
  89. package/dist/core/llm/base.js.map +1 -0
  90. package/dist/core/llm/build.d.ts +16 -0
  91. package/dist/core/llm/build.d.ts.map +1 -0
  92. package/dist/core/llm/build.js +34 -0
  93. package/dist/core/llm/build.js.map +1 -0
  94. package/dist/core/llm/claudeCli.d.ts +20 -0
  95. package/dist/core/llm/claudeCli.d.ts.map +1 -0
  96. package/dist/core/llm/claudeCli.js +57 -0
  97. package/dist/core/llm/claudeCli.js.map +1 -0
  98. package/dist/core/llm/codexCli.d.ts +13 -0
  99. package/dist/core/llm/codexCli.d.ts.map +1 -0
  100. package/dist/core/llm/codexCli.js +30 -0
  101. package/dist/core/llm/codexCli.js.map +1 -0
  102. package/dist/core/llm/cursorCli.d.ts +13 -0
  103. package/dist/core/llm/cursorCli.d.ts.map +1 -0
  104. package/dist/core/llm/cursorCli.js +27 -0
  105. package/dist/core/llm/cursorCli.js.map +1 -0
  106. package/dist/core/llm/index.d.ts +5 -0
  107. package/dist/core/llm/index.d.ts.map +1 -0
  108. package/dist/core/llm/index.js +4 -0
  109. package/dist/core/llm/index.js.map +1 -0
  110. package/dist/core/llm/scripted.d.ts +16 -0
  111. package/dist/core/llm/scripted.d.ts.map +1 -0
  112. package/dist/core/llm/scripted.js +29 -0
  113. package/dist/core/llm/scripted.js.map +1 -0
  114. package/dist/core/progress.d.ts +29 -0
  115. package/dist/core/progress.d.ts.map +1 -0
  116. package/dist/core/progress.js +22 -0
  117. package/dist/core/progress.js.map +1 -0
  118. package/dist/core/registry.d.ts +29 -0
  119. package/dist/core/registry.d.ts.map +1 -0
  120. package/dist/core/registry.js +63 -0
  121. package/dist/core/registry.js.map +1 -0
  122. package/dist/core/spawn.d.ts +19 -0
  123. package/dist/core/spawn.d.ts.map +1 -0
  124. package/dist/core/spawn.js +58 -0
  125. package/dist/core/spawn.js.map +1 -0
  126. package/dist/core/state.d.ts +58 -0
  127. package/dist/core/state.d.ts.map +1 -0
  128. package/dist/core/state.js +3 -0
  129. package/dist/core/state.js.map +1 -0
  130. package/dist/core/timeout.d.ts +13 -0
  131. package/dist/core/timeout.d.ts.map +1 -0
  132. package/dist/core/timeout.js +33 -0
  133. package/dist/core/timeout.js.map +1 -0
  134. package/dist/core/types.d.ts +15 -0
  135. package/dist/core/types.d.ts.map +1 -0
  136. package/dist/core/types.js +3 -0
  137. package/dist/core/types.js.map +1 -0
  138. package/dist/core/validate.d.ts +7 -0
  139. package/dist/core/validate.d.ts.map +1 -0
  140. package/dist/core/validate.js +47 -0
  141. package/dist/core/validate.js.map +1 -0
  142. package/dist/graph.d.ts +4 -0
  143. package/dist/graph.d.ts.map +1 -0
  144. package/dist/graph.js +14 -0
  145. package/dist/graph.js.map +1 -0
  146. package/dist/index.d.ts +18 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +16 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/modes/adversarial.d.ts +3 -0
  151. package/dist/modes/adversarial.d.ts.map +1 -0
  152. package/dist/modes/adversarial.js +42 -0
  153. package/dist/modes/adversarial.js.map +1 -0
  154. package/dist/modes/consensus.d.ts +3 -0
  155. package/dist/modes/consensus.d.ts.map +1 -0
  156. package/dist/modes/consensus.js +47 -0
  157. package/dist/modes/consensus.js.map +1 -0
  158. package/dist/modes/debate.d.ts +3 -0
  159. package/dist/modes/debate.d.ts.map +1 -0
  160. package/dist/modes/debate.js +76 -0
  161. package/dist/modes/debate.js.map +1 -0
  162. package/dist/modes/index.d.ts +7 -0
  163. package/dist/modes/index.d.ts.map +1 -0
  164. package/dist/modes/index.js +7 -0
  165. package/dist/modes/index.js.map +1 -0
  166. package/dist/modes/single.d.ts +3 -0
  167. package/dist/modes/single.d.ts.map +1 -0
  168. package/dist/modes/single.js +42 -0
  169. package/dist/modes/single.js.map +1 -0
  170. package/dist/modes/tournament.d.ts +3 -0
  171. package/dist/modes/tournament.d.ts.map +1 -0
  172. package/dist/modes/tournament.js +48 -0
  173. package/dist/modes/tournament.js.map +1 -0
  174. package/dist/nodes/agentRunner.d.ts +15 -0
  175. package/dist/nodes/agentRunner.d.ts.map +1 -0
  176. package/dist/nodes/agentRunner.js +106 -0
  177. package/dist/nodes/agentRunner.js.map +1 -0
  178. package/dist/nodes/auditor.d.ts +38 -0
  179. package/dist/nodes/auditor.d.ts.map +1 -0
  180. package/dist/nodes/auditor.js +179 -0
  181. package/dist/nodes/auditor.js.map +1 -0
  182. package/dist/nodes/bracket.d.ts +19 -0
  183. package/dist/nodes/bracket.d.ts.map +1 -0
  184. package/dist/nodes/bracket.js +90 -0
  185. package/dist/nodes/bracket.js.map +1 -0
  186. package/dist/nodes/consensusEngine.d.ts +18 -0
  187. package/dist/nodes/consensusEngine.d.ts.map +1 -0
  188. package/dist/nodes/consensusEngine.js +94 -0
  189. package/dist/nodes/consensusEngine.js.map +1 -0
  190. package/dist/nodes/moderator.d.ts +20 -0
  191. package/dist/nodes/moderator.d.ts.map +1 -0
  192. package/dist/nodes/moderator.js +83 -0
  193. package/dist/nodes/moderator.js.map +1 -0
  194. package/dist/nodes/planner.d.ts +17 -0
  195. package/dist/nodes/planner.d.ts.map +1 -0
  196. package/dist/nodes/planner.js +40 -0
  197. package/dist/nodes/planner.js.map +1 -0
  198. package/dist/nodes/supervisor.d.ts +28 -0
  199. package/dist/nodes/supervisor.d.ts.map +1 -0
  200. package/dist/nodes/supervisor.js +75 -0
  201. package/dist/nodes/supervisor.js.map +1 -0
  202. package/package.json +66 -0
  203. package/schemas/coterie.config.schema.json +204 -0
@@ -0,0 +1,39 @@
1
+ /** Conversation memory. Agents are stateless subprocess calls, so prior turns
2
+ * are threaded into each new turn's task as context. */
3
+ /** Cap on how much prior conversation rides into each turn's task. Prompts are
4
+ * passed as a subprocess argv element, so an unbounded transcript would inflate
5
+ * every turn's cost and eventually exceed the OS argv limit (ARG_MAX → E2BIG).
6
+ * We keep the most recent turns within this character budget. */
7
+ const MAX_HISTORY_CHARS = 12_000;
8
+ export class Transcript {
9
+ turns = [];
10
+ add(role, content) {
11
+ this.turns.push({ role, content });
12
+ }
13
+ clear() {
14
+ this.turns = [];
15
+ }
16
+ get length() {
17
+ return this.turns.length;
18
+ }
19
+ /** Build the task for a new prompt, prepending the (bounded) conversation. */
20
+ taskFor(prompt) {
21
+ if (this.turns.length === 0)
22
+ return prompt;
23
+ const lines = [];
24
+ let used = 0;
25
+ // Walk newest→oldest, keeping turns until the budget is spent.
26
+ for (let i = this.turns.length - 1; i >= 0; i--) {
27
+ const t = this.turns[i];
28
+ const line = `${t.role === "user" ? "User" : "Assistant"}: ${t.content}`;
29
+ if (used + line.length > MAX_HISTORY_CHARS) {
30
+ lines.unshift("…(earlier conversation trimmed)…");
31
+ break;
32
+ }
33
+ lines.unshift(line);
34
+ used += line.length;
35
+ }
36
+ return `Conversation so far:\n${lines.join("\n\n")}\n\n---\nUser's new request: ${prompt}`;
37
+ }
38
+ }
39
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/chat/transcript.ts"],"names":[],"mappings":"AAAA;yDACyD;AAOzD;;;kEAGkE;AAClE,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,MAAM,OAAO,UAAU;IACb,KAAK,GAAW,EAAE,CAAC;IAE3B,GAAG,CAAC,IAAkB,EAAE,OAAe;QACrC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,8EAA8E;IAC9E,OAAO,CAAC,MAAc;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,+DAA+D;QAC/D,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;YACzB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YACzE,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;gBAC3C,KAAK,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;gBAClD,MAAM;YACR,CAAC;YACD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;QACtB,CAAC;QACD,OAAO,yBAAyB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gCAAgC,MAAM,EAAE,CAAC;IAC7F,CAAC;CACF"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ /** Composition root. Picks LLM provider per role + executor. */
3
+ import "./adapters/index.js";
4
+ import "./modes/index.js";
5
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,gEAAgE;AAsBhE,OAAO,qBAAqB,CAAC;AAC7B,OAAO,kBAAkB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ /** Composition root. Picks LLM provider per role + executor. */
3
+ import { setMaxListeners } from "node:events";
4
+ import { Command } from "commander";
5
+ import kleur from "kleur";
6
+ // A turn aborts via one AbortSignal that LangGraph fans out to per-step derived
7
+ // signals; raise the default ceiling for all newly-created EventTargets so a
8
+ // multi-round turn never trips Node's MaxListenersExceededWarning.
9
+ setMaxListeners(64);
10
+ import { formatProblems, preflight } from "./chat/preflight.js";
11
+ import { renderFailure, runFailed } from "./chat/render.js";
12
+ import { loadConfig } from "./config.js";
13
+ import { progress } from "./core/progress.js";
14
+ import { validateRuntimeConfig } from "./core/validate.js";
15
+ import { IsolatedWorktreeExecutor, LocalSubprocessExecutor } from "./core/executor.js";
16
+ import { buildLLM, coordinationCliFor } from "./core/llm/build.js";
17
+ import { buildGraph } from "./graph.js";
18
+ import "./adapters/index.js"; // trigger adapter registration
19
+ import "./modes/index.js"; // trigger mode registration
20
+ function buildExecutor(cfg) {
21
+ const explicit = cfg.executor?.kind;
22
+ if (explicit === "local")
23
+ return new LocalSubprocessExecutor();
24
+ if (explicit === "isolated")
25
+ return new IsolatedWorktreeExecutor();
26
+ if (explicit != null) {
27
+ console.warn(kleur.yellow(`unknown executor.kind '${explicit}'; using the mode default (local/isolated)`));
28
+ }
29
+ // `run` has no separate finalizer, so adversarial/debate use the local executor
30
+ // on purpose — their edits land in the workdir (that's the point of `run`).
31
+ // The parallel many-agent modes isolate to avoid clobbering each other.
32
+ if (cfg.mode === "consensus" || cfg.mode === "tournament")
33
+ return new IsolatedWorktreeExecutor();
34
+ return new LocalSubprocessExecutor();
35
+ }
36
+ async function main() {
37
+ const program = new Command();
38
+ program
39
+ .name("coterie")
40
+ .description("Chat with a team of AI coding agents that collaborate on each task — in your terminal.")
41
+ .version("0.1.0")
42
+ .showHelpAfterError("(run `coterie --help` to see the available commands)");
43
+ program
44
+ .command("run")
45
+ .description("Run one task through a coordination mode from a config file (for scripting/CI; for interactive use see `chat`).")
46
+ .argument("<task>", "Task to run through the agent graph")
47
+ .requiredOption("--config <path>", "Path to a coterie.yaml config (see examples/ in the repo for templates)")
48
+ .option("--workdir <path>", "Working directory", ".")
49
+ .action(async (task, opts) => {
50
+ const cfg = loadConfig(opts.config);
51
+ validateRuntimeConfig(cfg);
52
+ // Same friendly preflight as chat: surface missing/signed-out agents up
53
+ // front instead of failing with a raw spawn error deep in the graph.
54
+ const problems = preflight(cfg);
55
+ if (problems.length) {
56
+ console.error(kleur.yellow(formatProblems(problems)));
57
+ process.exit(1);
58
+ }
59
+ const mode = cfg.mode;
60
+ const executor = buildExecutor(cfg);
61
+ const coordCli = coordinationCliFor(cfg.agents.map((a) => a.id));
62
+ const llms = {
63
+ supervisor_llm: mode === "single" ? await buildLLM(cfg.router?.model, coordCli) : null,
64
+ judge_llm: ["adversarial", "tournament", "debate"].includes(mode)
65
+ ? await buildLLM(cfg[mode]?.judge?.model, coordCli)
66
+ : null,
67
+ consensus_llm: mode === "consensus" ? await buildLLM(cfg.consensus?.engine?.model, coordCli) : null,
68
+ moderator_llm: mode === "debate" ? await buildLLM(cfg.debate?.moderator?.model, coordCli) : null,
69
+ planner_llm: cfg.planner?.enabled ? await buildLLM(cfg.planner?.model, coordCli) : null,
70
+ };
71
+ const graph = buildGraph({ workdir: opts.workdir, executor, config: cfg, ...llms });
72
+ console.log(kleur.cyan().bold(`— coterie · mode=${mode} · ${cfg.agents.length} agents —`));
73
+ // Stream live progress so a long run isn't a silent wait.
74
+ const onDone = ({ run }) => {
75
+ const tag = runFailed(run) ? kleur.yellow(`⚠ ${renderFailure(run)}`) : kleur.dim("done");
76
+ console.log(kleur.dim(` · ${run.role} (${run.agent_id}) `) + tag);
77
+ };
78
+ progress.on("done", onDone);
79
+ const initial = {
80
+ task, mode, plan: [], current_step_idx: 0, runs: [], artifacts: {},
81
+ status: "planning", config: cfg, spend_usd: 0, route_history: [],
82
+ judge_history: [], next_agent: null, mode_state: {},
83
+ };
84
+ const final = await graph.invoke(initial, { recursionLimit: 24 }).finally(() => progress.off("done", onDone));
85
+ if (final.runs?.length)
86
+ console.log(final.runs[final.runs.length - 1].stdout);
87
+ for (const r of final.runs ?? []) {
88
+ if (runFailed(r))
89
+ console.error(kleur.yellow(`⚠ ${r.role} (${r.agent_id}) ${renderFailure(r)}`));
90
+ }
91
+ console.log(kleur.dim(`total spend ≈ $${(final.spend_usd ?? 0).toFixed(4)}`));
92
+ console.log(kleur.bold(`— ${final.status} —`));
93
+ process.exit(final.status === "done" ? 0 : 1);
94
+ });
95
+ program
96
+ .command("chat")
97
+ .description("Conversational REPL: each turn runs through a coordination mode behind the scenes.")
98
+ .option("--mode <mode>", "Coordination mode (single|adversarial|debate|tournament|consensus)", "adversarial")
99
+ .option("--workdir <path>", "Directory the agents read/edit", ".")
100
+ .option("--quiet", "Start with the live agent exchanges hidden (show only the final reply)", false)
101
+ .action(async (opts) => {
102
+ const { runChat } = await import("./chat/repl.js");
103
+ const valid = ["single", "adversarial", "debate", "tournament", "consensus"];
104
+ if (!valid.includes(opts.mode)) {
105
+ console.error(`unknown mode '${opts.mode}'; pick one of ${valid.join(", ")}`);
106
+ process.exit(2);
107
+ }
108
+ await runChat({ mode: opts.mode, workdir: opts.workdir, quiet: opts.quiet });
109
+ });
110
+ program
111
+ .command("doctor")
112
+ .description("Check which agent CLIs are installed and signed in (Coterie needs at least two).")
113
+ .action(async () => {
114
+ const { runDoctor, formatDoctor } = await import("./chat/doctor.js");
115
+ const result = runDoctor();
116
+ console.log(formatDoctor(result));
117
+ process.exit(result.ok ? 0 : 1);
118
+ });
119
+ // No subcommand: show help and exit cleanly (0). Printing help is a success,
120
+ // not an error — bare `coterie` shouldn't look like something went wrong.
121
+ if (process.argv.slice(2).length === 0) {
122
+ program.outputHelp();
123
+ return;
124
+ }
125
+ await program.parseAsync(process.argv);
126
+ }
127
+ main().catch((e) => {
128
+ // Friendly one-line errors for a CLI; full stack only when DEBUG is set.
129
+ console.error(kleur.red(e instanceof Error ? e.message : String(e)));
130
+ if (process.env.DEBUG && e instanceof Error)
131
+ console.error(e.stack);
132
+ process.exit(1);
133
+ });
134
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function loadConfig(path: string): Record<string, any>;
2
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAYA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuC5D"}
package/dist/config.js ADDED
@@ -0,0 +1,52 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import Ajv2020 from "ajv/dist/2020.js";
5
+ import { parse as parseYaml } from "yaml";
6
+ const here = dirname(fileURLToPath(import.meta.url));
7
+ // Schema ships inside the package (../schemas relative to both src/ and dist/),
8
+ // so config validation works for npm installs, not just the source checkout.
9
+ const SCHEMA_PATH = resolve(here, "..", "schemas", "coterie.config.schema.json");
10
+ export function loadConfig(path) {
11
+ let text;
12
+ try {
13
+ text = readFileSync(path, "utf8");
14
+ }
15
+ catch (e) {
16
+ if (e?.code === "ENOENT")
17
+ throw new Error(`Config file not found: ${path}`);
18
+ throw e;
19
+ }
20
+ let raw;
21
+ try {
22
+ raw = parseYaml(text);
23
+ }
24
+ catch (e) {
25
+ throw new Error(`Invalid YAML in ${path}: ${e?.message ?? String(e)}`);
26
+ }
27
+ if (raw === null || raw === undefined) {
28
+ throw new Error(`Config file is empty: ${path}`);
29
+ }
30
+ if (typeof raw !== "object" || Array.isArray(raw)) {
31
+ throw new Error(`Invalid config: ${path} must contain a YAML mapping (key: value) at the top level`);
32
+ }
33
+ // Validate against the bundled schema. Only a *missing* schema file is skipped
34
+ // (a partial/broken install); a schema that loads MUST run, so genuine config
35
+ // errors always surface rather than being silently swallowed.
36
+ let schemaText = null;
37
+ try {
38
+ schemaText = readFileSync(SCHEMA_PATH, "utf8");
39
+ }
40
+ catch {
41
+ schemaText = null;
42
+ }
43
+ if (schemaText) {
44
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
45
+ const validate = ajv.compile(JSON.parse(schemaText));
46
+ if (!validate(raw)) {
47
+ throw new Error(`Invalid config: ${ajv.errorsText(validate.errors)}`);
48
+ }
49
+ }
50
+ return raw;
51
+ }
52
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,gFAAgF;AAChF,6EAA6E;AAC7E,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAC;AAEjF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,CAAC;IACV,CAAC;IAED,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,KAAK,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,4DAA4D,CAAC,CAAC;IACvG,CAAC;IAED,+EAA+E;IAC/E,8EAA8E;IAC9E,8DAA8D;IAC9D,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,CAAC;QACH,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,OAAO,GAA0B,CAAC;AACpC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * LangGraph state annotation. The reducer-bearing channels here mirror the
3
+ * `Annotated[..., add]` Python TypedDict fields.
4
+ */
5
+ import type { AgentRun, JudgeDecision, Mode, RouteDecision, Status } from "./state.js";
6
+ export declare const CoterieStateAnnotation: import("@langchain/langgraph").AnnotationRoot<{
7
+ task: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
8
+ mode: import("@langchain/langgraph").BinaryOperatorAggregate<Mode, Mode>;
9
+ plan: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
10
+ current_step_idx: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
11
+ runs: import("@langchain/langgraph").BinaryOperatorAggregate<AgentRun[], AgentRun[]>;
12
+ artifacts: import("@langchain/langgraph").BinaryOperatorAggregate<Record<string, string>, Record<string, string>>;
13
+ status: import("@langchain/langgraph").BinaryOperatorAggregate<Status, Status>;
14
+ config: import("@langchain/langgraph").BinaryOperatorAggregate<Record<string, any>, Record<string, any>>;
15
+ spend_usd: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
16
+ route_history: import("@langchain/langgraph").BinaryOperatorAggregate<RouteDecision[], RouteDecision[]>;
17
+ judge_history: import("@langchain/langgraph").BinaryOperatorAggregate<JudgeDecision[], JudgeDecision[]>;
18
+ next_agent: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
19
+ mode_state: import("@langchain/langgraph").BinaryOperatorAggregate<Record<string, any>, Record<string, any>>;
20
+ }>;
21
+ export type CoterieStateValues = typeof CoterieStateAnnotation.State;
22
+ //# sourceMappingURL=annotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation.d.ts","sourceRoot":"","sources":["../../src/core/annotation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EACV,QAAQ,EAER,aAAa,EACb,IAAI,EACJ,aAAa,EACb,MAAM,EACP,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;EAsCjC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,OAAO,sBAAsB,CAAC,KAAK,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * LangGraph state annotation. The reducer-bearing channels here mirror the
3
+ * `Annotated[..., add]` Python TypedDict fields.
4
+ */
5
+ import { Annotation } from "@langchain/langgraph";
6
+ export const CoterieStateAnnotation = Annotation.Root({
7
+ task: Annotation({ default: () => "", reducer: (_a, b) => b }),
8
+ mode: Annotation({ default: () => "single", reducer: (_a, b) => b }),
9
+ plan: Annotation({ default: () => [], reducer: (_a, b) => b }),
10
+ current_step_idx: Annotation({ default: () => 0, reducer: (_a, b) => b }),
11
+ runs: Annotation({
12
+ default: () => [],
13
+ reducer: (a, b) => [...a, ...b],
14
+ }),
15
+ artifacts: Annotation({
16
+ default: () => ({}),
17
+ reducer: (_a, b) => b,
18
+ }),
19
+ status: Annotation({ default: () => "planning", reducer: (_a, b) => b }),
20
+ config: Annotation({
21
+ default: () => ({}),
22
+ reducer: (_a, b) => b,
23
+ }),
24
+ spend_usd: Annotation({
25
+ default: () => 0,
26
+ reducer: (a, b) => a + b,
27
+ }),
28
+ route_history: Annotation({
29
+ default: () => [],
30
+ reducer: (a, b) => [...a, ...b],
31
+ }),
32
+ judge_history: Annotation({
33
+ default: () => [],
34
+ reducer: (a, b) => [...a, ...b],
35
+ }),
36
+ next_agent: Annotation({
37
+ default: () => null,
38
+ reducer: (_a, b) => b,
39
+ }),
40
+ mode_state: Annotation({
41
+ default: () => ({}),
42
+ reducer: (_a, b) => b,
43
+ }),
44
+ });
45
+ //# sourceMappingURL=annotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation.js","sourceRoot":"","sources":["../../src/core/annotation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAWlD,MAAM,CAAC,MAAM,sBAAsB,GAAG,UAAU,CAAC,IAAI,CAAC;IACpD,IAAI,EAAE,UAAU,CAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IACtE,IAAI,EAAE,UAAU,CAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IAC1E,IAAI,EAAE,UAAU,CAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IACxE,gBAAgB,EAAE,UAAU,CAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IACjF,IAAI,EAAE,UAAU,CAAa;QAC3B,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,SAAS,EAAE,UAAU,CAAyB;QAC5C,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;KACtB,CAAC;IACF,MAAM,EAAE,UAAU,CAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,EAAE,UAAU,CAAsB;QACtC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;KACtB,CAAC;IACF,SAAS,EAAE,UAAU,CAAS;QAC5B,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC;KACzB,CAAC;IACF,aAAa,EAAE,UAAU,CAAkB;QACzC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,aAAa,EAAE,UAAU,CAAkB;QACzC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,UAAU,EAAE,UAAU,CAAgB;QACpC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI;QACnB,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;KACtB,CAAC;IACF,UAAU,EAAE,UAAU,CAAsB;QAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;KACtB,CAAC;CACH,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Shared graph compilation. */
2
+ export declare function compileGraph(builder: any, _config: Record<string, any>): any;
3
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/core/compile.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAMhC,wBAAgB,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAE5E"}
@@ -0,0 +1,9 @@
1
+ /** Shared graph compilation. */
2
+ // NOTE: the prior checkpointer + interruptBefore path (audit #23) was removed —
3
+ // it required a `configurable.thread_id` at stream/invoke time (never passed) and
4
+ // there was no resume path, so the interrupt/`awaiting_human` flow was unusable.
5
+ // Budget halts now surface as a terminal status instead (the finalizer is skipped).
6
+ export function compileGraph(builder, _config) {
7
+ return builder.compile();
8
+ }
9
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/core/compile.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,gFAAgF;AAChF,kFAAkF;AAClF,iFAAiF;AACjF,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,OAAY,EAAE,OAA4B;IACrE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * AdapterExecutor seam. Mirrors Python `core/executor.py`.
3
+ *
4
+ * Two concretes:
5
+ * - `LocalSubprocessExecutor` — delegates to `adapter.run()`. Default.
6
+ * - `IsolatedWorktreeExecutor` — each call runs in an ephemeral git worktree.
7
+ */
8
+ import type { AdapterResult, CLIAdapter } from "../adapters/base.js";
9
+ export interface ExecuteOpts {
10
+ timeoutMs?: number;
11
+ signal?: AbortSignal;
12
+ /** Called with a short progress note for each streamed event from the agent. */
13
+ onStream?: (text: string) => void;
14
+ }
15
+ /** Whether `workdir` is a git repo with ≥1 commit — the precondition for isolated
16
+ * worktree deliberation. Lets callers warn upfront instead of failing mid-turn. */
17
+ export declare function gitRepoReady(workdir: string): {
18
+ ok: boolean;
19
+ reason?: string;
20
+ };
21
+ export interface AdapterExecutor {
22
+ execute(adapter: CLIAdapter, prompt: string, workdir: string, opts?: ExecuteOpts): Promise<AdapterResult>;
23
+ }
24
+ export declare class LocalSubprocessExecutor implements AdapterExecutor {
25
+ execute(adapter: CLIAdapter, prompt: string, workdir: string, opts?: ExecuteOpts): Promise<AdapterResult>;
26
+ }
27
+ export declare class IsolatedWorktreeExecutor implements AdapterExecutor {
28
+ execute(adapter: CLIAdapter, prompt: string, workdir: string, opts?: ExecuteOpts): Promise<AdapterResult>;
29
+ private makeIsolated;
30
+ private cleanup;
31
+ }
32
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;oFACoF;AACpF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAM9E;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CACL,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3B;AAED,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CACL,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,aAAa,CAAC;CAG1B;AAED,qBAAa,wBAAyB,YAAW,eAAe;IACxD,OAAO,CACX,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,aAAa,CAAC;IASzB,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,OAAO;CAgBhB"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * AdapterExecutor seam. Mirrors Python `core/executor.py`.
3
+ *
4
+ * Two concretes:
5
+ * - `LocalSubprocessExecutor` — delegates to `adapter.run()`. Default.
6
+ * - `IsolatedWorktreeExecutor` — each call runs in an ephemeral git worktree.
7
+ */
8
+ import { spawnSync } from "node:child_process";
9
+ import { existsSync, mkdtempSync, rmSync } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ /** Whether `workdir` is a git repo with ≥1 commit — the precondition for isolated
13
+ * worktree deliberation. Lets callers warn upfront instead of failing mid-turn. */
14
+ export function gitRepoReady(workdir) {
15
+ const inside = spawnSync("git", ["rev-parse", "--is-inside-work-tree"], { cwd: workdir, encoding: "utf8" });
16
+ if (inside.status !== 0)
17
+ return { ok: false, reason: "not a git repository" };
18
+ const head = spawnSync("git", ["rev-parse", "HEAD"], { cwd: workdir, encoding: "utf8" });
19
+ if (head.status !== 0)
20
+ return { ok: false, reason: "the git repository has no commits yet" };
21
+ return { ok: true };
22
+ }
23
+ export class LocalSubprocessExecutor {
24
+ execute(adapter, prompt, workdir, opts = {}) {
25
+ return adapter.run(prompt, workdir, opts);
26
+ }
27
+ }
28
+ export class IsolatedWorktreeExecutor {
29
+ async execute(adapter, prompt, workdir, opts = {}) {
30
+ const isolated = this.makeIsolated(workdir);
31
+ try {
32
+ return await adapter.run(prompt, isolated, opts);
33
+ }
34
+ finally {
35
+ this.cleanup(isolated, workdir);
36
+ }
37
+ }
38
+ makeIsolated(base) {
39
+ const d = mkdtempSync(join(tmpdir(), "coterie-wt-"));
40
+ if (!existsSync(join(base, ".git"))) {
41
+ rmSync(d, { recursive: true, force: true });
42
+ throw new Error(`coterie runs deliberation in an isolated git worktree, but ${base} is not a git repository. ` +
43
+ "Run `git init && git add -A && git commit -m init` there first.");
44
+ }
45
+ const proc = spawnSync("git", ["worktree", "add", "--detach", d], { cwd: base, encoding: "utf8" });
46
+ if (proc.status !== 0) {
47
+ // Never silently run the agent against an empty temp dir with none of the
48
+ // user's code — fail loudly instead.
49
+ rmSync(d, { recursive: true, force: true });
50
+ throw new Error(`could not create an isolated worktree in ${base}: ${(proc.stderr || "").trim().slice(0, 200)} ` +
51
+ "(a git repo needs at least one commit).");
52
+ }
53
+ return d;
54
+ }
55
+ cleanup(isolated, base) {
56
+ const removed = spawnSync("git", ["worktree", "remove", "--force", isolated], {
57
+ cwd: base,
58
+ encoding: "utf8",
59
+ });
60
+ try {
61
+ rmSync(isolated, { recursive: true, force: true });
62
+ }
63
+ catch {
64
+ // best-effort
65
+ }
66
+ // If `git worktree remove` failed, the .git/worktrees entry would linger and
67
+ // accumulate over a session — prune the now-deleted dir's stale registration.
68
+ if (removed.status !== 0) {
69
+ spawnSync("git", ["worktree", "prune"], { cwd: base, encoding: "utf8" });
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Parse JSON that an LLM may have wrapped in a ```json fence or padded with
2
+ * prose ("Here's the result: [...]"). Coordination nodes call this instead of a
3
+ * bare JSON.parse so a well-formed answer in a fence/prose wrapper isn't
4
+ * misread as a parse failure. Returns undefined when no JSON value is found. */
5
+ export declare function parseJsonLoose(raw: string): any;
6
+ /** Parse NDJSON (one JSON value per line) — the streaming format the agent CLIs
7
+ * emit. Blank or unparseable lines are skipped. */
8
+ export declare function parseNdjson(text: string): any[];
9
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/core/json.ts"],"names":[],"mappings":"AAAA;;;iFAGiF;AACjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAsB/C;AAED;oDACoD;AACpD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,EAAE,CAY/C"}
@@ -0,0 +1,49 @@
1
+ /** Parse JSON that an LLM may have wrapped in a ```json fence or padded with
2
+ * prose ("Here's the result: [...]"). Coordination nodes call this instead of a
3
+ * bare JSON.parse so a well-formed answer in a fence/prose wrapper isn't
4
+ * misread as a parse failure. Returns undefined when no JSON value is found. */
5
+ export function parseJsonLoose(raw) {
6
+ if (!raw)
7
+ return undefined;
8
+ let s = raw.trim();
9
+ const fence = s.match(/^```[a-zA-Z]*\n([\s\S]*?)\n?```$/);
10
+ if (fence?.[1] !== undefined)
11
+ s = fence[1].trim();
12
+ try {
13
+ return JSON.parse(s);
14
+ }
15
+ catch {
16
+ // Fall back to extracting the first balanced-looking object/array span.
17
+ }
18
+ const start = s.search(/[[{]/);
19
+ if (start === -1)
20
+ return undefined;
21
+ const close = s[start] === "{" ? "}" : "]";
22
+ const end = s.lastIndexOf(close);
23
+ if (end <= start)
24
+ return undefined;
25
+ try {
26
+ return JSON.parse(s.slice(start, end + 1));
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ }
32
+ /** Parse NDJSON (one JSON value per line) — the streaming format the agent CLIs
33
+ * emit. Blank or unparseable lines are skipped. */
34
+ export function parseNdjson(text) {
35
+ const out = [];
36
+ for (const line of text.split("\n")) {
37
+ const t = line.trim();
38
+ if (!t)
39
+ continue;
40
+ try {
41
+ out.push(JSON.parse(t));
42
+ }
43
+ catch {
44
+ // ignore non-JSON noise on a line
45
+ }
46
+ }
47
+ return out;
48
+ }
49
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/core/json.ts"],"names":[],"mappings":"AAAA;;;iFAGiF;AACjF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAEnB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC1D,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAElD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;IAC1E,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3C,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;oDACoD;AACpD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** LLMClient contract. One method (`chat`). */
2
+ export interface LLMMessage {
3
+ role: "user" | "assistant" | "system";
4
+ content: string;
5
+ }
6
+ export interface LLMClient {
7
+ chat(system: string, messages: LLMMessage[]): Promise<string>;
8
+ }
9
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/core/llm/base.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D"}
@@ -0,0 +1,3 @@
1
+ /** LLMClient contract. One method (`chat`). */
2
+ export {};
3
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/core/llm/base.ts"],"names":[],"mappings":"AAAA,+CAA+C"}
@@ -0,0 +1,16 @@
1
+ /** Coordination LLM construction — subscription-only, with fallback.
2
+ *
3
+ * Coordination (judge / router / consensus engine / moderator) runs on a coding
4
+ * agent's CLI so it stays $0-metered (no pay-as-you-go API). Claude is preferred
5
+ * (it supports tool-disabling + reports cost), but coterie must work without
6
+ * Claude on the machine — so it falls back to codex, then cursor. There is
7
+ * intentionally no metered API backend.
8
+ */
9
+ import type { LLMClient } from "./base.js";
10
+ export type CoordinationCli = "claude" | "codex" | "cursor-agent";
11
+ /** Choose the coordination CLI from the agents available this session, preferring
12
+ * claude-code → codex → cursor. `agentIds` are config agent ids (claude-code,
13
+ * codex, cursor). */
14
+ export declare function coordinationCliFor(agentIds: string[]): CoordinationCli;
15
+ export declare function buildLLM(model?: string, cli?: CoordinationCli): Promise<LLMClient>;
16
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/core/llm/build.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAK3C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,CAAC;AAElE;;sBAEsB;AACtB,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CAKtE;AAED,wBAAsB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,eAA0B,GAAG,OAAO,CAAC,SAAS,CAAC,CASlG"}