@ken-jo/agent-connector 0.4.92 → 0.4.94
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 +49 -30
- package/dist/{action-CVIEPX4U.js → action-VW5SACXY.js} +9 -9
- package/dist/{amazon-q-TIT7FIW3.js → amazon-q-ETMAGY3D.js} +3 -3
- package/dist/{amp-NF3OAAUG.js → amp-67BZONGF.js} +3 -3
- package/dist/{antigravity-7LPK7QOY.js → antigravity-VXLDLTO7.js} +4 -4
- package/dist/{antigravity-cli-MDEMPPAH.js → antigravity-cli-OM6SC3PE.js} +4 -4
- package/dist/{chunk-7UT6OB52.js → chunk-2RIFORQS.js} +2 -2
- package/dist/{chunk-JFXL4HYA.js → chunk-6WZODR3Z.js} +2 -2
- package/dist/{chunk-IBLYVAWH.js → chunk-B5W3RHTI.js} +48 -20
- package/dist/{chunk-IBLYVAWH.js.map → chunk-B5W3RHTI.js.map} +1 -1
- package/dist/{chunk-447JWFZO.js → chunk-EHP7WISI.js} +5 -5
- package/dist/{chunk-FBCBHEGB.js → chunk-I5TO42QC.js} +3 -3
- package/dist/{chunk-3C5AASHM.js → chunk-JKKU2WKG.js} +2 -2
- package/dist/{chunk-AY3VFNOH.js → chunk-KJLFGQQM.js} +178 -8
- package/dist/chunk-KJLFGQQM.js.map +1 -0
- package/dist/{chunk-JVO6NBTT.js → chunk-KSPMSRVU.js} +26 -14
- package/dist/chunk-KSPMSRVU.js.map +1 -0
- package/dist/{chunk-WFEHWTLM.js → chunk-MGTDQLJJ.js} +2 -2
- package/dist/{chunk-L26PSQTY.js → chunk-P23RVIUY.js} +4 -4
- package/dist/{chunk-KA55FISM.js → chunk-SILKSP2Y.js} +43 -43
- package/dist/{chunk-5Z36KVU2.js → chunk-TQRLMA2C.js} +19 -19
- package/dist/chunk-TQRLMA2C.js.map +1 -0
- package/dist/{chunk-JO2IM2JL.js → chunk-TTKSYJRY.js} +6 -6
- package/dist/{chunk-M2H7JURF.js → chunk-UMQ6NBQR.js} +2 -2
- package/dist/chunk-UMQ6NBQR.js.map +1 -0
- package/dist/{chunk-DI5S6TXJ.js → chunk-XC5SJ35F.js} +2 -2
- package/dist/{chunk-FO5CEXXN.js → chunk-ZMAJ2XFD.js} +2 -2
- package/dist/{claude-code-7RS4YVGZ.js → claude-code-DUZNOAS2.js} +6 -6
- package/dist/cli/sdk.d.ts +53 -12
- package/dist/cli/sdk.js +83 -15
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/{cline-BZQAUYPC.js → cline-25KW25IN.js} +3 -3
- package/dist/{codebuddy-G42IKGKB.js → codebuddy-ZNYQACMF.js} +3 -3
- package/dist/{codebuff-5RLTLZAU.js → codebuff-VR6JUDIY.js} +3 -3
- package/dist/{codex-XHAMJILX.js → codex-CPNKTXG3.js} +3 -3
- package/dist/{continue-JLIB7R7X.js → continue-WU2IB5KS.js} +3 -3
- package/dist/{copilot-cli-XZSUYNQZ.js → copilot-cli-PAP377OM.js} +3 -3
- package/dist/{crush-ESERLVLT.js → crush-3AVQA4YU.js} +3 -3
- package/dist/{cursor-FUDOV5VK.js → cursor-GSLUET3V.js} +4 -4
- package/dist/define-connector-LQFJL_at.d.ts +89 -0
- package/dist/{detect-Z5BDTY6B.js → detect-P5OA5UYM.js} +4 -4
- package/dist/{devin-Y7PWKVHY.js → devin-QMEM3OFA.js} +3 -3
- package/dist/{doctor-GAP27PP2.js → doctor-2O2Q6MIB.js} +14 -14
- package/dist/{droid-DTO5POTK.js → droid-MOKV53J4.js} +3 -3
- package/dist/{gemini-cli-RBIG6U2F.js → gemini-cli-47ZHCOZR.js} +3 -3
- package/dist/{goose-VGNOP5J2.js → goose-4EI5MYTI.js} +3 -3
- package/dist/{grok-cli-2RFBK6J3.js → grok-cli-QYQPDSVB.js} +3 -3
- package/dist/{hermes-NUKFWZI5.js → hermes-F75OSK3Y.js} +3 -3
- package/dist/{hook-XPR3AHDI.js → hook-4N3BMKIK.js} +9 -9
- package/dist/index.d.ts +15 -88
- package/dist/index.js +13 -5
- package/dist/{install-O32TDIZP.js → install-NPN77N3S.js} +11 -11
- package/dist/{introspect-BkId4LGP.d.ts → introspect-D4fEGuhN.d.ts} +1 -1
- package/dist/{jetbrains-copilot-FXZ5AOTS.js → jetbrains-copilot-ZGIWI6YV.js} +3 -3
- package/dist/{junie-TSXIZSCE.js → junie-DIFN2P22.js} +3 -3
- package/dist/{kilo-JLH3KVZJ.js → kilo-EMZJBEBB.js} +3 -3
- package/dist/{kilo-cli-5W36VJQZ.js → kilo-cli-S3GXBPAE.js} +3 -3
- package/dist/{kimi-R62W7HKZ.js → kimi-IQJOIY6B.js} +3 -3
- package/dist/{kiro-AUJMGIBL.js → kiro-BYX4HEAJ.js} +3 -3
- package/dist/{leaderboard-YWMOSJBC.js → leaderboard-QKB36OBR.js} +2 -2
- package/dist/{mimo-code-PGLFFVER.js → mimo-code-7R53QDHB.js} +3 -3
- package/dist/{mistral-vibe-36CZVQNQ.js → mistral-vibe-LHJ55FSB.js} +3 -3
- package/dist/{mux-HWL4N5KH.js → mux-NYCNGL43.js} +3 -3
- package/dist/{nemoclaw-QPHETUXM.js → nemoclaw-WSIPSE7U.js} +4 -4
- package/dist/{omp-3TFMTJ5U.js → omp-562NK5BJ.js} +3 -3
- package/dist/{open-interpreter-UTBKE2EH.js → open-interpreter-I2CNOEXY.js} +3 -3
- package/dist/{openclaw-RYFO5TLY.js → openclaw-7EYBQS4R.js} +4 -4
- package/dist/{opencode-JX7GBE5Q.js → opencode-YS4WX2E2.js} +3 -3
- package/dist/{openhands-AZW4PXJ3.js → openhands-QMYIKNOS.js} +3 -3
- package/dist/{package-2KKUGZFS.js → package-Q6DV5247.js} +9 -9
- package/dist/{pi-MRI3EBWU.js → pi-644FIN3A.js} +3 -3
- package/dist/{qwen-code-ISR6BEET.js → qwen-code-STDMX7EM.js} +3 -3
- package/dist/{roo-code-6TSCME4R.js → roo-code-DLPIHHQ6.js} +3 -3
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +7 -7
- package/dist/sdk/index.d.ts +4 -4
- package/dist/sdk/index.js +4 -4
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +7 -7
- package/dist/{serve-EPRN7F2X.js → serve-MJTTXDX4.js} +9 -9
- package/dist/{status-B2PG6YKR.js → status-Q3UY4NZU.js} +7 -7
- package/dist/{statusline-5ERFMYSM.js → statusline-QF4G724E.js} +8 -8
- package/dist/{telemetry-ZMCAWBWB.js → telemetry-JHVRDDNK.js} +6 -6
- package/dist/{trae-7KDCYIMN.js → trae-UOYD6JZZ.js} +3 -3
- package/dist/{types-D0RqWxT8.d.ts → types-BhcUEIJJ.d.ts} +39 -3
- package/dist/{uninstall-M76BHLTH.js → uninstall-H2SOV3AP.js} +11 -11
- package/dist/{upgrade-JLSCNAQA.js → upgrade-UCSG7L5U.js} +11 -11
- package/dist/{usage-5I72HWCR.js → usage-4EGIJ4TM.js} +2 -2
- package/dist/{usage-event-HIX4ZI45.js → usage-event-GRQE7XWT.js} +8 -8
- package/dist/{vscode-copilot-LILHAPJI.js → vscode-copilot-NIMH2DGU.js} +3 -3
- package/dist/{warp-KJUCWEA3.js → warp-QYJGKURM.js} +3 -3
- package/dist/{windsurf-5TGGQR5I.js → windsurf-75LLZ37C.js} +3 -3
- package/dist/{zed-EL3JCZ25.js → zed-HKAZXEJW.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-5Z36KVU2.js.map +0 -1
- package/dist/chunk-AY3VFNOH.js.map +0 -1
- package/dist/chunk-JVO6NBTT.js.map +0 -1
- package/dist/chunk-M2H7JURF.js.map +0 -1
- /package/dist/{action-CVIEPX4U.js.map → action-VW5SACXY.js.map} +0 -0
- /package/dist/{amazon-q-TIT7FIW3.js.map → amazon-q-ETMAGY3D.js.map} +0 -0
- /package/dist/{amp-NF3OAAUG.js.map → amp-67BZONGF.js.map} +0 -0
- /package/dist/{antigravity-7LPK7QOY.js.map → antigravity-VXLDLTO7.js.map} +0 -0
- /package/dist/{antigravity-cli-MDEMPPAH.js.map → antigravity-cli-OM6SC3PE.js.map} +0 -0
- /package/dist/{chunk-7UT6OB52.js.map → chunk-2RIFORQS.js.map} +0 -0
- /package/dist/{chunk-JFXL4HYA.js.map → chunk-6WZODR3Z.js.map} +0 -0
- /package/dist/{chunk-447JWFZO.js.map → chunk-EHP7WISI.js.map} +0 -0
- /package/dist/{chunk-FBCBHEGB.js.map → chunk-I5TO42QC.js.map} +0 -0
- /package/dist/{chunk-3C5AASHM.js.map → chunk-JKKU2WKG.js.map} +0 -0
- /package/dist/{chunk-WFEHWTLM.js.map → chunk-MGTDQLJJ.js.map} +0 -0
- /package/dist/{chunk-L26PSQTY.js.map → chunk-P23RVIUY.js.map} +0 -0
- /package/dist/{chunk-KA55FISM.js.map → chunk-SILKSP2Y.js.map} +0 -0
- /package/dist/{chunk-JO2IM2JL.js.map → chunk-TTKSYJRY.js.map} +0 -0
- /package/dist/{chunk-DI5S6TXJ.js.map → chunk-XC5SJ35F.js.map} +0 -0
- /package/dist/{chunk-FO5CEXXN.js.map → chunk-ZMAJ2XFD.js.map} +0 -0
- /package/dist/{claude-code-7RS4YVGZ.js.map → claude-code-DUZNOAS2.js.map} +0 -0
- /package/dist/{cline-BZQAUYPC.js.map → cline-25KW25IN.js.map} +0 -0
- /package/dist/{codebuddy-G42IKGKB.js.map → codebuddy-ZNYQACMF.js.map} +0 -0
- /package/dist/{codebuff-5RLTLZAU.js.map → codebuff-VR6JUDIY.js.map} +0 -0
- /package/dist/{codex-XHAMJILX.js.map → codex-CPNKTXG3.js.map} +0 -0
- /package/dist/{continue-JLIB7R7X.js.map → continue-WU2IB5KS.js.map} +0 -0
- /package/dist/{copilot-cli-XZSUYNQZ.js.map → copilot-cli-PAP377OM.js.map} +0 -0
- /package/dist/{crush-ESERLVLT.js.map → crush-3AVQA4YU.js.map} +0 -0
- /package/dist/{cursor-FUDOV5VK.js.map → cursor-GSLUET3V.js.map} +0 -0
- /package/dist/{detect-Z5BDTY6B.js.map → detect-P5OA5UYM.js.map} +0 -0
- /package/dist/{devin-Y7PWKVHY.js.map → devin-QMEM3OFA.js.map} +0 -0
- /package/dist/{doctor-GAP27PP2.js.map → doctor-2O2Q6MIB.js.map} +0 -0
- /package/dist/{droid-DTO5POTK.js.map → droid-MOKV53J4.js.map} +0 -0
- /package/dist/{gemini-cli-RBIG6U2F.js.map → gemini-cli-47ZHCOZR.js.map} +0 -0
- /package/dist/{goose-VGNOP5J2.js.map → goose-4EI5MYTI.js.map} +0 -0
- /package/dist/{grok-cli-2RFBK6J3.js.map → grok-cli-QYQPDSVB.js.map} +0 -0
- /package/dist/{hermes-NUKFWZI5.js.map → hermes-F75OSK3Y.js.map} +0 -0
- /package/dist/{hook-XPR3AHDI.js.map → hook-4N3BMKIK.js.map} +0 -0
- /package/dist/{install-O32TDIZP.js.map → install-NPN77N3S.js.map} +0 -0
- /package/dist/{jetbrains-copilot-FXZ5AOTS.js.map → jetbrains-copilot-ZGIWI6YV.js.map} +0 -0
- /package/dist/{junie-TSXIZSCE.js.map → junie-DIFN2P22.js.map} +0 -0
- /package/dist/{kilo-JLH3KVZJ.js.map → kilo-EMZJBEBB.js.map} +0 -0
- /package/dist/{kilo-cli-5W36VJQZ.js.map → kilo-cli-S3GXBPAE.js.map} +0 -0
- /package/dist/{kimi-R62W7HKZ.js.map → kimi-IQJOIY6B.js.map} +0 -0
- /package/dist/{kiro-AUJMGIBL.js.map → kiro-BYX4HEAJ.js.map} +0 -0
- /package/dist/{leaderboard-YWMOSJBC.js.map → leaderboard-QKB36OBR.js.map} +0 -0
- /package/dist/{mimo-code-PGLFFVER.js.map → mimo-code-7R53QDHB.js.map} +0 -0
- /package/dist/{mistral-vibe-36CZVQNQ.js.map → mistral-vibe-LHJ55FSB.js.map} +0 -0
- /package/dist/{mux-HWL4N5KH.js.map → mux-NYCNGL43.js.map} +0 -0
- /package/dist/{nemoclaw-QPHETUXM.js.map → nemoclaw-WSIPSE7U.js.map} +0 -0
- /package/dist/{omp-3TFMTJ5U.js.map → omp-562NK5BJ.js.map} +0 -0
- /package/dist/{open-interpreter-UTBKE2EH.js.map → open-interpreter-I2CNOEXY.js.map} +0 -0
- /package/dist/{openclaw-RYFO5TLY.js.map → openclaw-7EYBQS4R.js.map} +0 -0
- /package/dist/{opencode-JX7GBE5Q.js.map → opencode-YS4WX2E2.js.map} +0 -0
- /package/dist/{openhands-AZW4PXJ3.js.map → openhands-QMYIKNOS.js.map} +0 -0
- /package/dist/{package-2KKUGZFS.js.map → package-Q6DV5247.js.map} +0 -0
- /package/dist/{pi-MRI3EBWU.js.map → pi-644FIN3A.js.map} +0 -0
- /package/dist/{qwen-code-ISR6BEET.js.map → qwen-code-STDMX7EM.js.map} +0 -0
- /package/dist/{roo-code-6TSCME4R.js.map → roo-code-DLPIHHQ6.js.map} +0 -0
- /package/dist/{serve-EPRN7F2X.js.map → serve-MJTTXDX4.js.map} +0 -0
- /package/dist/{status-B2PG6YKR.js.map → status-Q3UY4NZU.js.map} +0 -0
- /package/dist/{statusline-5ERFMYSM.js.map → statusline-QF4G724E.js.map} +0 -0
- /package/dist/{telemetry-ZMCAWBWB.js.map → telemetry-JHVRDDNK.js.map} +0 -0
- /package/dist/{trae-7KDCYIMN.js.map → trae-UOYD6JZZ.js.map} +0 -0
- /package/dist/{uninstall-M76BHLTH.js.map → uninstall-H2SOV3AP.js.map} +0 -0
- /package/dist/{upgrade-JLSCNAQA.js.map → upgrade-UCSG7L5U.js.map} +0 -0
- /package/dist/{usage-5I72HWCR.js.map → usage-4EGIJ4TM.js.map} +0 -0
- /package/dist/{usage-event-HIX4ZI45.js.map → usage-event-GRQE7XWT.js.map} +0 -0
- /package/dist/{vscode-copilot-LILHAPJI.js.map → vscode-copilot-NIMH2DGU.js.map} +0 -0
- /package/dist/{warp-KJUCWEA3.js.map → warp-QYJGKURM.js.map} +0 -0
- /package/dist/{windsurf-5TGGQR5I.js.map → windsurf-75LLZ37C.js.map} +0 -0
- /package/dist/{zed-EL3JCZ25.js.map → zed-HKAZXEJW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/managed-block.ts"],"sourcesContent":["/**\n * core/managed-block — the marker-fenced MANAGED BLOCK engine behind the\n * `memory` content surface.\n *\n * Memory/rules files (AGENTS.md, CLAUDE.md, GEMINI.md, …) are SHARED,\n * user-authored files — unlike commands/skills/subagents, agent-connector does\n * not own them. Every write therefore goes through this one module, which\n * implements idempotent, hash-stamped, uninstall-reversible blocks:\n *\n * <!-- agent-connector:begin <connectorId>/<name> hash=<sha256-12> -->\n * <!-- Managed by agent-connector for \"<connectorId>\". Do not edit … -->\n * …guidance…\n * <!-- agent-connector:end <connectorId>/<name> -->\n *\n * Design rules (each grounded in surveyed prior art — ansible blockinfile,\n * conda init, OMC mergeClaudeMd, Ruler, doctoc):\n * • UNIQUE marker per block: the blockId (`<connectorId>/<entryName>`) lives\n * ON the marker line, so multiple connectors coexist in one file and each\n * update path only ever touches its own pair (ansible's documented\n * multi-block rule). The shared `agent-connector` namespace token lets\n * doctor/uninstall enumerate every block with one scan.\n * • `hash=` is the first 12 hex chars of sha256 over the NORMALIZED inner\n * region (CRLF→LF + trim — stable under prettier/EOL converters): O(1)\n * idempotence (unchanged → skip, no mtime/git churn) and tamper detection\n * (actual inner hash ≠ recorded ⇒ the user edited inside the block ⇒ warn,\n * never clobber without an explicit force).\n * • IN-PLACE replacement (conda semantics): zero bytes outside the marker\n * pair ever change — no move-to-top, no user blank-line reflow.\n * • Line-anchored matching that explicitly tolerates `\\r` line ends and a\n * FENCE-AWARE scanner (markers quoted inside ``` / ~~~ code fences never\n * match) — fixes the CRLF duplicate-block and quoted-marker classes.\n * • First-begin / FIRST-end-after pairing (never last-end): a missing end\n * marker must not swallow a sibling connector's block.\n * • HTML-comment markers are CORRECT for CLAUDE.md: Claude Code strips HTML\n * comments from CLAUDE.md before context injection (verified against docs\n * and the 2.1.172 binary), so the markers and the do-not-edit notice are\n * INVISIBLE to the model there while remaining fully parseable by us for\n * sync/doctor/uninstall. On AGENTS.md hosts (which inline the whole file\n * into the prompt) the short notice doubles as an in-prompt \"do not edit\"\n * instruction to the host's own agent. A `commentStyle: \"hash\"` variant\n * exists for future non-markdown targets (`#`-prefixed marker lines).\n *\n * The module also owns the per-connector MEMORY OWNERSHIP LEDGER\n * (`connectorDir(id)/memory-state.json`): the markers in the file remain the\n * source of truth for uninstall (a teammate's machine with no ledger still\n * uninstalls via the prefix scan); the ledger only adds the created-vs-modified\n * distinction (file deletion rights) and doctor diagnostics.\n */\n\nimport { createHash } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { assertNoSymlinkInPath, backupsDir, connectorDir, ensureDir } from \"./paths.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Grammar constants (shared with defineConnector's content validation)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Literal begin token. Connector memory content MUST NOT contain it. */\nexport const MANAGED_BLOCK_BEGIN_TOKEN = \"agent-connector:begin\";\n/** Literal end token. Connector memory content MUST NOT contain it. */\nexport const MANAGED_BLOCK_END_TOKEN = \"agent-connector:end\";\n\n/** Hard cap on one memory entry's content (ConnectorConfigError above this). */\nexport const MEMORY_CONTENT_HARD_CAP_BYTES = 16 * 1024;\n/**\n * Soft per-entry budget — exceeded → install-time `warn` ChangeRecord (memory\n * files are injected into EVERY prompt of EVERY session on the host; codex\n * additionally caps combined project docs at 32 KiB).\n */\nexport const MEMORY_CONTENT_SOFT_BUDGET_BYTES = 4 * 1024;\n\n/** Marker comment style: HTML comments (default, all v1 markdown targets) or `#` lines. */\nexport type BlockCommentStyle = \"html\" | \"hash\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Hashing / rendering\n// ─────────────────────────────────────────────────────────────────────────\n\n/** CRLF/CR → LF + trim: the normalization both hashing sides use. */\nfunction normalizeInner(s: string): string {\n return s.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").trim();\n}\n\n/** First 12 hex chars of sha256 over the NORMALIZED inner region. */\nexport function hashBlockContent(inner: string): string {\n return createHash(\"sha256\").update(normalizeInner(inner), \"utf8\").digest(\"hex\").slice(0, 12);\n}\n\n/** The conda-style in-block warning, adapted for the LLM era (see header). */\nfunction defaultNotice(connectorId: string): string {\n return (\n `Managed by agent-connector for \"${connectorId}\". Do not edit between these markers: ` +\n `run your connector package's upgrade/sync command to rewrite this block; ` +\n `run its uninstall command to remove it ` +\n `(framework fallback: \\`agent-connector uninstall ${connectorId}\\`).`\n );\n}\n\nfunction beginLine(blockId: string, hash: string, style: BlockCommentStyle): string {\n return style === \"hash\"\n ? `# ${MANAGED_BLOCK_BEGIN_TOKEN} ${blockId} hash=${hash}`\n : `<!-- ${MANAGED_BLOCK_BEGIN_TOKEN} ${blockId} hash=${hash} -->`;\n}\n\n/** END line is a fixed exact string (no hash) so a content change never strands it. */\nfunction endLine(blockId: string, style: BlockCommentStyle): string {\n return style === \"hash\"\n ? `# ${MANAGED_BLOCK_END_TOKEN} ${blockId}`\n : `<!-- ${MANAGED_BLOCK_END_TOKEN} ${blockId} -->`;\n}\n\nfunction noticeLine(notice: string, style: BlockCommentStyle): string {\n return style === \"hash\" ? `# ${notice}` : `<!-- ${notice} -->`;\n}\n\nexport interface RenderBlockOptions {\n /** `<connectorId>/<entryName>` (or the reserved `_shared/<name>` bridge prefix). */\n blockId: string;\n /** Connector id named in the default do-not-edit notice line. */\n connectorId: string;\n /** The guidance payload (plain markdown; normalized + trimmed on emit). */\n content: string;\n /** Marker comment style; default \"html\". */\n commentStyle?: BlockCommentStyle;\n /** Override the default notice line TEXT (without comment delimiters). */\n notice?: string;\n}\n\n/**\n * Render the block as LOGICAL lines (no EOL chars). The recorded `hash=`\n * covers the full inner region (notice line + content) so install and scan\n * compare like for like.\n */\nexport function renderBlockLines(opts: RenderBlockOptions): string[] {\n const style = opts.commentStyle ?? \"html\";\n const inner = [\n noticeLine(opts.notice ?? defaultNotice(opts.connectorId), style),\n ...normalizeInner(opts.content).split(\"\\n\"),\n ];\n const hash = hashBlockContent(inner.join(\"\\n\"));\n return [beginLine(opts.blockId, hash, style), ...inner, endLine(opts.blockId, style)];\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Scanning (fence-aware, line-anchored, CRLF-tolerant)\n// ─────────────────────────────────────────────────────────────────────────\n\n// Both comment styles are RECOGNIZED in one pass (a file may legitimately mix\n// styles only across rewrites; emission always uses the requested style).\nconst BEGIN_RE =\n /^(?:<!--\\s+agent-connector:begin\\s+(\\S+)\\s+hash=([0-9a-f]{12})\\s+-->|#\\s+agent-connector:begin\\s+(\\S+)\\s+hash=([0-9a-f]{12}))\\s*$/;\nconst END_RE = /^(?:<!--\\s+agent-connector:end\\s+(\\S+)\\s+-->|#\\s+agent-connector:end\\s+(\\S+))\\s*$/;\n\ninterface MarkerEvent {\n kind: \"begin\" | \"end\";\n blockId: string;\n /** Recorded hash (begin markers only). */\n hash?: string;\n /** Line index into the logical-lines array. */\n index: number;\n}\n\n/** Strip ONE trailing `\\r` — `raw.split(\"\\n\")` leaves it on CRLF files. */\nfunction stripCr(line: string): string {\n return line.endsWith(\"\\r\") ? line.slice(0, -1) : line;\n}\n\n/**\n * Scan logical lines for marker events, tracking ``` / ~~~ fence state so a\n * marker QUOTED inside a fenced code block never matches (the OMC class of\n * false positives, eliminated rather than just reduced).\n */\nfunction scanMarkers(logical: string[]): MarkerEvent[] {\n const events: MarkerEvent[] = [];\n let fence: { char: string; len: number } | null = null;\n for (let i = 0; i < logical.length; i++) {\n const line = logical[i]!;\n if (fence) {\n const close = line.match(/^ {0,3}(`{3,}|~{3,})\\s*$/);\n if (close && close[1]![0] === fence.char && close[1]!.length >= fence.len) fence = null;\n continue;\n }\n const open = line.match(/^ {0,3}(`{3,}|~{3,})/);\n if (open) {\n fence = { char: open[1]![0]!, len: open[1]!.length };\n continue;\n }\n const b = line.match(BEGIN_RE);\n if (b) {\n events.push({ kind: \"begin\", blockId: (b[1] ?? b[3])!, hash: (b[2] ?? b[4])!, index: i });\n continue;\n }\n const e = line.match(END_RE);\n if (e) events.push({ kind: \"end\", blockId: (e[1] ?? e[2])!, index: i });\n }\n return events;\n}\n\n/**\n * Logical lines of `raw` that sit OUTSIDE ``` / ~~~ code fences — for host\n * probes that must ignore quoted examples (e.g. the claude-code `@AGENTS.md`\n * import detection). Fence lines themselves are excluded.\n */\nexport function linesOutsideFences(raw: string): string[] {\n const body = raw.startsWith(\"\\uFEFF\") ? raw.slice(1) : raw;\n const logical = body.split(\"\\n\").map(stripCr);\n const out: string[] = [];\n let fence: { char: string; len: number } | null = null;\n for (const line of logical) {\n if (fence) {\n const close = line.match(/^ {0,3}(`{3,}|~{3,})\\s*$/);\n if (close && close[1]![0] === fence.char && close[1]!.length >= fence.len) fence = null;\n continue;\n }\n const open = line.match(/^ {0,3}(`{3,}|~{3,})/);\n if (open) {\n fence = { char: open[1]![0]!, len: open[1]!.length };\n continue;\n }\n out.push(line);\n }\n return out;\n}\n\ninterface BlockPair {\n blockId: string;\n begin: MarkerEvent;\n end: MarkerEvent;\n}\n\n/**\n * Pair markers per blockId: first begin, then the FIRST end at-or-after it.\n * A nested begin for the SAME id (inside an open pair) is treated as inner\n * content; unpaired markers are returned as strays. Per-id state means a\n * missing end for connector A can never swallow connector B's block.\n */\nfunction pairMarkers(events: MarkerEvent[]): { pairs: BlockPair[]; strays: MarkerEvent[] } {\n const open = new Map<string, MarkerEvent>();\n const pairs: BlockPair[] = [];\n const strays: MarkerEvent[] = [];\n for (const ev of events) {\n if (ev.kind === \"begin\") {\n if (!open.has(ev.blockId)) open.set(ev.blockId, ev);\n // else: a begin inside an open pair — inner content / abuse; the hash\n // check will flag the pair as drifted rather than guessing boundaries.\n } else {\n const b = open.get(ev.blockId);\n if (b) {\n pairs.push({ blockId: ev.blockId, begin: b, end: ev });\n open.delete(ev.blockId);\n } else {\n strays.push(ev);\n }\n }\n }\n for (const b of open.values()) strays.push(b);\n return { pairs, strays };\n}\n\n/** One discovered block (for doctor / refcount / uninstall enumeration). */\nexport interface ManagedBlockInfo {\n blockId: string;\n /** The hash recorded on the begin marker line. */\n recordedHash: string;\n /** Hash of the actual normalized inner region as found on disk. */\n actualHash: string;\n /** True when recordedHash ≠ actualHash — the user edited inside the block. */\n drifted: boolean;\n beginLine: number;\n endLine: number;\n}\n\n/** Enumerate every complete agent-connector block in `raw` (namespace scan). */\nexport function listManagedBlocks(raw: string): ManagedBlockInfo[] {\n const body = raw.startsWith(\"\\uFEFF\") ? raw.slice(1) : raw;\n const logical = body.split(\"\\n\").map(stripCr);\n const { pairs } = pairMarkers(scanMarkers(logical));\n return pairs.map((p) => {\n const inner = logical.slice(p.begin.index + 1, p.end.index).join(\"\\n\");\n const actualHash = hashBlockContent(inner);\n const recordedHash = p.begin.hash ?? \"\";\n return {\n blockId: p.blockId,\n recordedHash,\n actualHash,\n drifted: recordedHash !== actualHash,\n beginLine: p.begin.index,\n endLine: p.end.index,\n };\n });\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Pure text upsert / removal\n// ─────────────────────────────────────────────────────────────────────────\n\nexport interface UpsertBlockOptions extends RenderBlockOptions {\n /** Overwrite a USER-EDITED (drifted) block. Default false → warn + leave intact. */\n force?: boolean;\n}\n\nexport interface BlockTextResult {\n /** Resulting full text (=== input when nothing changed). */\n text: string;\n action: \"create\" | \"update\" | \"skip\" | \"warn\";\n detail: string;\n changed: boolean;\n /**\n * True when the rewrite was DESTRUCTIVE-ADJACENT (force-overwrote a drifted\n * block, collapsed duplicate pairs, or stripped stray markers) — the file\n * wrapper writes a timestamped backup before persisting such a change.\n */\n recovered: boolean;\n /** Hash of the (new) rendered inner region — recorded in the ledger. */\n hash: string;\n}\n\n/** Detect the file's dominant EOL; new/replaced lines are emitted with it. */\nfunction detectEol(body: string): \"\\n\" | \"\\r\\n\" {\n const crlf = (body.match(/\\r\\n/g) ?? []).length;\n const total = (body.match(/\\n/g) ?? []).length;\n return crlf > 0 && crlf >= total - crlf ? \"\\r\\n\" : \"\\n\";\n}\n\n/** Add `\\r` to logical lines when the file is CRLF (joined with \"\\n\" later). */\nfunction withEol(lines: string[], eol: \"\\n\" | \"\\r\\n\"): string[] {\n return eol === \"\\r\\n\" ? lines.map((l) => `${l}\\r`) : lines;\n}\n\n/**\n * Strip trailing newline(s) + whitespace-only line tails WITHOUT touching\n * trailing spaces on the last content line (bytes outside our block).\n */\nfunction trimTrailingBlank(body: string): string {\n let out = body;\n for (;;) {\n const m = out.match(/\\r?\\n[ \\t]*$/);\n if (!m) return out;\n out = out.slice(0, out.length - m[0].length);\n }\n}\n\n/** Append the rendered block at EOF with exactly ONE blank separator line. */\nfunction appendBlock(body: string, blockLines: string[], eol: \"\\n\" | \"\\r\\n\"): string {\n const blockText = blockLines.join(eol) + eol;\n if (body.trim() === \"\") return blockText;\n return trimTrailingBlank(body) + eol + eol + blockText;\n}\n\n/**\n * Idempotent upsert of one managed block into `raw` (pure; no I/O).\n * See the module header for the full algorithm contract.\n */\nexport function upsertBlockInText(raw: string, opts: UpsertBlockOptions): BlockTextResult {\n const bom = raw.startsWith(\"\\uFEFF\");\n const body = bom ? raw.slice(1) : raw;\n const eol = detectEol(body);\n const lines = body.split(\"\\n\"); // elements keep a trailing \"\\r\" on CRLF files\n const logical = lines.map(stripCr);\n\n const events = scanMarkers(logical).filter((e) => e.blockId === opts.blockId);\n const { pairs, strays } = pairMarkers(events);\n\n const newLines = renderBlockLines(opts);\n const newHash = hashBlockContent(newLines.slice(1, -1).join(\"\\n\"));\n const finish = (text: string, r: Omit<BlockTextResult, \"text\" | \"hash\">): BlockTextResult => ({\n text: bom ? `\\uFEFF${text}` : text,\n hash: newHash,\n ...r,\n });\n\n if (pairs.length > 0) {\n const { begin, end } = pairs[0]!;\n const recorded = begin.hash ?? \"\";\n const actualHash = hashBlockContent(logical.slice(begin.index + 1, end.index).join(\"\\n\"));\n const drifted = actualHash !== recorded;\n\n if (drifted && !opts.force) {\n return finish(body, {\n action: \"warn\",\n detail:\n `block ${opts.blockId} was edited inside the markers ` +\n `(recorded hash ${recorded}, found ${actualHash}); left untouched — ` +\n `re-run with --force to overwrite the in-block edits`,\n changed: false,\n recovered: false,\n });\n }\n\n const duplicates = pairs.slice(1);\n const needsWrite =\n drifted || recorded !== newHash || duplicates.length > 0 || strays.length > 0;\n if (!needsWrite) {\n return finish(body, {\n action: \"skip\",\n detail: `block ${opts.blockId} already up to date (hash ${newHash})`,\n changed: false,\n recovered: false,\n });\n }\n\n // Build the deletion set: the canonical pair region (replaced in place),\n // duplicate pairs (+ ONE adjacent blank line each), and stray marker LINES.\n const del = new Set<number>();\n for (let i = begin.index; i <= end.index; i++) del.add(i);\n for (const dup of duplicates) {\n for (let i = dup.begin.index; i <= dup.end.index; i++) del.add(i);\n reclaimBlankLine(logical, dup.begin.index, dup.end.index, del, lines.length);\n }\n for (const s of strays) del.add(s.index);\n\n const out: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n if (i === begin.index) out.push(...withEol(newLines, eol));\n if (!del.has(i)) out.push(lines[i]!);\n }\n const notes: string[] = [];\n if (drifted) notes.push(\"in-block edits overwritten (--force; backup taken)\");\n if (duplicates.length > 0) notes.push(`${duplicates.length} duplicate pair(s) collapsed`);\n if (strays.length > 0) notes.push(`${strays.length} stray marker line(s) removed`);\n return finish(out.join(\"\\n\"), {\n action: \"update\",\n detail:\n `block ${opts.blockId} updated (hash ${recorded || \"?\"} → ${newHash})` +\n (notes.length > 0 ? `; ${notes.join(\"; \")}` : \"\"),\n changed: true,\n recovered: drifted || duplicates.length > 0 || strays.length > 0,\n });\n }\n\n if (strays.length > 0) {\n // Corruption recovery: strip ONLY the stray marker line(s) (never the text\n // between guessed boundaries), then proceed as not-found.\n const del = new Set(strays.map((s) => s.index));\n const cleaned = lines.filter((_, i) => !del.has(i)).join(\"\\n\");\n return finish(appendBlock(cleaned, newLines, eol), {\n action: \"create\",\n detail:\n `block ${opts.blockId} appended after recovery: ${strays.length} stray ` +\n `marker line(s) removed (backup taken)`,\n changed: true,\n recovered: true,\n });\n }\n\n // Not found → append at EOF (one blank separator; whole file when empty).\n return finish(appendBlock(body, newLines, eol), {\n action: \"create\",\n detail: `block ${opts.blockId} appended (hash ${newHash})`,\n changed: true,\n recovered: false,\n });\n}\n\n/**\n * Mark ONE blank line adjacent to a removed begin..end region for deletion\n * (prefer the line before; never the post-final-newline \"\" sentinel).\n */\nfunction reclaimBlankLine(\n logical: string[],\n beginIdx: number,\n endIdx: number,\n del: Set<number>,\n lineCount: number,\n): void {\n const before = beginIdx - 1;\n if (before >= 0 && !del.has(before) && logical[before]!.trim() === \"\") {\n del.add(before);\n return;\n }\n const after = endIdx + 1;\n // The final \"\" element of split(\"\\n\") on a newline-terminated file is the\n // trailing-newline sentinel, not a blank line — leave it alone.\n const isSentinel = after === lineCount - 1 && logical[after] === \"\";\n if (after < lineCount && !isSentinel && !del.has(after) && logical[after]!.trim() === \"\") {\n del.add(after);\n }\n}\n\nexport interface RemoveBlocksOptions {\n /** Remove the block with EXACTLY this id… */\n blockId?: string;\n /** …or every block whose id starts with this prefix (e.g. `<connectorId>/`). */\n blockIdPrefix?: string;\n}\n\nexport interface RemoveRecord {\n blockId: string;\n action: \"remove\" | \"warn\";\n detail: string;\n}\n\nexport interface RemoveBlocksResult {\n text: string;\n changed: boolean;\n records: RemoveRecord[];\n /** True when the remaining text is whitespace-only (file-deletion candidate). */\n fileNowEmpty: boolean;\n /** True when a drifted block was removed or stray markers were stripped. */\n recovered: boolean;\n}\n\n/**\n * Remove every matching managed block (begin..end inclusive + at most ONE\n * adjacent blank separator line — no blank-line accumulation across cycles).\n * Drifted blocks are removed WITH a warn (uninstall intent is explicit; the\n * file wrapper backs the file up first). Stray matching markers are stripped\n * line-only with a warn. Pure; no I/O.\n */\nexport function removeBlocksFromText(raw: string, match: RemoveBlocksOptions): RemoveBlocksResult {\n const bom = raw.startsWith(\"\\uFEFF\");\n const body = bom ? raw.slice(1) : raw;\n const lines = body.split(\"\\n\");\n const logical = lines.map(stripCr);\n\n const matches = (id: string): boolean =>\n (match.blockId !== undefined && id === match.blockId) ||\n (match.blockIdPrefix !== undefined && id.startsWith(match.blockIdPrefix));\n\n const { pairs, strays } = pairMarkers(scanMarkers(logical));\n const targetPairs = pairs.filter((p) => matches(p.blockId));\n const targetStrays = strays.filter((s) => matches(s.blockId));\n\n if (targetPairs.length === 0 && targetStrays.length === 0) {\n return { text: raw, changed: false, records: [], fileNowEmpty: false, recovered: false };\n }\n\n const del = new Set<number>();\n const records: RemoveRecord[] = [];\n let recovered = false;\n\n for (const p of targetPairs) {\n const recorded = p.begin.hash ?? \"\";\n const actualHash = hashBlockContent(\n logical.slice(p.begin.index + 1, p.end.index).join(\"\\n\"),\n );\n for (let i = p.begin.index; i <= p.end.index; i++) del.add(i);\n reclaimBlankLine(logical, p.begin.index, p.end.index, del, lines.length);\n if (actualHash !== recorded) {\n recovered = true;\n records.push({\n blockId: p.blockId,\n action: \"warn\",\n detail:\n `block ${p.blockId} had in-block edits (recorded hash ${recorded}, found ` +\n `${actualHash}); removed anyway (backup taken)`,\n });\n }\n records.push({ blockId: p.blockId, action: \"remove\", detail: `block ${p.blockId} removed` });\n }\n for (const s of targetStrays) {\n del.add(s.index);\n recovered = true;\n records.push({\n blockId: s.blockId,\n action: \"warn\",\n detail: `stray ${s.kind} marker for ${s.blockId} removed (marker line only)`,\n });\n }\n\n const text = lines.filter((_, i) => !del.has(i)).join(\"\\n\");\n return {\n text: bom ? `\\uFEFF${text}` : text,\n changed: true,\n records,\n fileNowEmpty: text.trim() === \"\",\n recovered,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// File-level wrappers (atomic write, backups, dry-run)\n// ─────────────────────────────────────────────────────────────────────────\n\nexport interface BlockFileChange {\n action: \"create\" | \"update\" | \"skip\" | \"warn\" | \"remove\";\n path: string;\n detail: string;\n /** True when the FILE did not exist and this upsert created it (ledger fact). */\n createdFile: boolean;\n /** Set when a pre-mutation backup was written (destructive/recovery paths only). */\n backupPath?: string;\n /** Hash of the rendered inner region (ledger / doctor). */\n hash: string;\n}\n\n/** Timestamped copy into backupsDir(); best-effort (null on failure). */\nfunction backupFile(path: string): string | null {\n try {\n ensureDir(backupsDir());\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const dest = join(backupsDir(), `memory-${stamp}-${basename(path)}`);\n copyFileSync(path, dest);\n return dest;\n } catch {\n return null;\n }\n}\n\n/**\n * Atomic write: temp file in the SAME directory + rename, preserving the\n * destination's mode. Shrinks (does not eliminate) the read-modify-write race\n * with hosts that append to memory files mid-session (Claude `#` quick-memory).\n */\nfunction atomicWriteFile(path: string, text: string): void {\n const dir = dirname(path);\n ensureDir(dir);\n const tmp = join(dir, `.${basename(path)}.ac-tmp-${process.pid}-${Date.now()}`);\n try {\n writeFileSync(tmp, text, \"utf8\");\n try {\n chmodSync(tmp, statSync(path).mode);\n } catch {\n /* destination absent — default mode is fine */\n }\n renameSync(tmp, path);\n } catch (err) {\n rmSync(tmp, { force: true });\n throw err;\n }\n}\n\n/**\n * Upsert one managed block into the file at `path` (created when absent).\n * Re-reads immediately before computing+writing; honors dryRun (the action is\n * computed and reported, nothing is written).\n */\nexport function upsertManagedBlockFile(\n path: string,\n opts: UpsertBlockOptions & { dryRun: boolean },\n): BlockFileChange {\n let raw: string | null = null;\n if (existsSync(path)) {\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return {\n action: \"warn\",\n path,\n detail: `cannot read ${path}; memory block ${opts.blockId} not written`,\n createdFile: false,\n hash: \"\",\n };\n }\n }\n\n if (raw === null) {\n const lines = renderBlockLines(opts);\n const hash = hashBlockContent(lines.slice(1, -1).join(\"\\n\"));\n if (!opts.dryRun) atomicWriteFile(path, `${lines.join(\"\\n\")}\\n`);\n return {\n action: \"create\",\n path,\n detail: `created ${basename(path)} with block ${opts.blockId} (hash ${hash})`,\n createdFile: true,\n hash,\n };\n }\n\n const res = upsertBlockInText(raw, opts);\n const change: BlockFileChange = {\n action: res.action,\n path,\n detail: res.detail,\n createdFile: false,\n hash: res.hash,\n };\n if (res.changed && !opts.dryRun) {\n if (res.recovered) {\n const backup = backupFile(path);\n if (backup) change.backupPath = backup;\n }\n atomicWriteFile(path, res.text);\n }\n return change;\n}\n\n/**\n * Remove every matching managed block from the file at `path`. Missing file or\n * no matching markers → a single idempotent \"skip\". When the remaining content\n * is whitespace-only AND `deleteFileIfCreated` is true (the ledger recorded\n * that agent-connector created this file), the file itself is deleted (Ruler\n * revert semantics: delete only what we created).\n */\nexport function removeManagedBlocksFile(\n path: string,\n match: RemoveBlocksOptions,\n opts: { dryRun: boolean; deleteFileIfCreated?: boolean },\n): BlockFileChange[] {\n if (!existsSync(path)) {\n return [\n {\n action: \"skip\",\n path,\n detail: `${basename(path)} absent; nothing to remove`,\n createdFile: false,\n hash: \"\",\n },\n ];\n }\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return [\n {\n action: \"warn\",\n path,\n detail: `cannot read ${path}; managed blocks left in place`,\n createdFile: false,\n hash: \"\",\n },\n ];\n }\n\n const res = removeBlocksFromText(raw, match);\n if (!res.changed) {\n return [\n {\n action: \"skip\",\n path,\n detail: `no agent-connector blocks matching ${match.blockId ?? match.blockIdPrefix ?? \"?\"} in ${basename(path)}`,\n createdFile: false,\n hash: \"\",\n },\n ];\n }\n\n const changes: BlockFileChange[] = [];\n let backupPath: string | undefined;\n if (!opts.dryRun) {\n if (res.recovered) backupPath = backupFile(path) ?? undefined;\n if (res.fileNowEmpty && opts.deleteFileIfCreated) {\n rmSync(path, { force: true });\n } else {\n atomicWriteFile(path, res.text);\n }\n }\n for (const r of res.records) {\n changes.push({\n action: r.action,\n path,\n detail: r.detail,\n createdFile: false,\n hash: \"\",\n ...(backupPath && r.action === \"warn\" ? { backupPath } : {}),\n });\n }\n if (res.fileNowEmpty && opts.deleteFileIfCreated) {\n changes.push({\n action: \"remove\",\n path,\n detail: `${basename(path)} deleted (agent-connector created it; only whitespace remained)`,\n createdFile: false,\n hash: \"\",\n });\n }\n return changes;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Memory ownership ledger — connectorDir(id)/memory-state.json\n// ─────────────────────────────────────────────────────────────────────────\n\nexport interface MemoryLedgerTarget {\n platform: string;\n scope: string;\n path: string;\n blockId: string;\n /** True when agent-connector CREATED the file (grants deletion rights). */\n createdFile: boolean;\n /** Inner-region hash we last wrote (doctor drift detection). */\n hash: string;\n}\n\nexport interface MemoryLedger {\n version: 1;\n targets: MemoryLedgerTarget[];\n}\n\nexport function memoryLedgerPath(connectorId: string): string {\n return join(connectorDir(connectorId), \"memory-state.json\");\n}\n\nexport function loadMemoryLedger(connectorId: string): MemoryLedger {\n const p = memoryLedgerPath(connectorId);\n if (!existsSync(p)) return { version: 1, targets: [] };\n try {\n const parsed = JSON.parse(readFileSync(p, \"utf8\")) as MemoryLedger;\n if (parsed && Array.isArray(parsed.targets)) return { version: 1, targets: parsed.targets };\n } catch {\n /* corrupt → fresh ledger; the markers remain the source of truth */\n }\n return { version: 1, targets: [] };\n}\n\n/** Persist the ledger; an EMPTY ledger deletes the file (no orphan state). */\nexport function saveMemoryLedger(connectorId: string, ledger: MemoryLedger): void {\n const p = memoryLedgerPath(connectorId);\n assertNoSymlinkInPath(p);\n if (ledger.targets.length === 0) {\n rmSync(p, { force: true });\n return;\n }\n ensureDir(dirname(p));\n writeFileSync(p, `${JSON.stringify(ledger, null, 2)}\\n`, \"utf8\");\n}\n\n/** True when the connector has any recorded memory targets (uninstall guard). */\nexport function hasMemoryLedger(connectorId: string): boolean {\n return loadMemoryLedger(connectorId).targets.length > 0;\n}\n\n/**\n * Upsert one ledger row (keyed by platform+scope+path+blockId). The\n * `createdFile` fact is STICKY: once we created the file, deletion rights\n * survive later syncs that found it present.\n */\nexport function recordMemoryTarget(ledger: MemoryLedger, t: MemoryLedgerTarget): void {\n const i = ledger.targets.findIndex(\n (x) =>\n x.platform === t.platform &&\n x.scope === t.scope &&\n x.path === t.path &&\n x.blockId === t.blockId,\n );\n if (i >= 0) {\n ledger.targets[i] = { ...t, createdFile: ledger.targets[i]!.createdFile || t.createdFile };\n } else {\n ledger.targets.push(t);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
BaseAdapter,
|
|
10
10
|
renderSkillMd
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
12
12
|
import {
|
|
13
13
|
buildHomeBinHookCommand,
|
|
14
14
|
buildUsageEventCommand,
|
|
@@ -687,4 +687,4 @@ export {
|
|
|
687
687
|
adapter,
|
|
688
688
|
antigravity_default
|
|
689
689
|
};
|
|
690
|
-
//# sourceMappingURL=chunk-
|
|
690
|
+
//# sourceMappingURL=chunk-XC5SJ35F.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ADAPTER_REGISTRY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SILKSP2Y.js";
|
|
5
5
|
|
|
6
6
|
// src/adapters/detect.ts
|
|
7
7
|
async function detectInstalledPlatforms(projectDir) {
|
|
@@ -85,4 +85,4 @@ export {
|
|
|
85
85
|
detectInstalledPlatforms,
|
|
86
86
|
detectRuntimeHost
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=chunk-
|
|
88
|
+
//# sourceMappingURL=chunk-ZMAJ2XFD.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readRegisteredMeta
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-KSPMSRVU.js";
|
|
5
|
+
import "./chunk-KJLFGQQM.js";
|
|
6
|
+
import "./chunk-SILKSP2Y.js";
|
|
7
7
|
import {
|
|
8
8
|
addLedgerOwner,
|
|
9
9
|
configPatchManualEdit,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
renderCommandMd,
|
|
35
35
|
renderSkillMd,
|
|
36
36
|
renderSubagentMd
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
38
38
|
import {
|
|
39
39
|
buildHomeBinStatuslineCommand,
|
|
40
40
|
buildWrappedStdio,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
removeManagedBlocksFile,
|
|
51
51
|
saveMemoryLedger,
|
|
52
52
|
upsertManagedBlockFile
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-UMQ6NBQR.js";
|
|
54
54
|
import {
|
|
55
55
|
backupsDir,
|
|
56
56
|
ensureDir
|
|
@@ -1493,4 +1493,4 @@ export {
|
|
|
1493
1493
|
claudeSensitiveKeyViolation,
|
|
1494
1494
|
claude_code_default as default
|
|
1495
1495
|
};
|
|
1496
|
-
//# sourceMappingURL=claude-code-
|
|
1496
|
+
//# sourceMappingURL=claude-code-DUZNOAS2.js.map
|
package/dist/cli/sdk.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { URL } from 'node:url';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* cli/sdk — the EMBEDDED SDK entry point for a developer-branded CLI.
|
|
3
5
|
*
|
|
@@ -7,13 +9,11 @@
|
|
|
7
9
|
* delegated and AUTO-SCOPED to the developer's connector:
|
|
8
10
|
*
|
|
9
11
|
* #!/usr/bin/env node
|
|
10
|
-
* import { fileURLToPath } from "node:url";
|
|
11
12
|
* import { createConnectorCli } from "@ken-jo/agent-connector/cli";
|
|
12
13
|
* createConnectorCli({
|
|
13
|
-
*
|
|
14
|
-
* connector:
|
|
14
|
+
* packageJson: new URL("./package.json", import.meta.url),
|
|
15
|
+
* connector: new URL("./agent-connector.config.mjs", import.meta.url),
|
|
15
16
|
* }).run();
|
|
16
|
-
* // fileURLToPath, NOT URL.pathname — .pathname yields "/C:/…" on Windows.
|
|
17
17
|
*
|
|
18
18
|
* Then a consumer runs `acme-db install`, `acme-db leaderboard`, `acme-db
|
|
19
19
|
* telemetry`, `acme-db doctor`, etc. — and each one targets the developer's
|
|
@@ -21,28 +21,69 @@
|
|
|
21
21
|
*
|
|
22
22
|
* This module is PURE ARGUMENT TRANSFORMATION: it injects the right --connector
|
|
23
23
|
* (path) or --connector <id> filter when the user did not supply one, then hands
|
|
24
|
-
* off to {@link main} with the developer's program name. It never
|
|
25
|
-
* command logic — every behavior still lives in the command
|
|
24
|
+
* off to {@link main} with the developer's program name/version. It never
|
|
25
|
+
* duplicates any command logic — every behavior still lives in the command
|
|
26
|
+
* modules.
|
|
26
27
|
*/
|
|
28
|
+
|
|
29
|
+
type ConnectorCliPath = string | URL;
|
|
30
|
+
interface ConnectorCliContext {
|
|
31
|
+
/** Resolved brand/bin name shown in usage, errors, and --version output. */
|
|
32
|
+
programName: string;
|
|
33
|
+
/** Resolved branded package version shown by --version. */
|
|
34
|
+
programVersion: string;
|
|
35
|
+
/** Absolute connector config path injected into connector-targeted commands. */
|
|
36
|
+
connector: string;
|
|
37
|
+
/** Lazily resolves the connector id for telemetry/serve/hook scoping. */
|
|
38
|
+
connectorId(): Promise<string>;
|
|
39
|
+
}
|
|
40
|
+
interface ConnectorCliPassthrough {
|
|
41
|
+
/**
|
|
42
|
+
* Return true when this invocation should be handled by custom package logic
|
|
43
|
+
* instead of the agent-connector command dispatcher.
|
|
44
|
+
*/
|
|
45
|
+
when(argv: readonly string[], context: ConnectorCliContext): boolean;
|
|
46
|
+
/** Handle a matched invocation. Return the process exit code. */
|
|
47
|
+
run(argv: readonly string[], context: ConnectorCliContext): number | Promise<number>;
|
|
48
|
+
}
|
|
27
49
|
/** Options for {@link createConnectorCli}. */
|
|
28
50
|
interface CreateConnectorCliOptions {
|
|
29
|
-
/** The developer's bin/brand name (shown in usage/help, e.g. "acme-db"). */
|
|
30
|
-
name: string;
|
|
31
51
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
52
|
+
* The developer's bin/brand name (shown in usage/help, e.g. "acme-db").
|
|
53
|
+
* Prefer `packageJson` for packaged connectors so name/version stay in one
|
|
54
|
+
* source of truth; this remains available for custom launchers and tests.
|
|
55
|
+
*/
|
|
56
|
+
name?: string;
|
|
57
|
+
/**
|
|
58
|
+
* package.json for the branded connector package. When supplied, the CLI
|
|
59
|
+
* derives the bin name and version from package metadata.
|
|
60
|
+
*/
|
|
61
|
+
packageJson?: ConnectorCliPath;
|
|
62
|
+
/**
|
|
63
|
+
* Absolute path or file URL to the developer's connector config (.mjs / .js /
|
|
64
|
+
* .json) that ships inside their package. Injected as `--connector <path>` for
|
|
34
65
|
* connector-targeted subcommands when the user did not pass one.
|
|
35
66
|
*/
|
|
36
|
-
connector:
|
|
67
|
+
connector: ConnectorCliPath;
|
|
37
68
|
/**
|
|
38
69
|
* The connector id used for the telemetry/leaderboard FILTER injection. When
|
|
39
70
|
* omitted it is derived lazily by loading the connector config the first time a
|
|
40
71
|
* telemetry/leaderboard subcommand runs.
|
|
41
72
|
*/
|
|
42
73
|
connectorId?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Package-specific command escapes that should run before agent-connector's
|
|
76
|
+
* dispatcher. Use sparingly for legacy/runtime commands that intentionally
|
|
77
|
+
* live outside the universal connector surface.
|
|
78
|
+
*/
|
|
79
|
+
passthrough?: readonly ConnectorCliPassthrough[];
|
|
43
80
|
}
|
|
44
81
|
/** The runner returned by {@link createConnectorCli}. */
|
|
45
82
|
interface ConnectorCli {
|
|
83
|
+
/** Resolved brand/bin name. */
|
|
84
|
+
name: string;
|
|
85
|
+
/** Resolved branded package version. */
|
|
86
|
+
version: string;
|
|
46
87
|
/**
|
|
47
88
|
* Run a branded invocation. `argv` defaults to `process.argv.slice(2)`.
|
|
48
89
|
* Resolves to the process exit code (0 success, non-zero failure).
|
|
@@ -51,4 +92,4 @@ interface ConnectorCli {
|
|
|
51
92
|
}
|
|
52
93
|
declare function createConnectorCli(opts: CreateConnectorCliOptions): ConnectorCli;
|
|
53
94
|
|
|
54
|
-
export { type ConnectorCli, type CreateConnectorCliOptions, createConnectorCli };
|
|
95
|
+
export { type ConnectorCli, type ConnectorCliContext, type ConnectorCliPassthrough, type ConnectorCliPath, type CreateConnectorCliOptions, createConnectorCli };
|
package/dist/cli/sdk.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
main
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-TQRLMA2C.js";
|
|
5
5
|
import {
|
|
6
6
|
loadConnectorFromPath
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-KSPMSRVU.js";
|
|
8
|
+
import "../chunk-KJLFGQQM.js";
|
|
9
|
+
import "../chunk-SILKSP2Y.js";
|
|
10
10
|
import "../chunk-NBYKLUF6.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-UMQ6NBQR.js";
|
|
12
12
|
import "../chunk-GZGLCCEE.js";
|
|
13
13
|
|
|
14
14
|
// src/cli/sdk.ts
|
|
15
|
+
import { readFileSync, realpathSync } from "fs";
|
|
16
|
+
import { dirname, resolve } from "path";
|
|
17
|
+
import { fileURLToPath, URL } from "url";
|
|
15
18
|
var CONFIG_PATH_COMMANDS = /* @__PURE__ */ new Set([
|
|
16
19
|
"install",
|
|
17
20
|
"uninstall",
|
|
@@ -44,29 +47,91 @@ function injectAfterCommand(argv, flag, value) {
|
|
|
44
47
|
function appendFlag(argv, flag, value) {
|
|
45
48
|
return [...argv, flag, value];
|
|
46
49
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
function cleanString(value) {
|
|
51
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
52
|
+
}
|
|
53
|
+
function pathFrom(value, label) {
|
|
54
|
+
if (value instanceof URL) return fileURLToPath(value);
|
|
55
|
+
if (typeof value === "string" && value.trim() !== "") return value;
|
|
56
|
+
throw new TypeError(`createConnectorCli: \`${label}\` must be a non-empty path or file URL`);
|
|
57
|
+
}
|
|
58
|
+
function normalizeBinTarget(target) {
|
|
59
|
+
return target.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
60
|
+
}
|
|
61
|
+
function realPathIfExists(path) {
|
|
62
|
+
try {
|
|
63
|
+
return realpathSync(path);
|
|
64
|
+
} catch {
|
|
65
|
+
return void 0;
|
|
50
66
|
}
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
}
|
|
68
|
+
function packageNameToBinName(packageName) {
|
|
69
|
+
if (!packageName) return void 0;
|
|
70
|
+
if (packageName.startsWith("@")) return cleanString(packageName.split("/")[1]);
|
|
71
|
+
return cleanString(packageName);
|
|
72
|
+
}
|
|
73
|
+
function readPackageCliMetadata(packageJsonPath) {
|
|
74
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
75
|
+
const packageName = cleanString(parsed.name);
|
|
76
|
+
const version = cleanString(parsed.version);
|
|
77
|
+
const packageBinName = packageNameToBinName(packageName);
|
|
78
|
+
let name;
|
|
79
|
+
if (typeof parsed.bin === "string") {
|
|
80
|
+
name = packageBinName;
|
|
81
|
+
} else if (parsed.bin && typeof parsed.bin === "object" && !Array.isArray(parsed.bin)) {
|
|
82
|
+
const entries = Object.entries(parsed.bin).filter(
|
|
83
|
+
(entry) => cleanString(entry[0]) != null && typeof entry[1] === "string"
|
|
84
|
+
).map(([binName, target]) => [binName, normalizeBinTarget(target)]);
|
|
85
|
+
const packageDir = dirname(packageJsonPath);
|
|
86
|
+
const invokedPath = process.argv[1] ? resolve(process.argv[1]) : void 0;
|
|
87
|
+
const invoked = invokedPath ? realPathIfExists(invokedPath) ?? invokedPath : void 0;
|
|
88
|
+
name = (invoked ? entries.find(([, target]) => {
|
|
89
|
+
const targetPath = resolve(packageDir, target);
|
|
90
|
+
return (realPathIfExists(targetPath) ?? targetPath) === invoked;
|
|
91
|
+
})?.[0] : void 0) ?? (packageBinName ? entries.find(([binName]) => binName === packageBinName)?.[0] : void 0) ?? (entries.length === 1 ? entries[0]?.[0] : void 0);
|
|
53
92
|
}
|
|
93
|
+
return { ...name ? { name } : {}, ...version ? { version } : {} };
|
|
94
|
+
}
|
|
95
|
+
function createConnectorCli(opts) {
|
|
96
|
+
const packageJsonPath = opts.packageJson ? pathFrom(opts.packageJson, "packageJson") : void 0;
|
|
97
|
+
const packageMetadata = packageJsonPath ? readPackageCliMetadata(packageJsonPath) : {};
|
|
98
|
+
const name = cleanString(opts.name) ?? packageMetadata.name;
|
|
99
|
+
const version = packageMetadata.version;
|
|
100
|
+
if (!name) {
|
|
101
|
+
throw new TypeError("createConnectorCli: `name` or packageJson-derived bin name is required");
|
|
102
|
+
}
|
|
103
|
+
const programName = name;
|
|
104
|
+
const connectorPath = pathFrom(opts.connector, "connector");
|
|
54
105
|
let cachedId = opts.connectorId;
|
|
55
106
|
async function resolveConnectorId() {
|
|
56
107
|
if (cachedId !== void 0 && cachedId !== "") return cachedId;
|
|
57
|
-
const { connector } = await loadConnectorFromPath(
|
|
108
|
+
const { connector } = await loadConnectorFromPath(connectorPath);
|
|
58
109
|
cachedId = connector.id;
|
|
59
110
|
return cachedId;
|
|
60
111
|
}
|
|
61
112
|
async function run(argv = process.argv.slice(2)) {
|
|
113
|
+
const context = {
|
|
114
|
+
programName,
|
|
115
|
+
programVersion: version ?? "0.0.0",
|
|
116
|
+
connector: connectorPath,
|
|
117
|
+
connectorId: resolveConnectorId
|
|
118
|
+
};
|
|
119
|
+
for (const passthrough of opts.passthrough ?? []) {
|
|
120
|
+
if (passthrough.when(argv, context)) {
|
|
121
|
+
return passthrough.run(argv, context);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
62
124
|
const command = argv[0];
|
|
63
125
|
if (command === void 0 || command.startsWith("-")) {
|
|
64
|
-
return main(
|
|
126
|
+
return main(
|
|
127
|
+
argv,
|
|
128
|
+
version ? { programName, programVersion: version } : { programName }
|
|
129
|
+
);
|
|
65
130
|
}
|
|
66
131
|
let scoped = argv;
|
|
67
132
|
if (!hasConnectorFlag(argv)) {
|
|
68
133
|
if (CONFIG_PATH_COMMANDS.has(command)) {
|
|
69
|
-
scoped = injectAfterCommand(argv, "--connector",
|
|
134
|
+
scoped = injectAfterCommand(argv, "--connector", connectorPath);
|
|
70
135
|
} else if (ID_HEAD_COMMANDS.has(command)) {
|
|
71
136
|
const id = await resolveConnectorId();
|
|
72
137
|
scoped = injectAfterCommand(argv, "--connector", id);
|
|
@@ -75,9 +140,12 @@ function createConnectorCli(opts) {
|
|
|
75
140
|
scoped = appendFlag(argv, "--connector", id);
|
|
76
141
|
}
|
|
77
142
|
}
|
|
78
|
-
return main(
|
|
143
|
+
return main(
|
|
144
|
+
scoped,
|
|
145
|
+
version ? { programName, programVersion: version } : { programName }
|
|
146
|
+
);
|
|
79
147
|
}
|
|
80
|
-
return { run };
|
|
148
|
+
return { name: programName, version: version ?? "0.0.0", run };
|
|
81
149
|
}
|
|
82
150
|
export {
|
|
83
151
|
createConnectorCli
|
package/dist/cli/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/sdk.ts"],"sourcesContent":["/**\n * cli/sdk — the EMBEDDED SDK entry point for a developer-branded CLI.\n *\n * A developer adds agent-connector as a dependency, writes their connector\n * config, and ships their OWN bin. `createConnectorCli` returns a runner that\n * exposes EVERY agent-connector subcommand under the developer's brand, fully\n * delegated and AUTO-SCOPED to the developer's connector:\n *\n * #!/usr/bin/env node\n * import { fileURLToPath } from \"node:url\";\n * import { createConnectorCli } from \"@ken-jo/agent-connector/cli\";\n * createConnectorCli({\n * name: \"acme-db\",\n * connector: fileURLToPath(new URL(\"./agent-connector.config.mjs\", import.meta.url)),\n * }).run();\n * // fileURLToPath, NOT URL.pathname — .pathname yields \"/C:/…\" on Windows.\n *\n * Then a consumer runs `acme-db install`, `acme-db leaderboard`, `acme-db\n * telemetry`, `acme-db doctor`, etc. — and each one targets the developer's\n * connector WITHOUT the consumer having to pass --connector.\n *\n * This module is PURE ARGUMENT TRANSFORMATION: it injects the right --connector\n * (path) or --connector <id> filter when the user did not supply one, then hands\n * off to {@link main} with the developer's program name. It never duplicates any\n * command logic — every behavior still lives in the command modules.\n */\n\nimport { loadConnectorFromPath } from \"../core/load-connector.js\";\nimport { main } from \"./app.js\";\n\n/** Options for {@link createConnectorCli}. */\nexport interface CreateConnectorCliOptions {\n /** The developer's bin/brand name (shown in usage/help, e.g. \"acme-db\"). */\n name: string;\n /**\n * Absolute path to the developer's connector config (.mjs / .js / .json) that\n * ships inside their package. Injected as `--connector <path>` for the\n * connector-targeted subcommands when the user did not pass one.\n */\n connector: string;\n /**\n * The connector id used for the telemetry/leaderboard FILTER injection. When\n * omitted it is derived lazily by loading the connector config the first time a\n * telemetry/leaderboard subcommand runs.\n */\n connectorId?: string;\n}\n\n/** The runner returned by {@link createConnectorCli}. */\nexport interface ConnectorCli {\n /**\n * Run a branded invocation. `argv` defaults to `process.argv.slice(2)`.\n * Resolves to the process exit code (0 success, non-zero failure).\n */\n run(argv?: string[]): Promise<number>;\n}\n\n/**\n * Connector-targeted subcommands whose `--connector` is a CONFIG PATH: they load\n * the connector definition from disk. For these we inject the developer's config\n * PATH so their connector is the implicit target.\n *\n * (`uninstall` also accepts `--connector-id`; injecting the path is sufficient —\n * uninstall derives the id from the config when no explicit id is given.)\n */\nconst CONFIG_PATH_COMMANDS: ReadonlySet<string> = new Set([\n \"install\",\n \"uninstall\",\n \"upgrade\",\n // `sync` + `update` are back-compat aliases of `upgrade`; scope them too so a\n // branded `acme-db sync` / `acme-db update` still targets the dev connector.\n \"sync\",\n \"update\",\n \"doctor\",\n \"status\",\n \"package\",\n]);\n\n/**\n * Connector-targeted subcommands whose `--connector` is the registered connector\n * ID, spliced right AFTER the subcommand token: `serve` and `hook` pass it\n * straight to the runtime. (They cannot take a trailing flag — serve has a `--`\n * separator and hook has positionals — so the flag must lead.)\n */\nconst ID_HEAD_COMMANDS: ReadonlySet<string> = new Set([\"serve\", \"hook\"]);\n\n/**\n * View subcommands where `--connector <id>` is a FILTER appended at the END:\n * `leaderboard` (top-level) and `telemetry` (whose own sub — report|export|\n * leaderboard — is the leading positional, so the filter must come after it).\n * Appending keeps that leading positional intact while parseArgs still reads the\n * flag, so the branded tool shows ITS connector's data.\n *\n * Note: `usage` reads host CLI logs which carry no connector attribution, so it\n * is intentionally absent — there is nothing to scope it to.\n */\nconst ID_TAIL_COMMANDS: ReadonlySet<string> = new Set([\"telemetry\", \"leaderboard\"]);\n\n/**\n * Should the tail (telemetry/leaderboard) filter injection be SKIPPED because the\n * invocation is just asking for help / has no actionable sub? Skipping leaves the\n * branded usage text intact instead of turning `acme-db telemetry` into\n * `telemetry --connector <id>` (which the telemetry dispatcher would reject as an\n * unknown sub). True when a help flag appears, or when `telemetry` has no sub.\n */\nfunction wantsHelp(argv: string[]): boolean {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) return true;\n // `telemetry` with no sub-subcommand → show its help, don't inject a filter.\n if (argv[0] === \"telemetry\" && argv[1] === undefined) return true;\n return false;\n}\n\n/** Did the user already pass a --connector / --connector-id flag (any form)? */\nfunction hasConnectorFlag(argv: string[]): boolean {\n for (const a of argv) {\n if (a === \"--connector\" || a === \"--connector-id\") return true;\n if (a.startsWith(\"--connector=\") || a.startsWith(\"--connector-id=\")) return true;\n }\n return false;\n}\n\n/**\n * Splice `--connector <value>` immediately after the subcommand token (argv[0])\n * so it sits BEFORE any positionals or a `serve` `--` separator. Used for the\n * config-path commands and for serve/hook (whose `--` / positional grammar makes\n * trailing append unsafe). The original argv is never mutated.\n */\nfunction injectAfterCommand(argv: string[], flag: string, value: string): string[] {\n return [argv[0] as string, flag, value, ...argv.slice(1)];\n}\n\n/**\n * Append `--connector <value>` to the END of argv. Used for the view commands\n * (`leaderboard`/`telemetry`) whose leading positional sub must be preserved.\n * The original argv is never mutated.\n */\nfunction appendFlag(argv: string[], flag: string, value: string): string[] {\n return [...argv, flag, value];\n}\n\nexport function createConnectorCli(opts: CreateConnectorCliOptions): ConnectorCli {\n if (typeof opts.name !== \"string\" || opts.name.trim() === \"\") {\n throw new TypeError(\"createConnectorCli: `name` must be a non-empty string\");\n }\n if (typeof opts.connector !== \"string\" || opts.connector.trim() === \"\") {\n throw new TypeError(\"createConnectorCli: `connector` must be a non-empty path\");\n }\n\n // Cache the derived id so the connector module is loaded at most once across\n // repeated `.run()` calls in the same process.\n let cachedId: string | undefined = opts.connectorId;\n\n async function resolveConnectorId(): Promise<string> {\n if (cachedId !== undefined && cachedId !== \"\") return cachedId;\n const { connector } = await loadConnectorFromPath(opts.connector);\n cachedId = connector.id;\n return cachedId;\n }\n\n async function run(argv: string[] = process.argv.slice(2)): Promise<number> {\n const command = argv[0];\n\n // No subcommand, a help/version flag, or an unknown command: nothing to scope\n // — hand off verbatim so usage/version is branded and errors stay accurate.\n if (command === undefined || command.startsWith(\"-\")) {\n return main(argv, { programName: opts.name });\n }\n\n let scoped = argv;\n\n if (!hasConnectorFlag(argv)) {\n if (CONFIG_PATH_COMMANDS.has(command)) {\n // Inject the connector CONFIG PATH as the implicit target.\n scoped = injectAfterCommand(argv, \"--connector\", opts.connector);\n } else if (ID_HEAD_COMMANDS.has(command)) {\n // serve/hook take the connector ID and pass it to the runtime. Splice it\n // right after the subcommand token so a serve `--` separator and hook's\n // positionals are preserved.\n const id = await resolveConnectorId();\n scoped = injectAfterCommand(argv, \"--connector\", id);\n } else if (ID_TAIL_COMMANDS.has(command) && !wantsHelp(argv)) {\n // leaderboard/telemetry use the connector ID as a FILTER. Append it so\n // telemetry's leading positional sub (report|export|leaderboard) stays\n // the first token while parseArgs still reads the flag. We skip injection\n // for a bare/help invocation so the (un-filtered) usage text still shows.\n const id = await resolveConnectorId();\n scoped = appendFlag(argv, \"--connector\", id);\n }\n }\n\n return main(scoped, { programName: opts.name });\n }\n\n return { run };\n}\n"],"mappings":";;;;;;;;;;;;;;AAiEA,IAAM,uBAA4C,oBAAI,IAAI;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQD,IAAM,mBAAwC,oBAAI,IAAI,CAAC,SAAS,MAAM,CAAC;AAYvE,IAAM,mBAAwC,oBAAI,IAAI,CAAC,aAAa,aAAa,CAAC;AASlF,SAAS,UAAU,MAAyB;AAC1C,MAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,EAAG,QAAO;AAE3D,MAAI,KAAK,CAAC,MAAM,eAAe,KAAK,CAAC,MAAM,OAAW,QAAO;AAC7D,SAAO;AACT;AAGA,SAAS,iBAAiB,MAAyB;AACjD,aAAW,KAAK,MAAM;AACpB,QAAI,MAAM,iBAAiB,MAAM,iBAAkB,QAAO;AAC1D,QAAI,EAAE,WAAW,cAAc,KAAK,EAAE,WAAW,iBAAiB,EAAG,QAAO;AAAA,EAC9E;AACA,SAAO;AACT;AAQA,SAAS,mBAAmB,MAAgB,MAAc,OAAyB;AACjF,SAAO,CAAC,KAAK,CAAC,GAAa,MAAM,OAAO,GAAG,KAAK,MAAM,CAAC,CAAC;AAC1D;AAOA,SAAS,WAAW,MAAgB,MAAc,OAAyB;AACzE,SAAO,CAAC,GAAG,MAAM,MAAM,KAAK;AAC9B;AAEO,SAAS,mBAAmB,MAA+C;AAChF,MAAI,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,MAAM,IAAI;AAC5D,UAAM,IAAI,UAAU,uDAAuD;AAAA,EAC7E;AACA,MAAI,OAAO,KAAK,cAAc,YAAY,KAAK,UAAU,KAAK,MAAM,IAAI;AACtE,UAAM,IAAI,UAAU,0DAA0D;AAAA,EAChF;AAIA,MAAI,WAA+B,KAAK;AAExC,iBAAe,qBAAsC;AACnD,QAAI,aAAa,UAAa,aAAa,GAAI,QAAO;AACtD,UAAM,EAAE,UAAU,IAAI,MAAM,sBAAsB,KAAK,SAAS;AAChE,eAAW,UAAU;AACrB,WAAO;AAAA,EACT;AAEA,iBAAe,IAAI,OAAiB,QAAQ,KAAK,MAAM,CAAC,GAAoB;AAC1E,UAAM,UAAU,KAAK,CAAC;AAItB,QAAI,YAAY,UAAa,QAAQ,WAAW,GAAG,GAAG;AACpD,aAAO,KAAK,MAAM,EAAE,aAAa,KAAK,KAAK,CAAC;AAAA,IAC9C;AAEA,QAAI,SAAS;AAEb,QAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B,UAAI,qBAAqB,IAAI,OAAO,GAAG;AAErC,iBAAS,mBAAmB,MAAM,eAAe,KAAK,SAAS;AAAA,MACjE,WAAW,iBAAiB,IAAI,OAAO,GAAG;AAIxC,cAAM,KAAK,MAAM,mBAAmB;AACpC,iBAAS,mBAAmB,MAAM,eAAe,EAAE;AAAA,MACrD,WAAW,iBAAiB,IAAI,OAAO,KAAK,CAAC,UAAU,IAAI,GAAG;AAK5D,cAAM,KAAK,MAAM,mBAAmB;AACpC,iBAAS,WAAW,MAAM,eAAe,EAAE;AAAA,MAC7C;AAAA,IACF;AAEA,WAAO,KAAK,QAAQ,EAAE,aAAa,KAAK,KAAK,CAAC;AAAA,EAChD;AAEA,SAAO,EAAE,IAAI;AACf;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/sdk.ts"],"sourcesContent":["/**\n * cli/sdk — the EMBEDDED SDK entry point for a developer-branded CLI.\n *\n * A developer adds agent-connector as a dependency, writes their connector\n * config, and ships their OWN bin. `createConnectorCli` returns a runner that\n * exposes EVERY agent-connector subcommand under the developer's brand, fully\n * delegated and AUTO-SCOPED to the developer's connector:\n *\n * #!/usr/bin/env node\n * import { createConnectorCli } from \"@ken-jo/agent-connector/cli\";\n * createConnectorCli({\n * packageJson: new URL(\"./package.json\", import.meta.url),\n * connector: new URL(\"./agent-connector.config.mjs\", import.meta.url),\n * }).run();\n *\n * Then a consumer runs `acme-db install`, `acme-db leaderboard`, `acme-db\n * telemetry`, `acme-db doctor`, etc. — and each one targets the developer's\n * connector WITHOUT the consumer having to pass --connector.\n *\n * This module is PURE ARGUMENT TRANSFORMATION: it injects the right --connector\n * (path) or --connector <id> filter when the user did not supply one, then hands\n * off to {@link main} with the developer's program name/version. It never\n * duplicates any command logic — every behavior still lives in the command\n * modules.\n */\n\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\n\nimport { loadConnectorFromPath } from \"../core/load-connector.js\";\nimport { main } from \"./app.js\";\n\nexport type ConnectorCliPath = string | URL;\n\nexport interface ConnectorCliContext {\n /** Resolved brand/bin name shown in usage, errors, and --version output. */\n programName: string;\n /** Resolved branded package version shown by --version. */\n programVersion: string;\n /** Absolute connector config path injected into connector-targeted commands. */\n connector: string;\n /** Lazily resolves the connector id for telemetry/serve/hook scoping. */\n connectorId(): Promise<string>;\n}\n\nexport interface ConnectorCliPassthrough {\n /**\n * Return true when this invocation should be handled by custom package logic\n * instead of the agent-connector command dispatcher.\n */\n when(argv: readonly string[], context: ConnectorCliContext): boolean;\n /** Handle a matched invocation. Return the process exit code. */\n run(\n argv: readonly string[],\n context: ConnectorCliContext,\n ): number | Promise<number>;\n}\n\n/** Options for {@link createConnectorCli}. */\nexport interface CreateConnectorCliOptions {\n /**\n * The developer's bin/brand name (shown in usage/help, e.g. \"acme-db\").\n * Prefer `packageJson` for packaged connectors so name/version stay in one\n * source of truth; this remains available for custom launchers and tests.\n */\n name?: string;\n /**\n * package.json for the branded connector package. When supplied, the CLI\n * derives the bin name and version from package metadata.\n */\n packageJson?: ConnectorCliPath;\n /**\n * Absolute path or file URL to the developer's connector config (.mjs / .js /\n * .json) that ships inside their package. Injected as `--connector <path>` for\n * connector-targeted subcommands when the user did not pass one.\n */\n connector: ConnectorCliPath;\n /**\n * The connector id used for the telemetry/leaderboard FILTER injection. When\n * omitted it is derived lazily by loading the connector config the first time a\n * telemetry/leaderboard subcommand runs.\n */\n connectorId?: string;\n /**\n * Package-specific command escapes that should run before agent-connector's\n * dispatcher. Use sparingly for legacy/runtime commands that intentionally\n * live outside the universal connector surface.\n */\n passthrough?: readonly ConnectorCliPassthrough[];\n}\n\n/** The runner returned by {@link createConnectorCli}. */\nexport interface ConnectorCli {\n /** Resolved brand/bin name. */\n name: string;\n /** Resolved branded package version. */\n version: string;\n /**\n * Run a branded invocation. `argv` defaults to `process.argv.slice(2)`.\n * Resolves to the process exit code (0 success, non-zero failure).\n */\n run(argv?: string[]): Promise<number>;\n}\n\n/**\n * Connector-targeted subcommands whose `--connector` is a CONFIG PATH: they load\n * the connector definition from disk. For these we inject the developer's config\n * PATH so their connector is the implicit target.\n *\n * (`uninstall` also accepts `--connector-id`; injecting the path is sufficient —\n * uninstall derives the id from the config when no explicit id is given.)\n */\nconst CONFIG_PATH_COMMANDS: ReadonlySet<string> = new Set([\n \"install\",\n \"uninstall\",\n \"upgrade\",\n // `sync` + `update` are back-compat aliases of `upgrade`; scope them too so a\n // branded `acme-db sync` / `acme-db update` still targets the dev connector.\n \"sync\",\n \"update\",\n \"doctor\",\n \"status\",\n \"package\",\n]);\n\n/**\n * Connector-targeted subcommands whose `--connector` is the registered connector\n * ID, spliced right AFTER the subcommand token: `serve` and `hook` pass it\n * straight to the runtime. (They cannot take a trailing flag — serve has a `--`\n * separator and hook has positionals — so the flag must lead.)\n */\nconst ID_HEAD_COMMANDS: ReadonlySet<string> = new Set([\"serve\", \"hook\"]);\n\n/**\n * View subcommands where `--connector <id>` is a FILTER appended at the END:\n * `leaderboard` (top-level) and `telemetry` (whose own sub — report|export|\n * leaderboard — is the leading positional, so the filter must come after it).\n * Appending keeps that leading positional intact while parseArgs still reads the\n * flag, so the branded tool shows ITS connector's data.\n *\n * Note: `usage` reads host CLI logs which carry no connector attribution, so it\n * is intentionally absent — there is nothing to scope it to.\n */\nconst ID_TAIL_COMMANDS: ReadonlySet<string> = new Set([\"telemetry\", \"leaderboard\"]);\n\n/**\n * Should the tail (telemetry/leaderboard) filter injection be SKIPPED because the\n * invocation is just asking for help / has no actionable sub? Skipping leaves the\n * branded usage text intact instead of turning `acme-db telemetry` into\n * `telemetry --connector <id>` (which the telemetry dispatcher would reject as an\n * unknown sub). True when a help flag appears, or when `telemetry` has no sub.\n */\nfunction wantsHelp(argv: string[]): boolean {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) return true;\n // `telemetry` with no sub-subcommand → show its help, don't inject a filter.\n if (argv[0] === \"telemetry\" && argv[1] === undefined) return true;\n return false;\n}\n\n/** Did the user already pass a --connector / --connector-id flag (any form)? */\nfunction hasConnectorFlag(argv: string[]): boolean {\n for (const a of argv) {\n if (a === \"--connector\" || a === \"--connector-id\") return true;\n if (a.startsWith(\"--connector=\") || a.startsWith(\"--connector-id=\")) return true;\n }\n return false;\n}\n\n/**\n * Splice `--connector <value>` immediately after the subcommand token (argv[0])\n * so it sits BEFORE any positionals or a `serve` `--` separator. Used for the\n * config-path commands and for serve/hook (whose `--` / positional grammar makes\n * trailing append unsafe). The original argv is never mutated.\n */\nfunction injectAfterCommand(argv: string[], flag: string, value: string): string[] {\n return [argv[0] as string, flag, value, ...argv.slice(1)];\n}\n\n/**\n * Append `--connector <value>` to the END of argv. Used for the view commands\n * (`leaderboard`/`telemetry`) whose leading positional sub must be preserved.\n * The original argv is never mutated.\n */\nfunction appendFlag(argv: string[], flag: string, value: string): string[] {\n return [...argv, flag, value];\n}\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction pathFrom(value: ConnectorCliPath, label: string): string {\n if (value instanceof URL) return fileURLToPath(value);\n if (typeof value === \"string\" && value.trim() !== \"\") return value;\n throw new TypeError(`createConnectorCli: \\`${label}\\` must be a non-empty path or file URL`);\n}\n\nfunction normalizeBinTarget(target: string): string {\n return target.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction realPathIfExists(path: string): string | undefined {\n try {\n return realpathSync(path);\n } catch {\n return undefined;\n }\n}\n\nfunction packageNameToBinName(packageName: string | undefined): string | undefined {\n if (!packageName) return undefined;\n if (packageName.startsWith(\"@\")) return cleanString(packageName.split(\"/\")[1]);\n return cleanString(packageName);\n}\n\nfunction readPackageCliMetadata(packageJsonPath: string): {\n name?: string;\n version?: string;\n} {\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n name?: unknown;\n version?: unknown;\n bin?: unknown;\n };\n const packageName = cleanString(parsed.name);\n const version = cleanString(parsed.version);\n const packageBinName = packageNameToBinName(packageName);\n\n let name: string | undefined;\n if (typeof parsed.bin === \"string\") {\n name = packageBinName;\n } else if (parsed.bin && typeof parsed.bin === \"object\" && !Array.isArray(parsed.bin)) {\n const entries = Object.entries(parsed.bin)\n .filter(\n (entry): entry is [string, string] =>\n cleanString(entry[0]) != null && typeof entry[1] === \"string\",\n )\n .map(([binName, target]) => [binName, normalizeBinTarget(target)] as const);\n const packageDir = dirname(packageJsonPath);\n const invokedPath = process.argv[1] ? resolve(process.argv[1]) : undefined;\n const invoked = invokedPath ? (realPathIfExists(invokedPath) ?? invokedPath) : undefined;\n name =\n (invoked\n ? entries.find(([, target]) => {\n const targetPath = resolve(packageDir, target);\n return (realPathIfExists(targetPath) ?? targetPath) === invoked;\n })?.[0]\n : undefined) ??\n (packageBinName ? entries.find(([binName]) => binName === packageBinName)?.[0] : undefined) ??\n (entries.length === 1 ? entries[0]?.[0] : undefined);\n }\n\n return { ...(name ? { name } : {}), ...(version ? { version } : {}) };\n}\n\nexport function createConnectorCli(opts: CreateConnectorCliOptions): ConnectorCli {\n const packageJsonPath = opts.packageJson ? pathFrom(opts.packageJson, \"packageJson\") : undefined;\n const packageMetadata = packageJsonPath ? readPackageCliMetadata(packageJsonPath) : {};\n const name = cleanString(opts.name) ?? packageMetadata.name;\n const version = packageMetadata.version;\n\n if (!name) {\n throw new TypeError(\"createConnectorCli: `name` or packageJson-derived bin name is required\");\n }\n const programName = name;\n const connectorPath = pathFrom(opts.connector, \"connector\");\n\n // Cache the derived id so the connector module is loaded at most once across\n // repeated `.run()` calls in the same process.\n let cachedId: string | undefined = opts.connectorId;\n\n async function resolveConnectorId(): Promise<string> {\n if (cachedId !== undefined && cachedId !== \"\") return cachedId;\n const { connector } = await loadConnectorFromPath(connectorPath);\n cachedId = connector.id;\n return cachedId;\n }\n\n async function run(argv: string[] = process.argv.slice(2)): Promise<number> {\n const context: ConnectorCliContext = {\n programName,\n programVersion: version ?? \"0.0.0\",\n connector: connectorPath,\n connectorId: resolveConnectorId,\n };\n for (const passthrough of opts.passthrough ?? []) {\n if (passthrough.when(argv, context)) {\n return passthrough.run(argv, context);\n }\n }\n\n const command = argv[0];\n\n // No subcommand, a help/version flag, or an unknown command: nothing to scope\n // — hand off verbatim so usage/version is branded and errors stay accurate.\n if (command === undefined || command.startsWith(\"-\")) {\n return main(\n argv,\n version ? { programName, programVersion: version } : { programName },\n );\n }\n\n let scoped = argv;\n\n if (!hasConnectorFlag(argv)) {\n if (CONFIG_PATH_COMMANDS.has(command)) {\n // Inject the connector CONFIG PATH as the implicit target.\n scoped = injectAfterCommand(argv, \"--connector\", connectorPath);\n } else if (ID_HEAD_COMMANDS.has(command)) {\n // serve/hook take the connector ID and pass it to the runtime. Splice it\n // right after the subcommand token so a serve `--` separator and hook's\n // positionals are preserved.\n const id = await resolveConnectorId();\n scoped = injectAfterCommand(argv, \"--connector\", id);\n } else if (ID_TAIL_COMMANDS.has(command) && !wantsHelp(argv)) {\n // leaderboard/telemetry use the connector ID as a FILTER. Append it so\n // telemetry's leading positional sub (report|export|leaderboard) stays\n // the first token while parseArgs still reads the flag. We skip injection\n // for a bare/help invocation so the (un-filtered) usage text still shows.\n const id = await resolveConnectorId();\n scoped = appendFlag(argv, \"--connector\", id);\n }\n }\n\n return main(\n scoped,\n version ? { programName, programVersion: version } : { programName },\n );\n }\n\n return { name: programName, version: version ?? \"0.0.0\", run };\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
BaseAdapter,
|
|
7
7
|
renderCommandMd,
|
|
8
8
|
renderSkillMd
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
10
10
|
import {
|
|
11
11
|
buildWrappedStdio
|
|
12
12
|
} from "./chunk-4NHXLXSD.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-UMQ6NBQR.js";
|
|
14
14
|
import "./chunk-GZGLCCEE.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/cline/index.ts
|
|
@@ -405,4 +405,4 @@ export {
|
|
|
405
405
|
adapter,
|
|
406
406
|
cline_default as default
|
|
407
407
|
};
|
|
408
|
-
//# sourceMappingURL=cline-
|
|
408
|
+
//# sourceMappingURL=cline-25KW25IN.js.map
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
renderCommandMd,
|
|
14
14
|
renderSkillMd,
|
|
15
15
|
renderSubagentMd
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
17
17
|
import {
|
|
18
18
|
buildWrappedStdio,
|
|
19
19
|
isHomeBinHookCommand
|
|
20
20
|
} from "./chunk-4NHXLXSD.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-UMQ6NBQR.js";
|
|
22
22
|
import "./chunk-GZGLCCEE.js";
|
|
23
23
|
|
|
24
24
|
// src/adapters/codebuddy/index.ts
|
|
@@ -640,4 +640,4 @@ export {
|
|
|
640
640
|
adapter,
|
|
641
641
|
codebuddy_default as default
|
|
642
642
|
};
|
|
643
|
-
//# sourceMappingURL=codebuddy-
|
|
643
|
+
//# sourceMappingURL=codebuddy-ZNYQACMF.js.map
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
BaseAdapter,
|
|
7
7
|
renderSkillMd
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
9
9
|
import {
|
|
10
10
|
buildWrappedStdio
|
|
11
11
|
} from "./chunk-4NHXLXSD.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-UMQ6NBQR.js";
|
|
13
13
|
import "./chunk-GZGLCCEE.js";
|
|
14
14
|
|
|
15
15
|
// src/adapters/codebuff/index.ts
|
|
@@ -417,4 +417,4 @@ export {
|
|
|
417
417
|
adapter,
|
|
418
418
|
codebuff_default as default
|
|
419
419
|
};
|
|
420
|
-
//# sourceMappingURL=codebuff-
|
|
420
|
+
//# sourceMappingURL=codebuff-VR6JUDIY.js.map
|
|
@@ -17,12 +17,12 @@ import {
|
|
|
17
17
|
renderCommandMd,
|
|
18
18
|
renderSkillMd,
|
|
19
19
|
upsertInObjectMap
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
21
21
|
import {
|
|
22
22
|
buildHomeBinHookCommand,
|
|
23
23
|
buildWrappedStdio
|
|
24
24
|
} from "./chunk-4NHXLXSD.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-UMQ6NBQR.js";
|
|
26
26
|
import {
|
|
27
27
|
ensureDir
|
|
28
28
|
} from "./chunk-GZGLCCEE.js";
|
|
@@ -762,4 +762,4 @@ export {
|
|
|
762
762
|
adapter,
|
|
763
763
|
codex_default as default
|
|
764
764
|
};
|
|
765
|
-
//# sourceMappingURL=codex-
|
|
765
|
+
//# sourceMappingURL=codex-CPNKTXG3.js.map
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
} from "./chunk-BEFVJ2OE.js";
|
|
14
14
|
import {
|
|
15
15
|
BaseAdapter
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
17
17
|
import {
|
|
18
18
|
buildHomeBinHookCommand,
|
|
19
19
|
buildWrappedStdio,
|
|
20
20
|
isHomeBinHookCommand
|
|
21
21
|
} from "./chunk-4NHXLXSD.js";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-UMQ6NBQR.js";
|
|
23
23
|
import "./chunk-GZGLCCEE.js";
|
|
24
24
|
|
|
25
25
|
// src/adapters/continue/index.ts
|
|
@@ -769,4 +769,4 @@ export {
|
|
|
769
769
|
adapter,
|
|
770
770
|
continue_default as default
|
|
771
771
|
};
|
|
772
|
-
//# sourceMappingURL=continue-
|
|
772
|
+
//# sourceMappingURL=continue-WU2IB5KS.js.map
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
BaseAdapter,
|
|
10
10
|
renderSkillMd,
|
|
11
11
|
renderSubagentMd
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MGTDQLJJ.js";
|
|
13
13
|
import {
|
|
14
14
|
buildHomeBinHookCommand,
|
|
15
15
|
buildWrappedStdio,
|
|
16
16
|
isHomeBinHookCommand
|
|
17
17
|
} from "./chunk-4NHXLXSD.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-UMQ6NBQR.js";
|
|
19
19
|
import "./chunk-GZGLCCEE.js";
|
|
20
20
|
|
|
21
21
|
// src/adapters/copilot-cli/index.ts
|
|
@@ -819,4 +819,4 @@ export {
|
|
|
819
819
|
adapter,
|
|
820
820
|
copilot_cli_default as default
|
|
821
821
|
};
|
|
822
|
-
//# sourceMappingURL=copilot-cli-
|
|
822
|
+
//# sourceMappingURL=copilot-cli-PAP377OM.js.map
|