@ken-jo/agent-connector 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +13 -2
  2. package/dist/{chunk-AKJGNTU3.js → chunk-3RBLIHPZ.js} +21 -21
  3. package/dist/chunk-3RBLIHPZ.js.map +1 -0
  4. package/dist/chunk-G5CQHVQG.js +511 -0
  5. package/dist/chunk-G5CQHVQG.js.map +1 -0
  6. package/dist/chunk-KMAKDD3Z.js +3010 -0
  7. package/dist/chunk-KMAKDD3Z.js.map +1 -0
  8. package/dist/{chunk-KHO5WNTP.js → chunk-KVAAFYRR.js} +18 -2
  9. package/dist/chunk-KVAAFYRR.js.map +1 -0
  10. package/dist/{chunk-O2SBA5KR.js → chunk-NJU275US.js} +9 -9
  11. package/dist/{chunk-WCETQWWK.js → chunk-OP4KBXUO.js} +1 -17
  12. package/dist/chunk-OP4KBXUO.js.map +1 -0
  13. package/dist/{package-O63K4S7T.js → chunk-WNREHWKL.js} +20 -114
  14. package/dist/chunk-WNREHWKL.js.map +1 -0
  15. package/dist/{chunk-4ML7SZ7R.js → chunk-ZAM4M7LI.js} +7 -7
  16. package/dist/cli/sdk.js +1 -1
  17. package/dist/cli.js +1 -1
  18. package/dist/{detect-JK7T46N6.js → detect-U3E7NVNW.js} +3 -3
  19. package/dist/{doctor-62BHIXOR.js → doctor-DZTWED4O.js} +35 -5
  20. package/dist/doctor-DZTWED4O.js.map +1 -0
  21. package/dist/{hook-AC7APC66.js → hook-EVY7LOUQ.js} +6 -6
  22. package/dist/{install-DMW2C7SV.js → install-OWAS5UIE.js} +31 -7
  23. package/dist/install-OWAS5UIE.js.map +1 -0
  24. package/dist/kilo-PKAJCWPX.js +852 -0
  25. package/dist/kilo-PKAJCWPX.js.map +1 -0
  26. package/dist/{kilo-cli-2RNODHWY.js → kilo-cli-QWUVXG2O.js} +157 -6
  27. package/dist/kilo-cli-QWUVXG2O.js.map +1 -0
  28. package/dist/{kimi-Q5RG7CYT.js → kimi-EVD7YKXS.js} +79 -4
  29. package/dist/kimi-EVD7YKXS.js.map +1 -0
  30. package/dist/{kiro-EKTRW424.js → kiro-UQRY6EIO.js} +68 -3
  31. package/dist/kiro-UQRY6EIO.js.map +1 -0
  32. package/dist/{leaderboard-R5HRJHNU.js → leaderboard-CSWHI4UY.js} +2 -2
  33. package/dist/package-WFOS4QVU.js +130 -0
  34. package/dist/package-WFOS4QVU.js.map +1 -0
  35. package/dist/{pi-SJPIL4VE.js → pi-WMTUX6ES.js} +102 -23
  36. package/dist/pi-WMTUX6ES.js.map +1 -0
  37. package/dist/{qwen-code-IFCM6BJY.js → qwen-code-MRRIUQ3P.js} +78 -5
  38. package/dist/qwen-code-MRRIUQ3P.js.map +1 -0
  39. package/dist/runtime/index.js +4 -4
  40. package/dist/{serve-LFOUSZAD.js → serve-3C2VFPAY.js} +6 -6
  41. package/dist/{status-M7JLZVLC.js → status-MKQYX5MW.js} +16 -7
  42. package/dist/status-MKQYX5MW.js.map +1 -0
  43. package/dist/{telemetry-3NVEXPYX.js → telemetry-3DN6XGYB.js} +2 -2
  44. package/dist/uninstall-WG6PFWF3.js +162 -0
  45. package/dist/uninstall-WG6PFWF3.js.map +1 -0
  46. package/dist/{upgrade-76BQZBMA.js → upgrade-32NC2RKI.js} +26 -8
  47. package/dist/upgrade-32NC2RKI.js.map +1 -0
  48. package/dist/{usage-G3GSCX23.js → usage-CJOM2WQM.js} +2 -2
  49. package/dist/{usage-event-QUTMNBS5.js → usage-event-472X3DOY.js} +5 -5
  50. package/dist/{warp-LLOSXR7A.js → warp-X6MB67NT.js} +81 -3
  51. package/dist/warp-X6MB67NT.js.map +1 -0
  52. package/dist/{zed-HYOITK7F.js → zed-NTCYW4V2.js} +68 -3
  53. package/dist/zed-NTCYW4V2.js.map +1 -0
  54. package/package.json +1 -1
  55. package/dist/chunk-AKJGNTU3.js.map +0 -1
  56. package/dist/chunk-KHO5WNTP.js.map +0 -1
  57. package/dist/chunk-WCETQWWK.js.map +0 -1
  58. package/dist/chunk-Z2BVYKZL.js +0 -369
  59. package/dist/chunk-Z2BVYKZL.js.map +0 -1
  60. package/dist/doctor-62BHIXOR.js.map +0 -1
  61. package/dist/install-DMW2C7SV.js.map +0 -1
  62. package/dist/kilo-ISR5FBBJ.js +0 -408
  63. package/dist/kilo-ISR5FBBJ.js.map +0 -1
  64. package/dist/kilo-cli-2RNODHWY.js.map +0 -1
  65. package/dist/kimi-Q5RG7CYT.js.map +0 -1
  66. package/dist/kiro-EKTRW424.js.map +0 -1
  67. package/dist/package-O63K4S7T.js.map +0 -1
  68. package/dist/pi-SJPIL4VE.js.map +0 -1
  69. package/dist/qwen-code-IFCM6BJY.js.map +0 -1
  70. package/dist/status-M7JLZVLC.js.map +0 -1
  71. package/dist/uninstall-H6FGMIHN.js +0 -73
  72. package/dist/uninstall-H6FGMIHN.js.map +0 -1
  73. package/dist/upgrade-76BQZBMA.js.map +0 -1
  74. package/dist/warp-LLOSXR7A.js.map +0 -1
  75. package/dist/zed-HYOITK7F.js.map +0 -1
  76. /package/dist/{chunk-O2SBA5KR.js.map → chunk-NJU275US.js.map} +0 -0
  77. /package/dist/{chunk-4ML7SZ7R.js.map → chunk-ZAM4M7LI.js.map} +0 -0
  78. /package/dist/{detect-JK7T46N6.js.map → detect-U3E7NVNW.js.map} +0 -0
  79. /package/dist/{hook-AC7APC66.js.map → hook-EVY7LOUQ.js.map} +0 -0
  80. /package/dist/{leaderboard-R5HRJHNU.js.map → leaderboard-CSWHI4UY.js.map} +0 -0
  81. /package/dist/{serve-LFOUSZAD.js.map → serve-3C2VFPAY.js.map} +0 -0
  82. /package/dist/{telemetry-3NVEXPYX.js.map → telemetry-3DN6XGYB.js.map} +0 -0
  83. /package/dist/{usage-G3GSCX23.js.map → usage-CJOM2WQM.js.map} +0 -0
  84. /package/dist/{usage-event-QUTMNBS5.js.map → usage-event-472X3DOY.js.map} +0 -0
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  print
4
- } from "./chunk-AKJGNTU3.js";
4
+ } from "./chunk-3RBLIHPZ.js";
5
5
  import {
6
6
  detectInstalledPlatforms
7
- } from "./chunk-O2SBA5KR.js";
7
+ } from "./chunk-NJU275US.js";
8
8
 
9
9
  // src/cli/commands/detect.ts
10
10
  import { parseArgs } from "util";
@@ -69,4 +69,4 @@ async function run(argv) {
69
69
  export {
70
70
  run
71
71
  };
72
- //# sourceMappingURL=detect-JK7T46N6.js.map
72
+ //# sourceMappingURL=detect-U3E7NVNW.js.map
@@ -1,21 +1,30 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ marketplaceDoctorChecks
4
+ } from "./chunk-KMAKDD3Z.js";
5
+ import "./chunk-WNREHWKL.js";
6
+ import {
7
+ readMarketplaceInstalls
8
+ } from "./chunk-G5CQHVQG.js";
2
9
  import {
3
10
  fail,
4
11
  parseScope,
5
12
  parseTargets,
6
13
  print
7
- } from "./chunk-AKJGNTU3.js";
14
+ } from "./chunk-3RBLIHPZ.js";
8
15
  import {
9
16
  LineBuffer,
10
17
  idKey,
11
- isObject,
18
+ isObject
19
+ } from "./chunk-OP4KBXUO.js";
20
+ import {
12
21
  spawnChild
13
- } from "./chunk-WCETQWWK.js";
22
+ } from "./chunk-KVAAFYRR.js";
14
23
  import {
15
24
  REGISTERED_PLATFORM_IDS,
16
25
  detectInstalledPlatforms,
17
26
  loadAdapter
18
- } from "./chunk-O2SBA5KR.js";
27
+ } from "./chunk-NJU275US.js";
19
28
  import {
20
29
  findConnectorConfig,
21
30
  listRegisteredConnectors,
@@ -24,6 +33,8 @@ import {
24
33
  import {
25
34
  MCP_PROTOCOL_VERSION
26
35
  } from "./chunk-GSGDG2BV.js";
36
+ import "./chunk-OPXAP3AC.js";
37
+ import "./chunk-7L6ITC4T.js";
27
38
  import "./chunk-MEH7GC7R.js";
28
39
  import "./chunk-N6HH7K6P.js";
29
40
  import {
@@ -311,6 +322,15 @@ async function run(argv) {
311
322
  const results = [];
312
323
  for (const connector of connectors) {
313
324
  if (connector.targets !== "auto" && !connector.targets.includes(id)) continue;
325
+ if (readMarketplaceInstalls(connector.id)[id]) {
326
+ const note = {
327
+ check: `${connector.id}: ${id} delivery`,
328
+ status: "pass",
329
+ message: "surfaces delivered via the marketplace plugin \u2014 see marketplace checks"
330
+ };
331
+ results.push(multi ? { ...note, check: `(${connector.id}) ${note.check}` } : note);
332
+ continue;
333
+ }
314
334
  const ctx = buildContext(connector, id, scope, projectDir);
315
335
  let r;
316
336
  try {
@@ -326,6 +346,16 @@ async function run(argv) {
326
346
  if (results.some((d) => d.status === "fail")) anyFail = true;
327
347
  byPlatform.push({ platform: id, results });
328
348
  }
349
+ for (const connector of connectors) {
350
+ const groups = await marketplaceDoctorChecks(connector, scope, projectDir);
351
+ for (const group of groups) {
352
+ const tagged = multi ? group.results.map((d) => ({ ...d, check: `(${connector.id}) ${d.check}` })) : group.results;
353
+ if (tagged.some((d) => d.status === "fail")) anyFail = true;
354
+ const bucket = byPlatform.find((b) => b.platform === group.platform);
355
+ if (bucket) bucket.results.push(...tagged);
356
+ else byPlatform.push({ platform: group.platform, results: tagged });
357
+ }
358
+ }
329
359
  const probes = [];
330
360
  if (values.probe) {
331
361
  for (const connector of connectors) {
@@ -377,4 +407,4 @@ async function run(argv) {
377
407
  export {
378
408
  run
379
409
  };
380
- //# sourceMappingURL=doctor-62BHIXOR.js.map
410
+ //# sourceMappingURL=doctor-DZTWED4O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/doctor.ts","../src/runtime/probe.ts"],"sourcesContent":["/**\n * cli/commands/doctor — health-check every detected platform.\n *\n * For each detected host (or the explicit --targets list) we load its adapter,\n * build a uniform InstallContext, and run adapter.doctor(ctx). Results are\n * printed as pass/warn/fail with any suggested fix. Exit code is non-zero when\n * any check fails (warns alone do not fail the command).\n *\n * The connector context comes from the local config when present; otherwise a\n * minimal id-only connector is used so path-only checks still run.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport type {\n DiagnosticResult,\n InstallScope,\n PlatformId,\n ResolvedConnector,\n} from \"../../core/types.js\";\nimport type { InstallContext } from \"../../adapters/spi.js\";\nimport { detectInstalledPlatforms } from \"../../adapters/detect.js\";\nimport { loadAdapter, REGISTERED_PLATFORM_IDS } from \"../../adapters/registry.js\";\nimport {\n findConnectorConfig,\n listRegisteredConnectors,\n loadConnectorFromPath,\n} from \"../../core/load-connector.js\";\nimport { marketplaceDoctorChecks } from \"../../core/marketplace.js\";\nimport { readMarketplaceInstalls } from \"../../core/marketplace-state.js\";\nimport { dataRoot, homeBinPath } from \"../../core/paths.js\";\nimport { probeStdioServer } from \"../../runtime/probe.js\";\nimport { fail, parseScope, parseTargets, print } from \"../app.js\";\n\nconst STATUS_GLYPH: Record<DiagnosticResult[\"status\"], string> = {\n pass: \"[pass]\",\n warn: \"[warn]\",\n fail: \"[FAIL]\",\n};\n\n/**\n * Resolve which connector(s) doctor should health-check, in precedence order:\n * 1. An explicit --connector path, or a local agent-connector.config.* file.\n * 2. Every connector registered under the data-root (what is actually\n * installed). This is the common case — `doctor` from anywhere reports on\n * the real installs, not a guess from the working directory.\n * 3. A minimal id-only placeholder so path-only checks still run.\n */\nasync function resolveDoctorConnectors(\n connectorPath: string | undefined,\n projectDir: string,\n): Promise<ResolvedConnector[]> {\n const configPath = connectorPath ?? findConnectorConfig(projectDir);\n if (configPath) {\n try {\n const { connector } = await loadConnectorFromPath(configPath);\n return [connector];\n } catch {\n /* fall through */\n }\n }\n\n const registered = listRegisteredConnectors();\n if (registered.length > 0) return registered;\n\n return [\n {\n id: \"agent-connector\",\n displayName: \"agent-connector\",\n version: \"0.0.0\",\n hooks: {},\n hookEvents: [],\n telemetry: {\n enabled: true,\n modelFamilyHint: \"auto\",\n measureToolDefs: true,\n hostNativeUsage: false,\n store: \"ndjson\",\n calibration: { anthropicCountTokens: false },\n },\n commands: [],\n skills: [],\n subagents: [],\n memory: [],\n platforms: {},\n targets: \"auto\",\n },\n ];\n}\n\nfunction buildContext(\n connector: ResolvedConnector,\n id: PlatformId,\n scope: InstallScope,\n projectDir: string,\n): InstallContext {\n return {\n connector,\n scope: connector.platforms[id]?.scope ?? scope,\n projectDir,\n homeBinPath: homeBinPath(),\n dataRoot: dataRoot(),\n dryRun: true,\n };\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n scope: { type: \"string\", default: \"user\" },\n targets: { type: \"string\" },\n connector: { type: \"string\" },\n project: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n probe: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n\n const scope = parseScope(values.scope);\n if (scope == null) return fail(`invalid --scope \"${values.scope}\" (use user|project)`);\n\n const connectors = await resolveDoctorConnectors(values.connector, projectDir);\n const multi = connectors.length > 1;\n\n // Target set: explicit --targets (intersected with the registry), else the\n // same chain install uses — connector-declared targets ∩ detected platforms\n // (\"auto\" = everything detected). Without this, doctor red-flags every\n // detected host the connector never targeted (found dogfooding context-mode:\n // targets:[5 ids] installed clean, doctor FAILed the other 9 detected hosts).\n const explicit = parseTargets(values.targets);\n let ids: PlatformId[];\n if (explicit && explicit.length > 0) {\n ids = explicit.filter((id) => REGISTERED_PLATFORM_IDS.has(id));\n } else {\n const detected = await detectInstalledPlatforms(projectDir);\n ids = detected.map((p) => p.id);\n const anyAuto = connectors.some((c) => c.targets === \"auto\");\n if (!anyAuto) {\n const targeted = new Set(connectors.flatMap((c) => c.targets as PlatformId[]));\n ids = ids.filter((id) => targeted.has(id));\n }\n }\n\n if (ids.length === 0 && !values.probe) {\n print(\"doctor: no target platforms (none detected; pass --targets to force).\");\n return 0;\n }\n\n const byPlatform: { platform: PlatformId; results: DiagnosticResult[] }[] = [];\n let anyFail = false;\n\n for (const id of ids) {\n const adapter = await loadAdapter(id);\n if (!adapter) {\n byPlatform.push({\n platform: id,\n results: [\n {\n check: `${id}: adapter`,\n status: \"fail\",\n message: `no adapter registered for ${id}`,\n },\n ],\n });\n anyFail = true;\n continue;\n }\n const results: DiagnosticResult[] = [];\n for (const connector of connectors) {\n // A connector with an explicit target list is only checked on those hosts.\n if (connector.targets !== \"auto\" && !connector.targets.includes(id)) continue;\n\n // MARKETPLACE-installed on this host: its surfaces are delivered via the\n // host's plugin (in the plugin cache), NOT the direct-config locations the\n // adapter's doctor() inspects — so the direct checks would falsely FAIL\n // (mcp_servers/command/skill \"not found\"). Skip them; the marketplace-method\n // checks below cover this install's real health.\n if (readMarketplaceInstalls(connector.id)[id]) {\n const note: DiagnosticResult = {\n check: `${connector.id}: ${id} delivery`,\n status: \"pass\",\n message: \"surfaces delivered via the marketplace plugin — see marketplace checks\",\n };\n results.push(multi ? { ...note, check: `(${connector.id}) ${note.check}` } : note);\n continue;\n }\n\n const ctx = buildContext(connector, id, scope, projectDir);\n let r: DiagnosticResult[];\n try {\n r = adapter.doctor(ctx);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n r = [{ check: `${adapter.name}: doctor`, status: \"fail\", message }];\n }\n // When checking multiple connectors, tag each check with the connector id.\n results.push(\n ...(multi\n ? r.map((d) => ({ ...d, check: `(${connector.id}) ${d.check}` }))\n : r),\n );\n }\n if (results.some((d) => d.status === \"fail\")) anyFail = true;\n byPlatform.push({ platform: id, results });\n }\n\n // ── Marketplace-method checks (framework-level, read-only fs — they run in\n // isolated homes without spawning a host CLI): duplicate-registration,\n // registration intact, state↔host drift, staleness, the embedded home-bin\n // launcher, missing host binary. Silent for connectors with no marketplace\n // state at all. Results merge into the platform's bucket (appended when the\n // platform was not otherwise targeted, e.g. a recorded install whose host\n // binary disappeared).\n for (const connector of connectors) {\n const groups = await marketplaceDoctorChecks(connector, scope, projectDir);\n for (const group of groups) {\n const tagged = multi\n ? group.results.map((d) => ({ ...d, check: `(${connector.id}) ${d.check}` }))\n : group.results;\n if (tagged.some((d) => d.status === \"fail\")) anyFail = true;\n const bucket = byPlatform.find((b) => b.platform === group.platform);\n if (bucket) bucket.results.push(...tagged);\n else byPlatform.push({ platform: group.platform, results: tagged });\n }\n }\n\n // ── Live MCP probe (--probe): connector-scoped, not platform-scoped ──────\n // Spawns each connector's REAL stdio server and runs initialize → ping →\n // tools/list. Probe FAILs fold into the doctor exit code.\n const probes: { connector: string; results: DiagnosticResult[] }[] = [];\n if (values.probe) {\n for (const connector of connectors) {\n const s = connector.server;\n if (!s || s.transport !== \"stdio\" || !s.command) {\n probes.push({\n connector: connector.id,\n results: [\n {\n check: `${connector.id}: MCP probe`,\n status: \"warn\",\n message: s\n ? `transport \"${s.transport}\" is not stdio — live probe skipped`\n : \"no server to probe\",\n },\n ],\n });\n continue;\n }\n const results = await probeStdioServer(s.command, s.args ?? [], {\n label: connector.id,\n ...(s.env ? { env: s.env } : {}),\n });\n if (results.some((d) => d.status === \"fail\")) anyFail = true;\n probes.push({ connector: connector.id, results });\n }\n }\n\n if (values.json) {\n print(JSON.stringify(values.probe ? { platforms: byPlatform, probes } : byPlatform, null, 2));\n return anyFail ? 1 : 0;\n }\n\n for (const { platform, results } of byPlatform) {\n print(`${platform}:`);\n for (const r of results) {\n print(` ${STATUS_GLYPH[r.status]} ${r.check} — ${r.message}`);\n if (r.fix) print(` fix: ${r.fix}`);\n }\n print(\"\");\n }\n for (const { connector, results } of probes) {\n print(`probe ${connector}:`);\n for (const r of results) {\n print(` ${STATUS_GLYPH[r.status]} ${r.check} — ${r.message}`);\n if (r.fix) print(` fix: ${r.fix}`);\n }\n print(\"\");\n }\n print(anyFail ? \"doctor: one or more checks FAILED.\" : \"doctor: all checks passed.\");\n return anyFail ? 1 : 0;\n}\n","/**\n * runtime/probe — a live MCP connection-lifecycle probe for `doctor --probe`.\n *\n * Where `doctor` checks files on disk, this spawns the connector's REAL stdio\n * server and speaks the MCP wire protocol to it: initialize → (read negotiated\n * protocolVersion + capabilities + serverInfo) → notifications/initialized →\n * ping (liveness) → tools/list (gated on the tools capability). It reuses the\n * SAME newline-delimited JSON-RPC framing + id-correlation as the telemetry\n * proxy (telemetry/jsonrpc), so the probe and the serve path read the wire\n * identically. Each step becomes a DiagnosticResult so doctor renders/aggregates\n * it uniformly; a dead/unlaunchable server FAILs (non-zero doctor exit).\n *\n * Negotiation rule: we OFFER {@link MCP_PROTOCOL_VERSION} but ACCEPT whatever\n * version the server returns (we only report it), per the spec — never a\n * hardcoded equality. There is no MCP shutdown message; we close stdin then\n * SIGTERM/SIGKILL.\n */\n\nimport type { DiagnosticResult } from \"../core/types.js\";\nimport { MCP_PROTOCOL_VERSION } from \"../core/mcp-standard.js\";\nimport { spawnChild } from \"../core/spawn-child.js\";\nimport { type JsonRpcMessage, LineBuffer, idKey, isObject } from \"../telemetry/jsonrpc.js\";\n\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nexport interface ProbeOptions {\n /** Per-step timeout in ms (default 5000). */\n timeoutMs?: number;\n /** Prefix for each DiagnosticResult.check (e.g. the connector id). */\n label?: string;\n /** Env merged over process.env for the spawned server (${env:VAR} resolved). */\n env?: Record<string, string>;\n /** Protocol version offered in initialize. Default {@link MCP_PROTOCOL_VERSION}. */\n protocolVersion?: string;\n}\n\nfunction diag(\n status: DiagnosticResult[\"status\"],\n check: string,\n message: string,\n fix?: string,\n): DiagnosticResult {\n return { check, status, message, ...(fix ? { fix } : {}) };\n}\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/** Resolve `${env:VAR}` references in env values against the current process env. */\nfunction resolveEnv(env: Record<string, string> | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(env ?? {})) {\n out[k] = v.replace(/\\$\\{env:([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_m, name) => process.env[name] ?? \"\");\n }\n return out;\n}\n\n/**\n * Spawn the stdio MCP server `command args` and run a real lifecycle probe.\n * Always resolves (never rejects) with one DiagnosticResult per step.\n */\nexport async function probeStdioServer(\n command: string,\n args: string[],\n opts: ProbeOptions = {},\n): Promise<DiagnosticResult[]> {\n const label = opts.label ? `${opts.label}: ` : \"\";\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const protocolVersion = opts.protocolVersion ?? MCP_PROTOCOL_VERSION;\n const results: DiagnosticResult[] = [];\n\n // spawnChild resolves a bare Windows package runner (npx/uvx → .cmd/.exe) so\n // the probe agrees with the live serve path; no-op on macOS/Linux.\n const child = spawnChild(command, args, {\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n env: { ...process.env, ...resolveEnv(opts.env) },\n });\n\n interface Pending {\n resolve: (m: JsonRpcMessage) => void;\n reject: (e: Error) => void;\n }\n const pending = new Map<string, Pending>();\n let spawnErr: Error | null = null;\n let exitCode: number | null = null;\n\n const rejectAll = (e: Error): void => {\n for (const p of pending.values()) p.reject(e);\n pending.clear();\n };\n child.on(\"error\", (e) => {\n spawnErr = e;\n rejectAll(e);\n });\n child.on(\"exit\", (code) => {\n exitCode = code ?? 0;\n rejectAll(new Error(`server exited (code ${exitCode}) before responding`));\n });\n\n const lines = new LineBuffer((line) => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n return; // non-JSON stdout noise — ignore\n }\n if (!isObject(parsed)) return;\n const k = idKey((parsed as JsonRpcMessage).id);\n if (k && pending.has(k)) {\n const p = pending.get(k)!;\n pending.delete(k);\n p.resolve(parsed as JsonRpcMessage);\n }\n });\n child.stdout?.on(\"data\", (c: Buffer) => lines.push(c));\n\n const send = (m: JsonRpcMessage): void => {\n if (child.stdin && child.stdin.writable) child.stdin.write(`${JSON.stringify(m)}\\n`);\n };\n const request = (id: number | string, method: string, params?: unknown): Promise<JsonRpcMessage> => {\n const key = idKey(id)!;\n return new Promise<JsonRpcMessage>((resolve, reject) => {\n const timer = setTimeout(() => {\n pending.delete(key);\n reject(new Error(`no response within ${timeoutMs}ms`));\n }, timeoutMs);\n if (typeof timer.unref === \"function\") timer.unref();\n pending.set(key, {\n resolve: (m) => {\n clearTimeout(timer);\n resolve(m);\n },\n reject: (e) => {\n clearTimeout(timer);\n reject(e);\n },\n });\n send({ jsonrpc: \"2.0\", id, method, ...(params !== undefined ? { params } : {}) });\n });\n };\n\n const cleanup = (): DiagnosticResult[] => {\n try {\n if (child.stdin && child.stdin.writable) child.stdin.end();\n } catch {\n /* ignore */\n }\n try {\n child.kill(\"SIGTERM\");\n } catch {\n /* ignore */\n }\n const killTimer = setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }, 500);\n if (typeof killTimer.unref === \"function\") killTimer.unref();\n return results;\n };\n\n // 1. initialize\n let initResult: Record<string, unknown>;\n try {\n const res = await request(1, \"initialize\", {\n protocolVersion,\n capabilities: {},\n clientInfo: { name: \"agent-connector-probe\", version: \"1\" },\n });\n if (isObject(res.error)) {\n results.push(\n diag(\"fail\", `${label}MCP initialize`, `server returned error: ${JSON.stringify(res.error)}`),\n );\n return cleanup();\n }\n initResult = isObject(res.result) ? res.result : {};\n } catch (e) {\n if (spawnErr) {\n results.push(\n diag(\n \"fail\",\n `${label}MCP initialize`,\n `server not launchable: ${errMsg(spawnErr)}`,\n `check that \"${command}\" is installed and on PATH`,\n ),\n );\n } else if (exitCode !== null) {\n // On Windows an unresolvable command surfaces as an early non-zero exit\n // (cmd.exe \"command not found\") rather than a spawn 'error' event, so fold\n // the not-launchable hint in here too — useful whether the command is\n // missing or the server genuinely crashed before initialize.\n results.push(\n diag(\n \"fail\",\n `${label}MCP initialize`,\n `server not launchable, or it exited (code ${exitCode}) before initialize`,\n `check that \"${command}\" is installed and on PATH`,\n ),\n );\n } else {\n results.push(diag(\"fail\", `${label}MCP initialize`, errMsg(e)));\n }\n return cleanup();\n }\n\n const serverInfo = isObject(initResult.serverInfo) ? initResult.serverInfo : {};\n const sName = typeof serverInfo.name === \"string\" ? serverInfo.name : \"unknown\";\n const sVer = typeof serverInfo.version === \"string\" ? serverInfo.version : \"?\";\n const negotiated =\n typeof initResult.protocolVersion === \"string\" ? initResult.protocolVersion : \"(none)\";\n results.push(diag(\"pass\", `${label}MCP initialize`, `serverInfo ${sName}@${sVer}, protocol ${negotiated}`));\n\n // capabilities (presence = feature offered)\n const caps = isObject(initResult.capabilities) ? initResult.capabilities : {};\n const capNames = [\"tools\", \"resources\", \"prompts\", \"logging\", \"completions\"].filter((c) => c in caps);\n results.push(\n diag(\"pass\", `${label}capabilities`, capNames.length > 0 ? capNames.join(\", \") : \"(none advertised)\"),\n );\n\n // 2. initialized notification (required before normal requests)\n send({ jsonrpc: \"2.0\", method: \"notifications/initialized\" });\n\n // 3. ping — liveness confirm (warn, not fail, on timeout)\n try {\n await request(\"probe-ping\", \"ping\");\n results.push(diag(\"pass\", `${label}ping`, \"alive\"));\n } catch (e) {\n results.push(diag(\"warn\", `${label}ping`, `no ping response (${errMsg(e)})`));\n }\n\n // 4. tools/list — only if the server advertised a tools capability\n if (\"tools\" in caps) {\n try {\n const res = await request(2, \"tools/list\", {});\n const r = isObject(res.result) ? res.result : {};\n const tools = Array.isArray(r.tools) ? r.tools : [];\n results.push(diag(\"pass\", `${label}tools/list`, `${tools.length} tool(s)`));\n } catch (e) {\n results.push(diag(\"fail\", `${label}tools/list`, `no tools/list response (${errMsg(e)})`));\n }\n } else {\n results.push(\n diag(\"warn\", `${label}tools/list`, \"skipped — server advertised no tools capability\"),\n );\n }\n\n return cleanup();\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fail
4
- } from "./chunk-AKJGNTU3.js";
4
+ } from "./chunk-3RBLIHPZ.js";
5
5
  import {
6
6
  isNativeHookDeclared,
7
7
  runHook,
8
8
  runNativeHook
9
- } from "./chunk-4ML7SZ7R.js";
9
+ } from "./chunk-ZAM4M7LI.js";
10
10
  import "./chunk-BCHWFTV4.js";
11
- import "./chunk-KHO5WNTP.js";
12
- import "./chunk-WCETQWWK.js";
13
- import "./chunk-O2SBA5KR.js";
11
+ import "./chunk-OP4KBXUO.js";
12
+ import "./chunk-KVAAFYRR.js";
13
+ import "./chunk-NJU275US.js";
14
14
  import "./chunk-3JCRUROU.js";
15
15
  import "./chunk-GSGDG2BV.js";
16
16
  import "./chunk-MEH7GC7R.js";
@@ -87,4 +87,4 @@ function exitWithReply(reply) {
87
87
  export {
88
88
  run
89
89
  };
90
- //# sourceMappingURL=hook-AC7APC66.js.map
90
+ //# sourceMappingURL=hook-EVY7LOUQ.js.map
@@ -1,21 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- installConnector
4
- } from "./chunk-Z2BVYKZL.js";
3
+ installConnector,
4
+ installViaMarketplace,
5
+ parseInstallMethod
6
+ } from "./chunk-KMAKDD3Z.js";
7
+ import "./chunk-WNREHWKL.js";
8
+ import "./chunk-G5CQHVQG.js";
5
9
  import {
6
10
  fail,
7
11
  parseScope,
8
12
  parseTargets,
9
13
  print,
10
14
  renderInstallResult
11
- } from "./chunk-AKJGNTU3.js";
12
- import "./chunk-KHO5WNTP.js";
13
- import "./chunk-O2SBA5KR.js";
15
+ } from "./chunk-3RBLIHPZ.js";
16
+ import "./chunk-KVAAFYRR.js";
17
+ import "./chunk-NJU275US.js";
14
18
  import {
15
19
  findConnectorConfig,
16
20
  loadConnectorFromPath
17
21
  } from "./chunk-3JCRUROU.js";
18
22
  import "./chunk-GSGDG2BV.js";
23
+ import "./chunk-OPXAP3AC.js";
24
+ import "./chunk-7L6ITC4T.js";
25
+ import "./chunk-MEH7GC7R.js";
19
26
  import "./chunk-N6HH7K6P.js";
20
27
  import "./chunk-TRQKHP7D.js";
21
28
 
@@ -25,6 +32,7 @@ async function run(argv) {
25
32
  const { values } = parseArgs({
26
33
  args: argv,
27
34
  options: {
35
+ method: { type: "string", default: "direct" },
28
36
  scope: { type: "string", default: "user" },
29
37
  targets: { type: "string" },
30
38
  connector: { type: "string" },
@@ -36,6 +44,10 @@ async function run(argv) {
36
44
  },
37
45
  allowPositionals: false
38
46
  });
47
+ const method = parseInstallMethod(values.method);
48
+ if (method == null) {
49
+ return fail(`invalid --method "${values.method}" (use direct|marketplace)`);
50
+ }
39
51
  const projectDir = values.project ?? process.cwd();
40
52
  const configPath = values.connector ?? findConnectorConfig(projectDir);
41
53
  if (!configPath) {
@@ -45,9 +57,21 @@ async function run(argv) {
45
57
  }
46
58
  const scope = parseScope(values.scope);
47
59
  if (scope == null) return fail(`invalid --scope "${values.scope}" (use user|project)`);
60
+ if (method === "marketplace" && scope !== "user") {
61
+ return fail(
62
+ "--method marketplace supports --scope user only (project-scope plugin installs are deferred)"
63
+ );
64
+ }
48
65
  const { connector, modulePath } = await loadConnectorFromPath(configPath);
49
66
  const targets = parseTargets(values.targets);
50
- const result = await installConnector({
67
+ const result = method === "marketplace" ? await installViaMarketplace({
68
+ connector,
69
+ modulePath,
70
+ scope,
71
+ projectDir,
72
+ dryRun: values["dry-run"],
73
+ ...targets ? { targets } : {}
74
+ }) : await installConnector({
51
75
  connector,
52
76
  modulePath,
53
77
  scope,
@@ -62,4 +86,4 @@ async function run(argv) {
62
86
  export {
63
87
  run
64
88
  };
65
- //# sourceMappingURL=install-DMW2C7SV.js.map
89
+ //# sourceMappingURL=install-OWAS5UIE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/install.ts"],"sourcesContent":["/**\n * cli/commands/install — deploy a connector across its target platforms.\n *\n * Resolves the connector config (--connector <path>, else findConnectorConfig\n * walking up from the project dir), loads it into a live ResolvedConnector, and\n * hands it to the chosen DELIVERY METHOD's orchestration:\n *\n * --method direct (default) — the installer renders each host's native\n * MCP + hook + content config in place (zero behavior\n * change for existing scripts).\n * --method marketplace — stage the connector's plugin bundle under the\n * data-root and DRIVE the host's own plugin/marketplace\n * install flow (v1 driver: claude-code; other hosts get\n * never-silent skip/warn records with manual commands).\n *\n * Both methods emit the same ChangeRecords, rendered as a readable diff;\n * --dry-run renders the plan without writing or spawning. A double-install\n * guard (both directions) enforces exactly one method per (connector, host,\n * scope) — a refusal is a `warn` record, so the exit-1-on-warn convention\n * carries over.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport { installConnector } from \"../../core/installer.js\";\nimport { installViaMarketplace, parseInstallMethod } from \"../../core/marketplace.js\";\nimport { findConnectorConfig, loadConnectorFromPath } from \"../../core/load-connector.js\";\nimport { fail, parseScope, parseTargets, print, renderInstallResult } from \"../app.js\";\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n method: { type: \"string\", default: \"direct\" },\n scope: { type: \"string\", default: \"user\" },\n targets: { type: \"string\" },\n connector: { type: \"string\" },\n project: { type: \"string\" },\n \"dry-run\": { type: \"boolean\", default: false },\n // Memory surface: overwrite USER-EDITED managed blocks (hash drift).\n // Default behavior is warn-and-leave; --force backs the file up first.\n force: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const method = parseInstallMethod(values.method);\n if (method == null) {\n return fail(`invalid --method \"${values.method}\" (use direct|marketplace)`);\n }\n\n const projectDir = values.project ?? process.cwd();\n const configPath = values.connector ?? findConnectorConfig(projectDir);\n if (!configPath) {\n return fail(\n \"no connector config found. Pass --connector <path> or add an \" +\n \"agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n\n const scope = parseScope(values.scope);\n if (scope == null) return fail(`invalid --scope \"${values.scope}\" (use user|project)`);\n if (method === \"marketplace\" && scope !== \"user\") {\n return fail(\n \"--method marketplace supports --scope user only (project-scope plugin installs are deferred)\",\n );\n }\n\n const { connector, modulePath } = await loadConnectorFromPath(configPath);\n const targets = parseTargets(values.targets);\n\n const result =\n method === \"marketplace\"\n ? await installViaMarketplace({\n connector,\n modulePath,\n scope,\n projectDir,\n dryRun: values[\"dry-run\"],\n ...(targets ? { targets } : {}),\n })\n : await installConnector({\n connector,\n modulePath,\n scope,\n projectDir,\n dryRun: values[\"dry-run\"],\n force: values.force,\n ...(targets ? { targets } : {}),\n });\n\n print(renderInstallResult(result, \"install\"));\n return result.changes.some((c) => c.action === \"warn\") ? 1 : 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAS,iBAAiB;AAO1B,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,OAAO,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,QAAQ,EAAE,MAAM,UAAU,SAAS,SAAS;AAAA,MAC5C,OAAO,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,MACzC,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,SAAS;AAAA,MAC5B,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA;AAAA;AAAA,MAG7C,OAAO,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,IAC3C;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,SAAS,mBAAmB,OAAO,MAAM;AAC/C,MAAI,UAAU,MAAM;AAClB,WAAO,KAAK,qBAAqB,OAAO,MAAM,4BAA4B;AAAA,EAC5E;AAEA,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AACjD,QAAM,aAAa,OAAO,aAAa,oBAAoB,UAAU;AACrE,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,MAAI,SAAS,KAAM,QAAO,KAAK,oBAAoB,OAAO,KAAK,sBAAsB;AACrF,MAAI,WAAW,iBAAiB,UAAU,QAAQ;AAChD,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,WAAW,WAAW,IAAI,MAAM,sBAAsB,UAAU;AACxE,QAAM,UAAU,aAAa,OAAO,OAAO;AAE3C,QAAM,SACJ,WAAW,gBACP,MAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,SAAS;AAAA,IACxB,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC,IACD,MAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,SAAS;AAAA,IACxB,OAAO,OAAO;AAAA,IACd,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC;AAEP,QAAM,oBAAoB,QAAQ,SAAS,CAAC;AAC5C,SAAO,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,IAAI;AAC/D;","names":[]}