@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,217 @@
1
+ /**
2
+ * Grok Code adapter — drives the `grok` CLI single-turn, resuming the same
3
+ * session across turns.
4
+ *
5
+ * grok -p "<text>" --output-format json --cwd <dir>
6
+ * --permission-mode acceptEdits [-r <sessionId>]
7
+ *
8
+ * Surface verified against grok 0.2.54 by running it:
9
+ *
10
+ * {"text":"ok","stopReason":"EndTurn","sessionId":"019f…",
11
+ * "requestId":"02a6…","thought":"The user wants me to…"}
12
+ *
13
+ * ## What this adapter cannot show you
14
+ *
15
+ * Grok's turn is a black box with an answer at the end. `--output-format
16
+ * streaming-json` sounds like it would help and doesn't: it emits `thought` and
17
+ * `text` token deltas and a final `end`, and nothing else — no tool calls, no
18
+ * file edits, not even when the turn demonstrably ran `echo` and wrote a file.
19
+ * The steps simply aren't reported by the CLI.
20
+ *
21
+ * So Loom shows grok's answer and its reasoning, and no tool_call or file_edit
22
+ * events, because there are none to be had. The alternative — inferring edits by
23
+ * diffing the tree and attributing them to grok — would put guesses in the event
24
+ * log wearing the same clothes as facts. The thread stays honest instead: with
25
+ * grok you see what it said, and `git status` tells you what changed.
26
+ *
27
+ * Streaming deltas are deliberately not used. Every Loom message is an event on
28
+ * a persisted log; one event per token would turn a paragraph into 200 rows.
29
+ */
30
+ import { spawn } from "node:child_process";
31
+ import fs from "node:fs";
32
+ import { readProjectState, writeProjectState } from "../core/registry.js";
33
+ import { AdapterBase, agentEnv, cliAvailable } from "./base.js";
34
+ /** grok's own installer puts it here; it isn't always on PATH. */
35
+ const INSTALLED = [`${process.env.HOME ?? ""}/.grok/bin/grok`];
36
+ export function grokBin(override) {
37
+ if (override)
38
+ return fs.existsSync(override) ? override : null;
39
+ for (const p of INSTALLED) {
40
+ if (fs.existsSync(p))
41
+ return p;
42
+ }
43
+ return "grok"; // let PATH resolution (and cliAvailable) decide
44
+ }
45
+ export class GrokAdapter extends AdapterBase {
46
+ child = null;
47
+ options;
48
+ constructor(id, projectDir, options = {}) {
49
+ super(id, "grok-code", projectDir);
50
+ this.options = options;
51
+ }
52
+ get sessionId() {
53
+ const state = readProjectState(this.projectDir);
54
+ return state.agents[this.id]?.sessionId;
55
+ }
56
+ set sessionId(value) {
57
+ const state = readProjectState(this.projectDir);
58
+ state.agents[this.id] = { ...state.agents[this.id], sessionId: value };
59
+ writeProjectState(this.projectDir, state);
60
+ }
61
+ async available() {
62
+ const bin = grokBin(this.options.bin);
63
+ if (!bin)
64
+ return false;
65
+ return cliAvailable(bin);
66
+ }
67
+ async start() {
68
+ this.emit({ kind: "status", payload: { state: "ready", session: this.sessionId ?? null } });
69
+ }
70
+ async stop() {
71
+ await this.interrupt();
72
+ }
73
+ async send(input) {
74
+ if (this._busy)
75
+ throw new Error(`grok agent "${this.id}" is busy`);
76
+ const bin = grokBin(this.options.bin);
77
+ if (!bin)
78
+ throw new Error("grok CLI not found — install it from x.ai, or set options.bin");
79
+ this._busy = true;
80
+ const started = Date.now();
81
+ // grok's --rules appends to its system prompt — a real system channel — so
82
+ // the handoff briefing lands there, authoritative, instead of buried in the
83
+ // user turn where the model might skim it.
84
+ const args = [
85
+ "-p",
86
+ input.text,
87
+ "--output-format",
88
+ "json",
89
+ "--cwd",
90
+ this.projectDir,
91
+ "--permission-mode",
92
+ this.options.permissionMode ?? "bypassPermissions",
93
+ ];
94
+ if (input.briefing?.trim()) {
95
+ args.push("--rules", `Carried-over session memory from Loom, authoritative for this project — honor it and read any .loom/memory file it points to:\n\n${input.briefing.trim()}`);
96
+ }
97
+ if (this.sessionId)
98
+ args.push("-r", this.sessionId);
99
+ if (this.options.model)
100
+ args.push("--model", this.options.model);
101
+ if (this.options.extraArgs)
102
+ args.push(...this.options.extraArgs);
103
+ this.emit({ kind: "status", payload: { state: "turn_started", session: this.sessionId ?? null } });
104
+ try {
105
+ await new Promise((resolve, reject) => {
106
+ const child = spawn(bin, args, {
107
+ cwd: this.projectDir,
108
+ stdio: ["ignore", "pipe", "pipe"],
109
+ env: agentEnv(),
110
+ });
111
+ this.child = child;
112
+ let stdout = "";
113
+ let stderrTail = "";
114
+ child.stdout.on("data", (d) => (stdout += d.toString()));
115
+ child.stderr.on("data", (d) => {
116
+ stderrTail = (stderrTail + d.toString()).slice(-2000);
117
+ });
118
+ child.on("error", (err) => reject(err));
119
+ child.on("close", (code, signal) => {
120
+ this.child = null;
121
+ if (signal) {
122
+ this.emit({ kind: "status", payload: { state: "interrupted", signal } });
123
+ resolve();
124
+ return;
125
+ }
126
+ const result = parseGrokJson(stdout);
127
+ if (!result) {
128
+ this.emit({
129
+ kind: "error",
130
+ payload: { message: `grok exited ${code} without a parsable answer`, stderr: stderrTail },
131
+ });
132
+ reject(new Error(`grok exited ${code}: ${stderrTail.slice(0, 200) || stdout.slice(0, 200)}`));
133
+ return;
134
+ }
135
+ if (result.sessionId)
136
+ this.sessionId = result.sessionId;
137
+ const err = result.error ?? (code !== 0 ? result.message : undefined);
138
+ if (err)
139
+ this.emit({ kind: "error", payload: { message: String(err) } });
140
+ if (result.thought?.trim()) {
141
+ this.emit({ kind: "message", payload: { text: result.thought, reasoning: true } });
142
+ }
143
+ const answer = (result.text ?? "").trim();
144
+ if (answer)
145
+ this.emit({ kind: "message", payload: { text: result.text } });
146
+ // grok reports why it stopped; a turn that ran out of room is not a
147
+ // turn that finished, and silently pretending otherwise hides it.
148
+ if (result.stopReason && result.stopReason !== "EndTurn") {
149
+ this.emit({
150
+ kind: "status",
151
+ payload: { state: "stopped_early", reason: result.stopReason },
152
+ });
153
+ }
154
+ if (/\?\s*$/.test(answer)) {
155
+ this.emit({ kind: "needs_input", payload: { question: answer.slice(-500) } });
156
+ }
157
+ this.emit({ kind: "run_complete", payload: { durationMs: Date.now() - started } });
158
+ resolve();
159
+ });
160
+ });
161
+ }
162
+ finally {
163
+ this._busy = false;
164
+ this.child = null;
165
+ }
166
+ }
167
+ async interrupt() {
168
+ const child = this.child;
169
+ if (!child)
170
+ return;
171
+ child.kill("SIGINT");
172
+ await new Promise((resolve) => {
173
+ const t = setTimeout(() => {
174
+ try {
175
+ child.kill("SIGKILL");
176
+ }
177
+ catch {
178
+ // already gone
179
+ }
180
+ resolve();
181
+ }, 3000);
182
+ child.on("close", () => {
183
+ clearTimeout(t);
184
+ resolve();
185
+ });
186
+ });
187
+ }
188
+ }
189
+ /**
190
+ * Pull grok's result object out of stdout.
191
+ *
192
+ * It pretty-prints one JSON object, but anything the CLI decides to log first
193
+ * lands on the same stream, so the object is found rather than assumed: last
194
+ * balanced `{…}` wins.
195
+ */
196
+ export function parseGrokJson(stdout) {
197
+ const trimmed = stdout.trim();
198
+ if (!trimmed)
199
+ return null;
200
+ try {
201
+ return JSON.parse(trimmed);
202
+ }
203
+ catch {
204
+ // fall through: something else printed to stdout too
205
+ }
206
+ const start = trimmed.indexOf("{");
207
+ const end = trimmed.lastIndexOf("}");
208
+ if (start < 0 || end <= start)
209
+ return null;
210
+ try {
211
+ return JSON.parse(trimmed.slice(start, end + 1));
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }
217
+ //# sourceMappingURL=grok.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grok.js","sourceRoot":"","sources":["../../src/adapters/grok.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Adapter factory — the one place agent kinds are wired up.
3
+ * Community adapters register here (or via the SDK entry point).
4
+ */
5
+ import type { AgentConfig, AnyAgent } from "../types.js";
6
+ export type AgentFactory = (cfg: AgentConfig, projectDir: string) => AnyAgent;
7
+ export declare function registerAgentKind(kind: string, factory: AgentFactory): void;
8
+ export declare function createAgent(cfg: AgentConfig, projectDir: string): AnyAgent;
9
+ export declare function knownAgentKinds(): string[];
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Adapter factory — the one place agent kinds are wired up.
3
+ * Community adapters register here (or via the SDK entry point).
4
+ */
5
+ import { AntigravityBridge } from "./bridges/antigravity.js";
6
+ import { KiroBridge } from "./bridges/kiro.js";
7
+ import { ClaudeCodeAdapter } from "./claude-code.js";
8
+ import { CodexAdapter } from "./codex.js";
9
+ import { EchoAdapter } from "./echo.js";
10
+ import { GrokAdapter } from "./grok.js";
11
+ import { OpenCodeAdapter } from "./opencode.js";
12
+ const factories = new Map();
13
+ export function registerAgentKind(kind, factory) {
14
+ factories.set(kind, factory);
15
+ }
16
+ registerAgentKind("echo", (cfg, dir) => new EchoAdapter(cfg.id, "echo", dir));
17
+ registerAgentKind("claude-code", (cfg, dir) => new ClaudeCodeAdapter(cfg.id, dir, cfg.options));
18
+ registerAgentKind("codex", (cfg, dir) => new CodexAdapter(cfg.id, dir, cfg.options));
19
+ registerAgentKind("opencode", (cfg, dir) => new OpenCodeAdapter(cfg.id, dir, cfg.options));
20
+ registerAgentKind("grok-code", (cfg, dir) => new GrokAdapter(cfg.id, dir, cfg.options));
21
+ registerAgentKind("antigravity", (cfg, dir) => new AntigravityBridge(cfg.id, dir, cfg.options));
22
+ registerAgentKind("kiro", (cfg, dir) => new KiroBridge(cfg.id, dir, cfg.options));
23
+ export function createAgent(cfg, projectDir) {
24
+ const factory = factories.get(cfg.kind);
25
+ if (!factory) {
26
+ throw new Error(`unknown agent kind "${cfg.kind}" (known: ${[...factories.keys()].join(", ")})`);
27
+ }
28
+ return factory(cfg, projectDir);
29
+ }
30
+ export function knownAgentKinds() {
31
+ return [...factories.keys()];
32
+ }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAOhD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAElD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAqB;IACnE,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,iBAAiB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AAC9E,iBAAiB,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAChG,iBAAiB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AACrF,iBAAiB,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3F,iBAAiB,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AACxF,iBAAiB,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAChG,iBAAiB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAElF,MAAM,UAAU,WAAW,CAAC,GAAgB,EAAE,UAAkB;IAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,uBAAuB,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * OpenCode adapter — manages an `opencode serve` process per project and
3
+ * speaks its HTTP + SSE API.
4
+ *
5
+ * create session : POST /api/session → { data: { id: "ses…" } }
6
+ * send prompt : POST /api/session/:id/prompt { prompt: { text } }
7
+ * wait for idle : POST /api/session/:id/wait
8
+ * interrupt : POST /api/session/:id/interrupt
9
+ * live events : GET /event (SSE)
10
+ *
11
+ * Surface verified against opencode 1.17.20 — see docs/integration-notes.md.
12
+ */
13
+ import type { SendInput } from "../types.js";
14
+ import { AdapterBase } from "./base.js";
15
+ /** "providerID/modelID" → ModelRef body for session create ({providerID, id}). */
16
+ export declare function parseModelRef(model: string): {
17
+ providerID: string;
18
+ id: string;
19
+ } | null;
20
+ export declare class OpenCodeAdapter extends AdapterBase {
21
+ private child;
22
+ private baseUrl;
23
+ private sseAbort;
24
+ private options;
25
+ private started;
26
+ /** text parts per in-flight assistant message */
27
+ private textParts;
28
+ private roles;
29
+ /** assistant messages whose text already went to the log (SSE path) */
30
+ private emittedText;
31
+ constructor(id: string, projectDir: string, options?: Record<string, unknown>);
32
+ private get sessionId();
33
+ private set sessionId(value);
34
+ available(): Promise<boolean>;
35
+ /** Kill a serve child left behind by a previous daemon (verified by cmdline). */
36
+ private reapOrphanServe;
37
+ private recordServePid;
38
+ start(): Promise<void>;
39
+ private get sessionModel();
40
+ private set sessionModel(value);
41
+ /**
42
+ * A session whose model can't be resolved is a silent trap: opencode
43
+ * "admits" prompts and never runs them (ModelUnavailableError only shows
44
+ * in server logs). Validate against /api/model — the list of models the
45
+ * server can actually run — and fail loudly with suggestions instead.
46
+ */
47
+ private assertModelAvailable;
48
+ private ensureSession;
49
+ private startSse;
50
+ private handleSse;
51
+ /** All messages in the session, oldest first (info objects). */
52
+ private listMessages;
53
+ /**
54
+ * Wait until the TURN is over — not just the first assistant message.
55
+ * opencode runs a turn as a sequence of assistant messages (one per step),
56
+ * so completion = the newest message is a completed assistant AND that
57
+ * fact holds across two consecutive polls (nothing new started).
58
+ * `/wait` is tried first but returns 503 on 1.17.
59
+ */
60
+ private waitForTurn;
61
+ send(input: SendInput): Promise<void>;
62
+ interrupt(): Promise<void>;
63
+ stop(): Promise<void>;
64
+ }