export declare const OPENCODE_PLUGIN_SOURCE = "// LOBU_OPENCODE_INTERACTIVE_PLUGIN=1\n// Managed by `lobu opencode-plugin`. Reinstalling updates this file.\nimport { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { chmodSync, mkdtempSync, rmSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\n\nconst REQUEST_CAP_BYTES = 8 * 1024 * 1024;\nfunction equalSecret(actual, expected) {\n if (typeof actual !== \"string\" || typeof expected !== \"string\") return false;\n const left = Buffer.from(actual);\n const right = Buffer.from(expected);\n return left.length === right.length && timingSafeEqual(left, right);\n}\n\nexport const LobuInteractiveSessionPlugin = async ({ client }) => {\n const bridgeDir = mkdtempSync(path.join(tmpdir(), \"lobu-opencode-\"));\n chmodSync(bridgeDir, 0o700);\n const socketPath = path.join(bridgeDir, \"bridge.sock\");\n const sessions = new Map();\n const sockets = new Set();\n let disposed = false;\n\n const server = net.createServer({ allowHalfOpen: true }, (socket) => {\n sockets.add(socket);\n socket.once(\"close\", () => sockets.delete(socket));\n const chunks = [];\n let total = 0;\n let handled = false;\n const reply = (value) => {\n if (handled) return;\n handled = true;\n socket.end(JSON.stringify(value) + \"\\n\");\n };\n socket.on(\"data\", (chunk) => {\n if (handled) return;\n total += chunk.length;\n if (total > REQUEST_CAP_BYTES) {\n reply({ ok: false });\n return;\n }\n const newline = chunk.indexOf(0x0a);\n if (newline >= 0 && newline !== chunk.length - 1) {\n reply({ ok: false });\n return;\n }\n chunks.push(chunk);\n if (newline < 0) return;\n void (async () => {\n let request;\n try {\n request = JSON.parse(\n Buffer.concat(chunks, total).subarray(0, total - 1).toString(\"utf8\")\n );\n } catch {\n reply({ ok: false });\n return;\n }\n const keys = request && typeof request === \"object\" ? Object.keys(request).sort() : [];\n if (\n disposed ||\n keys.join(\",\") !== \"prompt,session_id,token,version\" ||\n request.version !== 1 ||\n typeof request.session_id !== \"string\" ||\n typeof request.prompt !== \"string\"\n ) {\n reply({ ok: false });\n return;\n }\n const access = sessions.get(request.session_id);\n if (!access || !equalSecret(request.token, access.token)) {\n reply({ ok: false });\n return;\n }\n try {\n const result = await client.session.promptAsync({\n path: { id: request.session_id },\n body: { parts: [{ type: \"text\", text: request.prompt }] },\n query: { directory: access.directory },\n });\n if (result && result.error) {\n reply({ ok: false });\n return;\n }\n reply({ ok: true, session_id: request.session_id });\n } catch {\n reply({ ok: false });\n }\n })();\n });\n socket.on(\"error\", () => {});\n });\n\n try {\n await new Promise((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(socketPath, resolve);\n });\n } catch (error) {\n rmSync(bridgeDir, { recursive: true, force: true });\n throw error;\n }\n chmodSync(socketPath, 0o600);\n\n return {\n \"shell.env\": async (input, output) => {\n if (!input.sessionID) return;\n let access = sessions.get(input.sessionID);\n if (!access) {\n access = { token: randomBytes(32).toString(\"hex\"), directory: input.cwd };\n sessions.set(input.sessionID, access);\n } else {\n access.directory = input.cwd;\n }\n output.env.OPENCODE_PID = String(process.pid);\n output.env.OPENCODE_SESSION_ID = input.sessionID;\n output.env.LOBU_OPENCODE_BRIDGE_SOCKET = socketPath;\n output.env.LOBU_OPENCODE_BRIDGE_TOKEN = access.token;\n },\n dispose: async () => {\n disposed = true;\n sessions.clear();\n for (const socket of sockets) socket.destroy();\n sockets.clear();\n await new Promise((resolve) => {\n if (!server.listening) return resolve();\n server.close(resolve);\n });\n rmSync(bridgeDir, { recursive: true, force: true });\n },\n };\n};\n"; export type OpenCodePluginAction = "install" | "status" | "uninstall"; export declare function opencodePluginCommand(action: OpenCodePluginAction, env?: NodeJS.ProcessEnv): Promise; //# sourceMappingURL=opencode-plugin.d.ts.map