import { mkdtemp, readFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { serviceOpencodeConfig } from "../src/runtime/opencode2-config.js"; import { startOpencode2 } from "../src/runtime/opencode2-server.js"; import { assertWebSearchReady } from "../src/runtime/web-search-check.js"; const args = process.argv.slice(2); if (args.some((arg) => arg !== "--search") || args.length > 1) throw new Error("Usage: bun scripts/check-websearch.ts [--search]"); const root = await mkdtemp(join(tmpdir(), "tjwater-websearch-check-")); let native: Awaited> | undefined; const abort = new AbortController(); const stop = () => abort.abort(); process.once("SIGINT", stop); process.once("SIGTERM", stop); try { const source = JSON.parse(await readFile("opencode.json", "utf8")); native = await startOpencode2({ command: process.env.OPENCODE_COMMAND ?? "opencode2", hostname: "127.0.0.1", port: 0, timeout: 30_000, signal: abort.signal, config: serviceOpencodeConfig({ ...source, mcp: { servers: {} } }, undefined, root), env: { AGENT_INTERNAL_TOKEN: "SEARCH_CHECK_ONLY", TJWATER_AGENT_WORKSPACE_ROOT: root, TJWATER_AGENT_MCP_CONNECTION_PATH: join(root, "absent.json"), OPENCODE_DB: join(root, "data", "opencode.db"), XDG_DATA_HOME: join(root, "data"), XDG_CONFIG_HOME: join(root, "config"), XDG_CACHE_HOME: join(root, "cache"), XDG_STATE_HOME: join(root, "state") }, }); const location = { directory: process.cwd() }; await native.client.rpc.call({ rpcID: "tjwater.tools", method: "list", input: {}, location }, { signal: AbortSignal.any([abort.signal, AbortSignal.timeout(15_000)]), }); const report = await assertWebSearchReady(native.client, location.directory); if (!args.includes("--search")) console.log(JSON.stringify({ status: "catalog_ready", ...report })); else { const result = await native.client.websearch.query({ location, query: "OpenCode official documentation" }, { signal: AbortSignal.any([abort.signal, AbortSignal.timeout(30_000)]), }); console.log(JSON.stringify({ status: "search_succeeded", provider: result.data.providerID, result_count: result.data.results.length })); } } catch { console.error("Web search check failed; verify the configured provider, credentials and network. No model inference was requested."); process.exitCode = 1; } finally { native?.close(); if (native) await native.exited; process.removeListener("SIGINT", stop); process.removeListener("SIGTERM", stop); await rm(root, { recursive: true, force: true }); }