opencode-gateway 0.2.9 → 0.2.10

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.
package/README.md CHANGED
@@ -28,10 +28,22 @@ Check what it resolved:
28
28
  npx opencode-gateway doctor
29
29
  ```
30
30
 
31
- Then start OpenCode normally:
31
+ Recommended:
32
+
33
+ ```bash
34
+ opencode-gateway serve
35
+ ```
36
+
37
+ This wraps `opencode serve` and warms the gateway plugin worker immediately, so
38
+ Telegram polling and scheduled jobs do not stay idle until the first
39
+ project-scoped request.
40
+
41
+ If you still prefer the raw OpenCode command, warm the gateway explicitly after
42
+ startup:
32
43
 
33
44
  ```bash
34
45
  opencode serve
46
+ opencode-gateway warm
35
47
  ```
36
48
 
37
49
  If you want a separate managed config tree instead of editing your existing
@@ -39,9 +51,7 @@ OpenCode config:
39
51
 
40
52
  ```bash
41
53
  npx opencode-gateway init --managed
42
- export OPENCODE_CONFIG="$HOME/.config/opencode-gateway/opencode/opencode.json"
43
- export OPENCODE_CONFIG_DIR="$HOME/.config/opencode-gateway/opencode"
44
- opencode serve
54
+ opencode-gateway serve --managed
45
55
  ```
46
56
 
47
57
  ## Example gateway config
@@ -1,7 +1,7 @@
1
1
  export type CliCommand = {
2
2
  kind: "help";
3
3
  } | {
4
- kind: "init" | "doctor";
4
+ kind: "init" | "doctor" | "serve" | "warm";
5
5
  managed: boolean;
6
6
  configDir: string | null;
7
7
  };
@@ -0,0 +1,19 @@
1
+ type CliOptions = {
2
+ managed: boolean;
3
+ configDir: string | null;
4
+ };
5
+ export type ResolvedServeTarget = {
6
+ configDir: string;
7
+ gatewayConfigPath: string;
8
+ workspaceDirPath: string;
9
+ opencodeConfigPath: string;
10
+ serverOrigin: string;
11
+ env: Record<string, string>;
12
+ };
13
+ export declare function resolveServeTarget(options: CliOptions, env: Record<string, string | undefined>): Promise<ResolvedServeTarget>;
14
+ export declare function warmGatewayProject(target: ResolvedServeTarget, options?: {
15
+ deadlineMs?: number;
16
+ intervalMs?: number;
17
+ }): Promise<void>;
18
+ export declare function resolveServerOriginFromDocument(document: Record<string, unknown>): string;
19
+ export {};
@@ -0,0 +1,6 @@
1
+ type ServeOptions = {
2
+ managed: boolean;
3
+ configDir: string | null;
4
+ };
5
+ export declare function runServe(options: ServeOptions, env: Record<string, string | undefined>): Promise<void>;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ type WarmOptions = {
2
+ managed: boolean;
3
+ configDir: string | null;
4
+ };
5
+ export declare function runWarm(options: WarmOptions, env: Record<string, string | undefined>): Promise<void>;
6
+ export {};
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ function parseCliCommand(argv) {
7
7
  if (!command || command === "help" || command === "--help" || command === "-h") {
8
8
  return { kind: "help" };
9
9
  }
10
- if (command !== "init" && command !== "doctor") {
10
+ if (command !== "init" && command !== "doctor" && command !== "serve" && command !== "warm") {
11
11
  throw new Error(`unknown command: ${command}`);
12
12
  }
13
13
  let managed = false;
@@ -48,6 +48,8 @@ function formatCliHelp() {
48
48
  "Commands:",
49
49
  " opencode-gateway init [--managed] [--config-dir <path>]",
50
50
  " opencode-gateway doctor [--managed] [--config-dir <path>]",
51
+ " opencode-gateway warm [--managed] [--config-dir <path>]",
52
+ " opencode-gateway serve [--managed] [--config-dir <path>]",
51
53
  "",
52
54
  "Defaults:",
53
55
  " init/doctor use OPENCODE_CONFIG_DIR when set, otherwise ~/.config/opencode",
@@ -57,42 +59,7 @@ function formatCliHelp() {
57
59
  }
58
60
 
59
61
  // src/cli/doctor.ts
60
- import { readFile } from "node:fs/promises";
61
- import { join as join3 } from "node:path";
62
-
63
- // src/config/paths.ts
64
- import { homedir } from "node:os";
65
- import { dirname, join, resolve as resolve2 } from "node:path";
66
- var GATEWAY_CONFIG_FILE = "opencode-gateway.toml";
67
- var OPENCODE_CONFIG_FILE = "opencode.json";
68
- var OPENCODE_CONFIG_FILE_JSONC = "opencode.jsonc";
69
- var OPENCODE_CONFIG_FILE_CANDIDATES = [OPENCODE_CONFIG_FILE_JSONC, OPENCODE_CONFIG_FILE];
70
- var GATEWAY_WORKSPACE_DIR = "opencode-gateway-workspace";
71
- function resolveOpencodeConfigDir(env) {
72
- const explicit = env.OPENCODE_CONFIG_DIR;
73
- if (explicit && explicit.trim().length > 0) {
74
- return resolve2(explicit);
75
- }
76
- return defaultOpencodeConfigDir(env);
77
- }
78
- function resolveManagedOpencodeConfigDir(env) {
79
- return join(resolveConfigHome(env), "opencode-gateway", "opencode");
80
- }
81
- function resolveGatewayWorkspacePath(configPath) {
82
- return join(dirname(configPath), GATEWAY_WORKSPACE_DIR);
83
- }
84
- function defaultGatewayStateDbPath(env) {
85
- return join(resolveDataHome(env), "opencode-gateway", "state.db");
86
- }
87
- function resolveConfigHome(env) {
88
- return env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
89
- }
90
- function resolveDataHome(env) {
91
- return env.XDG_DATA_HOME ?? join(homedir(), ".local", "share");
92
- }
93
- function defaultOpencodeConfigDir(env) {
94
- return join(resolveConfigHome(env), "opencode");
95
- }
62
+ import { readFile as readFile2 } from "node:fs/promises";
96
63
 
97
64
  // src/cli/opencode-config.ts
98
65
  var OPENCODE_SCHEMA_URL = "https://opencode.ai/config.json";
@@ -290,6 +257,47 @@ function isGatewayPluginReference(entry) {
290
257
  // src/cli/opencode-config-file.ts
291
258
  import { join as join2 } from "node:path";
292
259
 
260
+ // src/config/paths.ts
261
+ import { homedir } from "node:os";
262
+ import { dirname, join, resolve as resolve2 } from "node:path";
263
+ var GATEWAY_CONFIG_FILE = "opencode-gateway.toml";
264
+ var OPENCODE_CONFIG_FILE = "opencode.json";
265
+ var OPENCODE_CONFIG_FILE_JSONC = "opencode.jsonc";
266
+ var OPENCODE_CONFIG_FILE_CANDIDATES = [OPENCODE_CONFIG_FILE_JSONC, OPENCODE_CONFIG_FILE];
267
+ var GATEWAY_WORKSPACE_DIR = "opencode-gateway-workspace";
268
+ function resolveGatewayConfigPath(env) {
269
+ const explicit = env.OPENCODE_GATEWAY_CONFIG;
270
+ if (explicit && explicit.trim().length > 0) {
271
+ return resolve2(explicit);
272
+ }
273
+ return join(resolveOpencodeConfigDir(env), GATEWAY_CONFIG_FILE);
274
+ }
275
+ function resolveOpencodeConfigDir(env) {
276
+ const explicit = env.OPENCODE_CONFIG_DIR;
277
+ if (explicit && explicit.trim().length > 0) {
278
+ return resolve2(explicit);
279
+ }
280
+ return defaultOpencodeConfigDir(env);
281
+ }
282
+ function resolveManagedOpencodeConfigDir(env) {
283
+ return join(resolveConfigHome(env), "opencode-gateway", "opencode");
284
+ }
285
+ function resolveGatewayWorkspacePath(configPath) {
286
+ return join(dirname(configPath), GATEWAY_WORKSPACE_DIR);
287
+ }
288
+ function defaultGatewayStateDbPath(env) {
289
+ return join(resolveDataHome(env), "opencode-gateway", "state.db");
290
+ }
291
+ function resolveConfigHome(env) {
292
+ return env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
293
+ }
294
+ function resolveDataHome(env) {
295
+ return env.XDG_DATA_HOME ?? join(homedir(), ".local", "share");
296
+ }
297
+ function defaultOpencodeConfigDir(env) {
298
+ return join(resolveConfigHome(env), "opencode");
299
+ }
300
+
293
301
  // src/cli/paths.ts
294
302
  import { constants } from "node:fs";
295
303
  import { access } from "node:fs/promises";
@@ -329,19 +337,106 @@ async function resolveOpencodeConfigFile(configDir) {
329
337
  };
330
338
  }
331
339
 
340
+ // src/cli/opencode-server.ts
341
+ import { readFile } from "node:fs/promises";
342
+ var DEFAULT_SERVER_ORIGIN = "http://127.0.0.1:4096";
343
+ var WARM_REQUEST_TIMEOUT_MS = 2000;
344
+ async function resolveServeTarget(options, env) {
345
+ const configDir = resolveCliConfigDir(options, env);
346
+ const gatewayConfigPath = resolveGatewayConfigPath({
347
+ ...env,
348
+ OPENCODE_CONFIG_DIR: configDir
349
+ });
350
+ const workspaceDirPath = resolveGatewayWorkspacePath(gatewayConfigPath);
351
+ const opencodeConfig = await resolveOpencodeConfigFile(configDir);
352
+ const serverOrigin = opencodeConfig.exists ? await resolveServerOrigin(opencodeConfig.path) : DEFAULT_SERVER_ORIGIN;
353
+ return {
354
+ configDir,
355
+ gatewayConfigPath,
356
+ workspaceDirPath,
357
+ opencodeConfigPath: opencodeConfig.path,
358
+ serverOrigin,
359
+ env: {
360
+ OPENCODE_CONFIG_DIR: configDir,
361
+ OPENCODE_CONFIG: opencodeConfig.path
362
+ }
363
+ };
364
+ }
365
+ async function warmGatewayProject(target, options) {
366
+ const deadlineMs = options?.deadlineMs ?? 30000;
367
+ const intervalMs = options?.intervalMs ?? 250;
368
+ const warmUrl = new URL("/experimental/tool/ids", target.serverOrigin);
369
+ warmUrl.searchParams.set("directory", target.workspaceDirPath);
370
+ const deadline = Date.now() + deadlineMs;
371
+ while (Date.now() < deadline) {
372
+ try {
373
+ const response = await fetch(warmUrl, {
374
+ signal: AbortSignal.timeout(WARM_REQUEST_TIMEOUT_MS)
375
+ });
376
+ if (response.ok) {
377
+ const payload = await response.json();
378
+ if (isGatewayToolList(payload)) {
379
+ return;
380
+ }
381
+ }
382
+ } catch {}
383
+ await delay(intervalMs);
384
+ }
385
+ throw new Error(`failed to warm the gateway plugin at ${target.serverOrigin} for ${target.workspaceDirPath}`);
386
+ }
387
+ function resolveServerOriginFromDocument(document) {
388
+ const server = document.server;
389
+ if (server === null || typeof server !== "object" || Array.isArray(server)) {
390
+ return DEFAULT_SERVER_ORIGIN;
391
+ }
392
+ const hostname = readNonEmptyString(server.hostname);
393
+ const port = readPort(server.port);
394
+ if (hostname === null || port === null) {
395
+ return DEFAULT_SERVER_ORIGIN;
396
+ }
397
+ return `http://${hostname}:${port}`;
398
+ }
399
+ async function resolveServerOrigin(configPath) {
400
+ const source = await readFile(configPath, "utf8");
401
+ const document = parseOpencodeConfig(source, configPath);
402
+ return resolveServerOriginFromDocument(document);
403
+ }
404
+ function readNonEmptyString(value) {
405
+ if (typeof value !== "string") {
406
+ return null;
407
+ }
408
+ const normalized = value.trim();
409
+ return normalized.length > 0 ? normalized : null;
410
+ }
411
+ function readPort(value) {
412
+ if (typeof value !== "number" || !Number.isInteger(value)) {
413
+ return null;
414
+ }
415
+ return value >= 1 && value <= 65535 ? value : null;
416
+ }
417
+ function isGatewayToolList(value) {
418
+ return Array.isArray(value) && value.includes("gateway_status");
419
+ }
420
+ function delay(durationMs) {
421
+ return new Promise((resolve4) => {
422
+ setTimeout(resolve4, durationMs);
423
+ });
424
+ }
425
+
332
426
  // src/cli/doctor.ts
333
427
  async function runDoctor(options, env) {
334
428
  const configDir = resolveCliConfigDir(options, env);
335
- const gatewayConfigPath = join3(configDir, GATEWAY_CONFIG_FILE);
336
- const workspaceDirPath = resolveGatewayWorkspacePath(gatewayConfigPath);
337
429
  const opencodeConfig = await resolveOpencodeConfigFile(configDir);
338
430
  const opencodeStatus = await inspectOpencodeConfig(opencodeConfig.path);
339
431
  const gatewayOverride = env.OPENCODE_GATEWAY_CONFIG?.trim() || null;
432
+ const serveTarget = await resolveServeTarget(options, env);
340
433
  console.log("doctor report");
341
434
  console.log(` config dir: ${configDir}`);
342
435
  console.log(` opencode config: ${await describePath(opencodeConfig.path)}`);
343
- console.log(` gateway config: ${await describePath(gatewayConfigPath)}`);
344
- console.log(` gateway workspace: ${await describePath(workspaceDirPath)}`);
436
+ console.log(` gateway config: ${await describePath(serveTarget.gatewayConfigPath)}`);
437
+ console.log(` gateway workspace: ${await describePath(serveTarget.workspaceDirPath)}`);
438
+ console.log(` warm server: ${serveTarget.serverOrigin}`);
439
+ console.log(` warm directory: ${serveTarget.workspaceDirPath}`);
345
440
  console.log(` gateway config override: ${gatewayOverride ?? "not set"}`);
346
441
  console.log(` plugin configured: ${opencodeStatus.pluginConfigured}`);
347
442
  console.log(` TELEGRAM_BOT_TOKEN: ${env.TELEGRAM_BOT_TOKEN?.trim() ? "set" : "missing"}`);
@@ -360,7 +455,7 @@ async function inspectOpencodeConfig(path) {
360
455
  };
361
456
  }
362
457
  try {
363
- const parsed = parseOpencodeConfig(await readFile(path, "utf8"), path);
458
+ const parsed = parseOpencodeConfig(await readFile2(path, "utf8"), path);
364
459
  return {
365
460
  pluginConfigured: inspectGatewayPlugin(parsed),
366
461
  error: null
@@ -374,8 +469,8 @@ async function inspectOpencodeConfig(path) {
374
469
  }
375
470
 
376
471
  // src/cli/init.ts
377
- import { mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
378
- import { dirname as dirname2, join as join4 } from "node:path";
472
+ import { mkdir, readFile as readFile3, writeFile } from "node:fs/promises";
473
+ import { dirname as dirname2, join as join3 } from "node:path";
379
474
 
380
475
  // src/cli/templates.ts
381
476
  function buildGatewayConfigTemplate(stateDbPath) {
@@ -438,7 +533,7 @@ function escapeTomlString(value) {
438
533
  // src/cli/init.ts
439
534
  async function runInit(options, env) {
440
535
  const configDir = resolveCliConfigDir(options, env);
441
- const gatewayConfigPath = join4(configDir, GATEWAY_CONFIG_FILE);
536
+ const gatewayConfigPath = join3(configDir, GATEWAY_CONFIG_FILE);
442
537
  const workspaceDirPath = resolveGatewayWorkspacePath(gatewayConfigPath);
443
538
  const opencodeConfig = await resolveOpencodeConfigFile(configDir);
444
539
  const opencodeConfigPath = opencodeConfig.path;
@@ -449,7 +544,7 @@ async function runInit(options, env) {
449
544
  await writeFile(opencodeConfigPath, stringifyOpencodeConfig(createDefaultOpencodeConfig(options.managed)));
450
545
  opencodeStatus = "created";
451
546
  } else {
452
- const source = await readFile2(opencodeConfigPath, "utf8");
547
+ const source = await readFile3(opencodeConfigPath, "utf8");
453
548
  const parsed = parseOpencodeConfig(source, opencodeConfigPath);
454
549
  const next = ensureGatewayPlugin(parsed);
455
550
  if (next.changed) {
@@ -467,6 +562,54 @@ async function runInit(options, env) {
467
562
  console.log(`opencode config: ${opencodeConfigPath} (${opencodeStatus})`);
468
563
  console.log(`gateway config: ${gatewayConfigPath} (${gatewayStatus})`);
469
564
  console.log(`gateway workspace: ${workspaceDirPath} (ready)`);
565
+ console.log("next step: start OpenCode with `opencode-gateway serve`");
566
+ console.log("fallback: if you still run `opencode serve`, run `opencode-gateway warm` after startup");
567
+ }
568
+
569
+ // src/cli/serve.ts
570
+ import { spawn } from "node:child_process";
571
+ import { mkdir as mkdir2 } from "node:fs/promises";
572
+ async function runServe(options, env) {
573
+ const target = await resolveServeTarget(options, env);
574
+ await mkdir2(target.workspaceDirPath, { recursive: true });
575
+ const child = spawn("opencode", ["serve"], {
576
+ stdio: "inherit",
577
+ env: {
578
+ ...process.env,
579
+ ...target.env
580
+ }
581
+ });
582
+ warmGatewayProject(target).catch((error) => {
583
+ const message = error instanceof Error ? error.message : String(error);
584
+ console.warn(`warning: ${message}`);
585
+ console.warn("warning: the gateway plugin may stay idle until the first project-scoped request");
586
+ });
587
+ const exitCode = await waitForChild(child);
588
+ if (exitCode !== 0) {
589
+ process.exitCode = exitCode;
590
+ }
591
+ }
592
+ function waitForChild(child) {
593
+ return new Promise((resolve4, reject) => {
594
+ child.once("error", reject);
595
+ child.once("exit", (code, signal) => {
596
+ if (signal !== null) {
597
+ resolve4(1);
598
+ return;
599
+ }
600
+ resolve4(code ?? 0);
601
+ });
602
+ });
603
+ }
604
+
605
+ // src/cli/warm.ts
606
+ import { mkdir as mkdir3 } from "node:fs/promises";
607
+ async function runWarm(options, env) {
608
+ const target = await resolveServeTarget(options, env);
609
+ await mkdir3(target.workspaceDirPath, { recursive: true });
610
+ await warmGatewayProject(target);
611
+ console.log(`gateway plugin warmed: ${target.serverOrigin}`);
612
+ console.log(`warm directory: ${target.workspaceDirPath}`);
470
613
  }
471
614
 
472
615
  // src/cli.ts
@@ -482,6 +625,12 @@ async function main() {
482
625
  case "init":
483
626
  await runInit(command, process.env);
484
627
  return;
628
+ case "serve":
629
+ await runServe(command, process.env);
630
+ return;
631
+ case "warm":
632
+ await runWarm(command, process.env);
633
+ return;
485
634
  }
486
635
  }
487
636
  main().catch((error) => {
package/dist/index.js CHANGED
@@ -17754,7 +17754,9 @@ function delay(durationMs) {
17754
17754
 
17755
17755
  // src/opencode/adapter.ts
17756
17756
  var SESSION_IDLE_POLL_MS = 250;
17757
- var PROMPT_RESPONSE_TIMEOUT_MS = 90000;
17757
+ var PROMPT_RESPONSE_PROGRESS_TIMEOUT_MS = 90000;
17758
+ var PROMPT_RESPONSE_MAX_TIMEOUT_MS = 10 * 60000;
17759
+ var PROMPT_RESPONSE_SETTLE_MS = 1000;
17758
17760
 
17759
17761
  class OpencodeSdkAdapter {
17760
17762
  client;
@@ -17900,8 +17902,12 @@ class OpencodeSdkAdapter {
17900
17902
  };
17901
17903
  }
17902
17904
  async awaitPromptResponse(command) {
17903
- const deadline = Date.now() + PROMPT_RESPONSE_TIMEOUT_MS;
17905
+ const startedAtMs = Date.now();
17906
+ const maxDeadline = startedAtMs + PROMPT_RESPONSE_MAX_TIMEOUT_MS;
17907
+ let progressDeadline = startedAtMs + PROMPT_RESPONSE_PROGRESS_TIMEOUT_MS;
17904
17908
  let stableCandidateKey = null;
17909
+ let stableCandidateSinceMs = null;
17910
+ let progressKey = null;
17905
17911
  for (;; ) {
17906
17912
  const messages = await this.client.session.messages({
17907
17913
  path: { id: command.sessionId },
@@ -17912,22 +17918,32 @@ class OpencodeSdkAdapter {
17912
17918
  responseStyle: "data",
17913
17919
  throwOnError: true
17914
17920
  });
17915
- const response = selectAssistantResponse(unwrapData(messages), command.messageId);
17921
+ const assistantChildren = listAssistantResponses(unwrapData(messages), command.messageId);
17922
+ const nextProgressKey = createAssistantProgressKey(assistantChildren);
17923
+ const now = Date.now();
17924
+ if (progressKey !== nextProgressKey) {
17925
+ progressKey = nextProgressKey;
17926
+ progressDeadline = now + PROMPT_RESPONSE_PROGRESS_TIMEOUT_MS;
17927
+ }
17928
+ const response = selectAssistantResponse(assistantChildren);
17916
17929
  if (response !== null) {
17917
17930
  const candidateKey = createAssistantCandidateKey(response);
17918
17931
  if (stableCandidateKey === candidateKey) {
17919
- return {
17920
- kind: "awaitPromptResponse",
17921
- sessionId: command.sessionId,
17922
- messageId: response.info.id,
17923
- parts: response.parts.flatMap(toBindingMessagePart)
17924
- };
17932
+ if (stableCandidateSinceMs !== null && now - stableCandidateSinceMs >= PROMPT_RESPONSE_SETTLE_MS) {
17933
+ return toAwaitPromptResponseResult(command.sessionId, response);
17934
+ }
17935
+ } else {
17936
+ stableCandidateKey = candidateKey;
17937
+ stableCandidateSinceMs = now;
17925
17938
  }
17926
- stableCandidateKey = candidateKey;
17927
17939
  } else {
17928
17940
  stableCandidateKey = null;
17941
+ stableCandidateSinceMs = null;
17929
17942
  }
17930
- if (Date.now() >= deadline) {
17943
+ if (now >= progressDeadline || now >= maxDeadline) {
17944
+ if (response !== null) {
17945
+ return toAwaitPromptResponseResult(command.sessionId, response);
17946
+ }
17931
17947
  throw new Error(`assistant message for prompt ${command.messageId} is unavailable after prompt completion`);
17932
17948
  }
17933
17949
  await delay(SESSION_IDLE_POLL_MS);
@@ -17988,8 +18004,10 @@ function toSessionPromptPart(part) {
17988
18004
  };
17989
18005
  }
17990
18006
  }
17991
- function selectAssistantResponse(messages, userMessageId) {
17992
- const assistantChildren = messages.filter(isAssistantChildMessage(userMessageId));
18007
+ function listAssistantResponses(messages, userMessageId) {
18008
+ return messages.filter(isAssistantChildMessage(userMessageId));
18009
+ }
18010
+ function selectAssistantResponse(assistantChildren) {
17993
18011
  for (let index = assistantChildren.length - 1;index >= 0; index -= 1) {
17994
18012
  const candidate = assistantChildren[index];
17995
18013
  if (hasVisibleText(candidate)) {
@@ -18004,6 +18022,9 @@ function selectAssistantResponse(messages, userMessageId) {
18004
18022
  }
18005
18023
  return null;
18006
18024
  }
18025
+ function createAssistantProgressKey(messages) {
18026
+ return JSON.stringify(messages.map(createAssistantCandidateKey));
18027
+ }
18007
18028
  function createAssistantCandidateKey(message) {
18008
18029
  return JSON.stringify({
18009
18030
  messageId: message.info.id,
@@ -18020,6 +18041,14 @@ function createAssistantCandidateKey(message) {
18020
18041
  function isAssistantChildMessage(userMessageId) {
18021
18042
  return (message) => message.info?.role === "assistant" && message.info.parentID === userMessageId;
18022
18043
  }
18044
+ function toAwaitPromptResponseResult(sessionId, message) {
18045
+ return {
18046
+ kind: "awaitPromptResponse",
18047
+ sessionId,
18048
+ messageId: message.info.id,
18049
+ parts: message.parts.flatMap(toBindingMessagePart)
18050
+ };
18051
+ }
18023
18052
  function toBindingMessagePart(part) {
18024
18053
  if (typeof part.id !== "string" || typeof part.messageID !== "string" || part.type.length === 0) {
18025
18054
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-gateway",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Gateway plugin for OpenCode",
5
5
  "license": "MIT",
6
6
  "type": "module",