@skaile/workspaces 6.9.0 → 6.9.1
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/CHANGELOG.md +8 -0
- package/dist/{asset-feeds-JWRIWLVX.js → asset-feeds-PANNQPEE.js} +6 -6
- package/dist/{asset-feeds-JWRIWLVX.js.map → asset-feeds-PANNQPEE.js.map} +1 -1
- package/dist/asset-manager/index.js +1 -1
- package/dist/bridge/harnesses/claude-sdk.js +3 -3
- package/dist/bridge/harnesses/codex.js +3 -3
- package/dist/bridge/harnesses/continue.js +4 -4
- package/dist/bridge/harnesses/echo.js +2 -2
- package/dist/bridge/harnesses/gemini.js +5 -5
- package/dist/bridge/harnesses/goose.js +4 -4
- package/dist/bridge/harnesses/omp.js +39 -4
- package/dist/bridge/harnesses/omp.js.map +1 -1
- package/dist/bridge/harnesses/opencode.js +4 -4
- package/dist/bridge/harnesses/qwen.js +5 -5
- package/dist/bridge/index.js +7 -7
- package/dist/bridge/src/harnesses/omp.d.ts +11 -0
- package/dist/bridge/src/harnesses/omp.d.ts.map +1 -1
- package/dist/{chunk-PTJZCOBH.js → chunk-2UKNI2HJ.js} +2 -2
- package/dist/{chunk-PTJZCOBH.js.map → chunk-2UKNI2HJ.js.map} +1 -1
- package/dist/{chunk-CFTTXUM2.js → chunk-5J6N6LHL.js} +3 -3
- package/dist/{chunk-CFTTXUM2.js.map → chunk-5J6N6LHL.js.map} +1 -1
- package/dist/{chunk-SQMDFM4N.js → chunk-7TF5MNFK.js} +2 -2
- package/dist/{chunk-SQMDFM4N.js.map → chunk-7TF5MNFK.js.map} +1 -1
- package/dist/{chunk-AVRTZAH2.js → chunk-7UCPGQCW.js} +8 -8
- package/dist/{chunk-AVRTZAH2.js.map → chunk-7UCPGQCW.js.map} +1 -1
- package/dist/{chunk-MPRWVZXF.js → chunk-AQTAULXT.js} +4 -4
- package/dist/{chunk-MPRWVZXF.js.map → chunk-AQTAULXT.js.map} +1 -1
- package/dist/{chunk-SE6OL7Y5.js → chunk-BDAXHJC5.js} +6 -6
- package/dist/{chunk-SE6OL7Y5.js.map → chunk-BDAXHJC5.js.map} +1 -1
- package/dist/{chunk-V3EJYOP2.js → chunk-BLBXOG5Q.js} +4 -4
- package/dist/{chunk-V3EJYOP2.js.map → chunk-BLBXOG5Q.js.map} +1 -1
- package/dist/{chunk-GYBDWW6K.js → chunk-C324IAXI.js} +3 -3
- package/dist/{chunk-GYBDWW6K.js.map → chunk-C324IAXI.js.map} +1 -1
- package/dist/{chunk-5AQLCRR7.js → chunk-CPMLMNI5.js} +4 -4
- package/dist/{chunk-5AQLCRR7.js.map → chunk-CPMLMNI5.js.map} +1 -1
- package/dist/{chunk-JY2JXCL6.js → chunk-DJSGQW2Q.js} +3 -3
- package/dist/{chunk-JY2JXCL6.js.map → chunk-DJSGQW2Q.js.map} +1 -1
- package/dist/{chunk-3EPRTMXY.js → chunk-EMSU6L7K.js} +3 -3
- package/dist/{chunk-3EPRTMXY.js.map → chunk-EMSU6L7K.js.map} +1 -1
- package/dist/{chunk-B2DGCYVC.js → chunk-FZTHL6SK.js} +8 -8
- package/dist/{chunk-B2DGCYVC.js.map → chunk-FZTHL6SK.js.map} +1 -1
- package/dist/{chunk-DZRN3SNG.js → chunk-IISEBVMA.js} +3 -3
- package/dist/{chunk-DZRN3SNG.js.map → chunk-IISEBVMA.js.map} +1 -1
- package/dist/{chunk-AERQFD6T.js → chunk-J45JCYS4.js} +3 -3
- package/dist/{chunk-AERQFD6T.js.map → chunk-J45JCYS4.js.map} +1 -1
- package/dist/{chunk-V2CONXKD.js → chunk-KVTV4LT2.js} +3 -3
- package/dist/{chunk-V2CONXKD.js.map → chunk-KVTV4LT2.js.map} +1 -1
- package/dist/{chunk-72BDCGBB.js → chunk-MPO5CQUZ.js} +3 -3
- package/dist/{chunk-72BDCGBB.js.map → chunk-MPO5CQUZ.js.map} +1 -1
- package/dist/{chunk-WPLZGT5Z.js → chunk-PBEDRYHP.js} +23 -15
- package/dist/chunk-PBEDRYHP.js.map +1 -0
- package/dist/{chunk-5NTB64PW.js → chunk-PLVM6OIV.js} +8 -8
- package/dist/{chunk-5NTB64PW.js.map → chunk-PLVM6OIV.js.map} +1 -1
- package/dist/{chunk-X2B5GMJO.js → chunk-Q5SSRVD5.js} +6 -6
- package/dist/{chunk-X2B5GMJO.js.map → chunk-Q5SSRVD5.js.map} +1 -1
- package/dist/{chunk-T5EIWWEJ.js → chunk-QIV7H3GJ.js} +4 -4
- package/dist/{chunk-T5EIWWEJ.js.map → chunk-QIV7H3GJ.js.map} +1 -1
- package/dist/{chunk-4WB4KSSQ.js → chunk-RP3ML3QD.js} +3 -3
- package/dist/{chunk-4WB4KSSQ.js.map → chunk-RP3ML3QD.js.map} +1 -1
- package/dist/{chunk-NJVHGS7X.js → chunk-RZRJTCP2.js} +3 -3
- package/dist/{chunk-NJVHGS7X.js.map → chunk-RZRJTCP2.js.map} +1 -1
- package/dist/{chunk-YGT3CGPD.js → chunk-S47KU4YB.js} +3 -3
- package/dist/{chunk-YGT3CGPD.js.map → chunk-S47KU4YB.js.map} +1 -1
- package/dist/{chunk-XPKUFOS3.js → chunk-SME3PK4L.js} +3 -3
- package/dist/{chunk-XPKUFOS3.js.map → chunk-SME3PK4L.js.map} +1 -1
- package/dist/{chunk-23Q5LT4U.js → chunk-VEIWFS7Z.js} +2 -2
- package/dist/{chunk-23Q5LT4U.js.map → chunk-VEIWFS7Z.js.map} +1 -1
- package/dist/{chunk-Y2BQWZXT.js → chunk-WEPTGUR4.js} +5 -5
- package/dist/{chunk-Y2BQWZXT.js.map → chunk-WEPTGUR4.js.map} +1 -1
- package/dist/{chunk-Y242OE4B.js → chunk-X5SGUBUV.js} +3 -3
- package/dist/{chunk-Y242OE4B.js.map → chunk-X5SGUBUV.js.map} +1 -1
- package/dist/{chunk-M4G2SVXI.js → chunk-XB4XHGIE.js} +3 -3
- package/dist/{chunk-M4G2SVXI.js.map → chunk-XB4XHGIE.js.map} +1 -1
- package/dist/{chunk-C7L5MFUL.js → chunk-YPTDPN2B.js} +3 -3
- package/dist/{chunk-C7L5MFUL.js.map → chunk-YPTDPN2B.js.map} +1 -1
- package/dist/{chunk-O3FYOS64.js → chunk-ZUROGXJM.js} +5 -5
- package/dist/{chunk-O3FYOS64.js.map → chunk-ZUROGXJM.js.map} +1 -1
- package/dist/{claude-code-YRJIGXTL.js → claude-code-ILZ46SLO.js} +4 -4
- package/dist/{claude-code-YRJIGXTL.js.map → claude-code-ILZ46SLO.js.map} +1 -1
- package/dist/cli/index.js +52 -52
- package/dist/connectors/index.js +8 -8
- package/dist/{connectors-JKT32HZT.js → connectors-KTRUUKWG.js} +11 -11
- package/dist/{connectors-JKT32HZT.js.map → connectors-KTRUUKWG.js.map} +1 -1
- package/dist/{ensure-sources-GUJODKY5.js → ensure-sources-5QWKUIUD.js} +11 -11
- package/dist/{ensure-sources-GUJODKY5.js.map → ensure-sources-5QWKUIUD.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +8 -8
- package/dist/factory-assets/connectors/deploy.js +8 -8
- package/dist/factory-assets/connectors/devserver.js +8 -8
- package/dist/factory-assets/connectors/flow/adapter.js +8 -8
- package/dist/factory-assets/connectors/flow/run-flow.js +9 -9
- package/dist/factory-assets/connectors/flow.js +8 -8
- package/dist/factory-assets/connectors/git.js +8 -8
- package/dist/factory-assets/connectors/gmail.js +8 -8
- package/dist/factory-assets/connectors/googledrive.js +8 -8
- package/dist/factory-assets/connectors/local.js +8 -8
- package/dist/factory-assets/connectors/mattermost.js +8 -8
- package/dist/factory-assets/connectors/memory.js +8 -8
- package/dist/factory-assets/connectors/minio.js +8 -8
- package/dist/factory-assets/connectors/postgres.js +8 -8
- package/dist/factory-assets/connectors/s3.js +8 -8
- package/dist/factory-assets/connectors/sharepoint.js +8 -8
- package/dist/factory-assets/connectors/sqlite.js +8 -8
- package/dist/factory-assets/connectors/static-server.js +8 -8
- package/dist/factory-assets/connectors/tunnel.js +8 -8
- package/dist/factory-assets/connectors/webdav.js +8 -8
- package/dist/factory-assets/connectors/xstate-store.js +8 -8
- package/dist/factory-assets/connectors/xstate.js +8 -8
- package/dist/{helpers-SO53MRHF.js → helpers-INS4B7OQ.js} +11 -11
- package/dist/{helpers-SO53MRHF.js.map → helpers-INS4B7OQ.js.map} +1 -1
- package/dist/{library-publish-Z5E3YZCZ.js → library-publish-AZTYRASL.js} +24 -24
- package/dist/{library-publish-Z5E3YZCZ.js.map → library-publish-AZTYRASL.js.map} +1 -1
- package/dist/model-endpoint/index.js +3 -3
- package/dist/{open-library-A5OB72FD.js → open-library-3HMXYGUF.js} +12 -12
- package/dist/{open-library-A5OB72FD.js.map → open-library-3HMXYGUF.js.map} +1 -1
- package/dist/{project-KTEUN7KR.js → project-HVNPK2ZF.js} +20 -20
- package/dist/{project-KTEUN7KR.js.map → project-HVNPK2ZF.js.map} +1 -1
- package/dist/runner/index.js +14 -14
- package/dist/runner/src/agent-loop.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/turn-end-contract.d.ts.map +1 -1
- package/dist/runner/src/turn-scheduler.d.ts +8 -0
- package/dist/runner/src/turn-scheduler.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +1 -1
- package/dist/sdk/bridge.js +7 -7
- package/dist/sdk/index.js +14 -14
- package/dist/sdk/runner.js +14 -14
- package/dist/{serve-preflight-ODQGVUFL.js → serve-preflight-NHZOKHIC.js} +14 -14
- package/dist/{serve-preflight-ODQGVUFL.js.map → serve-preflight-NHZOKHIC.js.map} +1 -1
- package/dist/{setup-QJDI5YAW.js → setup-EX7Z7XRN.js} +12 -12
- package/dist/{setup-QJDI5YAW.js.map → setup-EX7Z7XRN.js.map} +1 -1
- package/dist/{source-FKOUYMEM.js → source-URRPRGMZ.js} +21 -21
- package/dist/{source-FKOUYMEM.js.map → source-URRPRGMZ.js.map} +1 -1
- package/dist/{source-manifest-publish-JA4TY4Z6.js → source-manifest-publish-ZWRYRJ2U.js} +23 -23
- package/dist/{source-manifest-publish-JA4TY4Z6.js.map → source-manifest-publish-ZWRYRJ2U.js.map} +1 -1
- package/dist/tui/index.js +14 -14
- package/dist/workspace-plugin/adapters/mcp.js +10 -10
- package/dist/workspace-plugin/adapters/omp.js +7 -7
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WPLZGT5Z.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../bridge/src/harnesses/omp.ts"],"names":["sessionDir"],"mappings":"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","file":"omp.js","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport type { EventEmitter } from \"node:events\";\nimport { rmSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport type { HarnessTarget } from \"@skaile/workspaces/plugin-registry\";\nimport {\n type HarnessContextReport,\n type Logger,\n type TokenUsage,\n withActivityLabelJsonSchema,\n} from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { classifyGenericErrorMessage } from \"../error-classifier.js\";\nimport { HARNESS_BINARIES } from \"../harness-binaries.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { checkToolInputSchema } from \"../mcp-tool-schema-filter.js\";\nimport type { ModelEntry } from \"../models.js\";\nimport { registryHarnessConfig } from \"../provider-registry-derive.js\";\nimport {\n type ReconfigureApplyResult,\n ReconfigureLedger,\n type ReconfigurePushContext,\n type ReconfigureSnapshot,\n} from \"../reconfigure-ledger.js\";\nimport { BUILTIN_HARNESS_CATALOG } from \"../registry.js\";\nimport { resolveAgentExec, wrapAgentCommand } from \"../agent-exec.js\";\nimport { RUNNER_AGENT_ENV_KEYS, stripRunnerPrivateEnv } from \"../runner-private-env.js\";\nimport {\n type AgentConfig,\n AgentHarness,\n type AgentError,\n type AgentPromptInput,\n type BridgeCapabilityTool,\n type HarnessInfo,\n type ReconfigureApplied,\n type ReconfigureOutcome,\n type ReconfigurePatch,\n type SlashCommandInfo,\n TOOL_ALLOWLIST_UNSUPPORTED,\n} from \"../types.js\";\nimport {\n isCredentialOmissionWarning,\n materializeOmpIdentityDir,\n materializeOmpProviders,\n registryModelEntries,\n} from \"./omp-models-yml.js\";\n\n/**\n * omp's own `No API key found for <provider>` text ends with `or create <home>/agent.db`:\n * the home is the session's private directory, a path nobody logs in at. Say what a user\n * can do instead: add the provider to the registry, or log in once with `omp`.\n * Any other message is returned as it came.\n */\nexport function ompCredentialMessage(msg: string): string {\n const match = /^(?:Error:\\s*)?No API key found for ([A-Za-z0-9._-]+?)\\.?(?:\\s|$)/.exec(msg);\n if (!match) return msg;\n const provider = match[1];\n const envName = `${provider.toUpperCase().replace(/[^A-Z0-9]/g, \"_\")}_API_KEY`;\n return (\n `No API key found for ${provider}. Add the provider with ` +\n `\\`skaile providers add ${provider} --credential env:${envName}\\`, ` +\n \"or log in once with `omp` (type /login).\"\n );\n}\n\n/**\n * Process-level vars omp needs to run at all, independent of any provider.\n */\nconst OMP_BASE_ENV_KEYS: readonly string[] = [\n \"PATH\",\n \"HOME\",\n \"USER\",\n \"HOSTNAME\",\n \"SKAILE_SESSION_ID\",\n ...RUNNER_AGENT_ENV_KEYS,\n];\n\n/**\n * Build the explicit env allowlist forwarded to the omp child process.\n *\n * The runner's full environment is never inherited — only\n * {@link OMP_BASE_ENV_KEYS} (process essentials) and the `PI_*` prefix (omp's\n * own app config the host operator may have set).\n *\n * **Credentials are not on this list.** Every endpoint omp may address is a\n * registry entry, serialized into the session's own `models.yml` with its\n * credential named as `SKAILE_AIP_<ID>_KEY` and the value assigned after this\n * allowlist is built (`./omp-models-yml.ts`). An ambient `ANTHROPIC_API_KEY`\n * in the runner's shell is not a session's statement of intent and does not\n * reach the child; `skaile providers add anthropic --preset anthropic\n * --credential env:ANTHROPIC_API_KEY` is.\n *\n * Test seams (`OMP_BRIDGE_*`, `FAKE_OMP_*`) are passed through so the\n * subprocess harness in `tests/omp-harness.test.ts` can drive a fake-omp\n * script via env-driven mode flags.\n *\n * @docLink packages/bridge/concepts#omp-env-whitelist\n */\nexport function buildOmpChildEnv(parent: NodeJS.ProcessEnv): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of OMP_BASE_ENV_KEYS) {\n const v = parent[key];\n if (typeof v === \"string\") out[key] = v;\n }\n for (const [key, value] of Object.entries(parent)) {\n if (typeof value !== \"string\") continue;\n if (key.startsWith(\"PI_\") || key.startsWith(\"OMP_BRIDGE_\") || key.startsWith(\"FAKE_OMP_\")) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * omp's built-in tools, as reported by `omp --help` (\"Available Tools\").\n *\n * `computer` is the one entry omp does not enable by default; everything else\n * is on unless `--tools` narrows the set. Used to turn a manifest *deny* list\n * into the *allow* list omp's CLI actually accepts.\n */\nexport const OMP_BUILTIN_TOOLS = [\n \"read\",\n \"bash\",\n \"edit\",\n \"write\",\n \"grep\",\n \"glob\",\n \"lsp\",\n \"python\",\n \"notebook\",\n \"browser\",\n \"computer\",\n \"task\",\n \"todo\",\n \"web_search\",\n \"ask\",\n] as const;\n\n/** omp's default-enabled toolset — every built-in except `computer`. */\nexport const OMP_DEFAULT_TOOLS: readonly string[] = OMP_BUILTIN_TOOLS.filter(\n (t) => t !== \"computer\",\n);\n\n/**\n * Canonical (Claude Code) tool name → omp built-in tool name.\n *\n * Agent manifests are authored once in the canonical vocabulary and run on\n * whichever harness the workspace is configured for, so the harness owns the\n * translation. Names already in omp's own spelling pass through unchanged.\n *\n * Deliberately partial: Claude tools with no omp counterpart (`WebFetch`,\n * `BashOutput`, `KillShell`, `mcp__*` server tools) are absent and get dropped\n * from the omp `--tools` value — omp's `--tools` governs built-ins only, so\n * naming a non-built-in there would be rejected, and silently keeping it would\n * not restrict anything.\n */\nconst CANONICAL_TO_OMP_TOOL: Record<string, string> = {\n read: \"read\",\n write: \"write\",\n edit: \"edit\",\n multiedit: \"edit\",\n notebookedit: \"notebook\",\n bash: \"bash\",\n grep: \"grep\",\n glob: \"glob\",\n ls: \"glob\",\n task: \"task\",\n agent: \"task\",\n todowrite: \"todo\",\n todoread: \"todo\",\n websearch: \"web_search\",\n web_search: \"web_search\",\n notebook: \"notebook\",\n lsp: \"lsp\",\n python: \"python\",\n browser: \"browser\",\n computer: \"computer\",\n todo: \"todo\",\n ask: \"ask\",\n askuserquestion: \"ask\",\n};\n\n/**\n * Translate a manifest tool list into omp built-in tool names.\n *\n * Unknown names are dropped rather than passed through: a manifest is expected\n * to run on more than one harness, so it legitimately names tools this one has\n * never heard of.\n */\nfunction toOmpToolNames(names: readonly string[] | undefined): string[] {\n const out: string[] = [];\n for (const raw of names ?? []) {\n const mapped = CANONICAL_TO_OMP_TOOL[raw.trim().toLowerCase().replace(/[\\s-]/g, \"\")];\n if (mapped && !out.includes(mapped)) out.push(mapped);\n }\n return out;\n}\n\n/**\n * Resolve `AgentConfig.tools` into the omp CLI flags that enforce it.\n *\n * omp expresses tool restriction as a positive `--tools a,b,c` list (or\n * `--no-tools`) — there is no deny flag — so a manifest deny list is applied by\n * subtracting from {@link OMP_DEFAULT_TOOLS}.\n *\n * Returns `[]` when the manifest declares no restriction, which leaves omp on\n * its full default toolset exactly as before. That default toolset is the bulk\n * of every request's fixed token prefix, so this is the lever an agent\n * definition needs in order to shrink it.\n *\n * Pure — exported for direct testing.\n *\n * @since 1.5.0\n */\nexport function buildOmpToolArgs(tools: AgentConfig[\"tools\"]): string[] {\n const allowed = toOmpToolNames(tools?.allowed);\n const denied = new Set(toOmpToolNames(tools?.denied));\n\n const declaredAllow = (tools?.allowed?.length ?? 0) > 0;\n const declaredDeny = (tools?.denied?.length ?? 0) > 0;\n if (!declaredAllow && !declaredDeny) return [];\n\n const base = declaredAllow ? allowed : [...OMP_DEFAULT_TOOLS];\n const effective = base.filter((t) => !denied.has(t));\n\n // An allow list that named only tools omp does not have, or a deny list that\n // removed everything, both mean \"no tools\" — say so explicitly rather than\n // emitting `--tools ` and letting omp fall back to the full default set.\n if (effective.length === 0) return [\"--no-tools\"];\n return [\"--tools\", effective.join(\",\")];\n}\n\n/**\n * Longest host tool name handed to omp. omp forwards host tool names to the\n * provider verbatim; Anthropic allows 128 characters, OpenAI-compatible\n * endpoints 64, so the stricter bound keeps every provider working.\n */\nconst OMP_HOST_TOOL_NAME_MAX = 64;\n\n/** One `set_host_tools` entry (`omp://rpc.md`, \"set_host_tools payload\"). */\nexport interface OmpHostToolDefinition {\n name: string;\n label: string;\n description: string;\n parameters: Record<string, unknown>;\n loadMode: \"essential\";\n}\n\n/** Result of {@link buildOmpHostTools}. */\nexport interface OmpHostToolSet {\n /** Definitions to send in `set_host_tools`. */\n definitions: OmpHostToolDefinition[];\n /** omp host tool name → capability name, for routing `host_tool_call`. */\n capabilityNames: Map<string, string>;\n /** Capabilities left out because the provider would reject their schema. */\n dropped: Array<{ tool: string; reason: string }>;\n}\n\n/**\n * Turn the runner's capability tool list into omp host tool definitions.\n *\n * omp accepts any name in `set_host_tools` but forwards it to the provider\n * as-is, and providers reject anything outside `^[a-zA-Z0-9_-]{1,64}$` with a\n * 400 that fails the whole turn (verified against omp 18.6.0 + Anthropic:\n * `app.editor.open` → `tools.3.custom.name: String should match pattern`).\n * Names are therefore sanitised (`app.editor.open` → `app_editor_open`) and\n * the original kept in `capabilityNames`. Collisions — with another\n * capability or with an omp built-in, which omp refuses — get a numeric\n * suffix.\n *\n * omp also forwards the JSON Schema untouched, so each advertised schema is\n * checked with the same rules the claude-sdk harness applies to raw MCP\n * schemas ({@link checkToolInputSchema}); a failing tool is dropped rather\n * than turning every request into a 400. `loadMode: \"essential\"` keeps every\n * capability in the prompt instead of behind omp's tool discovery, matching\n * claude-sdk where every capability is in the tool list.\n *\n * Pure — exported for direct testing.\n */\nexport function buildOmpHostTools(tools: readonly BridgeCapabilityTool[]): OmpHostToolSet {\n const taken = new Set<string>(OMP_BUILTIN_TOOLS);\n const out: OmpHostToolSet = { definitions: [], capabilityNames: new Map(), dropped: [] };\n for (const tool of tools) {\n // Advertise-only label, as in claude-sdk and codex; `dispatchCapability`\n // strips it before the registry sees the input.\n const parameters = { ...withActivityLabelJsonSchema(tool.parameters), type: \"object\" };\n const reason = checkToolInputSchema(parameters);\n if (reason) {\n out.dropped.push({ tool: tool.name, reason });\n continue;\n }\n const base =\n tool.name.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, OMP_HOST_TOOL_NAME_MAX) || \"capability\";\n let name = base;\n for (let n = 2; taken.has(name); n++) {\n const suffix = `_${n}`;\n name = `${base.slice(0, OMP_HOST_TOOL_NAME_MAX - suffix.length)}${suffix}`;\n }\n taken.add(name);\n out.capabilityNames.set(name, tool.name);\n out.definitions.push({\n name,\n label: tool.name,\n description: tool.description,\n parameters,\n loadMode: \"essential\",\n });\n }\n return out;\n}\n\n/** Thinking levels omp accepts for `--thinking` / `set_thinking_level`. omp drops anything else silently. */\nexport const OMP_THINKING_LEVELS = [\n \"off\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n \"auto\",\n] as const;\nexport type OmpThinkingLevel = (typeof OMP_THINKING_LEVELS)[number];\n\n/** Largest image attachment omp will be sent (Anthropic's 5 MB per-image limit). */\nconst OMP_MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Map `AgentConfig.thinking` / `effort` to an omp thinking level.\n *\n * `disabled` wins over `effort` → `off`. Otherwise an explicit `effort`\n * (low/medium/high/xhigh/max) maps to the same-named level (omp clamps `max` to\n * `xhigh` on models without it). Without effort, `enabled` → `medium` and\n * `adaptive` → `auto`. Returns `undefined` when neither is set (omp keeps its\n * own default) or when the value is outside omp's set — `set_thinking_level`\n * accepts garbage without an error, so validation has to happen here.\n */\nexport function ompThinkingLevel(\n cfg: Pick<AgentConfig, \"thinking\" | \"effort\">,\n): OmpThinkingLevel | undefined {\n const level = (() => {\n if (cfg.thinking === \"disabled\") return \"off\";\n if (cfg.effort) return cfg.effort;\n if (cfg.thinking === \"enabled\") return \"medium\";\n if (cfg.thinking === \"adaptive\") return \"auto\";\n return undefined;\n })();\n return level !== undefined && (OMP_THINKING_LEVELS as readonly string[]).includes(level)\n ? (level as OmpThinkingLevel)\n : undefined;\n}\n\n/**\n * Split a model selector into the `provider` / `modelId` pair `set_model`\n * takes. The registry renders selectors as `<providerId>/<providerModelId>`\n * (the spawn-time `--model` value); provider ids never contain `/` but model\n * ids can, so the split is on the FIRST `/`:\n * `openrouter/anthropic/claude-sonnet-4` → `{ provider: \"openrouter\", modelId: \"anthropic/claude-sonnet-4\" }`.\n * A bare name (no `provider/` prefix) cannot be expressed: omp's `--model`\n * fuzzy matching has no RPC equivalent, so the result is `undefined`.\n */\nexport function splitOmpModel(model: string): { provider: string; modelId: string } | undefined {\n const slash = model.indexOf(\"/\");\n if (slash > 0 && slash < model.length - 1) {\n return { provider: model.slice(0, slash), modelId: model.slice(slash + 1) };\n }\n return undefined;\n}\n\ninterface OmpEvent {\n type: string;\n data?: unknown;\n id?: string;\n success?: boolean;\n error?: string;\n message?: OmpMessage;\n [key: string]: unknown;\n}\n\ninterface OmpMessage {\n role?: string;\n content?: string | OmpContentBlock[];\n /**\n * Why the turn stopped. omp reports a failed request as a normal\n * `message_end` carrying `stopReason: \"error\"` rather than as an `error`\n * event, so this is the only signal that the turn failed.\n */\n stopReason?: string;\n /** Provider/transport error text accompanying `stopReason: \"error\"`. */\n errorMessage?: string;\n /** Final usage of this model call; running partials on `message_start`/updates are ignored. */\n usage?: OmpUsage;\n}\n\n/** Token counters on an assistant `message_end`; every field is optional and unvalidated. */\ninterface OmpUsage {\n input?: unknown;\n output?: unknown;\n cacheRead?: unknown;\n cacheWrite?: unknown;\n reasoningTokens?: unknown;\n totalTokens?: unknown;\n}\n\n/** omp RPC `ImageContent`: raw base64 (no `data:` prefix) plus its MIME type. */\ninterface OmpImageContent {\n type: \"image\";\n data: string;\n mimeType: string;\n}\n\ninterface OmpContentBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: unknown;\n thinking?: string;\n}\n\n/**\n * A question omp is parked on: the `extension_ui_request` the host still owes\n * an `extension_ui_response` for. One request can carry several questions;\n * the response goes out once every one has an answer.\n */\ninterface OmpPendingQuestion {\n /** Id of the `extension_ui_request`; the response must echo it. */\n id: string;\n /** `ask` answers with `answers[]`; the `select` fallback answers with `value`. */\n method: \"ask\" | \"select\";\n questions: Array<{ id: string; question: string; options: string[]; multi: boolean }>;\n /** The user's answer per question, by position; `undefined` while unanswered. */\n answers: Array<string | undefined>;\n}\n\n/** What the running omp process holds, for the reconfigure ledger. */\ninterface OmpApplied extends ReconfigureSnapshot {\n /** The omp thinking level last sent (or spawned with). */\n level?: OmpThinkingLevel;\n}\n\n/**\n * The line of omp's stderr that says why it gave up. omp prints an unrelated\n * warning first (a failed extension load) and the real cause last (`No default\n * model selected. Use /login ...`), so the cause is the last line that reads as\n * an error, else the last line. Escape sequences are stripped.\n */\nexport function ompStartFailureCause(lines: readonly string[]): string {\n const clean = lines\n // biome-ignore lint/suspicious/noControlCharactersInRegex: strips ANSI escapes\n .map((l) => l.replace(/\\u001b\\[[0-9;]*m/g, \"\").trim())\n .filter(Boolean);\n const isCause = (l: string) =>\n /\\b(error|no default model|not (?:found|installed|logged)|invalid|unauthori[sz]ed|cannot|can't|failed)\\b/i.test(\n l,\n ) && !/failed to load extension/i.test(l);\n for (let i = clean.length - 1; i >= 0; i--) {\n if (isCause(clean[i] as string)) return clean[i] as string;\n }\n return clean.at(-1) ?? \"\";\n}\n\n/** How long a killed omp gets to exit before its private home is deleted anyway. */\nconst KILLED_EXIT_WAIT_MS = 5000;\n\n/** What a turn rejects with when omp exits before showing any output: `prompt()` sends it again once. */\nclass EarlyOmpExit extends Error {\n constructor(\n readonly code: number | null,\n readonly signal: NodeJS.Signals | null,\n ) {\n super(`omp process crashed (exit code ${code})`);\n }\n}\n\n/**\n * Delete `home` again once the killed `proc` has exited. omp writes into its home while it\n * shuts down, so a delete done at the kill can leave a directory behind. Resolves when the\n * home is gone; never rejects.\n */\nfunction removeHomeAfterExit(proc: ChildProcess, home: string): Promise<void> {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => {\n resolve = r;\n });\n const timer = setTimeout(remove, KILLED_EXIT_WAIT_MS);\n timer.unref?.();\n function remove(): void {\n clearTimeout(timer);\n try {\n rmSync(home, { recursive: true, force: true });\n } catch {\n // A later start sweeps what is left.\n }\n resolve();\n }\n if (proc.exitCode !== null || proc.signalCode !== null) remove();\n else (proc as unknown as EventEmitter).once(\"exit\", remove);\n return promise;\n}\n\n/**\n * Agent harness for the oh-my-pi (omp) coding agent.\n *\n * Spawns `omp --mode rpc-ui --no-ui` as a child process and communicates via newline-delimited\n * JSON-RPC over stdin/stdout. Model-agnostic: supports any LLM provider.\n *\n * @see https://github.com/can1357/oh-my-pi\n *\n * @remarks\n * **Session persistence** — omp writes JSONL session files to `<cwd>/.omp/sessions/`\n * (via `--session-dir`). After each turn (`agent_end`), sends a `get_state` RPC to\n * capture the native session ID and emits a `session_info` event so the forge layer\n * can persist it. On the next spawn, callers pass `resumeSessionId` to restore omp's\n * native context.\n *\n * **stderrBuffer** — collects the last 20 lines of stderr so they can be appended to\n * crash error messages for diagnostics without blocking the stdout readline loop.\n *\n * **systemPrompt injection** — omp does not accept a system prompt string directly.\n * The harness writes `AgentConfig.systemPrompt` to a file of its own under\n * `<cwd>/.skaile/cache/omp-system/`, passes the path via `--append-system-prompt` and deletes\n * the file when the process ends.\n *\n * **agentDir** — omp's home (`PI_CODING_AGENT_DIR`) is a private directory outside `cwd`\n * that links in the entries of the GitAgent directory (agent.yaml, RULES.md, knowledge/), so\n * omp's runtime databases never land beside the pinned agent files. omp reads no SOUL.md:\n * the runner puts the soul into `systemPrompt`.\n *\n * **Capabilities** — `AgentConfig.capabilities` (Protocol v2) is registered with omp\n * as host tools (`set_host_tools`) once the process is ready, and again whenever the\n * registry reports a change. omp calls them back with `host_tool_call`, answered via\n * `dispatchCapability` exactly as claude-sdk's `skaile-capabilities` MCP server does.\n * Names are sanitised for the provider; see {@link buildOmpHostTools}.\n *\n * **Questions** — omp's `ask` tool is enabled as one `extension_ui_request` dialog\n * (`set_ask_dialog`), published as the same `question` events as claude-sdk's\n * `AskUserQuestion` and answered through {@link OmpHarness.answerQuestion}. The turn stays\n * parked in omp until then; abort, kill and process exit release it. Dialogs the host\n * cannot answer (`confirm`, `input`, `editor`) are cancelled immediately.\n *\n * @docLink packages/bridge/harnesses#omp-harness\n */\nexport class OmpHarness extends AgentHarness {\n readonly harnessInfo: HarnessInfo = {\n id: \"omp\",\n name: \"omp (oh-my-pi)\",\n modelAgnostic: true,\n supportsInBandAbort: true,\n capabilities: BUILTIN_HARNESS_CATALOG.omp?.capabilities,\n };\n\n private readonly log: Logger = getBridgeLogger(\"omp\");\n private proc: ChildProcess | null = null;\n private rl: Interface | null = null;\n private reqId = 0;\n private config: AgentConfig;\n private ready = false;\n private startPromise: Promise<void> | null = null;\n private stderrBuffer: string[] = [];\n private prevText = \"\";\n /** OMP session ID captured via `get_state` after each turn. */\n private _ompSessionId?: string;\n /**\n * The omp session the last unexpected exit left behind, set as `config.resumeSessionId` for\n * the respawn; cleared once a respawn on it fails (the next one starts empty).\n */\n private exitResumeSessionId?: string;\n /**\n * Usage of the most recent turn, summed over every model call in it (a tool\n * loop is one prompt but many assistant messages). Cleared when a turn\n * starts, like claude-sdk, so it never mixes two turns.\n */\n private _lastTokens: TokenUsage | null = null;\n /**\n * Prompt size of the most recent model call: the real context fill, which\n * `_lastTokens` (turn-cumulative) overstates on a tool loop. omp's own\n * `get_state.contextUsage.tokens` replaces it once that reply lands.\n */\n private _lastContextTokens: number | null = null;\n /** Context window of the active model, from `get_state.contextUsage`. */\n private _contextWindow: number | null = null;\n /** Per-spawn file holding the system prompt omp was started with; removed with the process. */\n private systemPromptFile: string | null = null;\n /** The private omp home of the running process, when it is the harness's own temporary one. */\n private privateHome: string | null = null;\n /** Settles when the process last killed has exited and its private home is deleted. */\n private homeGone: Promise<void> = Promise.resolve();\n\n override getTokenUsage(): TokenUsage | null {\n return this._lastTokens;\n }\n\n override getContextTokens(): number | null {\n return this._lastContextTokens;\n }\n\n override getContextWindow(): number | null {\n return this._contextWindow;\n }\n\n /**\n * omp reports only its fill and window (`get_state.contextUsage`), refreshed\n * here so a request between turns is current. A local RPC, so cheap. Unlike\n * `captureState` it throws on a failed reply: a stale fill must never be\n * reported as a fresh measurement.\n */\n override async getContextUsageReport(): Promise<HarnessContextReport | null> {\n if (!this.proc) return null;\n const response = await this.request({ type: \"get_state\" }, { quiet: true });\n if (!response.success) {\n throw new Error(`omp get_state failed: ${response.error ?? \"no error given\"}`);\n }\n this.captureContextUsage((response.data as Record<string, unknown> | undefined)?.contextUsage);\n if (this._lastContextTokens === null && this._contextWindow === null) return null;\n return { usedTokens: this._lastContextTokens, contextWindow: this._contextWindow };\n }\n\n /** Per-turn settlement handlers; non-null only while a prompt is in flight. */\n private turnResolve: (() => void) | null = null;\n private turnReject: ((err: Error) => void) | null = null;\n /** omp host tool name → capability name for the last `set_host_tools` sent. */\n private hostToolCapabilities = new Map<string, string>();\n /** In-flight `host_tool_call`s by omp request id; aborted by `host_tool_cancel`. */\n private readonly hostToolCalls = new Map<string, { controller: AbortController; name: string }>();\n /** Requests awaiting a `response`, by request id; failed when the process goes away. */\n private readonly pendingRequests = new Map<string, (err: Error) => void>();\n /** Unsubscribes the capability registry listener; set while a process runs. */\n private unsubscribeToolsChanged: (() => void) | null = null;\n /** Request ids whose failed `response` is logged by the caller, not surfaced as an error event. */\n private readonly quietRequestIds = new Set<string>();\n /** Capability tools already warned about, so a re-send logs each once. */\n private readonly warnedDroppedHostTools = new Set<string>();\n /** The `ask` (or `select` fallback) omp is parked on, until answered, cancelled or the process ends. */\n private pendingQuestion: OmpPendingQuestion | null = null;\n /**\n * Tail of the FIFO of prompts: each `prompt()`/`promptInput()` runs only after\n * the previous one settled, so one turn at a time is ever in flight (omp runs\n * a single agent loop). Never rejects.\n */\n private promptTail: Promise<void> = Promise.resolve();\n /** `true` while `agent_end` is being delivered to listeners. */\n private turnEnded = false;\n /** `true` once the current turn showed model output (text, a thinking delta or a tool run). */\n private turnOutputSeen = false;\n /** `true` once `runPrompt` sent the current prompt a second time after an early exit. */\n private promptRetried = false;\n /** `true` once omp recorded the current prompt as a user message in its session. */\n private turnUserMessageSeen = false;\n /** Counts `kill()` calls, so a prompt that restarts omp itself can tell it was killed meanwhile. */\n private killEpoch = 0;\n\n override get runtimeSessionId(): string | undefined {\n return this._ompSessionId;\n }\n\n /** Slash commands from omp's last `available_commands_update`. */\n private cachedCommands: SlashCommandInfo[] = [];\n\n override getSlashCommands(): SlashCommandInfo[] {\n return this.cachedCommands;\n }\n\n override getModel(): string | undefined {\n return this.config.model;\n }\n\n /**\n * Owns the desired config, drift and ordering of live reconfigures. Its\n * snapshot is what the running omp process was last told: the config values\n * `model`, `modelRef`, `thinking` and `effort` came from (the rollback targets\n * when omp refuses a change) and the omp thinking `level` sent. Set at spawn,\n * updated on each successful `set_*`.\n */\n private readonly reconfig: ReconfigureLedger<OmpApplied>;\n\n /**\n * Apply `model` / `thinking` / `effort`: the {@link ReconfigureLedger} writes\n * the desired config and, when the process is up and idle, pushes it through\n * {@link applyLive} (`set_model` / `set_thinking_level`), answering from omp's\n * reply. A patch that arrives mid-turn or before `ready` is not lost: config is\n * the source of truth, flushed before the next `prompt()` and read by the next\n * spawn. A refusal (omp's, or a model `set_model` cannot express live: no\n * `provider/` prefix) rolls the config back and answers `rejected`. In registry\n * mode the patch also replaces `modelRef`, so a respawn (crash, `resetSession()`)\n * starts the reconfigured model; models.yml already lists every enabled provider.\n */\n override reconfigure(patch: ReconfigurePatch): Promise<ReconfigureOutcome> {\n return this.reconfig.reconfigure(patch);\n }\n\n /** Push drifted model / thinking settings to the running process. Never rejects. */\n private async applyLive(\n delta: ReconfigureApplied,\n applied: OmpApplied,\n { late }: ReconfigurePushContext,\n ): Promise<ReconfigureApplyResult> {\n if (delta.model !== undefined) {\n const target = splitOmpModel(delta.model);\n if (!target) {\n // `set_model` cannot express a bare name, so the running process keeps\n // its model: refuse rather than report one omp is not running.\n const message = `set_model cannot apply \"${delta.model}\" live (no provider/ prefix); model unchanged`;\n this.log.warn(\"model has no provider prefix; set_model cannot apply it live\", {\n model: delta.model,\n });\n if (!late) this.emit(\"agent-event\", { type: \"error\", error: message });\n return { rejected: message };\n }\n const refusal = await this.sendReconfigure({ type: \"set_model\", ...target }, late);\n if (refusal !== null) return { rejected: refusal };\n applied.model = delta.model;\n applied.modelRef = delta.modelRef ?? applied.modelRef;\n }\n\n if (delta.thinking !== undefined || delta.effort !== undefined) {\n const level = ompThinkingLevel(this.config);\n if (level !== undefined && level !== applied.level) {\n const refusal = await this.sendReconfigure({ type: \"set_thinking_level\", level }, late);\n if (refusal !== null) return { rejected: refusal };\n applied.level = level;\n }\n }\n return \"applied\";\n }\n\n /**\n * Send one live-reconfigure request. A failed `response` is emitted as an\n * `error` event by {@link handleEvent}, and a transport failure (timeout,\n * process gone) here, unless `late`: a refusal of a patch already answered\n * `ok` reaches the host as `reconfigure_rejected`, so it gets no `error`\n * event as well. Returns `null` when omp accepted it, else why not.\n */\n private async sendReconfigure(\n msg: { type: string; [key: string]: unknown },\n late: boolean,\n ): Promise<string | null> {\n try {\n const resp = await this.request(msg, { quiet: late });\n if (resp.success) return null;\n this.log.warn(\"omp rejected reconfigure\", { type: msg.type, error: resp.error });\n return typeof resp.error === \"string\" ? resp.error : `omp refused ${msg.type}`;\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err);\n this.log.warn(\"reconfigure request failed\", { type: msg.type, error });\n if (!late) {\n this.emit(\"agent-event\", { type: \"error\", error: `${msg.type} failed: ${error}` });\n }\n return `${msg.type} failed: ${error}`;\n }\n }\n\n /**\n * @param config - Harness configuration. omp-relevant fields:\n * - `cwd` — working directory; omp session files are stored under `<cwd>/.omp/sessions/`.\n * - `model` — forwarded as `--model <selector>`. In registry mode `modelRef` takes precedence at spawn; `reconfigure({ model })` keeps both in step.\n * - `systemPrompt` — written to a per-spawn file under `<cwd>/.skaile/cache/omp-system/` and appended via `--append-system-prompt`.\n * - `agentDir` — its entries are linked into omp's private home (`PI_CODING_AGENT_DIR`); the directory itself is never omp's home.\n * - `sshKeyPath` — injected as `GIT_SSH_COMMAND` for authenticated git operations.\n * - `resumeSessionId` — omp session UUID to restore via `--session <id>`.\n */\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n this.reconfig = new ReconfigureLedger<OmpApplied>({\n config: () => this.config,\n isLive: () => this.proc !== null && this.ready,\n isIdle: () => !this.turnResolve,\n applyLive: (delta, applied, context) => this.applyLive(delta, applied, context),\n onLateRejection: (rollback) => this.emit(\"reconfigure-rollback\", rollback),\n log: this.log,\n });\n }\n\n public async start(): Promise<void> {\n // In-flight start first: `proc` is set before `ready` and before the host\n // tools are registered, and callers must not prompt ahead of either.\n if (this.startPromise) return this.startPromise;\n if (this.proc) return;\n // A start that fails before omp is running (home or env setup, a spawn error) must not\n // leave the per-spawn system prompt file behind.\n this.startPromise = this._start()\n .then(() => {\n this.exitResumeSessionId = undefined;\n })\n .catch(async (err: unknown) => {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n // A restart that reopens the session omp lost can fail on that very session (its file is\n // gone or unreadable): start once more empty rather than leave the harness unusable.\n const resumeId = this.exitResumeSessionId;\n if (resumeId !== undefined && this.config.resumeSessionId === resumeId) {\n this.log.warn(\"omp did not restart on its previous session; starting a new one\", {\n sessionId: resumeId,\n error: err instanceof Error ? err.message : String(err),\n });\n this.exitResumeSessionId = undefined;\n this._ompSessionId = undefined;\n this.config = { ...this.config, resumeSessionId: undefined };\n return this._start().catch((retryErr: unknown) => {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n throw retryErr;\n });\n }\n throw err;\n });\n return this.startPromise;\n }\n\n private async _start(): Promise<void> {\n // `rpc-ui` keeps omp's tool UI (the `ask` dialog) on the wire; `--no-ui`\n // keeps its extensions headless, so no widget/notify frames or approval dialogs.\n const args = [\"--mode\", \"rpc-ui\", \"--no-ui\"];\n\n // ── Session persistence ───────────────────────────────────────────────────\n // Store OMP session files in <cwd>/.omp/sessions/ so they survive process\n // restarts. The caller passes resumeSessionId to restore a prior session.\n const sessionDir = path.join(this.config.cwd, \".omp\", \"sessions\");\n await fs.mkdir(sessionDir, { recursive: true });\n args.push(\"--session-dir\", sessionDir);\n\n if (this.config.resumeSessionId) {\n this.log.info(\"resuming OMP session\", { sessionId: this.config.resumeSessionId });\n args.push(\"--session\", this.config.resumeSessionId);\n }\n\n // ── Provider registry → session-private omp agent directory ───────────────\n // Every enabled registry entry is serialized into omp's own `models.yml`\n // inside a directory `PI_CODING_AGENT_DIR` points at, so an omp session\n // sees N selectable providers and resolves `@role` across them. Returns\n // undefined for a session that carries no registry, which keeps the\n // legacy `provider`/`model`/env path byte-identical.\n const providers = await materializeOmpProviders(this.config);\n if (providers) {\n // Known to cleanup() from here on, so a later start step that throws cannot leave it behind.\n this.privateHome = providers.ephemeral ? providers.agentDir : null;\n // A credential omission is printed once by `skaile run`/`repl` as the `! provider ... is\n // not used` line; the other warnings are plain text, not a raw JSON record (p598).\n for (const warning of providers.warnings) {\n if (isCredentialOmissionWarning(warning)) this.log.debug(warning);\n else this.log.warn(warning);\n }\n this.log.info(\"rendered omp models.yml\", {\n agentDir: providers.agentDir,\n providers: providers.providerIds,\n modelRoles: providers.modelRoles,\n seeded: providers.seeded.length,\n });\n } else if (this.config.registry) {\n // No usable entry, the selected model's entry was left out, or the session names no\n // model and the user's own omp default needs their own models.yml (p1172): omp runs on\n // the user's own agent directory and login.\n this.log.info(\"registry is not applied to omp; omp uses its own login and models\");\n }\n\n const modelArg = providers?.modelArg ?? this.config.model;\n if (modelArg) args.push(\"--model\", modelArg);\n\n // Thinking level: `--thinking <level>` (omp's default is `high`). The\n // spawn-time snapshot lets `reconfigure()` send only what has drifted.\n const thinkingLevel = ompThinkingLevel(this.config);\n if (thinkingLevel) args.push(\"--thinking\", thinkingLevel);\n this.reconfig.setSnapshot({\n model: this.config.model,\n modelRef: this.config.modelRef,\n thinking: this.config.thinking,\n effort: this.config.effort,\n level: thinkingLevel,\n });\n\n // ── Tool restrictions ─────────────────────────────────────────────────────\n // agent.yaml `tools:` reaches the harness as AgentConfig.tools. The\n // claude-sdk harness has always honoured it; omp did not, so a restricted\n // agent definition silently ran with omp's full default toolset — which\n // dominates the fixed token prefix of every request.\n const toolArgs = buildOmpToolArgs(this.config.tools);\n if (toolArgs.length > 0) {\n this.log.info(\"applying tool restrictions\", { args: toolArgs });\n args.push(...toolArgs);\n }\n\n // ── System prompt injection ───────────────────────────────────────────────\n // omp does not accept a system prompt string directly; it reads from a file.\n // The file is private to this spawn and goes away with the process: a fixed\n // `<cwd>/.omp/system.md` is loaded by every native omp session and sub-agent that\n // runs in the same project afterwards, and the nested `agent.run` child of one run\n // overwrote the parent's (last writer wins). The path is passed via\n // --append-system-prompt.\n //\n // In flow mode (factory-assets/connectors/flow/run-flow.ts conductFlow), systemPrompt carries the full agent\n // identity (SOUL + RULES + knowledge + connector docs) because no agentDir is set.\n // In REPL mode (agent.ts buildHarness), systemPrompt carries the runner's agent sections\n // (the soul included: omp reads no SOUL.md) and the connector docs.\n this.removeSystemPromptFile();\n if (this.config.systemPrompt) {\n const promptDir = path.join(this.config.cwd, \".skaile\", \"cache\", \"omp-system\");\n await fs.mkdir(promptDir, { recursive: true });\n const systemFile = path.join(promptDir, `${randomUUID()}.md`);\n await fs.writeFile(systemFile, this.config.systemPrompt);\n this.systemPromptFile = systemFile;\n args.push(\"--append-system-prompt\", systemFile);\n }\n\n // Explicit env whitelist for the omp child process. Avoids leaking the\n // runner's full environment (which may carry user secrets provisioned by\n // the platform) into the spawned subprocess. `this.config.env`, when\n // supplied, is merged over the whitelist (the caller wins per key), never\n // used in its place: a replaced env drops PATH and the spawn fails with\n // ENOENT (the model endpoint hands the harness only its endpoint variables).\n const env: Record<string, string> = {\n ...buildOmpChildEnv(process.env),\n ...(this.config.env as Record<string, string> | undefined),\n };\n // ── Main-agent handoff ────────────────────────────────────────────────────\n // PI_CODING_AGENT_DIR is omp's home: its runtime databases, credential store and\n // settings live there. It is never the agent directory itself: that holds the pinned\n // agent files (`.skaile/cache/agents/<name>/`) and omp's databases do not belong\n // beside them. omp reads `RULES.md` (not `SOUL.md`) from its home, so the agent's\n // entries are linked into a private home directory (see `materializeOmpIdentityDir`).\n // A rendered registry owns that home: it already contains the agent's files\n // (linked in from `agentDir`) plus the session's `models.yml` / `config.yml`.\n if (providers) {\n env.PI_CODING_AGENT_DIR = providers.agentDir;\n // The only place a credential *value* exists in this adapter. Registry\n // credentials override the ambient allowlist unconditionally: the\n // session's registry is the statement of intent, not whatever the host\n // happened to export.\n Object.assign(env, providers.credentialEnv);\n } else if (this.config.agentDir) {\n const home = await materializeOmpIdentityDir(this.config);\n if (home) {\n this.log.info(\"omp home for the agent\", { agentDir: home.agentDir });\n env.PI_CODING_AGENT_DIR = home.agentDir;\n this.privateHome = home.ephemeral ? home.agentDir : null;\n }\n }\n if (this.config.sshKeyPath) {\n env.GIT_SSH_COMMAND = `ssh -i \"${this.config.sshKeyPath}\" -o StrictHostKeyChecking=accept-new`;\n }\n stripRunnerPrivateEnv(env);\n\n // test-only: `OMP_BRIDGE_BIN` overrides the binary name and `OMP_BRIDGE_PREARGS`\n // (space-delimited) supplies any leading args (e.g. a JS script path when the\n // override binary is `node` or `bun`). Used by the subprocess harness tests in\n // `tests/omp-harness.test.ts` to point spawn at a fake-omp script without\n // monkey-patching `node:child_process`. Both are ignored in production.\n const overrideBin = process.env.OMP_BRIDGE_BIN;\n const overridePreArgs = process.env.OMP_BRIDGE_PREARGS\n ? process.env.OMP_BRIDGE_PREARGS.split(/\\s+/).filter(Boolean)\n : [];\n const spawnBin = overrideBin || \"omp\";\n const spawnArgs = overrideBin ? [...overridePreArgs, ...args] : args;\n\n const spawned = await new Promise<ChildProcess>((resolve, reject) => {\n const startStderr: string[] = [];\n this.log.info(\"spawning omp\", {\n bin: spawnBin,\n args: spawnArgs,\n cwd: this.config.cwd,\n });\n if (env.PI_CODING_AGENT_DIR)\n this.log.debug(\"env: PI_CODING_AGENT_DIR set\", { value: env.PI_CODING_AGENT_DIR });\n if (env.GIT_SSH_COMMAND) this.log.debug(\"env: GIT_SSH_COMMAND set\");\n\n // Cast to ChildProcess: spawn infers ChildProcessWithoutNullStreams for\n // pipe stdio, but bun-types doesn't expose EventEmitter.on on that subtype.\n // With the uid split on, omp runs as the agent uid through the launch shim.\n const target = wrapAgentCommand(spawnBin, spawnArgs, resolveAgentExec());\n const proc = spawn(target.command, target.args, {\n cwd: this.config.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }) as ChildProcess;\n this.proc = proc;\n // bun-types 1.3.11 omits EventEmitter.on from ChildProcess; cast to subscribe.\n const procEmitter = proc as unknown as EventEmitter;\n\n procEmitter.on(\"error\", (err: Error) => {\n // A process replaced (or killed) by kill()/resetSession() no longer\n // owns the turn, the ready state or the error channel.\n if (this.proc !== proc) {\n clearTimeout(readyTimeout);\n reject(err);\n return;\n }\n const detail = this.classifyProcessError(err as NodeJS.ErrnoException);\n this.log.error(\"process error\", err, { detail });\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n if (!this.ready) reject(err);\n // Settle any in-flight turn so a process-level error cannot hang prompt().\n this.rejectTurn(Object.assign(new Error(detail.message), { detail }));\n });\n\n procEmitter.on(\"exit\", (code: number | null, signal: NodeJS.Signals | null) => {\n this.log.info(\"process exited\", { code, signal });\n if (this.proc !== proc) {\n // Killed or replaced by kill()/resetSession(): the kill settled its own\n // turn and cleaned up, and a late exit must neither reject the turn of\n // the process that succeeded it nor tear down that process's state.\n // A start still waiting for `ready` on this process is over.\n clearTimeout(readyTimeout);\n reject(new Error(\"omp process killed before it was ready\"));\n // Only a plain kill() is announced; a live successor is not exiting.\n if (this.proc === null) this.emit(\"exit\", { code, signal });\n return;\n }\n const lastStderr = this.stderrBuffer.slice(-10).join(\"\\n\");\n const crashed = code !== null && code !== 0;\n // An exit while no turn is in flight (and after omp was ready) loses nothing the client\n // is waiting for: the next prompt starts omp again on the same session. It is logged\n // with omp's last stderr lines, not sent as an error the client must treat as fatal.\n const wasReady = this.ready;\n const betweenTurns = wasReady && this.turnReject === null;\n if (wasReady) {\n const sessionId = this._ompSessionId;\n // The respawn reopens the conversation omp had: without this it starts empty.\n if (sessionId) {\n this.config = { ...this.config, resumeSessionId: sessionId };\n this.exitResumeSessionId = sessionId;\n }\n if (betweenTurns) {\n this.log.warn(\"omp exited between turns; it restarts on the next prompt\", {\n code,\n signal,\n resumeSessionId: sessionId ?? null,\n stderr: lastStderr || null,\n });\n } else if (lastStderr) {\n this.log.warn(\"omp exited during a turn\", { code, signal, stderr: lastStderr });\n }\n }\n // A restart on the session omp lost that fails is retried on a new session by start().\n const resumeAttempt =\n !wasReady &&\n this.exitResumeSessionId !== undefined &&\n this.config.resumeSessionId === this.exitResumeSessionId;\n // An exit in a turn before omp showed any output is retried once by `runPrompt`: the\n // error the client would treat as fatal is held back for it.\n // A session omp already wrote the prompt into is not reopened to send it again.\n const wouldDuplicate =\n this.turnUserMessageSeen && this.config.resumeSessionId !== undefined;\n const retryEarly =\n (crashed || signal !== null) &&\n wasReady &&\n !betweenTurns &&\n !this.turnOutputSeen &&\n !wouldDuplicate &&\n !this.promptRetried &&\n !resumeAttempt;\n if (retryEarly) {\n this.log.warn(\"omp exited in a turn before its first output\", {\n code,\n signal,\n stderr: lastStderr || null,\n });\n } else if (crashed && !betweenTurns && !resumeAttempt) {\n // Without stderr nothing says why omp stopped: name the exit and where its session\n // files are, so the run can be looked at.\n const sessionDir = path.join(this.config.cwd, \".omp\", \"sessions\");\n const detail: AgentError = {\n message: `omp process crashed (exit code ${code})${lastStderr ? `: ${lastStderr}` : \"\"}`,\n category: \"process\",\n retryable: true,\n hint:\n lastStderr ||\n `omp exited with code ${code}${signal ? ` (signal ${signal})` : \"\"} and wrote nothing to stderr; its session files are in ${sessionDir}. Try sending your prompt again.`,\n };\n if (!lastStderr) {\n this.log.warn(\"omp exited with no stderr\", {\n code,\n signal,\n sessionDir,\n sessionId: this._ompSessionId ?? null,\n });\n }\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n }\n // An exit before `ready` ends the start: without this the start promise never\n // settles (the ready timeout skips a gone process), and a caller awaiting it\n // hangs, or the process ends on a pending top-level await. Rejected on `close`\n // so omp's last stderr lines (the reason it gave up) are read first.\n if (!this.ready) {\n clearTimeout(readyTimeout);\n // Settles once: on `close` (stdio drained), or after 1 s if `close` never fires.\n // Not unref'd, so the pending start keeps the process alive until it rejects.\n const rejectStart = () => {\n clearTimeout(fallback);\n reject(\n new Error(\n `omp exited before it was ready (${code !== null ? `exit code ${code}` : `signal ${signal}`})${startStderr.length > 0 ? `: ${ompCredentialMessage(ompStartFailureCause(startStderr))}` : \"\"}`,\n ),\n );\n };\n const fallback = setTimeout(rejectStart, 1000);\n procEmitter.once(\"close\", rejectStart);\n }\n this.cleanup();\n // Settle any in-flight turn: an exit before `agent_end` means the turn\n // can never complete normally, so reject rather than leak a pending promise.\n this.rejectTurn(\n retryEarly\n ? new EarlyOmpExit(code, signal)\n : new Error(\n crashed\n ? `omp process crashed (exit code ${code})`\n : `omp process exited before the turn completed${signal ? ` (signal ${signal})` : \"\"}`,\n ),\n );\n this.emit(\"exit\", { code, signal });\n });\n\n if (proc.stdout) {\n const rl = createInterface({ input: proc.stdout });\n this.rl = rl;\n // bun-types 1.3.11 omits EventEmitter.on from readline.Interface; cast to subscribe.\n (rl as unknown as EventEmitter).on(\"line\", (line: string) => {\n if (!line.trim()) return;\n try {\n const event: OmpEvent = JSON.parse(line);\n this.handleEvent(event);\n } catch {\n this.log.debug(\"stdout\", { line });\n }\n });\n }\n\n // Before omp is ready its stderr is the cause of a failed start, and the start error\n // carries that cause once (p598). The lines go to the debug log meanwhile; a start that\n // succeeds replays them as warnings, so a notice of a working omp is not lost.\n const replayStartStderr = (): void => {\n for (const line of startStderr) this.log.warn(`stderr: ${line}`);\n };\n if (proc.stderr) {\n const stderrRl = createInterface({ input: proc.stderr });\n (stderrRl as unknown as EventEmitter).on(\"line\", (line: string) => {\n if (this.ready) this.log.warn(`stderr: ${line}`);\n else this.log.debug(`stderr: ${line}`);\n this.stderrBuffer.push(line);\n if (this.stderrBuffer.length > 20) this.stderrBuffer.shift();\n startStderr.push(line);\n if (startStderr.length > 20) startStderr.shift();\n });\n }\n\n const startTime = Date.now();\n const readyTimeout = setTimeout(() => {\n // Not for a process that was replaced or has gone: it must not mark the\n // harness (now owned by a successor, or stopped) as ready.\n if (!this.ready && this.proc === proc) {\n this.log.warn(\"ready timeout, proceeding\", { timeoutMs: 5000 });\n this.ready = true;\n replayStartStderr();\n resolve(proc);\n }\n }, 5000);\n\n this.once(\"ready\", () => {\n clearTimeout(readyTimeout);\n if (!this.ready && this.proc === proc) {\n this.log.info(\"process ready\", { elapsedMs: Date.now() - startTime });\n this.ready = true;\n replayStartStderr();\n resolve(proc);\n }\n });\n });\n\n // Every await below can span a kill()/resetSession(): the successor owns the\n // harness state then, so a start for this process must not touch it.\n const assertCurrent = (): void => {\n if (this.proc !== spawned) throw new Error(\"omp process was killed during start\");\n };\n\n assertCurrent();\n // Subscribed before the requests so a registry change that lands while they\n // are in flight is not missed. There is no await between the check and the\n // subscription, so a later kill()'s cleanup() always unsubscribes it.\n const hooks = this.config.capabilities;\n if (hooks) {\n this.unsubscribeToolsChanged =\n hooks.onToolsChanged?.(() => {\n void this.syncHostTools();\n }) ?? null;\n }\n\n // Independent of each other, so concurrent: a misbehaving omp blocks start\n // for one request timeout, not two. Both are best-effort and never throw.\n // Before start() resolves, so the first `ask` already arrives as one dialog\n // and the first prompt already sees the tools.\n await Promise.all([this.enableAskDialog(), hooks ? this.syncHostTools() : undefined]);\n assertCurrent();\n\n // Context fill is known before the first prompt (system prompt + tools);\n // best-effort and not awaited, so a slow `get_state` never delays start().\n void this.captureState({ announceSession: false });\n }\n\n /**\n * Register the runner's capabilities with omp as host tools.\n *\n * Sends the full set every time: `set_host_tools` replaces omp's previous\n * host-owned set, so a registry change that removes a capability takes\n * effect too. Best-effort — a failure is logged and the session runs\n * without host tools rather than failing to start.\n */\n private async syncHostTools(): Promise<void> {\n const hooks = this.config.capabilities;\n if (!hooks || !this.proc) return;\n const set = buildOmpHostTools(hooks.composeTools());\n for (const { tool, reason } of set.dropped) {\n const key = `${tool}\\u0000${reason}`;\n if (this.warnedDroppedHostTools.has(key)) continue;\n this.warnedDroppedHostTools.add(key);\n this.log.warn(\"host tool dropped: invalid input schema\", { tool, reason });\n }\n // Swapped before sending so a call racing the response already routes.\n this.hostToolCapabilities = set.capabilityNames;\n try {\n const response = await this.request(\n { type: \"set_host_tools\", tools: set.definitions },\n { quiet: true },\n );\n if (response.success) {\n const data = response.data as { toolNames?: unknown } | undefined;\n this.log.info(\"registered omp host tools\", { toolNames: data?.toolNames });\n } else {\n this.log.error(\"omp rejected host tools\", new Error(response.error ?? \"unknown error\"), {\n tools: set.definitions.map((t) => t.name),\n });\n }\n } catch (err) {\n this.log.error(\"registering omp host tools failed\", err as Error);\n }\n }\n\n /**\n * Execute a capability omp asked the host to run (`host_tool_call`) and\n * answer with `host_tool_result`. Goes through {@link dispatchCapability}\n * so validation, fire-and-forget and render semantics match claude-sdk.\n *\n * Emits `tool_call` / `tool_execution_end` around the dispatch: the\n * normalizer does not read omp's own tool frames, so without these the\n * call — and its `activity_label` — would never reach the chat.\n */\n private handleHostToolCall(event: OmpEvent): void {\n const id = event.id;\n if (typeof id !== \"string\") return;\n const hostName = typeof event.toolName === \"string\" ? event.toolName : \"\";\n const name = this.hostToolCapabilities.get(hostName) ?? hostName;\n const callId = typeof event.toolCallId === \"string\" ? event.toolCallId : id;\n const input = event.arguments ?? {};\n const hooks = this.config.capabilities;\n const controller = new AbortController();\n const call = { controller, name };\n this.hostToolCalls.set(id, call);\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name,\n tool: { name },\n toolCallId: callId,\n input,\n });\n\n void (async () => {\n let text: string;\n let isError = false;\n try {\n if (!hooks) throw new Error(`no capability host for ${name}`);\n const dispatch = await dispatchCapability(\n hooks,\n name,\n input,\n (_err, dispatchCallId) =>\n this.log.warn(\"background capability handler failed\", {\n name,\n toolCallId: callId,\n callId: dispatchCallId,\n // Nothing from the error: its message can quote the call's content.\n }),\n controller.signal,\n );\n text =\n typeof dispatch.result === \"string\"\n ? dispatch.result\n : JSON.stringify(dispatch.result ?? {});\n } catch (err) {\n isError = true;\n text = `Error: ${(err as Error)?.message ?? String(err)}`;\n }\n // Cancelled by omp or the process went away: nobody awaits a result.\n if (this.hostToolCalls.get(id) !== call) return;\n this.hostToolCalls.delete(id);\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: name });\n try {\n this.send({\n type: \"host_tool_result\",\n id,\n result: { content: [{ type: \"text\", text }] },\n ...(isError ? { isError: true } : {}),\n });\n } catch (err) {\n this.log.warn(\"host tool result undeliverable\", { name, callId, error: String(err) });\n }\n })();\n }\n\n /**\n * `host_tool_cancel`: omp aborted the call, so abort the capability handler\n * and close the call's chat activity (the handler's later settlement is\n * ignored, so this is the only `tool_execution_end` the call gets).\n */\n private handleHostToolCancel(event: OmpEvent): void {\n const targetId = event.targetId;\n if (typeof targetId !== \"string\") return;\n this.abortHostToolCall(targetId);\n }\n\n /** Abort one in-flight host tool call and end its activity; no-op if already settled. */\n private abortHostToolCall(id: string): void {\n const call = this.hostToolCalls.get(id);\n if (!call) return;\n this.hostToolCalls.delete(id);\n call.controller.abort();\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: call.name });\n }\n\n // ── Interactive questions (`ask`) ──────────────────────────────────────────\n\n /**\n * `extension_ui_request`: omp asks the host something. Only `ask` (and the\n * `select` omp falls back to when `set_ask_dialog` is unavailable) can carry\n * a user question; both park until {@link answerQuestion}. Presentation\n * frames expect no reply. Every other kind is a dialog nobody here can\n * answer, so it is cancelled at once — an unanswered dialog would leave the\n * tool call, and the turn, waiting forever.\n */\n private handleExtensionUiRequest(event: OmpEvent): void {\n const method = event.method;\n if (method === \"cancel\") {\n // omp closed a dialog itself (timeout, abort): nothing is owed any more.\n if (typeof event.targetId === \"string\" && this.pendingQuestion?.id === event.targetId) {\n this.pendingQuestion = null;\n }\n return;\n }\n if (\n method === \"notify\" ||\n method === \"setStatus\" ||\n method === \"setWidget\" ||\n method === \"setTitle\" ||\n method === \"set_editor_text\" ||\n method === \"open_url\"\n ) {\n return;\n }\n const id = event.id;\n if (typeof id !== \"string\") return;\n let parsed: OmpPendingQuestion | null = null;\n if (method === \"ask\") parsed = this.parseAskRequest(id, event);\n else if (method === \"select\") parsed = this.parseSelectRequest(id, event);\n if (!parsed) {\n this.log.debug(\"cancelling unsupported omp dialog\", { method: String(method) });\n this.sendUiResponse({ id, cancelled: true });\n return;\n }\n // omp parks on one dialog at a time; a second request means the first is dead.\n this.cancelPendingQuestion();\n this.pendingQuestion = parsed;\n this.announceQuestion(parsed, event);\n }\n\n private parseAskRequest(id: string, event: OmpEvent): OmpPendingQuestion | null {\n if (!Array.isArray(event.questions) || event.questions.length === 0) return null;\n const questions: OmpPendingQuestion[\"questions\"] = [];\n for (const raw of event.questions as unknown[]) {\n const q = raw as { id?: unknown; question?: unknown; options?: unknown; multi?: unknown };\n // The response needs one `{ id }` entry per question; without either field\n // the ask cannot be answered correctly, so refuse it rather than guess.\n if (!q || typeof q.id !== \"string\" || typeof q.question !== \"string\" || !q.question) {\n return null;\n }\n const options = (Array.isArray(q.options) ? (q.options as unknown[]) : []).flatMap((o) => {\n let label: unknown = o;\n if (o && typeof o === \"object\" && \"label\" in o) label = o.label;\n return typeof label === \"string\" ? [label] : [];\n });\n questions.push({ id: q.id, question: q.question, options, multi: q.multi === true });\n }\n return { id, method: \"ask\", questions, answers: questions.map(() => undefined) };\n }\n\n private parseSelectRequest(id: string, event: OmpEvent): OmpPendingQuestion | null {\n if (typeof event.title !== \"string\" || !event.title || !Array.isArray(event.options)) {\n return null;\n }\n const options = (event.options as unknown[]).filter((o): o is string => typeof o === \"string\");\n if (options.length === 0) return null;\n return {\n id,\n method: \"select\",\n questions: [{ id, question: event.title, options, multi: false }],\n answers: [undefined],\n };\n }\n\n /**\n * Publish the parked question the way claude-sdk does for `AskUserQuestion`:\n * an assistant `tool_use` block the normalizer turns into one `question`\n * event per question, plus the matching `tool_call`. Option descriptions and\n * `header`s survive in the tool input for consumers that render them.\n */\n private announceQuestion(pending: OmpPendingQuestion, event: OmpEvent): void {\n const rawQuestions = Array.isArray(event.questions) ? (event.questions as unknown[]) : [];\n const input = {\n requestId: pending.id,\n questions: pending.questions.map((q, i) => {\n const raw = rawQuestions[i] as\n | { header?: unknown; options?: Array<{ label?: unknown; description?: unknown }> }\n | undefined;\n return {\n question: q.question,\n ...(typeof raw?.header === \"string\" ? { header: raw.header } : {}),\n multiSelect: q.multi,\n options: q.options.map((label, j) => {\n const description = raw?.options?.[j]?.description;\n return { label, ...(typeof description === \"string\" ? { description } : {}) };\n }),\n };\n }),\n };\n const toolCallId = `omp-ask:${pending.id}`;\n this.emit(\"agent-event\", {\n type: \"message_start\",\n message: {\n role: \"assistant\",\n content: [{ type: \"tool_use\", name: \"AskUserQuestion\", id: toolCallId, input }],\n },\n });\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: \"AskUserQuestion\",\n tool: { name: \"AskUserQuestion\" },\n toolCallId,\n input,\n });\n this.log.debug(\"paused on omp ask\", { questions: pending.questions.length });\n }\n\n override supersedePendingQuestion(): void {\n this.cancelPendingQuestion();\n }\n\n override hasPendingQuestion(): boolean {\n return this.pendingQuestion !== null;\n }\n\n /**\n * While omp is parked on a question a reply that is not an answer must not\n * become a prompt: the turn is still running, and a second prompt would\n * collide with it.\n */\n override get acceptsReplyAsPrompt(): boolean {\n return this.pendingQuestion === null;\n }\n\n override answerQuestion(answer: string, question?: string, requestId?: string): boolean {\n const pending = this.pendingQuestion;\n if (!pending || typeof answer !== \"string\") return false;\n if (requestId !== undefined && requestId !== pending.id) return false;\n\n // A named answer binds to its own question; an unnamed one fills the next\n // unanswered slot. Same rule as claude-sdk.\n let index =\n question !== undefined ? pending.questions.findIndex((q) => q.question === question) : -1;\n if (index === -1) index = pending.answers.indexOf(undefined);\n if (index === -1) return false;\n pending.answers[index] = answer;\n if (pending.answers.some((a) => a === undefined)) return true;\n\n this.pendingQuestion = null;\n this.sendUiResponse(this.buildQuestionResponse(pending));\n this.log.debug(\"answered omp ask\", { questions: pending.questions.length });\n return true;\n }\n\n /** Shape the collected answers as the `extension_ui_response` payload for the request's method. */\n private buildQuestionResponse(pending: OmpPendingQuestion): Record<string, unknown> {\n const find = (options: string[], text: string): string | undefined =>\n options.find((o) => o === text) ??\n options.find((o) => o.toLowerCase() === text.toLowerCase());\n\n if (pending.method === \"select\") {\n const match = find(pending.questions[0]!.options, (pending.answers[0] ?? \"\").trim());\n if (match !== undefined) return { id: pending.id, value: match };\n // A `select` only takes one of its options; free text has nowhere to go.\n this.log.warn(\"select answer matches no option; cancelling it\");\n return { id: pending.id, cancelled: true };\n }\n\n const answers = pending.questions.map((q, i) => {\n const text = (pending.answers[i] ?? \"\").trim();\n const whole = find(q.options, text);\n if (whole !== undefined) return { id: q.id, selectedOptions: [whole] };\n if (q.multi) {\n // The UI hands a multi-select back as one string; take a comma-separated\n // list of labels apart, but only if every piece is a real option.\n const parts = text\n .split(\",\")\n .map((p) => p.trim())\n .filter(Boolean);\n const matched = parts.map((p) => find(q.options, p));\n if (parts.length > 0 && matched.every((m) => m !== undefined)) {\n return { id: q.id, selectedOptions: [...new Set(matched as string[])] };\n }\n }\n // Anything else is the user's own words (omp always offers free text).\n return { id: q.id, selectedOptions: [], ...(text ? { customInput: text } : {}) };\n });\n return { id: pending.id, answers };\n }\n\n /** Write an `extension_ui_response`; undeliverable (process gone) is logged, not thrown. */\n private sendUiResponse(payload: Record<string, unknown>): void {\n try {\n this.send({ type: \"extension_ui_response\", ...payload });\n } catch (err) {\n this.log.warn(\"extension ui response undeliverable\", { error: String(err) });\n }\n }\n\n /** Drop the pending question and tell omp it was cancelled, so its tool call unwinds. */\n private cancelPendingQuestion(): void {\n const pending = this.pendingQuestion;\n if (!pending) return;\n this.pendingQuestion = null;\n this.sendUiResponse({ id: pending.id, cancelled: true });\n }\n\n /**\n * Opt in to omp's single `ask` dialog request (off by default per process).\n * Best-effort: a build without the command answers with a failed response and\n * its `ask` keeps degrading to one `select` per question, which\n * {@link handleExtensionUiRequest} still surfaces as a question.\n */\n private async enableAskDialog(): Promise<void> {\n try {\n const response = await this.request(\n { type: \"set_ask_dialog\", enabled: true },\n { quiet: true },\n );\n if (!response.success) {\n this.log.warn(\"omp rejected set_ask_dialog; ask falls back to select\", {\n error: response.error,\n });\n }\n } catch (err) {\n this.log.warn(\"set_ask_dialog failed\", { error: String(err) });\n }\n }\n\n private extractMessageText(msg: OmpMessage): string {\n if (!msg) return \"\";\n const c = msg.content;\n if (typeof c === \"string\") return c;\n if (Array.isArray(c))\n return c\n .filter((b) => b.type === \"text\" && b.text)\n .map((b) => b.text)\n .join(\"\");\n return \"\";\n }\n\n /**\n * `available_commands_update`: replace the cached slash-command list and\n * publish it. Names carry no leading slash (omp's already don't), matching\n * claude-sdk's `commands_available`. Entries without a name are skipped.\n */\n private handleCommandsUpdate(event: OmpEvent): void {\n const raw = Array.isArray(event.commands) ? (event.commands as unknown[]) : [];\n const commands: SlashCommandInfo[] = [];\n for (const entry of raw) {\n if (!entry || typeof entry !== \"object\") continue;\n const c = entry as { name?: unknown; description?: unknown; input?: { hint?: unknown } };\n if (typeof c.name !== \"string\" || !c.name) continue;\n const hint = c.input && typeof c.input === \"object\" ? c.input.hint : undefined;\n commands.push({\n name: c.name,\n description: typeof c.description === \"string\" ? c.description : \"\",\n argumentHint: typeof hint === \"string\" && hint ? hint : undefined,\n });\n }\n this.cachedCommands = commands;\n this.emit(\"agent-event\", { type: \"commands_available\", commands });\n this.log.debug(\"discovered slash commands\", { count: commands.length });\n }\n\n private handleEvent(event: OmpEvent) {\n if (event.type === \"ready\") {\n this.emit(\"ready\");\n return;\n }\n if (event.type === \"response\") {\n const quiet = typeof event.id === \"string\" && this.quietRequestIds.delete(event.id);\n if (!event.success && event.error && !quiet) {\n const detail = this.classifyErrorMessage(event.error);\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n }\n this.emit(`response:${event.id}`, event);\n return;\n }\n // The first sign of the model at work (text, a tool run, a host tool call or a dialog): from\n // here an exit loses output the client has seen, so the turn is no longer retried.\n if (\n (event.type === \"message_start\" && event.message?.role === \"assistant\") ||\n event.type === \"message_update\" ||\n event.type === \"host_tool_call\" ||\n event.type === \"extension_ui_request\" ||\n event.type.startsWith(\"tool_execution\")\n ) {\n this.turnOutputSeen = true;\n }\n // omp writes the user message to its session file at this point: a session that is\n // reopened afterwards already holds the prompt, so it must not be sent again.\n if (event.type === \"message_end\" && event.message?.role === \"user\") {\n this.turnUserMessageSeen = true;\n }\n // Host tool requests are answered here, not forwarded: they are a\n // host↔omp exchange, surfaced to consumers as `tool_call` events.\n if (event.type === \"host_tool_call\") {\n this.handleHostToolCall(event);\n return;\n }\n if (event.type === \"host_tool_cancel\") {\n this.handleHostToolCancel(event);\n return;\n }\n // UI dialogs (`ask`, …) are a host↔omp exchange: published as `question`\n // events and answered via `answerQuestion`, never forwarded raw.\n if (event.type === \"extension_ui_request\") {\n this.handleExtensionUiRequest(event);\n return;\n }\n // Slash-command list pushed by omp after `ready` and on change: published\n // as `commands_available` (like claude-sdk), never forwarded raw.\n if (event.type === \"available_commands_update\") {\n this.handleCommandsUpdate(event);\n return;\n }\n if (event.type === \"error\" && event.error) {\n const detail = this.classifyErrorMessage(event.error);\n this.emit(\"agent-event\", { ...event, error: detail.message, detail });\n return;\n }\n // Compute text delta for message_update events\n if (event.type === \"message_update\" && event.message) {\n const text = this.extractMessageText(event.message);\n let delta = \"\";\n if (text.startsWith(this.prevText)) {\n delta = text.slice(this.prevText.length);\n } else {\n // Text blocks restructured — emit full text as delta\n delta = text;\n }\n this.prevText = text;\n // Thinking never enters `_textDelta` (extractMessageText sees text blocks\n // only). It travels beside it as `_thinkingDelta`, taken straight from\n // omp's `thinking_delta` sub-event so it cannot duplicate or reorder.\n const sub = event.assistantMessageEvent;\n const thinking =\n sub && typeof sub === \"object\" && \"type\" in sub && sub.type === \"thinking_delta\"\n ? \"delta\" in sub && typeof sub.delta === \"string\"\n ? sub.delta\n : \"\"\n : \"\";\n this.emit(\"agent-event\", {\n ...event,\n _textDelta: delta,\n ...(thinking ? { _thinkingDelta: thinking } : {}),\n });\n return;\n }\n // Reset delta tracking on message boundaries. `message_start` may already\n // carry content (omp 18.x puts the whole reply, or its first chunk, into the\n // start frame). That text must reach a delta consumer: seeding `prevText`\n // from it alone dropped it (the one-shot `skaile run` printed only what the\n // later updates added), and clearing it made the normalizer count it twice.\n // So the assistant's start text leaves the start frame and travels as the\n // first `_textDelta`, in a `message_update` right after it.\n if (event.type === \"message_start\") {\n const startText =\n event.message?.role === \"assistant\" ? this.extractMessageText(event.message) : \"\";\n this.prevText = startText;\n if (startText && event.message) {\n const content = event.message.content;\n const message = {\n ...event.message,\n content: Array.isArray(content) ? content.filter((b) => b.type !== \"text\") : \"\",\n };\n this.emit(\"agent-event\", { ...event, message });\n this.emit(\"agent-event\", {\n type: \"message_update\",\n message: event.message,\n _textDelta: startText,\n });\n return;\n }\n }\n if (event.type === \"message_end\" || event.type === \"agent_end\") {\n this.prevText = \"\";\n }\n\n if (event.type === \"message_end\") this.recordMessageUsage(event.message);\n\n // A failed omp request arrives as `message_end` with `stopReason: \"error\"`,\n // not as an `error` event. Without this branch the turn ended silently: the\n // caller saw a normal completion with no assistant text and no failure,\n // which reads as a hung or empty agent. Surface it on the same channel as\n // every other harness error so callers can classify and retry.\n if (\n event.type === \"message_end\" &&\n event.message?.role === \"assistant\" &&\n event.message.stopReason === \"error\"\n ) {\n const error = event.message.errorMessage || \"omp request failed\";\n const detail = this.classifyErrorMessage(error);\n this.log.error(\"omp request failed\", new Error(error), { detail });\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n }\n\n // After each turn ends, capture the OMP session ID so callers can persist it\n // and pass it as resumeSessionId on the next spawn.\n if (event.type === \"agent_end\") {\n void this.captureState();\n }\n // A listener that kills the harness while it handles `agent_end` (the\n // one-shot `skaile run` does) ends a turn that already finished: `kill()`\n // must settle it as done, not as \"omp process killed\".\n const turnEnded = event.type === \"agent_end\";\n this.turnEnded = turnEnded;\n try {\n this.emit(\"agent-event\", event);\n } finally {\n this.turnEnded = false;\n }\n // Resolve AFTER emitting so listeners observing the turn see `agent_end`\n // before the caller's `prompt()` await unblocks.\n if (turnEnded) {\n this.resolveTurn();\n }\n }\n\n /**\n * Resolve the in-flight prompt turn (on `agent_end`). Idempotent — a turn\n * settles at most once, so a stray second `agent_end` is harmless.\n */\n private resolveTurn(): void {\n const resolve = this.turnResolve;\n this.turnResolve = null;\n this.turnReject = null;\n resolve?.();\n }\n\n /**\n * Reject the in-flight prompt turn (process crash/error). Settling here keeps\n * `prompt()` from hanging forever when the child dies before `agent_end`.\n */\n private rejectTurn(err: Error): void {\n const reject = this.turnReject;\n this.turnResolve = null;\n this.turnReject = null;\n reject?.(err);\n }\n\n /**\n * Query OMP's current state via the `get_state` RPC.\n *\n * Always refreshes the context fill from `contextUsage`. With\n * `announceSession` (the default, used after each turn) it also records the\n * native session ID and emits a `session_info` event so the forge layer can\n * persist it. Failures are silently swallowed — both are best-effort.\n */\n private async captureState(options: { announceSession?: boolean } = {}): Promise<void> {\n const announceSession = options.announceSession ?? true;\n try {\n const response = await this.request({ type: \"get_state\" }, { quiet: !announceSession });\n\n if (response.success && response.data) {\n const data = response.data as Record<string, unknown>;\n this.captureContextUsage(data.contextUsage);\n const sessionId = data.sessionId as string | undefined;\n const sessionFile = data.sessionFile as string | undefined;\n if (announceSession && sessionId) {\n this._ompSessionId = sessionId;\n this.log.debug(\"omp session id assigned\", { sessionId });\n this.emit(\"agent-event\", {\n type: \"session_info\",\n harnessSessionId: sessionId,\n ...(sessionFile ? { sessionFile } : {}),\n });\n }\n }\n } catch {\n // get_state is best-effort — OMP may not support it yet or the process\n // may have exited. The short-term history injection fallback still works.\n }\n }\n\n /** `get_state.contextUsage` → context fill + window; absent or malformed values are ignored. */\n private captureContextUsage(raw: unknown): void {\n if (!raw || typeof raw !== \"object\") return;\n const tokens = \"tokens\" in raw ? raw.tokens : undefined;\n const contextWindow = \"contextWindow\" in raw ? raw.contextWindow : undefined;\n if (typeof tokens === \"number\" && Number.isFinite(tokens) && tokens >= 0) {\n this._lastContextTokens = tokens;\n }\n if (typeof contextWindow === \"number\" && Number.isFinite(contextWindow) && contextWindow > 0) {\n this._contextWindow = contextWindow;\n }\n }\n\n /** Forget the previous turn's usage; called as a new turn begins. */\n private beginUsageTurn(): void {\n this._lastTokens = null;\n this._lastContextTokens = null;\n }\n\n /**\n * Fold one finished assistant message into the turn's usage. Only the\n * `message_end` value is final (`message_start` and partials carry running\n * zeros). A message without usage, or an errored one reporting all zeros,\n * bills nothing and must neither create a reading nor wipe a good one.\n */\n private recordMessageUsage(message: OmpMessage | undefined): void {\n if (message?.role !== \"assistant\" || !message.usage) return;\n const count = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : undefined;\n const input = count(message.usage.input);\n const output = count(message.usage.output);\n const cacheRead = count(message.usage.cacheRead);\n const cacheWrite = count(message.usage.cacheWrite);\n const reasoning = count(message.usage.reasoningTokens);\n const total = count(message.usage.totalTokens);\n const callContext = (input ?? 0) + (cacheRead ?? 0) + (cacheWrite ?? 0);\n if (callContext + (output ?? 0) + (total ?? 0) === 0) return;\n\n const turn: TokenUsage = { ...this._lastTokens };\n const add = (key: keyof TokenUsage, value: number | undefined) => {\n if (value !== undefined) turn[key] = (turn[key] ?? 0) + value;\n };\n add(\"inputTokens\", input);\n add(\"outputTokens\", output);\n add(\"cacheReadTokens\", cacheRead);\n add(\"cacheCreationTokens\", cacheWrite);\n add(\"reasoningTokens\", reasoning);\n add(\"totalTokens\", total);\n this._lastTokens = turn;\n // Provisional until `get_state` reports omp's own figure: that reply lands\n // after `agent_end`, and a compaction check can run before it.\n if (callContext > 0) this._lastContextTokens = callContext;\n }\n\n private nextId(): string {\n return `req-${++this.reqId}`;\n }\n\n /**\n * Send a command and await its `response` frame.\n *\n * @param options.quiet - Leave a failed response to the caller instead of\n * surfacing it as an `error` agent event.\n * @throws When the process is not running or no response arrives within\n * `options.timeoutMs` (default 5 s).\n */\n private request(\n msg: { type: string; [key: string]: unknown },\n options: { quiet?: boolean; timeoutMs?: number } = {},\n ): Promise<OmpEvent> {\n const id = this.nextId();\n const event = `response:${id}`;\n // Not `Promise.withResolvers`: the provider/connector packages that\n // typecheck this file target a lib older than es2024.\n let resolve!: (resp: OmpEvent) => void;\n let reject!: (err: Error) => void;\n const promise = new Promise<OmpEvent>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n const onResponse = (resp: OmpEvent) => {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n resolve(resp);\n };\n // A timed-out quiet request keeps its id: omp may still answer late (with a\n // failure), and that answer must stay as quiet as an in-time one. The id is\n // dropped when the response is handled or the process ends (`cleanup()`).\n const fail = (err: Error, keepQuiet = false) => {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n this.removeListener(event, onResponse);\n if (!keepQuiet) this.quietRequestIds.delete(id);\n reject(err);\n };\n const timer = setTimeout(\n () => fail(new Error(`${msg.type} timeout`), true),\n options.timeoutMs ?? 5000,\n );\n this.once(event, onResponse);\n this.pendingRequests.set(id, fail);\n if (options.quiet) this.quietRequestIds.add(id);\n try {\n this.send({ id, ...msg });\n } catch (err) {\n fail(err as Error);\n }\n return promise;\n }\n\n private send(msg: object): void {\n if (!this.proc?.stdin?.writable) {\n const detail: AgentError = {\n message: \"omp process not running\",\n category: \"process\",\n retryable: true,\n hint: \"The agent process is not available. It will restart automatically on the next prompt.\",\n };\n const err = Object.assign(new Error(detail.message), { detail });\n throw err;\n }\n this.proc.stdin.write(`${JSON.stringify(msg)}\\n`);\n }\n\n /**\n * Sends a prompt to the omp process via JSON-RPC and resolves when the turn\n * completes (after the `agent_end` event), honoring the `AgentHarness.prompt`\n * contract so harness-agnostic callers can await turn completion uniformly.\n *\n * The harness emits `agent-event` payloads as omp streams responses on stdout.\n * If the child process errors or exits before `agent_end`, the returned promise\n * rejects rather than hanging.\n *\n * @param message - Plain-text user prompt.\n * @throws {Error} When the omp process is not running, its stdin is closed, or\n * the child crashes/exits before the turn completes.\n */\n public prompt(message: string): Promise<void> {\n return this.enqueuePrompt(() => this.runPrompt({ message }));\n }\n\n /**\n * Run one prompt after every earlier one settled. A question omp is parked on\n * is cancelled first, synchronously and ahead of the queue: the parked turn\n * can only finish once its `ask` is released, so the new prompt (the user\n * typing instead of answering) must not wait behind it. The runner queues chat\n * prompts too; this queue still covers callers that drive the harness directly.\n */\n private enqueuePrompt(run: () => Promise<void>): Promise<void> {\n this.cancelPendingQuestion();\n const queued = this.promptTail.then(run);\n this.promptTail = queued.then(\n () => undefined,\n () => undefined,\n );\n return queued;\n }\n\n /**\n * Structured prompt: text plus image/file/skill attachments. Images travel as\n * omp `ImageContent` (`prompt.images`, base64 + mimeType); file and skill\n * attachments are named in a text preamble, because omp reads files itself.\n * Turn settlement is shared with {@link prompt}.\n */\n public override promptInput(input: AgentPromptInput): Promise<void> {\n if (input.toolAllowlist !== undefined)\n return Promise.reject(new Error(TOOL_ALLOWLIST_UNSUPPORTED));\n return this.enqueuePrompt(async () => this.runPrompt(await this.buildPromptPayload(input)));\n }\n\n /** Resolve attachments into the `message` + `images` fields of an omp `prompt` frame. */\n private async buildPromptPayload(\n input: AgentPromptInput,\n ): Promise<{ message: string; images?: OmpImageContent[] }> {\n const attachments = input.attachments ?? [];\n if (attachments.length === 0) return { message: input.text };\n const mimeByExt: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n };\n const images: OmpImageContent[] = [];\n const preamble: string[] = [];\n let root: string | undefined;\n for (const attachment of attachments) {\n if (attachment.type !== \"image\") {\n preamble.push(`[Attached ${attachment.type}: ${attachment.name} (${attachment.path})]`);\n continue;\n }\n // Image bytes are read here, so the path must stay inside the workspace.\n root ??= await fs.realpath(this.config.cwd);\n const resolved = await fs.realpath(path.resolve(root, attachment.path));\n const rel = path.relative(root, resolved);\n const escapes = rel === \"..\" || rel.startsWith(`..${path.sep}`);\n if (rel === \"\" || escapes || path.isAbsolute(rel)) {\n throw new Error(`Image attachment is outside the workspace: ${attachment.path}`);\n }\n const mimeType = mimeByExt[path.extname(resolved).toLowerCase()];\n if (!mimeType) {\n throw new Error(`Unsupported image type for attachment: ${attachment.path}`);\n }\n // Anthropic rejects images over 5 MB; fail before reading the bytes.\n const { size } = await fs.stat(resolved);\n if (size > OMP_MAX_IMAGE_BYTES) {\n throw new Error(`Image attachment too large (${size} bytes > 5 MB): ${attachment.path}`);\n }\n images.push({\n type: \"image\",\n data: (await fs.readFile(resolved)).toString(\"base64\"),\n mimeType,\n });\n }\n const message = preamble.length ? `${preamble.join(\"\\n\")}\\n\\n${input.text}` : input.text;\n return { message, ...(images.length ? { images } : {}) };\n }\n\n /**\n * Send one `prompt` frame and resolve when the turn completes (`agent_end`).\n * Rejects if the child dies first.\n */\n private async runPrompt(payload: { message: string; images?: OmpImageContent[] }): Promise<void> {\n this.promptRetried = false;\n const epoch = this.killEpoch;\n for (;;) {\n await this.start();\n if (this.killEpoch !== epoch) {\n // A kill() or dispose() landed while omp was restarting: the new process must not live.\n this.kill();\n throw new Error(\"omp process killed\");\n }\n // A reconfigure that landed mid-turn or before `ready` applies now.\n await this.reconfig.flushBeforeTurn();\n const id = this.nextId();\n\n // Install the per-turn resolver BEFORE sending: omp can stream a fast\n // `agent_end` on the next readline tick, and if the resolver isn't wired\n // yet that event would be missed and prompt() would hang forever.\n const turnPromise = new Promise<void>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n });\n\n this.turnOutputSeen = false;\n this.turnUserMessageSeen = false;\n this.beginUsageTurn();\n try {\n this.send({ id, type: \"prompt\", ...payload });\n } catch (err) {\n this.turnResolve = null;\n this.turnReject = null;\n throw err;\n }\n\n try {\n await turnPromise;\n return;\n } catch (err) {\n // omp exited before it produced anything: nothing of this turn was seen, so the same\n // prompt goes to a fresh process once. The exit handler held the error back for this.\n if (!(err instanceof EarlyOmpExit)) throw err;\n this.promptRetried = true;\n this.log.warn(\"omp exited before its first output; sending the prompt again\", {\n code: err.code,\n signal: err.signal,\n });\n }\n }\n }\n\n /**\n * Sends an in-band abort RPC to the omp process, requesting it to stop the\n * current turn without terminating the child process.\n *\n * @remarks This is a best-effort signal — omp may not honour the abort\n * immediately. The process remains alive after `abort()`.\n */\n public async abort(): Promise<void> {\n if (!this.proc) return;\n const id = this.nextId();\n this.send({ id, type: \"abort\" });\n // The dialog's tool call is aborted with the turn; release what it owed.\n this.cancelPendingQuestion();\n }\n\n /** `true` when the omp child process is alive and has not been killed. */\n public get isRunning(): boolean {\n return this.proc !== null && !this.proc.killed;\n }\n\n /**\n * Sends SIGTERM to the omp child process and performs cleanup.\n *\n * The harness instance must not be reused after `kill()`. Create a new\n * `OmpHarness` to start a fresh session.\n */\n kill(): void {\n this.killEpoch++;\n const proc = this.proc;\n if (!proc) return;\n // Settle this process's in-flight turn here: its late `exit` is ignored (the\n // process is superseded by then) and must not reach a successor's turn.\n if (this.turnEnded) this.resolveTurn();\n else this.rejectTurn(new Error(\"omp process killed\"));\n proc.kill(\"SIGTERM\");\n // omp is still shutting down and writes into its home (the `intercom` directory) while\n // the cleanup below deletes it, so a home deleted only now can reappear: delete it again\n // once the process is gone.\n const home = this.privateHome;\n this.homeGone = home ? removeHomeAfterExit(proc, home) : Promise.resolve();\n this.cleanup();\n }\n\n /** Stop omp and wait until the process has exited and its private home is deleted. */\n override async dispose(): Promise<void> {\n this.kill();\n await this.homeGone;\n }\n\n async resetSession(): Promise<void> {\n this.kill();\n // Otherwise the respawn passes `--session` and reopens the pre-reset session.\n this.config = { ...this.config, resumeSessionId: undefined };\n this._lastTokens = null;\n this._lastContextTokens = null;\n this._contextWindow = null;\n await this.start();\n }\n\n private classifyProcessError(err: NodeJS.ErrnoException): AgentError {\n if (err.code === \"ENOENT\") {\n return {\n message: \"omp command not found\",\n category: \"config\",\n retryable: false,\n hint: HARNESS_BINARIES.omp.hint,\n };\n }\n if (err.code === \"EACCES\") {\n return {\n message: \"Permission denied running omp\",\n category: \"config\",\n retryable: false,\n hint: \"Check file permissions for the omp binary.\",\n };\n }\n return {\n message: err.message,\n category: \"process\",\n retryable: true,\n hint: \"An unexpected process error occurred. Try sending your prompt again.\",\n };\n }\n\n private classifyErrorMessage(rawMsg: string): AgentError {\n const msg = ompCredentialMessage(rawMsg);\n // Shared keyword buckets live in error-classifier.ts; only the hint copy is omp-specific.\n const generic = classifyGenericErrorMessage(msg);\n if (!generic) return { message: msg, category: \"unknown\", retryable: true };\n\n const lower = msg.toLowerCase();\n // The rewritten no-login message already names the command to run (p1912): a second line\n // pointing at a `Settings` screen the CLI does not have only misleads.\n const namesCommand = msg !== rawMsg && msg.includes(\"`skaile providers add\");\n const hint =\n generic.category === \"auth\"\n ? namesCommand\n ? undefined\n : \"Check the provider's key with `skaile providers test <id>`.\"\n : generic.category === \"rate_limit\"\n ? \"You have hit the provider rate limit. Wait a moment and try again.\"\n : generic.category === \"network\"\n ? \"A network error occurred. Check your connection and try again.\"\n : // model: distinguish unavailable-model from over-long-context.\n lower.includes(\"model\")\n ? \"The selected model is not available. Pick another with --model.\"\n : \"The conversation is too long. Start a new session or choose a model with a larger context window.\";\n return {\n message: msg,\n category: generic.category,\n retryable: generic.retryable,\n ...(hint ? { hint } : {}),\n };\n }\n\n /**\n * The models this session can select.\n *\n * Answered entirely from the registry: the ids are exactly the\n * `<providerId>/<modelId>` selectors rendered into `models.yml`, so a\n * picker offers every enabled endpoint instead of whichever one the\n * ambient binary happens to be authenticated for. A registry whose\n * entries name no models yields no entries here — that gap is closed by\n * giving the entry a `discovery:` block (`PROVIDER-CONFIG-PLAN.md` §1.1),\n * not by asking the omp binary what it happens to know. omp's own catalog\n * (`omp models --json`) answers a different question — every model omp\n * knows across every provider, regardless of what this session's registry\n * enables or has credentials for — and shelling out to an ambient binary\n * from this code path is itself a liability: it can block indefinitely\n * reading a prompt from stdin when run inside another interactive session.\n */\n override async listModels(): Promise<ModelEntry[]> {\n return registryModelEntries(this.config.registry);\n }\n\n /** Delete the system prompt file of the process that is gone (or about to be replaced). */\n private removeSystemPromptFile(): void {\n const file = this.systemPromptFile;\n this.systemPromptFile = null;\n if (file) rmSync(file, { force: true });\n }\n\n /**\n * Delete the private omp home of the process that is gone: it holds symlinks to the login\n * and the agent files and omp's runtime databases, and nothing reads it afterwards (p811).\n */\n private removePrivateHome(): void {\n const home = this.privateHome;\n this.privateHome = null;\n if (home) rmSync(home, { recursive: true, force: true });\n }\n\n private cleanup(): void {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n this.rl?.close();\n this.rl = null;\n this.proc = null;\n this.ready = false;\n this.reconfig.setSnapshot(null);\n this.startPromise = null;\n this.stderrBuffer = [];\n // A respawn re-subscribes and re-registers the host tools from scratch.\n this.unsubscribeToolsChanged?.();\n this.unsubscribeToolsChanged = null;\n this.hostToolCapabilities = new Map();\n // Nothing can receive these results any more; stop the handlers and close\n // their chat activity (the handlers' later settlement is ignored).\n for (const id of [...this.hostToolCalls.keys()]) this.abortHostToolCall(id);\n // No response can arrive any more: fail the waiters now instead of at their timeout.\n for (const fail of [...this.pendingRequests.values()]) fail(new Error(\"omp process ended\"));\n this.pendingRequests.clear();\n this.quietRequestIds.clear();\n // The process that asked is gone; there is nobody to answer to.\n this.pendingQuestion = null;\n }\n}\n\n/**\n * `HarnessTarget` wrapper for the omp harness. Registered into the plugin\n * registry by `registerBuiltinHarnesses()`.\n */\nexport const ompHarnessTarget: HarnessTarget<AgentConfig> = {\n id: \"omp\",\n displayName: BUILTIN_HARNESS_CATALOG.omp?.name ?? \"omp (oh-my-pi)\",\n apiVersion: 1,\n // Harnesses take AgentConfig; passthrough — full schema validation is out of scope.\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new OmpHarness(config),\n listModels: async (registry, options) =>\n new OmpHarness({\n cwd: process.cwd(),\n sessionId: \"model-list\",\n ...registryHarnessConfig(registry, options),\n }).listModels(),\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../bridge/src/harnesses/omp.ts"],"names":["sessionDir"],"mappings":"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","file":"omp.js","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport type { EventEmitter } from \"node:events\";\nimport { rmSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport type { HarnessTarget } from \"@skaile/workspaces/plugin-registry\";\nimport {\n type HarnessContextReport,\n type Logger,\n type TokenUsage,\n withActivityLabelJsonSchema,\n} from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { classifyGenericErrorMessage } from \"../error-classifier.js\";\nimport { HARNESS_BINARIES } from \"../harness-binaries.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { checkToolInputSchema } from \"../mcp-tool-schema-filter.js\";\nimport type { ModelEntry } from \"../models.js\";\nimport { registryHarnessConfig } from \"../provider-registry-derive.js\";\nimport {\n type ReconfigureApplyResult,\n ReconfigureLedger,\n type ReconfigurePushContext,\n type ReconfigureSnapshot,\n} from \"../reconfigure-ledger.js\";\nimport { BUILTIN_HARNESS_CATALOG } from \"../registry.js\";\nimport { resolveAgentExec, wrapAgentCommand } from \"../agent-exec.js\";\nimport { RUNNER_AGENT_ENV_KEYS, stripRunnerPrivateEnv } from \"../runner-private-env.js\";\nimport {\n type AgentConfig,\n AgentHarness,\n type AgentError,\n type AgentPromptInput,\n type BridgeCapabilityTool,\n type HarnessInfo,\n type ReconfigureApplied,\n type ReconfigureOutcome,\n type ReconfigurePatch,\n type SlashCommandInfo,\n TOOL_ALLOWLIST_UNSUPPORTED,\n} from \"../types.js\";\nimport {\n isCredentialOmissionWarning,\n materializeOmpIdentityDir,\n materializeOmpProviders,\n registryModelEntries,\n} from \"./omp-models-yml.js\";\n\n/**\n * omp's own `No API key found for <provider>` text ends with `or create <home>/agent.db`:\n * the home is the session's private directory, a path nobody logs in at. Say what a user\n * can do instead: add the provider to the registry, or log in once with `omp`.\n * Any other message is returned as it came.\n */\nexport function ompCredentialMessage(msg: string): string {\n const match = /^(?:Error:\\s*)?No API key found for ([A-Za-z0-9._-]+?)\\.?(?:\\s|$)/.exec(msg);\n if (!match) return msg;\n const provider = match[1];\n const envName = `${provider.toUpperCase().replace(/[^A-Z0-9]/g, \"_\")}_API_KEY`;\n return (\n `No API key found for ${provider}. Add the provider with ` +\n `\\`skaile providers add ${provider} --credential env:${envName}\\`, ` +\n \"or log in once with `omp` (type /login).\"\n );\n}\n\n/**\n * Process-level vars omp needs to run at all, independent of any provider.\n */\nconst OMP_BASE_ENV_KEYS: readonly string[] = [\n \"PATH\",\n \"HOME\",\n \"USER\",\n \"HOSTNAME\",\n \"SKAILE_SESSION_ID\",\n ...RUNNER_AGENT_ENV_KEYS,\n];\n\n/**\n * Build the explicit env allowlist forwarded to the omp child process.\n *\n * The runner's full environment is never inherited — only\n * {@link OMP_BASE_ENV_KEYS} (process essentials) and the `PI_*` prefix (omp's\n * own app config the host operator may have set).\n *\n * **Credentials are not on this list.** Every endpoint omp may address is a\n * registry entry, serialized into the session's own `models.yml` with its\n * credential named as `SKAILE_AIP_<ID>_KEY` and the value assigned after this\n * allowlist is built (`./omp-models-yml.ts`). An ambient `ANTHROPIC_API_KEY`\n * in the runner's shell is not a session's statement of intent and does not\n * reach the child; `skaile providers add anthropic --preset anthropic\n * --credential env:ANTHROPIC_API_KEY` is.\n *\n * Test seams (`OMP_BRIDGE_*`, `FAKE_OMP_*`) are passed through so the\n * subprocess harness in `tests/omp-harness.test.ts` can drive a fake-omp\n * script via env-driven mode flags.\n *\n * @docLink packages/bridge/concepts#omp-env-whitelist\n */\nexport function buildOmpChildEnv(parent: NodeJS.ProcessEnv): Record<string, string> {\n const out: Record<string, string> = {};\n for (const key of OMP_BASE_ENV_KEYS) {\n const v = parent[key];\n if (typeof v === \"string\") out[key] = v;\n }\n for (const [key, value] of Object.entries(parent)) {\n if (typeof value !== \"string\") continue;\n if (key.startsWith(\"PI_\") || key.startsWith(\"OMP_BRIDGE_\") || key.startsWith(\"FAKE_OMP_\")) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * omp's built-in tools, as reported by `omp --help` (\"Available Tools\").\n *\n * `computer` is the one entry omp does not enable by default; everything else\n * is on unless `--tools` narrows the set. Used to turn a manifest *deny* list\n * into the *allow* list omp's CLI actually accepts.\n */\nexport const OMP_BUILTIN_TOOLS = [\n \"read\",\n \"bash\",\n \"edit\",\n \"write\",\n \"grep\",\n \"glob\",\n \"lsp\",\n \"python\",\n \"notebook\",\n \"browser\",\n \"computer\",\n \"task\",\n \"todo\",\n \"web_search\",\n \"ask\",\n] as const;\n\n/** omp's default-enabled toolset — every built-in except `computer`. */\nexport const OMP_DEFAULT_TOOLS: readonly string[] = OMP_BUILTIN_TOOLS.filter(\n (t) => t !== \"computer\",\n);\n\n/**\n * Canonical (Claude Code) tool name → omp built-in tool name.\n *\n * Agent manifests are authored once in the canonical vocabulary and run on\n * whichever harness the workspace is configured for, so the harness owns the\n * translation. Names already in omp's own spelling pass through unchanged.\n *\n * Deliberately partial: Claude tools with no omp counterpart (`WebFetch`,\n * `BashOutput`, `KillShell`, `mcp__*` server tools) are absent and get dropped\n * from the omp `--tools` value — omp's `--tools` governs built-ins only, so\n * naming a non-built-in there would be rejected, and silently keeping it would\n * not restrict anything.\n */\nconst CANONICAL_TO_OMP_TOOL: Record<string, string> = {\n read: \"read\",\n write: \"write\",\n edit: \"edit\",\n multiedit: \"edit\",\n notebookedit: \"notebook\",\n bash: \"bash\",\n grep: \"grep\",\n glob: \"glob\",\n ls: \"glob\",\n task: \"task\",\n agent: \"task\",\n todowrite: \"todo\",\n todoread: \"todo\",\n websearch: \"web_search\",\n web_search: \"web_search\",\n notebook: \"notebook\",\n lsp: \"lsp\",\n python: \"python\",\n browser: \"browser\",\n computer: \"computer\",\n todo: \"todo\",\n ask: \"ask\",\n askuserquestion: \"ask\",\n};\n\n/**\n * Translate a manifest tool list into omp built-in tool names.\n *\n * Unknown names are dropped rather than passed through: a manifest is expected\n * to run on more than one harness, so it legitimately names tools this one has\n * never heard of.\n */\nfunction toOmpToolNames(names: readonly string[] | undefined): string[] {\n const out: string[] = [];\n for (const raw of names ?? []) {\n const mapped = CANONICAL_TO_OMP_TOOL[raw.trim().toLowerCase().replace(/[\\s-]/g, \"\")];\n if (mapped && !out.includes(mapped)) out.push(mapped);\n }\n return out;\n}\n\n/**\n * Resolve `AgentConfig.tools` into the omp CLI flags that enforce it.\n *\n * omp expresses tool restriction as a positive `--tools a,b,c` list (or\n * `--no-tools`) — there is no deny flag — so a manifest deny list is applied by\n * subtracting from {@link OMP_DEFAULT_TOOLS}.\n *\n * Returns `[]` when the manifest declares no restriction, which leaves omp on\n * its full default toolset exactly as before. That default toolset is the bulk\n * of every request's fixed token prefix, so this is the lever an agent\n * definition needs in order to shrink it.\n *\n * Pure — exported for direct testing.\n *\n * @since 1.5.0\n */\nexport function buildOmpToolArgs(tools: AgentConfig[\"tools\"]): string[] {\n const allowed = toOmpToolNames(tools?.allowed);\n const denied = new Set(toOmpToolNames(tools?.denied));\n\n const declaredAllow = (tools?.allowed?.length ?? 0) > 0;\n const declaredDeny = (tools?.denied?.length ?? 0) > 0;\n if (!declaredAllow && !declaredDeny) return [];\n\n const base = declaredAllow ? allowed : [...OMP_DEFAULT_TOOLS];\n const effective = base.filter((t) => !denied.has(t));\n\n // An allow list that named only tools omp does not have, or a deny list that\n // removed everything, both mean \"no tools\" — say so explicitly rather than\n // emitting `--tools ` and letting omp fall back to the full default set.\n if (effective.length === 0) return [\"--no-tools\"];\n return [\"--tools\", effective.join(\",\")];\n}\n\n/**\n * Longest host tool name handed to omp. omp forwards host tool names to the\n * provider verbatim; Anthropic allows 128 characters, OpenAI-compatible\n * endpoints 64, so the stricter bound keeps every provider working.\n */\nconst OMP_HOST_TOOL_NAME_MAX = 64;\n\n/** One `set_host_tools` entry (`omp://rpc.md`, \"set_host_tools payload\"). */\nexport interface OmpHostToolDefinition {\n name: string;\n label: string;\n description: string;\n parameters: Record<string, unknown>;\n loadMode: \"essential\";\n}\n\n/** Result of {@link buildOmpHostTools}. */\nexport interface OmpHostToolSet {\n /** Definitions to send in `set_host_tools`. */\n definitions: OmpHostToolDefinition[];\n /** omp host tool name → capability name, for routing `host_tool_call`. */\n capabilityNames: Map<string, string>;\n /** Capabilities left out because the provider would reject their schema. */\n dropped: Array<{ tool: string; reason: string }>;\n}\n\n/**\n * Turn the runner's capability tool list into omp host tool definitions.\n *\n * omp accepts any name in `set_host_tools` but forwards it to the provider\n * as-is, and providers reject anything outside `^[a-zA-Z0-9_-]{1,64}$` with a\n * 400 that fails the whole turn (verified against omp 18.6.0 + Anthropic:\n * `app.editor.open` → `tools.3.custom.name: String should match pattern`).\n * Names are therefore sanitised (`app.editor.open` → `app_editor_open`) and\n * the original kept in `capabilityNames`. Collisions — with another\n * capability or with an omp built-in, which omp refuses — get a numeric\n * suffix.\n *\n * omp also forwards the JSON Schema untouched, so each advertised schema is\n * checked with the same rules the claude-sdk harness applies to raw MCP\n * schemas ({@link checkToolInputSchema}); a failing tool is dropped rather\n * than turning every request into a 400. `loadMode: \"essential\"` keeps every\n * capability in the prompt instead of behind omp's tool discovery, matching\n * claude-sdk where every capability is in the tool list.\n *\n * Pure — exported for direct testing.\n */\nexport function buildOmpHostTools(tools: readonly BridgeCapabilityTool[]): OmpHostToolSet {\n const taken = new Set<string>(OMP_BUILTIN_TOOLS);\n const out: OmpHostToolSet = { definitions: [], capabilityNames: new Map(), dropped: [] };\n for (const tool of tools) {\n // Advertise-only label, as in claude-sdk and codex; `dispatchCapability`\n // strips it before the registry sees the input.\n const parameters = { ...withActivityLabelJsonSchema(tool.parameters), type: \"object\" };\n const reason = checkToolInputSchema(parameters);\n if (reason) {\n out.dropped.push({ tool: tool.name, reason });\n continue;\n }\n const base =\n tool.name.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, OMP_HOST_TOOL_NAME_MAX) || \"capability\";\n let name = base;\n for (let n = 2; taken.has(name); n++) {\n const suffix = `_${n}`;\n name = `${base.slice(0, OMP_HOST_TOOL_NAME_MAX - suffix.length)}${suffix}`;\n }\n taken.add(name);\n out.capabilityNames.set(name, tool.name);\n out.definitions.push({\n name,\n label: tool.name,\n description: tool.description,\n parameters,\n loadMode: \"essential\",\n });\n }\n return out;\n}\n\n/** Thinking levels omp accepts for `--thinking` / `set_thinking_level`. omp drops anything else silently. */\nexport const OMP_THINKING_LEVELS = [\n \"off\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n \"auto\",\n] as const;\nexport type OmpThinkingLevel = (typeof OMP_THINKING_LEVELS)[number];\n\n/** Largest image attachment omp will be sent (Anthropic's 5 MB per-image limit). */\nconst OMP_MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Map `AgentConfig.thinking` / `effort` to an omp thinking level.\n *\n * `disabled` wins over `effort` → `off`. Otherwise an explicit `effort`\n * (low/medium/high/xhigh/max) maps to the same-named level (omp clamps `max` to\n * `xhigh` on models without it). Without effort, `enabled` → `medium` and\n * `adaptive` → `auto`. Returns `undefined` when neither is set (omp keeps its\n * own default) or when the value is outside omp's set — `set_thinking_level`\n * accepts garbage without an error, so validation has to happen here.\n */\nexport function ompThinkingLevel(\n cfg: Pick<AgentConfig, \"thinking\" | \"effort\">,\n): OmpThinkingLevel | undefined {\n const level = (() => {\n if (cfg.thinking === \"disabled\") return \"off\";\n if (cfg.effort) return cfg.effort;\n if (cfg.thinking === \"enabled\") return \"medium\";\n if (cfg.thinking === \"adaptive\") return \"auto\";\n return undefined;\n })();\n return level !== undefined && (OMP_THINKING_LEVELS as readonly string[]).includes(level)\n ? (level as OmpThinkingLevel)\n : undefined;\n}\n\n/**\n * Split a model selector into the `provider` / `modelId` pair `set_model`\n * takes. The registry renders selectors as `<providerId>/<providerModelId>`\n * (the spawn-time `--model` value); provider ids never contain `/` but model\n * ids can, so the split is on the FIRST `/`:\n * `openrouter/anthropic/claude-sonnet-4` → `{ provider: \"openrouter\", modelId: \"anthropic/claude-sonnet-4\" }`.\n * A bare name (no `provider/` prefix) cannot be expressed: omp's `--model`\n * fuzzy matching has no RPC equivalent, so the result is `undefined`.\n */\nexport function splitOmpModel(model: string): { provider: string; modelId: string } | undefined {\n const slash = model.indexOf(\"/\");\n if (slash > 0 && slash < model.length - 1) {\n return { provider: model.slice(0, slash), modelId: model.slice(slash + 1) };\n }\n return undefined;\n}\n\ninterface OmpEvent {\n type: string;\n data?: unknown;\n id?: string;\n success?: boolean;\n error?: string;\n message?: OmpMessage;\n [key: string]: unknown;\n}\n\ninterface OmpMessage {\n role?: string;\n content?: string | OmpContentBlock[];\n /**\n * Why the turn stopped. omp reports a failed request as a normal\n * `message_end` carrying `stopReason: \"error\"` rather than as an `error`\n * event, so this is the only signal that the turn failed.\n */\n stopReason?: string;\n /** Provider/transport error text accompanying `stopReason: \"error\"`. */\n errorMessage?: string;\n /** Final usage of this model call; running partials on `message_start`/updates are ignored. */\n usage?: OmpUsage;\n}\n\n/** Token counters on an assistant `message_end`; every field is optional and unvalidated. */\ninterface OmpUsage {\n input?: unknown;\n output?: unknown;\n cacheRead?: unknown;\n cacheWrite?: unknown;\n reasoningTokens?: unknown;\n totalTokens?: unknown;\n /** USD cost of the call; `total` is the sum omp bills. */\n cost?: { total?: unknown };\n}\n\n/** omp RPC `ImageContent`: raw base64 (no `data:` prefix) plus its MIME type. */\ninterface OmpImageContent {\n type: \"image\";\n data: string;\n mimeType: string;\n}\n\ninterface OmpContentBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: unknown;\n thinking?: string;\n}\n\n/**\n * A question omp is parked on: the `extension_ui_request` the host still owes\n * an `extension_ui_response` for. One request can carry several questions;\n * the response goes out once every one has an answer.\n */\ninterface OmpPendingQuestion {\n /** Id of the `extension_ui_request`; the response must echo it. */\n id: string;\n /** `ask` answers with `answers[]`; the `select` fallback answers with `value`. */\n method: \"ask\" | \"select\";\n questions: Array<{ id: string; question: string; options: string[]; multi: boolean }>;\n /** The user's answer per question, by position; `undefined` while unanswered. */\n answers: Array<string | undefined>;\n}\n\n/** What the running omp process holds, for the reconfigure ledger. */\ninterface OmpApplied extends ReconfigureSnapshot {\n /** The omp thinking level last sent (or spawned with). */\n level?: OmpThinkingLevel;\n}\n\n/**\n * The line of omp's stderr that says why it gave up. omp prints an unrelated\n * warning first (a failed extension load) and the real cause last (`No default\n * model selected. Use /login ...`), so the cause is the last line that reads as\n * an error, else the last line. Escape sequences are stripped.\n */\nexport function ompStartFailureCause(lines: readonly string[]): string {\n const clean = lines\n // biome-ignore lint/suspicious/noControlCharactersInRegex: strips ANSI escapes\n .map((l) => l.replace(/\\u001b\\[[0-9;]*m/g, \"\").trim())\n .filter(Boolean);\n const isCause = (l: string) =>\n /\\b(error|no default model|not (?:found|installed|logged)|invalid|unauthori[sz]ed|cannot|can't|failed)\\b/i.test(\n l,\n ) && !/failed to load extension/i.test(l);\n for (let i = clean.length - 1; i >= 0; i--) {\n if (isCause(clean[i] as string)) return clean[i] as string;\n }\n return clean.at(-1) ?? \"\";\n}\n\n/** How long a killed omp gets to exit before its private home is deleted anyway. */\nconst KILLED_EXIT_WAIT_MS = 5000;\n\n/** What a turn rejects with when omp exits before showing any output: `prompt()` sends it again once. */\nclass EarlyOmpExit extends Error {\n constructor(\n readonly code: number | null,\n readonly signal: NodeJS.Signals | null,\n ) {\n super(`omp process crashed (exit code ${code})`);\n }\n}\n\n/**\n * Delete `home` again once the killed `proc` has exited. omp writes into its home while it\n * shuts down, so a delete done at the kill can leave a directory behind. Resolves when the\n * home is gone; never rejects.\n */\nfunction removeHomeAfterExit(proc: ChildProcess, home: string): Promise<void> {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => {\n resolve = r;\n });\n const timer = setTimeout(remove, KILLED_EXIT_WAIT_MS);\n timer.unref?.();\n function remove(): void {\n clearTimeout(timer);\n try {\n rmSync(home, { recursive: true, force: true });\n } catch {\n // A later start sweeps what is left.\n }\n resolve();\n }\n if (proc.exitCode !== null || proc.signalCode !== null) remove();\n else (proc as unknown as EventEmitter).once(\"exit\", remove);\n return promise;\n}\n\n/**\n * Agent harness for the oh-my-pi (omp) coding agent.\n *\n * Spawns `omp --mode rpc-ui --no-ui` as a child process and communicates via newline-delimited\n * JSON-RPC over stdin/stdout. Model-agnostic: supports any LLM provider.\n *\n * @see https://github.com/can1357/oh-my-pi\n *\n * @remarks\n * **Session persistence** — omp writes JSONL session files to `<cwd>/.omp/sessions/`\n * (via `--session-dir`). After each turn (`agent_end`), sends a `get_state` RPC to\n * capture the native session ID and emits a `session_info` event so the forge layer\n * can persist it. On the next spawn, callers pass `resumeSessionId` to restore omp's\n * native context.\n *\n * **stderrBuffer** — collects the last 20 lines of stderr so they can be appended to\n * crash error messages for diagnostics without blocking the stdout readline loop.\n *\n * **systemPrompt injection** — omp does not accept a system prompt string directly.\n * The harness writes `AgentConfig.systemPrompt` to a file of its own under\n * `<cwd>/.skaile/cache/omp-system/`, passes the path via `--append-system-prompt` and deletes\n * the file when the process ends.\n *\n * **agentDir** — omp's home (`PI_CODING_AGENT_DIR`) is a private directory outside `cwd`\n * that links in the entries of the GitAgent directory (agent.yaml, RULES.md, knowledge/), so\n * omp's runtime databases never land beside the pinned agent files. omp reads no SOUL.md:\n * the runner puts the soul into `systemPrompt`.\n *\n * **Capabilities** — `AgentConfig.capabilities` (Protocol v2) is registered with omp\n * as host tools (`set_host_tools`) once the process is ready, and again whenever the\n * registry reports a change. omp calls them back with `host_tool_call`, answered via\n * `dispatchCapability` exactly as claude-sdk's `skaile-capabilities` MCP server does.\n * Names are sanitised for the provider; see {@link buildOmpHostTools}.\n *\n * **Questions** — omp's `ask` tool is enabled as one `extension_ui_request` dialog\n * (`set_ask_dialog`), published as the same `question` events as claude-sdk's\n * `AskUserQuestion` and answered through {@link OmpHarness.answerQuestion}. The turn stays\n * parked in omp until then; abort, kill and process exit release it. Dialogs the host\n * cannot answer (`confirm`, `input`, `editor`) are cancelled immediately.\n *\n * @docLink packages/bridge/harnesses#omp-harness\n */\nexport class OmpHarness extends AgentHarness {\n readonly harnessInfo: HarnessInfo = {\n id: \"omp\",\n name: \"omp (oh-my-pi)\",\n modelAgnostic: true,\n supportsInBandAbort: true,\n capabilities: BUILTIN_HARNESS_CATALOG.omp?.capabilities,\n };\n\n private readonly log: Logger = getBridgeLogger(\"omp\");\n private proc: ChildProcess | null = null;\n private rl: Interface | null = null;\n private reqId = 0;\n private config: AgentConfig;\n private ready = false;\n private startPromise: Promise<void> | null = null;\n private stderrBuffer: string[] = [];\n private prevText = \"\";\n /** OMP session ID captured via `get_state` after each turn. */\n private _ompSessionId?: string;\n /**\n * The omp session the last unexpected exit left behind, set as `config.resumeSessionId` for\n * the respawn; cleared once a respawn on it fails (the next one starts empty).\n */\n private exitResumeSessionId?: string;\n /**\n * Usage of the most recent turn, summed over every model call in it (a tool\n * loop is one prompt but many assistant messages). Cleared when a turn\n * starts, like claude-sdk, so it never mixes two turns.\n */\n private _lastTokens: TokenUsage | null = null;\n /**\n * Prompt size of the most recent model call: the real context fill, which\n * `_lastTokens` (turn-cumulative) overstates on a tool loop. omp's own\n * `get_state.contextUsage.tokens` replaces it once that reply lands.\n */\n private _lastContextTokens: number | null = null;\n /** USD cost of the most recent turn, summed like {@link _lastTokens}. */\n private _lastTurnCostUsd = 0;\n /** The current turn's request failed (`message_end` with `stopReason: \"error\"`). */\n private turnFailed = false;\n /** Context window of the active model, from `get_state.contextUsage`. */\n private _contextWindow: number | null = null;\n /** Per-spawn file holding the system prompt omp was started with; removed with the process. */\n private systemPromptFile: string | null = null;\n /** The private omp home of the running process, when it is the harness's own temporary one. */\n private privateHome: string | null = null;\n /** Settles when the process last killed has exited and its private home is deleted. */\n private homeGone: Promise<void> = Promise.resolve();\n\n override getTokenUsage(): TokenUsage | null {\n return this._lastTokens;\n }\n\n override getContextTokens(): number | null {\n return this._lastContextTokens;\n }\n\n override getContextWindow(): number | null {\n return this._contextWindow;\n }\n\n /**\n * omp reports only its fill and window (`get_state.contextUsage`), refreshed\n * here so a request between turns is current. A local RPC, so cheap. Unlike\n * `captureState` it throws on a failed reply: a stale fill must never be\n * reported as a fresh measurement.\n */\n override async getContextUsageReport(): Promise<HarnessContextReport | null> {\n if (!this.proc) return null;\n const response = await this.request({ type: \"get_state\" }, { quiet: true });\n if (!response.success) {\n throw new Error(`omp get_state failed: ${response.error ?? \"no error given\"}`);\n }\n this.captureContextUsage((response.data as Record<string, unknown> | undefined)?.contextUsage);\n if (this._lastContextTokens === null && this._contextWindow === null) return null;\n return { usedTokens: this._lastContextTokens, contextWindow: this._contextWindow };\n }\n\n /** Per-turn settlement handlers; non-null only while a prompt is in flight. */\n private turnResolve: (() => void) | null = null;\n private turnReject: ((err: Error) => void) | null = null;\n /** omp host tool name → capability name for the last `set_host_tools` sent. */\n private hostToolCapabilities = new Map<string, string>();\n /** In-flight `host_tool_call`s by omp request id; aborted by `host_tool_cancel`. */\n private readonly hostToolCalls = new Map<string, { controller: AbortController; name: string }>();\n /** Requests awaiting a `response`, by request id; failed when the process goes away. */\n private readonly pendingRequests = new Map<string, (err: Error) => void>();\n /** Unsubscribes the capability registry listener; set while a process runs. */\n private unsubscribeToolsChanged: (() => void) | null = null;\n /** Request ids whose failed `response` is logged by the caller, not surfaced as an error event. */\n private readonly quietRequestIds = new Set<string>();\n /** Capability tools already warned about, so a re-send logs each once. */\n private readonly warnedDroppedHostTools = new Set<string>();\n /** The `ask` (or `select` fallback) omp is parked on, until answered, cancelled or the process ends. */\n private pendingQuestion: OmpPendingQuestion | null = null;\n /**\n * Tail of the FIFO of prompts: each `prompt()`/`promptInput()` runs only after\n * the previous one settled, so one turn at a time is ever in flight (omp runs\n * a single agent loop). Never rejects.\n */\n private promptTail: Promise<void> = Promise.resolve();\n /** `true` while `agent_end` is being delivered to listeners. */\n private turnEnded = false;\n /** `true` once the current turn showed model output (text, a thinking delta or a tool run). */\n private turnOutputSeen = false;\n /** `true` once `runPrompt` sent the current prompt a second time after an early exit. */\n private promptRetried = false;\n /** `true` once omp recorded the current prompt as a user message in its session. */\n private turnUserMessageSeen = false;\n /** Counts `kill()` calls, so a prompt that restarts omp itself can tell it was killed meanwhile. */\n private killEpoch = 0;\n\n override get runtimeSessionId(): string | undefined {\n return this._ompSessionId;\n }\n\n /** Slash commands from omp's last `available_commands_update`. */\n private cachedCommands: SlashCommandInfo[] = [];\n\n override getSlashCommands(): SlashCommandInfo[] {\n return this.cachedCommands;\n }\n\n override getModel(): string | undefined {\n return this.config.model;\n }\n\n /**\n * Owns the desired config, drift and ordering of live reconfigures. Its\n * snapshot is what the running omp process was last told: the config values\n * `model`, `modelRef`, `thinking` and `effort` came from (the rollback targets\n * when omp refuses a change) and the omp thinking `level` sent. Set at spawn,\n * updated on each successful `set_*`.\n */\n private readonly reconfig: ReconfigureLedger<OmpApplied>;\n\n /**\n * Apply `model` / `thinking` / `effort`: the {@link ReconfigureLedger} writes\n * the desired config and, when the process is up and idle, pushes it through\n * {@link applyLive} (`set_model` / `set_thinking_level`), answering from omp's\n * reply. A patch that arrives mid-turn or before `ready` is not lost: config is\n * the source of truth, flushed before the next `prompt()` and read by the next\n * spawn. A refusal (omp's, or a model `set_model` cannot express live: no\n * `provider/` prefix) rolls the config back and answers `rejected`. In registry\n * mode the patch also replaces `modelRef`, so a respawn (crash, `resetSession()`)\n * starts the reconfigured model; models.yml already lists every enabled provider.\n */\n override reconfigure(patch: ReconfigurePatch): Promise<ReconfigureOutcome> {\n return this.reconfig.reconfigure(patch);\n }\n\n /** Push drifted model / thinking settings to the running process. Never rejects. */\n private async applyLive(\n delta: ReconfigureApplied,\n applied: OmpApplied,\n { late }: ReconfigurePushContext,\n ): Promise<ReconfigureApplyResult> {\n if (delta.model !== undefined) {\n const target = splitOmpModel(delta.model);\n if (!target) {\n // `set_model` cannot express a bare name, so the running process keeps\n // its model: refuse rather than report one omp is not running.\n const message = `set_model cannot apply \"${delta.model}\" live (no provider/ prefix); model unchanged`;\n this.log.warn(\"model has no provider prefix; set_model cannot apply it live\", {\n model: delta.model,\n });\n if (!late) this.emit(\"agent-event\", { type: \"error\", error: message });\n return { rejected: message };\n }\n const refusal = await this.sendReconfigure({ type: \"set_model\", ...target }, late);\n if (refusal !== null) return { rejected: refusal };\n applied.model = delta.model;\n applied.modelRef = delta.modelRef ?? applied.modelRef;\n }\n\n if (delta.thinking !== undefined || delta.effort !== undefined) {\n const level = ompThinkingLevel(this.config);\n if (level !== undefined && level !== applied.level) {\n const refusal = await this.sendReconfigure({ type: \"set_thinking_level\", level }, late);\n if (refusal !== null) return { rejected: refusal };\n applied.level = level;\n }\n }\n return \"applied\";\n }\n\n /**\n * Send one live-reconfigure request. A failed `response` is emitted as an\n * `error` event by {@link handleEvent}, and a transport failure (timeout,\n * process gone) here, unless `late`: a refusal of a patch already answered\n * `ok` reaches the host as `reconfigure_rejected`, so it gets no `error`\n * event as well. Returns `null` when omp accepted it, else why not.\n */\n private async sendReconfigure(\n msg: { type: string; [key: string]: unknown },\n late: boolean,\n ): Promise<string | null> {\n try {\n const resp = await this.request(msg, { quiet: late });\n if (resp.success) return null;\n this.log.warn(\"omp rejected reconfigure\", { type: msg.type, error: resp.error });\n return typeof resp.error === \"string\" ? resp.error : `omp refused ${msg.type}`;\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err);\n this.log.warn(\"reconfigure request failed\", { type: msg.type, error });\n if (!late) {\n this.emit(\"agent-event\", { type: \"error\", error: `${msg.type} failed: ${error}` });\n }\n return `${msg.type} failed: ${error}`;\n }\n }\n\n /**\n * @param config - Harness configuration. omp-relevant fields:\n * - `cwd` — working directory; omp session files are stored under `<cwd>/.omp/sessions/`.\n * - `model` — forwarded as `--model <selector>`. In registry mode `modelRef` takes precedence at spawn; `reconfigure({ model })` keeps both in step.\n * - `systemPrompt` — written to a per-spawn file under `<cwd>/.skaile/cache/omp-system/` and appended via `--append-system-prompt`.\n * - `agentDir` — its entries are linked into omp's private home (`PI_CODING_AGENT_DIR`); the directory itself is never omp's home.\n * - `sshKeyPath` — injected as `GIT_SSH_COMMAND` for authenticated git operations.\n * - `resumeSessionId` — omp session UUID to restore via `--session <id>`.\n */\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n this.reconfig = new ReconfigureLedger<OmpApplied>({\n config: () => this.config,\n isLive: () => this.proc !== null && this.ready,\n isIdle: () => !this.turnResolve,\n applyLive: (delta, applied, context) => this.applyLive(delta, applied, context),\n onLateRejection: (rollback) => this.emit(\"reconfigure-rollback\", rollback),\n log: this.log,\n });\n }\n\n public async start(): Promise<void> {\n // In-flight start first: `proc` is set before `ready` and before the host\n // tools are registered, and callers must not prompt ahead of either.\n if (this.startPromise) return this.startPromise;\n if (this.proc) return;\n // A start that fails before omp is running (home or env setup, a spawn error) must not\n // leave the per-spawn system prompt file behind.\n this.startPromise = this._start()\n .then(() => {\n this.exitResumeSessionId = undefined;\n })\n .catch(async (err: unknown) => {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n // A restart that reopens the session omp lost can fail on that very session (its file is\n // gone or unreadable): start once more empty rather than leave the harness unusable.\n const resumeId = this.exitResumeSessionId;\n if (resumeId !== undefined && this.config.resumeSessionId === resumeId) {\n this.log.warn(\"omp did not restart on its previous session; starting a new one\", {\n sessionId: resumeId,\n error: err instanceof Error ? err.message : String(err),\n });\n this.exitResumeSessionId = undefined;\n this._ompSessionId = undefined;\n this.config = { ...this.config, resumeSessionId: undefined };\n return this._start().catch((retryErr: unknown) => {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n throw retryErr;\n });\n }\n throw err;\n });\n return this.startPromise;\n }\n\n private async _start(): Promise<void> {\n // `rpc-ui` keeps omp's tool UI (the `ask` dialog) on the wire; `--no-ui`\n // keeps its extensions headless, so no widget/notify frames or approval dialogs.\n const args = [\"--mode\", \"rpc-ui\", \"--no-ui\"];\n\n // ── Session persistence ───────────────────────────────────────────────────\n // Store OMP session files in <cwd>/.omp/sessions/ so they survive process\n // restarts. The caller passes resumeSessionId to restore a prior session.\n const sessionDir = path.join(this.config.cwd, \".omp\", \"sessions\");\n await fs.mkdir(sessionDir, { recursive: true });\n args.push(\"--session-dir\", sessionDir);\n\n if (this.config.resumeSessionId) {\n this.log.info(\"resuming OMP session\", { sessionId: this.config.resumeSessionId });\n args.push(\"--session\", this.config.resumeSessionId);\n }\n\n // ── Provider registry → session-private omp agent directory ───────────────\n // Every enabled registry entry is serialized into omp's own `models.yml`\n // inside a directory `PI_CODING_AGENT_DIR` points at, so an omp session\n // sees N selectable providers and resolves `@role` across them. Returns\n // undefined for a session that carries no registry, which keeps the\n // legacy `provider`/`model`/env path byte-identical.\n const providers = await materializeOmpProviders(this.config);\n if (providers) {\n // Known to cleanup() from here on, so a later start step that throws cannot leave it behind.\n this.privateHome = providers.ephemeral ? providers.agentDir : null;\n // A credential omission is printed once by `skaile run`/`repl` as the `! provider ... is\n // not used` line; the other warnings are plain text, not a raw JSON record (p598).\n for (const warning of providers.warnings) {\n if (isCredentialOmissionWarning(warning)) this.log.debug(warning);\n else this.log.warn(warning);\n }\n this.log.info(\"rendered omp models.yml\", {\n agentDir: providers.agentDir,\n providers: providers.providerIds,\n modelRoles: providers.modelRoles,\n seeded: providers.seeded.length,\n });\n } else if (this.config.registry) {\n // No usable entry, the selected model's entry was left out, or the session names no\n // model and the user's own omp default needs their own models.yml (p1172): omp runs on\n // the user's own agent directory and login.\n this.log.info(\"registry is not applied to omp; omp uses its own login and models\");\n }\n\n const modelArg = providers?.modelArg ?? this.config.model;\n if (modelArg) args.push(\"--model\", modelArg);\n\n // Thinking level: `--thinking <level>` (omp's default is `high`). The\n // spawn-time snapshot lets `reconfigure()` send only what has drifted.\n const thinkingLevel = ompThinkingLevel(this.config);\n if (thinkingLevel) args.push(\"--thinking\", thinkingLevel);\n this.reconfig.setSnapshot({\n model: this.config.model,\n modelRef: this.config.modelRef,\n thinking: this.config.thinking,\n effort: this.config.effort,\n level: thinkingLevel,\n });\n\n // ── Tool restrictions ─────────────────────────────────────────────────────\n // agent.yaml `tools:` reaches the harness as AgentConfig.tools. The\n // claude-sdk harness has always honoured it; omp did not, so a restricted\n // agent definition silently ran with omp's full default toolset — which\n // dominates the fixed token prefix of every request.\n const toolArgs = buildOmpToolArgs(this.config.tools);\n if (toolArgs.length > 0) {\n this.log.info(\"applying tool restrictions\", { args: toolArgs });\n args.push(...toolArgs);\n }\n\n // ── System prompt injection ───────────────────────────────────────────────\n // omp does not accept a system prompt string directly; it reads from a file.\n // The file is private to this spawn and goes away with the process: a fixed\n // `<cwd>/.omp/system.md` is loaded by every native omp session and sub-agent that\n // runs in the same project afterwards, and the nested `agent.run` child of one run\n // overwrote the parent's (last writer wins). The path is passed via\n // --append-system-prompt.\n //\n // In flow mode (factory-assets/connectors/flow/run-flow.ts conductFlow), systemPrompt carries the full agent\n // identity (SOUL + RULES + knowledge + connector docs) because no agentDir is set.\n // In REPL mode (agent.ts buildHarness), systemPrompt carries the runner's agent sections\n // (the soul included: omp reads no SOUL.md) and the connector docs.\n this.removeSystemPromptFile();\n if (this.config.systemPrompt) {\n const promptDir = path.join(this.config.cwd, \".skaile\", \"cache\", \"omp-system\");\n await fs.mkdir(promptDir, { recursive: true });\n const systemFile = path.join(promptDir, `${randomUUID()}.md`);\n await fs.writeFile(systemFile, this.config.systemPrompt);\n this.systemPromptFile = systemFile;\n args.push(\"--append-system-prompt\", systemFile);\n }\n\n // Explicit env whitelist for the omp child process. Avoids leaking the\n // runner's full environment (which may carry user secrets provisioned by\n // the platform) into the spawned subprocess. `this.config.env`, when\n // supplied, is merged over the whitelist (the caller wins per key), never\n // used in its place: a replaced env drops PATH and the spawn fails with\n // ENOENT (the model endpoint hands the harness only its endpoint variables).\n const env: Record<string, string> = {\n ...buildOmpChildEnv(process.env),\n ...(this.config.env as Record<string, string> | undefined),\n };\n // ── Main-agent handoff ────────────────────────────────────────────────────\n // PI_CODING_AGENT_DIR is omp's home: its runtime databases, credential store and\n // settings live there. It is never the agent directory itself: that holds the pinned\n // agent files (`.skaile/cache/agents/<name>/`) and omp's databases do not belong\n // beside them. omp reads `RULES.md` (not `SOUL.md`) from its home, so the agent's\n // entries are linked into a private home directory (see `materializeOmpIdentityDir`).\n // A rendered registry owns that home: it already contains the agent's files\n // (linked in from `agentDir`) plus the session's `models.yml` / `config.yml`.\n if (providers) {\n env.PI_CODING_AGENT_DIR = providers.agentDir;\n // The only place a credential *value* exists in this adapter. Registry\n // credentials override the ambient allowlist unconditionally: the\n // session's registry is the statement of intent, not whatever the host\n // happened to export.\n Object.assign(env, providers.credentialEnv);\n } else if (this.config.agentDir) {\n const home = await materializeOmpIdentityDir(this.config);\n if (home) {\n this.log.info(\"omp home for the agent\", { agentDir: home.agentDir });\n env.PI_CODING_AGENT_DIR = home.agentDir;\n this.privateHome = home.ephemeral ? home.agentDir : null;\n }\n }\n if (this.config.sshKeyPath) {\n env.GIT_SSH_COMMAND = `ssh -i \"${this.config.sshKeyPath}\" -o StrictHostKeyChecking=accept-new`;\n }\n stripRunnerPrivateEnv(env);\n\n // test-only: `OMP_BRIDGE_BIN` overrides the binary name and `OMP_BRIDGE_PREARGS`\n // (space-delimited) supplies any leading args (e.g. a JS script path when the\n // override binary is `node` or `bun`). Used by the subprocess harness tests in\n // `tests/omp-harness.test.ts` to point spawn at a fake-omp script without\n // monkey-patching `node:child_process`. Both are ignored in production.\n const overrideBin = process.env.OMP_BRIDGE_BIN;\n const overridePreArgs = process.env.OMP_BRIDGE_PREARGS\n ? process.env.OMP_BRIDGE_PREARGS.split(/\\s+/).filter(Boolean)\n : [];\n const spawnBin = overrideBin || \"omp\";\n const spawnArgs = overrideBin ? [...overridePreArgs, ...args] : args;\n\n const spawned = await new Promise<ChildProcess>((resolve, reject) => {\n const startStderr: string[] = [];\n this.log.info(\"spawning omp\", {\n bin: spawnBin,\n args: spawnArgs,\n cwd: this.config.cwd,\n });\n if (env.PI_CODING_AGENT_DIR)\n this.log.debug(\"env: PI_CODING_AGENT_DIR set\", { value: env.PI_CODING_AGENT_DIR });\n if (env.GIT_SSH_COMMAND) this.log.debug(\"env: GIT_SSH_COMMAND set\");\n\n // Cast to ChildProcess: spawn infers ChildProcessWithoutNullStreams for\n // pipe stdio, but bun-types doesn't expose EventEmitter.on on that subtype.\n // With the uid split on, omp runs as the agent uid through the launch shim.\n const target = wrapAgentCommand(spawnBin, spawnArgs, resolveAgentExec());\n const proc = spawn(target.command, target.args, {\n cwd: this.config.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }) as ChildProcess;\n this.proc = proc;\n // bun-types 1.3.11 omits EventEmitter.on from ChildProcess; cast to subscribe.\n const procEmitter = proc as unknown as EventEmitter;\n\n procEmitter.on(\"error\", (err: Error) => {\n // A process replaced (or killed) by kill()/resetSession() no longer\n // owns the turn, the ready state or the error channel.\n if (this.proc !== proc) {\n clearTimeout(readyTimeout);\n reject(err);\n return;\n }\n const detail = this.classifyProcessError(err as NodeJS.ErrnoException);\n this.log.error(\"process error\", err, { detail });\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n if (!this.ready) reject(err);\n // Settle any in-flight turn so a process-level error cannot hang prompt().\n this.rejectTurn(Object.assign(new Error(detail.message), { detail }));\n });\n\n procEmitter.on(\"exit\", (code: number | null, signal: NodeJS.Signals | null) => {\n this.log.info(\"process exited\", { code, signal });\n if (this.proc !== proc) {\n // Killed or replaced by kill()/resetSession(): the kill settled its own\n // turn and cleaned up, and a late exit must neither reject the turn of\n // the process that succeeded it nor tear down that process's state.\n // A start still waiting for `ready` on this process is over.\n clearTimeout(readyTimeout);\n reject(new Error(\"omp process killed before it was ready\"));\n // Only a plain kill() is announced; a live successor is not exiting.\n if (this.proc === null) this.emit(\"exit\", { code, signal });\n return;\n }\n const lastStderr = this.stderrBuffer.slice(-10).join(\"\\n\");\n const crashed = code !== null && code !== 0;\n // An exit while no turn is in flight (and after omp was ready) loses nothing the client\n // is waiting for: the next prompt starts omp again on the same session. It is logged\n // with omp's last stderr lines, not sent as an error the client must treat as fatal.\n const wasReady = this.ready;\n const betweenTurns = wasReady && this.turnReject === null;\n if (wasReady) {\n const sessionId = this._ompSessionId;\n // The respawn reopens the conversation omp had: without this it starts empty.\n if (sessionId) {\n this.config = { ...this.config, resumeSessionId: sessionId };\n this.exitResumeSessionId = sessionId;\n }\n if (betweenTurns) {\n this.log.warn(\"omp exited between turns; it restarts on the next prompt\", {\n code,\n signal,\n resumeSessionId: sessionId ?? null,\n stderr: lastStderr || null,\n });\n } else if (lastStderr) {\n this.log.warn(\"omp exited during a turn\", { code, signal, stderr: lastStderr });\n }\n }\n // A restart on the session omp lost that fails is retried on a new session by start().\n const resumeAttempt =\n !wasReady &&\n this.exitResumeSessionId !== undefined &&\n this.config.resumeSessionId === this.exitResumeSessionId;\n // An exit in a turn before omp showed any output is retried once by `runPrompt`: the\n // error the client would treat as fatal is held back for it.\n // A session omp already wrote the prompt into is not reopened to send it again.\n const wouldDuplicate =\n this.turnUserMessageSeen && this.config.resumeSessionId !== undefined;\n const retryEarly =\n (crashed || signal !== null) &&\n wasReady &&\n !betweenTurns &&\n !this.turnOutputSeen &&\n !wouldDuplicate &&\n !this.promptRetried &&\n !resumeAttempt;\n if (retryEarly) {\n this.log.warn(\"omp exited in a turn before its first output\", {\n code,\n signal,\n stderr: lastStderr || null,\n });\n } else if (crashed && !betweenTurns && !resumeAttempt) {\n // Without stderr nothing says why omp stopped: name the exit and where its session\n // files are, so the run can be looked at.\n const sessionDir = path.join(this.config.cwd, \".omp\", \"sessions\");\n const detail: AgentError = {\n message: `omp process crashed (exit code ${code})${lastStderr ? `: ${lastStderr}` : \"\"}`,\n category: \"process\",\n retryable: true,\n hint:\n lastStderr ||\n `omp exited with code ${code}${signal ? ` (signal ${signal})` : \"\"} and wrote nothing to stderr; its session files are in ${sessionDir}. Try sending your prompt again.`,\n };\n if (!lastStderr) {\n this.log.warn(\"omp exited with no stderr\", {\n code,\n signal,\n sessionDir,\n sessionId: this._ompSessionId ?? null,\n });\n }\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n }\n // An exit before `ready` ends the start: without this the start promise never\n // settles (the ready timeout skips a gone process), and a caller awaiting it\n // hangs, or the process ends on a pending top-level await. Rejected on `close`\n // so omp's last stderr lines (the reason it gave up) are read first.\n if (!this.ready) {\n clearTimeout(readyTimeout);\n // Settles once: on `close` (stdio drained), or after 1 s if `close` never fires.\n // Not unref'd, so the pending start keeps the process alive until it rejects.\n const rejectStart = () => {\n clearTimeout(fallback);\n reject(\n new Error(\n `omp exited before it was ready (${code !== null ? `exit code ${code}` : `signal ${signal}`})${startStderr.length > 0 ? `: ${ompCredentialMessage(ompStartFailureCause(startStderr))}` : \"\"}`,\n ),\n );\n };\n const fallback = setTimeout(rejectStart, 1000);\n procEmitter.once(\"close\", rejectStart);\n }\n this.cleanup();\n // Settle any in-flight turn: an exit before `agent_end` means the turn\n // can never complete normally, so reject rather than leak a pending promise.\n this.rejectTurn(\n retryEarly\n ? new EarlyOmpExit(code, signal)\n : new Error(\n crashed\n ? `omp process crashed (exit code ${code})`\n : `omp process exited before the turn completed${signal ? ` (signal ${signal})` : \"\"}`,\n ),\n );\n this.emit(\"exit\", { code, signal });\n });\n\n if (proc.stdout) {\n const rl = createInterface({ input: proc.stdout });\n this.rl = rl;\n // bun-types 1.3.11 omits EventEmitter.on from readline.Interface; cast to subscribe.\n (rl as unknown as EventEmitter).on(\"line\", (line: string) => {\n if (!line.trim()) return;\n try {\n const event: OmpEvent = JSON.parse(line);\n this.handleEvent(event);\n } catch {\n this.log.debug(\"stdout\", { line });\n }\n });\n }\n\n // Before omp is ready its stderr is the cause of a failed start, and the start error\n // carries that cause once (p598). The lines go to the debug log meanwhile; a start that\n // succeeds replays them as warnings, so a notice of a working omp is not lost.\n const replayStartStderr = (): void => {\n for (const line of startStderr) this.log.warn(`stderr: ${line}`);\n };\n if (proc.stderr) {\n const stderrRl = createInterface({ input: proc.stderr });\n (stderrRl as unknown as EventEmitter).on(\"line\", (line: string) => {\n if (this.ready) this.log.warn(`stderr: ${line}`);\n else this.log.debug(`stderr: ${line}`);\n this.stderrBuffer.push(line);\n if (this.stderrBuffer.length > 20) this.stderrBuffer.shift();\n startStderr.push(line);\n if (startStderr.length > 20) startStderr.shift();\n });\n }\n\n const startTime = Date.now();\n const readyTimeout = setTimeout(() => {\n // Not for a process that was replaced or has gone: it must not mark the\n // harness (now owned by a successor, or stopped) as ready.\n if (!this.ready && this.proc === proc) {\n this.log.warn(\"ready timeout, proceeding\", { timeoutMs: 5000 });\n this.ready = true;\n replayStartStderr();\n resolve(proc);\n }\n }, 5000);\n\n this.once(\"ready\", () => {\n clearTimeout(readyTimeout);\n if (!this.ready && this.proc === proc) {\n this.log.info(\"process ready\", { elapsedMs: Date.now() - startTime });\n this.ready = true;\n replayStartStderr();\n resolve(proc);\n }\n });\n });\n\n // Every await below can span a kill()/resetSession(): the successor owns the\n // harness state then, so a start for this process must not touch it.\n const assertCurrent = (): void => {\n if (this.proc !== spawned) throw new Error(\"omp process was killed during start\");\n };\n\n assertCurrent();\n // Subscribed before the requests so a registry change that lands while they\n // are in flight is not missed. There is no await between the check and the\n // subscription, so a later kill()'s cleanup() always unsubscribes it.\n const hooks = this.config.capabilities;\n if (hooks) {\n this.unsubscribeToolsChanged =\n hooks.onToolsChanged?.(() => {\n void this.syncHostTools();\n }) ?? null;\n }\n\n // Independent of each other, so concurrent: a misbehaving omp blocks start\n // for one request timeout, not two. Both are best-effort and never throw.\n // Before start() resolves, so the first `ask` already arrives as one dialog\n // and the first prompt already sees the tools.\n await Promise.all([this.enableAskDialog(), hooks ? this.syncHostTools() : undefined]);\n assertCurrent();\n\n // Context fill is known before the first prompt (system prompt + tools);\n // best-effort and not awaited, so a slow `get_state` never delays start().\n void this.captureState({ announceSession: false });\n }\n\n /**\n * Register the runner's capabilities with omp as host tools.\n *\n * Sends the full set every time: `set_host_tools` replaces omp's previous\n * host-owned set, so a registry change that removes a capability takes\n * effect too. Best-effort — a failure is logged and the session runs\n * without host tools rather than failing to start.\n */\n private async syncHostTools(): Promise<void> {\n const hooks = this.config.capabilities;\n if (!hooks || !this.proc) return;\n const set = buildOmpHostTools(hooks.composeTools());\n for (const { tool, reason } of set.dropped) {\n const key = `${tool}\\u0000${reason}`;\n if (this.warnedDroppedHostTools.has(key)) continue;\n this.warnedDroppedHostTools.add(key);\n this.log.warn(\"host tool dropped: invalid input schema\", { tool, reason });\n }\n // Swapped before sending so a call racing the response already routes.\n this.hostToolCapabilities = set.capabilityNames;\n try {\n const response = await this.request(\n { type: \"set_host_tools\", tools: set.definitions },\n { quiet: true },\n );\n if (response.success) {\n const data = response.data as { toolNames?: unknown } | undefined;\n this.log.info(\"registered omp host tools\", { toolNames: data?.toolNames });\n } else {\n this.log.error(\"omp rejected host tools\", new Error(response.error ?? \"unknown error\"), {\n tools: set.definitions.map((t) => t.name),\n });\n }\n } catch (err) {\n this.log.error(\"registering omp host tools failed\", err as Error);\n }\n }\n\n /**\n * Execute a capability omp asked the host to run (`host_tool_call`) and\n * answer with `host_tool_result`. Goes through {@link dispatchCapability}\n * so validation, fire-and-forget and render semantics match claude-sdk.\n *\n * Emits `tool_call` / `tool_execution_end` around the dispatch: the\n * normalizer does not read omp's own tool frames, so without these the\n * call — and its `activity_label` — would never reach the chat.\n */\n private handleHostToolCall(event: OmpEvent): void {\n const id = event.id;\n if (typeof id !== \"string\") return;\n const hostName = typeof event.toolName === \"string\" ? event.toolName : \"\";\n const name = this.hostToolCapabilities.get(hostName) ?? hostName;\n const callId = typeof event.toolCallId === \"string\" ? event.toolCallId : id;\n const input = event.arguments ?? {};\n const hooks = this.config.capabilities;\n const controller = new AbortController();\n const call = { controller, name };\n this.hostToolCalls.set(id, call);\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name,\n tool: { name },\n toolCallId: callId,\n input,\n });\n\n void (async () => {\n let text: string;\n let isError = false;\n try {\n if (!hooks) throw new Error(`no capability host for ${name}`);\n const dispatch = await dispatchCapability(\n hooks,\n name,\n input,\n (_err, dispatchCallId) =>\n this.log.warn(\"background capability handler failed\", {\n name,\n toolCallId: callId,\n callId: dispatchCallId,\n // Nothing from the error: its message can quote the call's content.\n }),\n controller.signal,\n );\n text =\n typeof dispatch.result === \"string\"\n ? dispatch.result\n : JSON.stringify(dispatch.result ?? {});\n } catch (err) {\n isError = true;\n text = `Error: ${(err as Error)?.message ?? String(err)}`;\n }\n // Cancelled by omp or the process went away: nobody awaits a result.\n if (this.hostToolCalls.get(id) !== call) return;\n this.hostToolCalls.delete(id);\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: name });\n try {\n this.send({\n type: \"host_tool_result\",\n id,\n result: { content: [{ type: \"text\", text }] },\n ...(isError ? { isError: true } : {}),\n });\n } catch (err) {\n this.log.warn(\"host tool result undeliverable\", { name, callId, error: String(err) });\n }\n })();\n }\n\n /**\n * `host_tool_cancel`: omp aborted the call, so abort the capability handler\n * and close the call's chat activity (the handler's later settlement is\n * ignored, so this is the only `tool_execution_end` the call gets).\n */\n private handleHostToolCancel(event: OmpEvent): void {\n const targetId = event.targetId;\n if (typeof targetId !== \"string\") return;\n this.abortHostToolCall(targetId);\n }\n\n /** Abort one in-flight host tool call and end its activity; no-op if already settled. */\n private abortHostToolCall(id: string): void {\n const call = this.hostToolCalls.get(id);\n if (!call) return;\n this.hostToolCalls.delete(id);\n call.controller.abort();\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: call.name });\n }\n\n // ── Interactive questions (`ask`) ──────────────────────────────────────────\n\n /**\n * `extension_ui_request`: omp asks the host something. Only `ask` (and the\n * `select` omp falls back to when `set_ask_dialog` is unavailable) can carry\n * a user question; both park until {@link answerQuestion}. Presentation\n * frames expect no reply. Every other kind is a dialog nobody here can\n * answer, so it is cancelled at once — an unanswered dialog would leave the\n * tool call, and the turn, waiting forever.\n */\n private handleExtensionUiRequest(event: OmpEvent): void {\n const method = event.method;\n if (method === \"cancel\") {\n // omp closed a dialog itself (timeout, abort): nothing is owed any more.\n if (typeof event.targetId === \"string\" && this.pendingQuestion?.id === event.targetId) {\n this.pendingQuestion = null;\n }\n return;\n }\n if (\n method === \"notify\" ||\n method === \"setStatus\" ||\n method === \"setWidget\" ||\n method === \"setTitle\" ||\n method === \"set_editor_text\" ||\n method === \"open_url\"\n ) {\n return;\n }\n const id = event.id;\n if (typeof id !== \"string\") return;\n let parsed: OmpPendingQuestion | null = null;\n if (method === \"ask\") parsed = this.parseAskRequest(id, event);\n else if (method === \"select\") parsed = this.parseSelectRequest(id, event);\n if (!parsed) {\n this.log.debug(\"cancelling unsupported omp dialog\", { method: String(method) });\n this.sendUiResponse({ id, cancelled: true });\n return;\n }\n // omp parks on one dialog at a time; a second request means the first is dead.\n this.cancelPendingQuestion();\n this.pendingQuestion = parsed;\n this.announceQuestion(parsed, event);\n }\n\n private parseAskRequest(id: string, event: OmpEvent): OmpPendingQuestion | null {\n if (!Array.isArray(event.questions) || event.questions.length === 0) return null;\n const questions: OmpPendingQuestion[\"questions\"] = [];\n for (const raw of event.questions as unknown[]) {\n const q = raw as { id?: unknown; question?: unknown; options?: unknown; multi?: unknown };\n // The response needs one `{ id }` entry per question; without either field\n // the ask cannot be answered correctly, so refuse it rather than guess.\n if (!q || typeof q.id !== \"string\" || typeof q.question !== \"string\" || !q.question) {\n return null;\n }\n const options = (Array.isArray(q.options) ? (q.options as unknown[]) : []).flatMap((o) => {\n let label: unknown = o;\n if (o && typeof o === \"object\" && \"label\" in o) label = o.label;\n return typeof label === \"string\" ? [label] : [];\n });\n questions.push({ id: q.id, question: q.question, options, multi: q.multi === true });\n }\n return { id, method: \"ask\", questions, answers: questions.map(() => undefined) };\n }\n\n private parseSelectRequest(id: string, event: OmpEvent): OmpPendingQuestion | null {\n if (typeof event.title !== \"string\" || !event.title || !Array.isArray(event.options)) {\n return null;\n }\n const options = (event.options as unknown[]).filter((o): o is string => typeof o === \"string\");\n if (options.length === 0) return null;\n return {\n id,\n method: \"select\",\n questions: [{ id, question: event.title, options, multi: false }],\n answers: [undefined],\n };\n }\n\n /**\n * Publish the parked question the way claude-sdk does for `AskUserQuestion`:\n * an assistant `tool_use` block the normalizer turns into one `question`\n * event per question, plus the matching `tool_call`. Option descriptions and\n * `header`s survive in the tool input for consumers that render them.\n */\n private announceQuestion(pending: OmpPendingQuestion, event: OmpEvent): void {\n const rawQuestions = Array.isArray(event.questions) ? (event.questions as unknown[]) : [];\n const input = {\n requestId: pending.id,\n questions: pending.questions.map((q, i) => {\n const raw = rawQuestions[i] as\n | { header?: unknown; options?: Array<{ label?: unknown; description?: unknown }> }\n | undefined;\n return {\n question: q.question,\n ...(typeof raw?.header === \"string\" ? { header: raw.header } : {}),\n multiSelect: q.multi,\n options: q.options.map((label, j) => {\n const description = raw?.options?.[j]?.description;\n return { label, ...(typeof description === \"string\" ? { description } : {}) };\n }),\n };\n }),\n };\n const toolCallId = `omp-ask:${pending.id}`;\n this.emit(\"agent-event\", {\n type: \"message_start\",\n message: {\n role: \"assistant\",\n content: [{ type: \"tool_use\", name: \"AskUserQuestion\", id: toolCallId, input }],\n },\n });\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: \"AskUserQuestion\",\n tool: { name: \"AskUserQuestion\" },\n toolCallId,\n input,\n });\n this.log.debug(\"paused on omp ask\", { questions: pending.questions.length });\n }\n\n override supersedePendingQuestion(): void {\n this.cancelPendingQuestion();\n }\n\n override hasPendingQuestion(): boolean {\n return this.pendingQuestion !== null;\n }\n\n /**\n * While omp is parked on a question a reply that is not an answer must not\n * become a prompt: the turn is still running, and a second prompt would\n * collide with it.\n */\n override get acceptsReplyAsPrompt(): boolean {\n return this.pendingQuestion === null;\n }\n\n override answerQuestion(answer: string, question?: string, requestId?: string): boolean {\n const pending = this.pendingQuestion;\n if (!pending || typeof answer !== \"string\") return false;\n if (requestId !== undefined && requestId !== pending.id) return false;\n\n // A named answer binds to its own question; an unnamed one fills the next\n // unanswered slot. Same rule as claude-sdk.\n let index =\n question !== undefined ? pending.questions.findIndex((q) => q.question === question) : -1;\n if (index === -1) index = pending.answers.indexOf(undefined);\n if (index === -1) return false;\n pending.answers[index] = answer;\n if (pending.answers.some((a) => a === undefined)) return true;\n\n this.pendingQuestion = null;\n this.sendUiResponse(this.buildQuestionResponse(pending));\n this.log.debug(\"answered omp ask\", { questions: pending.questions.length });\n return true;\n }\n\n /** Shape the collected answers as the `extension_ui_response` payload for the request's method. */\n private buildQuestionResponse(pending: OmpPendingQuestion): Record<string, unknown> {\n const find = (options: string[], text: string): string | undefined =>\n options.find((o) => o === text) ??\n options.find((o) => o.toLowerCase() === text.toLowerCase());\n\n if (pending.method === \"select\") {\n const match = find(pending.questions[0]!.options, (pending.answers[0] ?? \"\").trim());\n if (match !== undefined) return { id: pending.id, value: match };\n // A `select` only takes one of its options; free text has nowhere to go.\n this.log.warn(\"select answer matches no option; cancelling it\");\n return { id: pending.id, cancelled: true };\n }\n\n const answers = pending.questions.map((q, i) => {\n const text = (pending.answers[i] ?? \"\").trim();\n const whole = find(q.options, text);\n if (whole !== undefined) return { id: q.id, selectedOptions: [whole] };\n if (q.multi) {\n // The UI hands a multi-select back as one string; take a comma-separated\n // list of labels apart, but only if every piece is a real option.\n const parts = text\n .split(\",\")\n .map((p) => p.trim())\n .filter(Boolean);\n const matched = parts.map((p) => find(q.options, p));\n if (parts.length > 0 && matched.every((m) => m !== undefined)) {\n return { id: q.id, selectedOptions: [...new Set(matched as string[])] };\n }\n }\n // Anything else is the user's own words (omp always offers free text).\n return { id: q.id, selectedOptions: [], ...(text ? { customInput: text } : {}) };\n });\n return { id: pending.id, answers };\n }\n\n /** Write an `extension_ui_response`; undeliverable (process gone) is logged, not thrown. */\n private sendUiResponse(payload: Record<string, unknown>): void {\n try {\n this.send({ type: \"extension_ui_response\", ...payload });\n } catch (err) {\n this.log.warn(\"extension ui response undeliverable\", { error: String(err) });\n }\n }\n\n /** Drop the pending question and tell omp it was cancelled, so its tool call unwinds. */\n private cancelPendingQuestion(): void {\n const pending = this.pendingQuestion;\n if (!pending) return;\n this.pendingQuestion = null;\n this.sendUiResponse({ id: pending.id, cancelled: true });\n }\n\n /**\n * Opt in to omp's single `ask` dialog request (off by default per process).\n * Best-effort: a build without the command answers with a failed response and\n * its `ask` keeps degrading to one `select` per question, which\n * {@link handleExtensionUiRequest} still surfaces as a question.\n */\n private async enableAskDialog(): Promise<void> {\n try {\n const response = await this.request(\n { type: \"set_ask_dialog\", enabled: true },\n { quiet: true },\n );\n if (!response.success) {\n this.log.warn(\"omp rejected set_ask_dialog; ask falls back to select\", {\n error: response.error,\n });\n }\n } catch (err) {\n this.log.warn(\"set_ask_dialog failed\", { error: String(err) });\n }\n }\n\n private extractMessageText(msg: OmpMessage): string {\n if (!msg) return \"\";\n const c = msg.content;\n if (typeof c === \"string\") return c;\n if (Array.isArray(c))\n return c\n .filter((b) => b.type === \"text\" && b.text)\n .map((b) => b.text)\n .join(\"\");\n return \"\";\n }\n\n /**\n * `available_commands_update`: replace the cached slash-command list and\n * publish it. Names carry no leading slash (omp's already don't), matching\n * claude-sdk's `commands_available`. Entries without a name are skipped.\n */\n private handleCommandsUpdate(event: OmpEvent): void {\n const raw = Array.isArray(event.commands) ? (event.commands as unknown[]) : [];\n const commands: SlashCommandInfo[] = [];\n for (const entry of raw) {\n if (!entry || typeof entry !== \"object\") continue;\n const c = entry as { name?: unknown; description?: unknown; input?: { hint?: unknown } };\n if (typeof c.name !== \"string\" || !c.name) continue;\n const hint = c.input && typeof c.input === \"object\" ? c.input.hint : undefined;\n commands.push({\n name: c.name,\n description: typeof c.description === \"string\" ? c.description : \"\",\n argumentHint: typeof hint === \"string\" && hint ? hint : undefined,\n });\n }\n this.cachedCommands = commands;\n this.emit(\"agent-event\", { type: \"commands_available\", commands });\n this.log.debug(\"discovered slash commands\", { count: commands.length });\n }\n\n private handleEvent(event: OmpEvent) {\n if (event.type === \"ready\") {\n this.emit(\"ready\");\n return;\n }\n if (event.type === \"response\") {\n const quiet = typeof event.id === \"string\" && this.quietRequestIds.delete(event.id);\n if (!event.success && event.error && !quiet) {\n const detail = this.classifyErrorMessage(event.error);\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n }\n this.emit(`response:${event.id}`, event);\n return;\n }\n // The first sign of the model at work (text, a tool run, a host tool call or a dialog): from\n // here an exit loses output the client has seen, so the turn is no longer retried.\n if (\n (event.type === \"message_start\" && event.message?.role === \"assistant\") ||\n event.type === \"message_update\" ||\n event.type === \"host_tool_call\" ||\n event.type === \"extension_ui_request\" ||\n event.type.startsWith(\"tool_execution\")\n ) {\n this.turnOutputSeen = true;\n }\n // omp writes the user message to its session file at this point: a session that is\n // reopened afterwards already holds the prompt, so it must not be sent again.\n if (event.type === \"message_end\" && event.message?.role === \"user\") {\n this.turnUserMessageSeen = true;\n }\n // Host tool requests are answered here, not forwarded: they are a\n // host↔omp exchange, surfaced to consumers as `tool_call` events.\n if (event.type === \"host_tool_call\") {\n this.handleHostToolCall(event);\n return;\n }\n if (event.type === \"host_tool_cancel\") {\n this.handleHostToolCancel(event);\n return;\n }\n // UI dialogs (`ask`, …) are a host↔omp exchange: published as `question`\n // events and answered via `answerQuestion`, never forwarded raw.\n if (event.type === \"extension_ui_request\") {\n this.handleExtensionUiRequest(event);\n return;\n }\n // Slash-command list pushed by omp after `ready` and on change: published\n // as `commands_available` (like claude-sdk), never forwarded raw.\n if (event.type === \"available_commands_update\") {\n this.handleCommandsUpdate(event);\n return;\n }\n if (event.type === \"error\" && event.error) {\n const detail = this.classifyErrorMessage(event.error);\n this.emit(\"agent-event\", { ...event, error: detail.message, detail });\n return;\n }\n // Compute text delta for message_update events\n if (event.type === \"message_update\" && event.message) {\n const text = this.extractMessageText(event.message);\n let delta = \"\";\n if (text.startsWith(this.prevText)) {\n delta = text.slice(this.prevText.length);\n } else {\n // Text blocks restructured — emit full text as delta\n delta = text;\n }\n this.prevText = text;\n // Thinking never enters `_textDelta` (extractMessageText sees text blocks\n // only). It travels beside it as `_thinkingDelta`, taken straight from\n // omp's `thinking_delta` sub-event so it cannot duplicate or reorder.\n const sub = event.assistantMessageEvent;\n const thinking =\n sub && typeof sub === \"object\" && \"type\" in sub && sub.type === \"thinking_delta\"\n ? \"delta\" in sub && typeof sub.delta === \"string\"\n ? sub.delta\n : \"\"\n : \"\";\n this.emit(\"agent-event\", {\n ...event,\n _textDelta: delta,\n ...(thinking ? { _thinkingDelta: thinking } : {}),\n });\n return;\n }\n // Reset delta tracking on message boundaries. `message_start` may already\n // carry content (omp 18.x puts the whole reply, or its first chunk, into the\n // start frame). That text must reach a delta consumer: seeding `prevText`\n // from it alone dropped it (the one-shot `skaile run` printed only what the\n // later updates added), and clearing it made the normalizer count it twice.\n // So the assistant's start text leaves the start frame and travels as the\n // first `_textDelta`, in a `message_update` right after it.\n if (event.type === \"message_start\") {\n const startText =\n event.message?.role === \"assistant\" ? this.extractMessageText(event.message) : \"\";\n this.prevText = startText;\n if (startText && event.message) {\n const content = event.message.content;\n const message = {\n ...event.message,\n content: Array.isArray(content) ? content.filter((b) => b.type !== \"text\") : \"\",\n };\n this.emit(\"agent-event\", { ...event, message });\n this.emit(\"agent-event\", {\n type: \"message_update\",\n message: event.message,\n _textDelta: startText,\n });\n return;\n }\n }\n if (event.type === \"message_end\" || event.type === \"agent_end\") {\n this.prevText = \"\";\n }\n\n if (event.type === \"message_end\") this.recordMessageUsage(event.message);\n if (event.type === \"tool_execution_start\") this.announceToolExecution(event);\n\n // A failed omp request arrives as `message_end` with `stopReason: \"error\"`,\n // not as an `error` event. Without this branch the turn ended silently: the\n // caller saw a normal completion with no assistant text and no failure,\n // which reads as a hung or empty agent. Surface it on the same channel as\n // every other harness error so callers can classify and retry.\n if (\n event.type === \"message_end\" &&\n event.message?.role === \"assistant\" &&\n event.message.stopReason === \"error\"\n ) {\n const error = event.message.errorMessage || \"omp request failed\";\n const detail = this.classifyErrorMessage(error);\n this.log.error(\"omp request failed\", new Error(error), { detail });\n this.emit(\"agent-event\", { type: \"error\", error: detail.message, detail });\n this.turnFailed = true;\n }\n\n // After each turn ends, capture the OMP session ID so callers can persist it\n // and pass it as resumeSessionId on the next spawn.\n if (event.type === \"agent_end\") {\n // omp sends no `result`: report the turn's usage the way the other harnesses do,\n // so the turn's `finished` carries its tokens and cost. The subtype stays\n // `success` on a failed turn: any other one would become a second `error`\n // and drop the `finished`; the `error` above already reported the failure.\n this.emit(\"agent-event\", {\n type: \"result\",\n subtype: \"success\",\n summary: this.turnFailed ? \"Turn failed\" : \"Turn completed\",\n costUsd: this._lastTurnCostUsd,\n ...(this._lastTokens ? { tokens: { ...this._lastTokens } } : {}),\n });\n void this.captureState();\n }\n // A listener that kills the harness while it handles `agent_end` (the\n // one-shot `skaile run` does) ends a turn that already finished: `kill()`\n // must settle it as done, not as \"omp process killed\".\n const turnEnded = event.type === \"agent_end\";\n this.turnEnded = turnEnded;\n try {\n this.emit(\"agent-event\", event);\n } finally {\n this.turnEnded = false;\n }\n // Resolve AFTER emitting so listeners observing the turn see `agent_end`\n // before the caller's `prompt()` await unblocks.\n if (turnEnded) {\n this.resolveTurn();\n }\n }\n\n /**\n * Resolve the in-flight prompt turn (on `agent_end`). Idempotent — a turn\n * settles at most once, so a stray second `agent_end` is harmless.\n */\n private resolveTurn(): void {\n const resolve = this.turnResolve;\n this.turnResolve = null;\n this.turnReject = null;\n resolve?.();\n }\n\n /**\n * Reject the in-flight prompt turn (process crash/error). Settling here keeps\n * `prompt()` from hanging forever when the child dies before `agent_end`.\n */\n private rejectTurn(err: Error): void {\n const reject = this.turnReject;\n this.turnResolve = null;\n this.turnReject = null;\n reject?.(err);\n }\n\n /**\n * Query OMP's current state via the `get_state` RPC.\n *\n * Always refreshes the context fill from `contextUsage`. With\n * `announceSession` (the default, used after each turn) it also records the\n * native session ID and emits a `session_info` event so the forge layer can\n * persist it. Failures are silently swallowed — both are best-effort.\n */\n private async captureState(options: { announceSession?: boolean } = {}): Promise<void> {\n const announceSession = options.announceSession ?? true;\n try {\n const response = await this.request({ type: \"get_state\" }, { quiet: !announceSession });\n\n if (response.success && response.data) {\n const data = response.data as Record<string, unknown>;\n this.captureContextUsage(data.contextUsage);\n const sessionId = data.sessionId as string | undefined;\n const sessionFile = data.sessionFile as string | undefined;\n if (announceSession && sessionId) {\n this._ompSessionId = sessionId;\n this.log.debug(\"omp session id assigned\", { sessionId });\n this.emit(\"agent-event\", {\n type: \"session_info\",\n harnessSessionId: sessionId,\n ...(sessionFile ? { sessionFile } : {}),\n });\n }\n }\n } catch {\n // get_state is best-effort — OMP may not support it yet or the process\n // may have exited. The short-term history injection fallback still works.\n }\n }\n\n /** `get_state.contextUsage` → context fill + window; absent or malformed values are ignored. */\n private captureContextUsage(raw: unknown): void {\n if (!raw || typeof raw !== \"object\") return;\n const tokens = \"tokens\" in raw ? raw.tokens : undefined;\n const contextWindow = \"contextWindow\" in raw ? raw.contextWindow : undefined;\n if (typeof tokens === \"number\" && Number.isFinite(tokens) && tokens >= 0) {\n this._lastContextTokens = tokens;\n }\n if (typeof contextWindow === \"number\" && Number.isFinite(contextWindow) && contextWindow > 0) {\n this._contextWindow = contextWindow;\n }\n }\n\n /** Forget the previous turn's usage; called as a new turn begins. */\n private beginUsageTurn(): void {\n this._lastTokens = null;\n this._lastContextTokens = null;\n this._lastTurnCostUsd = 0;\n this.turnFailed = false;\n }\n\n /**\n * omp announces a tool run as `tool_execution_start`; its assistant message names the\n * call only in `message_end`, after the run. Publish it as `tool_call` here, like a host\n * tool call. Host tools already got theirs from `host_tool_call`, and `ask` becomes a\n * `question` through its dialog.\n */\n private announceToolExecution(event: OmpEvent): void {\n const name = typeof event.toolName === \"string\" ? event.toolName : \"\";\n if (!name || name === \"ask\" || this.hostToolCapabilities.has(name)) return;\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name,\n tool: { name },\n ...(typeof event.toolCallId === \"string\" ? { toolCallId: event.toolCallId } : {}),\n input: event.args ?? {},\n });\n }\n\n /**\n * Fold one finished assistant message into the turn's usage. Only the\n * `message_end` value is final (`message_start` and partials carry running\n * zeros). A message without usage, or an errored one reporting all zeros,\n * bills nothing and must neither create a reading nor wipe a good one.\n */\n private recordMessageUsage(message: OmpMessage | undefined): void {\n if (message?.role !== \"assistant\" || !message.usage) return;\n const count = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : undefined;\n const input = count(message.usage.input);\n const output = count(message.usage.output);\n const cacheRead = count(message.usage.cacheRead);\n const cacheWrite = count(message.usage.cacheWrite);\n const reasoning = count(message.usage.reasoningTokens);\n const total = count(message.usage.totalTokens);\n const callContext = (input ?? 0) + (cacheRead ?? 0) + (cacheWrite ?? 0);\n if (callContext + (output ?? 0) + (total ?? 0) === 0) return;\n\n const turn: TokenUsage = { ...this._lastTokens };\n const add = (key: keyof TokenUsage, value: number | undefined) => {\n if (value !== undefined) turn[key] = (turn[key] ?? 0) + value;\n };\n add(\"inputTokens\", input);\n add(\"outputTokens\", output);\n add(\"cacheReadTokens\", cacheRead);\n add(\"cacheCreationTokens\", cacheWrite);\n add(\"reasoningTokens\", reasoning);\n add(\"totalTokens\", total);\n this._lastTokens = turn;\n const cost = count(message.usage.cost?.total);\n if (cost !== undefined) this._lastTurnCostUsd += cost;\n // Provisional until `get_state` reports omp's own figure: that reply lands\n // after `agent_end`, and a compaction check can run before it.\n if (callContext > 0) this._lastContextTokens = callContext;\n }\n\n private nextId(): string {\n return `req-${++this.reqId}`;\n }\n\n /**\n * Send a command and await its `response` frame.\n *\n * @param options.quiet - Leave a failed response to the caller instead of\n * surfacing it as an `error` agent event.\n * @throws When the process is not running or no response arrives within\n * `options.timeoutMs` (default 5 s).\n */\n private request(\n msg: { type: string; [key: string]: unknown },\n options: { quiet?: boolean; timeoutMs?: number } = {},\n ): Promise<OmpEvent> {\n const id = this.nextId();\n const event = `response:${id}`;\n // Not `Promise.withResolvers`: the provider/connector packages that\n // typecheck this file target a lib older than es2024.\n let resolve!: (resp: OmpEvent) => void;\n let reject!: (err: Error) => void;\n const promise = new Promise<OmpEvent>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n const onResponse = (resp: OmpEvent) => {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n resolve(resp);\n };\n // A timed-out quiet request keeps its id: omp may still answer late (with a\n // failure), and that answer must stay as quiet as an in-time one. The id is\n // dropped when the response is handled or the process ends (`cleanup()`).\n const fail = (err: Error, keepQuiet = false) => {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n this.removeListener(event, onResponse);\n if (!keepQuiet) this.quietRequestIds.delete(id);\n reject(err);\n };\n const timer = setTimeout(\n () => fail(new Error(`${msg.type} timeout`), true),\n options.timeoutMs ?? 5000,\n );\n this.once(event, onResponse);\n this.pendingRequests.set(id, fail);\n if (options.quiet) this.quietRequestIds.add(id);\n try {\n this.send({ id, ...msg });\n } catch (err) {\n fail(err as Error);\n }\n return promise;\n }\n\n private send(msg: object): void {\n if (!this.proc?.stdin?.writable) {\n const detail: AgentError = {\n message: \"omp process not running\",\n category: \"process\",\n retryable: true,\n hint: \"The agent process is not available. It will restart automatically on the next prompt.\",\n };\n const err = Object.assign(new Error(detail.message), { detail });\n throw err;\n }\n this.proc.stdin.write(`${JSON.stringify(msg)}\\n`);\n }\n\n /**\n * Sends a prompt to the omp process via JSON-RPC and resolves when the turn\n * completes (after the `agent_end` event), honoring the `AgentHarness.prompt`\n * contract so harness-agnostic callers can await turn completion uniformly.\n *\n * The harness emits `agent-event` payloads as omp streams responses on stdout.\n * If the child process errors or exits before `agent_end`, the returned promise\n * rejects rather than hanging.\n *\n * @param message - Plain-text user prompt.\n * @throws {Error} When the omp process is not running, its stdin is closed, or\n * the child crashes/exits before the turn completes.\n */\n public prompt(message: string): Promise<void> {\n return this.enqueuePrompt(() => this.runPrompt({ message }));\n }\n\n /**\n * Run one prompt after every earlier one settled. A question omp is parked on\n * is cancelled first, synchronously and ahead of the queue: the parked turn\n * can only finish once its `ask` is released, so the new prompt (the user\n * typing instead of answering) must not wait behind it. The runner queues chat\n * prompts too; this queue still covers callers that drive the harness directly.\n */\n private enqueuePrompt(run: () => Promise<void>): Promise<void> {\n this.cancelPendingQuestion();\n const queued = this.promptTail.then(run);\n this.promptTail = queued.then(\n () => undefined,\n () => undefined,\n );\n return queued;\n }\n\n /**\n * Structured prompt: text plus image/file/skill attachments. Images travel as\n * omp `ImageContent` (`prompt.images`, base64 + mimeType); file and skill\n * attachments are named in a text preamble, because omp reads files itself.\n * Turn settlement is shared with {@link prompt}.\n */\n public override promptInput(input: AgentPromptInput): Promise<void> {\n if (input.toolAllowlist !== undefined)\n return Promise.reject(new Error(TOOL_ALLOWLIST_UNSUPPORTED));\n return this.enqueuePrompt(async () => this.runPrompt(await this.buildPromptPayload(input)));\n }\n\n /** Resolve attachments into the `message` + `images` fields of an omp `prompt` frame. */\n private async buildPromptPayload(\n input: AgentPromptInput,\n ): Promise<{ message: string; images?: OmpImageContent[] }> {\n const attachments = input.attachments ?? [];\n if (attachments.length === 0) return { message: input.text };\n const mimeByExt: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n };\n const images: OmpImageContent[] = [];\n const preamble: string[] = [];\n let root: string | undefined;\n for (const attachment of attachments) {\n if (attachment.type !== \"image\") {\n preamble.push(`[Attached ${attachment.type}: ${attachment.name} (${attachment.path})]`);\n continue;\n }\n // Image bytes are read here, so the path must stay inside the workspace.\n root ??= await fs.realpath(this.config.cwd);\n const resolved = await fs.realpath(path.resolve(root, attachment.path));\n const rel = path.relative(root, resolved);\n const escapes = rel === \"..\" || rel.startsWith(`..${path.sep}`);\n if (rel === \"\" || escapes || path.isAbsolute(rel)) {\n throw new Error(`Image attachment is outside the workspace: ${attachment.path}`);\n }\n const mimeType = mimeByExt[path.extname(resolved).toLowerCase()];\n if (!mimeType) {\n throw new Error(`Unsupported image type for attachment: ${attachment.path}`);\n }\n // Anthropic rejects images over 5 MB; fail before reading the bytes.\n const { size } = await fs.stat(resolved);\n if (size > OMP_MAX_IMAGE_BYTES) {\n throw new Error(`Image attachment too large (${size} bytes > 5 MB): ${attachment.path}`);\n }\n images.push({\n type: \"image\",\n data: (await fs.readFile(resolved)).toString(\"base64\"),\n mimeType,\n });\n }\n const message = preamble.length ? `${preamble.join(\"\\n\")}\\n\\n${input.text}` : input.text;\n return { message, ...(images.length ? { images } : {}) };\n }\n\n /**\n * Send one `prompt` frame and resolve when the turn completes (`agent_end`).\n * Rejects if the child dies first.\n */\n private async runPrompt(payload: { message: string; images?: OmpImageContent[] }): Promise<void> {\n this.promptRetried = false;\n const epoch = this.killEpoch;\n for (;;) {\n await this.start();\n if (this.killEpoch !== epoch) {\n // A kill() or dispose() landed while omp was restarting: the new process must not live.\n this.kill();\n throw new Error(\"omp process killed\");\n }\n // A reconfigure that landed mid-turn or before `ready` applies now.\n await this.reconfig.flushBeforeTurn();\n const id = this.nextId();\n\n // Install the per-turn resolver BEFORE sending: omp can stream a fast\n // `agent_end` on the next readline tick, and if the resolver isn't wired\n // yet that event would be missed and prompt() would hang forever.\n const turnPromise = new Promise<void>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n });\n\n this.turnOutputSeen = false;\n this.turnUserMessageSeen = false;\n this.beginUsageTurn();\n try {\n this.send({ id, type: \"prompt\", ...payload });\n } catch (err) {\n this.turnResolve = null;\n this.turnReject = null;\n throw err;\n }\n\n try {\n await turnPromise;\n return;\n } catch (err) {\n // omp exited before it produced anything: nothing of this turn was seen, so the same\n // prompt goes to a fresh process once. The exit handler held the error back for this.\n if (!(err instanceof EarlyOmpExit)) throw err;\n this.promptRetried = true;\n this.log.warn(\"omp exited before its first output; sending the prompt again\", {\n code: err.code,\n signal: err.signal,\n });\n }\n }\n }\n\n /**\n * Sends an in-band abort RPC to the omp process, requesting it to stop the\n * current turn without terminating the child process.\n *\n * @remarks This is a best-effort signal — omp may not honour the abort\n * immediately. The process remains alive after `abort()`.\n */\n public async abort(): Promise<void> {\n if (!this.proc) return;\n const id = this.nextId();\n this.send({ id, type: \"abort\" });\n // The dialog's tool call is aborted with the turn; release what it owed.\n this.cancelPendingQuestion();\n }\n\n /** `true` when the omp child process is alive and has not been killed. */\n public get isRunning(): boolean {\n return this.proc !== null && !this.proc.killed;\n }\n\n /**\n * Sends SIGTERM to the omp child process and performs cleanup.\n *\n * The harness instance must not be reused after `kill()`. Create a new\n * `OmpHarness` to start a fresh session.\n */\n kill(): void {\n this.killEpoch++;\n const proc = this.proc;\n if (!proc) return;\n // Settle this process's in-flight turn here: its late `exit` is ignored (the\n // process is superseded by then) and must not reach a successor's turn.\n if (this.turnEnded) this.resolveTurn();\n else this.rejectTurn(new Error(\"omp process killed\"));\n proc.kill(\"SIGTERM\");\n // omp is still shutting down and writes into its home (the `intercom` directory) while\n // the cleanup below deletes it, so a home deleted only now can reappear: delete it again\n // once the process is gone.\n const home = this.privateHome;\n this.homeGone = home ? removeHomeAfterExit(proc, home) : Promise.resolve();\n this.cleanup();\n }\n\n /** Stop omp and wait until the process has exited and its private home is deleted. */\n override async dispose(): Promise<void> {\n this.kill();\n await this.homeGone;\n }\n\n async resetSession(): Promise<void> {\n this.kill();\n // Otherwise the respawn passes `--session` and reopens the pre-reset session.\n this.config = { ...this.config, resumeSessionId: undefined };\n this._lastTokens = null;\n this._lastContextTokens = null;\n this._lastTurnCostUsd = 0;\n this._contextWindow = null;\n await this.start();\n }\n\n private classifyProcessError(err: NodeJS.ErrnoException): AgentError {\n if (err.code === \"ENOENT\") {\n return {\n message: \"omp command not found\",\n category: \"config\",\n retryable: false,\n hint: HARNESS_BINARIES.omp.hint,\n };\n }\n if (err.code === \"EACCES\") {\n return {\n message: \"Permission denied running omp\",\n category: \"config\",\n retryable: false,\n hint: \"Check file permissions for the omp binary.\",\n };\n }\n return {\n message: err.message,\n category: \"process\",\n retryable: true,\n hint: \"An unexpected process error occurred. Try sending your prompt again.\",\n };\n }\n\n private classifyErrorMessage(rawMsg: string): AgentError {\n const msg = ompCredentialMessage(rawMsg);\n // Shared keyword buckets live in error-classifier.ts; only the hint copy is omp-specific.\n const generic = classifyGenericErrorMessage(msg);\n if (!generic) return { message: msg, category: \"unknown\", retryable: true };\n\n const lower = msg.toLowerCase();\n // The rewritten no-login message already names the command to run (p1912): a second line\n // pointing at a `Settings` screen the CLI does not have only misleads.\n const namesCommand = msg !== rawMsg && msg.includes(\"`skaile providers add\");\n const hint =\n generic.category === \"auth\"\n ? namesCommand\n ? undefined\n : \"Check the provider's key with `skaile providers test <id>`.\"\n : generic.category === \"rate_limit\"\n ? \"You have hit the provider rate limit. Wait a moment and try again.\"\n : generic.category === \"network\"\n ? \"A network error occurred. Check your connection and try again.\"\n : // model: distinguish unavailable-model from over-long-context.\n lower.includes(\"model\")\n ? \"The selected model is not available. Pick another with --model.\"\n : \"The conversation is too long. Start a new session or choose a model with a larger context window.\";\n return {\n message: msg,\n category: generic.category,\n retryable: generic.retryable,\n ...(hint ? { hint } : {}),\n };\n }\n\n /**\n * The models this session can select.\n *\n * Answered entirely from the registry: the ids are exactly the\n * `<providerId>/<modelId>` selectors rendered into `models.yml`, so a\n * picker offers every enabled endpoint instead of whichever one the\n * ambient binary happens to be authenticated for. A registry whose\n * entries name no models yields no entries here — that gap is closed by\n * giving the entry a `discovery:` block (`PROVIDER-CONFIG-PLAN.md` §1.1),\n * not by asking the omp binary what it happens to know. omp's own catalog\n * (`omp models --json`) answers a different question — every model omp\n * knows across every provider, regardless of what this session's registry\n * enables or has credentials for — and shelling out to an ambient binary\n * from this code path is itself a liability: it can block indefinitely\n * reading a prompt from stdin when run inside another interactive session.\n */\n override async listModels(): Promise<ModelEntry[]> {\n return registryModelEntries(this.config.registry);\n }\n\n /** Delete the system prompt file of the process that is gone (or about to be replaced). */\n private removeSystemPromptFile(): void {\n const file = this.systemPromptFile;\n this.systemPromptFile = null;\n if (file) rmSync(file, { force: true });\n }\n\n /**\n * Delete the private omp home of the process that is gone: it holds symlinks to the login\n * and the agent files and omp's runtime databases, and nothing reads it afterwards (p811).\n */\n private removePrivateHome(): void {\n const home = this.privateHome;\n this.privateHome = null;\n if (home) rmSync(home, { recursive: true, force: true });\n }\n\n private cleanup(): void {\n this.removeSystemPromptFile();\n this.removePrivateHome();\n this.rl?.close();\n this.rl = null;\n this.proc = null;\n this.ready = false;\n this.reconfig.setSnapshot(null);\n this.startPromise = null;\n this.stderrBuffer = [];\n // A respawn re-subscribes and re-registers the host tools from scratch.\n this.unsubscribeToolsChanged?.();\n this.unsubscribeToolsChanged = null;\n this.hostToolCapabilities = new Map();\n // Nothing can receive these results any more; stop the handlers and close\n // their chat activity (the handlers' later settlement is ignored).\n for (const id of [...this.hostToolCalls.keys()]) this.abortHostToolCall(id);\n // No response can arrive any more: fail the waiters now instead of at their timeout.\n for (const fail of [...this.pendingRequests.values()]) fail(new Error(\"omp process ended\"));\n this.pendingRequests.clear();\n this.quietRequestIds.clear();\n // The process that asked is gone; there is nobody to answer to.\n this.pendingQuestion = null;\n }\n}\n\n/**\n * `HarnessTarget` wrapper for the omp harness. Registered into the plugin\n * registry by `registerBuiltinHarnesses()`.\n */\nexport const ompHarnessTarget: HarnessTarget<AgentConfig> = {\n id: \"omp\",\n displayName: BUILTIN_HARNESS_CATALOG.omp?.name ?? \"omp (oh-my-pi)\",\n apiVersion: 1,\n // Harnesses take AgentConfig; passthrough — full schema validation is out of scope.\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new OmpHarness(config),\n listModels: async (registry, options) =>\n new OmpHarness({\n cwd: process.cwd(),\n sessionId: \"model-list\",\n ...registryHarnessConfig(registry, options),\n }).listModels(),\n};\n"]}
|