@ken-jo/agent-connector 0.4.44 → 0.4.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/dist/{action-72J2TCKQ.js → action-RUM6GP23.js} +12 -12
- package/dist/{amazon-q-UFLBUSHG.js → amazon-q-KXVJFT7Q.js} +7 -11
- package/dist/amazon-q-KXVJFT7Q.js.map +1 -0
- package/dist/{amp-5DJK7VAL.js → amp-WAPHJYTK.js} +38 -63
- package/dist/amp-WAPHJYTK.js.map +1 -0
- package/dist/{antigravity-NWP2TUG6.js → antigravity-GF3RU42A.js} +5 -5
- package/dist/{antigravity-cli-KPNLE7X4.js → antigravity-cli-OH27IFH5.js} +5 -5
- package/dist/{chunk-QY42WGBX.js → chunk-2HCJV6UO.js} +33 -3
- package/dist/chunk-2HCJV6UO.js.map +1 -0
- package/dist/{chunk-ERV4TKRV.js → chunk-3Y23ZYYF.js} +10 -10
- package/dist/chunk-3Y23ZYYF.js.map +1 -0
- package/dist/{chunk-L7ESV37V.js → chunk-7CZKXXBD.js} +4 -2
- package/dist/chunk-7CZKXXBD.js.map +1 -0
- package/dist/{chunk-ZY25RG4Y.js → chunk-ALVXORZM.js} +4 -2
- package/dist/chunk-ALVXORZM.js.map +1 -0
- package/dist/{chunk-M3H7PQWT.js → chunk-AXAHW2KU.js} +4 -2
- package/dist/chunk-AXAHW2KU.js.map +1 -0
- package/dist/{chunk-CFM3JKIR.js → chunk-CSRBMJLU.js} +7 -7
- package/dist/{chunk-F4DSMVZ7.js → chunk-D6ZJS4ND.js} +2 -2
- package/dist/{chunk-B47MDOV3.js → chunk-E45SUUD7.js} +5 -5
- package/dist/{chunk-3Q6YEDCG.js → chunk-F5COBB5F.js} +17 -45
- package/dist/chunk-F5COBB5F.js.map +1 -0
- package/dist/{chunk-5M2SMDA4.js → chunk-GCRRX4MO.js} +2 -2
- package/dist/{chunk-2RPHDVHW.js → chunk-IU42THN7.js} +2 -2
- package/dist/{chunk-VPSHGDDQ.js → chunk-IZ4XQ23W.js} +26 -10
- package/dist/chunk-IZ4XQ23W.js.map +1 -0
- package/dist/{chunk-SBV2QJ5C.js → chunk-LS65GL2P.js} +36 -36
- package/dist/{chunk-IKEXNI2W.js → chunk-NXR4HM5N.js} +18 -18
- package/dist/{chunk-ASHAMORS.js → chunk-P5KA5NVR.js} +2 -2
- package/dist/{chunk-A767JFHW.js → chunk-RHML2NOB.js} +65 -35
- package/dist/chunk-RHML2NOB.js.map +1 -0
- package/dist/{chunk-UXG64P6R.js → chunk-RQCBBLTA.js} +7 -4
- package/dist/chunk-RQCBBLTA.js.map +1 -0
- package/dist/{chunk-LETB5HCK.js → chunk-TZ5KGCE2.js} +2 -2
- package/dist/{chunk-WZWK4ICE.js → chunk-UVBAH263.js} +10 -7
- package/dist/chunk-UVBAH263.js.map +1 -0
- package/dist/{chunk-E3GWKJU5.js → chunk-ZEFUDBTY.js} +5 -5
- package/dist/{chunk-XW46WVR2.js → chunk-ZSMGHEB5.js} +10 -5
- package/dist/chunk-ZSMGHEB5.js.map +1 -0
- package/dist/{claude-code-HXIVRZCY.js → claude-code-WLN43K7I.js} +15 -8
- package/dist/claude-code-WLN43K7I.js.map +1 -0
- package/dist/cli/sdk.js +7 -7
- package/dist/cli.js +1 -1
- package/dist/{cline-AGFJF4AC.js → cline-PEGTGVQD.js} +4 -4
- package/dist/{codebuff-YUQ4PN7G.js → codebuff-UG6LVSOM.js} +4 -4
- package/dist/{codex-FLU37DV3.js → codex-4LVDQXCD.js} +32 -6
- package/dist/codex-4LVDQXCD.js.map +1 -0
- package/dist/{continue-ZMI4YN75.js → continue-DYV5V55Y.js} +9 -5
- package/dist/continue-DYV5V55Y.js.map +1 -0
- package/dist/{copilot-cli-XPRJ5MQB.js → copilot-cli-NVFXFLUF.js} +66 -51
- package/dist/copilot-cli-NVFXFLUF.js.map +1 -0
- package/dist/{crush-3OB5ZTCC.js → crush-PP4HYZLT.js} +4 -4
- package/dist/{cursor-F4HYO2FP.js → cursor-XMXOZKAP.js} +5 -5
- package/dist/{detect-L3NJTBO5.js → detect-IZOWP5AA.js} +4 -4
- package/dist/{doctor-PUE4HO3N.js → doctor-5IVUQ2YH.js} +14 -14
- package/dist/{droid-NZCKYKOV.js → droid-ETNOUIPJ.js} +6 -12
- package/dist/droid-ETNOUIPJ.js.map +1 -0
- package/dist/{gemini-cli-3ZGCXUDD.js → gemini-cli-P7XJXWVH.js} +19 -6
- package/dist/gemini-cli-P7XJXWVH.js.map +1 -0
- package/dist/{goose-MGGNVXJP.js → goose-UZVA6MQC.js} +16 -22
- package/dist/goose-UZVA6MQC.js.map +1 -0
- package/dist/{hermes-L3CBJ37L.js → hermes-IC6R4CII.js} +44 -22
- package/dist/hermes-IC6R4CII.js.map +1 -0
- package/dist/{hook-S3DNNGZX.js → hook-7IUPIHCZ.js} +12 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/{install-7SUJFRYO.js → install-EP6GPQ65.js} +14 -14
- package/dist/{introspect-B164-hj3.d.ts → introspect-BFcXpfUp.d.ts} +1 -1
- package/dist/{jetbrains-copilot-M2LHJBAW.js → jetbrains-copilot-MZO2RQGJ.js} +19 -15
- package/dist/jetbrains-copilot-MZO2RQGJ.js.map +1 -0
- package/dist/{kilo-RMRP2EL7.js → kilo-CCB34CQQ.js} +18 -55
- package/dist/kilo-CCB34CQQ.js.map +1 -0
- package/dist/{kilo-cli-6ITBNHTH.js → kilo-cli-EOMN3WC7.js} +18 -55
- package/dist/kilo-cli-EOMN3WC7.js.map +1 -0
- package/dist/{kimi-QYHWAY54.js → kimi-GUSJME55.js} +8 -4
- package/dist/kimi-GUSJME55.js.map +1 -0
- package/dist/{kiro-2K5UJVGC.js → kiro-6OHZ5RGV.js} +5 -5
- package/dist/kiro-6OHZ5RGV.js.map +1 -0
- package/dist/{leaderboard-2VAAOK3D.js → leaderboard-6I2E5XZK.js} +5 -5
- package/dist/{mimo-code-K7AMX2QW.js → mimo-code-ZPJJ6IIW.js} +21 -56
- package/dist/mimo-code-ZPJJ6IIW.js.map +1 -0
- package/dist/{mux-GT7FWVLH.js → mux-AFTVMGGM.js} +4 -4
- package/dist/{nemoclaw-GQMS6CUM.js → nemoclaw-D5EN4G2Q.js} +5 -5
- package/dist/{omp-2RPYIZUF.js → omp-GKI2PZ7G.js} +17 -46
- package/dist/omp-GKI2PZ7G.js.map +1 -0
- package/dist/{openclaw-P5GMEEGC.js → openclaw-A76PCNBV.js} +5 -5
- package/dist/{opencode-5D2SK3EX.js → opencode-M34E6PI7.js} +21 -56
- package/dist/opencode-M34E6PI7.js.map +1 -0
- package/dist/{package-VUX663ET.js → package-BWLV24OO.js} +11 -11
- package/dist/{pi-ZMM4KJTO.js → pi-HVG6ZWFE.js} +4 -4
- package/dist/{qwen-code-4ZLVGN2C.js → qwen-code-OWLM3I5P.js} +12 -5
- package/dist/qwen-code-OWLM3I5P.js.map +1 -0
- package/dist/{roo-code-67QGLQRM.js → roo-code-RFKKTNNI.js} +4 -4
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +10 -10
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.js +6 -6
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +9 -9
- package/dist/{serve-MOIIYFER.js → serve-CM4HZPMP.js} +12 -12
- package/dist/{status-SCBCWS7H.js → status-BPB4VLQX.js} +10 -10
- package/dist/{statusline-NRPDOPGA.js → statusline-HIKR2I4Q.js} +11 -11
- package/dist/{telemetry-Q55B5NSZ.js → telemetry-SBVUJYNE.js} +10 -10
- package/dist/{trae-TMJPHWZ5.js → trae-FVHQALK3.js} +4 -4
- package/dist/{types-COSBYpKs.d.ts → types-ChUrvw0j.d.ts} +8 -8
- package/dist/{uninstall-SNI7GPQD.js → uninstall-MO3RGGVE.js} +21 -14
- package/dist/uninstall-MO3RGGVE.js.map +1 -0
- package/dist/{upgrade-ZUNBJWJ7.js → upgrade-6XIGSPGY.js} +14 -14
- package/dist/{usage-UQDBIU42.js → usage-IBN36ZVW.js} +2 -2
- package/dist/{usage-event-HPG2BIAY.js → usage-event-4RJP37K6.js} +11 -11
- package/dist/{vscode-copilot-H7JKUKLZ.js → vscode-copilot-6FLDRTKV.js} +26 -19
- package/dist/vscode-copilot-6FLDRTKV.js.map +1 -0
- package/dist/{warp-SVDVKQQI.js → warp-7CC52UJV.js} +4 -4
- package/dist/{windsurf-H36YKOMR.js → windsurf-6ZLQMBQW.js} +4 -4
- package/dist/{zed-LHWJALLZ.js → zed-FULJMNBV.js} +4 -4
- package/package.json +2 -1
- package/dist/amazon-q-UFLBUSHG.js.map +0 -1
- package/dist/amp-5DJK7VAL.js.map +0 -1
- package/dist/chunk-3Q6YEDCG.js.map +0 -1
- package/dist/chunk-A767JFHW.js.map +0 -1
- package/dist/chunk-ERV4TKRV.js.map +0 -1
- package/dist/chunk-L7ESV37V.js.map +0 -1
- package/dist/chunk-M3H7PQWT.js.map +0 -1
- package/dist/chunk-QY42WGBX.js.map +0 -1
- package/dist/chunk-UXG64P6R.js.map +0 -1
- package/dist/chunk-VPSHGDDQ.js.map +0 -1
- package/dist/chunk-WZWK4ICE.js.map +0 -1
- package/dist/chunk-XW46WVR2.js.map +0 -1
- package/dist/chunk-ZY25RG4Y.js.map +0 -1
- package/dist/claude-code-HXIVRZCY.js.map +0 -1
- package/dist/codex-FLU37DV3.js.map +0 -1
- package/dist/continue-ZMI4YN75.js.map +0 -1
- package/dist/copilot-cli-XPRJ5MQB.js.map +0 -1
- package/dist/droid-NZCKYKOV.js.map +0 -1
- package/dist/gemini-cli-3ZGCXUDD.js.map +0 -1
- package/dist/goose-MGGNVXJP.js.map +0 -1
- package/dist/hermes-L3CBJ37L.js.map +0 -1
- package/dist/jetbrains-copilot-M2LHJBAW.js.map +0 -1
- package/dist/kilo-RMRP2EL7.js.map +0 -1
- package/dist/kilo-cli-6ITBNHTH.js.map +0 -1
- package/dist/kimi-QYHWAY54.js.map +0 -1
- package/dist/kiro-2K5UJVGC.js.map +0 -1
- package/dist/mimo-code-K7AMX2QW.js.map +0 -1
- package/dist/omp-2RPYIZUF.js.map +0 -1
- package/dist/opencode-5D2SK3EX.js.map +0 -1
- package/dist/qwen-code-4ZLVGN2C.js.map +0 -1
- package/dist/uninstall-SNI7GPQD.js.map +0 -1
- package/dist/vscode-copilot-H7JKUKLZ.js.map +0 -1
- /package/dist/{action-72J2TCKQ.js.map → action-RUM6GP23.js.map} +0 -0
- /package/dist/{antigravity-NWP2TUG6.js.map → antigravity-GF3RU42A.js.map} +0 -0
- /package/dist/{antigravity-cli-KPNLE7X4.js.map → antigravity-cli-OH27IFH5.js.map} +0 -0
- /package/dist/{chunk-CFM3JKIR.js.map → chunk-CSRBMJLU.js.map} +0 -0
- /package/dist/{chunk-F4DSMVZ7.js.map → chunk-D6ZJS4ND.js.map} +0 -0
- /package/dist/{chunk-B47MDOV3.js.map → chunk-E45SUUD7.js.map} +0 -0
- /package/dist/{chunk-5M2SMDA4.js.map → chunk-GCRRX4MO.js.map} +0 -0
- /package/dist/{chunk-2RPHDVHW.js.map → chunk-IU42THN7.js.map} +0 -0
- /package/dist/{chunk-SBV2QJ5C.js.map → chunk-LS65GL2P.js.map} +0 -0
- /package/dist/{chunk-IKEXNI2W.js.map → chunk-NXR4HM5N.js.map} +0 -0
- /package/dist/{chunk-ASHAMORS.js.map → chunk-P5KA5NVR.js.map} +0 -0
- /package/dist/{chunk-LETB5HCK.js.map → chunk-TZ5KGCE2.js.map} +0 -0
- /package/dist/{chunk-E3GWKJU5.js.map → chunk-ZEFUDBTY.js.map} +0 -0
- /package/dist/{cline-AGFJF4AC.js.map → cline-PEGTGVQD.js.map} +0 -0
- /package/dist/{codebuff-YUQ4PN7G.js.map → codebuff-UG6LVSOM.js.map} +0 -0
- /package/dist/{crush-3OB5ZTCC.js.map → crush-PP4HYZLT.js.map} +0 -0
- /package/dist/{cursor-F4HYO2FP.js.map → cursor-XMXOZKAP.js.map} +0 -0
- /package/dist/{detect-L3NJTBO5.js.map → detect-IZOWP5AA.js.map} +0 -0
- /package/dist/{doctor-PUE4HO3N.js.map → doctor-5IVUQ2YH.js.map} +0 -0
- /package/dist/{hook-S3DNNGZX.js.map → hook-7IUPIHCZ.js.map} +0 -0
- /package/dist/{install-7SUJFRYO.js.map → install-EP6GPQ65.js.map} +0 -0
- /package/dist/{leaderboard-2VAAOK3D.js.map → leaderboard-6I2E5XZK.js.map} +0 -0
- /package/dist/{mux-GT7FWVLH.js.map → mux-AFTVMGGM.js.map} +0 -0
- /package/dist/{nemoclaw-GQMS6CUM.js.map → nemoclaw-D5EN4G2Q.js.map} +0 -0
- /package/dist/{openclaw-P5GMEEGC.js.map → openclaw-A76PCNBV.js.map} +0 -0
- /package/dist/{package-VUX663ET.js.map → package-BWLV24OO.js.map} +0 -0
- /package/dist/{pi-ZMM4KJTO.js.map → pi-HVG6ZWFE.js.map} +0 -0
- /package/dist/{roo-code-67QGLQRM.js.map → roo-code-RFKKTNNI.js.map} +0 -0
- /package/dist/{serve-MOIIYFER.js.map → serve-CM4HZPMP.js.map} +0 -0
- /package/dist/{status-SCBCWS7H.js.map → status-BPB4VLQX.js.map} +0 -0
- /package/dist/{statusline-NRPDOPGA.js.map → statusline-HIKR2I4Q.js.map} +0 -0
- /package/dist/{telemetry-Q55B5NSZ.js.map → telemetry-SBVUJYNE.js.map} +0 -0
- /package/dist/{trae-TMJPHWZ5.js.map → trae-FVHQALK3.js.map} +0 -0
- /package/dist/{upgrade-ZUNBJWJ7.js.map → upgrade-6XIGSPGY.js.map} +0 -0
- /package/dist/{usage-UQDBIU42.js.map → usage-IBN36ZVW.js.map} +0 -0
- /package/dist/{usage-event-HPG2BIAY.js.map → usage-event-4RJP37K6.js.map} +0 -0
- /package/dist/{warp-SVDVKQQI.js.map → warp-7CC52UJV.js.map} +0 -0
- /package/dist/{windsurf-H36YKOMR.js.map → windsurf-6ZLQMBQW.js.map} +0 -0
- /package/dist/{zed-LHWJALLZ.js.map → zed-FULJMNBV.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/mimo-code/index.ts"],"sourcesContent":["/**\n * adapters/mimo-code — Xiaomi MiMoCode platform adapter for agent-connector.\n *\n * MiMoCode (github.com/XiaomiMiMo/MiMo-Code, MIT) is Xiaomi's open-source\n * terminal AI coding agent — a FORK OF OpenCode (anomalyco/opencode) that adds\n * cross-session memory, checkpoints, subagents, etc. Official npm `@mimo-ai/cli`\n * (bin: `mimo`). NOTE: `@xiaomi-mimo/cli` is an UNOFFICIAL squatter (GPL) — not\n * referenced here; the bin is `mimo`, NOT `mimo-code`.\n *\n * DESIGN — STANDALONE (mirrors OpenCode's render logic with mimocode paths),\n * NOT `extends OpenCodeAdapter`. The OpenCode adapter binds the host string in\n * several places that a subclass cannot cleanly override:\n * - a module-level `const HOST = \"opencode\"` used for the per-platform server/\n * hooks override lookup (`ctx.connector.platforms[HOST]`) and stamped as\n * `hostPlatform` on every parsed event — extending would read\n * `platforms[\"opencode\"]` overrides and mis-stamp events as opencode;\n * - the PRIVATE `buildPluginSource` hardcodes `[\"hook\", \"opencode\", event, …]`\n * in the GENERATED bridge, so an inherited plugin would dispatch the runtime\n * hook to the opencode adapter (`hook opencode`) instead of mimo-code;\n * - the config/plugin/content directory builders hardcode \"opencode\" /\n * \".opencode\" / \"opencode.json\".\n * Overriding all of that means re-implementing the private render core anyway,\n * so this adapter mirrors OpenCode's logic with a `HOST = \"mimo-code\"` constant\n * and the mimocode paths — a clean standalone that routes detection, the runtime\n * bridge, and per-platform overrides to its own id.\n *\n * MiMoCode IS OpenCode's config dialect, so the render shapes are IDENTICAL:\n * - config file `mimocode.json`\n * user scope → ~/.config/mimocode/mimocode.json\n * project scope → <projectDir>/mimocode.json\n * (the dir is `.mimocode` / `~/.config/mimocode` — NO hyphen; the committed\n * example is `.mimocode/mimocode.jsonc`).\n * - MCP root key \"mcp\" (the OpenCode shape, NOT \"mcpServers\"); each server\n * keyed by name; stdio → { type:\"local\", command:[exe,…args], environment },\n * remote → { type:\"remote\", url }.\n * - ts-plugin hooks: a self-contained ESM bridge module auto-loaded from the\n * user scope → ~/.config/mimocode/plugin/<id>.js\n * project scope → <projectDir>/.mimocode/plugin/<id>.js\n * plugin dir (writing the file IS the registration; no config array edit).\n * - content surfaces under <mcDir>/{commands,skills,agent} (singular `agent/`,\n * matching OpenCode).\n *\n * Event mapping (OpenCode's, unchanged):\n * PreToolUse → \"tool.execute.before\" (mutate output.args; throw to deny)\n * PostToolUse → \"tool.execute.after\" (mutate output.output)\n * SessionStart → \"experimental.chat.system.transform\" (inject into output.system)\n *\n * SOURCES: github.com/XiaomiMiMo/MiMo-Code (README, .mimocode/mimocode.jsonc,\n * packages/opencode/src/config/{config.ts,mcp.ts,plugin.ts}). npm @mimo-ai/cli.\n * mimo.xiaomi.com/en/mimocode.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type {\n Adapter,\n GeneratedPluginFile,\n HookReply,\n InstallContext,\n MemoryTarget,\n NormalizedEvent,\n} from \"../spi.js\";\nimport type {\n ChangeRecord,\n CommandDef,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PreToolUseEvent,\n ServerDef,\n SessionStartEvent,\n StopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { renderBridgePrelude } from \"../../core/ts-plugin-bridge.js\";\nimport {\n buildWrappedStdio,\n} from \"../../core/spawn.js\";\nimport { renderOpenCodeSubagentMd, renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"mimo-code\";\nconst MCP_ROOT_KEY = \"mcp\";\n\n/** The config dir name (NO hyphen): `.mimocode` / `~/.config/mimocode`. */\nconst CONFIG_DIR_NAME = \"mimocode\";\n/** The config file name: `mimocode.json`. */\nconst CONFIG_FILE_NAME = \"mimocode.json\";\n\n/**\n * Canonical → MiMoCode (OpenCode-shaped) event name map. A connector hook event\n * is only emitted by the generated plugin when it appears here AND is declared\n * by the connector.\n */\nconst EVENT_TO_MIMOCODE: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n // No real SessionStart hook (inherited from OpenCode #14808 / #5409). The\n // verified surrogate is experimental.chat.system.transform.\n SessionStart: \"experimental.chat.system.transform\",\n // chat.message fires on the user's prompt submission; the handler mutates\n // output (pushes a text part) to inject context. No documented block/abort.\n UserPromptSubmit: \"chat.message\",\n // session.idle (\"session finished responding\") → canonical Stop. NOT a direct\n // hook key — dispatched through the generic `event` hook (event.type switch).\n // session.idle is the OpenCode-family session-completion event (mirrors kilo /\n // kilo-cli); if it never fires on a given MiMoCode build, Stop is a silent\n // no-op (an acceptable degrade — it never mis-fires), so coverage may be\n // optimistic.\n Stop: \"session.idle\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface MiMoCodeBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n prompt?: string;\n sessionId?: string;\n projectDir?: string;\n}\n\n/** Native MCP server entry shapes MiMoCode accepts under the \"mcp\" key. */\ninterface MiMoCodeLocalServer {\n type: \"local\";\n command: string[];\n environment?: Record<string, string>;\n enabled?: boolean;\n}\ninterface MiMoCodeRemoteServer {\n type: \"remote\";\n url: string;\n enabled?: boolean;\n}\n\nexport class MiMoCodeAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"MiMoCode\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block (CLAUDE.md fallback, like\n // OpenCode — MiMoCode keeps OpenCode's CLAUDE.md import + AGENTS.md reading).\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n preCompact: false,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: true,\n // session.idle (via the generic `event` hook) backs Stop (mirrors kilo /\n // kilo-cli — same OpenCode-family ts-plugin layer).\n stop: true,\n notification: false,\n // tool.execute.before mutates output.args → input rewrite supported.\n canModifyArgs: true,\n // tool.execute.after mutates output.output → output rewrite supported.\n canModifyOutput: true,\n // injected via experimental.chat.system.transform at session start.\n canInjectSessionContext: true,\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: MiMoCode authors all three natively under <mcDir>\n // (inherited from OpenCode's commands/skills/agent layout).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ──────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userConfigDir = join(homedir(), \".config\", CONFIG_DIR_NAME);\n const userConfig = join(userConfigDir, CONFIG_FILE_NAME);\n const projectConfig = join(projectDir, CONFIG_FILE_NAME);\n\n const userInstalled = existsSync(userConfigDir) || existsSync(userConfig);\n const projInstalled = existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n\n // Report the marker that actually matched so a project-only install isn't\n // misreported as a (non-existent) user install.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectConfig : userConfig;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? scope === \"project\"\n ? `found project MiMoCode config at ${projectConfig}`\n : `found MiMoCode config under ${userConfigDir}`\n : `no MiMoCode config at ${userConfigDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Memory surface: AGENTS.md / CLAUDE.md-fallback probe (project) ──────\n // Mirrors OpenCode: project AGENTS.md, falling back to CLAUDE.md ONLY when no\n // AGENTS.md exists (creating AGENTS.md beside a relied-on CLAUDE.md would\n // shadow the user's rules). User scope stays on the BaseAdapter default.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"project\") {\n return super.memoryTargets(ctx);\n }\n const agentsMd = join(ctx.projectDir, \"AGENTS.md\");\n if (existsSync(agentsMd)) {\n return [{ path: agentsMd, reason: \"AGENTS.md (mimocode's primary project rules file)\" }];\n }\n const claudeMd = join(ctx.projectDir, \"CLAUDE.md\");\n if (existsSync(claudeMd)) {\n return [\n {\n path: claudeMd,\n reason:\n \"CLAUDE.md (mimocode's fallback rules file — creating AGENTS.md would shadow it)\",\n },\n ];\n }\n return [{ path: agentsMd, reason: \"AGENTS.md standard (created; no mimocode rules file yet)\" }];\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? ctx.projectDir\n : join(homedir(), \".config\", CONFIG_DIR_NAME);\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), CONFIG_FILE_NAME);\n }\n\n /**\n * For ts-plugin hosts the \"hook config path\" is the generated plugin FILE.\n * MiMoCode (like OpenCode) auto-loads every file in the plugin dir; writing\n * this file IS the registration.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.pluginDir(ctx), this.pluginFileName(ctx));\n }\n\n /** Plugin directory MiMoCode auto-loads modules from, per scope. */\n private pluginDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, `.${CONFIG_DIR_NAME}`, \"plugin\")\n : join(homedir(), \".config\", CONFIG_DIR_NAME, \"plugin\");\n }\n\n /** Plugin module file name (one per connector, kebab-case id). */\n private pluginFileName(ctx: InstallContext): string {\n return `${ctx.connector.id}.js`;\n }\n\n // ── MCP server install / uninstall ─────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const server = this.effectiveServer(ctx);\n const serverPath = this.getServerConfigPath(ctx);\n\n if (!server) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: serverPath,\n detail: ctx.connector.server\n ? \"server registration disabled for mimo-code\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const entry = this.renderServerEntry(ctx, server);\n return [\n this.upsertServerInJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n entry,\n ctx.dryRun,\n ),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n ctx.dryRun,\n ),\n ];\n }\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[HOST]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override && typeof override === \"object\" ? { ...base, ...override } : base;\n }\n\n /**\n * Render a normalized ServerDef into MiMoCode's native \"mcp\" entry (OpenCode\n * dialect).\n *\n * stdio → { type: \"local\", command: [exe, ...args], environment }\n * remote → { type: \"remote\", url }\n *\n * MiMoCode flattens command+args into a single ARRAY. When telemetry wrapping\n * applies, the wrapper's command+args (which already include the real command\n * tail after `--`) become the head of that array. No native interpolation\n * token → resolve every ${env:VAR} reference to a literal at install time.\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): MiMoCodeLocalServer | MiMoCodeRemoteServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n const commandArray = resolveEnvRefsDeep([command, ...args]).filter(\n (s) => s !== \"\",\n );\n const entry: MiMoCodeLocalServer = {\n type: \"local\",\n command: commandArray,\n };\n const environment = this.renderEnv(server.env);\n if (environment) entry.environment = environment;\n if (server.enabled === false) entry.enabled = false;\n return entry;\n }\n\n // sse / http / ws (any remote transport) — MiMoCode registers a URL.\n const entry: MiMoCodeRemoteServer = {\n type: \"remote\",\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n if (server.enabled === false) entry.enabled = false;\n return entry;\n }\n\n /** Render env values, resolving every ${env:VAR} reference to a literal. */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hook install / uninstall (ts-plugin) ───────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n\n if (ctx.connector.platforms[HOST]?.hooks === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"hooks disabled for mimo-code\",\n },\n ];\n }\n if (ctx.connector.hookEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"connector declares no hooks\",\n },\n ];\n }\n\n const files = this.synthesizePlugin(ctx);\n const changes: ChangeRecord[] = [];\n\n for (const file of files) {\n changes.push(\n this.writeManagedFile(\n file.path,\n file.contents,\n ctx.dryRun,\n `mimo-code plugin module (${this.hookDetail(ctx)})`,\n file.executable,\n ),\n );\n }\n\n return changes;\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module\n * ACTUALLY wires. Only events present in EVENT_TO_MIMOCODE are mapped/wired;\n * any declared event with no mapping is reported separately as \"unsupported\n * here\" so the detail never overstates coverage.\n */\n private hookDetail(ctx: InstallContext): string {\n const declared = ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_MIMOCODE[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_MIMOCODE[e] === undefined);\n const base = mapped.join(\",\");\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n return [\n this.removeManagedFile(\n pluginPath,\n ctx.dryRun,\n \"mimo-code plugin module\",\n \"no mimo-code plugin module present\",\n ),\n ];\n }\n\n // ── Content surfaces: commands / skills / subagents ──────────────────────\n // CONTENT-ONLY: pure native-file writers under <mcDir>/{commands,skills,\n // agent}. No runtime dispatch, no home-bin pointer, no telemetry wrap. Each\n // method is idempotent (byte-identical → skip) and reversible. Mirrors\n // OpenCode's layout: commands/<name>.md, skills/<name>/SKILL.md, and the\n // SINGULAR agent/<name>.md dir for subagents. For project scope the content\n // root is <projectDir>/.mimocode (NOT the project root where mimocode.json\n // lives).\n\n private contentRootDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, `.${CONFIG_DIR_NAME}`)\n : this.getConfigDir(ctx);\n }\n private commandsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"commands\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"skills\");\n }\n private agentDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"agent\");\n }\n\n /** Native command file path: <mcDir>/commands/<name>.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.commandsDir(ctx), `${name}.md`);\n }\n /** Native skill dir: <mcDir>/skills/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n /** Native subagent file path: <mcDir>/agent/<name>.md (SINGULAR dir). */\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.agentDir(ctx), `${name}.md`);\n }\n\n // ── Commands ──────────────────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for mimo-code\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.writeContentFile(\n this.commandPath(ctx, cmd.name),\n this.renderCommand(cmd),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n /** Render a command to md+frontmatter (description, model, subtask). */\n private renderCommand(cmd: CommandDef): string {\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n if (cmd.model !== undefined) frontmatter.model = cmd.model;\n if (cmd.subtask !== undefined) frontmatter.subtask = cmd.subtask;\n if (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return this.renderFrontmatterMd(frontmatter, cmd.prompt);\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for mimo-code\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\n );\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for mimo-code\" }];\n }\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.writeContentFile(\n this.subagentPath(ctx, agent.name),\n renderOpenCodeSubagentMd(agent),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun),\n );\n }\n\n // ── ts-plugin synthesis ────────────────────────────────────────────────\n\n /**\n * Build ONE self-contained ESM bridge module for MiMoCode. The module imports\n * nothing from agent-connector; it embeds the home-bin path + connector id and\n * a `bridge()` helper that shells out to the universal hook entrypoint\n * (`<homeBin> hook mimo-code <event> --connector <id>`), feeding the payload on\n * stdin and JSON.parsing the normalized HookResponse from stdout (fail-open).\n */\n synthesizePlugin(ctx: InstallContext): GeneratedPluginFile[] {\n const path = this.getHookConfigPath(ctx);\n const contents = this.buildPluginSource(ctx);\n return [{ path, contents, executable: false }];\n }\n\n /** Compose the generated plugin source with plain string concatenation. */\n private buildPluginSource(ctx: InstallContext): string {\n const events = ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_MIMOCODE[e] !== undefined,\n );\n const has = (e: HookEventName) => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Self-contained MiMoCode plugin bridge for connector ${ctx.connector.id}.\n * It imports nothing from agent-connector: every hook invocation shells out to\n * the stable home binary's universal entrypoint and JSON-parses the normalized\n * response. Fail-open: any bridge error degrades to \"allow\".\n */\nimport { execFileSync, execSync } from \"node:child_process\";\n\n${renderBridgePrelude({\n homeBin: ctx.homeBinPath,\n connectorId: ctx.connector.id,\n hookSlug: \"mimo-code\",\n payloadNoun: \"MiMoCode\",\n eventDoc: \" (PreToolUse|PostToolUse|SessionStart)\",\n failOpenComment: \"Fail-open — never wedge a tool call on a bridge error.\",\n})}\n`;\n\n const handlers: string[] = [];\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → block (throw) / rewrite args (mutate output.args).\n \"tool.execute.before\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (!res) return;\n // MiMoCode has no \"ask\" gate — degrade \"ask\" to a block (safe direction).\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${ctx.connector.id}\");\n }\n if (res.updatedInput && output && output.args) {\n Object.assign(output.args, res.updatedInput);\n }\n },`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → observe / rewrite tool output (mutate output.output).\n \"tool.execute.after\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PostToolUse\", payload);\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) {\n output.output = res.updatedOutput;\n }\n },`);\n }\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart surrogate → inject context into the system prompt.\n // MiMoCode has no real SessionStart hook (inherited from OpenCode\n // #14808 / #5409); experimental.chat.system.transform is the injection point.\n \"experimental.chat.system.transform\": async (input, output) => {\n const payload = {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"SessionStart\", payload);\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n // Insert at index 1 (after the header) to preserve the prompt-cache\n // fold (header must remain system[0]).\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n if (has(\"UserPromptSubmit\")) {\n handlers.push(` // UserPromptSubmit → context injection on prompt submission.\n // chat.message fires on the USER's prompt; output.message is a UserMessage\n // and output.parts holds the prompt parts. Inject context by PUSHING a text\n // part onto output.parts. chat.message has NO documented block/abort\n // mechanism, so a \"deny\" decision degrades to a NO-OP (best-effort) — same\n // way the tool/system handlers degrade decisions this host cannot honor.\n \"chat.message\": async (input, output) => {\n const promptText =\n output && Array.isArray(output.parts)\n ? output.parts\n .filter((p) => p && p.type === \"text\" && typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\\\\n\")\n : \"\";\n const res = bridge(\"UserPromptSubmit\", {\n prompt: promptText,\n sessionId: (input && input.sessionID) || \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.parts)) {\n output.parts.push({ type: \"text\", text: res.additionalContext });\n }\n },`);\n }\n\n if (has(\"Stop\")) {\n handlers.push(` // Stop → session.idle (\"session finished responding\"). session.idle is NOT a\n // direct hook key — it is dispatched through the generic \\`event\\` hook\n // switching on event.type (the OpenCode plugin shape, per opencode.ai/docs/\n // plugins). A block decision throws to halt (MiMoCode has no Stop-gate return\n // value). If session.idle never fires on a given build, Stop is a silent\n // no-op (an acceptable degrade — it never mis-fires).\n event: async ({ event }) => {\n if (!event || event.type !== \"session.idle\") return;\n const res = bridge(\"Stop\", {\n sessionId: (event.properties && event.properties.sessionID) || \"\",\n projectDir: PROJECT_DIR,\n });\n if (res && res.decision === \"deny\") {\n throw new Error(res.reason || \"Stop blocked by ${ctx.connector.id}\");\n }\n },`);\n }\n\n const factory = `\nexport default async function (ctx) {\n // ctx.directory is the MiMoCode project root; fall back to cwd.\n const PROJECT_DIR =\n (ctx && (ctx.directory || (ctx.worktree && ctx.worktree.path))) ||\n process.cwd();\n\n return {\n${handlers.join(\"\\n\")}\n };\n}\n`;\n\n return header + factory;\n }\n\n // ── Runtime: parse OUR bridge payload → normalized event ───────────────\n\n /**\n * `raw` is the payload OUR generated plugin posts (NOT a host-native shape):\n * { toolName, toolInput, toolOutput?, isError?, sessionId, projectDir }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as MiMoCodeBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\"\n ? { projectDir: input.projectDir }\n : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n ...(typeof input.toolOutput === \"string\"\n ? { toolOutput: input.toolOutput }\n : {}),\n ...(typeof input.isError === \"boolean\"\n ? { isError: input.isError }\n : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = { ...base };\n return ev;\n }\n default:\n // Other canonical events are not surfaced by MiMoCode; treat as a\n // session-start-shaped no-op so the dispatcher fails open gracefully.\n return { ...base, source: \"startup\" } satisfies SessionStartEvent;\n }\n }\n\n // ── Runtime: normalized response → reply the generated bridge parses ───\n\n /**\n * Our generated bridge consumes this stdout directly, so the reply body is the\n * NORMALIZED HookResponse itself — the bridge JSON.parses it and reads\n * decision / updatedInput / updatedOutput / additionalContext.\n */\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n return {\n exitCode: 0,\n stdout: JSON.stringify(response ?? { decision: \"allow\" }),\n };\n }\n\n // ── Diagnostics ────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const serverPath = this.getServerConfigPath(ctx);\n const pluginPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const hasHooks = ctx.connector.hookEvents.length > 0;\n\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: mimocode.json present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: mcp.${connectorId} registered`,\n check: () => {\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(\n serverPath,\n );\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${serverPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${serverPath}`,\n };\n },\n },\n {\n name: `${this.name}: plugin module present`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n return existsSync(pluginPath)\n ? { status: \"OK\", detail: pluginPath }\n : { status: \"FAIL\", detail: `not found: ${pluginPath}` };\n },\n },\n ];\n\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(ctx, cmd.name);\n checks.push({\n name: `${this.name}: command ${cmd.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const skill of ctx.connector.skills) {\n const p = join(this.skillDir(ctx, skill.name), \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const agent of ctx.connector.subagents) {\n const p = this.subagentPath(ctx, agent.name);\n checks.push({\n name: `${this.name}: subagent ${agent.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n /** Read a file, returning undefined on any error (idempotency compare). */\n}\n\nexport const adapter = new MiMoCodeAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
BaseAdapter,
|
|
8
8
|
renderSkillMd
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RHML2NOB.js";
|
|
10
10
|
import {
|
|
11
11
|
buildWrappedStdio
|
|
12
12
|
} from "./chunk-TO57WYBB.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-ALVXORZM.js";
|
|
14
|
+
import "./chunk-2HCJV6UO.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/mux/index.ts
|
|
17
17
|
import { existsSync, statSync } from "fs";
|
|
@@ -319,4 +319,4 @@ export {
|
|
|
319
319
|
adapter,
|
|
320
320
|
mux_default as default
|
|
321
321
|
};
|
|
322
|
-
//# sourceMappingURL=mux-
|
|
322
|
+
//# sourceMappingURL=mux-AFTVMGGM.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
OpenClawAdapter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-F5COBB5F.js";
|
|
5
5
|
import "./chunk-DBQMX75U.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-RHML2NOB.js";
|
|
7
7
|
import "./chunk-TO57WYBB.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-ALVXORZM.js";
|
|
9
|
+
import "./chunk-2HCJV6UO.js";
|
|
10
10
|
|
|
11
11
|
// src/adapters/nemoclaw/index.ts
|
|
12
12
|
import { existsSync } from "fs";
|
|
@@ -54,4 +54,4 @@ export {
|
|
|
54
54
|
adapter,
|
|
55
55
|
nemoclaw_default as default
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=nemoclaw-
|
|
57
|
+
//# sourceMappingURL=nemoclaw-D5EN4G2Q.js.map
|
|
@@ -7,24 +7,17 @@ import {
|
|
|
7
7
|
} from "./chunk-DBQMX75U.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseAdapter
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RHML2NOB.js";
|
|
11
11
|
import {
|
|
12
12
|
buildWrappedStdio
|
|
13
13
|
} from "./chunk-TO57WYBB.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-ALVXORZM.js";
|
|
15
|
+
import "./chunk-2HCJV6UO.js";
|
|
16
16
|
|
|
17
17
|
// src/adapters/omp/index.ts
|
|
18
|
-
import {
|
|
19
|
-
chmodSync,
|
|
20
|
-
existsSync,
|
|
21
|
-
mkdirSync,
|
|
22
|
-
readFileSync,
|
|
23
|
-
rmSync,
|
|
24
|
-
writeFileSync
|
|
25
|
-
} from "fs";
|
|
18
|
+
import { existsSync } from "fs";
|
|
26
19
|
import { homedir } from "os";
|
|
27
|
-
import {
|
|
20
|
+
import { join } from "path";
|
|
28
21
|
var HOST = "omp";
|
|
29
22
|
var MCP_ROOT_KEY = "mcpServers";
|
|
30
23
|
var EVENT_TO_OMP = {
|
|
@@ -309,22 +302,15 @@ var OMPAdapter = class extends BaseAdapter {
|
|
|
309
302
|
const files = this.synthesizePlugin(ctx);
|
|
310
303
|
const changes = [];
|
|
311
304
|
for (const file of files) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
changes.push({
|
|
323
|
-
platform: this.id,
|
|
324
|
-
action,
|
|
325
|
-
path: file.path,
|
|
326
|
-
detail: detailFor(file)
|
|
327
|
-
});
|
|
305
|
+
changes.push(
|
|
306
|
+
this.writeManagedFile(
|
|
307
|
+
file.path,
|
|
308
|
+
file.contents,
|
|
309
|
+
ctx.dryRun,
|
|
310
|
+
detailFor(file),
|
|
311
|
+
file.executable
|
|
312
|
+
)
|
|
313
|
+
);
|
|
328
314
|
}
|
|
329
315
|
return changes;
|
|
330
316
|
}
|
|
@@ -365,13 +351,8 @@ var OMPAdapter = class extends BaseAdapter {
|
|
|
365
351
|
}
|
|
366
352
|
const changes = [];
|
|
367
353
|
for (const p of present) {
|
|
368
|
-
|
|
369
|
-
changes.push({
|
|
370
|
-
platform: this.id,
|
|
371
|
-
action: "remove",
|
|
372
|
-
path: p,
|
|
373
|
-
detail: p.endsWith("package.json") ? "omp extension manifest" : "omp plugin module"
|
|
374
|
-
});
|
|
354
|
+
const detail = p.endsWith("package.json") ? "omp extension manifest" : "omp plugin module";
|
|
355
|
+
changes.push(this.removeManagedFile(p, ctx.dryRun, detail, `no ${detail} present`));
|
|
375
356
|
}
|
|
376
357
|
return changes;
|
|
377
358
|
}
|
|
@@ -663,17 +644,7 @@ ${[...handlers, ...actionHandlers].join("\n\n")}
|
|
|
663
644
|
];
|
|
664
645
|
}
|
|
665
646
|
/** Read a file, returning undefined on any error (idempotency compare). */
|
|
666
|
-
safeRead(path) {
|
|
667
|
-
try {
|
|
668
|
-
return readFileSync(path, "utf8");
|
|
669
|
-
} catch {
|
|
670
|
-
return void 0;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
647
|
};
|
|
674
|
-
function ensureDir(dir) {
|
|
675
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
676
|
-
}
|
|
677
648
|
var adapter = new OMPAdapter();
|
|
678
649
|
var omp_default = adapter;
|
|
679
650
|
export {
|
|
@@ -681,4 +652,4 @@ export {
|
|
|
681
652
|
adapter,
|
|
682
653
|
omp_default as default
|
|
683
654
|
};
|
|
684
|
-
//# sourceMappingURL=omp-
|
|
655
|
+
//# sourceMappingURL=omp-GKI2PZ7G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/omp/index.ts"],"sourcesContent":["/**\n * adapters/omp — Oh My Pi (OMP) platform adapter for agent-connector.\n *\n * OMP is a ts-plugin host with NATIVE MCP. The two surfaces are split:\n *\n * • MCP (native, real file) — OMP reads a real `mcp.json`:\n * user scope → <agentDir>/mcp.json (agentDir = ~/.omp/agent)\n * project scope → <projectDir>/.omp/mcp.json\n * JSON, root key \"mcpServers\", stdio entry { command, args, env } — the\n * portable field names. Verified against can1357/oh-my-pi\n * (packages/utils/src/dirs.ts getMCPConfigPath + docs/mcp-config.md). OMP\n * documents no native ${env:VAR} token, so env refs resolve to literals at\n * install time (resolveEnvRefsDeep).\n *\n * • Hooks (ts-plugin, in-process) — OMP loads EXTENSION PACKAGES. Its plugin\n * loader reads a package whose package.json carries an `omp` (or `pi`)\n * manifest field; the manifest's `extensions` array points at the plugin\n * module, whose DEFAULT export is a HookFactory `(pi) => void` that calls\n * `pi.on(event, handler)` (upstream loader.ts:75\n * `pluginPkg.omp || pluginPkg.pi`; hook factory types.ts:809). context-mode\n * proved this by dropping an extension under\n * `<agentDir>/extensions/<name>/{package.json,index.js}` whose index.js\n * default-exports the OMP plugin factory (src/setup.ts applyPlatformInstall\n * \"omp\"; src/adapters/omp/plugin.ts).\n *\n * Why we SYNTHESIZE instead of importing context-mode's plugin:\n * context-mode could load its own plugin module in-process because the handler\n * code shipped with the package. agent-connector cannot — the connector's hook\n * handlers are arbitrary developer code we must not import into OMP's runtime\n * (wrong cwd, wrong deps, version skew, the cache-heal bug class). So, exactly\n * like the OpenCode adapter, we generate a tiny self-contained ESM extension\n * that imports NOTHING from agent-connector: each `pi.on(...)` handler shells\n * out to the ONE stable home binary's universal entrypoint\n * (`<homeBin> hook omp <event> --connector <id>`) over child_process, feeds it\n * the OMP-shaped payload as JSON on stdin, and JSON.parses the normalized\n * HookResponse back from stdout. Fail-open: any bridge error → no-op. One\n * entrypoint, every paradigm.\n *\n * Event mapping (only events the connector declares are subscribed):\n * PreToolUse → pi.on(\"tool_call\", …) block via { block:true, reason }\n * (OMP tool_call cannot mutate args → canModifyArgs:false)\n * PostToolUse → pi.on(\"tool_result\", …) observe-only (no output rewrite hook)\n * SessionStart → pi.on(\"session_start\", …) (no context-injection surface)\n * PreCompact → pi.on(\"session_before_compact\", …) observe-only\n *\n * Distinct storage root from Pi: OMP lives under ~/.omp (NOT ~/.pi); the\n * PI_CODING_AGENT_DIR env var (the only OMP runtime dir override — OMP mirrors\n * any .env `OMP_*` keys to `PI_*` before process.env is read) takes precedence.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type {\n Adapter,\n GeneratedPluginFile,\n HookReply,\n InstallContext,\n NormalizedEvent,\n} from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PreCompactEvent,\n PreToolUseEvent,\n ServerDef,\n SessionStartEvent,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { renderBridgePrelude } from \"../../core/ts-plugin-bridge.js\";\nimport {\n buildWrappedStdio,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"omp\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Canonical → OMP event name map. A connector hook event is only subscribed by\n * the generated plugin when it appears here AND is declared by the connector.\n * Names verified against the proven context-mode OMP plugin (pi.on targets).\n */\nconst EVENT_TO_OMP: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool_call\",\n PostToolUse: \"tool_result\",\n SessionStart: \"session_start\",\n PreCompact: \"session_before_compact\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface OmpBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n sessionId?: string;\n projectDir?: string;\n}\n\n/** Native MCP server entry shapes OMP accepts under \"mcpServers\". */\ninterface OmpStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface OmpRemoteServer {\n type: \"http\" | \"sse\";\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class OMPAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Oh My Pi (OMP)\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block via the BaseAdapter default\n // (memoryTargets: project <projectDir>/AGENTS.md; user scope where documented).\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n // session_before_compact is wired as an observe-only PreCompact surface.\n preCompact: true,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // Newer events: OMP's agent_start/agent_end/turn_* hooks are the MAIN loop\n // (no subagent lifecycle events), there is no permission/approval surface,\n // and tool failure is merged into tool_result (isError) rather than a\n // dedicated event. None are wired, so permissionRequest /\n // postToolUseFailure / subagentStart / subagentStop stay unset — the\n // generated bridge never references them and install reports them as\n // \"unsupported here\".\n // OMP tool_call gates via { block, reason } only — it does not hand the\n // handler a mutable args object, so input rewrite is unsupported.\n canModifyArgs: false,\n // No tool_result output-rewrite surface upstream.\n canModifyOutput: false,\n // No session_start context-injection surface upstream.\n canInjectSessionContext: false,\n // OMP registers stdio and remote (streamable http + sse) MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Action surface: each declared action becomes a user-invokable slash\n // command registered INSIDE the generated plugin module (pi.registerCommand),\n // shelling out to the home-bin `action` verb. supportsActions → the\n // installActions/uninstallActions overrides below.\n supportsActions: true,\n // Native passthrough hooks: OMP's main-loop lifecycle events —\n // agent_start, agent_end, turn_start, turn_end — have NO canonical\n // HookEventName analog (verified in oh-my-pi shared-events.ts). A connector\n // reaches them by declaring platforms[\"omp\"].nativeHooks; the generated\n // plugin registers + bridges each declared native event verbatim\n // (buildPluginSource native loop), and the home-bin runtime dispatches it\n // host-generically via runNativeHook.\n supportsNativeHooks: true,\n };\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n /**\n * Resolve the OMP agent dir, honoring the PI_CODING_AGENT_DIR override (the\n * only OMP runtime dir env), else ~/.omp/agent. This is the user-scope root.\n */\n private agentDir(): string {\n const override = process.env.PI_CODING_AGENT_DIR;\n return override && override !== \"\"\n ? override\n : join(homedir(), \".omp\", \"agent\");\n }\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".omp\")\n : this.agentDir();\n }\n\n /** Native MCP file: <agentDir>/mcp.json (user) or <projectDir>/.omp/mcp.json. */\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /**\n * For this ts-plugin host the \"hook config path\" is the generated extension\n * entrypoint module (index.js). OMP loads the extension package by reading its\n * package.json manifest, so the package.json is written alongside (see\n * synthesizePlugin); this returns the entry module the manifest points at.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.extensionDir(ctx), \"index.js\");\n }\n\n /** Extension package directory OMP loads the plugin from, per scope. */\n private extensionDir(ctx: InstallContext): string {\n const base =\n ctx.scope === \"project\"\n ? join(ctx.projectDir, \".omp\")\n : this.agentDir();\n return join(base, \"extensions\", ctx.connector.id);\n }\n\n // ── Detection ──────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userAgentDir = this.agentDir();\n const userConfig = join(userAgentDir, \"mcp.json\");\n const projectConfig = join(projectDir, \".omp\", \"mcp.json\");\n\n const userInstalled = existsSync(userAgentDir) || existsSync(userConfig);\n const projInstalled =\n existsSync(join(projectDir, \".omp\")) || existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n\n // Report the marker that actually matched.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectConfig : userConfig;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? scope === \"project\"\n ? `found project OMP dir at ${join(projectDir, \".omp\")}`\n : `found OMP agent dir at ${userAgentDir}`\n : `no OMP agent dir at ${userAgentDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── MCP server install / uninstall (native mcp.json) ────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const server = this.effectiveServer(ctx);\n const serverPath = this.getServerConfigPath(ctx);\n\n if (!server) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: serverPath,\n detail: ctx.connector.server\n ? \"server registration disabled for omp\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n // Honesty: OMP documents stdio/sse/http. A connector declaring another\n // transport (e.g. the non-spec \"ws\") is still rendered best-effort — the\n // remote branch coerces it to type:\"http\" (OMP rejects an unknown `type`) —\n // but the mismatch is REPORTED, never silently downgraded (same \"degradation\n // is never silent\" posture as the hook warn-skips).\n if (!this.capabilities.transports.includes(server.transport)) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: serverPath,\n detail: `transport \"${server.transport}\" is not an OMP MCP transport (stdio/sse/http); registered best-effort as type:\"http\"`,\n });\n }\n\n const entry = this.renderServerEntry(ctx, server);\n changes.push(\n this.upsertServerInJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n entry,\n ctx.dryRun,\n ),\n );\n return changes;\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n ctx.dryRun,\n ),\n ];\n }\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[HOST]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override && typeof override === \"object\"\n ? { ...base, ...override }\n : base;\n }\n\n /**\n * Render a normalized ServerDef into OMP's native \"mcpServers\" entry.\n *\n * stdio → { command, args, env } (portable field names; `type` omitted —\n * OMP defaults an entry with no `type` to stdio)\n * remote → { type: \"http\"|\"sse\", url, headers? } (`type` is REQUIRED for a\n * URL server — without it OMP would mis-parse the entry as stdio)\n *\n * Telemetry wrapping routes the real command through\n * `<homeBin> serve --connector <id> -- <command> <args...>`. OMP has no native\n * env interpolation token, so every ${env:VAR} ref resolves to a literal.\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): OmpStdioServer | OmpRemoteServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n const entry: OmpStdioServer = {\n command: resolveEnvRefsDeep(command),\n };\n const resolvedArgs = resolveEnvRefsDeep(args).filter((s) => s !== \"\");\n if (resolvedArgs.length > 0) entry.args = resolvedArgs;\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // remote (http / sse) — OMP registers a URL with an explicit `type`\n // discriminator. OMP defaults a type-less entry to stdio (docs/mcp-config.md\n // \"stdio is the default when type is omitted\"), so a URL server MUST carry\n // its type or it is mis-parsed as a command.\n const entry: OmpRemoteServer = {\n type: server.transport === \"sse\" ? \"sse\" : \"http\",\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /** Resolve every ${env:VAR} ref to a literal (OMP has no native token). */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hook install / uninstall (ts-plugin extension package) ──────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const entryPath = this.getHookConfigPath(ctx);\n\n // Native passthrough events are a sibling, omp-scoped declaration: `hooks:\n // false` disables only the CANONICAL events, and the generated native loop\n // reads platforms.omp.nativeHooks directly (independent of hookEvents). So\n // whenever native events exist the plugin must still be synthesized.\n const nativeEvents = Object.keys(\n ctx.connector.platforms[HOST]?.nativeHooks ?? {},\n );\n\n if (ctx.connector.platforms[HOST]?.hooks === false && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: entryPath,\n detail: \"hooks disabled for omp\",\n },\n ];\n }\n // Empty-events gate: the plugin module is SHARED with the action surface, so\n // a connector with actions-but-no-hooks still needs it written — but that is\n // installActions' job. installHooks itself only writes when there ARE hooks,\n // so its skip detail stays honest about why (no hooks) while admitting the\n // plugin may still exist for actions. Native events are a third reason to\n // write it, so they suppress the skip too.\n if (ctx.connector.hookEvents.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: entryPath,\n detail:\n this.actionTriggers(ctx).length > 0\n ? \"no hooks (plugin written for actions)\"\n : \"connector declares no hooks\",\n },\n ];\n }\n\n return this.ensurePlugin(ctx, (file) =>\n file.path.endsWith(\"package.json\")\n ? \"omp extension manifest\"\n : `omp plugin module (${this.hookDetail(ctx)})`,\n );\n }\n\n // ── Action install / uninstall (slash commands in the shared plugin) ────\n\n /**\n * Each declared action becomes a `pi.registerCommand(...)` inside the SAME\n * generated extension module (see buildPluginSource). So installActions just\n * ensures that shared module is on disk: when hooks already wrote the identical\n * bytes the content-compare yields \"skip\" (no double material write), and an\n * actions-only connector gets the plugin written here. Honors\n * platforms.omp.actions === false and the empty-actions skip.\n */\n override installActions(ctx: InstallContext): ChangeRecord[] {\n const entryPath = this.getHookConfigPath(ctx);\n if (ctx.connector.platforms[HOST]?.actions === false) {\n return [\n { platform: this.id, action: \"skip\", path: entryPath, detail: \"actions disabled for omp\" },\n ];\n }\n if (this.actionTriggers(ctx).length === 0) {\n return [\n { platform: this.id, action: \"skip\", path: entryPath, detail: \"connector declares no actions\" },\n ];\n }\n return this.ensurePlugin(ctx, (file) =>\n file.path.endsWith(\"package.json\")\n ? \"omp extension manifest\"\n : \"omp plugin module (action commands)\",\n );\n }\n\n /**\n * Actions live INSIDE the shared plugin module, which uninstallHooks removes\n * unconditionally (it runs last in the teardown pass). Removing it here too\n * would race uninstallHooks, so this is a single informational skip.\n */\n override uninstallActions(ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: this.getHookConfigPath(ctx),\n detail: \"action commands are embedded in the plugin module; removed by uninstallHooks\",\n },\n ];\n }\n\n /**\n * Synthesize + content-compare-write the extension package (package.json +\n * index.js). Shared by installHooks and installActions: the generator is a pure\n * function of ctx, so whichever surface runs second sees byte-identical files\n * and reports \"skip\" — no double material write. `detailFor` flavors the\n * ChangeRecord detail per surface.\n */\n private ensurePlugin(\n ctx: InstallContext,\n detailFor: (file: GeneratedPluginFile) => string,\n ): ChangeRecord[] {\n const files = this.synthesizePlugin(ctx);\n const changes: ChangeRecord[] = [];\n\n for (const file of files) {\n changes.push(\n this.writeManagedFile(\n file.path,\n file.contents,\n ctx.dryRun,\n detailFor(file),\n file.executable,\n ),\n );\n }\n\n return changes;\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module ACTUALLY\n * wires. Only events present in EVENT_TO_OMP are mapped/wired; any declared\n * event with no OMP mapping (e.g. UserPromptSubmit) is reported separately as\n * \"unsupported here\" so the detail never overstates coverage.\n */\n private hookDetail(ctx: InstallContext): string {\n // `hooks: false` suppresses the canonical handlers (buildPluginSource), so\n // the detail must not claim them. Native events are still reported below.\n const canonicalOff = ctx.connector.platforms[HOST]?.hooks === false;\n const declared = canonicalOff ? [] : ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_OMP[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_OMP[e] === undefined);\n const nativeEvents = Object.keys(\n ctx.connector.platforms[HOST]?.nativeHooks ?? {},\n );\n const parts = [mapped.join(\",\")].filter((p) => p !== \"\");\n if (nativeEvents.length > 0) {\n parts.push(`native: ${nativeEvents.join(\",\")}`);\n }\n const base = parts.join(\"; \");\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const entryPath = this.getHookConfigPath(ctx);\n const manifestPath = join(this.extensionDir(ctx), \"package.json\");\n const present = [entryPath, manifestPath].filter((p) => existsSync(p));\n\n if (present.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: entryPath,\n detail: \"no omp extension present\",\n },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n for (const p of present) {\n const detail = p.endsWith(\"package.json\") ? \"omp extension manifest\" : \"omp plugin module\";\n changes.push(this.removeManagedFile(p, ctx.dryRun, detail, `no ${detail} present`));\n }\n return changes;\n }\n\n // ── ts-plugin synthesis ────────────────────────────────────────────────\n\n /**\n * Build the OMP extension package: TWO files.\n *\n * 1. package.json — the manifest OMP's loader reads. It carries the `omp`\n * field (`pluginPkg.omp || pluginPkg.pi`) whose `extensions` array points\n * at the entry module, plus `type:\"module\"` and `main:\"index.js\"`.\n * 2. index.js — a self-contained ESM plugin that imports nothing from\n * agent-connector. Its default export is the OMP HookFactory `(pi)=>void`;\n * each declared event registers a `pi.on(...)` handler that bridges to the\n * home binary via execFileSync (fail-open) and applies the normalized\n * response.\n */\n synthesizePlugin(ctx: InstallContext): GeneratedPluginFile[] {\n const dir = this.extensionDir(ctx);\n return [\n {\n path: join(dir, \"package.json\"),\n contents: this.buildManifest(ctx),\n executable: false,\n },\n {\n path: join(dir, \"index.js\"),\n contents: this.buildPluginSource(ctx),\n executable: false,\n },\n ];\n }\n\n /** The extension package.json manifest OMP's plugin loader reads. */\n private buildManifest(ctx: InstallContext): string {\n const manifest = {\n name: ctx.connector.id,\n version: ctx.connector.version || \"0.0.0\",\n description: `${ctx.connector.displayName} OMP extension (generated by agent-connector)`,\n type: \"module\",\n main: \"index.js\",\n // pluginPkg.omp || pluginPkg.pi → manifest. extensions points at the entry.\n omp: {\n extensions: [\"./index.js\"],\n },\n };\n return `${JSON.stringify(manifest, null, 2)}\\n`;\n }\n\n /** Compose the generated plugin source with plain string concatenation. */\n private buildPluginSource(ctx: InstallContext): string {\n // `platforms.omp.hooks === false` disables only the CANONICAL events (the\n // native loop below reads platforms.omp.nativeHooks directly and is a\n // sibling, unaffected). When canonical hooks are off the module may still be\n // synthesized for native events and/or actions, so the canonical handler set\n // collapses to empty here rather than short-circuiting the whole plugin.\n const canonicalOff = ctx.connector.platforms[HOST]?.hooks === false;\n const events = canonicalOff\n ? []\n : ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_OMP[e] !== undefined,\n );\n const has = (e: HookEventName) => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Self-contained Oh My Pi (OMP) plugin extension for connector ${ctx.connector.id}.\n * It imports nothing from agent-connector: every hook invocation shells out to\n * the stable home binary's universal entrypoint and JSON-parses the normalized\n * response. Fail-open: any bridge error degrades to a no-op (never wedges OMP).\n *\n * OMP loads this module via the sibling package.json \"omp\" manifest field; the\n * default export is the HookFactory (pi) => void called once at load time.\n */\nimport { execFileSync, execSync } from \"node:child_process\";\n\n${renderBridgePrelude({\n homeBin: ctx.homeBinPath,\n connectorId: ctx.connector.id,\n hookSlug: \"omp\",\n payloadNoun: \"OMP\",\n failOpenComment: \"Fail-open — never break an OMP tool call / lifecycle event.\",\n})}\n\n// OMP exposes the project dir via PI_PROJECT_DIR (PI_*-prefixed only); fall\n// through to cwd. The plugin process is long-lived, so resolve once at load.\nconst PROJECT_DIR = process.env.PI_PROJECT_DIR || process.cwd();\n\n// Derive a stable session id from OMP's session manager when available\n// (ctx.sessionManager.getSessionFile()), else a wall-clock token. The id is\n// rebound on each session_start so multi-session reuse stays attributed.\nlet SESSION_ID = \"\";\nfunction deriveSessionId(ctx) {\n try {\n const f = ctx && ctx.sessionManager && typeof ctx.sessionManager.getSessionFile === \"function\"\n ? ctx.sessionManager.getSessionFile()\n : \"\";\n if (f && typeof f === \"string\") return f;\n } catch {\n // best effort\n }\n return \"omp-\" + Date.now();\n}\n`;\n\n const handlers: string[] = [];\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart → rebind the session id and notify the connector.\n pi.on(\"session_start\", (_event, ctx) => {\n SESSION_ID = deriveSessionId(ctx);\n bridge(\"SessionStart\", { sessionId: SESSION_ID, projectDir: PROJECT_DIR });\n return undefined;\n });`);\n }\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → block via { block, reason }. OMP tool_call cannot mutate\n // args, so \"ask\" degrades to a block (the safe direction); \"modify\" degrades\n // to ALLOW (no-block), matching opencode/claude-code — only deny/ask block.\n pi.on(\"tool_call\", (event) => {\n const payload = {\n toolName: (event && event.toolName) || \"\",\n toolInput: (event && event.input) || {},\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (!res) return undefined;\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n return { block: true, reason: res.reason || \"Blocked by ${ctx.connector.id}\" };\n }\n return undefined;\n });`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → observe tool results (no output-rewrite surface upstream).\n pi.on(\"tool_result\", (event) => {\n const content = (event && Array.isArray(event.content)) ? event.content : [];\n const toolOutput = content\n .filter((c) => c && c.type === \"text\" && typeof c.text === \"string\")\n .map((c) => c.text)\n .join(\"\\\\n\");\n const payload = {\n toolName: (event && event.toolName) || \"\",\n toolInput: (event && event.input) || {},\n toolOutput,\n isError: !!(event && event.isError),\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n };\n bridge(\"PostToolUse\", payload);\n return undefined;\n });`);\n }\n\n if (has(\"PreCompact\")) {\n handlers.push(` // PreCompact → notify before OMP compacts the context window.\n pi.on(\"session_before_compact\", () => {\n bridge(\"PreCompact\", { sessionId: SESSION_ID, projectDir: PROJECT_DIR });\n return undefined;\n });`);\n }\n\n // NATIVE passthrough events: OMP's main-loop lifecycle hooks (agent_start,\n // agent_end, turn_start, turn_end) have NO canonical analog, so they are not\n // in EVENT_TO_OMP. Each declared native event registers a pi.on(...) handler\n // that bridges the NATIVE event name verbatim to the home-bin → runNativeHook\n // dispatches it host-generically. Read straight off platforms.omp.nativeHooks\n // (independent of hookEvents), so they install even with hooks:false.\n const nativeEvents = Object.keys(\n ctx.connector.platforms[HOST]?.nativeHooks ?? {},\n );\n for (const ev of nativeEvents) {\n handlers.push(` // nativeHooks passthrough → ${ev}\n pi.on(${JSON.stringify(ev)}, (event) => {\n bridge(${JSON.stringify(ev)}, { sessionId: SESSION_ID, projectDir: PROJECT_DIR, raw: event });\n return undefined;\n });`);\n }\n\n // Action surface: one pi.registerCommand per declared action. The command\n // shells out to the home-bin `action` verb (host token literal \"omp\" — OMP\n // has no fork). Fail-open: a launcher error degrades to a no-op (never wedges\n // OMP). Both id AND description are JSON.stringify'd — descriptions are\n // free-form connector text, so a raw \" / backtick would break the module.\n const actionHandlers: string[] = [];\n for (const action of this.actionTriggers(ctx)) {\n const id = JSON.stringify(action.id);\n const description = JSON.stringify(action.description);\n actionHandlers.push(` // Action /${action.id} → run the home-bin action verb directly.\n pi.registerCommand(${id}, {\n description: ${description},\n handler: async (_args, _ctx) => {\n try {\n const args = [\"action\", \"omp\", ${id}, \"--connector\", CONNECTOR_ID];\n process.platform === \"win32\"\n ? execSync([HOME_BIN, ...args].map((a) => '\"' + a + '\"').join(\" \"), { stdio: \"inherit\" })\n : execFileSync(HOME_BIN, args, { stdio: \"inherit\" });\n } catch { /* fail-open */ }\n return undefined;\n },\n });`);\n }\n\n // When hook events are empty but actions exist, the factory body is just the\n // action registrations (still valid JS — an empty handlers[] yields \"\").\n const factory = `\nexport default function plugin(pi) {\n${[...handlers, ...actionHandlers].join(\"\\n\\n\")}\n}\n`;\n\n return header + factory;\n }\n\n // ── Runtime: parse OUR bridge payload → normalized event ───────────────\n\n /**\n * `raw` is the payload OUR generated plugin posts (NOT a host-native shape):\n * { toolName?, toolInput?, toolOutput?, isError?, sessionId?, projectDir? }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as OmpBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\"\n ? { projectDir: input.projectDir }\n : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n ...(typeof input.toolOutput === \"string\"\n ? { toolOutput: input.toolOutput }\n : {}),\n ...(typeof input.isError === \"boolean\"\n ? { isError: input.isError }\n : {}),\n };\n return ev;\n }\n case \"PreCompact\": {\n const ev: PreCompactEvent = { ...base };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\n return ev;\n }\n default:\n // Other canonical events are not surfaced by OMP; treat as a\n // session-start-shaped no-op so the dispatcher fails open gracefully.\n return { ...base, source: \"startup\" } satisfies SessionStartEvent;\n }\n }\n\n // ── Runtime: normalized response → reply the generated bridge parses ───\n\n /**\n * Unlike json-stdio hosts (whose reply is the host's NATIVE control payload),\n * OUR generated bridge consumes this stdout directly. So the reply body is the\n * NORMALIZED HookResponse itself — the bridge JSON.parses it and maps decision\n * → OMP's { block, reason } for tool_call (and ignores it otherwise).\n */\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n return {\n exitCode: 0,\n stdout: JSON.stringify(response ?? { decision: \"allow\" }),\n };\n }\n\n // ── Diagnostics ────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const serverPath = this.getServerConfigPath(ctx);\n const entryPath = this.getHookConfigPath(ctx);\n const manifestPath = join(this.extensionDir(ctx), \"package.json\");\n const connectorId = ctx.connector.id;\n // Actions are health-equivalent to hooks: both write the SAME extension\n // package, so an actions-only connector must still assert it is present.\n const hasHooks =\n ctx.connector.hookEvents.length > 0 || this.actionTriggers(ctx).length > 0;\n\n return [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: ${MCP_ROOT_KEY}.${connectorId} registered`,\n check: () => {\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(\n serverPath,\n );\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY} in ${serverPath}`,\n };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${serverPath}`,\n };\n },\n },\n {\n name: `${this.name}: extension package present`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n if (!existsSync(manifestPath)) {\n return { status: \"FAIL\", detail: `not found: ${manifestPath}` };\n }\n return existsSync(entryPath)\n ? { status: \"OK\", detail: entryPath }\n : { status: \"FAIL\", detail: `not found: ${entryPath}` };\n },\n },\n ];\n }\n\n /** Read a file, returning undefined on any error (idempotency compare). */\n}\n\nexport const adapter = new OMPAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
OpenClawAdapter,
|
|
4
4
|
adapter,
|
|
5
5
|
openclaw_default
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-F5COBB5F.js";
|
|
7
7
|
import "./chunk-DBQMX75U.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-RHML2NOB.js";
|
|
9
9
|
import "./chunk-TO57WYBB.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-ALVXORZM.js";
|
|
11
|
+
import "./chunk-2HCJV6UO.js";
|
|
12
12
|
export {
|
|
13
13
|
OpenClawAdapter,
|
|
14
14
|
adapter,
|
|
15
15
|
openclaw_default as default
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=openclaw-
|
|
17
|
+
//# sourceMappingURL=openclaw-A76PCNBV.js.map
|
|
@@ -9,24 +9,17 @@ import {
|
|
|
9
9
|
BaseAdapter,
|
|
10
10
|
renderOpenCodeSubagentMd,
|
|
11
11
|
renderSkillMd
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RHML2NOB.js";
|
|
13
13
|
import {
|
|
14
14
|
buildWrappedStdio
|
|
15
15
|
} from "./chunk-TO57WYBB.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-ALVXORZM.js";
|
|
17
|
+
import "./chunk-2HCJV6UO.js";
|
|
18
18
|
|
|
19
19
|
// src/adapters/opencode/index.ts
|
|
20
|
-
import {
|
|
21
|
-
chmodSync,
|
|
22
|
-
existsSync,
|
|
23
|
-
mkdirSync,
|
|
24
|
-
readFileSync,
|
|
25
|
-
rmSync,
|
|
26
|
-
writeFileSync
|
|
27
|
-
} from "fs";
|
|
20
|
+
import { existsSync } from "fs";
|
|
28
21
|
import { homedir } from "os";
|
|
29
|
-
import {
|
|
22
|
+
import { join } from "path";
|
|
30
23
|
var HOST = "opencode";
|
|
31
24
|
var MCP_ROOT_KEY = "mcp";
|
|
32
25
|
var EVENT_TO_OPENCODE = {
|
|
@@ -267,22 +260,15 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
267
260
|
const files = this.synthesizePlugin(ctx);
|
|
268
261
|
const changes = [];
|
|
269
262
|
for (const file of files) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
changes.push({
|
|
281
|
-
platform: this.id,
|
|
282
|
-
action,
|
|
283
|
-
path: file.path,
|
|
284
|
-
detail: `opencode plugin module (${this.hookDetail(ctx)})`
|
|
285
|
-
});
|
|
263
|
+
changes.push(
|
|
264
|
+
this.writeManagedFile(
|
|
265
|
+
file.path,
|
|
266
|
+
file.contents,
|
|
267
|
+
ctx.dryRun,
|
|
268
|
+
`opencode plugin module (${this.hookDetail(ctx)})`,
|
|
269
|
+
file.executable
|
|
270
|
+
)
|
|
271
|
+
);
|
|
286
272
|
}
|
|
287
273
|
return changes;
|
|
288
274
|
}
|
|
@@ -314,24 +300,13 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
314
300
|
}
|
|
315
301
|
uninstallHooks(ctx) {
|
|
316
302
|
const pluginPath = this.getHookConfigPath(ctx);
|
|
317
|
-
if (!existsSync(pluginPath)) {
|
|
318
|
-
return [
|
|
319
|
-
{
|
|
320
|
-
platform: this.id,
|
|
321
|
-
action: "skip",
|
|
322
|
-
path: pluginPath,
|
|
323
|
-
detail: "no opencode plugin module present"
|
|
324
|
-
}
|
|
325
|
-
];
|
|
326
|
-
}
|
|
327
|
-
if (!ctx.dryRun) rmSync(pluginPath, { force: true });
|
|
328
303
|
return [
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
304
|
+
this.removeManagedFile(
|
|
305
|
+
pluginPath,
|
|
306
|
+
ctx.dryRun,
|
|
307
|
+
"opencode plugin module",
|
|
308
|
+
"no opencode plugin module present"
|
|
309
|
+
)
|
|
335
310
|
];
|
|
336
311
|
}
|
|
337
312
|
// ── Content surfaces: commands / skills / subagents ──────────────────────
|
|
@@ -751,17 +726,7 @@ ${handlers.join("\n")}
|
|
|
751
726
|
return checks;
|
|
752
727
|
}
|
|
753
728
|
/** Read a file, returning undefined on any error (idempotency compare). */
|
|
754
|
-
safeRead(path) {
|
|
755
|
-
try {
|
|
756
|
-
return readFileSync(path, "utf8");
|
|
757
|
-
} catch {
|
|
758
|
-
return void 0;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
729
|
};
|
|
762
|
-
function ensureDir(dir) {
|
|
763
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
764
|
-
}
|
|
765
730
|
var adapter = new OpenCodeAdapter();
|
|
766
731
|
var opencode_default = adapter;
|
|
767
732
|
export {
|
|
@@ -769,4 +734,4 @@ export {
|
|
|
769
734
|
adapter,
|
|
770
735
|
opencode_default as default
|
|
771
736
|
};
|
|
772
|
-
//# sourceMappingURL=opencode-
|
|
737
|
+
//# sourceMappingURL=opencode-M34E6PI7.js.map
|