@cotal-ai/connector-opencode 0.8.1 → 0.8.3

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.
@@ -4,8 +4,8 @@ import { type Connector } from "@cotal-ai/core";
4
4
  * OpenCode's client/server split (see serve.ts). The Cotal mesh bridge runs as an in-process plugin
5
5
  * inside a headless `opencode serve`: it holds the {@link MeshAgent}, registers the cotal_* tools
6
6
  * natively (from the shared specs, at parity with Claude Code), reports presence off the event bus,
7
- * and owns ONE session it drives — injecting each incoming peer batch as a turn via the prompt API
8
- * (`session.promptAsync`, server-side, so it can't race the TUI input box). The shim then attaches a
7
+ * and owns ONE session it drives — injecting each incoming peer batch through the authenticated
8
+ * OpenCode server API on the same serve process the TUI attaches to. The shim then attaches a
9
9
  * foreground TUI to that session, so a human watching sees the agent work and can type into it.
10
10
  *
11
11
  * Config rides in `OPENCODE_CONFIG_CONTENT` (inline JSON, the highest merge layer), so the
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAa3G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAiF/B,CAAC"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAa3G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAqG/B,CAAC"}
package/dist/extension.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { resolve } from "node:path";
3
3
  import { loadAgentFile, registry } from "@cotal-ai/core";
4
- import { aclEnv, launchEnv, MODEL_PROVIDER_KEYS } from "@cotal-ai/connector-core";
4
+ import { aclEnv, launchEnv, controlEndpoint, MODEL_PROVIDER_KEYS, transcriptChannel } from "@cotal-ai/connector-core";
5
5
  /** The bundled in-process plugin (esbuild → `dist/plugin.bundle.js`). `opencode serve` loads it by
6
6
  * absolute path from the inline config, so it runs *inside* the server and shares its SDK client.
7
7
  * Resolved relative to this module — beside the built `dist/extension.js`, so the connector must be
@@ -15,8 +15,8 @@ const SERVE_SHIM = fileURLToPath(new URL("./serve.js", import.meta.url));
15
15
  * OpenCode's client/server split (see serve.ts). The Cotal mesh bridge runs as an in-process plugin
16
16
  * inside a headless `opencode serve`: it holds the {@link MeshAgent}, registers the cotal_* tools
17
17
  * natively (from the shared specs, at parity with Claude Code), reports presence off the event bus,
18
- * and owns ONE session it drives — injecting each incoming peer batch as a turn via the prompt API
19
- * (`session.promptAsync`, server-side, so it can't race the TUI input box). The shim then attaches a
18
+ * and owns ONE session it drives — injecting each incoming peer batch through the authenticated
19
+ * OpenCode server API on the same serve process the TUI attaches to. The shim then attaches a
20
20
  * foreground TUI to that session, so a human watching sees the agent work and can type into it.
21
21
  *
22
22
  * Config rides in `OPENCODE_CONFIG_CONTENT` (inline JSON, the highest merge layer), so the
@@ -27,6 +27,7 @@ const SERVE_SHIM = fileURLToPath(new URL("./serve.js", import.meta.url));
27
27
  export const opencodeConnector = {
28
28
  kind: "connector",
29
29
  name: "opencode",
30
+ transcriptChannel, // the shared `tr-<name>` convention (connector-core), exposed via the contract
30
31
  requires: ["opencode"],
31
32
  buildLaunch(opts) {
32
33
  // Tool-sharing isn't wired for opencode: its OPENCODE_CONFIG_CONTENT is a merge layer, so an
@@ -57,6 +58,8 @@ export const opencodeConnector = {
57
58
  env.COTAL_CREDS = opts.creds;
58
59
  if (opts.servers)
59
60
  env.COTAL_SERVERS = opts.servers;
61
+ if (opts.transcript === true)
62
+ env.COTAL_TRANSCRIPT = "1"; // gate the plugin's transcript mirror (parity with Claude)
60
63
  // Where serve.ts roots this agent's SQLite DB + serve pidfile. Pin it to the manager's
61
64
  // workspace root so a per-agent launch cwd (which the manager can point at any repo) doesn't
62
65
  // drop `.cotal/opencode/<name>` into the target tree. Standalone `cotal spawn` has no manager
@@ -93,15 +96,31 @@ export const opencodeConnector = {
93
96
  if (face)
94
97
  env.COTAL_FACE_PERSONA = face; // shim swaps the TUI for the face viewer
95
98
  }
96
- // The `--model` flag wins over the agent file, and applies even with no agent file.
97
- if (model)
99
+ // The `--model` flag wins over the agent file, and applies even with no agent file. Pin it to a
100
+ // dedicated primary agent made the default, so an operator's own `default_agent` in
101
+ // ~/.config/opencode (with its own model) can't override the model a Cotal spawn asks for — the
102
+ // session the plugin drives runs the persona's model, not the operator's default agent's.
103
+ if (model) {
98
104
  config.model = model;
105
+ config.agent = { cotal: { mode: "primary", model } };
106
+ config.default_agent = "cotal";
107
+ }
99
108
  env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
109
+ // Local control endpoint: the manager sends a cooperative {op:"shutdown"} here on a signal-less
110
+ // runtime (ConPTY/Windows), where a hard kill skips cleanup and the agent lingers until its
111
+ // presence TTL expires. The plugin (in the opencode server process) starts the control server and
112
+ // leaves the mesh cleanly on shutdown. Minted here; passed to the plugin in the child env (the
113
+ // token never on argv/logs) — opencode serve inherits this process env, the attached TUI strips
114
+ // COTAL_*. Returned in the LaunchSpec so the manager holds it in memory to drive the stop.
115
+ const control = controlEndpoint(opts.space, opts.name);
116
+ env.COTAL_CONTROL_SOCKET = control.path;
117
+ env.COTAL_CONTROL_TOKEN = control.token;
100
118
  // Run the shim (node dist/serve.js): `opencode serve` + an attached foreground TUI.
101
119
  return {
102
120
  command: process.execPath,
103
121
  args: [SERVE_SHIM],
104
122
  env,
123
+ control,
105
124
  };
106
125
  },
107
126
  };
@@ -1 +1 @@
1
- {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
@@ -2993,7 +2993,7 @@ var require_nkeys = __commonJS({
2993
2993
  exports.createAccount = createAccount2;
2994
2994
  exports.createUser = createUser2;
2995
2995
  exports.createCluster = createCluster;
2996
- exports.createServer = createServer;
2996
+ exports.createServer = createServer2;
2997
2997
  exports.createCurve = createCurve;
2998
2998
  exports.fromPublic = fromPublic2;
2999
2999
  exports.fromCurveSeed = fromCurveSeed;
@@ -3021,7 +3021,7 @@ var require_nkeys = __commonJS({
3021
3021
  function createCluster() {
3022
3022
  return createPair(Prefix2.Cluster);
3023
3023
  }
3024
- function createServer() {
3024
+ function createServer2() {
3025
3025
  return createPair(Prefix2.Server);
3026
3026
  }
3027
3027
  function createCurve() {
@@ -14944,6 +14944,8 @@ function assertValidName(name) {
14944
14944
  throw new Error(`invalid name ${JSON.stringify(name)}: must be a single line`);
14945
14945
  if (name.includes("/"))
14946
14946
  throw new Error(`invalid name ${JSON.stringify(name)}: "/" is reserved (the owner/name separator)`);
14947
+ if (name.includes("\\"))
14948
+ throw new Error(`invalid name ${JSON.stringify(name)}: "\\" is reserved (a Windows path separator)`);
14947
14949
  }
14948
14950
 
14949
14951
  // ../../packages/core/dist/link.js
@@ -17038,6 +17040,9 @@ function loadAgentFile(path) {
17038
17040
  };
17039
17041
  }
17040
17042
 
17043
+ // ../../packages/core/dist/secret-fs.js
17044
+ var isWin = process.platform === "win32";
17045
+
17041
17046
  // ../../packages/core/dist/endpoint.js
17042
17047
  import { EventEmitter } from "node:events";
17043
17048
  import { randomUUID } from "node:crypto";
@@ -19321,7 +19326,7 @@ function configFromEnv(env = process.env) {
19321
19326
  description: def?.description,
19322
19327
  tags: def?.tags,
19323
19328
  meta: def?.meta,
19324
- capabilities: def?.capabilities,
19329
+ capabilities: splitList(env.COTAL_CAPABILITIES).length ? splitList(env.COTAL_CAPABILITIES) : def?.capabilities,
19325
19330
  model: env.COTAL_MODEL?.trim() || def?.model || void 0,
19326
19331
  servers: env.COTAL_SERVERS?.trim() || link?.servers || DEFAULT_SERVER,
19327
19332
  subscribe: resolvedSubscribe,
@@ -19889,6 +19894,11 @@ ${lines.join("\n")}`;
19889
19894
  }
19890
19895
  };
19891
19896
 
19897
+ // ../connector-core/dist/launch.js
19898
+ function transcriptChannel(name) {
19899
+ return `tr-${name.toLowerCase().replace(/[^a-z0-9_-]+/g, "-")}`;
19900
+ }
19901
+
19892
19902
  // ../connector-core/dist/tool-specs.js
19893
19903
  import { execFileSync } from "node:child_process";
19894
19904
 
@@ -34914,6 +34924,16 @@ ${info}${caught}`);
34914
34924
  }
34915
34925
 
34916
34926
  // ../connector-core/dist/control.js
34927
+ import { createServer } from "node:net";
34928
+ import { existsSync, unlinkSync } from "node:fs";
34929
+ import { createHash, timingSafeEqual } from "node:crypto";
34930
+ var MAX_FRAME_BYTES = 1 << 20;
34931
+ var AUTH_DEADLINE_MS = 5e3;
34932
+ function tokenMatches(presented, digest) {
34933
+ if (typeof presented !== "string")
34934
+ return false;
34935
+ return timingSafeEqual(createHash("sha256").update(presented).digest(), digest);
34936
+ }
34917
34937
  function who(i) {
34918
34938
  return i.fromRole ? `${i.fromName}/${i.fromRole}` : i.fromName;
34919
34939
  }
@@ -34934,6 +34954,76 @@ function formatInjection(items) {
34934
34954
  ${items.map(fmtItem2).join("\n")}
34935
34955
  ${tail}`;
34936
34956
  }
34957
+ function startControlServer(agent, endpoint, handle, opts = {}) {
34958
+ const { path } = endpoint;
34959
+ const digest = createHash("sha256").update(endpoint.token).digest();
34960
+ if (process.platform !== "win32" && existsSync(path)) {
34961
+ try {
34962
+ unlinkSync(path);
34963
+ } catch {
34964
+ }
34965
+ }
34966
+ const server = createServer((sock) => {
34967
+ let buf = "";
34968
+ let handled = false;
34969
+ sock.setEncoding("utf8");
34970
+ const deadline = setTimeout(() => sock.destroy(), AUTH_DEADLINE_MS);
34971
+ deadline.unref?.();
34972
+ sock.on("close", () => clearTimeout(deadline));
34973
+ sock.on("data", async (d) => {
34974
+ if (handled)
34975
+ return;
34976
+ buf += d;
34977
+ if (buf.length > MAX_FRAME_BYTES) {
34978
+ sock.destroy();
34979
+ return;
34980
+ }
34981
+ const nl = buf.indexOf("\n");
34982
+ if (nl < 0)
34983
+ return;
34984
+ handled = true;
34985
+ clearTimeout(deadline);
34986
+ let frame = {};
34987
+ try {
34988
+ frame = JSON.parse(buf.slice(0, nl) || "{}");
34989
+ } catch {
34990
+ }
34991
+ if (!tokenMatches(frame.token, digest)) {
34992
+ sock.destroy();
34993
+ return;
34994
+ }
34995
+ if (frame.op === "shutdown") {
34996
+ try {
34997
+ sock.end(JSON.stringify({ ok: true }) + "\n");
34998
+ } catch {
34999
+ }
35000
+ opts.onShutdown?.();
35001
+ return;
35002
+ }
35003
+ const ev = frame.event ?? {};
35004
+ const reply = await handle(agent, ev);
35005
+ try {
35006
+ sock.end(JSON.stringify(reply) + "\n");
35007
+ } catch {
35008
+ }
35009
+ });
35010
+ sock.on("error", () => {
35011
+ });
35012
+ });
35013
+ let bound = false;
35014
+ server.on("error", (e) => {
35015
+ process.stderr.write(`[cotal-connector] control server error: ${e.message}
35016
+ `);
35017
+ if (opts.fatalBind && !bound)
35018
+ process.exit(1);
35019
+ });
35020
+ server.listen(path, () => {
35021
+ bound = true;
35022
+ process.stderr.write(`[cotal-connector] control socket: ${path}
35023
+ `);
35024
+ });
35025
+ return server;
35026
+ }
34937
35027
 
34938
35028
  // src/tools.ts
34939
35029
  import { tool } from "@opencode-ai/plugin";
@@ -34964,13 +35054,99 @@ function buildCotalTools(agent, config2) {
34964
35054
  return tools;
34965
35055
  }
34966
35056
 
35057
+ // src/transcript.ts
35058
+ var MAX_PREVIEW = 700;
35059
+ var MAX_CHUNK = 6e3;
35060
+ function truncate(s, max) {
35061
+ return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
35062
+ }
35063
+ function salient(input) {
35064
+ const i = input ?? {};
35065
+ const v = i.command ?? i.filePath ?? i.file_path ?? i.path ?? i.url ?? i.pattern ?? i.description;
35066
+ const s = typeof v === "string" ? v : Object.keys(i).length ? JSON.stringify(i) : "";
35067
+ return s ? `: ${truncate(s, 300)}` : "";
35068
+ }
35069
+ function condensePart(part) {
35070
+ switch (part?.type) {
35071
+ case "text":
35072
+ if (part.synthetic || part.ignored || !part.text?.trim()) return [];
35073
+ return [part.text.trim()];
35074
+ // assistant text in FULL — chunkLines splits it across messages
35075
+ case "tool": {
35076
+ const head = `\u2692 ${part.tool}${salient(part.state?.input)}`;
35077
+ const status = part.state?.status;
35078
+ if (status === "completed")
35079
+ return [head, `\u2192 ${truncate(String(part.state.output ?? ""), MAX_PREVIEW) || "(no output)"}`];
35080
+ if (status === "error") return [head, `\u2192 ERROR: ${truncate(String(part.state.error ?? ""), MAX_PREVIEW)}`];
35081
+ return [head];
35082
+ }
35083
+ default:
35084
+ return [];
35085
+ }
35086
+ }
35087
+ function chunkLines(lines, max) {
35088
+ const chunks = [];
35089
+ let cur = "";
35090
+ for (const ln of lines) {
35091
+ if (ln.length > max) {
35092
+ if (cur) {
35093
+ chunks.push(cur);
35094
+ cur = "";
35095
+ }
35096
+ for (let i = 0; i < ln.length; i += max) chunks.push(ln.slice(i, i + max));
35097
+ continue;
35098
+ }
35099
+ if (cur && cur.length + ln.length + 1 > max) {
35100
+ chunks.push(cur);
35101
+ cur = "";
35102
+ }
35103
+ cur = cur ? `${cur}
35104
+ ${ln}` : ln;
35105
+ }
35106
+ if (cur) chunks.push(cur);
35107
+ return chunks;
35108
+ }
35109
+ function createTranscriptMirror(agent, channel) {
35110
+ const assistantMsgs = /* @__PURE__ */ new Set();
35111
+ const condensed = /* @__PURE__ */ new Map();
35112
+ const clear = () => {
35113
+ condensed.clear();
35114
+ assistantMsgs.clear();
35115
+ };
35116
+ return {
35117
+ record(message) {
35118
+ const info = message?.info ?? message;
35119
+ if (info?.role === "assistant" && typeof info.id === "string") assistantMsgs.add(info.id);
35120
+ },
35121
+ observe(part) {
35122
+ if (!part?.id || typeof part.messageID !== "string") return;
35123
+ const key = `${part.messageID}:${part.id}`;
35124
+ const lines = condensePart(part);
35125
+ if (lines.length) condensed.set(key, { messageID: part.messageID, lines });
35126
+ else condensed.delete(key);
35127
+ },
35128
+ async flush() {
35129
+ const lines = [];
35130
+ for (const { messageID, lines: ls } of condensed.values())
35131
+ if (assistantMsgs.has(messageID)) lines.push(...ls);
35132
+ clear();
35133
+ for (const chunk of chunkLines(lines, MAX_CHUNK)) await agent.send(chunk, channel);
35134
+ },
35135
+ reset() {
35136
+ clear();
35137
+ }
35138
+ };
35139
+ }
35140
+
34967
35141
  // src/plugin.ts
34968
35142
  function log(msg) {
34969
35143
  process.stderr.write(`[cotal-connector] ${msg}
34970
35144
  `);
34971
35145
  }
34972
35146
  var guard = globalThis;
34973
- var cotal = async ({ client }) => {
35147
+ var ERROR_RETRY_INITIAL_MS = 1e3;
35148
+ var ERROR_RETRY_MAX_MS = 3e4;
35149
+ var cotal = async () => {
34974
35150
  if (!hasIdentity()) {
34975
35151
  log("no COTAL_NAME \u2014 not a managed session; staying off the mesh");
34976
35152
  return {};
@@ -34978,8 +35154,27 @@ var cotal = async ({ client }) => {
34978
35154
  if (guard.__cotalOpencodeHooks) return guard.__cotalOpencodeHooks;
34979
35155
  const config2 = configFromEnv();
34980
35156
  config2.connector = "opencode";
35157
+ const serverUrl = process.env.COTAL_OPENCODE_SERVER_URL?.trim();
35158
+ const serverUsername = process.env.OPENCODE_SERVER_USERNAME?.trim() || "opencode";
35159
+ const serverPassword = process.env.OPENCODE_SERVER_PASSWORD?.trim();
35160
+ if (!serverUrl || !serverPassword) throw new Error("opencode connector: missing COTAL_OPENCODE_SERVER_URL/OPENCODE_SERVER_PASSWORD");
35161
+ const serverAuth = `Basic ${Buffer.from(`${serverUsername}:${serverPassword}`).toString("base64")}`;
34981
35162
  const agent = new MeshAgent(config2);
34982
35163
  agent.start();
35164
+ async function opencodeApi(path, init, timeoutMs = 1e4) {
35165
+ const res = await fetch(`${serverUrl}${path}`, {
35166
+ ...init,
35167
+ signal: init?.signal ?? AbortSignal.timeout(timeoutMs),
35168
+ headers: {
35169
+ authorization: serverAuth,
35170
+ "content-type": "application/json",
35171
+ ...init?.headers ?? {}
35172
+ }
35173
+ });
35174
+ if (!res.ok) throw new Error(`OpenCode HTTP ${res.status} ${res.statusText} for ${path}`);
35175
+ if (res.status === 204) return void 0;
35176
+ return await res.json();
35177
+ }
34983
35178
  const def = process.env.COTAL_AGENT_FILE?.trim() ? loadAgentFile(process.env.COTAL_AGENT_FILE.trim()) : void 0;
34984
35179
  const facePrompt = process.env.COTAL_FACE_PERSONA?.trim() ? 'You speak through an animated pixel-art avatar of yourself. Hard formatting rule: the text you pass to the cotal send tools (cotal_send / cotal_dm) must START with an emotion tag [[face:X]], where X is one of: neutral, happy, sad, angry, surprised \u2014 pick the one matching your mood, and insert another tag mid-text whenever your mood shifts. Example: "[[face:angry]] That race condition cost me three days. [[face:happy]] But watch it run now." Never mention or explain the tags \u2014 they are stripped before peers see your message.' : void 0;
34985
35180
  const persona = [def?.persona, facePrompt].filter(Boolean).join("\n\n") || void 0;
@@ -34991,15 +35186,58 @@ var cotal = async ({ client }) => {
34991
35186
  let briefed = false;
34992
35187
  let surfaced = [];
34993
35188
  let awaitingTurnEnd = false;
35189
+ let errorRetryTimer;
35190
+ let errorRetryMs = ERROR_RETRY_INITIAL_MS;
35191
+ const transcript = /^(1|true|yes|on)$/i.test(process.env.COTAL_TRANSCRIPT ?? "") ? createTranscriptMirror(agent, transcriptChannel(config2.name)) : void 0;
34994
35192
  const safeStatus = async (status, activity) => {
34995
35193
  try {
34996
35194
  if (agent.connected) await agent.setStatus(status, activity);
34997
35195
  } catch {
34998
35196
  }
34999
35197
  };
35198
+ let controlServer;
35199
+ const shutdown = async () => {
35200
+ try {
35201
+ controlServer?.close();
35202
+ } catch {
35203
+ }
35204
+ try {
35205
+ await safeStatus("offline");
35206
+ await agent.stop();
35207
+ } finally {
35208
+ process.exit(0);
35209
+ }
35210
+ };
35211
+ const controlPath = process.env.COTAL_CONTROL_SOCKET?.trim();
35212
+ const controlToken = process.env.COTAL_CONTROL_TOKEN?.trim();
35213
+ if (controlPath && controlToken) {
35214
+ const handle = async () => ({
35215
+ ok: false,
35216
+ error: "opencode runs cotal hooks in-process; only the shutdown control op is supported"
35217
+ });
35218
+ controlServer = startControlServer(agent, { path: controlPath, token: controlToken }, handle, {
35219
+ fatalBind: true,
35220
+ onShutdown: () => void shutdown()
35221
+ });
35222
+ }
35000
35223
  function pendingForWake() {
35001
35224
  return agent.pendingWake();
35002
35225
  }
35226
+ function clearErrorRetry(resetDelay = false) {
35227
+ if (errorRetryTimer) clearTimeout(errorRetryTimer);
35228
+ errorRetryTimer = void 0;
35229
+ if (resetDelay) errorRetryMs = ERROR_RETRY_INITIAL_MS;
35230
+ }
35231
+ function scheduleErrorRetry() {
35232
+ if (errorRetryTimer || pendingForWake() === 0) return;
35233
+ const delay = errorRetryMs;
35234
+ errorRetryMs = Math.min(errorRetryMs * 2, ERROR_RETRY_MAX_MS);
35235
+ errorRetryTimer = setTimeout(() => {
35236
+ errorRetryTimer = void 0;
35237
+ if (!busy && pendingForWake() > 0) void drive();
35238
+ }, delay);
35239
+ errorRetryTimer.unref?.();
35240
+ }
35003
35241
  function adoptSession(id, reason) {
35004
35242
  if (sessionID === id) return;
35005
35243
  const previous = sessionID;
@@ -35011,6 +35249,8 @@ var cotal = async ({ client }) => {
35011
35249
  briefed = false;
35012
35250
  surfaced = [];
35013
35251
  awaitingTurnEnd = false;
35252
+ clearErrorRetry(true);
35253
+ transcript?.reset();
35014
35254
  if (previous) {
35015
35255
  log(`adopted opencode session ${id} after ${reason}; mesh identity unchanged`);
35016
35256
  if (pendingForWake() > 0) void drive();
@@ -35018,8 +35258,11 @@ var cotal = async ({ client }) => {
35018
35258
  }
35019
35259
  const sessionReady = (async () => {
35020
35260
  try {
35021
- const res = await client.session.create({ body: { title: `cotal:${config2.space}:${config2.name}` } });
35022
- const id = res.data?.id;
35261
+ const res = await opencodeApi("/session", {
35262
+ method: "POST",
35263
+ body: JSON.stringify({ title: `cotal:${config2.space}:${config2.name}` })
35264
+ }, 1e4);
35265
+ const id = res.id;
35023
35266
  if (id) {
35024
35267
  adoptSession(id, "boot");
35025
35268
  process.stderr.write(`[cotal-session] ${id}
@@ -35064,13 +35307,14 @@ ${ORIENTATION_BOOTSTRAP}`;
35064
35307
  busy = true;
35065
35308
  surfaced = ids;
35066
35309
  awaitingTurnEnd = true;
35067
- await client.session.promptAsync({ path: { id }, body });
35310
+ await opencodeApi(`/session/${encodeURIComponent(id)}/prompt_async`, { method: "POST", body: JSON.stringify(body) }, 1e4);
35068
35311
  primed = true;
35069
35312
  } catch (e) {
35070
35313
  busy = false;
35071
35314
  surfaced = [];
35072
35315
  awaitingTurnEnd = false;
35073
35316
  log(`drive failed: ${e.message}`);
35317
+ scheduleErrorRetry();
35074
35318
  } finally {
35075
35319
  driving = false;
35076
35320
  }
@@ -35083,6 +35327,26 @@ ${ORIENTATION_BOOTSTRAP}`;
35083
35327
  if (n > 0) agent.drainInbox(n);
35084
35328
  surfaced = [];
35085
35329
  }
35330
+ function abandonSurfaced() {
35331
+ surfaced = [];
35332
+ }
35333
+ function injectIntoPrompt(output) {
35334
+ if (driving || awaitingTurnEnd) return;
35335
+ const items = agent.peekInbox();
35336
+ if (items.length === 0) return;
35337
+ const inj = formatInjection(items);
35338
+ if (!inj) return;
35339
+ const textPart = output.parts?.find(
35340
+ (p) => typeof p === "object" && p !== null && p.type === "text" && typeof p.text === "string"
35341
+ );
35342
+ if (!textPart) return;
35343
+ textPart.text = `${inj}
35344
+
35345
+ ${textPart.text}`;
35346
+ surfaced = items.map((i) => i.id);
35347
+ awaitingTurnEnd = true;
35348
+ busy = true;
35349
+ }
35086
35350
  function completeTurn() {
35087
35351
  if (!busy && !awaitingTurnEnd) return;
35088
35352
  busy = false;
@@ -35090,6 +35354,7 @@ ${ORIENTATION_BOOTSTRAP}`;
35090
35354
  awaitingTurnEnd = false;
35091
35355
  ackSurfaced();
35092
35356
  }
35357
+ clearErrorRetry(true);
35093
35358
  if (pendingForWake() > 0) void drive();
35094
35359
  }
35095
35360
  agent.on("incoming", (item) => {
@@ -35111,6 +35376,10 @@ ${ORIENTATION_BOOTSTRAP}`;
35111
35376
  };
35112
35377
  const hooks = {
35113
35378
  tool: buildCotalTools(agent, config2),
35379
+ "chat.message": async (input, output) => {
35380
+ if (!ours(input.sessionID)) return;
35381
+ injectIntoPrompt(output);
35382
+ },
35114
35383
  event: async ({ event }) => {
35115
35384
  if (event.type === "permission.asked") {
35116
35385
  const p = event.properties;
@@ -35121,11 +35390,21 @@ ${ORIENTATION_BOOTSTRAP}`;
35121
35390
  case "session.created":
35122
35391
  if (!event.properties.info.parentID) adoptSession(event.properties.info.id, "top-level session create");
35123
35392
  break;
35124
- case "session.idle":
35125
- if (!ours(event.properties.sessionID)) return;
35393
+ case "message.updated":
35394
+ if (transcript && ours(event.properties.info.sessionID)) transcript.record(event.properties.info);
35395
+ break;
35396
+ case "message.part.updated":
35397
+ if (transcript && ours(event.properties.part.sessionID)) transcript.observe(event.properties.part);
35398
+ break;
35399
+ case "session.idle": {
35400
+ const idleSession = event.properties.sessionID;
35401
+ if (!ours(idleSession)) return;
35126
35402
  await safeStatus("idle");
35403
+ if (transcript)
35404
+ await transcript.flush().catch((e) => log(`transcript mirror publish failed: ${e.message}`));
35127
35405
  completeTurn();
35128
35406
  break;
35407
+ }
35129
35408
  case "session.status": {
35130
35409
  if (!ours(event.properties.sessionID)) return;
35131
35410
  const s = event.properties.status;
@@ -35145,10 +35424,10 @@ ${ORIENTATION_BOOTSTRAP}`;
35145
35424
  busy = false;
35146
35425
  if (awaitingTurnEnd) {
35147
35426
  awaitingTurnEnd = false;
35148
- ackSurfaced();
35427
+ abandonSurfaced();
35149
35428
  }
35150
35429
  await safeStatus("idle");
35151
- if (pendingForWake() > 0) void drive();
35430
+ scheduleErrorRetry();
35152
35431
  break;
35153
35432
  case "session.deleted":
35154
35433
  if (!ours(event.properties.info.id)) return;
@@ -35162,7 +35441,12 @@ ${ORIENTATION_BOOTSTRAP}`;
35162
35441
  await safeStatus("working", input.tool);
35163
35442
  },
35164
35443
  dispose: async () => {
35444
+ try {
35445
+ controlServer?.close();
35446
+ } catch {
35447
+ }
35165
35448
  await safeStatus("offline");
35449
+ clearErrorRetry(true);
35166
35450
  await agent.stop();
35167
35451
  }
35168
35452
  };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAazD,eAAO,MAAM,KAAK,EAAE,MAuRnB,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAgBzD,eAAO,MAAM,KAAK,EAAE,MAqanB,CAAC"}
package/dist/plugin.js CHANGED
@@ -8,19 +8,19 @@
8
8
  * • registers the cotal_* tools natively, rendered from the SHARED {@link cotalToolSpecs}
9
9
  * (`./tools.ts`) — same surface as Claude Code, incl. channels / join / leave / channel_info;
10
10
  * • maps OpenCode bus events to presence (idle | working | waiting | offline);
11
- * • owns ONE session (created at boot) and drives it: it injects each inbox batch as a turn via the
12
- * prompt API (`session.promptAsync` server-side, so it can't race the TUI input box; the
13
- * attached TUI renders it live), acking ON TURN COMPLETION (so a crash/error redelivers).
14
- * Delivery is **attention-aware** (open/dnd/focus) and never interrupts a running turn a
15
- * message that arrives mid-turn waits for the turn to end (matching Claude's no-interrupt
16
- * behavior), then drives.
11
+ * • owns ONE session (created at boot) and drives it: it injects each inbox batch as a turn through
12
+ * the authenticated OpenCode server HTTP API (the same server the TUI is attached to), acking ON
13
+ * TURN COMPLETION (so a crash/error redelivers). Pending peer messages are also injected into
14
+ * the next native prompt creation when a human/API prompt starts in the attached session.
15
+ * Delivery is **attention-aware** (open/dnd/focus) and never interrupts a running turn.
17
16
  *
18
17
  * Identity comes from COTAL_* env (the plugin runs in the opencode process and inherits it).
19
18
  * No identity → inert, so an operator's own `opencode` never joins as a stray peer.
20
19
  */
21
20
  import { loadAgentFile } from "@cotal-ai/core";
22
- import { configFromEnv, hasIdentity, MeshAgent, formatInjection, fmtFrom, ORIENTATION_BOOTSTRAP, } from "@cotal-ai/connector-core";
21
+ import { configFromEnv, hasIdentity, MeshAgent, startControlServer, formatInjection, fmtFrom, ORIENTATION_BOOTSTRAP, transcriptChannel, } from "@cotal-ai/connector-core";
23
22
  import { buildCotalTools } from "./tools.js";
23
+ import { createTranscriptMirror } from "./transcript.js";
24
24
  function log(msg) {
25
25
  process.stderr.write(`[cotal-connector] ${msg}\n`);
26
26
  }
@@ -29,7 +29,9 @@ function log(msg) {
29
29
  * call wires up the agent, and every call returns the *same* hooks (the same tools, bound to that
30
30
  * one agent), whichever scope opencode ends up using. */
31
31
  const guard = globalThis;
32
- export const cotal = async ({ client }) => {
32
+ const ERROR_RETRY_INITIAL_MS = 1_000;
33
+ const ERROR_RETRY_MAX_MS = 30_000;
34
+ export const cotal = async () => {
33
35
  // No identity → a plain `opencode`, not a launcher-spawned agent. Stay inert.
34
36
  if (!hasIdentity()) {
35
37
  log("no COTAL_NAME — not a managed session; staying off the mesh");
@@ -39,8 +41,30 @@ export const cotal = async ({ client }) => {
39
41
  return guard.__cotalOpencodeHooks; // one agent; reuse the hooks
40
42
  const config = configFromEnv();
41
43
  config.connector = "opencode"; // advertise the host harness on our AgentCard (meta.connector)
44
+ const serverUrl = process.env.COTAL_OPENCODE_SERVER_URL?.trim();
45
+ const serverUsername = process.env.OPENCODE_SERVER_USERNAME?.trim() || "opencode";
46
+ const serverPassword = process.env.OPENCODE_SERVER_PASSWORD?.trim();
47
+ if (!serverUrl || !serverPassword)
48
+ throw new Error("opencode connector: missing COTAL_OPENCODE_SERVER_URL/OPENCODE_SERVER_PASSWORD");
49
+ const serverAuth = `Basic ${Buffer.from(`${serverUsername}:${serverPassword}`).toString("base64")}`;
42
50
  const agent = new MeshAgent(config);
43
51
  agent.start(); // background connect with retry — never blocks startup
52
+ async function opencodeApi(path, init, timeoutMs = 10_000) {
53
+ const res = await fetch(`${serverUrl}${path}`, {
54
+ ...init,
55
+ signal: init?.signal ?? AbortSignal.timeout(timeoutMs),
56
+ headers: {
57
+ authorization: serverAuth,
58
+ "content-type": "application/json",
59
+ ...(init?.headers ?? {}),
60
+ },
61
+ });
62
+ if (!res.ok)
63
+ throw new Error(`OpenCode HTTP ${res.status} ${res.statusText} for ${path}`);
64
+ if (res.status === 204)
65
+ return undefined;
66
+ return (await res.json());
67
+ }
44
68
  const def = process.env.COTAL_AGENT_FILE?.trim() ? loadAgentFile(process.env.COTAL_AGENT_FILE.trim()) : undefined;
45
69
  // Face-hosted (`face:` in the agent file → the shim attaches the face viewer): teach the agent
46
70
  // to steer its avatar's expression with inline [[face:X]] tags in the text it passes to the
@@ -67,11 +91,21 @@ export const cotal = async ({ client }) => {
67
91
  let sessionID;
68
92
  let busy = false; // a turn is running (ours via drive(), OR the human's via session.status) → don't
69
93
  // prompt: opencode would COALESCE onto it (no reject). Released at EVERY turn end (completeTurn).
70
- let driving = false; // re-entrancy guard around an in-flight promptAsync
94
+ let driving = false; // re-entrancy guard around an in-flight server prompt
71
95
  let primed = false; // persona is prepended to the first turn's text once
72
96
  let briefed = false; // the boot channel briefing is prepended once, on the first turn
73
97
  let surfaced = []; // ids surfaced into the current turn, acked on completion (by id, not count)
74
98
  let awaitingTurnEnd = false; // a turn is in flight → ignore a duplicate idle that isn't its end
99
+ let errorRetryTimer;
100
+ let errorRetryMs = ERROR_RETRY_INITIAL_MS;
101
+ // Transcript mirror → `tr-<name>`: opt-in via COTAL_TRANSCRIPT (the connector's buildLaunch / the
102
+ // manager set it for managed sessions; a personal opencode never mirrors). EVENT-DRIVEN — fed from
103
+ // the OpenCode event hook below (message.updated → assistant roles, message.part.updated → parts)
104
+ // and flushed at session.idle, so it never re-reads the whole session. The manager grants this agent
105
+ // pub rights on the same `tr-<name>` channel.
106
+ const transcript = /^(1|true|yes|on)$/i.test(process.env.COTAL_TRANSCRIPT ?? "")
107
+ ? createTranscriptMirror(agent, transcriptChannel(config.name))
108
+ : undefined;
75
109
  const safeStatus = async (status, activity) => {
76
110
  try {
77
111
  if (agent.connected)
@@ -81,9 +115,65 @@ export const cotal = async ({ client }) => {
81
115
  /* presence is best-effort — never throw into opencode */
82
116
  }
83
117
  };
118
+ // Cooperative shutdown. The manager sends an authenticated {op:"shutdown"} to this agent's local
119
+ // control endpoint on a signal-less runtime (ConPTY/Windows), where a hard kill would skip cleanup
120
+ // and leave the agent online until its presence TTL expires. We leave the mesh cleanly instead, then
121
+ // exit (the runtime hard-kills as a backstop). The endpoint (path + token) is minted by the
122
+ // connector's buildLaunch and arrives in the child env; the plugin runs inside the opencode server
123
+ // process, so it reads it there. Hooks are in-process (no external relay connects), so only the
124
+ // shutdown op is used — the handle path is inert. fatalBind: a managed agent MUST own its control
125
+ // endpoint, so a squatter (or a runtime that can't host the pipe) fails loud rather than running a
126
+ // hijacked or absent control plane.
127
+ let controlServer;
128
+ const shutdown = async () => {
129
+ try {
130
+ controlServer?.close();
131
+ }
132
+ catch {
133
+ /* ignore */
134
+ }
135
+ try {
136
+ await safeStatus("offline");
137
+ await agent.stop();
138
+ }
139
+ finally {
140
+ process.exit(0);
141
+ }
142
+ };
143
+ const controlPath = process.env.COTAL_CONTROL_SOCKET?.trim();
144
+ const controlToken = process.env.COTAL_CONTROL_TOKEN?.trim();
145
+ if (controlPath && controlToken) {
146
+ const handle = async () => ({
147
+ ok: false,
148
+ error: "opencode runs cotal hooks in-process; only the shutdown control op is supported",
149
+ });
150
+ controlServer = startControlServer(agent, { path: controlPath, token: controlToken }, handle, {
151
+ fatalBind: true,
152
+ onShutdown: () => void shutdown(),
153
+ });
154
+ }
84
155
  function pendingForWake() {
85
156
  return agent.pendingWake(); // mode-and-channel-aware: excludes held dnd/quiet ambient
86
157
  }
158
+ function clearErrorRetry(resetDelay = false) {
159
+ if (errorRetryTimer)
160
+ clearTimeout(errorRetryTimer);
161
+ errorRetryTimer = undefined;
162
+ if (resetDelay)
163
+ errorRetryMs = ERROR_RETRY_INITIAL_MS;
164
+ }
165
+ function scheduleErrorRetry() {
166
+ if (errorRetryTimer || pendingForWake() === 0)
167
+ return;
168
+ const delay = errorRetryMs;
169
+ errorRetryMs = Math.min(errorRetryMs * 2, ERROR_RETRY_MAX_MS);
170
+ errorRetryTimer = setTimeout(() => {
171
+ errorRetryTimer = undefined;
172
+ if (!busy && pendingForWake() > 0)
173
+ void drive();
174
+ }, delay);
175
+ errorRetryTimer.unref?.();
176
+ }
87
177
  function adoptSession(id, reason) {
88
178
  if (sessionID === id)
89
179
  return;
@@ -96,6 +186,8 @@ export const cotal = async ({ client }) => {
96
186
  briefed = false;
97
187
  surfaced = [];
98
188
  awaitingTurnEnd = false;
189
+ clearErrorRetry(true);
190
+ transcript?.reset(); // hard session boundary: drop any buffered parts so `/new` never mirrors them
99
191
  if (previous) {
100
192
  log(`adopted opencode session ${id} after ${reason}; mesh identity unchanged`);
101
193
  if (pendingForWake() > 0)
@@ -108,8 +200,11 @@ export const cotal = async ({ client }) => {
108
200
  * can't be picked. Awaited by ensureSession before the first drive. */
109
201
  const sessionReady = (async () => {
110
202
  try {
111
- const res = await client.session.create({ body: { title: `cotal:${config.space}:${config.name}` } });
112
- const id = res.data?.id;
203
+ const res = await opencodeApi("/session", {
204
+ method: "POST",
205
+ body: JSON.stringify({ title: `cotal:${config.space}:${config.name}` }),
206
+ }, 10_000);
207
+ const id = res.id;
113
208
  if (id) {
114
209
  adoptSession(id, "boot");
115
210
  process.stderr.write(`[cotal-session] ${id}\n`);
@@ -127,7 +222,7 @@ export const cotal = async ({ client }) => {
127
222
  return sessionID ?? (await sessionReady);
128
223
  }
129
224
  /** Drive a turn carrying the current inbox batch (and the boot briefing once) into the visible
130
- * session via the prompt API — server-side, so it can't race like the TUI input box, and the TUI
225
+ * session via the server API — server-side, so it can't race like the TUI input box, and the TUI
131
226
  * renders it live (it subscribes to that session's events). Surfaces the items but does NOT ack
132
227
  * them — ackSurfaced runs on turn completion, so a crash/error redelivers. `override` replaces
133
228
  * the body (a bare nudge, e.g. a focus @mention pull) and surfaces nothing to ack. Self-guards
@@ -171,10 +266,10 @@ export const cotal = async ({ client }) => {
171
266
  body.system = `${persona}\n\n${ORIENTATION_BOOTSTRAP}`;
172
267
  busy = true;
173
268
  surfaced = ids;
174
- // Arm BEFORE the await: a turn-end signal can land before promptAsync resolves, and
269
+ // Arm BEFORE the await: a turn-end signal can land before the server request resolves, and
175
270
  // completeTurn bails unless armed — arming after would drop it and wedge the agent.
176
271
  awaitingTurnEnd = true;
177
- await client.session.promptAsync({ path: { id }, body });
272
+ await opencodeApi(`/session/${encodeURIComponent(id)}/prompt_async`, { method: "POST", body: JSON.stringify(body) }, 10_000);
178
273
  primed = true;
179
274
  }
180
275
  catch (e) {
@@ -182,6 +277,7 @@ export const cotal = async ({ client }) => {
182
277
  surfaced = [];
183
278
  awaitingTurnEnd = false;
184
279
  log(`drive failed: ${e.message}`);
280
+ scheduleErrorRetry();
185
281
  }
186
282
  finally {
187
283
  driving = false;
@@ -203,6 +299,30 @@ export const cotal = async ({ client }) => {
203
299
  agent.drainInbox(n);
204
300
  surfaced = [];
205
301
  }
302
+ function abandonSurfaced() {
303
+ surfaced = [];
304
+ }
305
+ /** Native TUI / API prompts enter through OpenCode's chat.message hook before the model loop
306
+ * starts. This is the real "next turn" boundary for human-typed input: prepend the buffered Cotal
307
+ * batch to the user's text, then ack it when the resulting turn ends. We only mutate an existing
308
+ * text part so we don't need to manufacture OpenCode's internal part IDs. */
309
+ function injectIntoPrompt(output) {
310
+ if (driving || awaitingTurnEnd)
311
+ return; // drive() already injected, or one surfaced batch is open
312
+ const items = agent.peekInbox();
313
+ if (items.length === 0)
314
+ return;
315
+ const inj = formatInjection(items);
316
+ if (!inj)
317
+ return;
318
+ const textPart = output.parts?.find((p) => typeof p === "object" && p !== null && p.type === "text" && typeof p.text === "string");
319
+ if (!textPart)
320
+ return;
321
+ textPart.text = `${inj}\n\n${textPart.text}`;
322
+ surfaced = items.map((i) => i.id);
323
+ awaitingTurnEnd = true;
324
+ busy = true;
325
+ }
206
326
  /** A turn ended — ANY turn, ours (a driven inbox batch) OR the human's (typing into the attached
207
327
  * TUI, a `/reconnect`, etc). Clear `busy` regardless of who drove it: it's the COALESCE guard, so
208
328
  * a turn the connector didn't drive must still release it or every later push wedges behind a
@@ -218,6 +338,7 @@ export const cotal = async ({ client }) => {
218
338
  awaitingTurnEnd = false;
219
339
  ackSurfaced(); // our driven turn: ack the surfaced batch (the sole ack site)
220
340
  }
341
+ clearErrorRetry(true);
221
342
  if (pendingForWake() > 0)
222
343
  void drive();
223
344
  }
@@ -228,7 +349,7 @@ export const cotal = async ({ client }) => {
228
349
  // (ack-dropped at ingest); in `focus`, ambient/@mentions never reach "incoming" either.
229
350
  agent.on("incoming", (item) => {
230
351
  if (busy)
231
- return; // buffer; completeTurn drives at turn end
352
+ return; // buffer; chat.message or completeTurn drives at the next safe boundary
232
353
  const directed = item.kind !== "channel" || item.mentionsMe;
233
354
  const quiet = item.kind === "channel" && agent.channelMode(item.channel) === "quiet";
234
355
  if (directed || (!quiet && agent.attention === "open"))
@@ -254,6 +375,11 @@ export const cotal = async ({ client }) => {
254
375
  };
255
376
  const hooks = {
256
377
  tool: buildCotalTools(agent, config),
378
+ "chat.message": async (input, output) => {
379
+ if (!ours(input.sessionID))
380
+ return;
381
+ injectIntoPrompt(output);
382
+ },
257
383
  event: async ({ event }) => {
258
384
  // The server emits `permission.asked` (the SDK's `permission.updated` type ships but never
259
385
  // fires — #11616), so match the real runtime name out of band. With permission:"allow" this
@@ -271,12 +397,29 @@ export const cotal = async ({ client }) => {
271
397
  if (!event.properties.info.parentID)
272
398
  adoptSession(event.properties.info.id, "top-level session create");
273
399
  break;
274
- case "session.idle":
275
- if (!ours(event.properties.sessionID))
400
+ case "message.updated":
401
+ // Feed the transcript mirror: which messages on OUR session are assistant-authored.
402
+ if (transcript && ours(event.properties.info.sessionID))
403
+ transcript.record(event.properties.info);
404
+ break;
405
+ case "message.part.updated":
406
+ // Feed the transcript mirror: buffer each part as it streams (no per-turn refetch).
407
+ if (transcript && ours(event.properties.part.sessionID))
408
+ transcript.observe(event.properties.part);
409
+ break;
410
+ case "session.idle": {
411
+ const idleSession = event.properties.sessionID;
412
+ if (!ours(idleSession))
276
413
  return;
277
414
  await safeStatus("idle");
415
+ // Publish what the agent did this turn BEFORE driving the next batch, so a fresh turn's parts
416
+ // don't bleed in. The mirror is an observability side-channel: surface a publish failure but
417
+ // keep it OFF the turn loop, so a transport hiccup can never wedge the agent.
418
+ if (transcript)
419
+ await transcript.flush().catch((e) => log(`transcript mirror publish failed: ${e.message}`));
278
420
  completeTurn(); // the sole turn-end site: ack-on-surface + drive the next batch
279
421
  break;
422
+ }
280
423
  case "session.status": {
281
424
  if (!ours(event.properties.sessionID))
282
425
  return;
@@ -305,11 +448,10 @@ export const cotal = async ({ client }) => {
305
448
  busy = false;
306
449
  if (awaitingTurnEnd) {
307
450
  awaitingTurnEnd = false;
308
- ackSurfaced(); // our turn surfaced the batch but failed ack (don't retry-loop) and move on
451
+ abandonSurfaced(); // failed turn: leave inbox unacked so the batch can retry on a later safe turn
309
452
  }
310
453
  await safeStatus("idle");
311
- if (pendingForWake() > 0)
312
- void drive();
454
+ scheduleErrorRetry();
313
455
  break;
314
456
  case "session.deleted":
315
457
  if (!ours(event.properties.info.id))
@@ -325,7 +467,14 @@ export const cotal = async ({ client }) => {
325
467
  await safeStatus("working", input.tool);
326
468
  },
327
469
  dispose: async () => {
470
+ try {
471
+ controlServer?.close();
472
+ }
473
+ catch {
474
+ /* ignore */
475
+ }
328
476
  await safeStatus("offline");
477
+ clearErrorRetry(true);
329
478
  await agent.stop();
330
479
  },
331
480
  };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/dist/serve.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * 2. poke it once so the lazily-loaded plugin initializes (joins the mesh, creates ONE session);
7
7
  * 3. the plugin announces that session's id on stderr (`[cotal-session] <id>`);
8
8
  * 4. launch a foreground `opencode attach <url> --session <id>` — the TUI opens straight onto the
9
- * agent's session, and every turn the plugin drives (via `session.promptAsync`) renders live.
9
+ * agent's session, and every turn the plugin drives through this exact server renders live.
10
10
  *
11
11
  * The attach TUI is a pure viewer (it connects to the running server); its env strips the plugin
12
12
  * config + COTAL_* so it never loads a *second* mesh endpoint.
@@ -22,8 +22,30 @@ import { createServer } from "node:net";
22
22
  import { once } from "node:events";
23
23
  import { randomBytes } from "node:crypto";
24
24
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
25
- import { join } from "node:path";
26
- const BIN = process.env.COTAL_OPENCODE_BIN?.trim() || "opencode";
25
+ import { delimiter, join } from "node:path";
26
+ /** The opencode binary to spawn. `COTAL_OPENCODE_BIN` overrides. On Windows, `opencode` on PATH is
27
+ * an npm `.cmd` shim that child_process can't spawn, and the real `opencode.exe` it wraps
28
+ * (`<bindir>/node_modules/opencode-ai/bin/opencode.exe`) isn't itself on PATH — resolve and spawn
29
+ * it directly, so there's no `cmd.exe` wrapper to orphan the server on kill. POSIX spawns the name
30
+ * as-is. Unresolved on Windows → returns the bare name so spawn fails with a clear ENOENT. */
31
+ function resolveOpencodeBin() {
32
+ const override = process.env.COTAL_OPENCODE_BIN?.trim();
33
+ if (override)
34
+ return override;
35
+ if (process.platform !== "win32")
36
+ return "opencode";
37
+ for (const dir of (process.env.PATH ?? "").split(delimiter)) {
38
+ if (!dir)
39
+ continue;
40
+ for (const exe of [join(dir, "opencode.exe"), join(dir, "node_modules", "opencode-ai", "bin", "opencode.exe")]) {
41
+ if (existsSync(exe))
42
+ return exe;
43
+ }
44
+ }
45
+ return "opencode";
46
+ }
47
+ const BIN = resolveOpencodeBin();
48
+ const USERNAME = "opencode";
27
49
  /** Per-launch secret gating the spawned server's HTTP API (see SECURITY above). */
28
50
  const SECRET = randomBytes(24).toString("hex");
29
51
  /** Ask the OS for a free port (bind :0, read it, release) so co-located peers don't collide. */
@@ -82,7 +104,13 @@ async function main() {
82
104
  }
83
105
  mkdirSync(agentHome, { recursive: true });
84
106
  const serve = spawn(BIN, ["serve", "--hostname", "127.0.0.1", "--port", port], {
85
- env: { ...process.env, OPENCODE_SERVER_PASSWORD: SECRET, OPENCODE_DB: dbPath },
107
+ env: {
108
+ ...process.env,
109
+ COTAL_OPENCODE_SERVER_URL: url,
110
+ OPENCODE_SERVER_USERNAME: USERNAME,
111
+ OPENCODE_SERVER_PASSWORD: SECRET,
112
+ OPENCODE_DB: dbPath,
113
+ },
86
114
  stdio: ["ignore", "pipe", "pipe"],
87
115
  });
88
116
  writeFileSync(pidFile, String(serve.pid));
@@ -115,7 +143,7 @@ async function main() {
115
143
  // bootstrap that loads the plugin. Each poke carries its own abort timeout: a request that
116
144
  // lands in the early-boot window can hang with no response, and an un-timed fetch would pin
117
145
  // the loop on it forever (undici queues later requests behind it on the pooled connection).
118
- const auth = `Basic ${Buffer.from(`opencode:${SECRET}`).toString("base64")}`;
146
+ const auth = `Basic ${Buffer.from(`${USERNAME}:${SECRET}`).toString("base64")}`;
119
147
  void (async () => {
120
148
  for (let i = 0; i < 300 && !sessionId; i++) {
121
149
  try {
@@ -139,8 +167,20 @@ async function main() {
139
167
  await killServe(serve);
140
168
  process.exit(1);
141
169
  }
170
+ // Headless mode (COTAL_SERVE_HEADLESS=1): no foreground TUI. Hand the running server back to a
171
+ // non-terminal host (a web studio, an automated harness) via one machine-readable handshake line
172
+ // on stdout, then keep the serve alive. The host drives the session over HTTP (basic auth with the
173
+ // password below) and tails its event stream. `attached` stays false, so the `serve.on("exit")`
174
+ // handler above still exits us if the server dies; SIGTERM tears the server down for real.
175
+ if (process.env.COTAL_SERVE_HEADLESS?.trim() === "1") {
176
+ process.stdout.write(`[cotal-serve] ${JSON.stringify({ port: Number(port), session: id, password: SECRET })}\n`);
177
+ for (const sig of ["SIGINT", "SIGTERM"])
178
+ process.on(sig, () => void killServe(serve).then(() => process.exit(0)));
179
+ return;
180
+ }
142
181
  const tuiEnv = {
143
182
  ...process.env,
183
+ OPENCODE_SERVER_USERNAME: USERNAME,
144
184
  OPENCODE_SERVER_PASSWORD: SECRET,
145
185
  OPENCODE_DB: dbPath,
146
186
  };
package/dist/serve.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC;AAEjE,mFAAmF;AACnF,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE/C,gGAAgG;AAChG,KAAK,UAAU,QAAQ;IACrB,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3B,MAAM,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAI,GAAG,CAAC,OAAO,EAAuB,CAAC,IAAI,CAAC;IACtD,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;sGACsG;AACtG,KAAK,UAAU,SAAS,CAAC,KAAmB;IAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO;IACjE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QACpC,IAAI,OAAO,CAAU,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;KAC9D,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;IACvC,8FAA8F;IAC9F,0FAA0F;IAC1F,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC;IACvD,mGAAmG;IACnG,kGAAkG;IAClG,sEAAsE;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAChH,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAE9C,2FAA2F;IAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,4CAA4C,GAAG,mBAAmB,CAAC,CAAC;QAC7G,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QAC7E,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,wBAAwB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;QAC9E,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEzD,+FAA+F;IAC/F,mGAAmG;IACnG,IAAI,SAA6B,CAAC;IAClC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,SAA6C,CAAC;IAClD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAQ,EAAE;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACxD,IAAI,CAAC,EAAE,CAAC;gBACN,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjB,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B;IACvF,CAAC,CAAC,CAAC;IAEH,6FAA6F;IAC7F,8FAA8F;IAC9F,+FAA+F;IAC/F,2FAA2F;IAC3F,4FAA4F;IAC5F,4FAA4F;IAC5F,MAAM,IAAI,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC7E,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzG,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;YACnF,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,oEAAoE;IACpE,MAAM,EAAE,GAAG,MAAM,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QAC3D,IAAI,SAAS;YAAE,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,SAAS,GAAG,OAAO,CAAC;QACpB,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wIAAwI,MAAM,KAAK,CACpJ,CAAC;QACF,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAsB;QAChC,GAAG,OAAO,CAAC,GAAG;QACd,wBAAwB,EAAE,MAAM;QAChC,WAAW,EAAE,MAAM;KACpB,CAAC;IACF,OAAO,MAAM,CAAC,uBAAuB,CAAC,CAAC,wDAAwD;IAC/F,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAClF,QAAQ,GAAG,IAAI,CAAC;IAChB,yFAAyF;IACzF,qFAAqF;IACrF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,0DAA0D;QAClF,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,WAAW;QAC7B,CAAC,CAAC;YACE,OAAO,CAAC,QAAQ;YAChB,CAAC,OAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC;SAC7F;QACH,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QAC3B,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU;QAC9C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE;YACnB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAC9B,kFAAkF;QAClF,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;+FAI+F;AAC/F,SAAS,kBAAkB;IACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACxD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,UAAU,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YAC/G,IAAI,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;AACjC,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B,mFAAmF;AACnF,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE/C,gGAAgG;AAChG,KAAK,UAAU,QAAQ;IACrB,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3B,MAAM,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAI,GAAG,CAAC,OAAO,EAAuB,CAAC,IAAI,CAAC;IACtD,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;sGACsG;AACtG,KAAK,UAAU,SAAS,CAAC,KAAmB;IAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO;IACjE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QACpC,IAAI,OAAO,CAAU,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;KAC9D,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;IACvC,8FAA8F;IAC9F,0FAA0F;IAC1F,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC;IACvD,mGAAmG;IACnG,kGAAkG;IAClG,sEAAsE;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAChH,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAE9C,2FAA2F;IAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,4CAA4C,GAAG,mBAAmB,CAAC,CAAC;QAC7G,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QAC7E,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,yBAAyB,EAAE,GAAG;YAC9B,wBAAwB,EAAE,QAAQ;YAClC,wBAAwB,EAAE,MAAM;YAChC,WAAW,EAAE,MAAM;SACpB;QACD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEzD,+FAA+F;IAC/F,mGAAmG;IACnG,IAAI,SAA6B,CAAC;IAClC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,SAA6C,CAAC;IAClD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAQ,EAAE;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACxD,IAAI,CAAC,EAAE,CAAC;gBACN,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjB,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B;IACvF,CAAC,CAAC,CAAC;IAEH,6FAA6F;IAC7F,8FAA8F;IAC9F,+FAA+F;IAC/F,2FAA2F;IAC3F,4FAA4F;IAC5F,4FAA4F;IAC5F,MAAM,IAAI,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChF,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzG,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;YACnF,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,oEAAoE;IACpE,MAAM,EAAE,GAAG,MAAM,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QAC3D,IAAI,SAAS;YAAE,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,SAAS,GAAG,OAAO,CAAC;QACpB,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wIAAwI,MAAM,KAAK,CACpJ,CAAC;QACF,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,+FAA+F;IAC/F,iGAAiG;IACjG,mGAAmG;IACnG,gGAAgG;IAChG,2FAA2F;IAC3F,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACjH,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU;YAC9C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAsB;QAChC,GAAG,OAAO,CAAC,GAAG;QACd,wBAAwB,EAAE,QAAQ;QAClC,wBAAwB,EAAE,MAAM;QAChC,WAAW,EAAE,MAAM;KACpB,CAAC;IACF,OAAO,MAAM,CAAC,uBAAuB,CAAC,CAAC,wDAAwD;IAC/F,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAClF,QAAQ,GAAG,IAAI,CAAC;IAChB,yFAAyF;IACzF,qFAAqF;IACrF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,0DAA0D;QAClF,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,WAAW;QAC7B,CAAC,CAAC;YACE,OAAO,CAAC,QAAQ;YAChB,CAAC,OAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC;SAC7F;QACH,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QAC3B,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU;QAC9C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE;YACnB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAC9B,kFAAkF;QAClF,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * OpenCode transcript mirror — publishes the agent's OWN session output to the per-agent `tr-<name>`
3
+ * channel (assistant text in full, tool calls as one-liners, tool results truncated, reasoning
4
+ * omitted) so observers can read what an OpenCode agent ACTUALLY did — not only what it narrates on
5
+ * the work channels (the Claude connector has had this; OpenCode did not).
6
+ *
7
+ * EVENT-DRIVEN, not poll-based. The connector plugin already receives OpenCode's bus events
8
+ * in-process, so the mirror taps them (the same live stream the frontier-faces studio proxies to its
9
+ * browser, instead of re-reading the session each frame):
10
+ * • record(msg) ← message.updated: learn which messageIDs are ASSISTANT (mirror the agent's
11
+ * own output, never the injected user/peer turns).
12
+ * • observe(part) ← message.part.updated: condense the part NOW and buffer its lines (tool results
13
+ * truncated to a preview, assistant text kept in full;
14
+ * keyed by `${messageID}:${partID}`, replaced as it streams).
15
+ * • flush() ← session.idle: publish the turn's settled assistant lines, then clear.
16
+ * • reset() ← session adoption: drop the buffer at a hard boundary (`/new`).
17
+ * Cost is O(parts-this-turn) with NO HTTP — unlike a fetch-the-whole-session-every-idle poll, which is
18
+ * O(N²) and grows unboundedly over a long session. flush() snapshots the turn's lines and clears before
19
+ * it publishes, so a duplicate/late session.idle can't republish the batch.
20
+ *
21
+ * Each turn's lines are published ONCE to the channel; DURABLE delivery (persistence, replay to offline
22
+ * readers) is the channel's job — a durable `tr-<name>` is JetStream-backed — not a hand-rolled retry
23
+ * buffer here. This mirror is therefore best-effort at the publish boundary: the plugin runs flush() on
24
+ * the turn-end path and keeps a transport error OFF the turn loop by logging it (so a failed publish can
25
+ * never wedge the agent) — which means a publish that fails outright drops THAT turn's lines. That is
26
+ * the deliberate tradeoff for an opt-in observability side-channel; it is logged, never silent.
27
+ */
28
+ import type { MeshAgent } from "@cotal-ai/connector-core";
29
+ export interface TranscriptMirror {
30
+ /** message.updated → remember which messageIDs are assistant-authored (this turn). */
31
+ record(message: any): void;
32
+ /** message.part.updated → condense the part and buffer its lines (tool results truncated, assistant
33
+ * text kept full; keyed by `${messageID}:${partID}`, this turn). */
34
+ observe(part: any): void;
35
+ /** session.idle → publish the turn's settled assistant lines to the channel, then clear. */
36
+ flush(): Promise<void>;
37
+ /** session adoption (`/new`) → drop the buffer so a new session never inherits stale parts. */
38
+ reset(): void;
39
+ }
40
+ /** An event-driven mirror to `channel`, fed from the plugin's OpenCode event hook. */
41
+ export declare function createTranscriptMirror(agent: MeshAgent, channel: string): TranscriptMirror;
42
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AA8D1D,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IAC3B;yEACqE;IACrE,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACzB,4FAA4F;IAC5F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,+FAA+F;IAC/F,KAAK,IAAI,IAAI,CAAC;CACf;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAyC1F"}
@@ -0,0 +1,107 @@
1
+ const MAX_PREVIEW = 700; // tool results — enough to see what happened
2
+ const MAX_CHUNK = 6000; // chars per published message
3
+ function truncate(s, max) {
4
+ return s.length > max ? `${s.slice(0, max - 1)}…` : s;
5
+ }
6
+ /** A tool call's most salient input — mirrors the Claude connector's `salient`. */
7
+ function salient(input) {
8
+ const i = (input ?? {});
9
+ const v = i.command ?? i.filePath ?? i.file_path ?? i.path ?? i.url ?? i.pattern ?? i.description;
10
+ const s = typeof v === "string" ? v : Object.keys(i).length ? JSON.stringify(i) : "";
11
+ return s ? `: ${truncate(s, 300)}` : "";
12
+ }
13
+ /** One OpenCode message Part → the line(s) worth mirroring (empty for reasoning/file/step/etc). */
14
+ function condensePart(part) {
15
+ switch (part?.type) {
16
+ case "text":
17
+ if (part.synthetic || part.ignored || !part.text?.trim())
18
+ return [];
19
+ return [part.text.trim()]; // assistant text in FULL — chunkLines splits it across messages
20
+ case "tool": {
21
+ const head = `⚒ ${part.tool}${salient(part.state?.input)}`;
22
+ const status = part.state?.status;
23
+ if (status === "completed")
24
+ return [head, `→ ${truncate(String(part.state.output ?? ""), MAX_PREVIEW) || "(no output)"}`];
25
+ if (status === "error")
26
+ return [head, `→ ERROR: ${truncate(String(part.state.error ?? ""), MAX_PREVIEW)}`];
27
+ return [head];
28
+ }
29
+ default:
30
+ return []; // reasoning (thinking) omitted; file/step/snapshot/patch skipped
31
+ }
32
+ }
33
+ /** Batch lines into wire-sized chunks, splitting on line boundaries — and hard-splitting any single
34
+ * line longer than `max` (e.g. a long assistant answer/code block) so full text is preserved across
35
+ * messages rather than truncated. */
36
+ function chunkLines(lines, max) {
37
+ const chunks = [];
38
+ let cur = "";
39
+ for (const ln of lines) {
40
+ if (ln.length > max) {
41
+ if (cur) {
42
+ chunks.push(cur);
43
+ cur = "";
44
+ }
45
+ for (let i = 0; i < ln.length; i += max)
46
+ chunks.push(ln.slice(i, i + max));
47
+ continue;
48
+ }
49
+ if (cur && cur.length + ln.length + 1 > max) {
50
+ chunks.push(cur);
51
+ cur = "";
52
+ }
53
+ cur = cur ? `${cur}\n${ln}` : ln;
54
+ }
55
+ if (cur)
56
+ chunks.push(cur);
57
+ return chunks;
58
+ }
59
+ /** An event-driven mirror to `channel`, fed from the plugin's OpenCode event hook. */
60
+ export function createTranscriptMirror(agent, channel) {
61
+ // One turn's worth, cleared every flush. `condensed` keeps each part's already-condensed lines (not
62
+ // the raw part) — tool results truncated to a preview, assistant text kept in full — so noisy tool
63
+ // output never sits in memory at full size. Map insertion order preserves emission order (a later
64
+ // .updated replaces the value, keeping its slot).
65
+ const assistantMsgs = new Set(); // messageIDs whose role is "assistant"
66
+ // Keyed by `${messageID}:${partID}` (NOT partID alone): OpenCode part ids are message-scoped, so a
67
+ // multi-message turn could otherwise collide two parts on the same id and drop output.
68
+ const condensed = new Map();
69
+ const clear = () => {
70
+ condensed.clear();
71
+ assistantMsgs.clear();
72
+ };
73
+ return {
74
+ record(message) {
75
+ const info = message?.info ?? message;
76
+ if (info?.role === "assistant" && typeof info.id === "string")
77
+ assistantMsgs.add(info.id);
78
+ },
79
+ observe(part) {
80
+ if (!part?.id || typeof part.messageID !== "string")
81
+ return;
82
+ const key = `${part.messageID}:${part.id}`;
83
+ const lines = condensePart(part); // condense NOW (tool results truncated) → assistant text kept full
84
+ if (lines.length)
85
+ condensed.set(key, { messageID: part.messageID, lines });
86
+ else
87
+ condensed.delete(key); // a part that condensed to nothing (e.g. reasoning) holds no slot
88
+ },
89
+ async flush() {
90
+ // Collect this turn's assistant lines and clear — each turn's output is published ONCE, then
91
+ // forgotten. Snapshot-then-clear before the await means a duplicate/late session.idle finds an
92
+ // empty buffer and can't republish. Delivery reliability is the CHANNEL's job (NATS/JetStream),
93
+ // not a hand-rolled retry buffer here.
94
+ const lines = [];
95
+ for (const { messageID, lines: ls } of condensed.values())
96
+ if (assistantMsgs.has(messageID))
97
+ lines.push(...ls); // the agent's OWN output, not injected turns
98
+ clear();
99
+ for (const chunk of chunkLines(lines, MAX_CHUNK))
100
+ await agent.send(chunk, channel);
101
+ },
102
+ reset() {
103
+ clear();
104
+ },
105
+ };
106
+ }
107
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cotal-ai/connector-opencode",
3
3
  "description": "Cotal connector for OpenCode: a native in-process plugin that joins a session to the mesh.",
4
- "version": "0.8.1",
4
+ "version": "0.8.3",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -18,7 +18,7 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@cotal-ai/connector-core": "0.8.1"
21
+ "@cotal-ai/connector-core": "0.8.3"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "@cotal-ai/core": ">=0.1.0",
@@ -30,7 +30,7 @@
30
30
  "@opencode-ai/sdk": "^1.16.2",
31
31
  "esbuild": "^0.28.0",
32
32
  "tsx": "^4.22.4",
33
- "@cotal-ai/core": "0.8.1"
33
+ "@cotal-ai/core": "0.8.3"
34
34
  },
35
35
  "files": [
36
36
  "dist"