@ken-jo/agent-connector 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/chunk-44HUXXC6.js +284 -0
- package/dist/chunk-44HUXXC6.js.map +1 -0
- package/dist/{chunk-AKJGNTU3.js → chunk-DS3LUFVN.js} +21 -21
- package/dist/chunk-DS3LUFVN.js.map +1 -0
- package/dist/{chunk-KHO5WNTP.js → chunk-KVAAFYRR.js} +18 -2
- package/dist/chunk-KVAAFYRR.js.map +1 -0
- package/dist/{chunk-O2SBA5KR.js → chunk-NJU275US.js} +9 -9
- package/dist/{chunk-WCETQWWK.js → chunk-OP4KBXUO.js} +1 -17
- package/dist/chunk-OP4KBXUO.js.map +1 -0
- package/dist/chunk-QADSG2JY.js +1989 -0
- package/dist/chunk-QADSG2JY.js.map +1 -0
- package/dist/{package-O63K4S7T.js → chunk-WNREHWKL.js} +20 -114
- package/dist/chunk-WNREHWKL.js.map +1 -0
- package/dist/{chunk-4ML7SZ7R.js → chunk-ZAM4M7LI.js} +7 -7
- package/dist/cli/sdk.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/{detect-JK7T46N6.js → detect-MNDHGLSV.js} +3 -3
- package/dist/{doctor-62BHIXOR.js → doctor-N5KZDD55.js} +35 -5
- package/dist/doctor-N5KZDD55.js.map +1 -0
- package/dist/{hook-AC7APC66.js → hook-7LUOKIXH.js} +6 -6
- package/dist/{install-DMW2C7SV.js → install-TQTT4F3I.js} +31 -7
- package/dist/install-TQTT4F3I.js.map +1 -0
- package/dist/kilo-PKAJCWPX.js +852 -0
- package/dist/kilo-PKAJCWPX.js.map +1 -0
- package/dist/{kilo-cli-2RNODHWY.js → kilo-cli-QWUVXG2O.js} +157 -6
- package/dist/kilo-cli-QWUVXG2O.js.map +1 -0
- package/dist/{kimi-Q5RG7CYT.js → kimi-EVD7YKXS.js} +79 -4
- package/dist/kimi-EVD7YKXS.js.map +1 -0
- package/dist/{kiro-EKTRW424.js → kiro-UQRY6EIO.js} +68 -3
- package/dist/kiro-UQRY6EIO.js.map +1 -0
- package/dist/{leaderboard-R5HRJHNU.js → leaderboard-MUJ7DURM.js} +2 -2
- package/dist/package-SYPA5POO.js +130 -0
- package/dist/package-SYPA5POO.js.map +1 -0
- package/dist/{pi-SJPIL4VE.js → pi-WMTUX6ES.js} +102 -23
- package/dist/pi-WMTUX6ES.js.map +1 -0
- package/dist/{qwen-code-IFCM6BJY.js → qwen-code-MRRIUQ3P.js} +78 -5
- package/dist/qwen-code-MRRIUQ3P.js.map +1 -0
- package/dist/runtime/index.js +4 -4
- package/dist/{serve-LFOUSZAD.js → serve-XJOSA7BY.js} +6 -6
- package/dist/{status-M7JLZVLC.js → status-DYSS6BOR.js} +16 -7
- package/dist/status-DYSS6BOR.js.map +1 -0
- package/dist/{telemetry-3NVEXPYX.js → telemetry-IJ4GP2Q3.js} +2 -2
- package/dist/uninstall-3DXIBRCV.js +162 -0
- package/dist/uninstall-3DXIBRCV.js.map +1 -0
- package/dist/{upgrade-76BQZBMA.js → upgrade-GJEB3ITY.js} +26 -8
- package/dist/upgrade-GJEB3ITY.js.map +1 -0
- package/dist/{usage-G3GSCX23.js → usage-2BJLM3GJ.js} +2 -2
- package/dist/{usage-event-QUTMNBS5.js → usage-event-472X3DOY.js} +5 -5
- package/dist/{warp-LLOSXR7A.js → warp-X6MB67NT.js} +81 -3
- package/dist/warp-X6MB67NT.js.map +1 -0
- package/dist/{zed-HYOITK7F.js → zed-NTCYW4V2.js} +68 -3
- package/dist/zed-NTCYW4V2.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-AKJGNTU3.js.map +0 -1
- package/dist/chunk-KHO5WNTP.js.map +0 -1
- package/dist/chunk-WCETQWWK.js.map +0 -1
- package/dist/chunk-Z2BVYKZL.js +0 -369
- package/dist/chunk-Z2BVYKZL.js.map +0 -1
- package/dist/doctor-62BHIXOR.js.map +0 -1
- package/dist/install-DMW2C7SV.js.map +0 -1
- package/dist/kilo-ISR5FBBJ.js +0 -408
- package/dist/kilo-ISR5FBBJ.js.map +0 -1
- package/dist/kilo-cli-2RNODHWY.js.map +0 -1
- package/dist/kimi-Q5RG7CYT.js.map +0 -1
- package/dist/kiro-EKTRW424.js.map +0 -1
- package/dist/package-O63K4S7T.js.map +0 -1
- package/dist/pi-SJPIL4VE.js.map +0 -1
- package/dist/qwen-code-IFCM6BJY.js.map +0 -1
- package/dist/status-M7JLZVLC.js.map +0 -1
- package/dist/uninstall-H6FGMIHN.js +0 -73
- package/dist/uninstall-H6FGMIHN.js.map +0 -1
- package/dist/upgrade-76BQZBMA.js.map +0 -1
- package/dist/warp-LLOSXR7A.js.map +0 -1
- package/dist/zed-HYOITK7F.js.map +0 -1
- /package/dist/{chunk-O2SBA5KR.js.map → chunk-NJU275US.js.map} +0 -0
- /package/dist/{chunk-4ML7SZ7R.js.map → chunk-ZAM4M7LI.js.map} +0 -0
- /package/dist/{detect-JK7T46N6.js.map → detect-MNDHGLSV.js.map} +0 -0
- /package/dist/{hook-AC7APC66.js.map → hook-7LUOKIXH.js.map} +0 -0
- /package/dist/{leaderboard-R5HRJHNU.js.map → leaderboard-MUJ7DURM.js.map} +0 -0
- /package/dist/{serve-LFOUSZAD.js.map → serve-XJOSA7BY.js.map} +0 -0
- /package/dist/{telemetry-3NVEXPYX.js.map → telemetry-IJ4GP2Q3.js.map} +0 -0
- /package/dist/{usage-G3GSCX23.js.map → usage-2BJLM3GJ.js.map} +0 -0
- /package/dist/{usage-event-QUTMNBS5.js.map → usage-event-472X3DOY.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/installer.ts","../src/core/marketplace.ts","../src/core/marketplace-drivers/claude.ts","../src/core/marketplace-drivers/shared.ts","../src/core/marketplace-drivers/codex.ts","../src/core/marketplace-drivers/agy.ts","../src/core/marketplace-drivers/registry.ts"],"sourcesContent":["/**\n * core/installer — install / uninstall / sync orchestration.\n *\n * This is the coordination layer that sits above the per-platform adapters. It\n * does NOT know any platform's native dialect (that is the adapter's job); it\n * owns the cross-cutting choreography that every install flow shares:\n *\n * 1. Refresh the single stable home binary (so every host's pointer config\n * keeps execing a working CLI) and register the connector's serializable\n * metadata so the runtime can re-import live handlers later.\n * 2. Resolve the set of target platforms — explicit flag → connector targets →\n * auto-detected installed hosts — intersected with the registry's known ids.\n * 3. For each target: load its adapter, build a uniform InstallContext, back up\n * the native settings, then render the MCP server + hooks (install) or strip\n * them (uninstall). Per-adapter failures are captured as `warn` ChangeRecords\n * and never abort the whole run — partial success is always reported.\n *\n * `sync` is just an idempotent re-run of `install`: adapters are write-idempotent\n * (identical entries yield \"skip\"), and `ensureHomeBin` heals a stale/missing\n * home-bin pointer on every pass (docs/ARCHITECTURE.md §3 R1 / \"sync … heals\n * stale pointers\").\n */\n\nimport { existsSync, readdirSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type {\n ChangeRecord,\n InstallResult,\n InstallScope,\n PlatformId,\n ResolvedConnector,\n} from \"./types.js\";\nimport type { Adapter, InstallContext } from \"../adapters/spi.js\";\nimport { REGISTERED_PLATFORM_IDS, loadAdapter } from \"../adapters/registry.js\";\nimport { detectInstalledPlatforms } from \"../adapters/detect.js\";\nimport {\n deregisterConnector,\n loadRegisteredConnector,\n registerConnector,\n} from \"./load-connector.js\";\nimport {\n connectorDir,\n connectorsDir,\n dataRoot,\n ensureHomeBin,\n homeBinPath,\n} from \"./paths.js\";\nimport { configPatchManualEdit } from \"./config-patch-ledger.js\";\nimport { hasMemoryLedger } from \"./managed-block.js\";\nimport {\n anyMarketplaceRecordsRemain,\n connectorHasMarketplaceRecords,\n marketplaceEvidence,\n} from \"./marketplace-state.js\";\nimport { log } from \"./logger.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Options\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Options for {@link installConnector} / {@link syncConnector}. */\nexport interface OrchestrationOptions {\n /** The live, resolved connector (with hook handlers) to deploy. */\n connector: ResolvedConnector;\n /** Absolute path to the source module that produced `connector`. */\n modulePath: string;\n /** Default install scope; per-platform overrides win where present. */\n scope: InstallScope;\n /** Resolved project root used by project-scoped adapters and detection. */\n projectDir: string;\n /** Explicit target allow-list. Omit to derive from the connector / detection. */\n targets?: PlatformId[];\n /** Render but do not write anything. */\n dryRun: boolean;\n /**\n * Overwrite USER-EDITED managed memory blocks (hash drift). Default false:\n * drift is reported as a `warn` and the user's in-block edits are left\n * intact. With force, a one-time timestamped backup is written first.\n */\n force?: boolean;\n}\n\n/** Options for {@link uninstallConnector}. */\nexport interface UninstallOptions {\n /** Id of a previously-registered connector to tear down. */\n connectorId: string;\n /** Default scope to uninstall from; per-platform overrides win. */\n scope: InstallScope;\n /** Resolved project root used by project-scoped adapters and detection. */\n projectDir: string;\n /** Explicit target allow-list. Omit to derive from the connector / detection. */\n targets?: PlatformId[];\n /** Compute changes but do not write anything. */\n dryRun: boolean;\n /**\n * Also remove the framework-state for this connector after stripping every\n * per-target registration: the DATA-dir connector record (connectorDir(id)) and,\n * when no connectors remain, the shared home-bin launcher. Respects dryRun (no\n * mutation, but the would-be changes are still reported).\n */\n purge?: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Public orchestration\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Install a connector across its target platforms.\n *\n * Steps mirror docs/ARCHITECTURE.md §8 (\"Install per target\"):\n * 1. Refresh the stable home binary + register connector metadata.\n * 2. Resolve targets (flag → connector.targets → auto-detect) ∩ registry ids.\n * 3. Per target: backup → installServer → installHooks, collecting changes.\n * Per-adapter errors become `warn` records; the run never aborts midway.\n */\nexport async function installConnector(\n opts: OrchestrationOptions,\n): Promise<InstallResult> {\n const { connector, modulePath, scope, projectDir, dryRun, force } = opts;\n\n // 1. Stable home binary + connector registry record. These are framework-state\n // mutations (never platform-native config) and are safe to skip on dry-run.\n if (!dryRun) {\n try {\n ensureHomeBin(resolveCliEntry());\n } catch (err) {\n log.warn(`ensureHomeBin failed: ${errMessage(err)}`);\n }\n try {\n registerConnector(connector, modulePath);\n } catch (err) {\n log.warn(`registerConnector failed: ${errMessage(err)}`);\n }\n }\n\n const targets = await resolveTargets(opts.targets, connector.targets, projectDir);\n const result = newResult(connector.id, dryRun);\n\n if (targets.length === 0) {\n result.warnings.push(\n \"no target platforms resolved (none installed / detected, or all filtered out)\",\n );\n return result;\n }\n\n for (const id of targets) {\n // Double-install guard (inverse direction): a connector present BOTH\n // directly and as a host plugin duplicates hooks + the MCP server and\n // corrupts telemetry — exactly one method per (connector, host, scope).\n // The probe is state-file-first then read-only host fs (it also catches\n // installs the user performed manually from `package`'s instructions) and\n // refuses ONLY on positive evidence; unreadable/unknown proceeds.\n const evidence = marketplaceEvidence(connector.id, id);\n if (evidence) {\n const detail =\n `\"${connector.id}\" is already installed via MARKETPLACE on ${id} (${evidence}) — ` +\n `refusing the direct install. Run \\`agent-connector uninstall --method marketplace ` +\n `--targets ${id}\\` first, or keep the marketplace install.`;\n result.changes.push({ platform: id, action: \"warn\", detail });\n result.warnings.push(detail);\n continue;\n }\n\n const adapter = await tryLoadAdapter(id, result);\n if (!adapter) continue;\n\n const ctx = buildContext(connector, id, scope, projectDir, dryRun, force);\n\n // Back up native settings before any mutation (no-op on dry-run / absent file).\n if (!dryRun) {\n runStep(id, \"backupSettings\", result, () => {\n const backup = adapter.backupSettings(ctx);\n if (backup) {\n result.changes.push({\n platform: id,\n action: \"create\",\n path: backup,\n detail: \"backed up settings before install\",\n });\n }\n });\n }\n\n runStep(id, \"installServer\", result, () => {\n pushAll(result.changes, adapter.installServer(ctx));\n });\n runStep(id, \"installHooks\", result, () => {\n pushAll(result.changes, adapter.installHooks(ctx));\n });\n\n // Native passthrough hooks declared for THIS platform but not supported by\n // its adapter: the standard skip-warn ChangeRecord (never silent), mirroring\n // BaseAdapter.unsupportedSurface. nativeHooks is per-platform-keyed, so a\n // declaration only ever concerns the platform it was declared under; the\n // supporting adapters (capabilities.supportsNativeHooks) install the entries\n // themselves inside installHooks.\n const nativeHooks = connector.platforms[id]?.nativeHooks;\n const nativeCount = nativeHooks ? Object.keys(nativeHooks).length : 0;\n if (nativeCount > 0 && !(adapter.capabilities.supportsNativeHooks ?? false)) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail: `nativeHooks not supported on ${id}; ${nativeCount} skipped`,\n });\n }\n\n // Content surfaces: guarded by declaration so undeclared surfaces add no\n // noise. BaseAdapter defines all six, so the `!` is safe; per-step\n // try/catch (runStep) turns any adapter failure into a warn, never aborting.\n if (connector.commands.length) {\n runStep(id, \"installCommands\", result, () => {\n pushAll(result.changes, adapter.installCommands!(ctx));\n });\n }\n if (connector.skills.length) {\n runStep(id, \"installSkills\", result, () => {\n pushAll(result.changes, adapter.installSkills!(ctx));\n });\n }\n if (connector.subagents.length) {\n runStep(id, \"installSubagents\", result, () => {\n pushAll(result.changes, adapter.installSubagents!(ctx));\n });\n }\n // Memory (managed blocks in the host's memory/rules file) installs LAST\n // among the content surfaces; uninstall removes it FIRST (the inverse).\n // `?? []` tolerates pre-resolved connectors from versions before the\n // memory surface existed (loadConnectorFromPath passes those through).\n if ((connector.memory ?? []).length) {\n runStep(id, \"installMemory\", result, () => {\n pushAll(result.changes, adapter.installMemory!(ctx));\n });\n }\n\n // Declarative host-config key patches — LAST on install (so the reported\n // diff reflects final state; uninstall runs them FIRST, the inverse).\n // Unsupported hosts get the exact nativeHooks skip-warn treatment, plus\n // the per-patch manual-edit instructions (reason/docsUrl) so a skipped\n // declaration still documents the manual step. Never silent.\n const configPatches = connector.platforms[id]?.configPatch ?? [];\n if (configPatches.length > 0) {\n if (adapter.capabilities.supportsConfigPatch ?? false) {\n runStep(id, \"installConfigPatches\", result, () => {\n pushAll(result.changes, adapter.installConfigPatches!(ctx));\n });\n } else {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail: `configPatch not supported on ${id}; ${configPatches.length} skipped`,\n });\n for (const patch of configPatches) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail: `configPatch ${patch.key} skipped on ${id} — ${configPatchManualEdit(patch)}`,\n });\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Idempotent re-run of {@link installConnector}: every adapter re-renders its\n * config (identical entries report \"skip\"), and `ensureHomeBin` repairs a stale\n * or missing home-bin pointer. Use after editing a connector or upgrading the\n * framework. Behaviorally identical to install — the distinct name documents\n * intent and gives the CLI a stable verb to wire `agent-connector sync` to.\n */\nexport async function syncConnector(\n opts: OrchestrationOptions,\n): Promise<InstallResult> {\n return installConnector(opts);\n}\n\n/**\n * Uninstall a previously-registered connector: strip its hook registrations and\n * MCP server entries from every target platform. The registered connector is\n * loaded (best-effort) only to provide adapter context (server id, hook ids,\n * per-platform overrides); when it cannot be loaded a minimal synthetic\n * connector built from the id still lets adapters locate and remove their\n * entries (they key removals off `connector.id` + the home-bin path).\n */\nexport async function uninstallConnector(\n opts: UninstallOptions,\n): Promise<InstallResult> {\n const { connectorId, scope, projectDir, dryRun, purge } = opts;\n\n const connector = await loadConnectorForUninstall(connectorId);\n const result = newResult(connectorId, dryRun);\n\n const targets = await resolveTargets(opts.targets, connector.targets, projectDir);\n if (targets.length === 0) {\n result.warnings.push(\n \"no target platforms resolved for uninstall (none installed / detected, or all filtered out)\",\n );\n // --purge still removes the orphan framework-state even when no host targets\n // resolve (e.g. the user already uninstalled from every host).\n if (purge) purgeFrameworkState(connectorId, dryRun, result);\n return result;\n }\n\n for (const id of targets) {\n const adapter = await tryLoadAdapter(id, result);\n if (!adapter) continue;\n\n const ctx = buildContext(connector, id, scope, projectDir, dryRun);\n\n // Inverse order of install: config patches FIRST (install applies them\n // last), then content surfaces, then hooks, then the server entry. The\n // configPatch step is keyed off the persisted ownership LEDGER inside the\n // adapter (not just the declaration), so it still releases/removes owned\n // keys when the connector record is a minimal synthetic fallback. Only\n // supporting adapters can have applied patches, so others are skipped.\n if (adapter.capabilities.supportsConfigPatch ?? false) {\n runStep(id, \"uninstallConfigPatches\", result, () => {\n pushAll(result.changes, adapter.uninstallConfigPatches!(ctx));\n });\n }\n\n // Memory is removed FIRST among the content surfaces (inverse of its\n // install-last position). The guard is widened beyond the declaration:\n // an id-only synthetic uninstall (connector record lost) still reclaims\n // blocks via the persisted memory ledger + the marker prefix-scan.\n // (`?? []` tolerates pre-memory-surface resolved connectors.)\n if ((connector.memory ?? []).length > 0 || hasMemoryLedger(connector.id)) {\n runStep(id, \"uninstallMemory\", result, () => {\n pushAll(result.changes, adapter.uninstallMemory!(ctx));\n });\n }\n\n // Surface removals are guarded by declaration; BaseAdapter defines all six\n // so the `!` is safe.\n if (connector.subagents.length) {\n runStep(id, \"uninstallSubagents\", result, () => {\n pushAll(result.changes, adapter.uninstallSubagents!(ctx));\n });\n }\n if (connector.commands.length) {\n runStep(id, \"uninstallCommands\", result, () => {\n pushAll(result.changes, adapter.uninstallCommands!(ctx));\n });\n }\n if (connector.skills.length) {\n runStep(id, \"uninstallSkills\", result, () => {\n pushAll(result.changes, adapter.uninstallSkills!(ctx));\n });\n }\n runStep(id, \"uninstallHooks\", result, () => {\n pushAll(result.changes, adapter.uninstallHooks(ctx));\n });\n runStep(id, \"uninstallServer\", result, () => {\n pushAll(result.changes, adapter.uninstallServer(ctx));\n });\n }\n\n // --purge: after every per-target registration is stripped, also remove the\n // framework-state this connector left behind (its DATA-dir record and, when no\n // connectors remain, the shared home-bin launcher).\n if (purge) purgeFrameworkState(connectorId, dryRun, result);\n\n return result;\n}\n\n/**\n * Remove the framework-state a connector left behind (the inverse of install's\n * registerConnector + ensureHomeBin):\n * 1. Deregister the DATA-dir connector record (connectorDir(id)).\n * 2. When no connector records remain, remove the shared home-bin launcher.\n * All steps are guarded/best-effort and respect dryRun — on a dry run nothing is\n * mutated, but the would-be `remove` changes are still reported.\n *\n * MARKETPLACE guard: an installed host plugin's hooks exec the home-bin OUTSIDE\n * any adapter-managed config, and the connector record (which contains\n * marketplace-installs.json) is what lets that install be reversed later. So a\n * purge REFUSES to remove this connector's record while it still records\n * marketplace installs, and refuses to remove the home-bin while ANY\n * connector's marketplace installs survive.\n *\n * Exported for the uninstall command's marketplace path (which needs the\n * framework purge when no direct targets remain to run uninstallConnector for).\n */\nexport function purgeFrameworkState(\n connectorId: string,\n dryRun: boolean,\n result: InstallResult,\n): void {\n // These are framework-state changes, not platform-native ones. ChangeRecord\n // types `platform` as the closed PlatformId union, so label them with the\n // connector id (cast once) — there is no real host platform to attribute.\n const platform = connectorId as PlatformId;\n\n // Marketplace survivors → refuse the purge for this connector (the remedy is\n // a one-command marketplace uninstall; the failure mode is orphaned plugins).\n if (connectorHasMarketplaceRecords(connectorId)) {\n const detail =\n `--purge skipped: \"${connectorId}\" still records marketplace installs — ` +\n `run \\`agent-connector uninstall --method marketplace\\` first`;\n result.changes.push({ platform, action: \"warn\", detail });\n result.warnings.push(detail);\n return;\n }\n\n // 1. Deregister the connector record directory.\n const recordDir = connectorDir(connectorId);\n const recordExisted = existsSync(recordDir);\n if (recordExisted) {\n if (!dryRun) {\n try {\n deregisterConnector(connectorId);\n } catch (err) {\n log.warn(`deregisterConnector failed: ${errMessage(err)}`);\n }\n }\n result.changes.push({\n platform,\n action: \"remove\",\n path: recordDir,\n detail: \"deregistered connector record\",\n });\n }\n\n // 2. If no connector records remain, remove the shared home-bin launcher —\n // unless another connector's marketplace installs survive (their installed\n // plugin hooks exec this launcher; removing it would silently kill them).\n if (anyMarketplaceRecordsRemain(connectorId)) {\n return;\n }\n if (noConnectorsRemain(connectorId, dryRun, recordExisted)) {\n const binPath = homeBinPath();\n if (existsSync(binPath)) {\n if (!dryRun) {\n try {\n rmSync(binPath, { force: true });\n } catch (err) {\n log.warn(`home-bin removal failed: ${errMessage(err)}`);\n }\n }\n result.changes.push({\n platform,\n action: \"remove\",\n path: binPath,\n detail: \"removed home-bin (no connectors remain)\",\n });\n }\n }\n}\n\n/**\n * True when `connectorsDir()` holds no remaining connector records. On a dry run\n * the just-deregistered record is still on disk, so it is discounted: the dir is\n * \"empty\" when its only remaining entry is the connector we are purging.\n */\nfunction noConnectorsRemain(\n connectorId: string,\n dryRun: boolean,\n recordExisted: boolean,\n): boolean {\n const dir = connectorsDir();\n if (!existsSync(dir)) return true;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return false;\n }\n const remaining = entries.filter(\n (e) => !(dryRun && recordExisted && e === connectorId),\n );\n return remaining.length === 0;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Internals\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Absolute path to the CLI entry (`dist/cli.js`) the home binary should exec.\n *\n * Robust to the bundler's output layout: tsup flattens this module into a\n * `dist/chunk-*.js`, so a fixed relative guess like `../cli.js` is wrong. We\n * instead walk up from this module to the package root (the dir whose\n * `package.json` declares the `agent-connector` bin) and use its `dist/cli.js`.\n * Fallbacks: a same-directory `cli.js` (flat-bundle case) then `process.argv[1]`.\n */\nexport function resolveCliEntry(): string {\n try {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 8; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n const cli = join(dir, \"dist\", \"cli.js\");\n if (existsSync(cli)) return cli;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Flat-bundle case: cli.js sits beside this chunk.\n const sameDir = fileURLToPath(new URL(\"./cli.js\", import.meta.url));\n if (existsSync(sameDir)) return sameDir;\n } catch {\n /* fall through */\n }\n const argv1 = process.argv[1];\n if (argv1 && argv1.length > 0) return argv1;\n return \"cli.js\";\n}\n\n/**\n * Resolve the ordered, de-duplicated list of platform targets, intersected with\n * the adapter registry's known ids (an unknown id can have no adapter to drive).\n *\n * Precedence: explicit `flagTargets` → connector's `targets` array → auto-detect\n * installed hosts. \"auto\" connector targets also fall through to detection.\n *\n * Exported for the marketplace orchestration (core/marketplace.ts), which\n * resolves targets EXACTLY like the direct install before mapping each platform\n * to its bundle format.\n */\nexport async function resolveTargets(\n flagTargets: PlatformId[] | undefined,\n connectorTargets: ResolvedConnector[\"targets\"],\n projectDir: string,\n): Promise<PlatformId[]> {\n let requested: PlatformId[];\n if (flagTargets && flagTargets.length > 0) {\n requested = flagTargets;\n } else if (Array.isArray(connectorTargets) && connectorTargets.length > 0) {\n requested = connectorTargets;\n } else {\n requested = await autoDetectIds(projectDir);\n }\n\n const seen = new Set<PlatformId>();\n const out: PlatformId[] = [];\n for (const id of requested) {\n if (!REGISTERED_PLATFORM_IDS.has(id)) continue; // no adapter registered → cannot drive it\n if (seen.has(id)) continue;\n seen.add(id);\n out.push(id);\n }\n return out;\n}\n\n/** Auto-detect installed platforms and map them to their ids (best-effort). */\nasync function autoDetectIds(projectDir: string): Promise<PlatformId[]> {\n try {\n const detected = await detectInstalledPlatforms(projectDir);\n return detected.filter((p) => p.installed).map((p) => p.id);\n } catch (err) {\n log.warn(`platform detection failed: ${errMessage(err)}`);\n return [];\n }\n}\n\n/**\n * Build the uniform InstallContext for one platform. The effective scope is the\n * connector's per-platform override when present, else the run-wide default.\n */\nfunction buildContext(\n connector: ResolvedConnector,\n id: PlatformId,\n defaultScope: InstallScope,\n projectDir: string,\n dryRun: boolean,\n force = false,\n): InstallContext {\n return {\n connector,\n scope: connector.platforms[id]?.scope ?? defaultScope,\n projectDir,\n homeBinPath: homeBinPath(),\n dataRoot: dataRoot(),\n dryRun,\n force,\n };\n}\n\n/**\n * Load an adapter, recording a `warn` change (not throwing) when unavailable.\n * `loadAdapter` returns `undefined` for an unregistered id and may reject if the\n * adapter module itself fails to import; both degrade to a warn here.\n */\nasync function tryLoadAdapter(\n id: PlatformId,\n result: InstallResult,\n): Promise<Adapter | null> {\n try {\n const adapter = await loadAdapter(id);\n if (adapter) return adapter;\n const detail = `no adapter registered for ${id}`;\n result.changes.push({ platform: id, action: \"warn\", detail });\n result.warnings.push(detail);\n return null;\n } catch (err) {\n const detail = `failed to load adapter for ${id}: ${errMessage(err)}`;\n result.changes.push({ platform: id, action: \"warn\", detail });\n result.warnings.push(detail);\n return null;\n }\n}\n\n/**\n * Run one adapter step, converting any thrown error into a `warn` ChangeRecord +\n * warning string so a single bad adapter never aborts the whole run.\n */\nfunction runStep(\n id: PlatformId,\n step: string,\n result: InstallResult,\n fn: () => void,\n): void {\n try {\n fn();\n } catch (err) {\n const detail = `${step} failed on ${id}: ${errMessage(err)}`;\n result.changes.push({ platform: id, action: \"warn\", detail });\n result.warnings.push(detail);\n }\n}\n\n/**\n * Resolve the target platforms an uninstall of `connectorId` would touch —\n * the exact resolution {@link uninstallConnector} performs internally, exposed\n * so the CLI's `--method auto` can PARTITION targets (marketplace-evidence →\n * host plugin uninstall; everything else → the direct adapter strip) before\n * dispatching to the two orchestrations.\n */\nexport async function resolveUninstallTargets(\n connectorId: string,\n flagTargets: PlatformId[] | undefined,\n projectDir: string,\n): Promise<PlatformId[]> {\n const connector = await loadConnectorForUninstall(connectorId);\n return resolveTargets(flagTargets, connector.targets, projectDir);\n}\n\n/**\n * Load the registered connector for uninstall context. If it cannot be loaded\n * (record removed, source module deleted/moved), fall back to a minimal\n * synthetic connector carrying just the id — enough for adapters to locate and\n * strip their entries, which they match by `connector.id` + the home-bin path.\n */\nasync function loadConnectorForUninstall(\n connectorId: string,\n): Promise<ResolvedConnector> {\n try {\n return await loadRegisteredConnector(connectorId);\n } catch (err) {\n log.warn(\n `could not load registered connector \"${connectorId}\" for uninstall (${errMessage(err)}); ` +\n \"proceeding with a minimal id-only context\",\n );\n return syntheticConnector(connectorId);\n }\n}\n\n/** Minimal id-only connector used as uninstall fallback context. */\nfunction syntheticConnector(id: string): ResolvedConnector {\n return {\n id,\n displayName: id,\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\nfunction newResult(connectorId: string, dryRun: boolean): InstallResult {\n return { connectorId, dryRun, changes: [], warnings: [] };\n}\n\nfunction pushAll(target: ChangeRecord[], records: ChangeRecord[]): void {\n for (const r of records) target.push(r);\n}\n\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * core/marketplace — install / uninstall / upgrade via the MARKETPLACE method.\n *\n * Marketplace is a second DELIVERY METHOD for the same connector lifecycle, not\n * a new lifecycle: `install --method marketplace` stages the connector's plugin\n * bundle under the data-root and drives the HOST's own plugin/marketplace\n * install flow, emitting the same ChangeRecords the direct method renders.\n *\n * Every host-specific detail lives behind a {@link MarketplaceDriver}\n * (marketplace-drivers/*), resolved per target via the registry; this module\n * keeps only the generic policy (target resolution, the double-install guard,\n * dry-run rendering, state-record bookkeeping) and dispatches through the\n * driver. Live drivers: claude-code + codex (catalog drivers — shared root +\n * one \"agent-connector\" catalog + a registered local marketplace) and\n * antigravity / antigravity-cli (the agy direct install-by-path driver, no\n * catalog). Every other marketplace-capable host degrades to a never-silent\n * skip/warn record carrying the exact manual commands from `package`.\n *\n * Cross-cutting rules (mirrors docs/ARCHITECTURE.md principles):\n * • Probe-first idempotency: re-runs report `=` skips, never errors.\n * • Double-install guard: exactly ONE method per (connector, host, scope) —\n * a direct install on the host REFUSES the marketplace install (and the\n * installer refuses the inverse), because a doubled connector duplicates\n * hooks + the MCP server and corrupts telemetry. No --force escape.\n * • By-reference staging: catalog drivers reference the bundle IN PLACE, so\n * bundles stage under <dataRoot>/marketplace/<family>/ (stable across cwd\n * changes), with ONE shared catalog named \"agent-connector\" listing every\n * staged connector (regenerated content-stably on install/uninstall). The\n * agy driver installs by path; the host copies the bundle into its store.\n * • --dry-run prints the staged file tree and the exact host commands as\n * ChangeRecords without writing or spawning.\n */\n\nimport { existsSync, readdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type {\n DiagnosticResult,\n InstallResult,\n InstallScope,\n PlatformId,\n ResolvedConnector,\n} from \"./types.js\";\nimport { loadAdapter } from \"../adapters/registry.js\";\nimport { registerConnector } from \"./load-connector.js\";\nimport { dataRoot, ensureHomeBin, homeBinPath } from \"./paths.js\";\nimport { resolveCliEntry, resolveTargets } from \"./installer.js\";\nimport {\n installInstructions,\n packageConnector,\n type PackageFormat,\n} from \"./package.js\";\nimport {\n MARKETPLACE_NAME,\n claudeKnownMarketplacePath,\n claudePluginInstalled,\n claudePluginKey,\n claudeStagingRoot,\n hashDirectory,\n marketplaceRoot,\n readMarketplaceInstalls,\n writeMarketplaceInstalls,\n type MarketplaceInstallRecord,\n} from \"./marketplace-state.js\";\nimport { claudeBinary } from \"./marketplace-drivers/claude.js\";\nimport { getMarketplaceDriver } from \"./marketplace-drivers/registry.js\";\nimport { log } from \"./logger.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Method types + platform → bundle-format mapping\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Delivery method for install/upgrade. */\nexport type InstallMethod = \"direct\" | \"marketplace\";\n/** Uninstall additionally supports auto (reverse whatever state says exists). */\nexport type UninstallMethod = InstallMethod | \"auto\";\n\n/** Parse a --method value for install/upgrade. */\nexport function parseInstallMethod(value: string | undefined): InstallMethod | null {\n if (value == null || value === \"direct\" || value === \"marketplace\") {\n return value ?? \"direct\";\n }\n return null;\n}\n\n/** Parse a --method value for uninstall (default auto). */\nexport function parseUninstallMethod(\n value: string | undefined,\n): UninstallMethod | null {\n if (value == null || value === \"auto\" || value === \"direct\" || value === \"marketplace\") {\n return value ?? \"auto\";\n }\n return null;\n}\n\n/**\n * Users think in HOSTS, not bundle formats — `--targets` keeps its PlatformId\n * meaning and the method maps platform → bundle format internally. Platforms\n * absent here have no marketplace/plugin distribution path at all.\n */\nexport const MARKETPLACE_FORMAT_BY_PLATFORM: Partial<\n Record<PlatformId, PackageFormat>\n> = {\n \"claude-code\": \"claude-plugin\",\n codex: \"codex-plugin\",\n droid: \"factory-plugin\",\n \"gemini-cli\": \"gemini-extension\",\n \"qwen-code\": \"qwen-extension\",\n antigravity: \"agy-plugin\",\n \"antigravity-cli\": \"agy-plugin\",\n cursor: \"cursor-plugin\",\n kimi: \"kimi-plugin\",\n opencode: \"npm-plugin\",\n kilo: \"npm-plugin\",\n \"kilo-cli\": \"npm-plugin\",\n pi: \"npm-plugin\",\n \"vscode-copilot\": \"claude-plugin\",\n openclaw: \"claude-plugin\",\n omp: \"claude-plugin\",\n};\n\n/** The platforms a driver can actually DRIVE end-to-end. */\nexport const DRIVABLE_MARKETPLACE_PLATFORMS: ReadonlySet<PlatformId> = new Set([\n \"claude-code\",\n \"codex\",\n \"antigravity\",\n \"antigravity-cli\",\n]);\n\n// ─────────────────────────────────────────────────────────────────────────\n// Small shared helpers\n// ─────────────────────────────────────────────────────────────────────────\n\nfunction newResult(connectorId: string, dryRun: boolean): InstallResult {\n return { connectorId, dryRun, changes: [], warnings: [] };\n}\n\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** The manual install hint for a non-drivable marketplace target. */\nfunction manualHint(platform: PlatformId, format: PackageFormat, id: string): string {\n const steps = installInstructions(format, id, \"<out-dir>\").join(\"; \");\n return (\n `agent-connector cannot drive the ${platform} marketplace flow yet — install manually: ` +\n `\\`agent-connector package --format ${format} --out <out-dir>\\` then: ${steps}`\n );\n}\n\n/**\n * Read-only: is `connector` DIRECTLY installed on `platform`?\n *\n * STRUCTURAL probe, not a substring scan: a marketplace plugin install makes\n * the HOST itself mention the id in these same files (Claude writes\n * `\"<id>@<marketplace>\"` into settings.json enabledPlugins), so a bare\n * `.includes(id)` misreports a marketplace-only install as a duplicate. We\n * only count markers a DIRECT install writes:\n * - server config: the id as a registration KEY — JSON `\"<id>\":` or a TOML\n * `[mcp_servers.<id>]`-style table heading (`.<id>]`);\n * - hook config: a home-bin hook command carrying `--connector <id>`\n * (plugin-bundle hooks live inside the bundle, never in the host file).\n * The plugin-state key `\"<id>@<marketplace>\"` matches neither.\n */\nasync function directInstallPresent(\n connector: ResolvedConnector,\n platform: PlatformId,\n scope: InstallScope,\n projectDir: string,\n): Promise<boolean> {\n try {\n const adapter = await loadAdapter(platform);\n if (!adapter) return false;\n const ctx = {\n connector,\n scope: connector.platforms[platform]?.scope ?? scope,\n projectDir,\n homeBinPath: homeBinPath(),\n dataRoot: dataRoot(),\n dryRun: true,\n };\n const escaped = connector.id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const serverKey = new RegExp(`\"${escaped}\"\\\\s*:|\\\\.${escaped}\\\\]`);\n const hookCommand = new RegExp(`--connector\\\\s+${escaped}(?![\\\\w-])`);\n const matches = (path: string, re: RegExp): boolean => {\n try {\n return re.test(readFileSync(path, \"utf8\"));\n } catch {\n return false;\n }\n };\n try {\n if (matches(adapter.getServerConfigPath(ctx), serverKey)) return true;\n } catch {\n /* no server config path */\n }\n try {\n if (matches(adapter.getHookConfigPath(ctx), hookCommand)) return true;\n } catch {\n /* no hook config path */\n }\n return false;\n } catch {\n return false;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// install --method marketplace\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Options for {@link installViaMarketplace} / {@link upgradeViaMarketplace}. */\nexport interface MarketplaceInstallOptions {\n connector: ResolvedConnector;\n /** Absolute path to the source module that produced `connector`. */\n modulePath: string;\n /** v1: must be \"user\" (project-scope plugin installs are deferred). */\n scope: InstallScope;\n projectDir: string;\n targets?: PlatformId[];\n dryRun: boolean;\n}\n\n/**\n * Deploy a connector by driving each target host's plugin/marketplace install.\n * Targets resolve exactly like the direct install (flag → connector.targets →\n * auto-detect); non-drivable hosts get never-silent skip/warn records with the\n * exact manual commands (warn when the user explicitly targeted them).\n */\nexport async function installViaMarketplace(\n opts: MarketplaceInstallOptions,\n): Promise<InstallResult> {\n const { connector, modulePath, scope, projectDir, dryRun } = opts;\n const result = newResult(connector.id, dryRun);\n\n if (scope !== \"user\") {\n result.warnings.push(\n \"--method marketplace supports --scope user only in this version \" +\n \"(project-scope plugin installs are deferred)\",\n );\n return result;\n }\n\n // Same framework-state step as the direct install: the staged bundle's hooks\n // + MCP entry exec the stable home-bin, and the runtime re-imports the\n // registered module to run live handlers.\n if (!dryRun) {\n try {\n ensureHomeBin(resolveCliEntry());\n } catch (err) {\n log.warn(`ensureHomeBin failed: ${errMessage(err)}`);\n }\n try {\n registerConnector(connector, modulePath);\n } catch (err) {\n log.warn(`registerConnector failed: ${errMessage(err)}`);\n }\n }\n\n const explicit = opts.targets != null && opts.targets.length > 0;\n const targets = await resolveTargets(opts.targets, connector.targets, projectDir);\n if (targets.length === 0) {\n result.warnings.push(\n \"no target platforms resolved (none installed / detected, or all filtered out)\",\n );\n return result;\n }\n\n for (const id of targets) {\n const format = MARKETPLACE_FORMAT_BY_PLATFORM[id];\n if (!format) {\n result.changes.push({\n platform: id,\n action: explicit ? \"warn\" : \"skip\",\n detail:\n `no marketplace/plugin distribution path exists for ${id} — ` +\n `use the direct method: \\`agent-connector install --targets ${id}\\``,\n });\n continue;\n }\n if (!DRIVABLE_MARKETPLACE_PLATFORMS.has(id)) {\n result.changes.push({\n platform: id,\n action: explicit ? \"warn\" : \"skip\",\n detail: manualHint(id, format, connector.id),\n });\n continue;\n }\n\n // ── drivable host (dispatch through the driver) ────────────────────────\n const driver = getMarketplaceDriver(id);\n if (!driver) {\n // DRIVABLE_MARKETPLACE_PLATFORMS and the registry are kept in sync; this\n // is a never-silent guard for an out-of-sync set rather than a real path.\n result.changes.push({\n platform: id,\n action: explicit ? \"warn\" : \"skip\",\n detail: manualHint(id, format, connector.id),\n });\n continue;\n }\n\n // Double-install guard: exactly one method per (connector, host, scope).\n if (await directInstallPresent(connector, id, scope, projectDir)) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail:\n `\"${connector.id}\" is already installed DIRECTLY on ${id} — refusing the marketplace ` +\n `install (both at once duplicates hooks + the MCP server and corrupts telemetry). ` +\n `Run \\`agent-connector uninstall --targets ${id}\\` first, or keep the direct install.`,\n });\n continue;\n }\n\n const pluginDir = driver.pluginDir(connector.id);\n\n if (dryRun) {\n const planned = packageConnector(connector, {\n outDir: driver.stagingRoot(),\n format,\n dryRun: true,\n });\n for (const file of planned.files) {\n result.changes.push({\n platform: id,\n action: \"create\",\n path: file,\n detail: \"stage bundle file\",\n });\n }\n driver.planInstall(connector, result.changes);\n continue;\n }\n\n const contentHash = driver.stage(connector, result.changes);\n const outcome = await driver.driveInstall(connector.id);\n result.changes.push(...outcome.changes);\n if (outcome.ok) {\n const installs = readMarketplaceInstalls(connector.id);\n const record: MarketplaceInstallRecord = {\n format,\n bundleDir: pluginDir,\n marketplace: MARKETPLACE_NAME,\n scope,\n version: connector.version,\n contentHash,\n installedAt: installs[id]?.installedAt ?? new Date().toISOString(),\n };\n installs[id] = record;\n writeMarketplaceInstalls(connector.id, installs);\n }\n }\n\n return result;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// uninstall --method marketplace (or auto resolving to it)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Options for {@link uninstallViaMarketplace}. */\nexport interface MarketplaceUninstallOptions {\n connectorId: string;\n projectDir: string;\n /** Omit to derive from the state record (recorded platforms ∪ claude evidence). */\n targets?: PlatformId[];\n dryRun: boolean;\n /** Also remove the shared marketplace staging root when it ends up empty. */\n purge?: boolean;\n}\n\n/** Manual uninstall commands for evidence on non-drivable hosts. */\nconst MANUAL_UNINSTALL: Partial<Record<PlatformId, (id: string) => string>> = {\n \"gemini-cli\": (id) => `gemini extensions uninstall ${id}`,\n antigravity: (id) => `agy plugin uninstall ${id}`,\n \"antigravity-cli\": (id) => `agy plugin uninstall ${id}`,\n codex: (id) => `codex plugin remove ${id}@${MARKETPLACE_NAME}`,\n};\n\n/**\n * Reverse a marketplace install per target, inverse order: host plugin\n * uninstall → catalog regen (without this connector) → marketplace\n * de-registration when nothing of ours remains → staged-bundle removal →\n * state-record removal. Probe-first: an absent plugin is an idempotent skip.\n */\nexport async function uninstallViaMarketplace(\n opts: MarketplaceUninstallOptions,\n): Promise<InstallResult> {\n const { connectorId, dryRun, purge } = opts;\n const result = newResult(connectorId, dryRun);\n\n let targets: PlatformId[];\n if (opts.targets && opts.targets.length > 0) {\n targets = [...new Set(opts.targets)];\n } else {\n // Union recorded platforms with live host evidence for every drivable host\n // (a host whose probe-able state shows our plugin but whose record was lost).\n targets = Object.keys(readMarketplaceInstalls(connectorId)) as PlatformId[];\n for (const id of DRIVABLE_MARKETPLACE_PLATFORMS) {\n if (targets.includes(id)) continue;\n const driver = getMarketplaceDriver(id);\n if (driver?.installed(connectorId)) targets = [...targets, id];\n }\n }\n if (targets.length === 0) {\n result.warnings.push(\n `no marketplace installs found for \"${connectorId}\" (nothing recorded, no host evidence)`,\n );\n return result;\n }\n\n for (const id of targets) {\n const driver = getMarketplaceDriver(id);\n if (!driver) {\n // Non-drivable host: keep the manual hint + the record until the user\n // reverses it by hand (never silently drop a recorded install).\n const manual = MANUAL_UNINSTALL[id];\n const recorded = readMarketplaceInstalls(connectorId)[id] != null;\n result.changes.push({\n platform: id,\n action: recorded ? \"warn\" : \"skip\",\n detail: recorded\n ? `agent-connector cannot drive the ${id} marketplace uninstall yet — ` +\n `run manually${manual ? `: ${manual(connectorId)}` : \"\"} (record kept until then)`\n : `no marketplace install recorded for ${id}`,\n });\n continue;\n }\n\n if (dryRun) {\n driver.planUninstall(connectorId, result.changes);\n continue;\n }\n\n // 1. Presence probe + drive the host uninstall.\n const outcome = await driver.driveUninstall(connectorId);\n result.changes.push(...outcome.changes);\n if (!outcome.ok) continue; // host still references the bundle — keep everything\n\n // 2. Driver-specific cleanup: staged-bundle removal, catalog regen, and\n // (catalog drivers) marketplace de-registration when nothing of ours remains.\n await driver.finishUninstall(connectorId, result.changes);\n\n // 3. Drop the platform entry from the state record.\n const installs = readMarketplaceInstalls(connectorId);\n if (installs[id]) {\n delete installs[id];\n writeMarketplaceInstalls(connectorId, installs);\n result.changes.push({\n platform: id,\n action: \"remove\",\n path: marketplaceRoot(),\n detail: \"removed marketplace install record\",\n });\n }\n }\n\n // --purge: additionally remove every drivable host's shared staging root once\n // it holds no staged bundle of ours, then the marketplace root when empty.\n if (purge && !dryRun) {\n const seenRoots = new Set<string>();\n for (const id of DRIVABLE_MARKETPLACE_PLATFORMS) {\n const driver = getMarketplaceDriver(id);\n if (!driver) continue;\n const root = driver.stagingRoot();\n if (seenRoots.has(root)) continue;\n seenRoots.add(root);\n if (!existsSync(root)) continue;\n // Only remove a staging root with no bundle dirs left (a bundle dir is any\n // direct child dir; the catalog dir is dot-prefixed and never a bundle).\n let bundleDirs: string[];\n try {\n bundleDirs = readdirSync(root).filter((n) => !n.startsWith(\".\"));\n } catch {\n bundleDirs = [];\n }\n if (bundleDirs.length > 0) continue;\n try {\n rmSync(root, { recursive: true, force: true });\n result.changes.push({\n platform: id,\n action: \"remove\",\n path: root,\n detail: \"removed empty marketplace staging root (--purge)\",\n });\n } catch (err) {\n log.warn(`marketplace staging-root removal failed: ${errMessage(err)}`);\n }\n }\n const root = marketplaceRoot();\n try {\n if (existsSync(root) && readdirSync(root).length === 0) {\n rmSync(root, { recursive: true, force: true });\n }\n } catch {\n /* best-effort */\n }\n }\n\n return result;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// upgrade --method marketplace\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Bring a marketplace install current: re-stage the bundle + catalog in place,\n * then drive the host's update flow through the driver (claude: `plugin update`,\n * falling back to uninstall+install; codex/agy: re-stage + the install verb,\n * which is an idempotent overwrite). Warns when connector.version is unchanged\n * since the recorded install — hosts cache a versioned COPY, so a same-version\n * update silently no-ops.\n */\nexport async function upgradeViaMarketplace(\n opts: MarketplaceInstallOptions,\n): Promise<InstallResult> {\n const { connector, scope, dryRun } = opts;\n const result = newResult(connector.id, dryRun);\n\n if (scope !== \"user\") {\n result.warnings.push(\n \"--method marketplace supports --scope user only in this version\",\n );\n return result;\n }\n\n let targets: PlatformId[];\n if (opts.targets && opts.targets.length > 0) {\n targets = [...new Set(opts.targets)];\n } else {\n targets = Object.keys(readMarketplaceInstalls(connector.id)) as PlatformId[];\n for (const id of DRIVABLE_MARKETPLACE_PLATFORMS) {\n if (targets.includes(id)) continue;\n const driver = getMarketplaceDriver(id);\n if (driver?.installed(connector.id)) targets = [...targets, id];\n }\n }\n if (targets.length === 0) {\n result.warnings.push(\n `no marketplace installs found for \"${connector.id}\" — ` +\n \"run `agent-connector install --method marketplace` first\",\n );\n return result;\n }\n\n for (const id of targets) {\n const driver = getMarketplaceDriver(id);\n if (!driver) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail: `agent-connector cannot drive a ${id} marketplace upgrade yet — re-run \\`agent-connector package\\` and the host's own update flow`,\n });\n continue;\n }\n\n const record = readMarketplaceInstalls(connector.id)[id];\n if (!record && !driver.installed(connector.id)) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail:\n `\"${connector.id}\" is not marketplace-installed on ${id} — ` +\n `run \\`agent-connector install --method marketplace --targets ${id}\\``,\n });\n continue;\n }\n\n if (record && record.version === connector.version) {\n result.changes.push({\n platform: id,\n action: \"warn\",\n detail:\n `connector.version is unchanged since the recorded install (${record.version}) — ` +\n `${id} caches a versioned copy, so bump connector.version for the update to take effect`,\n });\n }\n\n const pluginDir = driver.pluginDir(connector.id);\n if (dryRun) {\n result.changes.push({\n platform: id,\n action: \"update\",\n path: pluginDir,\n detail: \"re-stage marketplace bundle in place\",\n });\n result.changes.push({\n platform: id,\n action: \"update\",\n detail: `drive the ${id} host update flow`,\n });\n continue;\n }\n\n const contentHash = driver.stage(connector, result.changes);\n const outcome = await driver.driveUpdate(connector.id);\n result.changes.push(...outcome.changes);\n if (outcome.ok) {\n const installs = readMarketplaceInstalls(connector.id);\n installs[id] = {\n format: record?.format ?? driver.format,\n bundleDir: pluginDir,\n marketplace: MARKETPLACE_NAME,\n scope,\n version: connector.version,\n contentHash,\n installedAt: record?.installedAt ?? new Date().toISOString(),\n };\n writeMarketplaceInstalls(connector.id, installs);\n }\n }\n\n return result;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// doctor — framework-level marketplace checks (read-only fs, no spawning)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Marketplace doctor results for one platform. */\nexport interface MarketplaceDoctorGroup {\n platform: PlatformId;\n results: DiagnosticResult[];\n}\n\n/**\n * The framework-level marketplace health checks (design checks 1–6): duplicate\n * registration, registration intact, state↔host drift, staleness, the embedded\n * home-bin launcher, and a missing host binary. Pure fs reads, so they run in\n * isolated homes without spawning. Empty when the connector has no marketplace\n * state on ANY drivable host (no noise for direct-only users).\n *\n * Claude's group (the original, richest check set) comes first and is BYTE-\n * IDENTICAL to the pre-driver behavior — emitted only when claude has state.\n * Each other drivable host (codex, antigravity, antigravity-cli) contributes a\n * driver-based group, emitted only when THAT host has state, in registry order.\n */\nexport async function marketplaceDoctorChecks(\n connector: ResolvedConnector,\n scope: InstallScope,\n projectDir: string,\n): Promise<MarketplaceDoctorGroup[]> {\n const groups: MarketplaceDoctorGroup[] = [];\n\n const claude = await claudeMarketplaceGroup(connector, scope, projectDir);\n if (claude) groups.push(claude);\n\n // The other drivable hosts share one generic, driver-based group builder.\n // antigravity + antigravity-cli are the SAME physical host behind one shared\n // agy driver (identical host-state probe), so emitting one group per id would\n // double-count: a record under antigravity-cli makes `installed()` true for\n // antigravity too, yielding a spurious drift group for the sibling id. Dedupe\n // by shared HOST identity, with the id that HAS the record preferred as the\n // representative (sorted first). The agy registry memoizes a SEPARATE driver\n // instance per id, so we cannot dedupe by instance identity — both agy ids\n // return the same stagingRoot, which uniquely identifies the host store.\n const seenHosts = new Set<string>();\n const candidates = (\n [\"codex\", \"antigravity\", \"antigravity-cli\"] as PlatformId[]\n ).sort((a, b) => recordRank(connector.id, a) - recordRank(connector.id, b));\n for (const platform of candidates) {\n const driver = getMarketplaceDriver(platform);\n if (!driver) continue;\n const hostKey = driver.stagingRoot();\n if (seenHosts.has(hostKey)) continue;\n const group = await genericMarketplaceGroup(connector, platform, scope, projectDir);\n if (group) {\n groups.push(group);\n seenHosts.add(hostKey);\n }\n }\n\n // Stable, intuitive order: claude first, then codex, then the agy host.\n groups.sort((a, b) => platformDoctorRank(a.platform) - platformDoctorRank(b.platform));\n\n return groups;\n}\n\n/** Sort key so a platform that HAS a marketplace record is preferred as the\n * representative id for a shared driver (the user's actual target id wins). */\nfunction recordRank(connectorId: string, platform: PlatformId): number {\n return readMarketplaceInstalls(connectorId)[platform] ? 0 : 1;\n}\n\n/** Doctor group ordering: claude, codex, then the agy host (stable + intuitive). */\nfunction platformDoctorRank(platform: PlatformId): number {\n const order: PlatformId[] = [\"claude-code\", \"codex\", \"antigravity\", \"antigravity-cli\"];\n const i = order.indexOf(platform);\n return i === -1 ? order.length : i;\n}\n\n/**\n * Claude's marketplace doctor group — the original checks 1–6, unchanged. Kept\n * verbatim (only the `id`/`record`/`pluginPresent` preamble and the\n * early-return-to-null differ) so claude's output stays byte-identical. Returns\n * null when claude has no marketplace state (the original \"silent\" path).\n */\nasync function claudeMarketplaceGroup(\n connector: ResolvedConnector,\n scope: InstallScope,\n projectDir: string,\n): Promise<MarketplaceDoctorGroup | null> {\n const id = connector.id;\n const record = readMarketplaceInstalls(id)[\"claude-code\"];\n const pluginPresent = claudePluginInstalled(id);\n if (!record && !pluginPresent) return null;\n\n const results: DiagnosticResult[] = [];\n const stagingRoot = claudeStagingRoot();\n const pluginKey = claudePluginKey(id);\n\n // 1. duplicate-registration (the double-install invariant, after the fact —\n // manual installs can bypass the CLI guards).\n const direct = await directInstallPresent(connector, \"claude-code\", scope, projectDir);\n if (direct && pluginPresent) {\n results.push({\n check: `${id}: marketplace duplicate-registration`,\n status: \"fail\",\n message: `installed BOTH directly and as plugin ${pluginKey} — hooks + MCP server are duplicated`,\n fix: `uninstall one method: \\`agent-connector uninstall --method marketplace --targets claude-code\\` or \\`agent-connector uninstall --targets claude-code\\``,\n });\n }\n\n // 2. marketplace registration intact (covers a deleted/relocated data-root\n // dangling the by-reference marketplace).\n if (record) {\n const registeredAt = claudeKnownMarketplacePath(MARKETPLACE_NAME);\n const catalogPath = join(stagingRoot, \".claude-plugin\", \"marketplace.json\");\n let catalogListed = false;\n try {\n const catalog = JSON.parse(readFileSync(catalogPath, \"utf8\")) as {\n plugins?: Array<{ name?: string }>;\n };\n catalogListed = (catalog.plugins ?? []).some((p) => p.name === id);\n } catch {\n catalogListed = false;\n }\n const intact =\n registeredAt === stagingRoot && existsSync(record.bundleDir) && catalogListed;\n results.push({\n check: `${id}: marketplace registration`,\n status: intact ? \"pass\" : \"fail\",\n message: intact\n ? `local marketplace \"${MARKETPLACE_NAME}\" registered at ${stagingRoot}, bundle staged + cataloged`\n : `marketplace registration broken (registered at ${registeredAt ?? \"nowhere\"}, bundle ${existsSync(record.bundleDir) ? \"present\" : \"missing\"}, catalog ${catalogListed ? \"lists it\" : \"does not list it\"})`,\n ...(intact\n ? {}\n : { fix: `agent-connector install --method marketplace --targets claude-code` }),\n });\n }\n\n // 3. state ↔ host drift (both directions).\n if (record && !pluginPresent) {\n results.push({\n check: `${id}: marketplace state drift`,\n status: \"warn\",\n message: `recorded as marketplace-installed but Claude's state shows ${pluginKey} absent`,\n fix: `re-run \\`agent-connector install --method marketplace --targets claude-code\\` or \\`agent-connector uninstall --method marketplace --targets claude-code\\` to reconcile`,\n });\n } else if (!record && pluginPresent) {\n results.push({\n check: `${id}: marketplace state drift`,\n status: \"warn\",\n message: `Claude lists ${pluginKey} installed but agent-connector has no record of it (manual install?)`,\n fix: `adopt it: \\`agent-connector install --method marketplace --targets claude-code\\` (idempotent), or remove it: \\`claude plugin uninstall ${pluginKey}\\``,\n });\n }\n\n // 4. staleness: connector changed since the recorded install (claude caches a\n // versioned COPY, so edits do not reach the host until an upgrade).\n if (record) {\n if (connector.version !== \"0.0.0\" && connector.version !== record.version) {\n results.push({\n check: `${id}: marketplace staleness`,\n status: \"warn\",\n message: `connector.version ${connector.version} ≠ installed ${record.version}`,\n fix: `agent-connector upgrade --method marketplace --targets claude-code`,\n });\n } else if (\n existsSync(record.bundleDir) &&\n record.contentHash !== \"\" &&\n hashDirectory(record.bundleDir) !== record.contentHash\n ) {\n results.push({\n check: `${id}: marketplace staleness`,\n status: \"warn\",\n message: \"staged bundle changed since install — Claude's cached copy is stale\",\n fix: `agent-connector upgrade --method marketplace --targets claude-code`,\n });\n }\n }\n\n // 5. embedded home-bin launcher: the installed plugin's hooks exec it OUTSIDE\n // any adapter-managed config.\n if (pluginPresent && !existsSync(homeBinPath())) {\n results.push({\n check: `${id}: marketplace home-bin`,\n status: \"fail\",\n message: `installed plugin hooks exec ${homeBinPath()} which does not exist`,\n fix: \"agent-connector upgrade\",\n });\n }\n\n // 6. host binary missing for a recorded marketplace install.\n if (record && claudeBinary() == null) {\n results.push({\n check: `${id}: marketplace host binary`,\n status: \"warn\",\n message:\n \"claude CLI not found on PATH — the recorded marketplace install cannot be managed until it is reinstalled\",\n });\n }\n\n // A green summary line when nothing above flagged.\n if (results.every((r) => r.status === \"pass\")) {\n results.push({\n check: `${id}: marketplace install`,\n status: \"pass\",\n message: `${pluginKey} installed via marketplace (version ${record?.version ?? \"unknown\"})`,\n });\n }\n\n return { platform: \"claude-code\", results };\n}\n\n/**\n * The generic driver-based marketplace doctor group for a NON-claude drivable\n * host (codex, antigravity, antigravity-cli). It mirrors claude's checks via the\n * platform's {@link MarketplaceDriver} state probes, omitting only the\n * claude-specific catalog-registration check (the registration shape differs per\n * host and is covered by the host's own install path). Returns null when the\n * host has no marketplace state at all (record absent AND not host-installed) —\n * matching claude's \"silent when no state\" behavior, so direct-only and\n * claude-only users see no new groups.\n */\nasync function genericMarketplaceGroup(\n connector: ResolvedConnector,\n platform: PlatformId,\n scope: InstallScope,\n projectDir: string,\n): Promise<MarketplaceDoctorGroup | null> {\n const driver = getMarketplaceDriver(platform);\n if (!driver) return null;\n\n const id = connector.id;\n const record = readMarketplaceInstalls(id)[platform];\n const installed = driver.installed(id);\n if (!record && !installed) return null;\n\n const results: DiagnosticResult[] = [];\n\n // 1. duplicate-registration (the double-install invariant, after the fact).\n const direct = await directInstallPresent(connector, platform, scope, projectDir);\n if (direct && installed) {\n results.push({\n check: `${id}: marketplace duplicate-registration`,\n status: \"fail\",\n message: `installed BOTH directly and as a marketplace plugin on ${platform} — hooks + MCP server are duplicated`,\n fix: `uninstall one method: \\`agent-connector uninstall --method marketplace --targets ${platform}\\` or \\`agent-connector uninstall --targets ${platform}\\``,\n });\n }\n\n // 2. state ↔ host drift (both directions).\n if (record && !installed) {\n results.push({\n check: `${id}: marketplace state drift`,\n status: \"warn\",\n message: `recorded as marketplace-installed but ${platform}'s state shows the plugin absent`,\n fix: `re-run \\`agent-connector install --method marketplace --targets ${platform}\\` or \\`agent-connector uninstall --method marketplace --targets ${platform}\\` to reconcile`,\n });\n } else if (!record && installed) {\n results.push({\n check: `${id}: marketplace state drift`,\n status: \"warn\",\n message: `${platform} lists the plugin installed but agent-connector has no record of it (manual install?)`,\n fix: `adopt it: \\`agent-connector install --method marketplace --targets ${platform}\\` (idempotent), or remove it via the host's plugin uninstall`,\n });\n }\n\n // 3. staleness: connector changed since the recorded install (the host caches\n // a versioned COPY, so edits do not reach it until an upgrade).\n if (record) {\n if (connector.version !== \"0.0.0\" && connector.version !== record.version) {\n results.push({\n check: `${id}: marketplace staleness`,\n status: \"warn\",\n message: `connector.version ${connector.version} ≠ installed ${record.version}`,\n fix: `agent-connector upgrade --method marketplace --targets ${platform}`,\n });\n } else if (\n existsSync(record.bundleDir) &&\n record.contentHash !== \"\" &&\n hashDirectory(record.bundleDir) !== record.contentHash\n ) {\n results.push({\n check: `${id}: marketplace staleness`,\n status: \"warn\",\n message: `staged bundle changed since install — ${platform}'s cached copy is stale`,\n fix: `agent-connector upgrade --method marketplace --targets ${platform}`,\n });\n }\n }\n\n // 4. embedded home-bin launcher: the installed plugin's hooks exec it OUTSIDE\n // any adapter-managed config.\n if (installed && !existsSync(homeBinPath())) {\n results.push({\n check: `${id}: marketplace home-bin`,\n status: \"fail\",\n message: `installed plugin hooks exec ${homeBinPath()} which does not exist`,\n fix: \"agent-connector upgrade\",\n });\n }\n\n // 5. host binary missing for a recorded marketplace install.\n if (record && driver.binary() == null) {\n results.push({\n check: `${id}: marketplace host binary`,\n status: \"warn\",\n message: `${platform} CLI not found on PATH — the recorded marketplace install cannot be managed until it is reinstalled`,\n });\n }\n\n // A green summary line when nothing above flagged.\n if (results.every((r) => r.status === \"pass\")) {\n results.push({\n check: `${id}: marketplace install`,\n status: \"pass\",\n message: `${id} installed via marketplace on ${platform} (version ${record?.version ?? \"unknown\"})`,\n });\n }\n\n return { platform, results };\n}\n\n// Re-exported so CLI surfaces can partition uninstall targets without importing\n// the leaf state module everywhere.\nexport { marketplaceEvidence } from \"./marketplace-state.js\";\n","/**\n * core/marketplace-drivers/claude — the Claude Code marketplace driver.\n *\n * Drives the host's OWN plugin lifecycle against a LOCAL directory marketplace\n * (first-class in Claude's docs): `claude plugin marketplace add <stagingRoot>`\n * + `claude plugin install <id>@agent-connector`, with the exact inverses on\n * uninstall. Every step is PROBE-FIRST: decisions key off Claude's own state\n * files (installed_plugins.json / known_marketplaces.json — read-only) rather\n * than exit codes, so re-runs are idempotent `=` skips and `uninstall` of an\n * absent plugin can never error (live-verified: re-add / re-install exit 0,\n * uninstall/remove of an absent object exit 1).\n *\n * NAME-COLLISION SAFETY: a marketplace named \"agent-connector\" registered at a\n * path OTHER than our staging root belongs to the user. The driver refuses with\n * instructions and NEVER runs `marketplace remove` on a registration it did not\n * create (Claude uninstalls that marketplace's plugins on last-scope removal).\n *\n * All spawns inherit process.env, so CLAUDE_CONFIG_DIR/HOME isolation flows\n * through to the host CLI naturally (the isolated-home test contract).\n */\n\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport type { ChangeRecord, ResolvedConnector } from \"../types.js\";\nimport {\n MARKETPLACE_NAME,\n anyClaudeAgentConnectorPlugins,\n claudeKnownMarketplacePath,\n claudePluginInstalled,\n claudePluginKey,\n claudeStagingRoot,\n hashDirectory,\n} from \"../marketplace-state.js\";\nimport { ensureDir } from \"../paths.js\";\nimport { packageConnector } from \"../package.js\";\nimport { findOnPath, firstLine, runHostCommand } from \"./shared.js\";\nimport type { MarketplaceDriveOutcome, MarketplaceDriver } from \"./types.js\";\n\nconst PLATFORM = \"claude-code\" as const;\n\n/** Absolute path of the claude CLI on PATH, or null (drivers ship behind detection). */\nexport function claudeBinary(): string | null {\n return findOnPath(\"claude\");\n}\n\n/** The manual two-step install, printed whenever the driver cannot drive. */\nexport function claudeManualInstallCommands(\n connectorId: string,\n stagingRoot: string,\n): string {\n return (\n `claude plugin marketplace add ${stagingRoot} && ` +\n `claude plugin install ${claudePluginKey(connectorId)}`\n );\n}\n\nfunction warn(detail: string, path?: string): ChangeRecord {\n return { platform: PLATFORM, action: \"warn\", detail, ...(path ? { path } : {}) };\n}\n\nfunction failDetail(step: string, r: { code: number | null; stderr: string; stdout: string; timedOut: boolean; error?: string }): string {\n if (r.timedOut) return `${step} timed out`;\n if (r.error) return `${step} failed to spawn: ${r.error}`;\n const line = firstLine(r.stderr) || firstLine(r.stdout);\n return `${step} exited ${r.code}${line ? `: ${line}` : \"\"}`;\n}\n\n/** Outcome of {@link claudeDriveInstall}. */\nexport interface ClaudeInstallOutcome {\n changes: ChangeRecord[];\n /** True when the plugin is installed in Claude's state after this run. */\n installed: boolean;\n}\n\n/**\n * Drive the host install for an ALREADY-STAGED bundle:\n * validate (best-effort) → register the staging-root marketplace (probe-first,\n * collision-safe) → install the plugin (probe-first). Never throws; failures\n * become `warn` records and `installed: false`.\n */\nexport async function claudeDriveInstall(\n connectorId: string,\n stagingRoot: string,\n pluginDir: string,\n): Promise<ClaudeInstallOutcome> {\n const changes: ChangeRecord[] = [];\n const pluginKey = claudePluginKey(connectorId);\n\n const bin = claudeBinary();\n if (!bin) {\n changes.push(\n warn(\n `claude CLI not found on PATH — bundle staged but not installed. ` +\n `Install manually: ${claudeManualInstallCommands(connectorId, stagingRoot)}`,\n stagingRoot,\n ),\n );\n return { changes, installed: false };\n }\n\n // Best-effort pre-install validation (live-verified against our bundles).\n const validation = await runHostCommand(bin, [\"plugin\", \"validate\", pluginDir]);\n if (!validation.ok && !validation.error) {\n changes.push(\n warn(\n `bundle failed \\`claude plugin validate\\` — not installing. ` +\n failDetail(\"validate\", validation),\n pluginDir,\n ),\n );\n return { changes, installed: false };\n }\n\n // Marketplace registration (probe-first + name-collision refusal).\n const registeredAt = claudeKnownMarketplacePath(MARKETPLACE_NAME);\n if (registeredAt === stagingRoot) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n path: stagingRoot,\n detail: `marketplace \"${MARKETPLACE_NAME}\" already registered`,\n });\n } else if (registeredAt != null) {\n changes.push(\n warn(\n `a marketplace named \"${MARKETPLACE_NAME}\" is already registered at ${registeredAt} ` +\n `(not ours) — refusing to touch it. Remove it first ` +\n `(claude plugin marketplace remove ${MARKETPLACE_NAME}) or install manually: ` +\n claudeManualInstallCommands(connectorId, stagingRoot),\n ),\n );\n return { changes, installed: false };\n } else {\n const add = await runHostCommand(bin, [\n \"plugin\",\n \"marketplace\",\n \"add\",\n stagingRoot,\n ]);\n if (!add.ok) {\n changes.push(\n warn(\n `could not register the local marketplace — ` +\n failDetail(\"claude plugin marketplace add\", add) +\n `. Install manually: ${claudeManualInstallCommands(connectorId, stagingRoot)}`,\n stagingRoot,\n ),\n );\n return { changes, installed: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"create\",\n path: stagingRoot,\n detail: `registered local marketplace \"${MARKETPLACE_NAME}\" (claude plugin marketplace add)`,\n });\n }\n\n // Plugin install (probe-first).\n if (claudePluginInstalled(connectorId)) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n detail: `plugin ${pluginKey} already installed`,\n });\n return { changes, installed: true };\n }\n const install = await runHostCommand(bin, [\"plugin\", \"install\", pluginKey]);\n if (!install.ok || !claudePluginInstalled(connectorId)) {\n changes.push(\n warn(\n `plugin install did not complete — ` +\n failDetail(`claude plugin install ${pluginKey}`, install),\n ),\n );\n return { changes, installed: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"create\",\n detail: `installed plugin ${pluginKey} (scope user)`,\n });\n return { changes, installed: true };\n}\n\n/** Outcome of {@link claudeDriveUninstall}. */\nexport interface ClaudeUninstallOutcome {\n changes: ChangeRecord[];\n /** True when the plugin is absent from Claude's state after this run. */\n removed: boolean;\n}\n\n/**\n * Drive the host uninstall (probe-first: absent → `=` skip, never an error —\n * Claude exits 1 uninstalling an absent plugin, which a probe-first driver\n * never has to see).\n */\nexport async function claudeDriveUninstall(\n connectorId: string,\n): Promise<ClaudeUninstallOutcome> {\n const changes: ChangeRecord[] = [];\n const pluginKey = claudePluginKey(connectorId);\n\n if (!claudePluginInstalled(connectorId)) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n detail: `plugin ${pluginKey} not installed on claude-code`,\n });\n return { changes, removed: true };\n }\n\n const bin = claudeBinary();\n if (!bin) {\n changes.push(\n warn(\n `claude CLI not found on PATH — cannot drive the uninstall. ` +\n `Run manually: claude plugin uninstall ${pluginKey}`,\n ),\n );\n return { changes, removed: false };\n }\n\n const uninstall = await runHostCommand(bin, [\"plugin\", \"uninstall\", pluginKey]);\n if (!uninstall.ok || claudePluginInstalled(connectorId)) {\n changes.push(\n warn(`plugin uninstall did not complete — ` + failDetail(`claude plugin uninstall ${pluginKey}`, uninstall)),\n );\n return { changes, removed: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n detail: `uninstalled plugin ${pluginKey} (claude plugin uninstall)`,\n });\n return { changes, removed: true };\n}\n\n/**\n * Remove OUR marketplace registration (callers must have verified the safe\n * ordering first: catalog empty + no surviving @agent-connector plugins + the\n * registration points at our staging root).\n */\nexport async function claudeDriveMarketplaceRemove(\n stagingRoot: string,\n): Promise<ChangeRecord[]> {\n const bin = claudeBinary();\n if (!bin) {\n return [\n warn(\n `claude CLI not found on PATH — marketplace registration \"${MARKETPLACE_NAME}\" left behind. ` +\n `Run manually: claude plugin marketplace remove ${MARKETPLACE_NAME}`,\n stagingRoot,\n ),\n ];\n }\n const remove = await runHostCommand(bin, [\n \"plugin\",\n \"marketplace\",\n \"remove\",\n MARKETPLACE_NAME,\n ]);\n if (!remove.ok) {\n return [\n warn(\n `could not remove the marketplace registration — ` +\n failDetail(`claude plugin marketplace remove ${MARKETPLACE_NAME}`, remove),\n stagingRoot,\n ),\n ];\n }\n return [\n {\n platform: PLATFORM,\n action: \"remove\",\n path: stagingRoot,\n detail: `removed marketplace registration \"${MARKETPLACE_NAME}\" (no plugins remain)`,\n },\n ];\n}\n\n/**\n * Drive `claude plugin update` for an already-re-staged bundle; on a CLI\n * without the verb (older releases) fall back to a recorded uninstall+install\n * pair, per the design.\n */\nexport async function claudeDriveUpdate(\n connectorId: string,\n stagingRoot: string,\n pluginDir: string,\n): Promise<ClaudeInstallOutcome> {\n const pluginKey = claudePluginKey(connectorId);\n const bin = claudeBinary();\n if (!bin) {\n return {\n changes: [\n warn(\n `claude CLI not found on PATH — bundle re-staged but the installed copy was not updated. ` +\n `Run manually: claude plugin update ${pluginKey}`,\n stagingRoot,\n ),\n ],\n installed: false,\n };\n }\n if (!claudePluginInstalled(connectorId)) {\n // Not installed → an update IS an install.\n return claudeDriveInstall(connectorId, stagingRoot, pluginDir);\n }\n const update = await runHostCommand(bin, [\"plugin\", \"update\", pluginKey]);\n if (update.ok) {\n return {\n changes: [\n {\n platform: PLATFORM,\n action: \"update\",\n detail: `updated plugin ${pluginKey} (claude plugin update)`,\n },\n ],\n installed: true,\n };\n }\n // Fallback: uninstall + reinstall (older CLIs without `plugin update`).\n const changes: ChangeRecord[] = [\n warn(\n `\\`claude plugin update\\` did not complete (` +\n failDetail(\"update\", update) +\n `) — falling back to uninstall + install`,\n ),\n ];\n const un = await claudeDriveUninstall(connectorId);\n changes.push(...un.changes);\n if (!un.removed) return { changes, installed: claudePluginInstalled(connectorId) };\n const re = await claudeDriveInstall(connectorId, stagingRoot, pluginDir);\n changes.push(...re.changes);\n return { changes, installed: re.installed };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Staging: bundle emit + shared-catalog regeneration (moved here from the\n// orchestrator so all claude-specific logic lives behind the driver).\n// ─────────────────────────────────────────────────────────────────────────\n\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Staged plugin dirs (those carrying a .claude-plugin/plugin.json manifest). */\nexport function stagedClaudePlugins(stagingRoot: string): string[] {\n if (!existsSync(stagingRoot)) return [];\n try {\n return readdirSync(stagingRoot)\n .filter((name) =>\n existsSync(join(stagingRoot, name, \".claude-plugin\", \"plugin.json\")),\n )\n .sort();\n } catch {\n return [];\n }\n}\n\n/**\n * Regenerate the ONE shared catalog listing every staged connector (solves the\n * multi-connector marketplace-name collision a per-bundle catalog would cause).\n * Content-stable: rewritten only when the serialized catalog actually changed.\n */\nexport function regenerateClaudeCatalog(\n stagingRoot: string,\n changes: ChangeRecord[],\n): void {\n const catalogPath = join(stagingRoot, \".claude-plugin\", \"marketplace.json\");\n const plugins = stagedClaudePlugins(stagingRoot).map((name) => {\n let description = `${name} — connector emitted by agent-connector`;\n try {\n const manifest = JSON.parse(\n readFileSync(join(stagingRoot, name, \".claude-plugin\", \"plugin.json\"), \"utf8\"),\n ) as { description?: string };\n if (typeof manifest.description === \"string\") description = manifest.description;\n } catch {\n /* keep the default description */\n }\n return { name, source: `./${name}`, description };\n });\n const catalog = {\n name: MARKETPLACE_NAME,\n owner: { name: MARKETPLACE_NAME },\n plugins,\n };\n const serialized = `${JSON.stringify(catalog, null, 2)}\\n`;\n let existing: string | null = null;\n try {\n existing = readFileSync(catalogPath, \"utf8\");\n } catch {\n /* absent */\n }\n if (existing === serialized) return; // content-stable: no record, no write\n ensureDir(dirname(catalogPath));\n writeFileSync(catalogPath, serialized, \"utf8\");\n changes.push({\n platform: PLATFORM,\n action: existing == null ? \"create\" : \"update\",\n path: catalogPath,\n detail: `regenerated shared marketplace catalog (${plugins.length} plugin(s))`,\n });\n}\n\n/** Stage (or re-stage) the connector's claude-plugin bundle in the shared root. */\nexport function stageClaudeBundle(\n connector: ResolvedConnector,\n changes: ChangeRecord[],\n): { pluginDir: string; contentHash: string } {\n const stagingRoot = claudeStagingRoot();\n const pluginDir = join(stagingRoot, connector.id);\n const existed = existsSync(pluginDir);\n const result = packageConnector(connector, {\n outDir: stagingRoot,\n format: \"claude-plugin\",\n });\n changes.push({\n platform: PLATFORM,\n action: existed ? \"update\" : \"create\",\n path: pluginDir,\n detail: `staged marketplace bundle (${result.files.length} files, claude-plugin)`,\n });\n regenerateClaudeCatalog(stagingRoot, changes);\n return { pluginDir, contentHash: hashDirectory(pluginDir) };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// claudeDriver: the MarketplaceDriver implementation the orchestrator dispatches\n// through. Wraps the functions above into the shared interface.\n// ─────────────────────────────────────────────────────────────────────────\n\nexport const claudeDriver: MarketplaceDriver = {\n platform: PLATFORM,\n format: \"claude-plugin\",\n\n binary: claudeBinary,\n stagingRoot: claudeStagingRoot,\n pluginDir(id) {\n return join(claudeStagingRoot(), id);\n },\n installed: claudePluginInstalled,\n\n stage(connector, changes) {\n return stageClaudeBundle(connector, changes).contentHash;\n },\n\n planInstall(connector, changes) {\n const stagingRoot = claudeStagingRoot();\n const registeredAt = claudeKnownMarketplacePath(MARKETPLACE_NAME);\n changes.push({\n platform: PLATFORM,\n action: registeredAt === stagingRoot ? \"skip\" : \"create\",\n path: stagingRoot,\n detail:\n registeredAt === stagingRoot\n ? `marketplace \"${MARKETPLACE_NAME}\" already registered`\n : `run: claude plugin marketplace add ${stagingRoot}`,\n });\n changes.push({\n platform: PLATFORM,\n action: claudePluginInstalled(connector.id) ? \"skip\" : \"create\",\n detail: claudePluginInstalled(connector.id)\n ? `plugin ${claudePluginKey(connector.id)} already installed`\n : `run: claude plugin install ${claudePluginKey(connector.id)}`,\n });\n },\n\n planUninstall(id, changes) {\n const stagingRoot = claudeStagingRoot();\n const pluginDir = join(stagingRoot, id);\n const pluginKey = claudePluginKey(id);\n changes.push({\n platform: PLATFORM,\n action: claudePluginInstalled(id) ? \"remove\" : \"skip\",\n detail: claudePluginInstalled(id)\n ? `run: claude plugin uninstall ${pluginKey}`\n : `plugin ${pluginKey} not installed on claude-code`,\n });\n if (existsSync(pluginDir)) {\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: pluginDir,\n detail: \"remove staged marketplace bundle\",\n });\n }\n const othersStaged = stagedClaudePlugins(stagingRoot).some((n) => n !== id);\n if (!othersStaged && claudeKnownMarketplacePath(MARKETPLACE_NAME) === stagingRoot) {\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: stagingRoot,\n detail: `run: claude plugin marketplace remove ${MARKETPLACE_NAME} (when no plugins remain)`,\n });\n }\n },\n\n async driveInstall(id): Promise<MarketplaceDriveOutcome> {\n const stagingRoot = claudeStagingRoot();\n const out = await claudeDriveInstall(id, stagingRoot, join(stagingRoot, id));\n return { changes: out.changes, ok: out.installed };\n },\n\n async driveUninstall(id): Promise<MarketplaceDriveOutcome> {\n const out = await claudeDriveUninstall(id);\n return { changes: out.changes, ok: out.removed };\n },\n\n async driveUpdate(id): Promise<MarketplaceDriveOutcome> {\n const stagingRoot = claudeStagingRoot();\n const out = await claudeDriveUpdate(id, stagingRoot, join(stagingRoot, id));\n return { changes: out.changes, ok: out.installed };\n },\n\n async finishUninstall(id, changes): Promise<void> {\n const stagingRoot = claudeStagingRoot();\n const pluginDir = join(stagingRoot, id);\n\n // Remove the staged bundle, then regenerate the catalog without this id.\n if (existsSync(pluginDir)) {\n try {\n rmSync(pluginDir, { recursive: true, force: true });\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: pluginDir,\n detail: \"removed staged marketplace bundle\",\n });\n } catch (err) {\n changes.push({\n platform: PLATFORM,\n action: \"warn\",\n path: pluginDir,\n detail: `could not remove staged bundle: ${errMessage(err)}`,\n });\n }\n }\n if (existsSync(stagingRoot)) regenerateClaudeCatalog(stagingRoot, changes);\n\n // De-register OUR marketplace only when nothing of ours remains anywhere\n // (safe ordering: plugins are gone first, so Claude's \"removing a\n // marketplace uninstalls its plugins\" behavior cannot bite a survivor) and\n // ONLY when the registration actually points at our staging root.\n const nothingStaged = stagedClaudePlugins(stagingRoot).length === 0;\n if (\n nothingStaged &&\n !anyClaudeAgentConnectorPlugins() &&\n claudeKnownMarketplacePath(MARKETPLACE_NAME) === stagingRoot\n ) {\n changes.push(...(await claudeDriveMarketplaceRemove(stagingRoot)));\n }\n },\n};\n","/**\n * core/marketplace-drivers/shared — the helpers every marketplace driver is\n * built on: PATH binary detection and a hard-timeout, non-TTY host-CLI runner.\n *\n * Drivers spawn YOUNG host-CLI surfaces (plugin verbs change between releases),\n * so the runner is deliberately defensive: no shell, stdin ignored (a host CLI\n * waiting on TTY input must fail fast, not hang the install), stdout/stderr\n * captured for tolerant parsing, and a hard per-spawn timeout that kills the\n * child and reports `timedOut` instead of throwing. It NEVER rejects — drivers\n * key decisions off presence probes first and treat command failure as a warn.\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { delimiter, join, resolve } from \"node:path\";\n\nimport { spawnChild } from \"../spawn-child.js\";\n\n/** Default hard timeout for one host-CLI spawn. */\nexport const HOST_COMMAND_TIMEOUT_MS = 30_000;\n\n/** Outcome of one host-CLI invocation (never thrown). */\nexport interface HostCommandResult {\n /** True iff the process exited 0 within the timeout. */\n ok: boolean;\n /** Exit code (null when killed / failed to spawn). */\n code: number | null;\n stdout: string;\n stderr: string;\n /** True when the hard timeout killed the child. */\n timedOut: boolean;\n /** Spawn-level error message, when the process could not start. */\n error?: string;\n}\n\n/**\n * Locate `command` on PATH, returning the absolute executable path or null.\n * On win32 the PATHEXT extensions are tried (claude installs as claude.cmd);\n * elsewhere a plain existing file is accepted (we spawn it directly, so the\n * exec bit check is left to spawn itself).\n */\nexport function findOnPath(command: string): string | null {\n const pathVar = process.env.PATH ?? \"\";\n const exts =\n process.platform === \"win32\"\n ? (process.env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\").split(\";\").concat(\"\")\n : [\"\"];\n for (const dir of pathVar.split(delimiter)) {\n if (dir === \"\") continue;\n for (const ext of exts) {\n const candidate = join(dir, command + ext.toLowerCase());\n try {\n if (existsSync(candidate) && statSync(candidate).isFile()) {\n return candidate;\n }\n } catch {\n /* unreadable PATH entry — keep walking */\n }\n }\n }\n return null;\n}\n\n/**\n * Run one host CLI command headlessly: direct spawn (no shell on POSIX;\n * spawnChild handles the Windows .cmd launcher), stdin ignored, output\n * captured, hard timeout kill. Resolves ALWAYS — failure shapes are data.\n */\nexport function runHostCommand(\n command: string,\n args: string[],\n timeoutMs: number = HOST_COMMAND_TIMEOUT_MS,\n): Promise<HostCommandResult> {\n return new Promise((resolvePromise) => {\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n let settled = false;\n\n const settle = (result: HostCommandResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolvePromise(result);\n };\n\n let child;\n try {\n child = spawnChild(command, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.env,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n resolvePromise({\n ok: false,\n code: null,\n stdout: \"\",\n stderr: \"\",\n timedOut: false,\n error: message,\n });\n return;\n }\n\n const timer = setTimeout(() => {\n timedOut = true;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* already gone */\n }\n }, timeoutMs);\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString(\"utf8\");\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString(\"utf8\");\n });\n child.on(\"error\", (err) => {\n settle({\n ok: false,\n code: null,\n stdout,\n stderr,\n timedOut,\n error: err.message,\n });\n });\n child.on(\"close\", (code) => {\n settle({\n ok: code === 0 && !timedOut,\n code,\n stdout,\n stderr,\n timedOut,\n });\n });\n });\n}\n\n/** First line of a host CLI's output, for compact warn details. */\nexport function firstLine(text: string): string {\n const line = text.split(/\\r?\\n/).find((l) => l.trim() !== \"\");\n return line ? line.trim() : \"\";\n}\n\n/**\n * Path equivalence for comparing a path WE built (e.g. a staging root) against a\n * path a HOST CLI recorded in its own state. A plain `===` is wrong on Windows:\n * codex canonicalizes the marketplace `source` to the extended-length form\n * `\\\\?\\C:\\…` (live-confirmed on codex-cli 0.139.0), which never string-equals our\n * `path.join` result. Normalize both: strip the `\\\\?\\` / `\\\\?\\UNC\\` prefix,\n * `resolve()`, and case-fold on win32 (NTFS is case-insensitive). On POSIX this\n * is just `resolve(a) === resolve(b)`, so existing exact-match behavior is\n * preserved (an exact match always stays a match — samePath only widens).\n */\nexport function samePath(\n a: string | null | undefined,\n b: string | null | undefined,\n): boolean {\n if (a == null || b == null) return false;\n const norm = (p: string): string => {\n let s = p;\n if (process.platform === \"win32\") {\n s = s.replace(/^\\\\\\\\\\?\\\\UNC\\\\/, \"\\\\\\\\\").replace(/^\\\\\\\\\\?\\\\/, \"\");\n }\n s = resolve(s);\n return process.platform === \"win32\" ? s.toLowerCase() : s;\n };\n return norm(a) === norm(b);\n}\n","/**\n * core/marketplace-drivers/codex — the Codex CLI marketplace driver.\n *\n * A CATALOG driver, mirroring claude.ts closely against codex-cli's plugin\n * verbs (live-verified 0.139.0): `codex plugin marketplace add <stagingRoot>` +\n * `codex plugin add <id>@agent-connector`, with the inverses `codex plugin\n * remove <id>@agent-connector` + `codex plugin marketplace remove\n * agent-connector` on uninstall. Every step is PROBE-FIRST: decisions key off\n * Codex's own state file (<CODEX_HOME>/config.toml — read-only) rather than exit\n * codes, so re-runs are idempotent `=` skips.\n *\n * Differences from claude (docs/research/codex-agy-marketplace-mechanics.md):\n * • catalog dir is `.agents/plugins` (codex REJECTS a `.codex-plugin/`\n * catalog); staged plugin marker is `<dir>/.codex-plugin/plugin.json`;\n * • install verb `plugin add` (not `plugin install`); remove verb\n * `plugin remove` (not `plugin uninstall`);\n * • state lives in TOML config.toml ([plugins.\"<id>@agent-connector\"] +\n * [marketplaces.agent-connector].source), CODEX_HOME env (not\n * CLAUDE_CONFIG_DIR);\n * • NO `plugin validate` verb (marketplace add validates) and NO `plugin\n * update` verb — update = re-stage + `plugin add` (version-cached, so bump\n * connector.version for the new copy to win, same caveat as claude).\n *\n * NAME-COLLISION SAFETY (== claude): a marketplace named \"agent-connector\"\n * registered at a path OTHER than our staging root belongs to the user; the\n * driver refuses and NEVER removes a registration it did not create.\n */\n\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport type { ChangeRecord, ResolvedConnector } from \"../types.js\";\nimport {\n MARKETPLACE_NAME,\n anyCodexAgentConnectorPlugins,\n codexMarketplaceSource,\n codexPluginInstalled,\n codexPluginKey,\n codexStagingRoot,\n hashDirectory,\n} from \"../marketplace-state.js\";\nimport { ensureDir } from \"../paths.js\";\nimport { packageConnector } from \"../package.js\";\nimport { findOnPath, firstLine, runHostCommand, samePath } from \"./shared.js\";\nimport type { MarketplaceDriveOutcome, MarketplaceDriver } from \"./types.js\";\n\nconst PLATFORM = \"codex\" as const;\n\n/** Absolute path of the codex CLI on PATH, or null. */\nexport function codexBinary(): string | null {\n return findOnPath(\"codex\");\n}\n\n/** The manual two-step install, printed whenever the driver cannot drive. */\nfunction codexManualInstallCommands(connectorId: string, stagingRoot: string): string {\n return (\n `codex plugin marketplace add ${stagingRoot} && ` +\n `codex plugin add ${codexPluginKey(connectorId)}`\n );\n}\n\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction warn(detail: string, path?: string): ChangeRecord {\n return { platform: PLATFORM, action: \"warn\", detail, ...(path ? { path } : {}) };\n}\n\nfunction failDetail(\n step: string,\n r: { code: number | null; stderr: string; stdout: string; timedOut: boolean; error?: string },\n): string {\n if (r.timedOut) return `${step} timed out`;\n if (r.error) return `${step} failed to spawn: ${r.error}`;\n const line = firstLine(r.stderr) || firstLine(r.stdout);\n return `${step} exited ${r.code}${line ? `: ${line}` : \"\"}`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Staging: bundle emit + shared-catalog regeneration (codex catalog dir is\n// `.agents/plugins`; staged plugins carry `.codex-plugin/plugin.json`).\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Staged plugin dirs (those carrying a .codex-plugin/plugin.json manifest). */\nexport function stagedCodexPlugins(stagingRoot: string): string[] {\n if (!existsSync(stagingRoot)) return [];\n try {\n return readdirSync(stagingRoot)\n .filter((name) =>\n existsSync(join(stagingRoot, name, \".codex-plugin\", \"plugin.json\")),\n )\n .sort();\n } catch {\n return [];\n }\n}\n\n/** Path of the shared catalog: <stagingRoot>/.agents/plugins/marketplace.json. */\nfunction codexCatalogPath(stagingRoot: string): string {\n return join(stagingRoot, \".agents\", \"plugins\", \"marketplace.json\");\n}\n\n/**\n * Regenerate the ONE shared catalog listing every staged connector\n * (content-stable; rewritten only on an actual change). Same shape as claude's.\n */\nexport function regenerateCodexCatalog(stagingRoot: string, changes: ChangeRecord[]): void {\n const catalogPath = codexCatalogPath(stagingRoot);\n const plugins = stagedCodexPlugins(stagingRoot).map((name) => {\n let description = `${name} — connector emitted by agent-connector`;\n try {\n const manifest = JSON.parse(\n readFileSync(join(stagingRoot, name, \".codex-plugin\", \"plugin.json\"), \"utf8\"),\n ) as { description?: string };\n if (typeof manifest.description === \"string\") description = manifest.description;\n } catch {\n /* keep the default description */\n }\n return { name, source: `./${name}`, description };\n });\n const catalog = { name: MARKETPLACE_NAME, owner: { name: MARKETPLACE_NAME }, plugins };\n const serialized = `${JSON.stringify(catalog, null, 2)}\\n`;\n let existing: string | null = null;\n try {\n existing = readFileSync(catalogPath, \"utf8\");\n } catch {\n /* absent */\n }\n if (existing === serialized) return; // content-stable: no record, no write\n ensureDir(dirname(catalogPath));\n writeFileSync(catalogPath, serialized, \"utf8\");\n changes.push({\n platform: PLATFORM,\n action: existing == null ? \"create\" : \"update\",\n path: catalogPath,\n detail: `regenerated shared marketplace catalog (${plugins.length} plugin(s))`,\n });\n}\n\n/** Stage (or re-stage) the connector's codex-plugin bundle in the shared root. */\nexport function stageCodexBundle(\n connector: ResolvedConnector,\n changes: ChangeRecord[],\n): { pluginDir: string; contentHash: string } {\n const stagingRoot = codexStagingRoot();\n const pluginDir = join(stagingRoot, connector.id);\n const existed = existsSync(pluginDir);\n const result = packageConnector(connector, { outDir: stagingRoot, format: \"codex-plugin\" });\n changes.push({\n platform: PLATFORM,\n action: existed ? \"update\" : \"create\",\n path: pluginDir,\n detail: `staged marketplace bundle (${result.files.length} files, codex-plugin)`,\n });\n regenerateCodexCatalog(stagingRoot, changes);\n return { pluginDir, contentHash: hashDirectory(pluginDir) };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Host driving (probe-first, never throws)\n// ─────────────────────────────────────────────────────────────────────────\n\nasync function driveInstall(connectorId: string): Promise<MarketplaceDriveOutcome> {\n const stagingRoot = codexStagingRoot();\n const changes: ChangeRecord[] = [];\n const pluginKey = codexPluginKey(connectorId);\n\n const bin = codexBinary();\n if (!bin) {\n changes.push(\n warn(\n `codex CLI not found on PATH — bundle staged but not installed. ` +\n `Install manually: ${codexManualInstallCommands(connectorId, stagingRoot)}`,\n stagingRoot,\n ),\n );\n return { changes, ok: false };\n }\n\n // Marketplace registration (probe-first + name-collision refusal). Codex has\n // no `plugin validate` — `marketplace add` validates the bundle itself.\n const registeredAt = codexMarketplaceSource(MARKETPLACE_NAME);\n if (samePath(registeredAt, stagingRoot)) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n path: stagingRoot,\n detail: `marketplace \"${MARKETPLACE_NAME}\" already registered`,\n });\n } else if (registeredAt != null) {\n changes.push(\n warn(\n `a marketplace named \"${MARKETPLACE_NAME}\" is already registered at ${registeredAt} ` +\n `(not ours) — refusing to touch it. Remove it first ` +\n `(codex plugin marketplace remove ${MARKETPLACE_NAME}) or install manually: ` +\n codexManualInstallCommands(connectorId, stagingRoot),\n ),\n );\n return { changes, ok: false };\n } else {\n const add = await runHostCommand(bin, [\"plugin\", \"marketplace\", \"add\", stagingRoot]);\n // Probe-first: trust config.toml over the exit code (codex prints a harmless\n // WARNING under /tmp). Only fail when the source did NOT land on our root.\n // samePath: codex stores the win32 extended-length `\\\\?\\C:\\…` form.\n if (!samePath(codexMarketplaceSource(MARKETPLACE_NAME), stagingRoot)) {\n changes.push(\n warn(\n `could not register the local marketplace — ` +\n failDetail(\"codex plugin marketplace add\", add) +\n `. Install manually: ${codexManualInstallCommands(connectorId, stagingRoot)}`,\n stagingRoot,\n ),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"create\",\n path: stagingRoot,\n detail: `registered local marketplace \"${MARKETPLACE_NAME}\" (codex plugin marketplace add)`,\n });\n }\n\n // Plugin add (probe-first).\n if (codexPluginInstalled(connectorId)) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n detail: `plugin ${pluginKey} already installed`,\n });\n return { changes, ok: true };\n }\n const add = await runHostCommand(bin, [\"plugin\", \"add\", pluginKey]);\n if (!add.ok || !codexPluginInstalled(connectorId)) {\n changes.push(\n warn(`plugin add did not complete — ` + failDetail(`codex plugin add ${pluginKey}`, add)),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"create\",\n detail: `installed plugin ${pluginKey} (scope user)`,\n });\n return { changes, ok: true };\n}\n\nasync function driveUninstall(connectorId: string): Promise<MarketplaceDriveOutcome> {\n const changes: ChangeRecord[] = [];\n const pluginKey = codexPluginKey(connectorId);\n\n if (!codexPluginInstalled(connectorId)) {\n changes.push({\n platform: PLATFORM,\n action: \"skip\",\n detail: `plugin ${pluginKey} not installed on codex`,\n });\n return { changes, ok: true };\n }\n\n const bin = codexBinary();\n if (!bin) {\n changes.push(\n warn(\n `codex CLI not found on PATH — cannot drive the uninstall. ` +\n `Run manually: codex plugin remove ${pluginKey}`,\n ),\n );\n return { changes, ok: false };\n }\n\n const remove = await runHostCommand(bin, [\"plugin\", \"remove\", pluginKey]);\n if (!remove.ok || codexPluginInstalled(connectorId)) {\n changes.push(\n warn(`plugin remove did not complete — ` + failDetail(`codex plugin remove ${pluginKey}`, remove)),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n detail: `uninstalled plugin ${pluginKey} (codex plugin remove)`,\n });\n return { changes, ok: true };\n}\n\n/**\n * Remove OUR marketplace registration (callers must have verified safe ordering:\n * catalog empty + no surviving @agent-connector plugins + the registration\n * points at our staging root).\n */\nasync function driveMarketplaceRemove(stagingRoot: string): Promise<ChangeRecord[]> {\n const bin = codexBinary();\n if (!bin) {\n return [\n warn(\n `codex CLI not found on PATH — marketplace registration \"${MARKETPLACE_NAME}\" left behind. ` +\n `Run manually: codex plugin marketplace remove ${MARKETPLACE_NAME}`,\n stagingRoot,\n ),\n ];\n }\n const remove = await runHostCommand(bin, [\"plugin\", \"marketplace\", \"remove\", MARKETPLACE_NAME]);\n if (!remove.ok && codexMarketplaceSource(MARKETPLACE_NAME) != null) {\n return [\n warn(\n `could not remove the marketplace registration — ` +\n failDetail(`codex plugin marketplace remove ${MARKETPLACE_NAME}`, remove),\n stagingRoot,\n ),\n ];\n }\n return [\n {\n platform: PLATFORM,\n action: \"remove\",\n path: stagingRoot,\n detail: `removed marketplace registration \"${MARKETPLACE_NAME}\" (no plugins remain)`,\n },\n ];\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// codexDriver: the MarketplaceDriver the orchestrator dispatches through.\n// ─────────────────────────────────────────────────────────────────────────\n\nexport const codexDriver: MarketplaceDriver = {\n platform: PLATFORM,\n format: \"codex-plugin\",\n\n binary: codexBinary,\n stagingRoot: codexStagingRoot,\n pluginDir(id) {\n return join(codexStagingRoot(), id);\n },\n installed: codexPluginInstalled,\n\n stage(connector, changes) {\n return stageCodexBundle(connector, changes).contentHash;\n },\n\n planInstall(connector, changes) {\n const stagingRoot = codexStagingRoot();\n const registered = samePath(codexMarketplaceSource(MARKETPLACE_NAME), stagingRoot);\n changes.push({\n platform: PLATFORM,\n action: registered ? \"skip\" : \"create\",\n path: stagingRoot,\n detail: registered\n ? `marketplace \"${MARKETPLACE_NAME}\" already registered`\n : `run: codex plugin marketplace add ${stagingRoot}`,\n });\n changes.push({\n platform: PLATFORM,\n action: codexPluginInstalled(connector.id) ? \"skip\" : \"create\",\n detail: codexPluginInstalled(connector.id)\n ? `plugin ${codexPluginKey(connector.id)} already installed`\n : `run: codex plugin add ${codexPluginKey(connector.id)}`,\n });\n },\n\n planUninstall(id, changes) {\n const stagingRoot = codexStagingRoot();\n const pluginDir = join(stagingRoot, id);\n const pluginKey = codexPluginKey(id);\n changes.push({\n platform: PLATFORM,\n action: codexPluginInstalled(id) ? \"remove\" : \"skip\",\n detail: codexPluginInstalled(id)\n ? `run: codex plugin remove ${pluginKey}`\n : `plugin ${pluginKey} not installed on codex`,\n });\n if (existsSync(pluginDir)) {\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: pluginDir,\n detail: \"remove staged marketplace bundle\",\n });\n }\n const othersStaged = stagedCodexPlugins(stagingRoot).some((n) => n !== id);\n if (!othersStaged && samePath(codexMarketplaceSource(MARKETPLACE_NAME), stagingRoot)) {\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: stagingRoot,\n detail: `run: codex plugin marketplace remove ${MARKETPLACE_NAME} (when no plugins remain)`,\n });\n }\n },\n\n driveInstall,\n driveUninstall,\n\n // Codex has no `plugin update` verb — update IS re-stage (done by the caller)\n // + `plugin add`, which is idempotent and version-cached.\n async driveUpdate(id): Promise<MarketplaceDriveOutcome> {\n return driveInstall(id);\n },\n\n async finishUninstall(id, changes): Promise<void> {\n const stagingRoot = codexStagingRoot();\n const pluginDir = join(stagingRoot, id);\n\n if (existsSync(pluginDir)) {\n try {\n rmSync(pluginDir, { recursive: true, force: true });\n changes.push({\n platform: PLATFORM,\n action: \"remove\",\n path: pluginDir,\n detail: \"removed staged marketplace bundle\",\n });\n } catch (err) {\n changes.push({\n platform: PLATFORM,\n action: \"warn\",\n path: pluginDir,\n detail: `could not remove staged bundle: ${errMessage(err)}`,\n });\n }\n }\n if (existsSync(stagingRoot)) regenerateCodexCatalog(stagingRoot, changes);\n\n const nothingStaged = stagedCodexPlugins(stagingRoot).length === 0;\n if (\n nothingStaged &&\n !anyCodexAgentConnectorPlugins() &&\n samePath(codexMarketplaceSource(MARKETPLACE_NAME), stagingRoot)\n ) {\n changes.push(...(await driveMarketplaceRemove(stagingRoot)));\n }\n },\n};\n","/**\n * core/marketplace-drivers/agy — the Antigravity (agy) marketplace driver.\n *\n * A DIRECT install-by-path driver (NO marketplace, NO catalog): the host copies\n * the bundle into its own store, so there is no registration to manage and no\n * collision check. Live-verified against agy 1.0.7\n * (docs/research/codex-agy-marketplace-mechanics.md):\n * • `agy plugin validate <root>/<id>` — best-effort pre-install validation\n * (warns when the embedded home-bin path is absent; harmless, exits 0);\n * • `agy plugin install <root>/<id>` — copies to ~/.gemini/config/plugins/<id>/\n * and records it in import_manifest.json (idempotent overwrite);\n * • `agy plugin uninstall <id>` — removes the dir + manifest entry\n * (fully idempotent: uninstalling an absent plugin still exits 0).\n *\n * State (read-only): ~/.gemini/config/plugins/import_manifest.json `imports[]`\n * has `{ name:<id> }` (fallback: ~/.gemini/config/plugins/<id>/plugin.json).\n * agy roots at ~/.gemini/ with NO dedicated config-dir env — isolation is via\n * HOME. There is NO `plugin update` verb: update = re-stage + `plugin install`\n * (idempotent overwrite).\n *\n * The SAME driver implementation serves BOTH `antigravity` and\n * `antigravity-cli` (both emit the agy-plugin bundle); the registry binds one\n * instance per PlatformId so ChangeRecords carry the user's actual target id.\n */\n\nimport { existsSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { ChangeRecord, PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n agyPluginInstalled,\n agyStagingRoot,\n hashDirectory,\n} from \"../marketplace-state.js\";\nimport { packageConnector } from \"../package.js\";\nimport { findOnPath, firstLine, runHostCommand } from \"./shared.js\";\nimport type { MarketplaceDriveOutcome, MarketplaceDriver } from \"./types.js\";\n\n/** Absolute path of the agy CLI on PATH, or null. */\nexport function agyBinary(): string | null {\n return findOnPath(\"agy\");\n}\n\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction failDetail(\n step: string,\n r: { code: number | null; stderr: string; stdout: string; timedOut: boolean; error?: string },\n): string {\n if (r.timedOut) return `${step} timed out`;\n if (r.error) return `${step} failed to spawn: ${r.error}`;\n const line = firstLine(r.stderr) || firstLine(r.stdout);\n return `${step} exited ${r.code}${line ? `: ${line}` : \"\"}`;\n}\n\n/** Stage (or re-stage) the connector's agy-plugin bundle in the shared root. */\nexport function stageAgyBundle(\n connector: ResolvedConnector,\n platform: PlatformId,\n changes: ChangeRecord[],\n): { pluginDir: string; contentHash: string } {\n const stagingRoot = agyStagingRoot();\n const pluginDir = join(stagingRoot, connector.id);\n const existed = existsSync(pluginDir);\n const result = packageConnector(connector, { outDir: stagingRoot, format: \"agy-plugin\" });\n changes.push({\n platform,\n action: existed ? \"update\" : \"create\",\n path: pluginDir,\n detail: `staged marketplace bundle (${result.files.length} files, agy-plugin)`,\n });\n return { pluginDir, contentHash: hashDirectory(pluginDir) };\n}\n\n/**\n * Build an agy driver bound to one PlatformId (antigravity | antigravity-cli),\n * so the records it emits carry the user's actual target id.\n */\nexport function makeAgyDriver(platform: PlatformId): MarketplaceDriver {\n const warn = (detail: string, path?: string): ChangeRecord => ({\n platform,\n action: \"warn\",\n detail,\n ...(path ? { path } : {}),\n });\n\n const manualInstall = (pluginDir: string): string => `agy plugin install ${pluginDir}`;\n\n return {\n platform,\n format: \"agy-plugin\",\n\n binary: agyBinary,\n stagingRoot: agyStagingRoot,\n pluginDir(id) {\n return join(agyStagingRoot(), id);\n },\n installed: agyPluginInstalled,\n\n stage(connector, changes) {\n return stageAgyBundle(connector, platform, changes).contentHash;\n },\n\n planInstall(connector, changes) {\n const pluginDir = join(agyStagingRoot(), connector.id);\n changes.push({\n platform,\n action: agyPluginInstalled(connector.id) ? \"skip\" : \"create\",\n detail: agyPluginInstalled(connector.id)\n ? `plugin ${connector.id} already installed`\n : `run: agy plugin install ${pluginDir}`,\n });\n },\n\n planUninstall(id, changes) {\n const pluginDir = join(agyStagingRoot(), id);\n changes.push({\n platform,\n action: agyPluginInstalled(id) ? \"remove\" : \"skip\",\n detail: agyPluginInstalled(id)\n ? `run: agy plugin uninstall ${id}`\n : `plugin ${id} not installed on ${platform}`,\n });\n if (existsSync(pluginDir)) {\n changes.push({\n platform,\n action: \"remove\",\n path: pluginDir,\n detail: \"remove staged marketplace bundle\",\n });\n }\n },\n\n async driveInstall(id): Promise<MarketplaceDriveOutcome> {\n const changes: ChangeRecord[] = [];\n const pluginDir = join(agyStagingRoot(), id);\n\n const bin = agyBinary();\n if (!bin) {\n changes.push(\n warn(\n `agy CLI not found on PATH — bundle staged but not installed. ` +\n `Install manually: ${manualInstall(pluginDir)}`,\n pluginDir,\n ),\n );\n return { changes, ok: false };\n }\n\n // Probe-first: already installed → idempotent skip (re-install would be a\n // silent overwrite, but a probe-first driver reports it as a `=` skip).\n if (agyPluginInstalled(id)) {\n changes.push({\n platform,\n action: \"skip\",\n detail: `plugin ${id} already installed`,\n });\n return { changes, ok: true };\n }\n\n // Best-effort pre-install validation (advisory on agy — it warns on an\n // absent home-bin path yet still exits 0; never block the install on it,\n // the post-install probe below is the source of truth).\n await runHostCommand(bin, [\"plugin\", \"validate\", pluginDir]);\n\n const install = await runHostCommand(bin, [\"plugin\", \"install\", pluginDir]);\n if (!install.ok || !agyPluginInstalled(id)) {\n changes.push(\n warn(`plugin install did not complete — ` + failDetail(`agy plugin install ${pluginDir}`, install)),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform,\n action: \"create\",\n detail: `installed plugin ${id} (scope user)`,\n });\n return { changes, ok: true };\n },\n\n async driveUninstall(id): Promise<MarketplaceDriveOutcome> {\n const changes: ChangeRecord[] = [];\n\n if (!agyPluginInstalled(id)) {\n changes.push({\n platform,\n action: \"skip\",\n detail: `plugin ${id} not installed on ${platform}`,\n });\n return { changes, ok: true };\n }\n\n const bin = agyBinary();\n if (!bin) {\n changes.push(\n warn(\n `agy CLI not found on PATH — cannot drive the uninstall. ` +\n `Run manually: agy plugin uninstall ${id}`,\n ),\n );\n return { changes, ok: false };\n }\n\n const uninstall = await runHostCommand(bin, [\"plugin\", \"uninstall\", id]);\n if (!uninstall.ok || agyPluginInstalled(id)) {\n changes.push(\n warn(`plugin uninstall did not complete — ` + failDetail(`agy plugin uninstall ${id}`, uninstall)),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform,\n action: \"remove\",\n detail: `uninstalled plugin ${id} (agy plugin uninstall)`,\n });\n return { changes, ok: true };\n },\n\n // No `plugin update` verb — update = re-stage (done by the caller) +\n // `plugin install` (idempotent overwrite). Force a fresh install even when\n // the probe already shows it present (the bundle on disk changed).\n async driveUpdate(id): Promise<MarketplaceDriveOutcome> {\n const changes: ChangeRecord[] = [];\n const pluginDir = join(agyStagingRoot(), id);\n\n const bin = agyBinary();\n if (!bin) {\n changes.push(\n warn(\n `agy CLI not found on PATH — bundle re-staged but the installed copy was not updated. ` +\n `Run manually: ${manualInstall(pluginDir)}`,\n pluginDir,\n ),\n );\n return { changes, ok: false };\n }\n const install = await runHostCommand(bin, [\"plugin\", \"install\", pluginDir]);\n if (!install.ok || !agyPluginInstalled(id)) {\n changes.push(\n warn(`plugin install did not complete — ` + failDetail(`agy plugin install ${pluginDir}`, install)),\n );\n return { changes, ok: false };\n }\n changes.push({\n platform,\n action: \"update\",\n detail: `updated plugin ${id} (agy plugin install — idempotent overwrite)`,\n });\n return { changes, ok: true };\n },\n\n // Direct driver: no catalog, no marketplace de-registration. Cleanup is just\n // removing the staged bundle dir (the host copied it into its own store).\n async finishUninstall(id, changes): Promise<void> {\n const pluginDir = join(agyStagingRoot(), id);\n if (existsSync(pluginDir)) {\n try {\n rmSync(pluginDir, { recursive: true, force: true });\n changes.push({\n platform,\n action: \"remove\",\n path: pluginDir,\n detail: \"removed staged marketplace bundle\",\n });\n } catch (err) {\n changes.push({\n platform,\n action: \"warn\",\n path: pluginDir,\n detail: `could not remove staged bundle: ${errMessage(err)}`,\n });\n }\n }\n },\n };\n}\n","/**\n * core/marketplace-drivers/registry — platform → MarketplaceDriver resolution.\n *\n * The single place the orchestrator (marketplace.ts) asks \"can I DRIVE this\n * host's marketplace flow, and how?\". Returns the host-specific driver, or null\n * for a platform that has a bundle FORMAT but no live driver yet (those keep the\n * manual-hint skip/warn path). The agy driver serves BOTH `antigravity` and\n * `antigravity-cli`, bound per-id so its ChangeRecords carry the user's target.\n */\n\nimport type { PlatformId } from \"../types.js\";\nimport { claudeDriver } from \"./claude.js\";\nimport { codexDriver } from \"./codex.js\";\nimport { makeAgyDriver } from \"./agy.js\";\nimport type { MarketplaceDriver } from \"./types.js\";\n\n// Memoize the per-id agy drivers (stable identity; one instance per platform).\nconst agyDrivers = new Map<PlatformId, MarketplaceDriver>();\nfunction agyDriver(platform: PlatformId): MarketplaceDriver {\n let driver = agyDrivers.get(platform);\n if (!driver) {\n driver = makeAgyDriver(platform);\n agyDrivers.set(platform, driver);\n }\n return driver;\n}\n\n/** The driver that can DRIVE `platform`'s marketplace flow, or null when none. */\nexport function getMarketplaceDriver(platform: PlatformId): MarketplaceDriver | null {\n switch (platform) {\n case \"claude-code\":\n return claudeDriver;\n case \"codex\":\n return codexDriver;\n case \"antigravity\":\n case \"antigravity-cli\":\n return agyDriver(platform);\n default:\n return null;\n }\n}\n"],"mappings":"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","names":["existsSync","readdirSync","readFileSync","rmSync","join","existsSync","readdirSync","rmSync","dirname","join","existsSync","join","join","existsSync","errMessage","existsSync","readdirSync","join","dirname","rmSync","existsSync","readdirSync","readFileSync","rmSync","writeFileSync","dirname","join","PLATFORM","errMessage","warn","failDetail","existsSync","readdirSync","join","readFileSync","dirname","writeFileSync","add","rmSync","existsSync","rmSync","join","errMessage","failDetail","join","existsSync","warn","rmSync","newResult","errMessage","readFileSync","root","existsSync","readdirSync","rmSync","join"]}
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
fail,
|
|
4
|
-
print
|
|
5
|
-
} from "./chunk-AKJGNTU3.js";
|
|
6
|
-
import {
|
|
7
|
-
findConnectorConfig,
|
|
8
|
-
loadConnectorFromPath
|
|
9
|
-
} from "./chunk-3JCRUROU.js";
|
|
10
2
|
import {
|
|
11
3
|
MCPB_MANIFEST_VERSION,
|
|
12
4
|
MCP_SERVER_SCHEMA_URL,
|
|
@@ -29,19 +21,14 @@ import {
|
|
|
29
21
|
buildServeWrapperCommand,
|
|
30
22
|
shouldWrapForTelemetry
|
|
31
23
|
} from "./chunk-MEH7GC7R.js";
|
|
32
|
-
import "./chunk-N6HH7K6P.js";
|
|
33
24
|
import {
|
|
34
25
|
ensureDir,
|
|
35
26
|
homeBinPath
|
|
36
27
|
} from "./chunk-TRQKHP7D.js";
|
|
37
28
|
|
|
38
|
-
// src/cli/commands/package.ts
|
|
39
|
-
import { parseArgs } from "util";
|
|
40
|
-
import { join as join7, relative as relative2 } from "path";
|
|
41
|
-
|
|
42
29
|
// src/core/package.ts
|
|
43
30
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
44
|
-
import { resolve as resolve4 } from "path";
|
|
31
|
+
import { join as join7, resolve as resolve4 } from "path";
|
|
45
32
|
|
|
46
33
|
// src/core/package-formats/claude-family.ts
|
|
47
34
|
import { join } from "path";
|
|
@@ -151,7 +138,11 @@ var SPECS = {
|
|
|
151
138
|
manifestDir: ".codex-plugin",
|
|
152
139
|
subagentDir: "agents",
|
|
153
140
|
mcpFile: ".mcp.json",
|
|
154
|
-
marketplace: {
|
|
141
|
+
marketplace: {
|
|
142
|
+
dir: join(".agents", "plugins"),
|
|
143
|
+
file: "marketplace.json",
|
|
144
|
+
shape: "claude"
|
|
145
|
+
}
|
|
155
146
|
},
|
|
156
147
|
"factory-plugin": {
|
|
157
148
|
platformId: "droid",
|
|
@@ -421,7 +412,7 @@ var emitAgyPlugin = (connector, ctx) => {
|
|
|
421
412
|
}
|
|
422
413
|
}
|
|
423
414
|
const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, PLATFORM2);
|
|
424
|
-
if (hooksJson) emit(join4(pluginDir, "hooks
|
|
415
|
+
if (hooksJson) emit(join4(pluginDir, "hooks.json"), json(hooksJson));
|
|
425
416
|
const mcp = buildMcpEntry(connector, ctx.homeBinPath, PLATFORM2);
|
|
426
417
|
if (mcp) {
|
|
427
418
|
emit(
|
|
@@ -624,6 +615,11 @@ OpenCode / Kilo / Pi plugin package emitted by agent-connector.
|
|
|
624
615
|
|
|
625
616
|
Install with \`opencode plugin install <pkg>\` / \`kilo plugin <pkg>\` / \`pi install <pkg>\`.
|
|
626
617
|
|
|
618
|
+
Local install (no npm publish needed \u2014 live-verified on opencode 1.17.0 / kilo 7.3.16):
|
|
619
|
+
\`opencode plugin --global file:///<abs-dir>\` or \`kilo plugin --global file:///<abs-dir>\`
|
|
620
|
+
(bare absolute paths work too; the entry lands in the config \`plugin\` array \u2014
|
|
621
|
+
there is no uninstall verb, remove it by editing that array).
|
|
622
|
+
|
|
627
623
|
## Prerequisite
|
|
628
624
|
|
|
629
625
|
Hooks shell out to the \`agent-connector\` CLI resolved from the consumer's PATH \u2014
|
|
@@ -983,40 +979,6 @@ function packageConnectorAll(connector, opts) {
|
|
|
983
979
|
})
|
|
984
980
|
}));
|
|
985
981
|
}
|
|
986
|
-
|
|
987
|
-
// src/cli/commands/package.ts
|
|
988
|
-
var HELP = `agent-connector package \u2014 emit a plugin/extension/marketplace bundle.
|
|
989
|
-
|
|
990
|
-
usage: agent-connector package [flags]
|
|
991
|
-
|
|
992
|
-
flags:
|
|
993
|
-
--connector <path> Connector config to package (else auto-discovered).
|
|
994
|
-
--format <fmt> Output format (default: claude-plugin). One of:
|
|
995
|
-
${ALL_FORMATS.join(", ")}
|
|
996
|
-
or "all" to emit every feasible format into <out>/<fmt>/.
|
|
997
|
-
--out <dir> Output directory. Default: <cwd>/dist-plugin.
|
|
998
|
-
--project <dir> Project root for connector discovery (default: cwd).
|
|
999
|
-
--dry-run Compute the file tree without writing anything.
|
|
1000
|
-
--help Show this help.`;
|
|
1001
|
-
function printFormatResult(format, connectorId, outDir, result) {
|
|
1002
|
-
print(` pluginDir: ${result.pluginDir}`);
|
|
1003
|
-
if (result.marketplacePath) {
|
|
1004
|
-
print(` marketplace: ${relative2(outDir, result.marketplacePath)}`);
|
|
1005
|
-
}
|
|
1006
|
-
print(" emitted files:");
|
|
1007
|
-
for (const f of result.files) {
|
|
1008
|
-
print(` + ${relative2(outDir, f)}`);
|
|
1009
|
-
}
|
|
1010
|
-
if (result.notes && result.notes.length > 0) {
|
|
1011
|
-
print(" notes:");
|
|
1012
|
-
for (const n of result.notes) print(` ! ${n}`);
|
|
1013
|
-
}
|
|
1014
|
-
print(" install:");
|
|
1015
|
-
for (const line of installInstructions(format, connectorId, outDir)) {
|
|
1016
|
-
print(` ${line}`);
|
|
1017
|
-
}
|
|
1018
|
-
print("");
|
|
1019
|
-
}
|
|
1020
982
|
function installInstructions(format, id, outDir) {
|
|
1021
983
|
switch (format) {
|
|
1022
984
|
case "claude-plugin":
|
|
@@ -1069,69 +1031,13 @@ function installInstructions(format, id, outDir) {
|
|
|
1069
1031
|
return [];
|
|
1070
1032
|
}
|
|
1071
1033
|
}
|
|
1072
|
-
|
|
1073
|
-
const { values } = parseArgs({
|
|
1074
|
-
args: argv,
|
|
1075
|
-
options: {
|
|
1076
|
-
connector: { type: "string" },
|
|
1077
|
-
format: { type: "string", default: "claude-plugin" },
|
|
1078
|
-
out: { type: "string" },
|
|
1079
|
-
project: { type: "string" },
|
|
1080
|
-
"dry-run": { type: "boolean", default: false },
|
|
1081
|
-
help: { type: "boolean", default: false }
|
|
1082
|
-
},
|
|
1083
|
-
allowPositionals: false
|
|
1084
|
-
});
|
|
1085
|
-
if (values.help) {
|
|
1086
|
-
print(HELP);
|
|
1087
|
-
return 0;
|
|
1088
|
-
}
|
|
1089
|
-
const formatArg = values.format ?? "claude-plugin";
|
|
1090
|
-
const isAll = formatArg === "all";
|
|
1091
|
-
if (!isAll && !isPackageFormat(formatArg)) {
|
|
1092
|
-
return fail(
|
|
1093
|
-
`invalid --format "${formatArg}" (expected one of: ${ALL_FORMATS.join(", ")}, or "all")`
|
|
1094
|
-
);
|
|
1095
|
-
}
|
|
1096
|
-
const projectDir = values.project ?? process.cwd();
|
|
1097
|
-
const configPath = values.connector ?? findConnectorConfig(projectDir);
|
|
1098
|
-
if (!configPath) {
|
|
1099
|
-
return fail(
|
|
1100
|
-
"no connector config found. Pass --connector <path> or add an agent-connector.config.{mjs,js,json} to your project."
|
|
1101
|
-
);
|
|
1102
|
-
}
|
|
1103
|
-
const outDir = values.out ?? `${process.cwd()}/dist-plugin`;
|
|
1104
|
-
const dryRun = values["dry-run"];
|
|
1105
|
-
const mode = dryRun ? " (dry-run \u2014 nothing written)" : "";
|
|
1106
|
-
const { connector } = await loadConnectorFromPath(configPath);
|
|
1107
|
-
if (isAll) {
|
|
1108
|
-
print(`package "${connector.id}" \u2192 all formats${mode}`);
|
|
1109
|
-
print(` outDir: ${outDir}`);
|
|
1110
|
-
print("");
|
|
1111
|
-
const results = packageConnectorAll(connector, { outDir, dryRun });
|
|
1112
|
-
for (const { format: format2, result: result2 } of results) {
|
|
1113
|
-
const formatOut = join7(outDir, format2);
|
|
1114
|
-
print(`\u2500\u2500 ${format2} \u2500\u2500`);
|
|
1115
|
-
printFormatResult(format2, connector.id, formatOut, result2);
|
|
1116
|
-
}
|
|
1117
|
-
print(`emitted ${results.length} formats: ${FEASIBLE_FORMATS.join(", ")}`);
|
|
1118
|
-
return 0;
|
|
1119
|
-
}
|
|
1120
|
-
const format = formatArg;
|
|
1121
|
-
let result;
|
|
1122
|
-
try {
|
|
1123
|
-
result = packageConnector(connector, { outDir, format, dryRun });
|
|
1124
|
-
} catch (err) {
|
|
1125
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1126
|
-
return fail(message);
|
|
1127
|
-
}
|
|
1128
|
-
print(`package "${connector.id}" \u2192 ${format}${mode}`);
|
|
1129
|
-
print(` outDir: ${outDir}`);
|
|
1130
|
-
print("");
|
|
1131
|
-
printFormatResult(format, connector.id, outDir, result);
|
|
1132
|
-
return 0;
|
|
1133
|
-
}
|
|
1034
|
+
|
|
1134
1035
|
export {
|
|
1135
|
-
|
|
1036
|
+
ALL_FORMATS,
|
|
1037
|
+
FEASIBLE_FORMATS,
|
|
1038
|
+
isPackageFormat,
|
|
1039
|
+
packageConnector,
|
|
1040
|
+
packageConnectorAll,
|
|
1041
|
+
installInstructions
|
|
1136
1042
|
};
|
|
1137
|
-
//# sourceMappingURL=
|
|
1043
|
+
//# sourceMappingURL=chunk-WNREHWKL.js.map
|