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,41 @@
1
+ /** In-process FakeAdapter for tests / offline demos. */
2
+ import { CLIAdapter } from "./base.js";
3
+ import { registerAdapter } from "../core/registry.js";
4
+ export class FakeAdapterError extends Error {
5
+ }
6
+ export class FakeAdapter extends CLIAdapter {
7
+ static adapterName = "fake";
8
+ static scripts = new Map();
9
+ static invocationsByAgent = new Map();
10
+ static script(agent_id, results) {
11
+ FakeAdapter.scripts.set(agent_id, [...results]);
12
+ if (!FakeAdapter.invocationsByAgent.has(agent_id)) {
13
+ FakeAdapter.invocationsByAgent.set(agent_id, []);
14
+ }
15
+ }
16
+ static invocationsFor(agent_id) {
17
+ return FakeAdapter.invocationsByAgent.get(agent_id) ?? [];
18
+ }
19
+ static resetAll() {
20
+ FakeAdapter.scripts.clear();
21
+ FakeAdapter.invocationsByAgent.clear();
22
+ }
23
+ buildCommand() {
24
+ return ["true"];
25
+ }
26
+ parseResult(stdout, stderr, exit_code) {
27
+ return { stdout, stderr, exit_code, files_changed: [], duration_s: 0, cost_estimate_usd: null };
28
+ }
29
+ async run(prompt, workdir) {
30
+ const invocations = FakeAdapter.invocationsByAgent.get(this.agent_id) ?? [];
31
+ invocations.push({ prompt, workdir });
32
+ FakeAdapter.invocationsByAgent.set(this.agent_id, invocations);
33
+ const queue = FakeAdapter.scripts.get(this.agent_id);
34
+ if (!queue || queue.length === 0) {
35
+ throw new FakeAdapterError(`FakeAdapter(${this.agent_id}) has no scripted results; prior invocations: ${invocations.length}`);
36
+ }
37
+ return queue.shift();
38
+ }
39
+ }
40
+ registerAdapter(FakeAdapter);
41
+ //# sourceMappingURL=fake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake.js","sourceRoot":"","sources":["../../src/adapters/fake.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,OAAO,EAAE,UAAU,EAAsB,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,OAAO,gBAAiB,SAAQ,KAAK;CAAG;AAE9C,MAAM,OAAO,WAAY,SAAQ,UAAU;IACzC,MAAM,CAAU,WAAW,GAAG,MAAM,CAAC;IAE7B,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IACpD,MAAM,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAsD,CAAC;IAElG,MAAM,CAAC,MAAM,CAAC,QAAgB,EAAE,OAAwB;QACtD,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,QAAgB;QACpC,OAAO,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,CAAC,QAAQ;QACb,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5B,WAAW,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,YAAY;QACV,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,WAAW,CAAC,MAAc,EAAE,MAAc,EAAE,SAAiB;QAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAClG,CAAC;IAEQ,KAAK,CAAC,GAAG,CAAC,MAAc,EAAE,OAAe;QAChD,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC5E,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/D,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,gBAAgB,CACxB,eAAe,IAAI,CAAC,QAAQ,iDAAiD,WAAW,CAAC,MAAM,EAAE,CAClG,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,EAAG,CAAC;IACxB,CAAC;;AAGH,eAAe,CAAC,WAAW,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Importing this module triggers all built-in adapter registrations. */
2
+ import "./claudeCode.js";
3
+ import "./codex.js";
4
+ import "./cursor.js";
5
+ import "./fake.js";
6
+ export { CLIAdapter, type AdapterResult, type CLIAdapterCtor } from "./base.js";
7
+ export { ClaudeCodeAdapter } from "./claudeCode.js";
8
+ export { CodexAdapter } from "./codex.js";
9
+ export { CursorAdapter } from "./cursor.js";
10
+ export { FakeAdapter, FakeAdapterError } from "./fake.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,iBAAiB,CAAC;AACzB,OAAO,YAAY,CAAC;AACpB,OAAO,aAAa,CAAC;AACrB,OAAO,WAAW,CAAC;AAEnB,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Importing this module triggers all built-in adapter registrations. */
2
+ import "./claudeCode.js";
3
+ import "./codex.js";
4
+ import "./cursor.js";
5
+ import "./fake.js";
6
+ export { CLIAdapter } from "./base.js";
7
+ export { ClaudeCodeAdapter } from "./claudeCode.js";
8
+ export { CodexAdapter } from "./codex.js";
9
+ export { CursorAdapter } from "./cursor.js";
10
+ export { FakeAdapter, FakeAdapterError } from "./fake.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,iBAAiB,CAAC;AACzB,OAAO,YAAY,CAAC;AACpB,OAAO,aAAa,CAAC;AACrB,OAAO,WAAW,CAAC;AAEnB,OAAO,EAAE,UAAU,EAA2C,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Shared helpers for turning an agent's streamed tool-call event into a short,
2
+ * human-readable progress note. */
3
+ /** A compact hint for a tool call — the file, command, pattern, or query it
4
+ * targets — so a live line reads "→ Read src/foo.ts" rather than just "→ Read". */
5
+ export declare function toolHint(input: unknown): string;
6
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/adapters/stream.ts"],"names":[],"mappings":"AAAA;oCACoC;AAEpC;oFACoF;AACpF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAW/C"}
@@ -0,0 +1,20 @@
1
+ /** Shared helpers for turning an agent's streamed tool-call event into a short,
2
+ * human-readable progress note. */
3
+ /** A compact hint for a tool call — the file, command, pattern, or query it
4
+ * targets — so a live line reads "→ Read src/foo.ts" rather than just "→ Read". */
5
+ export function toolHint(input) {
6
+ if (!input || typeof input !== "object")
7
+ return "";
8
+ const o = input;
9
+ // For a file path, show just the basename — agents run in an isolated worktree,
10
+ // so the absolute temp-dir prefix is noise.
11
+ const path = o.file_path ?? o.path;
12
+ if (typeof path === "string" && path)
13
+ return ` ${path.split("/").pop()}`;
14
+ const other = o.command ?? o.pattern ?? o.query ?? o.url ?? o.prompt;
15
+ if (other == null)
16
+ return "";
17
+ const s = Array.isArray(other) ? other.join(" ") : String(other);
18
+ return s ? ` ${s.replace(/\s+/g, " ").slice(0, 80)}` : "";
19
+ }
20
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/adapters/stream.ts"],"names":[],"mappings":"AAAA;oCACoC;AAEpC;oFACoF;AACpF,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,gFAAgF;IAChF,4CAA4C;IAC5C,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;IACnC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;IACzE,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IACrE,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** Default in-memory configs per mode for `coterie chat`. The agent lineup is
2
+ * built from whichever agent CLIs are actually available (see
3
+ * `availableAgents()`); roles within each strategy are assigned automatically
4
+ * from that lineup in preference order. (Manual per-strategy role assignment is
5
+ * on the roadmap — see the README.) */
6
+ import type { Mode } from "../core/state.js";
7
+ export interface AgentCfg {
8
+ id: string;
9
+ adapter: string;
10
+ }
11
+ /** Every agent Coterie can coordinate, in preference order. Roles that need a
12
+ * specific seat (implementer/auditor, debate sides) and the finalizer take the
13
+ * earliest available agents in this order. */
14
+ export declare const KNOWN_AGENTS: AgentCfg[];
15
+ export declare function defaultConfig(mode: Mode, agents?: AgentCfg[]): Record<string, any>;
16
+ /** Map an adapter name to the CLI binary the preflight must verify. */
17
+ export declare const ADAPTER_CLI: Record<string, string>;
18
+ //# sourceMappingURL=configs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../src/chat/configs.ts"],"names":[],"mappings":"AAAA;;;;wCAIwC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;+CAE+C;AAC/C,eAAO,MAAM,YAAY,EAAE,QAAQ,EAIlC,CAAC;AAMF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,QAAQ,EAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAgD/F;AAED,uEAAuE;AACvE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI9C,CAAC"}
@@ -0,0 +1,71 @@
1
+ /** Default in-memory configs per mode for `coterie chat`. The agent lineup is
2
+ * built from whichever agent CLIs are actually available (see
3
+ * `availableAgents()`); roles within each strategy are assigned automatically
4
+ * from that lineup in preference order. (Manual per-strategy role assignment is
5
+ * on the roadmap — see the README.) */
6
+ /** Every agent Coterie can coordinate, in preference order. Roles that need a
7
+ * specific seat (implementer/auditor, debate sides) and the finalizer take the
8
+ * earliest available agents in this order. */
9
+ export const KNOWN_AGENTS = [
10
+ { id: "claude-code", adapter: "claude-code" },
11
+ { id: "codex", adapter: "codex" },
12
+ { id: "cursor", adapter: "cursor" },
13
+ ];
14
+ /** Baseline lineup when a caller doesn't pass one (keeps non-interactive
15
+ * defaults and unit tests stable). The chat REPL passes the live lineup. */
16
+ const BASE_AGENTS = KNOWN_AGENTS.slice(0, 2);
17
+ export function defaultConfig(mode, agents = BASE_AGENTS) {
18
+ const ids = agents.map((a) => a.id);
19
+ const pair = agents.slice(0, 2);
20
+ switch (mode) {
21
+ case "single":
22
+ return { version: 1, mode, agents, router: { enabled: true, model: "claude-haiku-4-5" } };
23
+ case "adversarial":
24
+ return {
25
+ version: 1,
26
+ mode,
27
+ agents: pair,
28
+ adversarial: {
29
+ implementer: ids[0],
30
+ auditor: ids[1],
31
+ judge: { model: "claude-opus-4-7", sustain_threshold: "medium" },
32
+ max_rounds: 2,
33
+ },
34
+ };
35
+ case "consensus":
36
+ return {
37
+ version: 1,
38
+ mode,
39
+ agents,
40
+ // Consensus is structurally single-pass (each agent reviews once → engine
41
+ // merges); max_rounds is recorded explicitly so the cap is visible.
42
+ consensus: { participants: ids, engine: { model: "claude-haiku-4-5" }, threshold: 0.66, max_rounds: 1 },
43
+ };
44
+ case "debate":
45
+ return {
46
+ version: 1,
47
+ mode,
48
+ agents: pair,
49
+ debate: {
50
+ sides: [ids[0], ids[1]],
51
+ rounds: 2,
52
+ moderator: { model: "claude-haiku-4-5" },
53
+ judge: { model: "claude-opus-4-7" },
54
+ },
55
+ };
56
+ case "tournament":
57
+ return {
58
+ version: 1,
59
+ mode,
60
+ agents,
61
+ tournament: { participants: ids, judge: { model: "claude-opus-4-7" }, rounds: 1 },
62
+ };
63
+ }
64
+ }
65
+ /** Map an adapter name to the CLI binary the preflight must verify. */
66
+ export const ADAPTER_CLI = {
67
+ "claude-code": "claude",
68
+ codex: "codex",
69
+ cursor: "cursor-agent",
70
+ };
71
+ //# sourceMappingURL=configs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configs.js","sourceRoot":"","sources":["../../src/chat/configs.ts"],"names":[],"mappings":"AAAA;;;;wCAIwC;AASxC;;+CAE+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAe;IACtC,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE;IAC7C,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;IACjC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE;CACpC,CAAC;AAEF;6EAC6E;AAC7E,MAAM,WAAW,GAAe,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEzD,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,SAAqB,WAAW;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEhC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC;QAC5F,KAAK,aAAa;YAChB,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,IAAI;gBACJ,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE;oBACX,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;oBACnB,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBACf,KAAK,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE;oBAChE,UAAU,EAAE,CAAC;iBACd;aACF,CAAC;QACJ,KAAK,WAAW;YACd,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,IAAI;gBACJ,MAAM;gBACN,0EAA0E;gBAC1E,oEAAoE;gBACpE,SAAS,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE;aACxG,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,IAAI;gBACJ,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE;oBACN,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;oBACvB,MAAM,EAAE,CAAC;oBACT,SAAS,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE;oBACxC,KAAK,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE;iBACpC;aACF,CAAC;QACJ,KAAK,YAAY;YACf,OAAO;gBACL,OAAO,EAAE,CAAC;gBACV,IAAI;gBACJ,MAAM;gBACN,UAAU,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;aAClF,CAAC;IACN,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,cAAc;CACvB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** `coterie doctor`: report which agent CLIs are installed and signed in, and
2
+ * whether there are enough to run. Coterie coordinates multiple agents, so it
3
+ * needs at least two — but any two will do, and it happily uses more. The set of
4
+ * agents it knows about (ALL_AGENT_CLIS) is registry-derived, so this grows as
5
+ * new adapters are added. No agents are invoked here — it's a pure status check. */
6
+ import { type AgentStatus } from "./preflight.js";
7
+ /** Fewest agents needed to coordinate a round (you can't deliberate with one). */
8
+ export declare const MIN_AGENTS = 2;
9
+ export interface DoctorResult {
10
+ statuses: AgentStatus[];
11
+ ready: number;
12
+ ok: boolean;
13
+ }
14
+ export declare function runDoctor(clis?: string[]): DoctorResult;
15
+ export declare function formatDoctor(r: DoctorResult): string;
16
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/chat/doctor.ts"],"names":[],"mappings":"AAAA;;;;qFAIqF;AAErF,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE9E,kFAAkF;AAClF,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;CACb;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAmB,GAAG,YAAY,CAIvE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAgCpD"}
@@ -0,0 +1,43 @@
1
+ /** `coterie doctor`: report which agent CLIs are installed and signed in, and
2
+ * whether there are enough to run. Coterie coordinates multiple agents, so it
3
+ * needs at least two — but any two will do, and it happily uses more. The set of
4
+ * agents it knows about (ALL_AGENT_CLIS) is registry-derived, so this grows as
5
+ * new adapters are added. No agents are invoked here — it's a pure status check. */
6
+ import { ALL_AGENT_CLIS, checkAgent } from "./preflight.js";
7
+ /** Fewest agents needed to coordinate a round (you can't deliberate with one). */
8
+ export const MIN_AGENTS = 2;
9
+ export function runDoctor(clis = ALL_AGENT_CLIS) {
10
+ const statuses = clis.map(checkAgent);
11
+ const ready = statuses.filter((s) => s.ok).length;
12
+ return { statuses, ready, ok: ready >= MIN_AGENTS };
13
+ }
14
+ export function formatDoctor(r) {
15
+ const total = r.statuses.length;
16
+ const lines = [
17
+ `Coterie coordinates multiple agents, so it needs at least ${MIN_AGENTS} of these ` +
18
+ `installed and signed in (any combination — and it'll use more if you have them):`,
19
+ "",
20
+ ];
21
+ const width = Math.max(...r.statuses.map((s) => s.cli.length));
22
+ for (const s of r.statuses) {
23
+ lines.push(` ${s.ok ? "✓" : "✗"} ${s.cli.padEnd(width)} — ${s.reason}`);
24
+ if (s.fix)
25
+ lines.push(` ${s.fix}`);
26
+ }
27
+ lines.push("");
28
+ lines.push(r.ok
29
+ ? `${r.ready} of ${total} ready — good to go.`
30
+ : `${r.ready} of ${total} ready — Coterie needs at least ${MIN_AGENTS}. ` +
31
+ `Install or sign in to one more above.`);
32
+ // The "not signed in" check is a heuristic (it reads each tool's saved
33
+ // credentials), so it can occasionally be wrong. Only explain that when it's
34
+ // relevant — i.e. when something actually shows as not signed in. When agents
35
+ // are simply not installed, or all are ready, the note is just noise.
36
+ if (r.statuses.some((s) => s.reason === "not signed in")) {
37
+ lines.push("", "Note: sign-in is detected by checking each tool's saved credentials. If a tool " +
38
+ "already works in your terminal but shows as not signed in above, you can ignore " +
39
+ "that — Coterie runs each tool exactly as your shell does.");
40
+ }
41
+ return lines.join("\n");
42
+ }
43
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/chat/doctor.ts"],"names":[],"mappings":"AAAA;;;;qFAIqF;AAErF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAoB,MAAM,gBAAgB,CAAC;AAE9E,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAQ5B,MAAM,UAAU,SAAS,CAAC,OAAiB,cAAc;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,IAAI,UAAU,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAe;IAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;IAChC,MAAM,KAAK,GAAG;QACZ,6DAA6D,UAAU,YAAY;YACjF,kFAAkF;QACpF,EAAE;KACH,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,CAAC,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,EAAE;QACF,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,KAAK,sBAAsB;QAC9C,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,KAAK,mCAAmC,UAAU,IAAI;YACrE,uCAAuC,CAC9C,CAAC;IACF,uEAAuE;IACvE,6EAA6E;IAC7E,8EAA8E;IAC9E,sEAAsE;IACtE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iFAAiF;YAC/E,kFAAkF;YAClF,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,25 @@
1
+ /** The finalizer: after the agents deliberate, one agent (the judge seat) acts.
2
+ * It runs in the REAL workdir, applies whatever edits/actions fulfil the user's
3
+ * request — using the deliberation as advice — and writes the plain-prose reply.
4
+ * This is the sole step that mutates the user's files and the sole source of the
5
+ * answer, so the user never sees raw findings JSON. */
6
+ import { type AdapterExecutor } from "../core/executor.js";
7
+ import type { AgentRun } from "../core/state.js";
8
+ export declare function buildFinalizerPrompt(task: string, digest: string): string;
9
+ export interface FinalizerOpts {
10
+ task: string;
11
+ digest: string;
12
+ workdir: string;
13
+ /** Adapter to run as the finalizer (defaults to the first available agent). */
14
+ adapter?: string;
15
+ model?: string;
16
+ agentId?: string;
17
+ executor?: AdapterExecutor;
18
+ signal?: AbortSignal;
19
+ }
20
+ /** Run the finalizer agent and return its prose answer plus the raw run record. */
21
+ export declare function runFinalizer(opts: FinalizerOpts): Promise<{
22
+ answer: string;
23
+ run: AgentRun;
24
+ }>;
25
+ //# sourceMappingURL=finalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizer.d.ts","sourceRoot":"","sources":["../../src/chat/finalizer.ts"],"names":[],"mappings":"AAAA;;;;wDAIwD;AAExD,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBzE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,mFAAmF;AACnF,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,CAAC,CAyBlG"}
@@ -0,0 +1,52 @@
1
+ /** The finalizer: after the agents deliberate, one agent (the judge seat) acts.
2
+ * It runs in the REAL workdir, applies whatever edits/actions fulfil the user's
3
+ * request — using the deliberation as advice — and writes the plain-prose reply.
4
+ * This is the sole step that mutates the user's files and the sole source of the
5
+ * answer, so the user never sees raw findings JSON. */
6
+ import { LocalSubprocessExecutor } from "../core/executor.js";
7
+ import { progress } from "../core/progress.js";
8
+ import { ADAPTER_REGISTRY } from "../core/registry.js";
9
+ export function buildFinalizerPrompt(task, digest) {
10
+ return `${task}
11
+
12
+ ---
13
+ A panel of coding agents just deliberated on the request above. Their review and
14
+ attempts are summarised below — treat it as advice and critique, not as final or
15
+ necessarily correct work:
16
+
17
+ ${digest}
18
+ ---
19
+
20
+ Now finish the job. In this working directory, make any file edits or actions
21
+ needed to fully satisfy the user's request, drawing on the deliberation above and
22
+ correcting any mistakes in it. Then write the user a short, clear reply describing
23
+ what you did (or directly answering, if no edit was needed). Reply in plain prose
24
+ for a human — do NOT output JSON, finding-lists, or tool logs.`;
25
+ }
26
+ /** Run the finalizer agent and return its prose answer plus the raw run record. */
27
+ export async function runFinalizer(opts) {
28
+ const ctor = ADAPTER_REGISTRY.require(opts.adapter ?? "claude-code");
29
+ const adapter = new ctor(opts.agentId ?? "finalizer", { model: opts.model });
30
+ const executor = opts.executor ?? new LocalSubprocessExecutor();
31
+ const prompt = buildFinalizerPrompt(opts.task, opts.digest);
32
+ progress.start({ agent_id: adapter.agent_id, role: "finalizer" });
33
+ const result = await executor.execute(adapter, prompt, opts.workdir, {
34
+ timeoutMs: 600_000,
35
+ signal: opts.signal,
36
+ onStream: (text) => progress.step({ agent_id: adapter.agent_id, role: "finalizer", text }),
37
+ });
38
+ const run = {
39
+ agent_id: adapter.agent_id,
40
+ role: "finalizer",
41
+ prompt,
42
+ stdout: result.stdout,
43
+ stderr: result.stderr,
44
+ exit_code: result.exit_code,
45
+ files_changed: result.files_changed,
46
+ duration_s: result.duration_s,
47
+ cost_estimate_usd: result.cost_estimate_usd,
48
+ };
49
+ progress.done({ run });
50
+ return { answer: (result.stdout ?? "").trim(), run };
51
+ }
52
+ //# sourceMappingURL=finalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizer.js","sourceRoot":"","sources":["../../src/chat/finalizer.ts"],"names":[],"mappings":"AAAA;;;;wDAIwD;AAExD,OAAO,EAAE,uBAAuB,EAAwB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,MAAc;IAC/D,OAAO,GAAG,IAAI;;;;;;;EAOd,MAAM;;;;;;;+DAOuD,CAAC;AAChE,CAAC;AAcD,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAmB;IACpD,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,uBAAuB,EAAE,CAAC;IAChE,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5D,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;QACnE,SAAS,EAAE,OAAO;QAClB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;KAC3F,CAAC,CAAC;IACH,MAAM,GAAG,GAAa;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,WAAW;QACjB,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;KAC5C,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** Startup preflight: verify the agent CLIs a session needs are installed and
2
+ * (best-effort) authenticated, with a specific remediation message per tool. */
3
+ import { type AgentCfg } from "./configs.js";
4
+ export interface PreflightProblem {
5
+ agent: string;
6
+ cli: string;
7
+ reason: string;
8
+ fix: string;
9
+ }
10
+ export interface AgentStatus {
11
+ cli: string;
12
+ ok: boolean;
13
+ reason: "ready" | "not installed" | "not signed in";
14
+ fix?: string;
15
+ }
16
+ /** Every agent CLI Coterie knows how to drive, derived from the adapter→CLI map
17
+ * so registering a new adapter (with an ADAPTER_CLI entry) extends this list —
18
+ * and `coterie doctor` — automatically. */
19
+ export declare const ALL_AGENT_CLIS: string[];
20
+ /** Installed + (best-effort) signed-in status for one agent CLI. */
21
+ export declare function checkAgent(cli: string): AgentStatus;
22
+ export interface KnownAgentStatus {
23
+ agent: AgentCfg;
24
+ status: AgentStatus;
25
+ }
26
+ /** Status of every agent Coterie knows about, in preference order. Probing an
27
+ * agent's auth can be slow (e.g. cursor shells out), so callers that need both
28
+ * the ready lineup and the not-ready ones should call this ONCE and derive both
29
+ * from it rather than calling `availableAgents()` plus a second pass. */
30
+ export declare function agentStatuses(): KnownAgentStatus[];
31
+ /** The agents that are installed and signed in right now, in preference order —
32
+ * the lineup `coterie chat` coordinates and assigns roles from. */
33
+ export declare function availableAgents(): AgentCfg[];
34
+ /** Check every agent CLI referenced by the config. Returns problems (empty = OK). */
35
+ export declare function preflight(config: Record<string, any>): PreflightProblem[];
36
+ export declare function formatProblems(problems: PreflightProblem[]): string;
37
+ //# sourceMappingURL=preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/chat/preflight.ts"],"names":[],"mappings":"AAAA;iFACiF;AAOjF,OAAO,EAA6B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAqDD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,OAAO,GAAG,eAAe,GAAG,eAAe,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;4CAE4C;AAC5C,eAAO,MAAM,cAAc,EAAE,MAAM,EAA6C,CAAC;AAEjF,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAKnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;0EAG0E;AAC1E,wBAAgB,aAAa,IAAI,gBAAgB,EAAE,CAQlD;AAED;oEACoE;AACpE,wBAAgB,eAAe,IAAI,QAAQ,EAAE,CAI5C;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,EAAE,CAczE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAKnE"}
@@ -0,0 +1,115 @@
1
+ /** Startup preflight: verify the agent CLIs a session needs are installed and
2
+ * (best-effort) authenticated, with a specific remediation message per tool. */
3
+ import { spawnSync } from "node:child_process";
4
+ import { existsSync } from "node:fs";
5
+ import { homedir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { ADAPTER_CLI, KNOWN_AGENTS } from "./configs.js";
8
+ const REMEDIATION = {
9
+ claude: {
10
+ install: "npm install -g @anthropic-ai/claude-code",
11
+ login: "run `claude` once and sign in to your Claude (Max/Pro) account",
12
+ },
13
+ codex: {
14
+ install: "npm install -g @openai/codex",
15
+ login: "run `codex` once and sign in with your ChatGPT account",
16
+ },
17
+ "cursor-agent": {
18
+ install: "curl https://cursor.com/install -fsS | bash",
19
+ login: "run `cursor-agent login` and sign in to Cursor",
20
+ },
21
+ };
22
+ function isInstalled(cli) {
23
+ const probe = spawnSync(cli, ["--version"], { encoding: "utf8", timeout: 15_000 });
24
+ return !probe.error && (probe.status ?? 1) === 0;
25
+ }
26
+ /** Best-effort auth check (no network spend): look for the CLI's local creds at
27
+ * the locations it actually uses, honoring the env overrides each tool supports
28
+ * and resolving HOME from the environment — so it matches your shell, not a
29
+ * hardcoded path. This is a heuristic for a friendly message; the agent CLI is
30
+ * the real source of truth at run time (it reads its own creds, incl. Keychain),
31
+ * so a false "not signed in" here never stops a CLI that works in your shell. */
32
+ function looksAuthed(cli) {
33
+ const home = process.env.HOME || homedir();
34
+ if (cli === "claude") {
35
+ const dir = process.env.CLAUDE_CONFIG_DIR || join(home, ".claude");
36
+ return existsSync(join(home, ".claude.json")) || existsSync(join(dir, ".credentials.json"));
37
+ }
38
+ if (cli === "codex") {
39
+ const dir = process.env.CODEX_HOME || join(home, ".codex");
40
+ return existsSync(join(dir, "auth.json"));
41
+ }
42
+ if (cli === "cursor-agent") {
43
+ // ~/.cursor exists for anyone who's used the Cursor editor, so it's not an
44
+ // auth signal. Ask cursor-agent itself — `status` reports auth without
45
+ // running an agent (no cost), and exposes a clean JSON flag.
46
+ const probe = spawnSync(cli, ["status", "--format", "json"], { encoding: "utf8", timeout: 15_000 });
47
+ if (probe.error)
48
+ return false;
49
+ try {
50
+ return JSON.parse(probe.stdout || "{}").isAuthenticated === true;
51
+ }
52
+ catch {
53
+ return !/not logged in/i.test(probe.stdout || "");
54
+ }
55
+ }
56
+ return true;
57
+ }
58
+ /** Every agent CLI Coterie knows how to drive, derived from the adapter→CLI map
59
+ * so registering a new adapter (with an ADAPTER_CLI entry) extends this list —
60
+ * and `coterie doctor` — automatically. */
61
+ export const ALL_AGENT_CLIS = [...new Set(Object.values(ADAPTER_CLI))];
62
+ /** Installed + (best-effort) signed-in status for one agent CLI. */
63
+ export function checkAgent(cli) {
64
+ const rem = REMEDIATION[cli] ?? { install: `install ${cli}`, login: `authenticate ${cli}` };
65
+ if (!isInstalled(cli))
66
+ return { cli, ok: false, reason: "not installed", fix: `Install: ${rem.install}` };
67
+ if (!looksAuthed(cli))
68
+ return { cli, ok: false, reason: "not signed in", fix: `Log in: ${rem.login}` };
69
+ return { cli, ok: true, reason: "ready" };
70
+ }
71
+ /** Status of every agent Coterie knows about, in preference order. Probing an
72
+ * agent's auth can be slow (e.g. cursor shells out), so callers that need both
73
+ * the ready lineup and the not-ready ones should call this ONCE and derive both
74
+ * from it rather than calling `availableAgents()` plus a second pass. */
75
+ export function agentStatuses() {
76
+ return KNOWN_AGENTS.map((agent) => {
77
+ const cli = ADAPTER_CLI[agent.adapter];
78
+ const status = cli
79
+ ? checkAgent(cli)
80
+ : { cli: agent.adapter, ok: false, reason: "not installed" };
81
+ return { agent, status };
82
+ });
83
+ }
84
+ /** The agents that are installed and signed in right now, in preference order —
85
+ * the lineup `coterie chat` coordinates and assigns roles from. */
86
+ export function availableAgents() {
87
+ return agentStatuses()
88
+ .filter((s) => s.status.ok)
89
+ .map((s) => s.agent);
90
+ }
91
+ /** Check every agent CLI referenced by the config. Returns problems (empty = OK). */
92
+ export function preflight(config) {
93
+ const agents = config.agents ?? [];
94
+ const clis = new Set();
95
+ for (const a of agents) {
96
+ const cli = a.adapter && ADAPTER_CLI[a.adapter];
97
+ if (cli)
98
+ clis.add(cli);
99
+ }
100
+ const problems = [];
101
+ for (const cli of clis) {
102
+ const status = checkAgent(cli);
103
+ if (!status.ok)
104
+ problems.push({ agent: cli, cli, reason: status.reason, fix: status.fix ?? "" });
105
+ }
106
+ return problems;
107
+ }
108
+ export function formatProblems(problems) {
109
+ const lines = ["Coterie chat needs these agent CLIs installed and signed in:", ""];
110
+ for (const p of problems)
111
+ lines.push(` ✗ ${p.cli} — ${p.reason}\n ${p.fix}`);
112
+ lines.push("", "Each runs on its own subscription (Claude Max / ChatGPT / Cursor Pro) — no API keys needed.");
113
+ return lines.join("\n");
114
+ }
115
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/chat/preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** Human-readable rendering of a coordination round. Agents emit JSON (findings,
2
+ * verdicts) and prose; this module turns that into something a person reads.
3
+ * Nothing here ever surfaces raw JSON to the user. */
4
+ import type { AgentRun, CoterieState } from "../core/state.js";
5
+ export declare function runFailed(run: AgentRun): boolean;
6
+ /** A one-line, human-readable description of a failed run. */
7
+ export declare function renderFailure(run: AgentRun): string;
8
+ export interface FailureClass {
9
+ kind: "rate-limit" | "auth" | null;
10
+ /** A short note to bubble up — includes any "resets at…/try again in…" hint. */
11
+ detail: string;
12
+ }
13
+ /** Classify *why* a run failed so the session can adapt: drop a rate-limited or
14
+ * signed-out agent when others remain, or bubble up when/whether it'll recover. */
15
+ export declare function classifyFailure(run: AgentRun): FailureClass;
16
+ /** Render one agent's contribution as readable lines (no raw JSON). */
17
+ export declare function renderContribution(run: AgentRun, maxChars?: number): string;
18
+ /** A compact, readable digest of the deliberation, handed to the finalizer agent
19
+ * as advice. Built generically from runs + verdicts + mode-specific summaries. */
20
+ export declare function digestRound(final: CoterieState): string;
21
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/chat/render.ts"],"names":[],"mappings":"AAAA;;uDAEuD;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgC/D,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAIhD;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAInD;AAKD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAAC;IACnC,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;oFACoF;AACpF,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,YAAY,CAU3D;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,SAAO,GAAG,MAAM,CAWzE;AAED;mFACmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAkCvD"}