@ai-sdk/harness-opencode 1.0.52 → 1.0.54

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/dist/index.js CHANGED
@@ -168,7 +168,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
168
168
  ]);
169
169
 
170
170
  // src/version.ts
171
- var VERSION = true ? "1.0.52" : "0.0.0-test";
171
+ var VERSION = true ? "1.0.54" : "0.0.0-test";
172
172
 
173
173
  // src/opencode-harness.ts
174
174
  var OPENCODE_CLIENT_APP = `ai-sdk/harness-opencode/${VERSION}`;
@@ -271,7 +271,7 @@ var OPENCODE_BUILTIN_TOOLS = {
271
271
  })
272
272
  })
273
273
  };
274
- var BOOTSTRAP_DIR = "/tmp/harness/opencode";
274
+ var BOOTSTRAP_DIR = ".harness-bootstrap/opencode";
275
275
  var openCodeBridgeCoordsSchema = z2.object({
276
276
  port: z2.number(),
277
277
  token: z2.string(),
@@ -311,12 +311,11 @@ function createOpenCode(settings = {}) {
311
311
  }
312
312
  ],
313
313
  commands: [
314
- { command: `mkdir -p ${BOOTSTRAP_DIR}` },
315
314
  {
316
- command: `pnpm --dir ${BOOTSTRAP_DIR} install --frozen-lockfile --store-dir ${BOOTSTRAP_DIR}/.pnpm-store`
315
+ command: "pnpm install --frozen-lockfile --store-dir .pnpm-store"
317
316
  },
318
317
  {
319
- command: `cd ${BOOTSTRAP_DIR} && node node_modules/opencode-ai/postinstall.mjs && ./node_modules/.bin/opencode --version`
318
+ command: "node node_modules/opencode-ai/postinstall.mjs && ./node_modules/.bin/opencode --version"
320
319
  }
321
320
  ]
322
321
  };
@@ -326,6 +325,10 @@ function createOpenCode(settings = {}) {
326
325
  const sandboxSession = startOpts.sandboxSession;
327
326
  const session = sandboxSession.restricted();
328
327
  const sandboxId = sandboxSession.id;
328
+ const bootstrapDir = path.posix.resolve(
329
+ sandboxSession.defaultWorkingDirectory,
330
+ BOOTSTRAP_DIR
331
+ );
329
332
  const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;
330
333
  const isResume = lifecycleState != null;
331
334
  const isContinue = startOpts.continueFrom != null;
@@ -441,7 +444,7 @@ function createOpenCode(settings = {}) {
441
444
  abortSignal: startOpts.abortSignal
442
445
  });
443
446
  const proc = await session.spawn({
444
- command: `node ${BOOTSTRAP_DIR}/bridge.mjs --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(BOOTSTRAP_DIR)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ""}`,
447
+ command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ""}`,
445
448
  env,
446
449
  abortSignal: startOpts.abortSignal
447
450
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/opencode-harness.ts","../src/opencode-auth.ts","../src/opencode-bridge-protocol.ts","../src/version.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n commonTool,\n HarnessCapabilityUnsupportedError,\n harnessV1DiagnosticFromBridgeFrame,\n type HarnessV1,\n type HarnessV1Bootstrap,\n type HarnessV1BuiltinTool,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnState,\n type HarnessV1DebugConfig,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1Prompt,\n type HarnessV1PromptControl,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n} from '@ai-sdk/harness';\nimport {\n classifyDiskLog,\n createBridgeErrorHandler,\n createBridgeStartupError,\n drainBridgeProcessStream,\n forwardBridgeProcessStream,\n markBridgeStarting,\n resolveSandboxHomeDir,\n SandboxChannel,\n shellQuote,\n waitForBridgeReady,\n writeSkills as writeHarnessSkills,\n} from '@ai-sdk/harness/utils';\nimport {\n tool,\n type Experimental_SandboxProcess,\n type Experimental_SandboxSession,\n} from '@ai-sdk/provider-utils';\nimport { WebSocket } from 'ws';\nimport { z } from 'zod/v4';\nimport {\n resolveOpenCodeEnv,\n splitOpenCodeModel,\n type OpenCodeAuthOptions,\n} from './opencode-auth';\nimport {\n outboundMessageSchema,\n type InboundMessage,\n type OutboundMessage,\n} from './opencode-bridge-protocol';\nimport { VERSION } from './version';\n\ntype OpenCodeChannel = SandboxChannel<OutboundMessage, InboundMessage>;\ntype OpenCodeRespawnStrategy = 'replay' | 'rerun';\n\ntype WriteSkillsResult = {\n readonly skillsDir: string;\n};\n\n/**\n * Value to use in User-Agent and `x-client-app` headers.\n */\nconst OPENCODE_CLIENT_APP = `ai-sdk/harness-opencode/${VERSION}`;\n\nexport type OpenCodeHarnessSettings = {\n readonly auth?: OpenCodeAuthOptions;\n readonly model?: string;\n readonly provider?: string;\n /**\n * OpenCode reasoning/thinking variant for reasoning-capable models, e.g.\n * `'low'`, `'medium'`, `'high'`, or another model-supported OpenCode\n * variant.\n */\n readonly reasoningVariant?: string;\n readonly port?: number;\n readonly startupTimeoutMs?: number;\n};\n\nconst optionalStringRecord = z.record(z.string(), z.unknown()).optional();\n\nconst OPENCODE_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'view',\n toolUseKind: 'readonly',\n description: 'Read file contents',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n description: 'Write content to a file',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit',\n toolUseKind: 'edit',\n description: 'Edit a file by replacing text',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n old_string: z.string().optional(),\n new_string: z.string().optional(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'bash',\n toolUseKind: 'bash',\n description: 'Execute a shell command',\n inputSchema: z.looseObject({\n command: z.string().optional(),\n }),\n }),\n glob: commonTool('glob', {\n nativeName: 'glob',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern',\n inputSchema: z.looseObject({\n pattern: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents with regex',\n inputSchema: z.looseObject({\n pattern: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n ls: tool({\n description: 'List directory contents',\n inputSchema: z.looseObject({\n path: z.string().optional(),\n }),\n }),\n webfetch: tool({\n description: 'Fetch a URL',\n inputSchema: z.looseObject({\n url: z.string().optional(),\n prompt: z.string().optional(),\n }),\n }),\n skill: tool({\n description: 'Load an OpenCode skill by name',\n inputSchema: z.looseObject({\n name: z.string().optional(),\n }),\n }),\n todowrite: tool({\n description: 'Replace the OpenCode session todo list',\n inputSchema: z.looseObject({\n todos: z\n .array(\n z.looseObject({\n content: z.string().optional(),\n status: z.string().optional(),\n priority: z.string().optional(),\n }),\n )\n .optional(),\n }),\n }),\n agent: tool({\n description: 'Run an OpenCode subagent',\n inputSchema: z.looseObject({\n agent: z.string().optional(),\n prompt: z.string().optional(),\n description: z.string().optional(),\n metadata: optionalStringRecord,\n }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nconst BOOTSTRAP_DIR = '/tmp/harness/opencode';\n\nconst openCodeBridgeCoordsSchema = z.object({\n port: z.number(),\n token: z.string(),\n lastSeenEventId: z.number(),\n sandboxId: z.string().optional(),\n});\n\nconst openCodeResumeStateSchema = z.object({\n openCodeSessionId: z.string().optional(),\n bridge: openCodeBridgeCoordsSchema.optional(),\n});\n\ntype OpenCodeBridgeCoords = z.infer<typeof openCodeBridgeCoordsSchema>;\n\nexport function createOpenCode(\n settings: OpenCodeHarnessSettings = {},\n): HarnessV1<typeof OPENCODE_BUILTIN_TOOLS> {\n let cachedBootstrap: HarnessV1Bootstrap | undefined;\n\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'opencode',\n builtinTools: OPENCODE_BUILTIN_TOOLS,\n supportsBuiltinToolApprovals: true,\n lifecycleStateSchema: openCodeResumeStateSchema,\n getBootstrap: async () => {\n if (cachedBootstrap != null) return cachedBootstrap;\n const [pkg, lock, bridge, hostToolMcp] = await Promise.all([\n readBridgeAsset('package.json'),\n readBridgeAsset('pnpm-lock.yaml'),\n readBridgeAsset('index.mjs'),\n readBridgeAsset('host-tool-mcp.mjs'),\n ]);\n cachedBootstrap = {\n harnessId: 'opencode',\n bootstrapDir: BOOTSTRAP_DIR,\n files: [\n { path: `${BOOTSTRAP_DIR}/package.json`, content: pkg },\n { path: `${BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock },\n { path: `${BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },\n {\n path: `${BOOTSTRAP_DIR}/host-tool-mcp.mjs`,\n content: hostToolMcp,\n },\n ],\n commands: [\n { command: `mkdir -p ${BOOTSTRAP_DIR}` },\n {\n command: `pnpm --dir ${BOOTSTRAP_DIR} install --frozen-lockfile --store-dir ${BOOTSTRAP_DIR}/.pnpm-store`,\n },\n {\n command: `cd ${BOOTSTRAP_DIR} && node node_modules/opencode-ai/postinstall.mjs && ./node_modules/.bin/opencode --version`,\n },\n ],\n };\n return cachedBootstrap;\n },\n doStart: async startOpts => {\n const sandboxSession = startOpts.sandboxSession;\n const session = sandboxSession.restricted();\n const sandboxId = sandboxSession.id;\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const isResume = lifecycleState != null;\n const isContinue = startOpts.continueFrom != null;\n const resumeData =\n isResume && typeof lifecycleState?.data === 'object'\n ? (lifecycleState.data as {\n openCodeSessionId?: unknown;\n bridge?: OpenCodeBridgeCoords;\n })\n : undefined;\n const resumeSessionId =\n typeof resumeData?.openCodeSessionId === 'string' &&\n resumeData.openCodeSessionId.length > 0\n ? resumeData.openCodeSessionId\n : undefined;\n const coords = resumeData?.bridge;\n\n const workDir = startOpts.sessionWorkDir;\n const sessionDataDir = `${sandboxSession.defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;\n const bridgeStateDir = `${sessionDataDir}/bridge`;\n const timeoutMs = settings.startupTimeoutMs ?? 120_000;\n const model = splitOpenCodeModel(settings.model, settings.provider).model;\n\n const report = startOpts.observability?.report;\n const onDiagnostic = report\n ? (frame: Parameters<typeof harnessV1DiagnosticFromBridgeFrame>[0]) =>\n report(\n harnessV1DiagnosticFromBridgeFrame(frame, {\n sessionId: startOpts.sessionId,\n timestamp: Date.now(),\n }),\n )\n : undefined;\n const onBridgeError = createBridgeErrorHandler({\n harnessId: 'opencode',\n sessionId: startOpts.sessionId,\n });\n\n if (coords) {\n try {\n const attachUrl =\n (await sandboxSession.getPortUrl({\n port: coords.port,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(coords.token)}`;\n const attachChannel: OpenCodeChannel = new SandboxChannel({\n connect: () => openWebSocket(attachUrl),\n outboundSchema: outboundMessageSchema,\n initialLastSeenEventId: coords.lastSeenEventId,\n onDiagnostic,\n onBridgeError,\n });\n await attachChannel.open(isContinue ? { resume: true } : undefined);\n return createSession({\n sessionId: startOpts.sessionId,\n channel: attachChannel,\n proc: undefined,\n model,\n provider: settings.provider,\n reasoningVariant: settings.reasoningVariant,\n openCodeSessionId: resumeSessionId,\n isResume: true,\n seedResumeSessionOnFirstPrompt: false,\n rerunContinue: false,\n bridgePort: coords.port,\n bridgeToken: coords.token,\n sandboxId,\n debug: startOpts.observability?.debug,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n });\n } catch {}\n }\n\n let respawnStrategy: OpenCodeRespawnStrategy | undefined = isResume\n ? 'rerun'\n : undefined;\n if (coords && isContinue) {\n const logRaw = await Promise.resolve(\n session.readTextFile({\n path: `${bridgeStateDir}/event-log.ndjson`,\n abortSignal: startOpts.abortSignal,\n }),\n ).catch(() => null);\n if ((await classifyDiskLog(logRaw)) === 'replay') {\n respawnStrategy = 'replay';\n }\n }\n\n const port = resolveBridgePort(sandboxSession, settings.port);\n const token = randomBytes(32).toString('hex');\n const sandboxHomeDir = await resolveSandboxHomeDir({\n sandbox: session,\n abortSignal: startOpts.abortSignal,\n });\n const xdgConfigHome = `${sandboxHomeDir}/.config`;\n const xdgCacheHome = `${sandboxHomeDir}/.cache`;\n const xdgDataHome = `${sandboxHomeDir}/.local/share`;\n const xdgStateHome = `${sandboxHomeDir}/.local/state`;\n const skillSetup =\n startOpts.skills && startOpts.skills.length > 0\n ? await writeOpenCodeSkills({\n sandbox: session,\n skills: startOpts.skills,\n homeDir: sandboxHomeDir,\n abortSignal: startOpts.abortSignal,\n })\n : undefined;\n const env = {\n ...resolveOpenCodeEnv({\n auth: settings.auth,\n model: settings.model,\n provider: settings.provider,\n }),\n AI_SDK_HARNESS_CLIENT_APP: OPENCODE_CLIENT_APP,\n BRIDGE_CHANNEL_TOKEN: token,\n BRIDGE_WS_PORT: String(port),\n HOME: sandboxHomeDir,\n USERPROFILE: sandboxHomeDir,\n XDG_CONFIG_HOME: xdgConfigHome,\n XDG_CACHE_HOME: xdgCacheHome,\n XDG_DATA_HOME: xdgDataHome,\n XDG_STATE_HOME: xdgStateHome,\n ...(respawnStrategy === 'replay'\n ? { BRIDGE_REPLAY_FROM_DISK: '1' }\n : {}),\n };\n\n if (respawnStrategy === undefined) {\n await session.run({\n command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)} ${shellQuote(xdgConfigHome)} ${shellQuote(xdgCacheHome)} ${shellQuote(xdgDataHome)} ${shellQuote(xdgStateHome)}`,\n abortSignal: startOpts.abortSignal,\n });\n }\n\n await markBridgeStarting({\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'opencode',\n abortSignal: startOpts.abortSignal,\n });\n\n const proc = await session.spawn({\n command: `node ${BOOTSTRAP_DIR}/bridge.mjs --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(BOOTSTRAP_DIR)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ''}`,\n env,\n abortSignal: startOpts.abortSignal,\n });\n const stderrTail: string[] = [];\n const bridgeStderrDone = forwardBridgeProcessStream({\n stream: proc.stderr,\n streamName: 'stderr',\n source: 'opencode',\n collectTail: stderrTail,\n });\n\n const { port: boundPort } = await waitForBridgeReady({\n proc,\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'opencode',\n timeoutMs,\n abortSignal: startOpts.abortSignal,\n createTimeoutError: ({ proc, stdoutTail }) =>\n createBridgeStartupError({\n message: 'OpenCode bridge did not become ready in time.',\n proc,\n stdoutTail,\n stderrTail,\n stderrDone: bridgeStderrDone,\n }),\n createExitError: ({ proc, stdoutTail }) =>\n createBridgeStartupError({\n message: 'OpenCode bridge exited before becoming ready.',\n proc,\n stdoutTail,\n stderrTail,\n stderrDone: bridgeStderrDone,\n }),\n });\n void drainBridgeProcessStream(proc.stdout);\n\n const wsUrl =\n (await sandboxSession.getPortUrl({\n port: boundPort,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(token)}`;\n\n const channel: OpenCodeChannel = new SandboxChannel({\n connect: () => openWebSocket(wsUrl),\n outboundSchema: outboundMessageSchema,\n onDiagnostic,\n onBridgeError,\n ...(respawnStrategy === 'replay'\n ? { initialLastSeenEventId: coords?.lastSeenEventId ?? 0 }\n : {}),\n });\n await channel.open(\n respawnStrategy === 'replay' ? { resume: true } : undefined,\n );\n\n return createSession({\n sessionId: startOpts.sessionId,\n channel,\n proc,\n model,\n provider: settings.provider,\n reasoningVariant: settings.reasoningVariant,\n openCodeSessionId: resumeSessionId,\n isResume: respawnStrategy !== undefined,\n seedResumeSessionOnFirstPrompt: respawnStrategy !== undefined,\n rerunContinue: respawnStrategy === 'rerun',\n bridgePort: boundPort,\n bridgeToken: token,\n sandboxId,\n debug: startOpts.observability?.debug,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n });\n },\n };\n}\n\nfunction resolveBridgePort(\n sandboxSession: HarnessV1NetworkSandboxSession,\n override: number | undefined,\n): number {\n if (override !== undefined) return override;\n if (sandboxSession.ports.length > 0) return sandboxSession.ports[0];\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n 'The OpenCode harness needs a TCP port exposed by the sandbox. ' +\n 'Create the sandbox with `ports: [<port>]` or pass `createOpenCode({ port })`.',\n });\n}\n\nasync function readBridgeAsset(name: string): Promise<string> {\n const candidates = [\n new URL(`./bridge/${name}`, import.meta.url),\n new URL(`../bridge/${name}`, import.meta.url),\n ];\n let lastErr: unknown;\n for (const url of candidates) {\n try {\n return await readFile(fileURLToPath(url), 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') throw err;\n lastErr = err;\n }\n }\n throw lastErr ?? new Error(`bridge asset not found: ${name}`);\n}\n\nasync function writeOpenCodeSkills({\n sandbox,\n skills,\n homeDir,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n skills: ReadonlyArray<HarnessV1Skill>;\n homeDir: string;\n abortSignal?: AbortSignal;\n}): Promise<WriteSkillsResult> {\n const skillsDir = path.posix.join(homeDir, '.agents', 'skills');\n await writeHarnessSkills({\n sandbox,\n rootDir: skillsDir,\n skills,\n abortSignal,\n invalidSkillNameMessage: ({ name }) =>\n `Invalid OpenCode skill name: ${name}`,\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid OpenCode skill file path for ${skillName}: ${filePath}`,\n });\n\n return { skillsDir };\n}\n\nfunction openWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n const onOpen = () => {\n ws.off('error', onError);\n resolve(ws);\n };\n const onError = (err: Error) => {\n ws.off('open', onOpen);\n reject(err);\n };\n ws.once('open', onOpen);\n ws.once('error', onError);\n });\n}\n\nfunction createSession({\n sessionId,\n channel,\n proc,\n model,\n provider,\n reasoningVariant,\n openCodeSessionId,\n isResume,\n seedResumeSessionOnFirstPrompt,\n rerunContinue,\n bridgePort,\n bridgeToken,\n sandboxId,\n debug,\n permissionMode,\n builtinToolFiltering,\n}: {\n sessionId: string;\n channel: OpenCodeChannel;\n proc: Experimental_SandboxProcess | undefined;\n model: string | undefined;\n provider: string | undefined;\n reasoningVariant: string | undefined;\n openCodeSessionId: string | undefined;\n isResume: boolean;\n seedResumeSessionOnFirstPrompt: boolean;\n rerunContinue: boolean;\n bridgePort: number;\n bridgeToken: string;\n sandboxId: string;\n debug: HarnessV1DebugConfig | undefined;\n permissionMode: HarnessV1PermissionMode | undefined;\n builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;\n}): HarnessV1Session {\n let stopped = false;\n let stopPromise: Promise<void> | undefined;\n let latestOpenCodeSessionId = openCodeSessionId;\n let pendingResumeSessionId = seedResumeSessionOnFirstPrompt\n ? openCodeSessionId\n : undefined;\n let instructionsApplied = isResume;\n let activeTurn = false;\n const pendingCompactionParts: HarnessV1StreamPart[] = [];\n\n channel.on('bridge-thread', msg => {\n latestOpenCodeSessionId = msg.threadId;\n });\n\n const wireTurn = (turnOpts: {\n emit: (event: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): HarnessV1PromptControl => {\n activeTurn = true;\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n\n const unsubs: Array<() => void> = [];\n const forward = (event: HarnessV1StreamPart) => {\n try {\n turnOpts.emit(event);\n } catch {}\n };\n\n const eventTypes = [\n 'stream-start',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'tool-call',\n 'tool-approval-request',\n 'tool-result',\n 'file-change',\n 'finish-step',\n 'compaction',\n 'raw',\n ] as const;\n let isSettled = false;\n const settleSuccess = () => {\n if (isSettled) return;\n isSettled = true;\n activeTurn = false;\n for (const u of unsubs) u();\n pendingResolve!();\n };\n const settleError = (err: unknown) => {\n if (isSettled) return;\n isSettled = true;\n activeTurn = false;\n for (const u of unsubs) u();\n pendingReject!(err);\n };\n\n for (const type of eventTypes) {\n unsubs.push(\n channel.on(type, msg => {\n forward(msg);\n }),\n );\n }\n unsubs.push(\n channel.on('finish', msg => {\n forward(msg);\n settleSuccess();\n }),\n );\n unsubs.push(\n channel.on('error', msg => {\n forward(msg);\n settleError(msg.error);\n }),\n );\n\n const onClose = (_code?: number, reason?: string) => {\n if (isSettled) return;\n if (reason === 'suspended') {\n settleSuccess();\n return;\n }\n settleError(\n new Error('OpenCode bridge closed before the turn finished.'),\n );\n };\n channel.onClose(onClose);\n\n const onAbort = () => {\n if (isSettled) return;\n try {\n channel.send({ type: 'abort' });\n } catch {}\n settleError(\n turnOpts.abortSignal?.reason ??\n new DOMException('Aborted', 'AbortError'),\n );\n };\n if (turnOpts.abortSignal) {\n if (turnOpts.abortSignal.aborted) {\n onAbort();\n } else {\n turnOpts.abortSignal.addEventListener('abort', onAbort, {\n once: true,\n });\n }\n }\n\n while (pendingCompactionParts.length > 0) {\n forward(pendingCompactionParts.shift()!);\n }\n\n return {\n submitToolResult: async input => {\n channel.send({\n type: 'tool-result',\n toolCallId: input.toolCallId,\n output: input.output,\n isError: input.isError,\n });\n },\n submitToolApproval: async input => {\n channel.send({\n type: 'tool-approval-response',\n approvalId: input.approvalId,\n approved: input.approved,\n reason: input.reason,\n });\n },\n submitUserMessage: async text => {\n channel.send({ type: 'user-message', text });\n },\n done,\n };\n };\n\n const startBase = () => ({\n model,\n provider,\n ...(reasoningVariant ? { variant: reasoningVariant } : {}),\n ...(permissionMode ? { permissionMode } : {}),\n ...(builtinToolFiltering ? { builtinToolFiltering } : {}),\n ...(pendingResumeSessionId\n ? { resumeSessionId: pendingResumeSessionId }\n : latestOpenCodeSessionId\n ? { resumeSessionId: latestOpenCodeSessionId }\n : {}),\n ...(debug ? { debug } : {}),\n });\n\n return {\n sessionId,\n isResume,\n modelId: model,\n doPromptTurn: async promptOpts => {\n const control = wireTurn({\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n const applyInstructions =\n !instructionsApplied && !!promptOpts.instructions;\n instructionsApplied = true;\n channel.send({\n type: 'start',\n operation: 'prompt',\n prompt: extractUserText(promptOpts.prompt),\n tools: (promptOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...(applyInstructions ? { instructions: promptOpts.instructions } : {}),\n ...startBase(),\n });\n pendingResumeSessionId = undefined;\n return control;\n },\n doContinueTurn: async continueOpts => {\n const control = wireTurn({\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n if (rerunContinue) {\n channel.send({\n type: 'start',\n operation: 'prompt',\n prompt: 'Continue.',\n tools: (continueOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...startBase(),\n });\n pendingResumeSessionId = undefined;\n }\n return control;\n },\n doCompact: async (customInstructions?: string) => {\n if (customInstructions?.trim()) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n \"Harness 'opencode' supports native manual compaction, but OpenCode does not expose custom compaction instructions through the supported API.\",\n });\n }\n if (activeTurn) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n \"Harness 'opencode' supports manual compaction between turns; compacting during an active turn is not supported by the bridge transport.\",\n });\n }\n await runCompactOperation({\n channel,\n model,\n provider,\n permissionMode,\n debug,\n resumeSessionId: latestOpenCodeSessionId,\n onCompaction: part => pendingCompactionParts.push(part),\n });\n },\n doDetach: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is already stopped; cannot detach.`,\n );\n }\n stopped = true;\n const lastSeenEventId = await channel.suspend();\n return {\n type: 'resume-session',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: {\n ...(latestOpenCodeSessionId\n ? { openCodeSessionId: latestOpenCodeSessionId }\n : {}),\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n },\n doDestroy: async () => {\n if (stopped) return stopPromise;\n stopped = true;\n stopPromise = (async () => {\n channel.beginClose();\n try {\n if (!channel.isClosed()) {\n channel.send({ type: 'shutdown' });\n }\n } catch {}\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n })();\n return stopPromise;\n },\n doStop: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is already stopped; cannot stop.`,\n );\n }\n stopped = true;\n channel.beginClose();\n const data: unknown = channel.isClosed()\n ? {}\n : await new Promise<unknown>((resolve, reject) => {\n const timer = setTimeout(() => {\n unsub();\n reject(\n new Error(\n `OpenCode session ${sessionId} did not reply to detach within 5s.`,\n ),\n );\n }, 5000);\n timer.unref?.();\n const unsub = channel.on('bridge-detach', msg => {\n clearTimeout(timer);\n unsub();\n resolve(msg.data);\n });\n try {\n channel.send({ type: 'detach' });\n } catch (err) {\n clearTimeout(timer);\n unsub();\n reject(err);\n }\n });\n\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: (data ?? {}) as HarnessV1ResumeSessionState['data'],\n };\n return payload;\n },\n doSuspendTurn: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is stopped; cannot suspend.`,\n );\n }\n stopped = true;\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ContinueTurnState = {\n type: 'continue-turn',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: {\n ...(latestOpenCodeSessionId\n ? { openCodeSessionId: latestOpenCodeSessionId }\n : {}),\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n };\n}\n\nasync function runCompactOperation({\n channel,\n model,\n provider,\n permissionMode,\n debug,\n resumeSessionId,\n onCompaction,\n}: {\n channel: OpenCodeChannel;\n model: string | undefined;\n provider: string | undefined;\n permissionMode: HarnessV1PermissionMode | undefined;\n debug: HarnessV1DebugConfig | undefined;\n resumeSessionId: string | undefined;\n onCompaction: (part: HarnessV1StreamPart) => void;\n}): Promise<void> {\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n const unsubs = [\n channel.on('compaction', msg => onCompaction(msg)),\n channel.on('finish', () => {\n for (const u of unsubs) u();\n pendingResolve!();\n }),\n channel.on('error', msg => {\n for (const u of unsubs) u();\n pendingReject!(msg.error);\n }),\n ];\n channel.send({\n type: 'start',\n operation: 'compact',\n prompt: '',\n tools: [],\n model,\n provider,\n ...(permissionMode ? { permissionMode } : {}),\n ...(resumeSessionId ? { resumeSessionId } : {}),\n ...(debug ? { debug } : {}),\n });\n await done;\n}\n\nfunction extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') return prompt;\n const { content } = prompt;\n if (typeof content === 'string') return content;\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message: `The OpenCode harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.`,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n","import { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\nexport type OpenCodeAuthOptions = {\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n readonly anthropic?: {\n readonly apiKey?: string;\n readonly authToken?: string;\n readonly baseUrl?: string;\n };\n readonly openai?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n readonly organization?: string;\n readonly project?: string;\n };\n readonly openaiCompatible?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n readonly name?: string;\n readonly queryParams?: Record<string, string>;\n };\n};\n\nexport function resolveOpenCodeProvider({\n model,\n provider,\n}: {\n model?: string;\n provider?: string;\n}): 'anthropic' | 'openai' {\n if (provider === 'anthropic' || provider === 'openai') {\n return provider;\n }\n if (model?.includes('/')) {\n const [modelProvider] = model.split('/');\n if (modelProvider === 'anthropic' || modelProvider === 'openai') {\n return modelProvider;\n }\n }\n return 'anthropic';\n}\n\nexport function splitOpenCodeModel(\n model: string | undefined,\n provider: string | undefined,\n): { providerID?: string; modelID?: string; model?: string } {\n if (!model) return {};\n if (model.includes('/')) {\n const [providerID, ...rest] = model.split('/');\n return {\n providerID,\n modelID: rest.join('/'),\n model,\n };\n }\n return {\n providerID: provider,\n modelID: model,\n model: provider ? `${provider}/${model}` : model,\n };\n}\n\nexport function resolveOpenCodeEnv({\n auth,\n model,\n provider,\n processEnv = process.env,\n}: {\n auth: OpenCodeAuthOptions | undefined;\n model?: string;\n provider?: string;\n processEnv?: Record<string, string | undefined>;\n}): Record<string, string> {\n const selectedProvider = resolveOpenCodeProvider({ model, provider });\n if (auth?.openaiCompatible) {\n return pickOpenAICompatible(auth.openaiCompatible, processEnv);\n }\n if (selectedProvider === 'openai') {\n if (auth?.openai) {\n return pickOpenAI({ explicit: auth.openai, processEnv });\n }\n } else if (auth?.anthropic) {\n return pickAnthropic({ explicit: auth.anthropic, processEnv });\n }\n\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });\n if (auth?.gateway) {\n return pickGateway({ explicit: auth.gateway, gatewayAuthFromEnv });\n }\n if (gatewayAuthFromEnv.apiKey) {\n return pickGateway({ explicit: {}, gatewayAuthFromEnv });\n }\n return selectedProvider === 'openai'\n ? pickOpenAI({ processEnv })\n : pickAnthropic({ processEnv });\n}\n\nfunction pickOpenAICompatible(\n explicit: NonNullable<OpenCodeAuthOptions['openaiCompatible']>,\n processEnv: Record<string, string | undefined>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit.apiKey ?? processEnv.OPENAI_API_KEY;\n if (apiKey) env.OPENAI_API_KEY = apiKey;\n const baseUrl = explicit.baseUrl ?? processEnv.OPENAI_BASE_URL;\n if (baseUrl) env.OPENAI_BASE_URL = baseUrl;\n const name = explicit.name ?? processEnv.OPENAI_NAME;\n if (name) env.OPENAI_NAME = name;\n if (explicit.queryParams && Object.keys(explicit.queryParams).length > 0) {\n env.OPENAI_QUERY_PARAMS_JSON = JSON.stringify(explicit.queryParams);\n } else if (processEnv.OPENAI_QUERY_PARAMS_JSON) {\n env.OPENAI_QUERY_PARAMS_JSON = processEnv.OPENAI_QUERY_PARAMS_JSON;\n }\n return env;\n}\n\nfunction pickOpenAI({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<OpenCodeAuthOptions['openai']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.OPENAI_API_KEY;\n if (apiKey) env.OPENAI_API_KEY = apiKey;\n const baseUrl = explicit?.baseUrl ?? processEnv.OPENAI_BASE_URL;\n if (baseUrl) env.OPENAI_BASE_URL = baseUrl;\n const organization = explicit?.organization ?? processEnv.OPENAI_ORGANIZATION;\n if (organization) env.OPENAI_ORGANIZATION = organization;\n const project = explicit?.project ?? processEnv.OPENAI_PROJECT;\n if (project) env.OPENAI_PROJECT = project;\n return env;\n}\n\nfunction pickAnthropic({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<OpenCodeAuthOptions['anthropic']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.ANTHROPIC_API_KEY;\n if (apiKey) env.ANTHROPIC_API_KEY = apiKey;\n const authToken = explicit?.authToken ?? processEnv.ANTHROPIC_AUTH_TOKEN;\n if (authToken) env.ANTHROPIC_AUTH_TOKEN = authToken;\n const baseUrl = explicit?.baseUrl ?? processEnv.ANTHROPIC_BASE_URL;\n if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n\nfunction pickGateway({\n explicit,\n gatewayAuthFromEnv,\n}: {\n explicit: NonNullable<OpenCodeAuthOptions['gateway']>;\n gatewayAuthFromEnv: ReturnType<typeof getAiGatewayAuthFromEnv>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit.apiKey ?? gatewayAuthFromEnv.apiKey;\n if (apiKey) env.AI_GATEWAY_API_KEY = apiKey;\n env.AI_GATEWAY_BASE_URL = toOpenCodeGatewayBaseUrl(\n explicit.baseUrl ?? gatewayAuthFromEnv.baseUrl,\n );\n return env;\n}\n\nexport function toOpenCodeGatewayBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.replace(/\\/+$/, '');\n return trimmed.endsWith('/v1') ? trimmed : `${trimmed}/v1`;\n}\n","import {\n harnessV1BridgeInboundCommandSchemas,\n harnessV1BridgeOutboundMessageSchema,\n harnessV1BridgeReadySchema,\n harnessV1BridgeStartBaseSchema,\n} from '@ai-sdk/harness';\nimport { z } from 'zod/v4';\n\nexport const outboundMessageSchema = harnessV1BridgeOutboundMessageSchema;\nexport type OutboundMessage = z.infer<typeof outboundMessageSchema>;\n\nexport const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({\n operation: z.enum(['prompt', 'compact']).optional(),\n provider: z.string().optional(),\n variant: z.string().optional(),\n instructions: z.string().optional(),\n resumeSessionId: z.string().optional(),\n});\n\nexport type StartMessage = z.infer<typeof startMessageSchema>;\n\nexport const inboundMessageSchema = z.discriminatedUnion('type', [\n startMessageSchema,\n ...harnessV1BridgeInboundCommandSchemas,\n]);\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\nexport const bridgeReadySchema = harnessV1BridgeReadySchema;\nexport type BridgeReady = z.infer<typeof bridgeReadySchema>;\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { createOpenCode } from './opencode-harness';\n\n/**\n * Default `openCode` harness instance with no overrides. Equivalent to\n * `createOpenCode()`.\n */\nexport const openCode = createOpenCode();\n\nexport { createOpenCode } from './opencode-harness';\nexport { VERSION } from './version';\nexport type { OpenCodeHarnessSettings } from './opencode-harness';\nexport type { OpenCodeAuthOptions } from './opencode-auth';\n"],"mappings":"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","names":["z","z","proc"]}
1
+ {"version":3,"sources":["../src/opencode-harness.ts","../src/opencode-auth.ts","../src/opencode-bridge-protocol.ts","../src/version.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n commonTool,\n HarnessCapabilityUnsupportedError,\n harnessV1DiagnosticFromBridgeFrame,\n type HarnessV1,\n type HarnessV1Bootstrap,\n type HarnessV1BuiltinTool,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnState,\n type HarnessV1DebugConfig,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1Prompt,\n type HarnessV1PromptControl,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n} from '@ai-sdk/harness';\nimport {\n classifyDiskLog,\n createBridgeErrorHandler,\n createBridgeStartupError,\n drainBridgeProcessStream,\n forwardBridgeProcessStream,\n markBridgeStarting,\n resolveSandboxHomeDir,\n SandboxChannel,\n shellQuote,\n waitForBridgeReady,\n writeSkills as writeHarnessSkills,\n} from '@ai-sdk/harness/utils';\nimport {\n tool,\n type Experimental_SandboxProcess,\n type Experimental_SandboxSession,\n} from '@ai-sdk/provider-utils';\nimport { WebSocket } from 'ws';\nimport { z } from 'zod/v4';\nimport {\n resolveOpenCodeEnv,\n splitOpenCodeModel,\n type OpenCodeAuthOptions,\n} from './opencode-auth';\nimport {\n outboundMessageSchema,\n type InboundMessage,\n type OutboundMessage,\n} from './opencode-bridge-protocol';\nimport { VERSION } from './version';\n\ntype OpenCodeChannel = SandboxChannel<OutboundMessage, InboundMessage>;\ntype OpenCodeRespawnStrategy = 'replay' | 'rerun';\n\ntype WriteSkillsResult = {\n readonly skillsDir: string;\n};\n\n/**\n * Value to use in User-Agent and `x-client-app` headers.\n */\nconst OPENCODE_CLIENT_APP = `ai-sdk/harness-opencode/${VERSION}`;\n\nexport type OpenCodeHarnessSettings = {\n readonly auth?: OpenCodeAuthOptions;\n readonly model?: string;\n readonly provider?: string;\n /**\n * OpenCode reasoning/thinking variant for reasoning-capable models, e.g.\n * `'low'`, `'medium'`, `'high'`, or another model-supported OpenCode\n * variant.\n */\n readonly reasoningVariant?: string;\n readonly port?: number;\n readonly startupTimeoutMs?: number;\n};\n\nconst optionalStringRecord = z.record(z.string(), z.unknown()).optional();\n\nconst OPENCODE_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'view',\n toolUseKind: 'readonly',\n description: 'Read file contents',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n description: 'Write content to a file',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit',\n toolUseKind: 'edit',\n description: 'Edit a file by replacing text',\n inputSchema: z.looseObject({\n file_path: z.string().optional(),\n path: z.string().optional(),\n old_string: z.string().optional(),\n new_string: z.string().optional(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'bash',\n toolUseKind: 'bash',\n description: 'Execute a shell command',\n inputSchema: z.looseObject({\n command: z.string().optional(),\n }),\n }),\n glob: commonTool('glob', {\n nativeName: 'glob',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern',\n inputSchema: z.looseObject({\n pattern: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents with regex',\n inputSchema: z.looseObject({\n pattern: z.string().optional(),\n path: z.string().optional(),\n }),\n }),\n ls: tool({\n description: 'List directory contents',\n inputSchema: z.looseObject({\n path: z.string().optional(),\n }),\n }),\n webfetch: tool({\n description: 'Fetch a URL',\n inputSchema: z.looseObject({\n url: z.string().optional(),\n prompt: z.string().optional(),\n }),\n }),\n skill: tool({\n description: 'Load an OpenCode skill by name',\n inputSchema: z.looseObject({\n name: z.string().optional(),\n }),\n }),\n todowrite: tool({\n description: 'Replace the OpenCode session todo list',\n inputSchema: z.looseObject({\n todos: z\n .array(\n z.looseObject({\n content: z.string().optional(),\n status: z.string().optional(),\n priority: z.string().optional(),\n }),\n )\n .optional(),\n }),\n }),\n agent: tool({\n description: 'Run an OpenCode subagent',\n inputSchema: z.looseObject({\n agent: z.string().optional(),\n prompt: z.string().optional(),\n description: z.string().optional(),\n metadata: optionalStringRecord,\n }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nconst BOOTSTRAP_DIR = '.harness-bootstrap/opencode';\n\nconst openCodeBridgeCoordsSchema = z.object({\n port: z.number(),\n token: z.string(),\n lastSeenEventId: z.number(),\n sandboxId: z.string().optional(),\n});\n\nconst openCodeResumeStateSchema = z.object({\n openCodeSessionId: z.string().optional(),\n bridge: openCodeBridgeCoordsSchema.optional(),\n});\n\ntype OpenCodeBridgeCoords = z.infer<typeof openCodeBridgeCoordsSchema>;\n\nexport function createOpenCode(\n settings: OpenCodeHarnessSettings = {},\n): HarnessV1<typeof OPENCODE_BUILTIN_TOOLS> {\n let cachedBootstrap: HarnessV1Bootstrap | undefined;\n\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'opencode',\n builtinTools: OPENCODE_BUILTIN_TOOLS,\n supportsBuiltinToolApprovals: true,\n lifecycleStateSchema: openCodeResumeStateSchema,\n getBootstrap: async () => {\n if (cachedBootstrap != null) return cachedBootstrap;\n const [pkg, lock, bridge, hostToolMcp] = await Promise.all([\n readBridgeAsset('package.json'),\n readBridgeAsset('pnpm-lock.yaml'),\n readBridgeAsset('index.mjs'),\n readBridgeAsset('host-tool-mcp.mjs'),\n ]);\n cachedBootstrap = {\n harnessId: 'opencode',\n bootstrapDir: BOOTSTRAP_DIR,\n files: [\n { path: `${BOOTSTRAP_DIR}/package.json`, content: pkg },\n { path: `${BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock },\n { path: `${BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },\n {\n path: `${BOOTSTRAP_DIR}/host-tool-mcp.mjs`,\n content: hostToolMcp,\n },\n ],\n commands: [\n {\n command: 'pnpm install --frozen-lockfile --store-dir .pnpm-store',\n },\n {\n command:\n 'node node_modules/opencode-ai/postinstall.mjs && ./node_modules/.bin/opencode --version',\n },\n ],\n };\n return cachedBootstrap;\n },\n doStart: async startOpts => {\n const sandboxSession = startOpts.sandboxSession;\n const session = sandboxSession.restricted();\n const sandboxId = sandboxSession.id;\n const bootstrapDir = path.posix.resolve(\n sandboxSession.defaultWorkingDirectory,\n BOOTSTRAP_DIR,\n );\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const isResume = lifecycleState != null;\n const isContinue = startOpts.continueFrom != null;\n const resumeData =\n isResume && typeof lifecycleState?.data === 'object'\n ? (lifecycleState.data as {\n openCodeSessionId?: unknown;\n bridge?: OpenCodeBridgeCoords;\n })\n : undefined;\n const resumeSessionId =\n typeof resumeData?.openCodeSessionId === 'string' &&\n resumeData.openCodeSessionId.length > 0\n ? resumeData.openCodeSessionId\n : undefined;\n const coords = resumeData?.bridge;\n\n const workDir = startOpts.sessionWorkDir;\n const sessionDataDir = `${sandboxSession.defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;\n const bridgeStateDir = `${sessionDataDir}/bridge`;\n const timeoutMs = settings.startupTimeoutMs ?? 120_000;\n const model = splitOpenCodeModel(settings.model, settings.provider).model;\n\n const report = startOpts.observability?.report;\n const onDiagnostic = report\n ? (frame: Parameters<typeof harnessV1DiagnosticFromBridgeFrame>[0]) =>\n report(\n harnessV1DiagnosticFromBridgeFrame(frame, {\n sessionId: startOpts.sessionId,\n timestamp: Date.now(),\n }),\n )\n : undefined;\n const onBridgeError = createBridgeErrorHandler({\n harnessId: 'opencode',\n sessionId: startOpts.sessionId,\n });\n\n if (coords) {\n try {\n const attachUrl =\n (await sandboxSession.getPortUrl({\n port: coords.port,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(coords.token)}`;\n const attachChannel: OpenCodeChannel = new SandboxChannel({\n connect: () => openWebSocket(attachUrl),\n outboundSchema: outboundMessageSchema,\n initialLastSeenEventId: coords.lastSeenEventId,\n onDiagnostic,\n onBridgeError,\n });\n await attachChannel.open(isContinue ? { resume: true } : undefined);\n return createSession({\n sessionId: startOpts.sessionId,\n channel: attachChannel,\n proc: undefined,\n model,\n provider: settings.provider,\n reasoningVariant: settings.reasoningVariant,\n openCodeSessionId: resumeSessionId,\n isResume: true,\n seedResumeSessionOnFirstPrompt: false,\n rerunContinue: false,\n bridgePort: coords.port,\n bridgeToken: coords.token,\n sandboxId,\n debug: startOpts.observability?.debug,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n });\n } catch {}\n }\n\n let respawnStrategy: OpenCodeRespawnStrategy | undefined = isResume\n ? 'rerun'\n : undefined;\n if (coords && isContinue) {\n const logRaw = await Promise.resolve(\n session.readTextFile({\n path: `${bridgeStateDir}/event-log.ndjson`,\n abortSignal: startOpts.abortSignal,\n }),\n ).catch(() => null);\n if ((await classifyDiskLog(logRaw)) === 'replay') {\n respawnStrategy = 'replay';\n }\n }\n\n const port = resolveBridgePort(sandboxSession, settings.port);\n const token = randomBytes(32).toString('hex');\n const sandboxHomeDir = await resolveSandboxHomeDir({\n sandbox: session,\n abortSignal: startOpts.abortSignal,\n });\n const xdgConfigHome = `${sandboxHomeDir}/.config`;\n const xdgCacheHome = `${sandboxHomeDir}/.cache`;\n const xdgDataHome = `${sandboxHomeDir}/.local/share`;\n const xdgStateHome = `${sandboxHomeDir}/.local/state`;\n const skillSetup =\n startOpts.skills && startOpts.skills.length > 0\n ? await writeOpenCodeSkills({\n sandbox: session,\n skills: startOpts.skills,\n homeDir: sandboxHomeDir,\n abortSignal: startOpts.abortSignal,\n })\n : undefined;\n const env = {\n ...resolveOpenCodeEnv({\n auth: settings.auth,\n model: settings.model,\n provider: settings.provider,\n }),\n AI_SDK_HARNESS_CLIENT_APP: OPENCODE_CLIENT_APP,\n BRIDGE_CHANNEL_TOKEN: token,\n BRIDGE_WS_PORT: String(port),\n HOME: sandboxHomeDir,\n USERPROFILE: sandboxHomeDir,\n XDG_CONFIG_HOME: xdgConfigHome,\n XDG_CACHE_HOME: xdgCacheHome,\n XDG_DATA_HOME: xdgDataHome,\n XDG_STATE_HOME: xdgStateHome,\n ...(respawnStrategy === 'replay'\n ? { BRIDGE_REPLAY_FROM_DISK: '1' }\n : {}),\n };\n\n if (respawnStrategy === undefined) {\n await session.run({\n command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)} ${shellQuote(xdgConfigHome)} ${shellQuote(xdgCacheHome)} ${shellQuote(xdgDataHome)} ${shellQuote(xdgStateHome)}`,\n abortSignal: startOpts.abortSignal,\n });\n }\n\n await markBridgeStarting({\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'opencode',\n abortSignal: startOpts.abortSignal,\n });\n\n const proc = await session.spawn({\n command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ''}`,\n env,\n abortSignal: startOpts.abortSignal,\n });\n const stderrTail: string[] = [];\n const bridgeStderrDone = forwardBridgeProcessStream({\n stream: proc.stderr,\n streamName: 'stderr',\n source: 'opencode',\n collectTail: stderrTail,\n });\n\n const { port: boundPort } = await waitForBridgeReady({\n proc,\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'opencode',\n timeoutMs,\n abortSignal: startOpts.abortSignal,\n createTimeoutError: ({ proc, stdoutTail }) =>\n createBridgeStartupError({\n message: 'OpenCode bridge did not become ready in time.',\n proc,\n stdoutTail,\n stderrTail,\n stderrDone: bridgeStderrDone,\n }),\n createExitError: ({ proc, stdoutTail }) =>\n createBridgeStartupError({\n message: 'OpenCode bridge exited before becoming ready.',\n proc,\n stdoutTail,\n stderrTail,\n stderrDone: bridgeStderrDone,\n }),\n });\n void drainBridgeProcessStream(proc.stdout);\n\n const wsUrl =\n (await sandboxSession.getPortUrl({\n port: boundPort,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(token)}`;\n\n const channel: OpenCodeChannel = new SandboxChannel({\n connect: () => openWebSocket(wsUrl),\n outboundSchema: outboundMessageSchema,\n onDiagnostic,\n onBridgeError,\n ...(respawnStrategy === 'replay'\n ? { initialLastSeenEventId: coords?.lastSeenEventId ?? 0 }\n : {}),\n });\n await channel.open(\n respawnStrategy === 'replay' ? { resume: true } : undefined,\n );\n\n return createSession({\n sessionId: startOpts.sessionId,\n channel,\n proc,\n model,\n provider: settings.provider,\n reasoningVariant: settings.reasoningVariant,\n openCodeSessionId: resumeSessionId,\n isResume: respawnStrategy !== undefined,\n seedResumeSessionOnFirstPrompt: respawnStrategy !== undefined,\n rerunContinue: respawnStrategy === 'rerun',\n bridgePort: boundPort,\n bridgeToken: token,\n sandboxId,\n debug: startOpts.observability?.debug,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n });\n },\n };\n}\n\nfunction resolveBridgePort(\n sandboxSession: HarnessV1NetworkSandboxSession,\n override: number | undefined,\n): number {\n if (override !== undefined) return override;\n if (sandboxSession.ports.length > 0) return sandboxSession.ports[0];\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n 'The OpenCode harness needs a TCP port exposed by the sandbox. ' +\n 'Create the sandbox with `ports: [<port>]` or pass `createOpenCode({ port })`.',\n });\n}\n\nasync function readBridgeAsset(name: string): Promise<string> {\n const candidates = [\n new URL(`./bridge/${name}`, import.meta.url),\n new URL(`../bridge/${name}`, import.meta.url),\n ];\n let lastErr: unknown;\n for (const url of candidates) {\n try {\n return await readFile(fileURLToPath(url), 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') throw err;\n lastErr = err;\n }\n }\n throw lastErr ?? new Error(`bridge asset not found: ${name}`);\n}\n\nasync function writeOpenCodeSkills({\n sandbox,\n skills,\n homeDir,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n skills: ReadonlyArray<HarnessV1Skill>;\n homeDir: string;\n abortSignal?: AbortSignal;\n}): Promise<WriteSkillsResult> {\n const skillsDir = path.posix.join(homeDir, '.agents', 'skills');\n await writeHarnessSkills({\n sandbox,\n rootDir: skillsDir,\n skills,\n abortSignal,\n invalidSkillNameMessage: ({ name }) =>\n `Invalid OpenCode skill name: ${name}`,\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid OpenCode skill file path for ${skillName}: ${filePath}`,\n });\n\n return { skillsDir };\n}\n\nfunction openWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n const onOpen = () => {\n ws.off('error', onError);\n resolve(ws);\n };\n const onError = (err: Error) => {\n ws.off('open', onOpen);\n reject(err);\n };\n ws.once('open', onOpen);\n ws.once('error', onError);\n });\n}\n\nfunction createSession({\n sessionId,\n channel,\n proc,\n model,\n provider,\n reasoningVariant,\n openCodeSessionId,\n isResume,\n seedResumeSessionOnFirstPrompt,\n rerunContinue,\n bridgePort,\n bridgeToken,\n sandboxId,\n debug,\n permissionMode,\n builtinToolFiltering,\n}: {\n sessionId: string;\n channel: OpenCodeChannel;\n proc: Experimental_SandboxProcess | undefined;\n model: string | undefined;\n provider: string | undefined;\n reasoningVariant: string | undefined;\n openCodeSessionId: string | undefined;\n isResume: boolean;\n seedResumeSessionOnFirstPrompt: boolean;\n rerunContinue: boolean;\n bridgePort: number;\n bridgeToken: string;\n sandboxId: string;\n debug: HarnessV1DebugConfig | undefined;\n permissionMode: HarnessV1PermissionMode | undefined;\n builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;\n}): HarnessV1Session {\n let stopped = false;\n let stopPromise: Promise<void> | undefined;\n let latestOpenCodeSessionId = openCodeSessionId;\n let pendingResumeSessionId = seedResumeSessionOnFirstPrompt\n ? openCodeSessionId\n : undefined;\n let instructionsApplied = isResume;\n let activeTurn = false;\n const pendingCompactionParts: HarnessV1StreamPart[] = [];\n\n channel.on('bridge-thread', msg => {\n latestOpenCodeSessionId = msg.threadId;\n });\n\n const wireTurn = (turnOpts: {\n emit: (event: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): HarnessV1PromptControl => {\n activeTurn = true;\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n\n const unsubs: Array<() => void> = [];\n const forward = (event: HarnessV1StreamPart) => {\n try {\n turnOpts.emit(event);\n } catch {}\n };\n\n const eventTypes = [\n 'stream-start',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'tool-call',\n 'tool-approval-request',\n 'tool-result',\n 'file-change',\n 'finish-step',\n 'compaction',\n 'raw',\n ] as const;\n let isSettled = false;\n const settleSuccess = () => {\n if (isSettled) return;\n isSettled = true;\n activeTurn = false;\n for (const u of unsubs) u();\n pendingResolve!();\n };\n const settleError = (err: unknown) => {\n if (isSettled) return;\n isSettled = true;\n activeTurn = false;\n for (const u of unsubs) u();\n pendingReject!(err);\n };\n\n for (const type of eventTypes) {\n unsubs.push(\n channel.on(type, msg => {\n forward(msg);\n }),\n );\n }\n unsubs.push(\n channel.on('finish', msg => {\n forward(msg);\n settleSuccess();\n }),\n );\n unsubs.push(\n channel.on('error', msg => {\n forward(msg);\n settleError(msg.error);\n }),\n );\n\n const onClose = (_code?: number, reason?: string) => {\n if (isSettled) return;\n if (reason === 'suspended') {\n settleSuccess();\n return;\n }\n settleError(\n new Error('OpenCode bridge closed before the turn finished.'),\n );\n };\n channel.onClose(onClose);\n\n const onAbort = () => {\n if (isSettled) return;\n try {\n channel.send({ type: 'abort' });\n } catch {}\n settleError(\n turnOpts.abortSignal?.reason ??\n new DOMException('Aborted', 'AbortError'),\n );\n };\n if (turnOpts.abortSignal) {\n if (turnOpts.abortSignal.aborted) {\n onAbort();\n } else {\n turnOpts.abortSignal.addEventListener('abort', onAbort, {\n once: true,\n });\n }\n }\n\n while (pendingCompactionParts.length > 0) {\n forward(pendingCompactionParts.shift()!);\n }\n\n return {\n submitToolResult: async input => {\n channel.send({\n type: 'tool-result',\n toolCallId: input.toolCallId,\n output: input.output,\n isError: input.isError,\n });\n },\n submitToolApproval: async input => {\n channel.send({\n type: 'tool-approval-response',\n approvalId: input.approvalId,\n approved: input.approved,\n reason: input.reason,\n });\n },\n submitUserMessage: async text => {\n channel.send({ type: 'user-message', text });\n },\n done,\n };\n };\n\n const startBase = () => ({\n model,\n provider,\n ...(reasoningVariant ? { variant: reasoningVariant } : {}),\n ...(permissionMode ? { permissionMode } : {}),\n ...(builtinToolFiltering ? { builtinToolFiltering } : {}),\n ...(pendingResumeSessionId\n ? { resumeSessionId: pendingResumeSessionId }\n : latestOpenCodeSessionId\n ? { resumeSessionId: latestOpenCodeSessionId }\n : {}),\n ...(debug ? { debug } : {}),\n });\n\n return {\n sessionId,\n isResume,\n modelId: model,\n doPromptTurn: async promptOpts => {\n const control = wireTurn({\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n const applyInstructions =\n !instructionsApplied && !!promptOpts.instructions;\n instructionsApplied = true;\n channel.send({\n type: 'start',\n operation: 'prompt',\n prompt: extractUserText(promptOpts.prompt),\n tools: (promptOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...(applyInstructions ? { instructions: promptOpts.instructions } : {}),\n ...startBase(),\n });\n pendingResumeSessionId = undefined;\n return control;\n },\n doContinueTurn: async continueOpts => {\n const control = wireTurn({\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n if (rerunContinue) {\n channel.send({\n type: 'start',\n operation: 'prompt',\n prompt: 'Continue.',\n tools: (continueOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...startBase(),\n });\n pendingResumeSessionId = undefined;\n }\n return control;\n },\n doCompact: async (customInstructions?: string) => {\n if (customInstructions?.trim()) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n \"Harness 'opencode' supports native manual compaction, but OpenCode does not expose custom compaction instructions through the supported API.\",\n });\n }\n if (activeTurn) {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message:\n \"Harness 'opencode' supports manual compaction between turns; compacting during an active turn is not supported by the bridge transport.\",\n });\n }\n await runCompactOperation({\n channel,\n model,\n provider,\n permissionMode,\n debug,\n resumeSessionId: latestOpenCodeSessionId,\n onCompaction: part => pendingCompactionParts.push(part),\n });\n },\n doDetach: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is already stopped; cannot detach.`,\n );\n }\n stopped = true;\n const lastSeenEventId = await channel.suspend();\n return {\n type: 'resume-session',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: {\n ...(latestOpenCodeSessionId\n ? { openCodeSessionId: latestOpenCodeSessionId }\n : {}),\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n },\n doDestroy: async () => {\n if (stopped) return stopPromise;\n stopped = true;\n stopPromise = (async () => {\n channel.beginClose();\n try {\n if (!channel.isClosed()) {\n channel.send({ type: 'shutdown' });\n }\n } catch {}\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n })();\n return stopPromise;\n },\n doStop: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is already stopped; cannot stop.`,\n );\n }\n stopped = true;\n channel.beginClose();\n const data: unknown = channel.isClosed()\n ? {}\n : await new Promise<unknown>((resolve, reject) => {\n const timer = setTimeout(() => {\n unsub();\n reject(\n new Error(\n `OpenCode session ${sessionId} did not reply to detach within 5s.`,\n ),\n );\n }, 5000);\n timer.unref?.();\n const unsub = channel.on('bridge-detach', msg => {\n clearTimeout(timer);\n unsub();\n resolve(msg.data);\n });\n try {\n channel.send({ type: 'detach' });\n } catch (err) {\n clearTimeout(timer);\n unsub();\n reject(err);\n }\n });\n\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: (data ?? {}) as HarnessV1ResumeSessionState['data'],\n };\n return payload;\n },\n doSuspendTurn: async () => {\n if (stopped) {\n throw new Error(\n `OpenCode session ${sessionId} is stopped; cannot suspend.`,\n );\n }\n stopped = true;\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ContinueTurnState = {\n type: 'continue-turn',\n harnessId: 'opencode',\n specificationVersion: 'harness-v1',\n data: {\n ...(latestOpenCodeSessionId\n ? { openCodeSessionId: latestOpenCodeSessionId }\n : {}),\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n };\n}\n\nasync function runCompactOperation({\n channel,\n model,\n provider,\n permissionMode,\n debug,\n resumeSessionId,\n onCompaction,\n}: {\n channel: OpenCodeChannel;\n model: string | undefined;\n provider: string | undefined;\n permissionMode: HarnessV1PermissionMode | undefined;\n debug: HarnessV1DebugConfig | undefined;\n resumeSessionId: string | undefined;\n onCompaction: (part: HarnessV1StreamPart) => void;\n}): Promise<void> {\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n const unsubs = [\n channel.on('compaction', msg => onCompaction(msg)),\n channel.on('finish', () => {\n for (const u of unsubs) u();\n pendingResolve!();\n }),\n channel.on('error', msg => {\n for (const u of unsubs) u();\n pendingReject!(msg.error);\n }),\n ];\n channel.send({\n type: 'start',\n operation: 'compact',\n prompt: '',\n tools: [],\n model,\n provider,\n ...(permissionMode ? { permissionMode } : {}),\n ...(resumeSessionId ? { resumeSessionId } : {}),\n ...(debug ? { debug } : {}),\n });\n await done;\n}\n\nfunction extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') return prompt;\n const { content } = prompt;\n if (typeof content === 'string') return content;\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'opencode',\n message: `The OpenCode harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.`,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n","import { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\nexport type OpenCodeAuthOptions = {\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n readonly anthropic?: {\n readonly apiKey?: string;\n readonly authToken?: string;\n readonly baseUrl?: string;\n };\n readonly openai?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n readonly organization?: string;\n readonly project?: string;\n };\n readonly openaiCompatible?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n readonly name?: string;\n readonly queryParams?: Record<string, string>;\n };\n};\n\nexport function resolveOpenCodeProvider({\n model,\n provider,\n}: {\n model?: string;\n provider?: string;\n}): 'anthropic' | 'openai' {\n if (provider === 'anthropic' || provider === 'openai') {\n return provider;\n }\n if (model?.includes('/')) {\n const [modelProvider] = model.split('/');\n if (modelProvider === 'anthropic' || modelProvider === 'openai') {\n return modelProvider;\n }\n }\n return 'anthropic';\n}\n\nexport function splitOpenCodeModel(\n model: string | undefined,\n provider: string | undefined,\n): { providerID?: string; modelID?: string; model?: string } {\n if (!model) return {};\n if (model.includes('/')) {\n const [providerID, ...rest] = model.split('/');\n return {\n providerID,\n modelID: rest.join('/'),\n model,\n };\n }\n return {\n providerID: provider,\n modelID: model,\n model: provider ? `${provider}/${model}` : model,\n };\n}\n\nexport function resolveOpenCodeEnv({\n auth,\n model,\n provider,\n processEnv = process.env,\n}: {\n auth: OpenCodeAuthOptions | undefined;\n model?: string;\n provider?: string;\n processEnv?: Record<string, string | undefined>;\n}): Record<string, string> {\n const selectedProvider = resolveOpenCodeProvider({ model, provider });\n if (auth?.openaiCompatible) {\n return pickOpenAICompatible(auth.openaiCompatible, processEnv);\n }\n if (selectedProvider === 'openai') {\n if (auth?.openai) {\n return pickOpenAI({ explicit: auth.openai, processEnv });\n }\n } else if (auth?.anthropic) {\n return pickAnthropic({ explicit: auth.anthropic, processEnv });\n }\n\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });\n if (auth?.gateway) {\n return pickGateway({ explicit: auth.gateway, gatewayAuthFromEnv });\n }\n if (gatewayAuthFromEnv.apiKey) {\n return pickGateway({ explicit: {}, gatewayAuthFromEnv });\n }\n return selectedProvider === 'openai'\n ? pickOpenAI({ processEnv })\n : pickAnthropic({ processEnv });\n}\n\nfunction pickOpenAICompatible(\n explicit: NonNullable<OpenCodeAuthOptions['openaiCompatible']>,\n processEnv: Record<string, string | undefined>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit.apiKey ?? processEnv.OPENAI_API_KEY;\n if (apiKey) env.OPENAI_API_KEY = apiKey;\n const baseUrl = explicit.baseUrl ?? processEnv.OPENAI_BASE_URL;\n if (baseUrl) env.OPENAI_BASE_URL = baseUrl;\n const name = explicit.name ?? processEnv.OPENAI_NAME;\n if (name) env.OPENAI_NAME = name;\n if (explicit.queryParams && Object.keys(explicit.queryParams).length > 0) {\n env.OPENAI_QUERY_PARAMS_JSON = JSON.stringify(explicit.queryParams);\n } else if (processEnv.OPENAI_QUERY_PARAMS_JSON) {\n env.OPENAI_QUERY_PARAMS_JSON = processEnv.OPENAI_QUERY_PARAMS_JSON;\n }\n return env;\n}\n\nfunction pickOpenAI({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<OpenCodeAuthOptions['openai']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.OPENAI_API_KEY;\n if (apiKey) env.OPENAI_API_KEY = apiKey;\n const baseUrl = explicit?.baseUrl ?? processEnv.OPENAI_BASE_URL;\n if (baseUrl) env.OPENAI_BASE_URL = baseUrl;\n const organization = explicit?.organization ?? processEnv.OPENAI_ORGANIZATION;\n if (organization) env.OPENAI_ORGANIZATION = organization;\n const project = explicit?.project ?? processEnv.OPENAI_PROJECT;\n if (project) env.OPENAI_PROJECT = project;\n return env;\n}\n\nfunction pickAnthropic({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<OpenCodeAuthOptions['anthropic']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.ANTHROPIC_API_KEY;\n if (apiKey) env.ANTHROPIC_API_KEY = apiKey;\n const authToken = explicit?.authToken ?? processEnv.ANTHROPIC_AUTH_TOKEN;\n if (authToken) env.ANTHROPIC_AUTH_TOKEN = authToken;\n const baseUrl = explicit?.baseUrl ?? processEnv.ANTHROPIC_BASE_URL;\n if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n\nfunction pickGateway({\n explicit,\n gatewayAuthFromEnv,\n}: {\n explicit: NonNullable<OpenCodeAuthOptions['gateway']>;\n gatewayAuthFromEnv: ReturnType<typeof getAiGatewayAuthFromEnv>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit.apiKey ?? gatewayAuthFromEnv.apiKey;\n if (apiKey) env.AI_GATEWAY_API_KEY = apiKey;\n env.AI_GATEWAY_BASE_URL = toOpenCodeGatewayBaseUrl(\n explicit.baseUrl ?? gatewayAuthFromEnv.baseUrl,\n );\n return env;\n}\n\nexport function toOpenCodeGatewayBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.replace(/\\/+$/, '');\n return trimmed.endsWith('/v1') ? trimmed : `${trimmed}/v1`;\n}\n","import {\n harnessV1BridgeInboundCommandSchemas,\n harnessV1BridgeOutboundMessageSchema,\n harnessV1BridgeReadySchema,\n harnessV1BridgeStartBaseSchema,\n} from '@ai-sdk/harness';\nimport { z } from 'zod/v4';\n\nexport const outboundMessageSchema = harnessV1BridgeOutboundMessageSchema;\nexport type OutboundMessage = z.infer<typeof outboundMessageSchema>;\n\nexport const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({\n operation: z.enum(['prompt', 'compact']).optional(),\n provider: z.string().optional(),\n variant: z.string().optional(),\n instructions: z.string().optional(),\n resumeSessionId: z.string().optional(),\n});\n\nexport type StartMessage = z.infer<typeof startMessageSchema>;\n\nexport const inboundMessageSchema = z.discriminatedUnion('type', [\n startMessageSchema,\n ...harnessV1BridgeInboundCommandSchemas,\n]);\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\nexport const bridgeReadySchema = harnessV1BridgeReadySchema;\nexport type BridgeReady = z.infer<typeof bridgeReadySchema>;\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { createOpenCode } from './opencode-harness';\n\n/**\n * Default `openCode` harness instance with no overrides. Equivalent to\n * `createOpenCode()`.\n */\nexport const openCode = createOpenCode();\n\nexport { createOpenCode } from './opencode-harness';\nexport { VERSION } from './version';\nexport type { OpenCodeHarnessSettings } from './opencode-harness';\nexport type { OpenCodeAuthOptions } from './opencode-auth';\n"],"mappings":"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","names":["z","z","proc"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-opencode",
3
- "version": "1.0.52",
3
+ "version": "1.0.54",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "ws": "8.21.0",
30
- "@ai-sdk/harness": "1.0.51",
31
- "@ai-sdk/provider-utils": "5.0.17"
30
+ "@ai-sdk/harness": "1.0.53",
31
+ "@ai-sdk/provider-utils": "5.0.18"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "zod": "^3.25.76 || ^4.1.8"
@@ -1,17 +1,21 @@
1
1
  import type { BridgeTurn } from '@ai-sdk/harness/bridge';
2
- import { isRecord } from '@ai-sdk/provider-utils';
3
2
  import {
4
3
  emitLegacyPartDelta,
5
4
  emitLegacyTextPartUpdate,
6
5
  emitMissingFinalDelta,
7
- type OpenCodeEvent,
6
+ openCodeMessageInfoFromValue,
8
7
  type TranslationState,
9
8
  } from './opencode-events';
10
9
  import {
11
- legacyStepFinishPartToFinishStep,
12
10
  mapOpenCodeFinishReason,
11
+ translateLegacyStepFinishPart,
13
12
  } from './opencode-finish-step';
14
13
  import { mapUsage } from './opencode-usage';
14
+ import {
15
+ asOpenCodeObject,
16
+ type OpenCodeEvent,
17
+ type OpenCodeEventProperties,
18
+ } from './opencode-types';
15
19
 
16
20
  type Emit = (message: Record<string, unknown>) => void;
17
21
 
@@ -52,8 +56,8 @@ export function createEmitStreamEvent({
52
56
  const props = event.properties ?? {};
53
57
 
54
58
  if (type === 'message.updated') {
55
- const info = props.info;
56
- if (isRecord(info)) {
59
+ const info = openCodeMessageInfoFromValue(props.info);
60
+ if (info) {
57
61
  const id = stringValue(info.id);
58
62
  const role = stringValue(info.role);
59
63
  if (id && role) state.messageRoles.set(id, role);
@@ -238,7 +242,7 @@ export function createEmitStreamEvent({
238
242
  }
239
243
  if (type === 'session.next.retried') {
240
244
  const error = props.error ?? event;
241
- if (isRecord(error) && error.isRetryable === false) {
245
+ if (openCodeErrorFromValue(error)?.isRetryable === false) {
242
246
  emitError({
243
247
  error,
244
248
  message: 'OpenCode session retry failed',
@@ -326,9 +330,9 @@ function emitLegacyStepFinishPart({
326
330
  state: TranslationState;
327
331
  emit: Emit;
328
332
  }): boolean {
329
- const event = legacyStepFinishPartToFinishStep(part);
330
- if (!event) return false;
331
- const id = isRecord(part) ? stringValue(part.id) : undefined;
333
+ const translated = translateLegacyStepFinishPart(part);
334
+ if (!translated) return false;
335
+ const { event, partId: id } = translated;
332
336
  if (id) {
333
337
  if (state.legacyStepFinishPartIds.has(id)) return true;
334
338
  state.legacyStepFinishPartIds.add(id);
@@ -365,19 +369,12 @@ function emitLegacyToolPart({
365
369
  input: unknown;
366
370
  }) => void;
367
371
  }): void {
368
- if (!part || typeof part !== 'object') return;
369
- const toolPart = part as Record<string, any>;
370
- if (toolPart.type !== 'tool') return;
371
- const status = legacyToolPartStatus(toolPart);
372
+ const toolPart = legacyToolPartFromValue(part);
373
+ if (!toolPart) return;
374
+ const status = toolPart.status;
372
375
  if (status !== 'running' && status !== 'completed' && status !== 'error') {
373
376
  return;
374
377
  }
375
- if (
376
- typeof toolPart.tool !== 'string' ||
377
- typeof toolPart.callID !== 'string'
378
- ) {
379
- return;
380
- }
381
378
  const callID = toolPart.callID;
382
379
  const rawToolName = toolPart.tool;
383
380
  const toolName = toWireToolName(rawToolName);
@@ -402,8 +399,8 @@ function emitLegacyToolPart({
402
399
  ...nativeNameField({ nativeName: rawToolName, toolName }),
403
400
  input: JSON.stringify(legacyToolPartInput(toolPart)),
404
401
  providerExecuted: true,
405
- ...(toolPart.provider?.metadata
406
- ? { providerMetadata: toolPart.provider.metadata }
402
+ ...(toolPart.providerMetadata
403
+ ? { providerMetadata: toolPart.providerMetadata }
407
404
  : {}),
408
405
  });
409
406
  }
@@ -422,33 +419,16 @@ function emitLegacyToolPart({
422
419
  }
423
420
  }
424
421
 
425
- function legacyToolPartStatus(part: Record<string, any>): string | undefined {
426
- return typeof part.state === 'string'
427
- ? part.state
428
- : typeof part.state === 'object' && part.state !== null
429
- ? String(part.state.status ?? '')
430
- : undefined;
431
- }
432
-
433
- function legacyToolPartInput(
434
- part: Record<string, any>,
435
- ): Record<string, unknown> {
436
- const state =
437
- typeof part.state === 'object' && part.state !== null
438
- ? (part.state as Record<string, any>)
439
- : undefined;
422
+ function legacyToolPartInput(part: LegacyToolPart): Record<string, unknown> {
440
423
  return {
441
- ...(isRecord(part.metadata) ? part.metadata : {}),
442
- ...(isRecord(state?.metadata) ? state.metadata : {}),
443
- ...(isRecord(state?.input) ? state.input : {}),
424
+ ...(part.metadata ?? {}),
425
+ ...(part.state?.metadata ?? {}),
426
+ ...(part.state?.input ?? {}),
444
427
  };
445
428
  }
446
429
 
447
- function legacyToolPartOutput(part: Record<string, any>): unknown {
448
- const state =
449
- typeof part.state === 'object' && part.state !== null
450
- ? (part.state as Record<string, any>)
451
- : undefined;
430
+ function legacyToolPartOutput(part: LegacyToolPart): unknown {
431
+ const state = part.state;
452
432
  if (state?.status === 'error') {
453
433
  return state.error ?? part.error ?? state.result ?? 'tool failed';
454
434
  }
@@ -463,7 +443,7 @@ function legacyToolPartOutput(part: Record<string, any>): unknown {
463
443
 
464
444
  function parseToolInput(
465
445
  state: TranslationState,
466
- props: Record<string, any>,
446
+ props: OpenCodeEventProperties,
467
447
  ): unknown {
468
448
  const text = state.toolInputs.get(String(props.callID ?? ''));
469
449
  if (!text) return {};
@@ -487,11 +467,12 @@ function nextRetryEventMessage({
487
467
  details.push(`attempt ${props.attempt}`);
488
468
  }
489
469
  const error = props.error;
490
- if (isRecord(error)) {
470
+ const errorDetails = openCodeErrorFromValue(error);
471
+ if (errorDetails) {
491
472
  const message =
492
- stringValue(error.message) ??
493
- (isRecord(error.data) ? stringValue(error.data.message) : undefined);
494
- const statusCode = error.statusCode;
473
+ stringValue(errorDetails.message) ??
474
+ stringValue(errorDetails.data?.message);
475
+ const statusCode = errorDetails.statusCode;
495
476
  if (typeof statusCode === 'number') {
496
477
  details.push(`HTTP ${statusCode}`);
497
478
  }
@@ -507,3 +488,87 @@ function nextRetryEventMessage({
507
488
  export function stringValue(value: unknown): string | undefined {
508
489
  return typeof value === 'string' && value.length > 0 ? value : undefined;
509
490
  }
491
+
492
+ type LegacyToolState = {
493
+ status?: string;
494
+ input?: Record<string, unknown>;
495
+ metadata?: Record<string, unknown>;
496
+ output?: unknown;
497
+ result?: unknown;
498
+ structured?: unknown;
499
+ content?: unknown;
500
+ error?: unknown;
501
+ };
502
+
503
+ type LegacyToolPart = {
504
+ type: 'tool';
505
+ callID: string;
506
+ tool: string;
507
+ status?: string;
508
+ state?: LegacyToolState;
509
+ metadata?: Record<string, unknown>;
510
+ providerMetadata?: unknown;
511
+ error?: unknown;
512
+ };
513
+
514
+ function legacyToolPartFromValue(value: unknown): LegacyToolPart | undefined {
515
+ const part = asOpenCodeObject(value);
516
+ if (
517
+ !part ||
518
+ part.type !== 'tool' ||
519
+ typeof part.tool !== 'string' ||
520
+ typeof part.callID !== 'string'
521
+ ) {
522
+ return undefined;
523
+ }
524
+
525
+ const stateObject = asOpenCodeObject(part.state);
526
+ const provider = asOpenCodeObject(part.provider);
527
+ const state = stateObject
528
+ ? {
529
+ status: stringValue(stateObject.status),
530
+ input: asOpenCodeObject(stateObject.input),
531
+ metadata: asOpenCodeObject(stateObject.metadata),
532
+ output: stateObject.output,
533
+ result: stateObject.result,
534
+ structured: stateObject.structured,
535
+ content: stateObject.content,
536
+ error: stateObject.error,
537
+ }
538
+ : undefined;
539
+
540
+ return {
541
+ type: 'tool',
542
+ callID: part.callID,
543
+ tool: part.tool,
544
+ status:
545
+ typeof part.state === 'string'
546
+ ? part.state
547
+ : (state?.status ?? undefined),
548
+ state,
549
+ metadata: asOpenCodeObject(part.metadata),
550
+ providerMetadata: provider?.metadata,
551
+ error: part.error,
552
+ };
553
+ }
554
+
555
+ type OpenCodeErrorDetails = {
556
+ isRetryable?: unknown;
557
+ message?: unknown;
558
+ statusCode?: unknown;
559
+ data?: { message?: unknown };
560
+ };
561
+
562
+ function openCodeErrorFromValue(
563
+ value: unknown,
564
+ ): OpenCodeErrorDetails | undefined {
565
+ const error = asOpenCodeObject(value);
566
+ if (!error) return undefined;
567
+ const data = asOpenCodeObject(error.data);
568
+ return {
569
+ isRetryable: error.isRetryable,
570
+ message: error.message,
571
+ statusCode: error.statusCode,
572
+ data: data ? { message: data.message } : undefined,
573
+ };
574
+ }