@ken-jo/agent-connector 0.6.3 → 0.6.5

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.
Files changed (90) hide show
  1. package/README.md +25 -12
  2. package/dist/{action-IKJ2J3X4.js → action-DFUJOXVJ.js} +9 -8
  3. package/dist/{action-IKJ2J3X4.js.map → action-DFUJOXVJ.js.map} +1 -1
  4. package/dist/{audit-5K2H7PAT.js → audit-IMNQJZ4W.js} +6 -5
  5. package/dist/{audit-5K2H7PAT.js.map → audit-IMNQJZ4W.js.map} +1 -1
  6. package/dist/{chunk-K67UJSJI.js → chunk-66TGBYSL.js} +5 -5
  7. package/dist/{chunk-QG26JEJF.js → chunk-7C3COFOD.js} +9 -9
  8. package/dist/{chunk-QG26JEJF.js.map → chunk-7C3COFOD.js.map} +1 -1
  9. package/dist/{chunk-HUL5CRF2.js → chunk-BAJL27XI.js} +4 -4
  10. package/dist/{codex-C7ERS3TW.js → chunk-BB4DFAHC.js} +21 -8
  11. package/dist/chunk-BB4DFAHC.js.map +1 -0
  12. package/dist/{chunk-STR3CRH3.js → chunk-C4NDV6GW.js} +2 -2
  13. package/dist/{chunk-LO6NIZSL.js → chunk-CG44RWYJ.js} +5 -5
  14. package/dist/chunk-D35FMUFZ.js +48 -0
  15. package/dist/chunk-D35FMUFZ.js.map +1 -0
  16. package/dist/{chunk-OXANBA4I.js → chunk-ITVST3SZ.js} +2 -2
  17. package/dist/{chunk-W4GVN3TJ.js → chunk-KQBRUI3Y.js} +3 -3
  18. package/dist/{chunk-TCJN5S4T.js → chunk-PTITNBSS.js} +22 -33
  19. package/dist/chunk-PTITNBSS.js.map +1 -0
  20. package/dist/{chunk-O7CFTOM5.js → chunk-S2TAC22E.js} +2 -2
  21. package/dist/{chunk-BD72ZF6D.js → chunk-V7GZ3AMV.js} +2 -2
  22. package/dist/{chunk-BGPVMJOG.js → chunk-ZYB2UFEN.js} +6 -2
  23. package/dist/chunk-ZYB2UFEN.js.map +1 -0
  24. package/dist/{claude-code-EIC4Q7OT.js → claude-code-JRKJARPH.js} +5 -4
  25. package/dist/{claude-code-EIC4Q7OT.js.map → claude-code-JRKJARPH.js.map} +1 -1
  26. package/dist/cli/sdk.js +5 -4
  27. package/dist/cli/sdk.js.map +1 -1
  28. package/dist/cli.js +2 -1
  29. package/dist/cli.js.map +1 -1
  30. package/dist/{cline-AJZ67XEE.js → cline-XAFNCZFQ.js} +26 -5
  31. package/dist/cline-XAFNCZFQ.js.map +1 -0
  32. package/dist/codex-X3WZZOJ4.js +22 -0
  33. package/dist/codex-X3WZZOJ4.js.map +1 -0
  34. package/dist/{define-connector-iosc34CA.d.ts → define-connector-D4UOI__e.d.ts} +1 -1
  35. package/dist/{detect-KYRQJUDY.js → detect-RT75DWQ5.js} +5 -4
  36. package/dist/{detect-KYRQJUDY.js.map → detect-RT75DWQ5.js.map} +1 -1
  37. package/dist/{doctor-BGWPZ676.js → doctor-F3RRQBQN.js} +135 -11
  38. package/dist/doctor-F3RRQBQN.js.map +1 -0
  39. package/dist/{hook-YMCFZRJE.js → hook-VYA4Q3YR.js} +9 -8
  40. package/dist/{hook-YMCFZRJE.js.map → hook-VYA4Q3YR.js.map} +1 -1
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +2 -2
  43. package/dist/{install-RCHVHCHO.js → install-XNTRLUZI.js} +9 -8
  44. package/dist/{install-RCHVHCHO.js.map → install-XNTRLUZI.js.map} +1 -1
  45. package/dist/{introspect-z3eKVWHN.d.ts → introspect-gaKVzg2q.d.ts} +1 -1
  46. package/dist/{leaderboard-V3DXXZNL.js → leaderboard-VF4W6PZ2.js} +3 -2
  47. package/dist/{leaderboard-V3DXXZNL.js.map → leaderboard-VF4W6PZ2.js.map} +1 -1
  48. package/dist/open-interpreter-ZHBMASXY.js +154 -0
  49. package/dist/open-interpreter-ZHBMASXY.js.map +1 -0
  50. package/dist/{package-75T46SXP.js → package-VRV5YHUJ.js} +7 -6
  51. package/dist/{package-75T46SXP.js.map → package-VRV5YHUJ.js.map} +1 -1
  52. package/dist/runtime/index.d.ts +1 -1
  53. package/dist/runtime/index.js +7 -6
  54. package/dist/sdk/index.d.ts +4 -4
  55. package/dist/sdk/index.js +3 -3
  56. package/dist/sdk/test.d.ts +2 -2
  57. package/dist/sdk/test.js +7 -6
  58. package/dist/{serve-IRMYJWFT.js → serve-EPEAGVOE.js} +9 -8
  59. package/dist/{serve-IRMYJWFT.js.map → serve-EPEAGVOE.js.map} +1 -1
  60. package/dist/{status-VJVNMWT7.js → status-3EHFFIQ7.js} +7 -6
  61. package/dist/{status-VJVNMWT7.js.map → status-3EHFFIQ7.js.map} +1 -1
  62. package/dist/{statusline-OKW44KFR.js → statusline-64IDYANK.js} +8 -7
  63. package/dist/{statusline-OKW44KFR.js.map → statusline-64IDYANK.js.map} +1 -1
  64. package/dist/{telemetry-YVMUXTDG.js → telemetry-AEE4TOFA.js} +6 -5
  65. package/dist/{telemetry-YVMUXTDG.js.map → telemetry-AEE4TOFA.js.map} +1 -1
  66. package/dist/{types-CAKApZpX.d.ts → types-htm_wrWo.d.ts} +6 -5
  67. package/dist/{uninstall-WZHO4CVL.js → uninstall-EJLQGZRN.js} +9 -8
  68. package/dist/{uninstall-WZHO4CVL.js.map → uninstall-EJLQGZRN.js.map} +1 -1
  69. package/dist/{upgrade-DZMEUPF2.js → upgrade-ZPHQELKG.js} +9 -8
  70. package/dist/{upgrade-DZMEUPF2.js.map → upgrade-ZPHQELKG.js.map} +1 -1
  71. package/dist/{usage-QSM4PP3E.js → usage-IWPGACHN.js} +3 -2
  72. package/dist/{usage-QSM4PP3E.js.map → usage-IWPGACHN.js.map} +1 -1
  73. package/dist/{usage-event-FH3X232T.js → usage-event-W5VLRA3X.js} +8 -7
  74. package/dist/{usage-event-FH3X232T.js.map → usage-event-W5VLRA3X.js.map} +1 -1
  75. package/package.json +20 -7
  76. package/dist/chunk-BGPVMJOG.js.map +0 -1
  77. package/dist/chunk-TCJN5S4T.js.map +0 -1
  78. package/dist/cline-AJZ67XEE.js.map +0 -1
  79. package/dist/codex-C7ERS3TW.js.map +0 -1
  80. package/dist/doctor-BGWPZ676.js.map +0 -1
  81. package/dist/open-interpreter-CXUCCZI3.js +0 -264
  82. package/dist/open-interpreter-CXUCCZI3.js.map +0 -1
  83. /package/dist/{chunk-K67UJSJI.js.map → chunk-66TGBYSL.js.map} +0 -0
  84. /package/dist/{chunk-HUL5CRF2.js.map → chunk-BAJL27XI.js.map} +0 -0
  85. /package/dist/{chunk-STR3CRH3.js.map → chunk-C4NDV6GW.js.map} +0 -0
  86. /package/dist/{chunk-LO6NIZSL.js.map → chunk-CG44RWYJ.js.map} +0 -0
  87. /package/dist/{chunk-OXANBA4I.js.map → chunk-ITVST3SZ.js.map} +0 -0
  88. /package/dist/{chunk-W4GVN3TJ.js.map → chunk-KQBRUI3Y.js.map} +0 -0
  89. /package/dist/{chunk-O7CFTOM5.js.map → chunk-S2TAC22E.js.map} +0 -0
  90. /package/dist/{chunk-BD72ZF6D.js.map → chunk-V7GZ3AMV.js.map} +0 -0
@@ -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 { 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 \"audit\",\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":[]}
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 \"audit\",\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
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "./chunk-TCJN5S4T.js";
4
+ } from "./chunk-PTITNBSS.js";
5
+ import "./chunk-D35FMUFZ.js";
5
6
 
6
7
  // src/cli/index.ts
7
8
  main(process.argv.slice(2)).then((code) => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts"],"sourcesContent":["/**\n * cli/index — the agent-connector bin entry.\n *\n * Intentionally tiny: it imports `main` from ./app.js and runs it\n * UNCONDITIONALLY. All helpers + dispatch live in ./app.ts (no side effects), so\n * command modules can import helpers without re-triggering the program, and the\n * auto-run survives bundler entry-splitting (no import.meta.url entry-guard).\n */\n\nimport { main } from \"./app.js\";\n\nmain(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`agent-connector: fatal: ${message}\\n`);\n process.exitCode = 1;\n });\n"],"mappings":";;;;;;AAWA,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,EACvB,KAAK,CAAC,SAAS;AACd,UAAQ,WAAW;AACrB,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,QAAM,UAAU,eAAe,QAAS,IAAI,SAAS,IAAI,UAAW,OAAO,GAAG;AAC9E,UAAQ,OAAO,MAAM,2BAA2B,OAAO;AAAA,CAAI;AAC3D,UAAQ,WAAW;AACrB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/cli/index.ts"],"sourcesContent":["/**\n * cli/index — the agent-connector bin entry.\n *\n * Intentionally tiny: it imports `main` from ./app.js and runs it\n * UNCONDITIONALLY. All helpers + dispatch live in ./app.ts (no side effects), so\n * command modules can import helpers without re-triggering the program, and the\n * auto-run survives bundler entry-splitting (no import.meta.url entry-guard).\n */\n\nimport { main } from \"./app.js\";\n\nmain(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`agent-connector: fatal: ${message}\\n`);\n process.exitCode = 1;\n });\n"],"mappings":";;;;;;;AAWA,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,EACvB,KAAK,CAAC,SAAS;AACd,UAAQ,WAAW;AACrB,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,QAAM,UAAU,eAAe,QAAS,IAAI,SAAS,IAAI,UAAW,OAAO,GAAG;AAC9E,UAAQ,OAAO,MAAM,2BAA2B,OAAO;AAAA,CAAI;AAC3D,UAAQ,WAAW;AACrB,CAAC;","names":[]}
@@ -80,12 +80,13 @@ var ClineAdapter = class extends BaseAdapter {
80
80
  CLINE_EXTENSION_ID
81
81
  );
82
82
  const projectRules = join(projectDir, ".clinerules");
83
- const userMatch = existsSync(userSettings) || existsSync(userExtDir);
83
+ const cliDir = this.cliConfigDir();
84
+ const userMatch = existsSync(userSettings) || existsSync(userExtDir) || existsSync(cliDir);
84
85
  const projectMatch = existsSync(projectRules);
85
86
  const installed = userMatch || projectMatch;
86
87
  const scope = userMatch || !projectMatch ? "user" : "project";
87
88
  const configPath = scope === "user" ? userSettings : projectRules;
88
- const reason = installed ? userMatch ? `found Cline globalStorage under ${userExtDir}` : `found Cline project rules at ${projectRules}` : `no Cline config at ${userExtDir} or ${projectRules}`;
89
+ const reason = installed ? userMatch ? existsSync(userSettings) || existsSync(userExtDir) ? `found Cline globalStorage under ${userExtDir}` : `found Cline CLI state under ${cliDir}` : `found Cline project rules at ${projectRules}` : `no Cline config at ${userExtDir}, ${cliDir} or ${projectRules}`;
89
90
  return {
90
91
  id: this.id,
91
92
  name: this.name,
@@ -99,6 +100,14 @@ var ClineAdapter = class extends BaseAdapter {
99
100
  };
100
101
  }
101
102
  // ── Native paths ─────────────────────────────────────────────────────────
103
+ /** The Cline CLI state dir (`--config` default); its presence = CLI installed. */
104
+ cliConfigDir() {
105
+ return join(homedir(), ".cline");
106
+ }
107
+ /** The Cline CLI's own copy of cline_mcp_settings.json (see header). */
108
+ cliSettingsPath() {
109
+ return join(this.cliConfigDir(), "data", "settings", MCP_SETTINGS_FILE);
110
+ }
102
111
  /** Absolute path to the user-scope MCP settings file (VS Code globalStorage). */
103
112
  userSettingsPath() {
104
113
  return join(
@@ -207,15 +216,27 @@ var ClineAdapter = class extends BaseAdapter {
207
216
  const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
208
217
  const serverPath = this.getServerConfigPath(ctx);
209
218
  const entry = this.renderServerEntry(ctx, server);
210
- return [
219
+ const changes = [
211
220
  this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
212
221
  ];
222
+ if (existsSync(this.cliConfigDir())) {
223
+ changes.push(
224
+ this.upsertServerInJson(this.cliSettingsPath(), MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
225
+ );
226
+ }
227
+ return changes;
213
228
  }
214
229
  uninstallServer(ctx) {
215
230
  const serverPath = this.getServerConfigPath(ctx);
216
- return [
231
+ const changes = [
217
232
  this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
218
233
  ];
234
+ if (existsSync(this.cliSettingsPath())) {
235
+ changes.push(
236
+ this.removeServerFromJson(this.cliSettingsPath(), MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
237
+ );
238
+ }
239
+ return changes;
219
240
  }
220
241
  /** Render a normalized ServerDef into Cline's native mcpServers entry. */
221
242
  renderServerEntry(ctx, server) {
@@ -405,4 +426,4 @@ export {
405
426
  adapter,
406
427
  cline_default as default
407
428
  };
408
- //# sourceMappingURL=cline-AJZ67XEE.js.map
429
+ //# sourceMappingURL=cline-XAFNCZFQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/cline/index.ts"],"sourcesContent":["/**\n * adapters/cline — Cline (VS Code extension) platform adapter.\n *\n * Cline (`saoudrizwan.claude-dev`) is the most-installed AI coding VS Code\n * extension and the PARENT that Kilo Code (`kilocode.kilo-code`) forked. From\n * agent-connector's perspective it is an **mcp-only** host: it exposes no\n * lifecycle hook / event-callback plugin API, so MCP server registration is the\n * only runtime surface we install and every hook capability is reported false.\n * The kilo adapter (a Cline fork) mirrors this shape.\n *\n * SCOPE NOTE: the primary target is the VS Code EXTENSION path below. The Cline\n * CLI (`cline` npm, 3.0.x) keeps its OWN copy of the same file at\n * `<config>/data/settings/cline_mcp_settings.json` (default config dir ~/.cline;\n * live-verified 2026-09-07: with the entry there the CLI lists the MCP tool and\n * calls it; without it the CLI never sees the extension's file). When ~/.cline\n * exists the adapter MIRRORS the server entry into that CLI file and removes it\n * on uninstall; on a box without the CLI nothing extra is written.\n *\n * MCP config (cline/cline `main`, disk.ts GlobalFileNames):\n * - USER SCOPE ONLY → <vscodeUserDir>/globalStorage/saoudrizwan.claude-dev/\n * settings/cline_mcp_settings.json (root key \"mcpServers\").\n * There is NO project-scope MCP file — the VS Code extension only reads this\n * single global path (so, unlike the kilo fork, there is no project `mcp.json`\n * branch and no legacy-filename probe: `cline_mcp_settings.json` is Cline's\n * canonical, never-renamed settings file).\n * Per-server shape: stdio { command, args?, env?, disabled? }; remote\n * { url, type:\"sse\"|\"streamableHttp\" }. An untyped remote url defaults to sse\n * in Cline, so we ALWAYS write `type` explicitly for remote entries.\n *\n * VS Code user-dir resolution (cross-OS) — the shared VS Code extension idiom:\n * - macOS → ~/Library/Application Support/Code/User\n * - Linux → ~/.config/Code/User\n * - Windows → %APPDATA%/Code/User (falls back to ~/AppData/Roaming/Code/User)\n *\n * Memory / commands / skills (docs.cline.bot) — the `.clinerules` content tree:\n * - memory → project <projectDir>/.clinerules/agent-connector.md (DIRECTORY\n * form); user ~/Documents/Cline/Rules/agent-connector.md. Markdown.\n * - command → project <projectDir>/.clinerules/workflows/<name>.md; user\n * ~/Documents/Cline/Workflows/<name>.md. (Cline \"Workflows\" are the\n * slash-command equivalent.) Plain markdown (frontmatter + body).\n * - skill → project <projectDir>/.clinerules/skills/<name>/SKILL.md;\n * user ~/.cline/skills/<name>/SKILL.md (homedir/.cline, cross-OS)\n * (SKILL.md-in-named-dir, YAML frontmatter; both scopes are\n * documented in cline/cline docs/customization/skills.mdx).\n *\n * READ-ONLY interop (NEVER written under this adapter): Cline also reads\n * `.cursor/rules`, `AGENTS.md`, `.claude/skills`, `.agents/skills` for cross-tool\n * interop. Those are other tools' surfaces — AC owns only the `.clinerules`/\n * Documents-dir paths above.\n *\n * Env interpolation: Cline's settings file documents no native `${env:VAR}`\n * token, so every `${env:VAR}` reference is resolved to a literal at install time\n * (the no-native-token path, same as kilo / gemini-cli).\n *\n * The hook \"config path\" is the SAME MCP settings file (there is no hook file),\n * so the generic doctor/backup behave sensibly.\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { homedir, platform as osPlatform } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, InstallContext, MemoryTarget } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookParadigm,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildWrappedStdio,\n} from \"../../core/spawn.js\";\nimport { renderCommandMd, renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"cline\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/** Cline extension id → its VS Code globalStorage folder. */\nconst CLINE_EXTENSION_ID = \"saoudrizwan.claude-dev\";\n/** User-scope MCP settings filename — Cline's canonical, never-renamed name. */\nconst MCP_SETTINGS_FILE = \"cline_mcp_settings.json\";\n\n/**\n * Native MCP server entry shapes Cline accepts under `mcpServers`. We write the\n * minimal stdio shape { command, args?, env?, disabled }; for remote servers we\n * ALWAYS emit `type` (Cline defaults an untyped url to sse, so the type must be\n * explicit to register a streamable-http server).\n */\ninterface ClineStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n disabled: boolean;\n}\ninterface ClineRemoteServer {\n url: string;\n type: \"sse\" | \"streamableHttp\";\n headers?: Record<string, string>;\n disabled: boolean;\n}\n\n/**\n * Resolve the cross-OS VS Code per-user data directory (the \"User\" folder that\n * contains `globalStorage`). Shared VERBATIM with the kilo fork adapter — the\n * published extensions live under the same stable \"Code\" tree. See module\n * header for the per-platform mapping.\n */\nfunction vscodeUserDir(): string {\n const home = homedir();\n switch (osPlatform()) {\n case \"darwin\":\n return join(home, \"Library\", \"Application Support\", \"Code\", \"User\");\n case \"win32\": {\n const appData = process.env.APPDATA ?? join(home, \"AppData\", \"Roaming\");\n return join(appData, \"Code\", \"User\");\n }\n default:\n // Linux / other POSIX: XDG-style config dir.\n return join(home, \".config\", \"Code\", \"User\");\n }\n}\n\n/**\n * Resolve the cross-OS user Documents directory. Cline's user-scope memory +\n * workflows live under `<documentsDir>/Cline/{Rules,Workflows}`.\n *\n * CAVEAT (documented, honest approximation — NOT a fabricated path): on Windows\n * the real Cline uses the MyDocuments known-folder, which a user CAN relocate\n * (we do not read the registry to discover a moved folder). `~/Documents` is the\n * Windows default and covers the common case. POSIX additionally honors\n * `XDG_DOCUMENTS_DIR` when set. The path SHAPE `Documents/Cline/{Rules,Workflows}`\n * is source-verified against docs.cline.bot.\n */\nfunction documentsDir(): string {\n if (osPlatform() === \"win32\") {\n return join(homedir(), \"Documents\");\n }\n const xdg = process.env.XDG_DOCUMENTS_DIR;\n return xdg && xdg.trim() !== \"\" ? xdg : join(homedir(), \"Documents\");\n}\n\nexport class ClineAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Cline\";\n readonly paradigm: HookParadigm = \"mcp-only\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: the `.clinerules` content tree (project\n // <projectDir>/.clinerules/agent-connector.md; user\n // ~/Documents/Cline/Rules/agent-connector.md) — overrides memoryTargets()\n // below (Cline does NOT use the AGENTS.md base default for its OWN file).\n supportsMemory: true,\n // Cline has no lifecycle hook system — every hook capability is false.\n preToolUse: false,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Cline registers stdio, SSE, and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: Workflows (the slash-command equivalent) and AgentSkills.\n // command → <clineRulesDir>/workflows/<name>.md (md + optional frontmatter)\n // skill → <projectDir>/.clinerules/skills/<name>/SKILL.md (project only)\n supportsCommands: true,\n supportsSkills: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userSettings = this.userSettingsPath();\n const userExtDir = join(\n vscodeUserDir(),\n \"globalStorage\",\n CLINE_EXTENSION_ID,\n );\n // Project marker: the `.clinerules` content root (file OR directory form).\n const projectRules = join(projectDir, \".clinerules\");\n\n const cliDir = this.cliConfigDir();\n const userMatch = existsSync(userSettings) || existsSync(userExtDir) || existsSync(cliDir);\n const projectMatch = existsSync(projectRules);\n const installed = userMatch || projectMatch;\n\n // Prefer the user scope/path when present; otherwise surface the project one.\n const scope = userMatch || !projectMatch ? \"user\" : \"project\";\n const configPath = scope === \"user\" ? userSettings : projectRules;\n const reason = installed\n ? userMatch\n ? existsSync(userSettings) || existsSync(userExtDir)\n ? `found Cline globalStorage under ${userExtDir}`\n : `found Cline CLI state under ${cliDir}`\n : `found Cline project rules at ${projectRules}`\n : `no Cline config at ${userExtDir}, ${cliDir} or ${projectRules}`;\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,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /** The Cline CLI state dir (`--config` default); its presence = CLI installed. */\n private cliConfigDir(): string {\n return join(homedir(), \".cline\");\n }\n\n /** The Cline CLI's own copy of cline_mcp_settings.json (see header). */\n private cliSettingsPath(): string {\n return join(this.cliConfigDir(), \"data\", \"settings\", MCP_SETTINGS_FILE);\n }\n\n /** Absolute path to the user-scope MCP settings file (VS Code globalStorage). */\n private userSettingsPath(): string {\n return join(\n vscodeUserDir(),\n \"globalStorage\",\n CLINE_EXTENSION_ID,\n \"settings\",\n MCP_SETTINGS_FILE,\n );\n }\n\n /**\n * MCP config is USER-SCOPE ONLY (the VS Code ext reads one global file). At\n * project scope we still return the global path so a project-scope install\n * lands the server where Cline actually reads it.\n */\n getConfigDir(_ctx: InstallContext): string {\n return join(\n vscodeUserDir(),\n \"globalStorage\",\n CLINE_EXTENSION_ID,\n \"settings\",\n );\n }\n\n getServerConfigPath(_ctx: InstallContext): string {\n return this.userSettingsPath();\n }\n\n /**\n * Cline has no hook file — hooks are not a thing here. The hook \"config path\"\n * is the same MCP settings file so the generic doctor/backup behave sensibly.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\n }\n\n // ── Memory surface: the `.clinerules` content tree ───────────────────────\n // Cline uses .clinerules (NOT AGENTS.md) for its OWN rules, so this override\n // replaces the AGENTS.md base default entirely:\n // project → <projectDir>/.clinerules/agent-connector.md (DIRECTORY form)\n // user → ~/Documents/Cline/Rules/agent-connector.md\n // When `.clinerules` exists as a single FILE (the legacy single-file form),\n // we must NOT create a `.clinerules/agent-connector.md` underneath it — that\n // would throw ENOTDIR — so we return [] here and installMemory() emits a\n // precise skip-warn (see below) rather than clobbering the user's file.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n // An explicit platforms[cline].memory.path override wins (escape hatch).\n if (this.memoryOverride(ctx)?.path) return super.memoryTargets(ctx);\n if (ctx.scope === \"project\") {\n if (this.clineRulesIsFile(ctx.projectDir)) return [];\n return [\n {\n path: join(ctx.projectDir, \".clinerules\", \"agent-connector.md\"),\n reason: \"cline project rules dir (.clinerules/; agent-connector-owned file)\",\n },\n ];\n }\n if (ctx.scope === \"user\") {\n return [\n {\n path: join(documentsDir(), \"Cline\", \"Rules\", \"agent-connector.md\"),\n reason: \"cline user rules dir (~/Documents/Cline/Rules; agent-connector-owned file)\",\n },\n ];\n }\n return [];\n }\n\n /**\n * Override installMemory ONLY to surface a precise warn when `.clinerules`\n * exists as a single FILE at project scope (so memoryTargets() returned []):\n * we never clobber the user's single-file rules. All other behavior delegates\n * to the base implementation.\n */\n override installMemory(ctx: InstallContext): ChangeRecord[] {\n if (\n ctx.scope === \"project\" &&\n !this.memoryOverride(ctx)?.path &&\n (ctx.connector.memory ?? []).length > 0 &&\n ctx.connector.platforms[this.id]?.memory !== false &&\n this.clineRulesIsFile(ctx.projectDir)\n ) {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path: join(ctx.projectDir, \".clinerules\"),\n detail:\n \"existing .clinerules is a single file (legacy form); left untouched — \" +\n \"convert it to a .clinerules/ directory to receive agent-connector memory\",\n },\n ];\n }\n return super.installMemory(ctx);\n }\n\n /** True when `<dir>/.clinerules` exists and is a regular FILE (not a directory). */\n private clineRulesIsFile(dir: string): boolean {\n const p = join(dir, \".clinerules\");\n if (!existsSync(p)) return false;\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for cline\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n const changes = [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n // Mirror into the Cline CLI's own settings file when the CLI is present.\n if (existsSync(this.cliConfigDir())) {\n changes.push(\n this.upsertServerInJson(this.cliSettingsPath(), MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n );\n }\n return changes;\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n const changes = [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n if (existsSync(this.cliSettingsPath())) {\n changes.push(\n this.removeServerFromJson(this.cliSettingsPath(), MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n );\n }\n return changes;\n }\n\n /** Render a normalized ServerDef into Cline's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): ClineStdioServer | ClineRemoteServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n // Cline documents no native interpolation token, so resolve every\n // ${env:VAR} to a literal at install time.\n const entry: ClineStdioServer = {\n command: resolveEnvRefsDeep(command),\n // Honor the per-call server's enabled flag — a server marked\n // enabled:false installs disabled (mirror kilo).\n disabled: server.enabled === false,\n };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // sse / http (and any other remote transport) — Cline registers a URL. We\n // ALWAYS emit `type` (an untyped url defaults to sse in Cline, so streamable\n // http must be explicit): map our \"http\" transport to \"streamableHttp\".\n const entry: ClineRemoteServer = {\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n type: transport === \"http\" ? \"streamableHttp\" : \"sse\",\n disabled: server.enabled === false,\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Cline documents no native interpolation token, so\n * resolve `${env:VAR}` references to literals at install time.\n */\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 // ── Hooks (unavailable — Cline is mcp-only) ──────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Cline is mcp-only)\",\n },\n ];\n }\n\n uninstallHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Cline is mcp-only)\",\n },\n ];\n }\n\n // ── Content surfaces: commands (Workflows) / skills ──────────────────────\n // CONTENT-ONLY: pure native-file writers. No runtime dispatch, no home-bin\n // pointer, no telemetry wrap. Each method is idempotent (byte-identical →\n // skip) via writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"cline\"] per-surface false to skip.\n //\n // Native locations (the `.clinerules` content tree + the Documents-dir):\n // command → project <projectDir>/.clinerules/workflows/<name>.md\n // user ~/Documents/Cline/Workflows/<name>.md\n // skill → project <projectDir>/.clinerules/skills/<name>/SKILL.md\n // user (undocumented for the VS Code ext → skip-warn)\n\n /** The project-scope `.clinerules` content root. */\n private clineRulesDir(ctx: InstallContext): string {\n return join(ctx.projectDir, \".clinerules\");\n }\n\n private commandPath(ctx: InstallContext, name: string): string {\n return ctx.scope === \"project\"\n ? join(this.clineRulesDir(ctx), \"workflows\", `${name}.md`)\n : join(documentsDir(), \"Cline\", \"Workflows\", `${name}.md`);\n }\n\n private skillDir(ctx: InstallContext, name: string): string {\n // User/global scope → ~/.cline/skills/<name> (homedir/.cline, cross-OS via\n // homedir(); primary-verified cline/cline docs/customization/skills.mdx).\n // Project scope → <projectDir>/.clinerules/skills/<name> (a documented\n // project skills location alongside .cline/skills; AC owns the .clinerules tree).\n if (ctx.scope !== \"project\") {\n return join(homedir(), \".cline\", \"skills\", name);\n }\n return join(this.clineRulesDir(ctx), \"skills\", name);\n }\n\n // ── Commands (Workflows — both scopes) ────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for cline\" }];\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 renderCommandMd(cmd, { includeToolsAndModel: false }),\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 // ── Skills (project .clinerules/skills + user ~/.cline/skills) ────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for cline\" }];\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 // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\n // (config-time validation already rejects these, but never trust input).\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 // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\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; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n return [\n {\n name: `${this.name}: MCP settings present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector —\n // e.g. a catalog-only bundle of skills/commands — never writes an\n // mcpServers entry, so its absence is healthy.\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> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\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 ${mcpPath}`,\n };\n },\n },\n ];\n }\n}\n\nexport const adapter = new ClineAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ CODEX_HOOK_EVENTS,
4
+ CodexAdapter,
5
+ adapter,
6
+ codex_default
7
+ } from "./chunk-BB4DFAHC.js";
8
+ import "./chunk-KOFCNA5T.js";
9
+ import "./chunk-OPXAP3AC.js";
10
+ import "./chunk-H53QZQJI.js";
11
+ import "./chunk-BEFVJ2OE.js";
12
+ import "./chunk-PMOFA5BT.js";
13
+ import "./chunk-QSY74NAP.js";
14
+ import "./chunk-UMQ6NBQR.js";
15
+ import "./chunk-GZGLCCEE.js";
16
+ export {
17
+ CODEX_HOOK_EVENTS,
18
+ CodexAdapter,
19
+ adapter,
20
+ codex_default as default
21
+ };
22
+ //# sourceMappingURL=codex-X3WZZOJ4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,4 +1,4 @@
1
- import { A as ActionDef, Q as CommandDef, V as ConfigPatchDef, c as ConnectorConfig, v as ResolvedConnector, e as HookEventName, H as HookDefinition, k as MemoryDef, N as NativeHookDef, Y as SkillDef, z as StatuslineDef, Z as SubagentDef } from './types-CAKApZpX.js';
1
+ import { A as ActionDef, Q as CommandDef, V as ConfigPatchDef, c as ConnectorConfig, v as ResolvedConnector, e as HookEventName, H as HookDefinition, k as MemoryDef, N as NativeHookDef, Y as SkillDef, z as StatuslineDef, Z as SubagentDef } from './types-htm_wrWo.js';
2
2
 
3
3
  /**
4
4
  * core/define-connector — the public write-once entry point.
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  print
4
- } from "./chunk-TCJN5S4T.js";
4
+ } from "./chunk-PTITNBSS.js";
5
5
  import {
6
6
  detectInstalledPlatforms
7
- } from "./chunk-OXANBA4I.js";
8
- import "./chunk-QG26JEJF.js";
7
+ } from "./chunk-ITVST3SZ.js";
8
+ import "./chunk-D35FMUFZ.js";
9
+ import "./chunk-7C3COFOD.js";
9
10
 
10
11
  // src/cli/commands/detect.ts
11
12
  import { parseArgs } from "util";
@@ -71,4 +72,4 @@ async function run(argv) {
71
72
  export {
72
73
  run
73
74
  };
74
- //# sourceMappingURL=detect-KYRQJUDY.js.map
75
+ //# sourceMappingURL=detect-RT75DWQ5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/commands/detect.ts"],"sourcesContent":["/**\n * cli/commands/detect — list the AI-agent platforms installed on this machine.\n *\n * `detect` probes every registered adapter (via detectInstalledPlatforms) and\n * prints, for each installed host: id, name, hook paradigm, install scope, the\n * native config path that would be written, and a one-line capabilities summary.\n * `--json` emits the raw DetectedPlatform[] for scripting.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport type { DetectedPlatform, PlatformCapabilities } from \"../../core/types.js\";\nimport { detectInstalledPlatforms } from \"../../adapters/detect.js\";\nimport { print } from \"../app.js\";\n\n/** Compact, human one-line summary of what a host can honor. */\nfunction capabilitySummary(caps: PlatformCapabilities): string {\n const events: string[] = [];\n if (caps.preToolUse) events.push(\"PreToolUse\");\n if (caps.postToolUse) events.push(\"PostToolUse\");\n if (caps.sessionStart) events.push(\"SessionStart\");\n if (caps.sessionEnd) events.push(\"SessionEnd\");\n if (caps.userPromptSubmit) events.push(\"UserPromptSubmit\");\n if (caps.preCompact) events.push(\"PreCompact\");\n if (caps.stop) events.push(\"Stop\");\n if (caps.notification) events.push(\"Notification\");\n // Newer optional per-event flags (absent ⇒ unsupported, read as `?? false`).\n if (caps.permissionRequest ?? false) events.push(\"PermissionRequest\");\n if (caps.postToolUseFailure ?? false) events.push(\"PostToolUseFailure\");\n if (caps.subagentStart ?? false) events.push(\"SubagentStart\");\n if (caps.subagentStop ?? false) events.push(\"SubagentStop\");\n if (caps.postCompact ?? false) events.push(\"PostCompact\");\n\n const extras: string[] = [];\n if (caps.canModifyArgs) extras.push(\"modifyArgs\");\n if (caps.canModifyOutput) extras.push(\"modifyOutput\");\n if (caps.canInjectSessionContext) extras.push(\"injectContext\");\n\n const transports = caps.transports.length > 0 ? caps.transports.join(\"/\") : \"none\";\n const parts = [\n `events: ${events.length > 0 ? events.join(\",\") : \"none\"}`,\n `transports: ${transports}`,\n ];\n if (extras.length > 0) parts.push(extras.join(\",\"));\n return parts.join(\" | \");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n json: { type: \"boolean\", default: false },\n project: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n const detected: DetectedPlatform[] = await detectInstalledPlatforms(projectDir);\n\n if (values.json) {\n print(JSON.stringify(detected, null, 2));\n return 0;\n }\n\n if (detected.length === 0) {\n print(\"No supported AI-agent platforms detected on this machine.\");\n return 0;\n }\n\n print(`Detected ${detected.length} platform(s):\\n`);\n for (const p of detected) {\n print(`${p.name} (${p.id})`);\n print(` paradigm: ${p.paradigm}`);\n print(` scope: ${p.scope}`);\n print(` configPath: ${p.configPath}`);\n print(` confidence: ${p.confidence} (${p.reason})`);\n print(` capabilities: ${capabilitySummary(p.capabilities)}`);\n print(\"\");\n }\n return 0;\n}\n"],"mappings":";;;;;;;;;;AASA,SAAS,iBAAiB;AAO1B,SAAS,kBAAkB,MAAoC;AAC7D,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,YAAa,QAAO,KAAK,aAAa;AAC/C,MAAI,KAAK,aAAc,QAAO,KAAK,cAAc;AACjD,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,iBAAkB,QAAO,KAAK,kBAAkB;AACzD,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,KAAM,QAAO,KAAK,MAAM;AACjC,MAAI,KAAK,aAAc,QAAO,KAAK,cAAc;AAEjD,MAAI,KAAK,qBAAqB,MAAO,QAAO,KAAK,mBAAmB;AACpE,MAAI,KAAK,sBAAsB,MAAO,QAAO,KAAK,oBAAoB;AACtE,MAAI,KAAK,iBAAiB,MAAO,QAAO,KAAK,eAAe;AAC5D,MAAI,KAAK,gBAAgB,MAAO,QAAO,KAAK,cAAc;AAC1D,MAAI,KAAK,eAAe,MAAO,QAAO,KAAK,aAAa;AAExD,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK,cAAe,QAAO,KAAK,YAAY;AAChD,MAAI,KAAK,gBAAiB,QAAO,KAAK,cAAc;AACpD,MAAI,KAAK,wBAAyB,QAAO,KAAK,eAAe;AAE7D,QAAM,aAAa,KAAK,WAAW,SAAS,IAAI,KAAK,WAAW,KAAK,GAAG,IAAI;AAC5E,QAAM,QAAQ;AAAA,IACZ,WAAW,OAAO,SAAS,IAAI,OAAO,KAAK,GAAG,IAAI,MAAM;AAAA,IACxD,eAAe,UAAU;AAAA,EAC3B;AACA,MAAI,OAAO,SAAS,EAAG,OAAM,KAAK,OAAO,KAAK,GAAG,CAAC;AAClD,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,OAAO,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,MACxC,SAAS,EAAE,MAAM,SAAS;AAAA,IAC5B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AACjD,QAAM,WAA+B,MAAM,yBAAyB,UAAU;AAE9E,MAAI,OAAO,MAAM;AACf,UAAM,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AACvC,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,2DAA2D;AACjE,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,SAAS,MAAM;AAAA,CAAiB;AAClD,aAAW,KAAK,UAAU;AACxB,UAAM,GAAG,EAAE,IAAI,KAAK,EAAE,EAAE,GAAG;AAC3B,UAAM,kBAAkB,EAAE,QAAQ,EAAE;AACpC,UAAM,kBAAkB,EAAE,KAAK,EAAE;AACjC,UAAM,kBAAkB,EAAE,UAAU,EAAE;AACtC,UAAM,kBAAkB,EAAE,UAAU,MAAM,EAAE,MAAM,GAAG;AACrD,UAAM,mBAAmB,kBAAkB,EAAE,YAAY,CAAC,EAAE;AAC5D,UAAM,EAAE;AAAA,EACV;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/cli/commands/detect.ts"],"sourcesContent":["/**\n * cli/commands/detect — list the AI-agent platforms installed on this machine.\n *\n * `detect` probes every registered adapter (via detectInstalledPlatforms) and\n * prints, for each installed host: id, name, hook paradigm, install scope, the\n * native config path that would be written, and a one-line capabilities summary.\n * `--json` emits the raw DetectedPlatform[] for scripting.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport type { DetectedPlatform, PlatformCapabilities } from \"../../core/types.js\";\nimport { detectInstalledPlatforms } from \"../../adapters/detect.js\";\nimport { print } from \"../app.js\";\n\n/** Compact, human one-line summary of what a host can honor. */\nfunction capabilitySummary(caps: PlatformCapabilities): string {\n const events: string[] = [];\n if (caps.preToolUse) events.push(\"PreToolUse\");\n if (caps.postToolUse) events.push(\"PostToolUse\");\n if (caps.sessionStart) events.push(\"SessionStart\");\n if (caps.sessionEnd) events.push(\"SessionEnd\");\n if (caps.userPromptSubmit) events.push(\"UserPromptSubmit\");\n if (caps.preCompact) events.push(\"PreCompact\");\n if (caps.stop) events.push(\"Stop\");\n if (caps.notification) events.push(\"Notification\");\n // Newer optional per-event flags (absent ⇒ unsupported, read as `?? false`).\n if (caps.permissionRequest ?? false) events.push(\"PermissionRequest\");\n if (caps.postToolUseFailure ?? false) events.push(\"PostToolUseFailure\");\n if (caps.subagentStart ?? false) events.push(\"SubagentStart\");\n if (caps.subagentStop ?? false) events.push(\"SubagentStop\");\n if (caps.postCompact ?? false) events.push(\"PostCompact\");\n\n const extras: string[] = [];\n if (caps.canModifyArgs) extras.push(\"modifyArgs\");\n if (caps.canModifyOutput) extras.push(\"modifyOutput\");\n if (caps.canInjectSessionContext) extras.push(\"injectContext\");\n\n const transports = caps.transports.length > 0 ? caps.transports.join(\"/\") : \"none\";\n const parts = [\n `events: ${events.length > 0 ? events.join(\",\") : \"none\"}`,\n `transports: ${transports}`,\n ];\n if (extras.length > 0) parts.push(extras.join(\",\"));\n return parts.join(\" | \");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n json: { type: \"boolean\", default: false },\n project: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n const detected: DetectedPlatform[] = await detectInstalledPlatforms(projectDir);\n\n if (values.json) {\n print(JSON.stringify(detected, null, 2));\n return 0;\n }\n\n if (detected.length === 0) {\n print(\"No supported AI-agent platforms detected on this machine.\");\n return 0;\n }\n\n print(`Detected ${detected.length} platform(s):\\n`);\n for (const p of detected) {\n print(`${p.name} (${p.id})`);\n print(` paradigm: ${p.paradigm}`);\n print(` scope: ${p.scope}`);\n print(` configPath: ${p.configPath}`);\n print(` confidence: ${p.confidence} (${p.reason})`);\n print(` capabilities: ${capabilitySummary(p.capabilities)}`);\n print(\"\");\n }\n return 0;\n}\n"],"mappings":";;;;;;;;;;;AASA,SAAS,iBAAiB;AAO1B,SAAS,kBAAkB,MAAoC;AAC7D,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,YAAa,QAAO,KAAK,aAAa;AAC/C,MAAI,KAAK,aAAc,QAAO,KAAK,cAAc;AACjD,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,iBAAkB,QAAO,KAAK,kBAAkB;AACzD,MAAI,KAAK,WAAY,QAAO,KAAK,YAAY;AAC7C,MAAI,KAAK,KAAM,QAAO,KAAK,MAAM;AACjC,MAAI,KAAK,aAAc,QAAO,KAAK,cAAc;AAEjD,MAAI,KAAK,qBAAqB,MAAO,QAAO,KAAK,mBAAmB;AACpE,MAAI,KAAK,sBAAsB,MAAO,QAAO,KAAK,oBAAoB;AACtE,MAAI,KAAK,iBAAiB,MAAO,QAAO,KAAK,eAAe;AAC5D,MAAI,KAAK,gBAAgB,MAAO,QAAO,KAAK,cAAc;AAC1D,MAAI,KAAK,eAAe,MAAO,QAAO,KAAK,aAAa;AAExD,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK,cAAe,QAAO,KAAK,YAAY;AAChD,MAAI,KAAK,gBAAiB,QAAO,KAAK,cAAc;AACpD,MAAI,KAAK,wBAAyB,QAAO,KAAK,eAAe;AAE7D,QAAM,aAAa,KAAK,WAAW,SAAS,IAAI,KAAK,WAAW,KAAK,GAAG,IAAI;AAC5E,QAAM,QAAQ;AAAA,IACZ,WAAW,OAAO,SAAS,IAAI,OAAO,KAAK,GAAG,IAAI,MAAM;AAAA,IACxD,eAAe,UAAU;AAAA,EAC3B;AACA,MAAI,OAAO,SAAS,EAAG,OAAM,KAAK,OAAO,KAAK,GAAG,CAAC;AAClD,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,OAAO,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,MACxC,SAAS,EAAE,MAAM,SAAS;AAAA,IAC5B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AACjD,QAAM,WAA+B,MAAM,yBAAyB,UAAU;AAE9E,MAAI,OAAO,MAAM;AACf,UAAM,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AACvC,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,2DAA2D;AACjE,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,SAAS,MAAM;AAAA,CAAiB;AAClD,aAAW,KAAK,UAAU;AACxB,UAAM,GAAG,EAAE,IAAI,KAAK,EAAE,EAAE,GAAG;AAC3B,UAAM,kBAAkB,EAAE,QAAQ,EAAE;AACpC,UAAM,kBAAkB,EAAE,KAAK,EAAE;AACjC,UAAM,kBAAkB,EAAE,UAAU,EAAE;AACtC,UAAM,kBAAkB,EAAE,UAAU,MAAM,EAAE,MAAM,GAAG;AACrD,UAAM,mBAAmB,kBAAkB,EAAE,YAAY,CAAC,EAAE;AAC5D,UAAM,EAAE;AAAA,EACV;AACA,SAAO;AACT;","names":[]}
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  marketplaceDoctorChecks,
4
4
  syncConnector
5
- } from "./chunk-LO6NIZSL.js";
6
- import "./chunk-STR3CRH3.js";
5
+ } from "./chunk-CG44RWYJ.js";
6
+ import "./chunk-C4NDV6GW.js";
7
7
  import {
8
8
  readMarketplaceInstalls
9
9
  } from "./chunk-CWUPIT72.js";
@@ -16,7 +16,7 @@ import {
16
16
  parseScope,
17
17
  parseTargets,
18
18
  print
19
- } from "./chunk-TCJN5S4T.js";
19
+ } from "./chunk-PTITNBSS.js";
20
20
  import {
21
21
  LineBuffer,
22
22
  idKey,
@@ -27,28 +27,33 @@ import {
27
27
  } from "./chunk-GDIAHWNY.js";
28
28
  import {
29
29
  detectInstalledPlatforms
30
- } from "./chunk-OXANBA4I.js";
30
+ } from "./chunk-ITVST3SZ.js";
31
31
  import {
32
32
  explainHooks
33
- } from "./chunk-HUL5CRF2.js";
34
- import "./chunk-W4GVN3TJ.js";
33
+ } from "./chunk-BAJL27XI.js";
34
+ import "./chunk-KQBRUI3Y.js";
35
35
  import "./chunk-IVAWP6HH.js";
36
36
  import "./chunk-KHO5WNTP.js";
37
- import "./chunk-BD72ZF6D.js";
37
+ import "./chunk-V7GZ3AMV.js";
38
38
  import "./chunk-4NFDNY3C.js";
39
39
  import {
40
40
  findConnectorConfig,
41
41
  listRegisteredConnectors,
42
42
  loadConnectorFromPath,
43
43
  readRegisteredMeta
44
- } from "./chunk-BGPVMJOG.js";
44
+ } from "./chunk-ZYB2UFEN.js";
45
+ import {
46
+ cliEntryOfLauncher,
47
+ resolveOwnVersion,
48
+ versionOfCliEntry
49
+ } from "./chunk-D35FMUFZ.js";
45
50
  import {
46
51
  MCP_PROTOCOL_VERSION
47
- } from "./chunk-O7CFTOM5.js";
52
+ } from "./chunk-S2TAC22E.js";
48
53
  import {
49
54
  REGISTERED_PLATFORM_IDS,
50
55
  loadAdapter
51
- } from "./chunk-QG26JEJF.js";
56
+ } from "./chunk-7C3COFOD.js";
52
57
  import "./chunk-NBYKLUF6.js";
53
58
  import "./chunk-H53QZQJI.js";
54
59
  import "./chunk-BEFVJ2OE.js";
@@ -61,6 +66,7 @@ import {
61
66
  } from "./chunk-GZGLCCEE.js";
62
67
 
63
68
  // src/cli/commands/doctor.ts
69
+ import { existsSync, readFileSync } from "fs";
64
70
  import { parseArgs } from "util";
65
71
 
66
72
  // src/runtime/probe.ts
@@ -293,6 +299,118 @@ function buildContext(connector, id, scope, projectDir) {
293
299
  dryRun: true
294
300
  };
295
301
  }
302
+ var FRAMEWORK_BUCKET = "agent-connector";
303
+ function frameworkChecks(entries) {
304
+ const out = [];
305
+ const healEntry = Math.max(0, entries.findIndex((e) => !!e.modulePath));
306
+ const push = (result, entryIndex = healEntry) => out.push({ result, entryIndex });
307
+ const own = resolveOwnVersion();
308
+ const fix = "run `upgrade` (or `doctor --heal`) to re-render and re-point the home binary";
309
+ const bin = homeBinPath();
310
+ if (!existsSync(bin)) {
311
+ push({
312
+ check: "agent-connector: home-bin",
313
+ status: entries.some((e) => e.modulePath) ? "warn" : "pass",
314
+ message: entries.some((e) => e.modulePath) ? `launcher missing at ${bin} \u2014 host hooks/actions cannot reach agent-connector` : `no launcher yet at ${bin} (nothing installed)`,
315
+ ...entries.some((e) => e.modulePath) ? { fix, fixable: true } : {}
316
+ });
317
+ } else {
318
+ let text = "";
319
+ try {
320
+ text = readFileSync(bin, "utf8");
321
+ } catch {
322
+ }
323
+ const cli = cliEntryOfLauncher(text);
324
+ if (!cli) {
325
+ push({
326
+ check: "agent-connector: home-bin",
327
+ status: "warn",
328
+ message: `launcher at ${bin} is not in the shape agent-connector writes`,
329
+ fix,
330
+ fixable: true
331
+ });
332
+ } else if (!existsSync(cli)) {
333
+ push({
334
+ check: "agent-connector: home-bin",
335
+ status: "fail",
336
+ message: `launcher execs a CLI that no longer exists: ${cli} (an uninstalled or moved agent-connector)`,
337
+ fix,
338
+ fixable: true
339
+ });
340
+ } else {
341
+ push({ check: "agent-connector: home-bin", status: "pass", message: `execs ${cli}` });
342
+ const target = versionOfCliEntry(cli);
343
+ if (target === null) {
344
+ push({
345
+ check: "agent-connector: home-bin version",
346
+ status: "warn",
347
+ message: `cannot read the package version behind ${cli}`,
348
+ fix,
349
+ fixable: true
350
+ });
351
+ } else if (target !== own) {
352
+ push({
353
+ check: "agent-connector: home-bin version",
354
+ status: "warn",
355
+ message: `launcher runs agent-connector ${target}, this CLI is ${own}`,
356
+ fix,
357
+ fixable: true
358
+ });
359
+ } else {
360
+ push({ check: "agent-connector: home-bin version", status: "pass", message: own });
361
+ }
362
+ }
363
+ }
364
+ entries.forEach((entry, i) => {
365
+ if (!entry.modulePath) return;
366
+ const meta = readRegisteredMeta(entry.connector.id);
367
+ if (!meta) return;
368
+ const idFix = `run \`upgrade\` (or \`doctor --heal\`) to re-render ${entry.connector.id}`;
369
+ if (!meta.frameworkVersion) {
370
+ push(
371
+ {
372
+ check: `${entry.connector.id}: framework version`,
373
+ status: "warn",
374
+ message: `rendered by an agent-connector older than 0.6.5 (no version recorded); running ${own}`,
375
+ fix: idFix,
376
+ fixable: true
377
+ },
378
+ i
379
+ );
380
+ } else if (meta.frameworkVersion !== own) {
381
+ push(
382
+ {
383
+ check: `${entry.connector.id}: framework version`,
384
+ status: "warn",
385
+ message: `rendered by agent-connector ${meta.frameworkVersion}, running ${own}`,
386
+ fix: idFix,
387
+ fixable: true
388
+ },
389
+ i
390
+ );
391
+ } else {
392
+ push({ check: `${entry.connector.id}: framework version`, status: "pass", message: own }, i);
393
+ }
394
+ if (meta.version !== entry.connector.version) {
395
+ push(
396
+ {
397
+ check: `${entry.connector.id}: connector version`,
398
+ status: "warn",
399
+ message: `registered ${meta.version}, source declares ${entry.connector.version}`,
400
+ fix: idFix,
401
+ fixable: true
402
+ },
403
+ i
404
+ );
405
+ } else {
406
+ push(
407
+ { check: `${entry.connector.id}: connector version`, status: "pass", message: meta.version },
408
+ i
409
+ );
410
+ }
411
+ });
412
+ return out;
413
+ }
296
414
  async function collectDiagnostics(entries, ids, scope, projectDir) {
297
415
  const multi = entries.length > 1;
298
416
  const byPlatform = [];
@@ -352,6 +470,12 @@ async function collectDiagnostics(entries, ids, scope, projectDir) {
352
470
  else byPlatform.push({ platform: group.platform, results: tagged_g });
353
471
  }
354
472
  }
473
+ const fw = frameworkChecks(entries);
474
+ if (fw.length > 0) {
475
+ if (fw.some((t) => t.result.status === "fail")) anyFail = true;
476
+ tagged.push(...fw);
477
+ byPlatform.unshift({ platform: FRAMEWORK_BUCKET, results: fw.map((t) => t.result) });
478
+ }
355
479
  return { byPlatform, tagged, anyFail };
356
480
  }
357
481
  var VERDICT_GLYPH = {
@@ -628,4 +752,4 @@ async function run(argv) {
628
752
  export {
629
753
  run
630
754
  };
631
- //# sourceMappingURL=doctor-BGWPZ676.js.map
755
+ //# sourceMappingURL=doctor-F3RRQBQN.js.map