@ken-jo/agent-connector 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -2
- package/dist/{chunk-AKJGNTU3.js → chunk-3RBLIHPZ.js} +21 -21
- package/dist/chunk-3RBLIHPZ.js.map +1 -0
- package/dist/chunk-G5CQHVQG.js +511 -0
- package/dist/chunk-G5CQHVQG.js.map +1 -0
- package/dist/chunk-KMAKDD3Z.js +3010 -0
- package/dist/chunk-KMAKDD3Z.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/{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-U3E7NVNW.js} +3 -3
- package/dist/{doctor-62BHIXOR.js → doctor-DZTWED4O.js} +35 -5
- package/dist/doctor-DZTWED4O.js.map +1 -0
- package/dist/{hook-AC7APC66.js → hook-EVY7LOUQ.js} +6 -6
- package/dist/{install-DMW2C7SV.js → install-OWAS5UIE.js} +31 -7
- package/dist/install-OWAS5UIE.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-CSWHI4UY.js} +2 -2
- package/dist/package-WFOS4QVU.js +130 -0
- package/dist/package-WFOS4QVU.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-3C2VFPAY.js} +6 -6
- package/dist/{status-M7JLZVLC.js → status-MKQYX5MW.js} +16 -7
- package/dist/status-MKQYX5MW.js.map +1 -0
- package/dist/{telemetry-3NVEXPYX.js → telemetry-3DN6XGYB.js} +2 -2
- package/dist/uninstall-WG6PFWF3.js +162 -0
- package/dist/uninstall-WG6PFWF3.js.map +1 -0
- package/dist/{upgrade-76BQZBMA.js → upgrade-32NC2RKI.js} +26 -8
- package/dist/upgrade-32NC2RKI.js.map +1 -0
- package/dist/{usage-G3GSCX23.js → usage-CJOM2WQM.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-U3E7NVNW.js.map} +0 -0
- /package/dist/{hook-AC7APC66.js.map → hook-EVY7LOUQ.js.map} +0 -0
- /package/dist/{leaderboard-R5HRJHNU.js.map → leaderboard-CSWHI4UY.js.map} +0 -0
- /package/dist/{serve-LFOUSZAD.js.map → serve-3C2VFPAY.js.map} +0 -0
- /package/dist/{telemetry-3NVEXPYX.js.map → telemetry-3DN6XGYB.js.map} +0 -0
- /package/dist/{usage-G3GSCX23.js.map → usage-CJOM2WQM.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/adapters/zed/index.ts"],"sourcesContent":["/**\n * adapters/zed — Zed editor platform adapter for agent-connector.\n *\n * Zed is an **mcp-only** host: it is an IDE, not a CLI with a hook pipeline, so\n * there is NO lifecycle hook system. MCP (\"context servers\") is the only\n * integration path, so this adapter installs only the MCP server and reports\n * hooks as unavailable — like Warp, it exercises the `mcp-only` paradigm.\n *\n * MCP config (one JSON-with-comments settings file, NOT a dedicated MCP file):\n * - user scope → settings.json under Zed's OS-native config dir (Rust\n * `dirs::config_dir()`):\n * • Windows: %APPDATA%\\Zed\\settings.json (Roaming, NOT %LOCALAPPDATA%)\n * • macOS / Linux: ~/.config/zed/settings.json\n * - project scope → <projectDir>/.zed/settings.json\n * Root key is \"context_servers\" (NOT \"mcpServers\"). The same file holds the\n * (non-existent) hook config — there is no separate hook file here.\n *\n * MERGE CONTRACT: Zed's settings.json is a large user-owned IDE config. We read\n * the whole file, set ONLY context_servers[<id>], and write it back — every\n * other top-level key and sibling context server is preserved. (Zed accepts\n * JSONC; we WRITE plain JSON, mirroring the other JSON-config adapters.)\n *\n * ENTRY SHAPE QUIRK (verified against context-mode's proven Zed adapter +\n * zed-industries/zed crates/settings_content/src/project.rs): Zed's\n * context_servers Stdio variant flattens ContextServerCommand and renames its\n * `path` field to the JSON key `command`. The accepted shape is therefore a\n * FLAT entry: { \"command\": \"<exe>\", \"args\": [...], \"env\": {...} }. The nested\n * { command: { path, args } } form fails to deserialize under Zed's\n * #[serde(untagged)] enum and is silently dropped (the server never loads).\n *\n * Zed documents no native ${env:VAR} interpolation token for context_servers,\n * so env refs are resolved to literals at install time (the no-native-token\n * path, same as Warp).\n *\n * Skills surface: Zed reads SKILL.md files from:\n * project scope → <projectDir>/.agents/skills/<name>/SKILL.md\n * user scope → ~/.agents/skills/<name>/SKILL.md\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, InstallContext, MemoryTarget } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookParadigm,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n SkillDef,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"zed\";\nconst MCP_ROOT_KEY = \"context_servers\";\n\n/**\n * Zed's context_servers Stdio entry. FLAT shape — `command` is a string, NOT a\n * nested { path, args } object (see file header). Remote transports are\n * represented as a URL-bearing entry.\n */\ninterface ZedStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface ZedHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class ZedAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Zed\";\n readonly paradigm: HookParadigm = \"mcp-only\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block. Zed's project rules file\n // is FIRST-MATCH across nine candidates — memoryTargets below probes that\n // order and writes into the file Zed will actually read; user scope is the\n // personal ~/.config/zed/AGENTS.md (%APPDATA%\\Zed on Windows, base map).\n supportsMemory: true,\n // Zed has no lifecycle hook system — every hook capability is false.\n preToolUse: false,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Zed registers stdio context servers; remote URLs are also accepted.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Skills: Zed reads SKILL.md from .agents/skills/<name>/SKILL.md (project)\n // and ~/.agents/skills/<name>/SKILL.md (user).\n supportsSkills: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = this.userConfigDir();\n const userSettings = this.userSettingsPath();\n const projDir = join(projectDir, \".zed\");\n const projSettings = join(projDir, \"settings.json\");\n\n const userInstalled = existsSync(userDir) || existsSync(userSettings);\n const projInstalled = existsSync(projDir) || existsSync(projSettings);\n const installed = userInstalled || projInstalled;\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projSettings : userSettings;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? `found Zed config (${scope}) at ${configPath}`\n : `no Zed config at ${userSettings} or ${projSettings}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".zed\")\n : this.userConfigDir();\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"settings.json\");\n }\n\n /**\n * Zed has no hook file — hooks are not a thing here. The hook \"config path\"\n * is the same settings.json so the generic doctor/backup behave sensibly.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\n }\n\n /**\n * Zed's user config dir is OS-native (Rust `dirs::config_dir()`), NOT a\n * uniform ~/.config:\n * - Windows: %APPDATA%\\Zed (Roaming, NOT Local/%LOCALAPPDATA%)\n * - macOS / Linux: ~/.config/zed\n */\n private userConfigDir(): string {\n if (process.platform === \"win32\") {\n const appData =\n process.env.APPDATA && process.env.APPDATA.trim() !== \"\"\n ? process.env.APPDATA\n : resolve(homedir(), \"AppData\", \"Roaming\");\n return join(appData, \"Zed\");\n }\n return join(homedir(), \".config\", \"zed\");\n }\n\n private userSettingsPath(): string {\n return join(this.userConfigDir(), \"settings.json\");\n }\n\n // ── Memory surface: first-match project rules probe ─────────────────────\n /**\n * Zed reads exactly ONE project rules file — the FIRST existing of these\n * worktree-root candidates (zed docs/src/ai/instructions.md order). A block\n * in AGENTS.md is silently ignored when e.g. `.cursorrules` exists, so the\n * probe targets the file Zed will actually pick; AGENTS.md is created only\n * when nothing shadows it.\n */\n private static readonly PROJECT_RULES_PROBE_ORDER = [\n \".rules\",\n \".cursorrules\",\n \".windsurfrules\",\n \".clinerules\",\n join(\".github\", \"copilot-instructions.md\"),\n \"AGENT.md\",\n \"AGENTS.md\",\n \"CLAUDE.md\",\n \"GEMINI.md\",\n ];\n\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"project\") {\n return super.memoryTargets(ctx); // user scope: personal AGENTS.md (base map)\n }\n for (const rel of ZedAdapter.PROJECT_RULES_PROBE_ORDER) {\n const candidate = join(ctx.projectDir, rel);\n if (existsSync(candidate)) {\n return [\n {\n path: candidate,\n reason: `zed first-match project rules file (${rel} shadows later candidates)`,\n },\n ];\n }\n }\n return [\n {\n path: join(ctx.projectDir, \"AGENTS.md\"),\n reason: \"AGENTS.md (created; no zed first-match rules file present)\",\n },\n ];\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for zed\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n // upsertServerInJson reads the WHOLE settings file, sets only\n // context_servers[<id>], and writes it back — preserving every other\n // top-level key and sibling context server (the merge contract).\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /** Render a normalized ServerDef into Zed's native context_servers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): ZedStdioServer | ZedHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n ctx.homeBinPath,\n ctx.connector.id,\n command,\n args,\n ctx.scope,\n this.id,\n );\n command = wrapped.command;\n args = wrapped.args;\n }\n\n // Zed has no documented native interpolation token, so resolve every\n // ${env:VAR} to a literal at install time.\n // FLAT shape: `command` is a string, never a nested { path, args }.\n const entry: ZedStdioServer = { command: resolveEnvRefsDeep(command) };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // sse / http (and any other remote transport) — Zed registers a URL.\n const entry: ZedHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Zed documents no native interpolation token, so\n * resolve `${env:VAR}` references to literals at install time.\n */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Skills surface ───────────────────────────────────────────────────────\n // Zed reads SKILL.md files from:\n // project scope → <projectDir>/.agents/skills/<name>/SKILL.md\n // user scope → ~/.agents/skills/<name>/SKILL.md\n\n private skillsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".agents\", \"skills\")\n : join(homedir(), \".agents\", \"skills\");\n }\n\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for zed\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), this.renderSkill(skill), ctx.dryRun),\n );\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n private renderSkill(skill: SkillDef): string {\n return renderSkillMd(skill);\n }\n\n // ── Hooks (unavailable — Zed is mcp-only) ────────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Zed is mcp-only)\",\n },\n ];\n }\n\n uninstallHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Zed is mcp-only)\",\n },\n ];\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const settingsPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n return [\n {\n name: `${this.name}: settings.json present`,\n check: () =>\n existsSync(settingsPath)\n ? { status: \"OK\", detail: settingsPath }\n : { status: \"FAIL\", detail: `not found: ${settingsPath}` },\n },\n {\n name: `${this.name}: context server entry registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector —\n // e.g. a catalog-only bundle of agents/skills/commands — never writes\n // a context_servers entry, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(settingsPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${settingsPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${settingsPath}`,\n };\n },\n },\n ];\n }\n}\n\nexport const adapter = new ZedAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ken-jo/agent-connector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Write your MCP server + hooks once; agent-connector installs and adapts them across every AI-agent platform (Claude Code, Codex, Cursor, OpenCode, Copilot, Gemini, Warp, …) and gives you default, platform-independent per-tool token telemetry.",
|
|
6
6
|
"keywords": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/app.ts"],"sourcesContent":["/**\n * cli/app — shared CLI helpers + command dispatch (NO side effects).\n *\n * Command modules import the shared helpers (print, fail, parse-flags,\n * renderInstallResult) from here, and main() dispatches the first positional to a\n * command module.\n * This module never auto-runs — `cli/index.ts` is the thin bin entry that calls\n * `main()`. Keeping the auto-run out of here is what prevents a dispatch recursion\n * (a command module importing a helper must not re-trigger the program) and makes\n * it robust to bundler entry-splitting (the old import.meta.url entry-guard broke\n * once tsup hoisted this code into a shared chunk).\n */\n\nimport { createRequire } from \"node:module\";\n\nimport type {\n ChangeRecord,\n InstallResult,\n InstallScope,\n PlatformId,\n} from \"../core/types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Shared helpers (imported by the command modules)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Print a line to stdout (machine-readable payloads must stay on stdout). */\nexport function print(line: string): void {\n process.stdout.write(`${line}\\n`);\n}\n\n/**\n * The brand active for THIS invocation. main() sets it from\n * {@link MainOptions.programName} before dispatch, so error messages printed by\n * command modules via {@link fail} read as the embedding tool (e.g. `acme-db:`)\n * instead of always `agent-connector:`.\n */\nlet activeProgramName = \"agent-connector\";\n\n/** Print an error to stderr (branded) and return a non-zero exit code (default 2). */\nexport function fail(message: string, code = 2): number {\n process.stderr.write(`${activeProgramName}: ${message}\\n`);\n return code;\n}\n\n/**\n * Resolve agent-connector's own package version at runtime. Works from both the\n * bundled dist layout (dist/*.js → ../package.json) and the src layout under\n * tsx/vitest (src/cli/ → ../../package.json); the name check guards against\n * accidentally reading some other package.json on the walk.\n */\nexport function resolveOwnVersion(): string {\n const req = createRequire(import.meta.url);\n for (const rel of [\"../package.json\", \"../../package.json\", \"../../../package.json\"]) {\n try {\n const pkg = req(rel) as { name?: string; version?: string };\n if (pkg.name === \"@ken-jo/agent-connector\" && typeof pkg.version === \"string\") {\n return pkg.version;\n }\n } catch {\n /* keep walking */\n }\n }\n return \"0.0.0\";\n}\n\n/** Parse a --scope value the CLI accepts (user|project) into an InstallScope. */\nexport function parseScope(value: string | undefined): InstallScope | null {\n if (value === \"user\" || value === \"project\") return value;\n return null;\n}\n\n/**\n * Parse a comma-separated --targets value into PlatformId[]. Returns undefined\n * when the flag is absent/empty so callers can fall back to connector/detection.\n */\nexport function parseTargets(value: string | undefined): PlatformId[] | undefined {\n if (value == null || value.trim() === \"\") return undefined;\n const ids = value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\") as PlatformId[];\n return ids.length > 0 ? ids : undefined;\n}\n\nconst ACTION_GLYPH: Record<ChangeRecord[\"action\"], string> = {\n create: \"+\",\n update: \"~\",\n remove: \"-\",\n skip: \"=\",\n warn: \"!\",\n};\n\n/**\n * Render an InstallResult as a readable diff: one line per ChangeRecord (glyph,\n * platform, detail, path) followed by any warnings and a summary tally. Used by\n * install / upgrade / uninstall.\n */\nexport function renderInstallResult(\n result: InstallResult,\n verb: \"install\" | \"upgrade\" | \"uninstall\",\n): string {\n const lines: string[] = [];\n const mode = result.dryRun ? \" (dry-run — nothing written)\" : \"\";\n lines.push(`${verb} \"${result.connectorId}\"${mode}`);\n\n if (result.changes.length === 0) {\n lines.push(\" (no changes)\");\n } else {\n for (const c of result.changes) {\n const glyph = ACTION_GLYPH[c.action];\n const where = c.path ? ` ${c.path}` : \"\";\n lines.push(` ${glyph} [${c.platform}] ${c.action}: ${c.detail}${where}`);\n }\n }\n\n if (result.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"warnings:\");\n for (const w of result.warnings) lines.push(` ! ${w}`);\n }\n\n const tally = result.changes.reduce<Record<ChangeRecord[\"action\"], number>>(\n (acc, c) => {\n acc[c.action] += 1;\n return acc;\n },\n { create: 0, update: 0, remove: 0, skip: 0, warn: 0 },\n );\n lines.push(\"\");\n lines.push(\n `summary: ${tally.create} created, ${tally.update} updated, ` +\n `${tally.remove} removed, ${tally.skip} skipped, ${tally.warn} warning(s)`,\n );\n\n return lines.join(\"\\n\");\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Command dispatch\n// ─────────────────────────────────────────────────────────────────────────\n\n/** A command module: takes the post-command argv slice, returns an exit code. */\ntype CommandModule = { run: (argv: string[]) => Promise<number> | number };\n\n/** Lazy command loaders — keyed by the first positional. Imported on demand. */\nconst COMMANDS: Record<string, () => Promise<CommandModule>> = {\n detect: () => import(\"./commands/detect.js\"),\n install: () => import(\"./commands/install.js\"),\n uninstall: () => import(\"./commands/uninstall.js\"),\n // `upgrade` is the single \"bring everything current\" verb (re-render host\n // config + refresh the home pointer + managed channel guidance). `sync` and\n // `update` are kept as back-compat aliases that route to the same module so\n // existing scripts/docs keep working without a second concept to learn.\n upgrade: () => import(\"./commands/upgrade.js\"),\n sync: () => import(\"./commands/upgrade.js\"),\n update: () => import(\"./commands/upgrade.js\"),\n package: () => import(\"./commands/package.js\"),\n doctor: () => import(\"./commands/doctor.js\"),\n status: () => import(\"./commands/status.js\"),\n telemetry: () => import(\"./commands/telemetry.js\"),\n usage: () => import(\"./commands/usage.js\"),\n leaderboard: () => import(\"./commands/leaderboard.js\"),\n hook: () => import(\"./commands/hook.js\"),\n serve: () => import(\"./commands/serve.js\"),\n // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an\n // AfterModel / PostInvocation hook points at. Always exits 0; records a\n // distinct `model_turn` row. See cli/commands/usage-event.ts.\n \"usage-event\": () => import(\"./commands/usage-event.js\"),\n};\n\n/** Default program name; an embedding SDK CLI overrides it via {@link MainOptions}. */\nexport const DEFAULT_PROGRAM_NAME = \"agent-connector\";\n\n/**\n * One-line usage signature per command — the single central copy behind\n * `<command> --help` and the friendly bad-flag error. Command modules use\n * node:util parseArgs (strict), which THROWS on an unknown flag; without the\n * dispatcher-level handling in {@link main}, `agent-connector install --help`\n * would die with a raw ERR_PARSE_ARGS stack trace — the very invocation the\n * root help tells users to run.\n */\nconst COMMAND_USAGE: Record<string, string> = {\n detect: \"detect [--json] [--project <dir>]\",\n install:\n \"install [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--force]\",\n uninstall:\n \"uninstall [--connector <path>] [--connector-id <id>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--purge]\",\n upgrade:\n \"upgrade [--channel stable|latest] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run]\",\n sync: \"sync — alias of upgrade (see `upgrade --help`)\",\n update: \"update — alias of upgrade (see `upgrade --help`)\",\n package:\n \"package [--connector <path>] [--format <fmt>|all] [--out <dir>] [--project <dir>] [--dry-run]\",\n doctor:\n \"doctor [--targets a,b] [--connector <path>] [--scope user|project] [--project <dir>] [--probe] [--json]\",\n status: \"status [--connector <path>] [--scope user|project] [--project <dir>] [--json]\",\n telemetry:\n \"telemetry report|export|leaderboard [--by <dim>] [--since <dur>] [--connector <id>] [--scope <slice>] [--format csv|json] [--out <file>] [--json]\",\n usage:\n \"usage report|export|leaderboard [--by <dim>] [--since <dur>] [--platform <id>] [--format csv|json] [--out <file>] [--json]\",\n leaderboard: \"leaderboard [--since <dur>] [--connector <id>] [--scope <slice>] [--json]\",\n hook: \"hook <platform> <event> --connector <id> (internal — host hook configs point here)\",\n serve:\n \"serve --connector <id> [--scope user|project] [--host <platformId>] -- <command> [args...] (internal — host MCP entries point here)\",\n};\n\n/**\n * Build the top-level usage string for a given program name. The brand replaces\n * \"agent-connector\" in the title, the `usage:` line, and the per-command help\n * footer so an embedded CLI (e.g. `acme-db`) reads as its own tool.\n */\nfunction buildUsage(programName: string): string {\n return `${programName} — write your MCP server + hooks once, install everywhere.\n\nusage: ${programName} <command> [flags]\n\ncommands:\n detect List the AI-agent platforms installed on this machine.\n install Deploy a connector across its target platforms.\n uninstall Remove a connector's MCP + hook registrations.\n upgrade Bring everything current: re-render host config + heal the home pointer + managed update guidance (alias: update, sync).\n package Emit a marketplace/extension bundle (9 host formats, or the standard artifacts mcp-server-json | mcpb).\n doctor Health-check every detected platform; non-zero exit on any failure.\n status Light install-state summary: which connectors are present on which hosts (always exits 0).\n telemetry Inspect local per-tool token telemetry (report | export | leaderboard).\n usage Inspect host-native token usage from agent CLI logs (report | export | leaderboard).\n leaderboard Three leaderboards: 🔌 MCP/plugin (mcp-self) + 🖥️ host/user (host-scan-logs) + 🛰️ host-native turns (host-native-live) — never summed.\n hook Universal json-stdio hook entrypoint (hosts call this).\n serve Telemetry-wrapping MCP stdio proxy (wraps a real server command).\n\nRun \\`${programName} <command> --help\\` for command-specific flags.`;\n}\n\n/** Options accepted by {@link main}. */\nexport interface MainOptions {\n /**\n * The brand shown in usage/help text. Defaults to {@link DEFAULT_PROGRAM_NAME}.\n * An embedding SDK CLI (see cli/sdk.ts) passes its own bin name so every\n * subcommand's help reads as the developer's tool.\n */\n programName?: string;\n}\n\nexport async function main(argv: string[], opts: MainOptions = {}): Promise<number> {\n const programName = opts.programName ?? DEFAULT_PROGRAM_NAME;\n activeProgramName = programName; // brand every fail() in this invocation\n const usage = buildUsage(programName);\n const command = argv[0];\n\n if (command == null || command === \"--help\" || command === \"-h\" || command === \"help\") {\n print(usage);\n return command == null ? 1 : 0;\n }\n if (command === \"--version\" || command === \"-v\") {\n print(`${programName} ${resolveOwnVersion()}`);\n return 0;\n }\n\n const loader = COMMANDS[command];\n if (!loader) {\n process.stderr.write(`${programName}: unknown command \"${command}\"\\n\\n`);\n process.stderr.write(`${usage}\\n`);\n return 2;\n }\n\n // Per-command help: no command module defines a --help flag (strict parseArgs\n // would throw on it), so answer it centrally from COMMAND_USAGE.\n const rest = argv.slice(1);\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n const sig = COMMAND_USAGE[command];\n if (sig) {\n print(`usage: ${programName} ${sig}`);\n return 0;\n }\n }\n\n const mod = await loader();\n try {\n return await mod.run(rest);\n } catch (err) {\n // Friendly bad-flag errors: strict parseArgs throws ERR_PARSE_ARGS_* for an\n // unknown/malformed option — print the message + the usage line instead of\n // letting a raw stack trace reach the user. Everything else still rethrows\n // (the bin entry reports those as fatal).\n const code = (err as { code?: string }).code;\n if (typeof code === \"string\" && code.startsWith(\"ERR_PARSE_ARGS\")) {\n const message = err instanceof Error ? err.message : String(err);\n const sig = COMMAND_USAGE[command];\n if (sig) process.stderr.write(`usage: ${programName} ${sig}\\n`);\n return fail(message);\n }\n throw err;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/logger.ts"],"sourcesContent":["/**\n * core/logger — minimal leveled logger. Writes human output to stderr so stdout\n * stays clean for machine-readable payloads (hook replies, --json output).\n */\n\nexport type LogLevel = \"silent\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nconst ORDER: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nfunction currentLevel(): LogLevel {\n const env = (process.env.AGENT_CONNECTOR_LOG ?? \"info\").toLowerCase();\n return (env in ORDER ? env : \"info\") as LogLevel;\n}\n\nfunction emit(level: Exclude<LogLevel, \"silent\">, args: unknown[]): void {\n if (ORDER[currentLevel()] < ORDER[level]) return;\n const prefix = { error: \"✗\", warn: \"!\", info: \"›\", debug: \"·\" }[level];\n // eslint-disable-next-line no-console\n console.error(prefix, ...args);\n}\n\nexport const log = {\n error: (...args: unknown[]) => emit(\"error\", args),\n warn: (...args: unknown[]) => emit(\"warn\", args),\n info: (...args: unknown[]) => emit(\"info\", args),\n debug: (...args: unknown[]) => emit(\"debug\", args),\n};\n"],"mappings":";;;AAOA,IAAM,QAAkC;AAAA,EACtC,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAAS,eAAyB;AAChC,QAAM,OAAO,QAAQ,IAAI,uBAAuB,QAAQ,YAAY;AACpE,SAAQ,OAAO,QAAQ,MAAM;AAC/B;AAEA,SAAS,KAAK,OAAoC,MAAuB;AACvE,MAAI,MAAM,aAAa,CAAC,IAAI,MAAM,KAAK,EAAG;AAC1C,QAAM,SAAS,EAAE,OAAO,UAAK,MAAM,KAAK,MAAM,UAAK,OAAO,OAAI,EAAE,KAAK;AAErE,UAAQ,MAAM,QAAQ,GAAG,IAAI;AAC/B;AAEO,IAAM,MAAM;AAAA,EACjB,OAAO,IAAI,SAAoB,KAAK,SAAS,IAAI;AAAA,EACjD,MAAM,IAAI,SAAoB,KAAK,QAAQ,IAAI;AAAA,EAC/C,MAAM,IAAI,SAAoB,KAAK,QAAQ,IAAI;AAAA,EAC/C,OAAO,IAAI,SAAoB,KAAK,SAAS,IAAI;AACnD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/spawn-child.ts","../src/telemetry/jsonrpc.ts"],"sourcesContent":["/**\n * core/spawn-child — the cross-platform child_process.spawn wrapper.\n *\n * Kept SEPARATE from core/spawn.ts (pure string/path helpers, imported widely\n * and early) so that pulling in `node:child_process` here does not perturb the\n * module-eval order of test suites that vi.mock(\"node:child_process\").\n */\n\nimport { type ChildProcess, type SpawnOptions, spawn } from \"node:child_process\";\n\nimport { resolveSpawnCommand } from \"./spawn.js\";\n\n/**\n * Quote one token for a cmd.exe command line: wrap in double quotes, doubling any\n * embedded double quote. Sufficient for the paths / package names / flags we\n * spawn (connector config, not untrusted end-user input) — we intentionally do\n * not escape cmd metacharacters (& | ^ %), which never appear in those tokens.\n */\nfunction winQuoteArg(s: string): string {\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Cross-platform child spawn that fixes native-Windows package-runner launches.\n * Direct spawn on macOS/Linux. On win32 it routes through\n * {@link resolveSpawnCommand}; an `.exe` runs directly, while a `.cmd`/`.bat`\n * (npx.cmd, the agent-connector.cmd launcher) is launched via a SINGLE quoted\n * command line with `shell: true` — a string rather than an args array, which\n * Node requires for a batch file AND which avoids the DEP0190 deprecation that\n * `shell: true` + an args array triggers on Node ≥ 24.\n */\nexport function spawnChild(\n command: string,\n args: string[],\n options: SpawnOptions,\n): ChildProcess {\n const resolved = resolveSpawnCommand(command);\n if (!resolved.needsShell) return spawn(resolved.file, args, options);\n const line = [resolved.file, ...args].map(winQuoteArg).join(\" \");\n return spawn(line, { ...options, shell: true });\n}\n","/**\n * telemetry/jsonrpc — shared MCP stdio wire primitives.\n *\n * The MCP stdio transport is NEWLINE-DELIMITED JSON-RPC: one single-line JSON\n * object per message, terminated by `\\n` (no Content-Length framing). These\n * primitives — the message shape, the id key, the line buffer — are used by BOTH\n * the telemetry proxy (which tees + measures) and `doctor --probe` (which sends\n * a real initialize/ping/tools-list handshake), so framing + id-correlation are\n * byte-identical across the two paths. Extracted here rather than duplicated.\n */\n\nimport { StringDecoder } from \"node:string_decoder\";\n\n/** Any newline-delimited JSON-RPC message — request, response, or notification. */\nexport interface JsonRpcMessage {\n jsonrpc?: unknown;\n id?: unknown;\n method?: unknown;\n params?: unknown;\n result?: unknown;\n error?: unknown;\n}\n\nexport function isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\n/** JSON-RPC ids are number | string; normalize to a Map key. `null` → no key. */\nexport function idKey(id: unknown): string | null {\n if (typeof id === \"string\") return `s:${id}`;\n if (typeof id === \"number\") return `n:${id}`;\n return null;\n}\n\n/**\n * Buffer a byte stream into complete `\\n`-terminated lines and invoke `onLine`\n * for each. Carriage returns are tolerated (some hosts emit CRLF). This is a\n * pure side-channel: it never owns or mutates the bytes being forwarded — the\n * caller has already written the original chunk downstream verbatim.\n */\nexport class LineBuffer {\n private buf = \"\";\n private readonly onLine: (line: string) => void;\n // Incremental UTF-8 decoder: `data` events split on arbitrary byte\n // boundaries, so a multi-byte sequence (emoji/CJK in a tool arg or result)\n // can straddle two chunks. StringDecoder holds back a trailing partial\n // sequence until it completes, keeping the measured copy byte-accurate.\n // (The forwarded stream is untouched — this is only the tee copy.)\n private readonly decoder = new StringDecoder(\"utf8\");\n\n constructor(onLine: (line: string) => void) {\n this.onLine = onLine;\n }\n\n push(chunk: Buffer): void {\n this.buf += this.decoder.write(chunk);\n let nl = this.buf.indexOf(\"\\n\");\n while (nl !== -1) {\n // Slice off one line (without the newline), tolerate a trailing CR.\n let line = this.buf.slice(0, nl);\n if (line.endsWith(\"\\r\")) line = line.slice(0, -1);\n if (line.length > 0) this.onLine(line);\n this.buf = this.buf.slice(nl + 1);\n nl = this.buf.indexOf(\"\\n\");\n }\n }\n}\n"],"mappings":";;;;;;AAQA,SAA+C,aAAa;AAU5D,SAAS,YAAY,GAAmB;AACtC,SAAO,IAAI,EAAE,QAAQ,MAAM,IAAI,CAAC;AAClC;AAWO,SAAS,WACd,SACA,MACA,SACc;AACd,QAAM,WAAW,oBAAoB,OAAO;AAC5C,MAAI,CAAC,SAAS,WAAY,QAAO,MAAM,SAAS,MAAM,MAAM,OAAO;AACnE,QAAM,OAAO,CAAC,SAAS,MAAM,GAAG,IAAI,EAAE,IAAI,WAAW,EAAE,KAAK,GAAG;AAC/D,SAAO,MAAM,MAAM,EAAE,GAAG,SAAS,OAAO,KAAK,CAAC;AAChD;;;AC7BA,SAAS,qBAAqB;AAYvB,SAAS,SAAS,GAA0C;AACjE,SAAO,OAAO,MAAM,YAAY,MAAM;AACxC;AAGO,SAAS,MAAM,IAA4B;AAChD,MAAI,OAAO,OAAO,SAAU,QAAO,KAAK,EAAE;AAC1C,MAAI,OAAO,OAAO,SAAU,QAAO,KAAK,EAAE;AAC1C,SAAO;AACT;AAQO,IAAM,aAAN,MAAiB;AAAA,EACd,MAAM;AAAA,EACG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,IAAI,cAAc,MAAM;AAAA,EAEnD,YAAY,QAAgC;AAC1C,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,KAAK,OAAqB;AACxB,SAAK,OAAO,KAAK,QAAQ,MAAM,KAAK;AACpC,QAAI,KAAK,KAAK,IAAI,QAAQ,IAAI;AAC9B,WAAO,OAAO,IAAI;AAEhB,UAAI,OAAO,KAAK,IAAI,MAAM,GAAG,EAAE;AAC/B,UAAI,KAAK,SAAS,IAAI,EAAG,QAAO,KAAK,MAAM,GAAG,EAAE;AAChD,UAAI,KAAK,SAAS,EAAG,MAAK,OAAO,IAAI;AACrC,WAAK,MAAM,KAAK,IAAI,MAAM,KAAK,CAAC;AAChC,WAAK,KAAK,IAAI,QAAQ,IAAI;AAAA,IAC5B;AAAA,EACF;AACF;","names":[]}
|
package/dist/chunk-Z2BVYKZL.js
DELETED
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
log
|
|
4
|
-
} from "./chunk-KHO5WNTP.js";
|
|
5
|
-
import {
|
|
6
|
-
REGISTERED_PLATFORM_IDS,
|
|
7
|
-
detectInstalledPlatforms,
|
|
8
|
-
loadAdapter
|
|
9
|
-
} from "./chunk-O2SBA5KR.js";
|
|
10
|
-
import {
|
|
11
|
-
deregisterConnector,
|
|
12
|
-
loadRegisteredConnector,
|
|
13
|
-
registerConnector
|
|
14
|
-
} from "./chunk-3JCRUROU.js";
|
|
15
|
-
import {
|
|
16
|
-
configPatchManualEdit
|
|
17
|
-
} from "./chunk-GSGDG2BV.js";
|
|
18
|
-
import {
|
|
19
|
-
hasMemoryLedger
|
|
20
|
-
} from "./chunk-N6HH7K6P.js";
|
|
21
|
-
import {
|
|
22
|
-
connectorDir,
|
|
23
|
-
connectorsDir,
|
|
24
|
-
dataRoot,
|
|
25
|
-
ensureHomeBin,
|
|
26
|
-
homeBinPath
|
|
27
|
-
} from "./chunk-TRQKHP7D.js";
|
|
28
|
-
|
|
29
|
-
// src/core/installer.ts
|
|
30
|
-
import { existsSync, readdirSync, rmSync } from "fs";
|
|
31
|
-
import { dirname, join } from "path";
|
|
32
|
-
import { fileURLToPath } from "url";
|
|
33
|
-
async function installConnector(opts) {
|
|
34
|
-
const { connector, modulePath, scope, projectDir, dryRun, force } = opts;
|
|
35
|
-
if (!dryRun) {
|
|
36
|
-
try {
|
|
37
|
-
ensureHomeBin(resolveCliEntry());
|
|
38
|
-
} catch (err) {
|
|
39
|
-
log.warn(`ensureHomeBin failed: ${errMessage(err)}`);
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
registerConnector(connector, modulePath);
|
|
43
|
-
} catch (err) {
|
|
44
|
-
log.warn(`registerConnector failed: ${errMessage(err)}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const targets = await resolveTargets(opts.targets, connector.targets, projectDir);
|
|
48
|
-
const result = newResult(connector.id, dryRun);
|
|
49
|
-
if (targets.length === 0) {
|
|
50
|
-
result.warnings.push(
|
|
51
|
-
"no target platforms resolved (none installed / detected, or all filtered out)"
|
|
52
|
-
);
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
for (const id of targets) {
|
|
56
|
-
const adapter = await tryLoadAdapter(id, result);
|
|
57
|
-
if (!adapter) continue;
|
|
58
|
-
const ctx = buildContext(connector, id, scope, projectDir, dryRun, force);
|
|
59
|
-
if (!dryRun) {
|
|
60
|
-
runStep(id, "backupSettings", result, () => {
|
|
61
|
-
const backup = adapter.backupSettings(ctx);
|
|
62
|
-
if (backup) {
|
|
63
|
-
result.changes.push({
|
|
64
|
-
platform: id,
|
|
65
|
-
action: "create",
|
|
66
|
-
path: backup,
|
|
67
|
-
detail: "backed up settings before install"
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
runStep(id, "installServer", result, () => {
|
|
73
|
-
pushAll(result.changes, adapter.installServer(ctx));
|
|
74
|
-
});
|
|
75
|
-
runStep(id, "installHooks", result, () => {
|
|
76
|
-
pushAll(result.changes, adapter.installHooks(ctx));
|
|
77
|
-
});
|
|
78
|
-
const nativeHooks = connector.platforms[id]?.nativeHooks;
|
|
79
|
-
const nativeCount = nativeHooks ? Object.keys(nativeHooks).length : 0;
|
|
80
|
-
if (nativeCount > 0 && !(adapter.capabilities.supportsNativeHooks ?? false)) {
|
|
81
|
-
result.changes.push({
|
|
82
|
-
platform: id,
|
|
83
|
-
action: "warn",
|
|
84
|
-
detail: `nativeHooks not supported on ${id}; ${nativeCount} skipped`
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
if (connector.commands.length) {
|
|
88
|
-
runStep(id, "installCommands", result, () => {
|
|
89
|
-
pushAll(result.changes, adapter.installCommands(ctx));
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
if (connector.skills.length) {
|
|
93
|
-
runStep(id, "installSkills", result, () => {
|
|
94
|
-
pushAll(result.changes, adapter.installSkills(ctx));
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
if (connector.subagents.length) {
|
|
98
|
-
runStep(id, "installSubagents", result, () => {
|
|
99
|
-
pushAll(result.changes, adapter.installSubagents(ctx));
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
if ((connector.memory ?? []).length) {
|
|
103
|
-
runStep(id, "installMemory", result, () => {
|
|
104
|
-
pushAll(result.changes, adapter.installMemory(ctx));
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
const configPatches = connector.platforms[id]?.configPatch ?? [];
|
|
108
|
-
if (configPatches.length > 0) {
|
|
109
|
-
if (adapter.capabilities.supportsConfigPatch ?? false) {
|
|
110
|
-
runStep(id, "installConfigPatches", result, () => {
|
|
111
|
-
pushAll(result.changes, adapter.installConfigPatches(ctx));
|
|
112
|
-
});
|
|
113
|
-
} else {
|
|
114
|
-
result.changes.push({
|
|
115
|
-
platform: id,
|
|
116
|
-
action: "warn",
|
|
117
|
-
detail: `configPatch not supported on ${id}; ${configPatches.length} skipped`
|
|
118
|
-
});
|
|
119
|
-
for (const patch of configPatches) {
|
|
120
|
-
result.changes.push({
|
|
121
|
-
platform: id,
|
|
122
|
-
action: "warn",
|
|
123
|
-
detail: `configPatch ${patch.key} skipped on ${id} \u2014 ${configPatchManualEdit(patch)}`
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
async function syncConnector(opts) {
|
|
132
|
-
return installConnector(opts);
|
|
133
|
-
}
|
|
134
|
-
async function uninstallConnector(opts) {
|
|
135
|
-
const { connectorId, scope, projectDir, dryRun, purge } = opts;
|
|
136
|
-
const connector = await loadConnectorForUninstall(connectorId);
|
|
137
|
-
const result = newResult(connectorId, dryRun);
|
|
138
|
-
const targets = await resolveTargets(opts.targets, connector.targets, projectDir);
|
|
139
|
-
if (targets.length === 0) {
|
|
140
|
-
result.warnings.push(
|
|
141
|
-
"no target platforms resolved for uninstall (none installed / detected, or all filtered out)"
|
|
142
|
-
);
|
|
143
|
-
if (purge) purgeFrameworkState(connectorId, dryRun, result);
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
for (const id of targets) {
|
|
147
|
-
const adapter = await tryLoadAdapter(id, result);
|
|
148
|
-
if (!adapter) continue;
|
|
149
|
-
const ctx = buildContext(connector, id, scope, projectDir, dryRun);
|
|
150
|
-
if (adapter.capabilities.supportsConfigPatch ?? false) {
|
|
151
|
-
runStep(id, "uninstallConfigPatches", result, () => {
|
|
152
|
-
pushAll(result.changes, adapter.uninstallConfigPatches(ctx));
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
if ((connector.memory ?? []).length > 0 || hasMemoryLedger(connector.id)) {
|
|
156
|
-
runStep(id, "uninstallMemory", result, () => {
|
|
157
|
-
pushAll(result.changes, adapter.uninstallMemory(ctx));
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
if (connector.subagents.length) {
|
|
161
|
-
runStep(id, "uninstallSubagents", result, () => {
|
|
162
|
-
pushAll(result.changes, adapter.uninstallSubagents(ctx));
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
if (connector.commands.length) {
|
|
166
|
-
runStep(id, "uninstallCommands", result, () => {
|
|
167
|
-
pushAll(result.changes, adapter.uninstallCommands(ctx));
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
if (connector.skills.length) {
|
|
171
|
-
runStep(id, "uninstallSkills", result, () => {
|
|
172
|
-
pushAll(result.changes, adapter.uninstallSkills(ctx));
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
runStep(id, "uninstallHooks", result, () => {
|
|
176
|
-
pushAll(result.changes, adapter.uninstallHooks(ctx));
|
|
177
|
-
});
|
|
178
|
-
runStep(id, "uninstallServer", result, () => {
|
|
179
|
-
pushAll(result.changes, adapter.uninstallServer(ctx));
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
if (purge) purgeFrameworkState(connectorId, dryRun, result);
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
function purgeFrameworkState(connectorId, dryRun, result) {
|
|
186
|
-
const platform = connectorId;
|
|
187
|
-
const recordDir = connectorDir(connectorId);
|
|
188
|
-
const recordExisted = existsSync(recordDir);
|
|
189
|
-
if (recordExisted) {
|
|
190
|
-
if (!dryRun) {
|
|
191
|
-
try {
|
|
192
|
-
deregisterConnector(connectorId);
|
|
193
|
-
} catch (err) {
|
|
194
|
-
log.warn(`deregisterConnector failed: ${errMessage(err)}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
result.changes.push({
|
|
198
|
-
platform,
|
|
199
|
-
action: "remove",
|
|
200
|
-
path: recordDir,
|
|
201
|
-
detail: "deregistered connector record"
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
if (noConnectorsRemain(connectorId, dryRun, recordExisted)) {
|
|
205
|
-
const binPath = homeBinPath();
|
|
206
|
-
if (existsSync(binPath)) {
|
|
207
|
-
if (!dryRun) {
|
|
208
|
-
try {
|
|
209
|
-
rmSync(binPath, { force: true });
|
|
210
|
-
} catch (err) {
|
|
211
|
-
log.warn(`home-bin removal failed: ${errMessage(err)}`);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
result.changes.push({
|
|
215
|
-
platform,
|
|
216
|
-
action: "remove",
|
|
217
|
-
path: binPath,
|
|
218
|
-
detail: "removed home-bin (no connectors remain)"
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
function noConnectorsRemain(connectorId, dryRun, recordExisted) {
|
|
224
|
-
const dir = connectorsDir();
|
|
225
|
-
if (!existsSync(dir)) return true;
|
|
226
|
-
let entries;
|
|
227
|
-
try {
|
|
228
|
-
entries = readdirSync(dir);
|
|
229
|
-
} catch {
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
const remaining = entries.filter(
|
|
233
|
-
(e) => !(dryRun && recordExisted && e === connectorId)
|
|
234
|
-
);
|
|
235
|
-
return remaining.length === 0;
|
|
236
|
-
}
|
|
237
|
-
function resolveCliEntry() {
|
|
238
|
-
try {
|
|
239
|
-
let dir = dirname(fileURLToPath(import.meta.url));
|
|
240
|
-
for (let i = 0; i < 8; i++) {
|
|
241
|
-
if (existsSync(join(dir, "package.json"))) {
|
|
242
|
-
const cli = join(dir, "dist", "cli.js");
|
|
243
|
-
if (existsSync(cli)) return cli;
|
|
244
|
-
}
|
|
245
|
-
const parent = dirname(dir);
|
|
246
|
-
if (parent === dir) break;
|
|
247
|
-
dir = parent;
|
|
248
|
-
}
|
|
249
|
-
const sameDir = fileURLToPath(new URL("./cli.js", import.meta.url));
|
|
250
|
-
if (existsSync(sameDir)) return sameDir;
|
|
251
|
-
} catch {
|
|
252
|
-
}
|
|
253
|
-
const argv1 = process.argv[1];
|
|
254
|
-
if (argv1 && argv1.length > 0) return argv1;
|
|
255
|
-
return "cli.js";
|
|
256
|
-
}
|
|
257
|
-
async function resolveTargets(flagTargets, connectorTargets, projectDir) {
|
|
258
|
-
let requested;
|
|
259
|
-
if (flagTargets && flagTargets.length > 0) {
|
|
260
|
-
requested = flagTargets;
|
|
261
|
-
} else if (Array.isArray(connectorTargets) && connectorTargets.length > 0) {
|
|
262
|
-
requested = connectorTargets;
|
|
263
|
-
} else {
|
|
264
|
-
requested = await autoDetectIds(projectDir);
|
|
265
|
-
}
|
|
266
|
-
const seen = /* @__PURE__ */ new Set();
|
|
267
|
-
const out = [];
|
|
268
|
-
for (const id of requested) {
|
|
269
|
-
if (!REGISTERED_PLATFORM_IDS.has(id)) continue;
|
|
270
|
-
if (seen.has(id)) continue;
|
|
271
|
-
seen.add(id);
|
|
272
|
-
out.push(id);
|
|
273
|
-
}
|
|
274
|
-
return out;
|
|
275
|
-
}
|
|
276
|
-
async function autoDetectIds(projectDir) {
|
|
277
|
-
try {
|
|
278
|
-
const detected = await detectInstalledPlatforms(projectDir);
|
|
279
|
-
return detected.filter((p) => p.installed).map((p) => p.id);
|
|
280
|
-
} catch (err) {
|
|
281
|
-
log.warn(`platform detection failed: ${errMessage(err)}`);
|
|
282
|
-
return [];
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function buildContext(connector, id, defaultScope, projectDir, dryRun, force = false) {
|
|
286
|
-
return {
|
|
287
|
-
connector,
|
|
288
|
-
scope: connector.platforms[id]?.scope ?? defaultScope,
|
|
289
|
-
projectDir,
|
|
290
|
-
homeBinPath: homeBinPath(),
|
|
291
|
-
dataRoot: dataRoot(),
|
|
292
|
-
dryRun,
|
|
293
|
-
force
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
async function tryLoadAdapter(id, result) {
|
|
297
|
-
try {
|
|
298
|
-
const adapter = await loadAdapter(id);
|
|
299
|
-
if (adapter) return adapter;
|
|
300
|
-
const detail = `no adapter registered for ${id}`;
|
|
301
|
-
result.changes.push({ platform: id, action: "warn", detail });
|
|
302
|
-
result.warnings.push(detail);
|
|
303
|
-
return null;
|
|
304
|
-
} catch (err) {
|
|
305
|
-
const detail = `failed to load adapter for ${id}: ${errMessage(err)}`;
|
|
306
|
-
result.changes.push({ platform: id, action: "warn", detail });
|
|
307
|
-
result.warnings.push(detail);
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
function runStep(id, step, result, fn) {
|
|
312
|
-
try {
|
|
313
|
-
fn();
|
|
314
|
-
} catch (err) {
|
|
315
|
-
const detail = `${step} failed on ${id}: ${errMessage(err)}`;
|
|
316
|
-
result.changes.push({ platform: id, action: "warn", detail });
|
|
317
|
-
result.warnings.push(detail);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
async function loadConnectorForUninstall(connectorId) {
|
|
321
|
-
try {
|
|
322
|
-
return await loadRegisteredConnector(connectorId);
|
|
323
|
-
} catch (err) {
|
|
324
|
-
log.warn(
|
|
325
|
-
`could not load registered connector "${connectorId}" for uninstall (${errMessage(err)}); proceeding with a minimal id-only context`
|
|
326
|
-
);
|
|
327
|
-
return syntheticConnector(connectorId);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
function syntheticConnector(id) {
|
|
331
|
-
return {
|
|
332
|
-
id,
|
|
333
|
-
displayName: id,
|
|
334
|
-
version: "0.0.0",
|
|
335
|
-
hooks: {},
|
|
336
|
-
hookEvents: [],
|
|
337
|
-
telemetry: {
|
|
338
|
-
enabled: true,
|
|
339
|
-
modelFamilyHint: "auto",
|
|
340
|
-
measureToolDefs: true,
|
|
341
|
-
hostNativeUsage: false,
|
|
342
|
-
store: "ndjson",
|
|
343
|
-
calibration: { anthropicCountTokens: false }
|
|
344
|
-
},
|
|
345
|
-
commands: [],
|
|
346
|
-
skills: [],
|
|
347
|
-
subagents: [],
|
|
348
|
-
memory: [],
|
|
349
|
-
platforms: {},
|
|
350
|
-
targets: "auto"
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
function newResult(connectorId, dryRun) {
|
|
354
|
-
return { connectorId, dryRun, changes: [], warnings: [] };
|
|
355
|
-
}
|
|
356
|
-
function pushAll(target, records) {
|
|
357
|
-
for (const r of records) target.push(r);
|
|
358
|
-
}
|
|
359
|
-
function errMessage(err) {
|
|
360
|
-
return err instanceof Error ? err.message : String(err);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
export {
|
|
364
|
-
installConnector,
|
|
365
|
-
syncConnector,
|
|
366
|
-
uninstallConnector,
|
|
367
|
-
resolveCliEntry
|
|
368
|
-
};
|
|
369
|
-
//# sourceMappingURL=chunk-Z2BVYKZL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/installer.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 { 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 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 */\nfunction 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 // 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 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 */\nasync 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 * 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"],"mappings":"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","names":[]}
|