@snapback/cli 1.1.12 → 1.1.14
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 -9
- package/dist/{analysis-Z53F5FT2.js → analysis-C6XVLBAL.js} +3 -3
- package/dist/{analysis-Z53F5FT2.js.map → analysis-C6XVLBAL.js.map} +1 -1
- package/dist/{chunk-KPETDXQO.js → chunk-2TOJVUVJ.js} +296 -33
- package/dist/chunk-2TOJVUVJ.js.map +1 -0
- package/dist/chunk-5EQLSU5B.js +385 -0
- package/dist/chunk-5EQLSU5B.js.map +1 -0
- package/dist/{chunk-YOVA65PS.js → chunk-A3TUM7U4.js} +320 -63
- package/dist/chunk-A3TUM7U4.js.map +1 -0
- package/dist/{chunk-ISVRGBWT.js → chunk-LEXNOXPV.js} +6030 -632
- package/dist/chunk-LEXNOXPV.js.map +1 -0
- package/dist/{chunk-G7QXHNGB.js → chunk-OJNDAPC2.js} +41 -15
- package/dist/chunk-OJNDAPC2.js.map +1 -0
- package/dist/{chunk-NKBZIXCN.js → chunk-Q5XZ3DCB.js} +5 -5
- package/dist/{chunk-NKBZIXCN.js.map → chunk-Q5XZ3DCB.js.map} +1 -1
- package/dist/chunk-QLCHTUT5.js +1067 -0
- package/dist/chunk-QLCHTUT5.js.map +1 -0
- package/dist/dist-D2SHOZMS.js +8 -0
- package/dist/{dist-7UKXVKH3.js.map → dist-D2SHOZMS.js.map} +1 -1
- package/dist/{dist-7UKXVKH3.js → dist-L76VXYJ5.js} +3 -3
- package/dist/{dist-VDK7WEF4.js.map → dist-L76VXYJ5.js.map} +1 -1
- package/dist/dist-RPM72FHJ.js +5 -0
- package/dist/{dist-WKLJSPJT.js.map → dist-RPM72FHJ.js.map} +1 -1
- package/dist/index.js +38672 -24130
- package/dist/index.js.map +1 -1
- package/dist/learning-pruner-YSZSOOOC.js +7 -0
- package/dist/learning-pruner-YSZSOOOC.js.map +1 -0
- package/dist/{secure-credentials-6UMEU22H.js → secure-credentials-A4QHHOE2.js} +14 -6
- package/dist/secure-credentials-A4QHHOE2.js.map +1 -0
- package/dist/{snapback-dir-T3CRQRY6.js → snapback-dir-6QUSO6Y3.js} +3 -3
- package/dist/{snapback-dir-T3CRQRY6.js.map → snapback-dir-6QUSO6Y3.js.map} +1 -1
- package/dist/storage-H366UNAR.js +6 -0
- package/dist/storage-H366UNAR.js.map +1 -0
- package/package.json +8 -9
- package/dist/chunk-G7QXHNGB.js.map +0 -1
- package/dist/chunk-ISVRGBWT.js.map +0 -1
- package/dist/chunk-KPETDXQO.js.map +0 -1
- package/dist/chunk-YOVA65PS.js.map +0 -1
- package/dist/dist-VDK7WEF4.js +0 -5
- package/dist/dist-WKLJSPJT.js +0 -8
- package/dist/secure-credentials-6UMEU22H.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/mcp-config/src/detect.ts","../../../packages/mcp-config/src/identity.ts","../../../packages/mcp-config/src/process-check.ts","../../../packages/mcp-config/src/validate.ts","../../../packages/mcp-config/src/write.ts","../../../packages/mcp-config/src/repair.ts"],"names":["CLIENT_CONFIGS","claude","home","platform","join","process","env","APPDATA","cursor","__name","_home","cwd","windsurf","continue","vscode","zed","cline","gemini","aider","qoder","workspaceConfig","globalConfig","CLIENT_DISPLAY_NAMES","detectAIClients","options","homedir","clients","seenPaths","Set","name","getPaths","Object","entries","paths","configPath","has","add","exists","existsSync","hasSnapback","content","readFileSync","endsWith","includes","parsed","JSON","parse","checkForSnapback","push","displayName","format","detected","filter","c","needsSetup","getClient","clientName","result","find","getConfiguredClients","config","configObj","mcpServers","servers","context_servers","experimental","Array","isArray","modelContextProtocolServers","some","server","getClientConfigPath","undefined","readClientConfig","client","detectWorkspaceConfig","workspaceRoot","root","qoderConfig","path","type","cursorConfig","vscodeConfig","windsurfConfig","getSnapbackConfigDir","isWindows","getIdentityFilePath","cachedIdentity","getOrCreateIdentity","identityPath","identity","userId","installId","randomUUID","createdAt","Date","toISOString","configDir","mkdirSync","recursive","writeFileSync","stringify","getCLIVersion","packagePaths","__dirname","pkgPath","pkg","version","createManagedMetadata","workspaceId","cliVersion","updatedAt","transport","isOwnedByThisInstall","metadata","resetIdentityCache","execAsync","promisify","exec","detectMCPProcesses","stdout","timeout","processes","parseProcessOutput","snapbackProcesses","p","isSnapback","allProcesses","snapbackRunning","length","totalCount","checkedAt","output","lines","trim","split","line","match","pidStr","command","pid","Number","parseInt","isNaN","serverName","extractServerName","toLowerCase","patterns","pattern","isSnapbackMCPRunning","health","validateClientConfig","issues","severity","code","message","fix","valid","configContent","parsedConfig","error","Error","snapbackConfig","extractSnapbackConfig","validateSnapbackConfig","args","workspaceIdx","indexOf","workspacePath","wsValidation","validateWorkspacePath","hasMarkers","i","absPath","resolve","hasGit","hasPackageJson","snapback","s","url","isCommandExecutable","cliPath","URL","SNAPBACK_API_KEY","SNAPBACK_WORKSPACE_ID","startsWith","cmd","execSync","encoding","cachedNodePath","resolveNodePath","nodePath","commonPaths","STDIO_ONLY_CLIENTS","getSnapbackMCPConfig","apiKey","serverUrl","useBinary","customCommand","additionalEnv","useLocalDev","localCliPath","useNpx","keys","tier","writeClientConfig","mcpConfig","dirname","existingConfig","hasExistingConfig","backup","now","newConfig","mergeConfig","success","removeSnapbackConfig","serverKey","getServerKey","zedConfig","contextServers","existing","disabled","alwaysAllow","_","rest","continueConfig","filteredServers","validateConfig","serverConfig","Boolean","cfg","expCfg","srvs","repairClientConfig","fixed","remaining","validation","force","performFullReconfiguration","issue","fixResult","attemptFix","hasCriticalErrors","msg","injectWorkspacePath","detectedWorkspace","detectWorkspaceRoot","hasWorkspace","_validation","findCliPath","workspace","console","writeResult","startPath","currentPath","maxIterations","iterations","parent","candidates"],"mappings":"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","file":"chunk-2TOJVUVJ.js","sourcesContent":["/**\n * AI Client Detection Module\n *\n * Detects installed AI assistants (Claude Desktop, Cursor, Windsurf, Continue)\n * and checks their MCP configuration status.\n *\n * @packageDocumentation\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { AIClientConfig, AIClientFormat, DetectionResult, MCPConfig } from \"./types.js\";\n\n// =============================================================================\n// CLIENT PATH CONFIGURATION\n// =============================================================================\n\n/**\n * Platform-specific config path resolvers for each AI client\n * Note: User preference is project-level configs where supported\n */\nconst CLIENT_CONFIGS: Record<string, (home: string, cwd?: string) => string[]> = {\n\tclaude: (home) => {\n\t\tswitch (platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\treturn [join(home, \"Library/Application Support/Claude/claude_desktop_config.json\")];\n\t\t\tcase \"win32\":\n\t\t\t\treturn [join(process.env.APPDATA || \"\", \"Claude/claude_desktop_config.json\")];\n\t\t\tdefault:\n\t\t\t\treturn [join(home, \".config/Claude/claude_desktop_config.json\")];\n\t\t}\n\t},\n\t// Project-level first (user preference), then global fallback\n\tcursor: (_home, cwd) => [...(cwd ? [join(cwd, \".cursor/mcp.json\")] : []), join(_home, \".cursor/mcp.json\")],\n\twindsurf: (home, cwd) => [\n\t\t...(cwd ? [join(cwd, \".windsurf/mcp.json\")] : []),\n\t\tjoin(home, \".codeium/windsurf/mcp_config.json\"),\n\t],\n\tcontinue: (home) => [join(home, \".continue/config.json\")],\n\t// New clients\n\tvscode: (_home, cwd) => [...(cwd ? [join(cwd, \".vscode/mcp.json\")] : [])],\n\tzed: (home) => [join(home, \".config/zed/settings.json\")],\n\tcline: (home) => [join(home, \".cline/mcp.json\")],\n\tgemini: (home) => [join(home, \".gemini/settings.json\")],\n\taider: (home) => [join(home, \".aider/mcp.yaml\")],\n\t\"roo-code\": (home) => [join(home, \".roo-code/mcp.json\")],\n\t// Qoder (VS Code fork) - supports both project-level and global configs\n\tqoder: (home, cwd) => {\n\t\tconst workspaceConfig = cwd ? [join(cwd, \".qoder-mcp-config.json\")] : [];\n\t\tconst globalConfig = (() => {\n\t\t\tswitch (platform()) {\n\t\t\t\tcase \"darwin\":\n\t\t\t\t\treturn join(home, \"Library/Application Support/Qoder/SharedClientCache/extension/local/mcp.json\");\n\t\t\t\tcase \"win32\":\n\t\t\t\t\treturn join(process.env.APPDATA || \"\", \"Qoder/mcp.json\");\n\t\t\t\tdefault:\n\t\t\t\t\treturn join(home, \".config/Qoder/mcp.json\");\n\t\t\t}\n\t\t})();\n\t\treturn [...workspaceConfig, globalConfig];\n\t},\n};\n\n/**\n * Display names for AI clients\n */\nconst CLIENT_DISPLAY_NAMES: Record<string, string> = {\n\tclaude: \"Claude Desktop\",\n\tcursor: \"Cursor\",\n\twindsurf: \"Windsurf\",\n\tcontinue: \"Continue\",\n\tvscode: \"VS Code\",\n\tzed: \"Zed\",\n\tcline: \"Cline\",\n\tgemini: \"Gemini/Antigravity\",\n\taider: \"Aider\",\n\t\"roo-code\": \"Roo Code\",\n\tqoder: \"Qoder\",\n};\n\n// =============================================================================\n// DETECTION FUNCTIONS\n// =============================================================================\n\n/**\n * Detect all AI clients and their configuration status\n *\n * @param options - Detection options\n * @param options.cwd - Current working directory for project-level configs\n * @returns Detection result with all clients, detected clients, and clients needing setup\n *\n * @example\n * ```ts\n * const result = detectAIClients();\n * console.log(`Found ${result.detected.length} AI assistants`);\n *\n * for (const client of result.needsSetup) {\n * console.log(`${client.displayName} needs SnapBack configuration`);\n * }\n * ```\n */\nexport function detectAIClients(options: { cwd?: string } = {}): DetectionResult {\n\tconst home = homedir();\n\tconst cwd = options.cwd || process.cwd();\n\tconst clients: AIClientConfig[] = [];\n\tconst seenPaths = new Set<string>();\n\n\tfor (const [name, getPaths] of Object.entries(CLIENT_CONFIGS)) {\n\t\tconst paths = getPaths(home, cwd);\n\n\t\tfor (const configPath of paths) {\n\t\t\t// Avoid duplicate entries for same path\n\t\t\tif (seenPaths.has(configPath)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tseenPaths.add(configPath);\n\n\t\t\tconst exists = existsSync(configPath);\n\t\t\tlet hasSnapback = false;\n\n\t\t\tif (exists) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = readFileSync(configPath, \"utf-8\");\n\t\t\t\t\t// Handle YAML for aider\n\t\t\t\t\tif (configPath.endsWith(\".yaml\") || configPath.endsWith(\".yml\")) {\n\t\t\t\t\t\thasSnapback = content.includes(\"snapback\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst parsed = JSON.parse(content) as unknown;\n\t\t\t\t\t\thasSnapback = checkForSnapback(parsed, name as AIClientFormat);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Invalid JSON/YAML or read error - treat as no snapback\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tclients.push({\n\t\t\t\tname,\n\t\t\t\tdisplayName: CLIENT_DISPLAY_NAMES[name] || name,\n\t\t\t\tconfigPath,\n\t\t\t\texists,\n\t\t\t\thasSnapback,\n\t\t\t\tformat: name as AIClientFormat,\n\t\t\t});\n\t\t}\n\t}\n\n\tconst detected = clients.filter((c) => c.exists);\n\tconst needsSetup = detected.filter((c) => !c.hasSnapback);\n\n\treturn { clients, detected, needsSetup };\n}\n\n/**\n * Check if a specific AI client is installed\n *\n * @param clientName - Name of the client to check (claude, cursor, windsurf, continue)\n * @returns The client config if found, undefined otherwise\n */\nexport function getClient(clientName: string): AIClientConfig | undefined {\n\tconst result = detectAIClients();\n\treturn result.clients.find((c) => c.name === clientName && c.exists);\n}\n\n/**\n * Get all clients that have SnapBack configured\n *\n * @returns Array of configured clients\n */\nexport function getConfiguredClients(): AIClientConfig[] {\n\tconst result = detectAIClients();\n\treturn result.detected.filter((c) => c.hasSnapback);\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Check if SnapBack is configured in a config object\n */\nfunction checkForSnapback(config: unknown, format: AIClientFormat): boolean {\n\tif (!config || typeof config !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst configObj = config as Record<string, unknown>;\n\n\tswitch (format) {\n\t\tcase \"claude\":\n\t\tcase \"cursor\":\n\t\tcase \"windsurf\":\n\t\tcase \"cline\":\n\t\tcase \"roo-code\":\n\t\tcase \"qoder\":\n\t\t\t// These use mcpServers.snapback format\n\t\t\tif (\n\t\t\t\t\"mcpServers\" in configObj &&\n\t\t\t\ttypeof configObj.mcpServers === \"object\" &&\n\t\t\t\tconfigObj.mcpServers !== null\n\t\t\t) {\n\t\t\t\tconst servers = configObj.mcpServers as Record<string, unknown>;\n\t\t\t\t// Check for namespaced key or legacy \"snapback\" key\n\t\t\t\treturn \"snapback\" in servers || `snapback-${format}` in servers;\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase \"vscode\":\n\t\t\t// VS Code uses \"servers\" not \"mcpServers\"\n\t\t\tif (\"servers\" in configObj && typeof configObj.servers === \"object\" && configObj.servers !== null) {\n\t\t\t\tconst servers = configObj.servers as Record<string, unknown>;\n\t\t\t\t// Check for namespaced key or legacy \"snapback\" key\n\t\t\t\treturn \"snapback\" in servers || \"snapback-vscode\" in servers;\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase \"gemini\":\n\t\tcase \"zed\":\n\t\t\t// Zed uses \"context_servers\" not \"mcpServers\"\n\t\t\tif (\n\t\t\t\t\"context_servers\" in configObj &&\n\t\t\t\ttypeof configObj.context_servers === \"object\" &&\n\t\t\t\tconfigObj.context_servers !== null\n\t\t\t) {\n\t\t\t\tconst servers = configObj.context_servers as Record<string, unknown>;\n\t\t\t\t// Check for namespaced key or legacy \"snapback\" key\n\t\t\t\treturn \"snapback\" in servers || \"snapback-zed\" in servers;\n\t\t\t}\n\t\t\t// Fallback: also check mcpServers for gemini\n\t\t\tif (\n\t\t\t\t\"mcpServers\" in configObj &&\n\t\t\t\ttypeof configObj.mcpServers === \"object\" &&\n\t\t\t\tconfigObj.mcpServers !== null\n\t\t\t) {\n\t\t\t\tconst servers = configObj.mcpServers as Record<string, unknown>;\n\t\t\t\treturn \"snapback\" in servers || `snapback-${format}` in servers;\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase \"continue\":\n\t\t\t// Continue uses a different structure - check for experimental.modelContextProtocolServers\n\t\t\tif (\n\t\t\t\t\"experimental\" in configObj &&\n\t\t\t\ttypeof configObj.experimental === \"object\" &&\n\t\t\t\tconfigObj.experimental !== null\n\t\t\t) {\n\t\t\t\tconst experimental = configObj.experimental as Record<string, unknown>;\n\t\t\t\tif (\n\t\t\t\t\t\"modelContextProtocolServers\" in experimental &&\n\t\t\t\t\tArray.isArray(experimental.modelContextProtocolServers)\n\t\t\t\t) {\n\t\t\t\t\treturn experimental.modelContextProtocolServers.some(\n\t\t\t\t\t\t(server: unknown) =>\n\t\t\t\t\t\t\ttypeof server === \"object\" &&\n\t\t\t\t\t\t\tserver !== null &&\n\t\t\t\t\t\t\t(server as Record<string, unknown>).name === \"snapback\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase \"aider\":\n\t\t\t// Aider uses YAML - handled separately in detectAIClients\n\t\t\treturn false;\n\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Get the expected config path for a client on the current platform\n *\n * @param clientName - Name of the client\n * @returns The config path or undefined if unknown client\n */\nexport function getClientConfigPath(clientName: string): string | undefined {\n\tconst getPaths = CLIENT_CONFIGS[clientName];\n\tif (!getPaths) {\n\t\treturn undefined;\n\t}\n\n\tconst paths = getPaths(homedir());\n\treturn paths[0];\n}\n\n/**\n * Read and parse a client's MCP config file\n *\n * @param client - The client to read config for\n * @returns Parsed config or undefined if not found/invalid\n */\nexport function readClientConfig(client: AIClientConfig): MCPConfig | undefined {\n\ttry {\n\t\tconst content = readFileSync(client.configPath, \"utf-8\");\n\t\treturn JSON.parse(content) as MCPConfig;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Detect workspace-specific MCP configurations\n * Checks for project-level configs that take precedence over global ones\n *\n * @param workspaceRoot - Workspace root directory (defaults to cwd)\n * @returns Config info if found, null otherwise\n *\n * @example\n * ```ts\n * const wsConfig = detectWorkspaceConfig();\n * if (wsConfig) {\n * console.log(`Found workspace config: ${wsConfig.path}`);\n * // Skip adding global config to prevent conflicts\n * }\n * ```\n */\nexport function detectWorkspaceConfig(\n\tworkspaceRoot?: string,\n): { path: string; type: \"qoder\" | \"vscode\" | \"cursor\" | \"windsurf\" } | null {\n\tconst root = workspaceRoot || process.cwd();\n\n\t// Check Qoder workspace config (.qoder-mcp-config.json)\n\tconst qoderConfig = join(root, \".qoder-mcp-config.json\");\n\tif (existsSync(qoderConfig)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(qoderConfig, \"utf-8\");\n\t\t\tif (content.includes(\"snapback\")) {\n\t\t\t\treturn { path: qoderConfig, type: \"qoder\" };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid JSON or read error\n\t\t}\n\t}\n\n\t// Check Cursor project config (.cursor/mcp.json)\n\tconst cursorConfig = join(root, \".cursor\", \"mcp.json\");\n\tif (existsSync(cursorConfig)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(cursorConfig, \"utf-8\");\n\t\t\tif (content.includes(\"snapback\")) {\n\t\t\t\treturn { path: cursorConfig, type: \"cursor\" };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid JSON or read error\n\t\t}\n\t}\n\n\t// Check VS Code project config (.vscode/mcp.json)\n\tconst vscodeConfig = join(root, \".vscode\", \"mcp.json\");\n\tif (existsSync(vscodeConfig)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(vscodeConfig, \"utf-8\");\n\t\t\tif (content.includes(\"snapback\")) {\n\t\t\t\treturn { path: vscodeConfig, type: \"vscode\" };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid JSON or read error\n\t\t}\n\t}\n\n\t// Check Windsurf project config (.windsurf/mcp.json)\n\tconst windsurfConfig = join(root, \".windsurf\", \"mcp.json\");\n\tif (existsSync(windsurfConfig)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(windsurfConfig, \"utf-8\");\n\t\t\tif (content.includes(\"snapback\")) {\n\t\t\t\treturn { path: windsurfConfig, type: \"windsurf\" };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid JSON or read error\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * Identity Module for MCP Config\n *\n * §10.2: Manages persistent identifiers for managed MCP config entries:\n * - userId: Stable user identifier (persists across reinstalls on same machine)\n * - installId: Per-installation identifier (regenerated on reinstall)\n *\n * @packageDocumentation\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { AIClientFormat, SnapbackManagedMetadata } from \"./types.js\";\n\n// =============================================================================\n// PATHS\n// =============================================================================\n\n/**\n * Get SnapBack config directory path\n */\nexport function getSnapbackConfigDir(): string {\n\tconst isWindows = process.platform === \"win32\";\n\tif (isWindows) {\n\t\treturn join(process.env.APPDATA || homedir(), \"SnapBack\");\n\t}\n\treturn join(homedir(), \".snapback\");\n}\n\n/**\n * Get identity file path\n */\nfunction getIdentityFilePath(): string {\n\treturn join(getSnapbackConfigDir(), \"identity.json\");\n}\n\n// =============================================================================\n// IDENTITY TYPES\n// =============================================================================\n\ninterface StoredIdentity {\n\t/** User ID - stable across sessions */\n\tuserId: string;\n\t/** Install ID - per machine install */\n\tinstallId: string;\n\t/** Created timestamp */\n\tcreatedAt: string;\n}\n\n// =============================================================================\n// IDENTITY MANAGEMENT\n// =============================================================================\n\n/** Cached identity to avoid repeated disk reads */\nlet cachedIdentity: StoredIdentity | null = null;\n\n/**\n * Get or create stored identity\n *\n * §5.2: Generates and persists userId and installId\n */\nexport function getOrCreateIdentity(): StoredIdentity {\n\tif (cachedIdentity) {\n\t\treturn cachedIdentity;\n\t}\n\n\tconst identityPath = getIdentityFilePath();\n\n\t// Try to read existing identity\n\tif (existsSync(identityPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(identityPath, \"utf-8\");\n\t\t\tconst identity = JSON.parse(content) as StoredIdentity;\n\t\t\tif (identity.userId && identity.installId) {\n\t\t\t\tcachedIdentity = identity;\n\t\t\t\treturn identity;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid file, will regenerate\n\t\t}\n\t}\n\n\t// Create new identity\n\tconst identity: StoredIdentity = {\n\t\tuserId: randomUUID(),\n\t\tinstallId: randomUUID(),\n\t\tcreatedAt: new Date().toISOString(),\n\t};\n\n\t// Ensure directory exists\n\tconst configDir = getSnapbackConfigDir();\n\tmkdirSync(configDir, { recursive: true });\n\n\t// Write identity file\n\twriteFileSync(identityPath, JSON.stringify(identity, null, 2));\n\n\tcachedIdentity = identity;\n\treturn identity;\n}\n\n/**\n * Get current CLI version from package.json\n */\nfunction getCLIVersion(): string {\n\ttry {\n\t\t// Try to read from node_modules or nearby package.json\n\t\tconst packagePaths = [\n\t\t\tjoin(__dirname, \"../package.json\"),\n\t\t\tjoin(__dirname, \"../../package.json\"),\n\t\t\tjoin(process.cwd(), \"package.json\"),\n\t\t];\n\n\t\tfor (const pkgPath of packagePaths) {\n\t\t\tif (existsSync(pkgPath)) {\n\t\t\t\tconst content = readFileSync(pkgPath, \"utf-8\");\n\t\t\t\tconst pkg = JSON.parse(content);\n\t\t\t\tif (pkg.name?.includes(\"snapback\")) {\n\t\t\t\t\treturn pkg.version || \"1.0.0\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Fallback\n\t}\n\treturn \"1.0.0\";\n}\n\n// =============================================================================\n// MANAGED METADATA\n// =============================================================================\n\n/**\n * Generate managed metadata for MCP config entries\n *\n * §10.2: Creates the snapbackManaged object for config entries\n *\n * @param client - Target client\n * @param options - Additional options\n * @returns Managed metadata object\n */\nexport function createManagedMetadata(\n\tclient: AIClientFormat | \"other\",\n\toptions: {\n\t\tworkspaceId?: string;\n\t\ttransport: \"stdio\" | \"stdio-shim\" | \"http\";\n\t},\n): SnapbackManagedMetadata {\n\tconst identity = getOrCreateIdentity();\n\n\treturn {\n\t\tuserId: identity.userId,\n\t\tinstallId: identity.installId,\n\t\tclient,\n\t\tworkspaceId: options.workspaceId,\n\t\tcliVersion: getCLIVersion(),\n\t\tupdatedAt: new Date().toISOString(),\n\t\ttransport: options.transport,\n\t};\n}\n\n/**\n * Check if a managed metadata object belongs to this installation\n *\n * §10.3: Used to determine if we can auto-modify an entry\n *\n * @param metadata - Metadata from existing config entry\n * @returns True if this install owns the entry\n */\nexport function isOwnedByThisInstall(metadata: SnapbackManagedMetadata | undefined): boolean {\n\tif (!metadata?.installId) {\n\t\treturn false;\n\t}\n\n\tconst identity = getOrCreateIdentity();\n\treturn metadata.installId === identity.installId;\n}\n\n/**\n * Reset cached identity (for testing)\n */\nexport function resetIdentityCache(): void {\n\tcachedIdentity = null;\n}\n","/**\n * MCP Process Detection Module\n *\n * Detects running MCP stdio processes spawned by AI clients.\n * This helps verify that MCP configuration is not just present,\n * but actually functional with processes running.\n *\n * @packageDocumentation\n */\n\nimport { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\n/**\n * Running MCP process information\n */\nexport interface MCPProcess {\n\t/** Process ID */\n\tpid: number;\n\t/** Command being executed */\n\tcommand: string;\n\t/** MCP server name (e.g., \"snapback\", \"context7\") */\n\tserverName: string;\n\t/** Whether this is a SnapBack MCP process */\n\tisSnapback: boolean;\n}\n\n/**\n * MCP process health status\n */\nexport interface MCPProcessHealth {\n\t/** All detected MCP stdio processes */\n\tallProcesses: MCPProcess[];\n\t/** SnapBack-specific processes */\n\tsnapbackProcesses: MCPProcess[];\n\t/** Whether any SnapBack MCP process is running */\n\tsnapbackRunning: boolean;\n\t/** Total count of all MCP processes */\n\ttotalCount: number;\n\t/** Timestamp of check */\n\tcheckedAt: Date;\n}\n\n/**\n * Detect running MCP stdio processes\n *\n * Uses `ps` command to find processes matching MCP stdio patterns:\n * - node ... mcp --stdio\n * - snapback mcp --stdio\n * - uvx mcp-server-*\n * - npx ... mcp ...\n *\n * @returns Health status of MCP processes\n *\n * @example\n * ```ts\n * const health = await detectMCPProcesses();\n * if (health.snapbackRunning) {\n * console.log(`✓ SnapBack MCP running (${health.snapbackProcesses.length} processes)`);\n * } else {\n * console.log('⚠ SnapBack MCP not running');\n * }\n * ```\n */\nexport async function detectMCPProcesses(): Promise<MCPProcessHealth> {\n\ttry {\n\t\t// Use ps to find MCP-related processes\n\t\t// grep for common patterns: stdio, mcp, server names\n\t\tconst { stdout } = await execAsync(\n\t\t\t'ps aux | grep -E \"(mcp.*--stdio|--stdio.*mcp|uvx.*mcp-server|npx.*mcp|node.*mcp)\" | grep -v grep',\n\t\t\t{\n\t\t\t\ttimeout: 5000, // 5s timeout\n\t\t\t},\n\t\t);\n\n\t\tconst processes = parseProcessOutput(stdout);\n\t\tconst snapbackProcesses = processes.filter((p) => p.isSnapback);\n\n\t\treturn {\n\t\t\tallProcesses: processes,\n\t\t\tsnapbackProcesses,\n\t\t\tsnapbackRunning: snapbackProcesses.length > 0,\n\t\t\ttotalCount: processes.length,\n\t\t\tcheckedAt: new Date(),\n\t\t};\n\t} catch {\n\t\t// ps command failed or no processes found (grep returns exit code 1)\n\t\t// Return empty result rather than throwing\n\t\treturn {\n\t\t\tallProcesses: [],\n\t\t\tsnapbackProcesses: [],\n\t\t\tsnapbackRunning: false,\n\t\t\ttotalCount: 0,\n\t\t\tcheckedAt: new Date(),\n\t\t};\n\t}\n}\n\n/**\n * Parse ps output into MCPProcess objects\n */\nfunction parseProcessOutput(output: string): MCPProcess[] {\n\tconst lines = output\n\t\t.trim()\n\t\t.split(\"\\n\")\n\t\t.filter((line) => line.trim());\n\n\tconst processes: MCPProcess[] = [];\n\n\tfor (const line of lines) {\n\t\t// ps aux output format: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND\n\t\t// We need PID and COMMAND\n\t\tconst match = line.match(/^(\\S+)\\s+(\\d+)\\s+.*?\\s+(.+)$/);\n\t\tif (!match) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst [, , pidStr, command] = match;\n\t\tconst pid = Number.parseInt(pidStr, 10);\n\n\t\tif (Number.isNaN(pid)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Determine server name from command\n\t\tconst serverName = extractServerName(command);\n\t\tconst isSnapback = command.toLowerCase().includes(\"snapback\");\n\n\t\tprocesses.push({\n\t\t\tpid,\n\t\t\tcommand: command.trim(),\n\t\t\tserverName,\n\t\t\tisSnapback,\n\t\t});\n\t}\n\n\treturn processes;\n}\n\n/**\n * Extract MCP server name from command string\n */\nfunction extractServerName(command: string): string {\n\t// Try to extract server name from common patterns\n\tconst patterns = [\n\t\t// snapback mcp --stdio\n\t\t/snapback[/\\s]/i,\n\t\t// mcp-server-fetch\n\t\t/mcp-server-(\\w+)/,\n\t\t// @modelcontextprotocol/server-sequential-thinking\n\t\t/server-(\\w+)/,\n\t\t// context7-mcp\n\t\t/(\\w+)-mcp/,\n\t\t// fly mcp server\n\t\t/fly.*mcp/i,\n\t\t// supabase-mcp\n\t\t/supabase-mcp/i,\n\t];\n\n\tfor (const pattern of patterns) {\n\t\tconst match = command.match(pattern);\n\t\tif (match) {\n\t\t\t// Return first capture group or full match\n\t\t\treturn match[1] || match[0];\n\t\t}\n\t}\n\n\t// Fallback: just say \"mcp\"\n\treturn \"mcp\";\n}\n\n/**\n * Quick check if SnapBack MCP is running\n *\n * Lightweight version that just returns boolean.\n *\n * @returns true if SnapBack MCP process detected\n */\nexport async function isSnapbackMCPRunning(): Promise<boolean> {\n\tconst health = await detectMCPProcesses();\n\treturn health.snapbackRunning;\n}\n","/**\n * MCP Config Validation Module\n *\n * Validates MCP configurations and detects common issues.\n * Provides detailed diagnostics for troubleshooting.\n *\n * @packageDocumentation\n */\n\nimport { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport type { AIClientConfig, MCPServerConfig } from \"./types.js\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface ValidationIssue {\n\t/** Severity of the issue */\n\tseverity: \"error\" | \"warning\" | \"info\";\n\t/** Issue code for programmatic handling */\n\tcode: string;\n\t/** Human-readable message */\n\tmessage: string;\n\t/** Suggested fix */\n\tfix?: string;\n}\n\nexport interface ValidationResult {\n\t/** Whether the config is valid */\n\tvalid: boolean;\n\t/** List of issues found */\n\tissues: ValidationIssue[];\n\t/** The parsed snapback config (if found) */\n\tconfig?: MCPServerConfig;\n}\n\nexport interface WorkspaceValidation {\n\t/** Whether workspace path exists */\n\texists: boolean;\n\t/** Whether workspace has markers (.git, package.json, .snapback) */\n\thasMarkers: boolean;\n\t/** Workspace path being validated */\n\tpath?: string;\n}\n\n// =============================================================================\n// VALIDATION FUNCTIONS\n// =============================================================================\n\n/**\n * Validate an AI client's MCP configuration\n *\n * @param client - The client to validate\n * @returns Validation result with issues\n *\n * @example\n * ```ts\n * const client = getClient('qoder');\n * const result = validateClientConfig(client);\n *\n * if (!result.valid) {\n * for (const issue of result.issues) {\n * console.error(`${issue.severity}: ${issue.message}`);\n * if (issue.fix) console.log(`Fix: ${issue.fix}`);\n * }\n * }\n * ```\n */\nexport function validateClientConfig(client: AIClientConfig): ValidationResult {\n\tconst issues: ValidationIssue[] = [];\n\n\t// Check if config file exists\n\tif (!existsSync(client.configPath)) {\n\t\tissues.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: \"CONFIG_NOT_FOUND\",\n\t\t\tmessage: `Config file not found: ${client.configPath}`,\n\t\t\tfix: `Run: snap tools configure --${client.name}`,\n\t\t});\n\t\treturn { valid: false, issues };\n\t}\n\n\t// Try to read and parse config\n\tlet configContent: string;\n\tlet parsedConfig: unknown;\n\n\ttry {\n\t\tconfigContent = readFileSync(client.configPath, \"utf-8\");\n\t} catch (error) {\n\t\tissues.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: \"CONFIG_READ_ERROR\",\n\t\t\tmessage: `Cannot read config file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\tfix: \"Check file permissions\",\n\t\t});\n\t\treturn { valid: false, issues };\n\t}\n\n\ttry {\n\t\tparsedConfig = JSON.parse(configContent);\n\t} catch (error) {\n\t\tissues.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: \"CONFIG_PARSE_ERROR\",\n\t\t\tmessage: `Invalid JSON in config file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\tfix: `Edit ${client.configPath} to fix JSON syntax, or run: snap tools configure --${client.name} --force`,\n\t\t});\n\t\treturn { valid: false, issues };\n\t}\n\n\t// Check if SnapBack is configured\n\tif (!client.hasSnapback) {\n\t\tissues.push({\n\t\t\tseverity: \"warning\",\n\t\t\tcode: \"SNAPBACK_NOT_CONFIGURED\",\n\t\t\tmessage: \"SnapBack MCP server not found in config\",\n\t\t\tfix: `Run: snap tools configure --${client.name}`,\n\t\t});\n\t\treturn { valid: false, issues };\n\t}\n\n\t// Extract snapback config based on format\n\tconst snapbackConfig = extractSnapbackConfig(parsedConfig, client.format);\n\tif (!snapbackConfig) {\n\t\tissues.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: \"SNAPBACK_CONFIG_INVALID\",\n\t\t\tmessage: \"SnapBack config found but cannot be parsed\",\n\t\t});\n\t\treturn { valid: false, issues };\n\t}\n\n\t// Validate snapback config structure\n\tvalidateSnapbackConfig(snapbackConfig, issues);\n\n\t// Validate workspace path if present\n\tif (snapbackConfig.command && snapbackConfig.args) {\n\t\tconst workspaceIdx = snapbackConfig.args.indexOf(\"--workspace\");\n\t\tif (workspaceIdx !== -1 && workspaceIdx + 1 < snapbackConfig.args.length) {\n\t\t\tconst workspacePath = snapbackConfig.args[workspaceIdx + 1];\n\t\t\tconst wsValidation = validateWorkspacePath(workspacePath);\n\n\t\t\tif (!wsValidation.exists) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"WORKSPACE_NOT_FOUND\",\n\t\t\t\t\tmessage: `Workspace path does not exist: ${workspacePath}`,\n\t\t\t\t\tfix: \"Update workspace path or run: snap tools configure --force\",\n\t\t\t\t});\n\t\t\t} else if (!wsValidation.hasMarkers) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\tcode: \"WORKSPACE_NO_MARKERS\",\n\t\t\t\t\tmessage: `Workspace path has no markers (.git, package.json, .snapback): ${workspacePath}`,\n\t\t\t\t\tfix: \"Run: snap init\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: issues.filter((i) => i.severity === \"error\").length === 0,\n\t\tissues,\n\t\tconfig: snapbackConfig,\n\t};\n}\n\n/**\n * Validate workspace path\n */\nexport function validateWorkspacePath(workspacePath: string): WorkspaceValidation {\n\tconst absPath = resolve(workspacePath);\n\n\tif (!existsSync(absPath)) {\n\t\treturn { exists: false, hasMarkers: false, path: absPath };\n\t}\n\n\t// Check for workspace markers\n\tconst hasGit = existsSync(resolve(absPath, \".git\"));\n\tconst hasPackageJson = existsSync(resolve(absPath, \"package.json\"));\n\tconst hasSnapback = existsSync(resolve(absPath, \".snapback\"));\n\n\treturn {\n\t\texists: true,\n\t\thasMarkers: hasGit || hasPackageJson || hasSnapback,\n\t\tpath: absPath,\n\t};\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Extract SnapBack config from parsed config file\n */\nfunction extractSnapbackConfig(parsed: unknown, format: AIClientConfig[\"format\"]): MCPServerConfig | null {\n\tif (!parsed || typeof parsed !== \"object\") {\n\t\treturn null;\n\t}\n\n\tconst config = parsed as Record<string, unknown>;\n\n\tswitch (format) {\n\t\tcase \"claude\":\n\t\tcase \"cursor\":\n\t\tcase \"windsurf\":\n\t\tcase \"vscode\":\n\t\tcase \"cline\":\n\t\tcase \"roo-code\":\n\t\tcase \"qoder\":\n\t\tcase \"gemini\":\n\t\tcase \"zed\":\n\t\t\t// Standard mcpServers format\n\t\t\tif (\"mcpServers\" in config && typeof config.mcpServers === \"object\" && config.mcpServers !== null) {\n\t\t\t\tconst servers = config.mcpServers as Record<string, unknown>;\n\t\t\t\tif (\"snapback\" in servers) {\n\t\t\t\t\treturn servers.snapback as MCPServerConfig;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\n\t\tcase \"continue\":\n\t\t\t// Continue uses experimental.modelContextProtocolServers array\n\t\t\tif (\"experimental\" in config && typeof config.experimental === \"object\" && config.experimental !== null) {\n\t\t\t\tconst experimental = config.experimental as Record<string, unknown>;\n\t\t\t\tif (\n\t\t\t\t\t\"modelContextProtocolServers\" in experimental &&\n\t\t\t\t\tArray.isArray(experimental.modelContextProtocolServers)\n\t\t\t\t) {\n\t\t\t\t\tconst server = experimental.modelContextProtocolServers.find(\n\t\t\t\t\t\t(s: unknown) =>\n\t\t\t\t\t\t\ttypeof s === \"object\" && s !== null && (s as Record<string, unknown>).name === \"snapback\",\n\t\t\t\t\t);\n\t\t\t\t\treturn server ? (server as MCPServerConfig) : null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Validate SnapBack config structure\n */\nfunction validateSnapbackConfig(config: MCPServerConfig, issues: ValidationIssue[]): void {\n\t// Must have either command or url\n\tif (!config.command && !config.url) {\n\t\tissues.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: \"MISSING_COMMAND_OR_URL\",\n\t\t\tmessage: \"Config must have either 'command' (stdio) or 'url' (HTTP)\",\n\t\t\tfix: \"Run: snap tools configure --force\",\n\t\t});\n\t\treturn;\n\t}\n\n\t// If using stdio transport (command), validate structure\n\tif (config.command) {\n\t\t// CRITICAL: Validate that command is executable\n\t\tif (!isCommandExecutable(config.command)) {\n\t\t\tissues.push({\n\t\t\t\tseverity: \"error\",\n\t\t\t\tcode: \"COMMAND_NOT_EXECUTABLE\",\n\t\t\t\tmessage: `Command not found or not executable: ${config.command}`,\n\t\t\t\tfix: \"Run: snap tools repair (will auto-fix node path)\",\n\t\t\t});\n\t\t}\n\n\t\tif (!config.args || !Array.isArray(config.args)) {\n\t\t\tissues.push({\n\t\t\t\tseverity: \"error\",\n\t\t\t\tcode: \"MISSING_ARGS\",\n\t\t\t\tmessage: \"Command-based config must have 'args' array\",\n\t\t\t\tfix: \"Run: snap tools configure --force\",\n\t\t\t});\n\t\t} else {\n\t\t\t// Check for required args\n\t\t\tif (!config.args.includes(\"mcp\")) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"MISSING_MCP_ARG\",\n\t\t\t\t\tmessage: \"Args must include 'mcp' command\",\n\t\t\t\t\tfix: \"Run: snap tools configure --force\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!config.args.includes(\"--stdio\")) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"MISSING_STDIO_ARG\",\n\t\t\t\t\tmessage: \"Args must include '--stdio' flag\",\n\t\t\t\t\tfix: \"Run: snap mcp repair --client <name>\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Check for deprecated 'shim' command (removed in favor of --stdio)\n\t\t\tif (config.args.includes(\"shim\")) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"DEPRECATED_SHIM_COMMAND\",\n\t\t\t\t\tmessage: \"Args contain deprecated 'shim' command - use '--stdio' instead\",\n\t\t\t\t\tfix: \"Run: snap mcp repair --client <name>\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Warn if missing workspace\n\t\t\tif (!config.args.includes(\"--workspace\")) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\tcode: \"MISSING_WORKSPACE_ARG\",\n\t\t\t\t\tmessage: \"Args should include '--workspace' path for reliability\",\n\t\t\t\t\tfix: \"Run: snap tools configure --force\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Validate CLI path exists (first arg after command)\n\t\t\tif (config.args.length > 0) {\n\t\t\t\tconst cliPath = config.args[0];\n\t\t\t\tif (cliPath?.endsWith(\".js\") && !existsSync(cliPath)) {\n\t\t\t\t\tissues.push({\n\t\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\t\tcode: \"CLI_PATH_NOT_FOUND\",\n\t\t\t\t\t\tmessage: `CLI script not found: ${cliPath}`,\n\t\t\t\t\t\tfix: \"Rebuild CLI: pnpm --filter @snapback/cli build\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If using HTTP transport (url), validate\n\tif (config.url) {\n\t\ttry {\n\t\t\tnew URL(config.url);\n\t\t} catch {\n\t\t\tissues.push({\n\t\t\t\tseverity: \"error\",\n\t\t\t\tcode: \"INVALID_URL\",\n\t\t\t\tmessage: `Invalid server URL: ${config.url}`,\n\t\t\t\tfix: \"Run: snap tools configure --force\",\n\t\t\t});\n\t\t}\n\t}\n\n\t// Check for API key or workspace ID in env\n\tif (config.env) {\n\t\tif (!config.env.SNAPBACK_API_KEY && !config.env.SNAPBACK_WORKSPACE_ID) {\n\t\t\tissues.push({\n\t\t\t\tseverity: \"info\",\n\t\t\t\tcode: \"NO_AUTH\",\n\t\t\t\tmessage: \"No API key or workspace ID found (free tier will be used)\",\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Check if a command is executable (exists in PATH or is absolute path)\n *\n * @param command - Command to check\n * @returns True if command is likely executable\n */\nfunction isCommandExecutable(command: string): boolean {\n\t// If it's an absolute path, check if file exists\n\tif (command.startsWith(\"/\") || command.match(/^[A-Z]:\\\\/i)) {\n\t\treturn existsSync(command);\n\t}\n\n\t// For relative commands, try to find them\n\ttry {\n\t\tconst isWindows = process.platform === \"win32\";\n\t\tconst cmd = isWindows ? `where ${command}` : `which ${command}`;\n\t\texecSync(cmd, { encoding: \"utf-8\", timeout: 5000 });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","/**\n * MCP Config Writer Module\n *\n * Writes SnapBack MCP configuration to AI client config files.\n * Handles backup creation, merging with existing config, and various formats.\n *\n * @packageDocumentation\n */\n\nimport { execSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport type {\n\tAIClientConfig,\n\tAIClientFormat,\n\tMCPConfig,\n\tMCPServerConfig,\n\tRemoveResult,\n\tSnapbackConfigOptions,\n\tWriteResult,\n} from \"./types.js\";\n\n// =============================================================================\n// PATH RESOLUTION UTILITIES\n// =============================================================================\n\n/** Cached node path to avoid repeated lookups */\nlet cachedNodePath: string | null = null;\n\n/**\n * Resolve the absolute path to the Node.js executable\n *\n * This is critical for MCP reliability - using just \"node\" depends on PATH\n * which varies between environments (terminal vs IDE vs system service).\n *\n * @returns Absolute path to node, or \"node\" as fallback\n */\nexport function resolveNodePath(): string {\n\tif (cachedNodePath) {\n\t\treturn cachedNodePath;\n\t}\n\n\ttry {\n\t\t// Try `which node` (Unix) or `where node` (Windows)\n\t\tconst isWindows = process.platform === \"win32\";\n\t\tconst command = isWindows ? \"where node\" : \"which node\";\n\t\tconst result = execSync(command, { encoding: \"utf-8\", timeout: 5000 }).trim();\n\n\t\t// On Windows, `where` may return multiple paths - take the first\n\t\tconst nodePath = result.split(/\\r?\\n/)[0].trim();\n\n\t\tif (nodePath && existsSync(nodePath)) {\n\t\t\tcachedNodePath = nodePath;\n\t\t\treturn nodePath;\n\t\t}\n\t} catch {\n\t\t// Fallback: try common paths\n\t\tconst commonPaths = [\n\t\t\t\"/opt/homebrew/bin/node\", // macOS ARM (Homebrew)\n\t\t\t\"/usr/local/bin/node\", // macOS Intel (Homebrew)\n\t\t\t\"/usr/bin/node\", // Linux\n\t\t\t\"C:\\\\Program Files\\\\nodejs\\\\node.exe\", // Windows\n\t\t];\n\n\t\tfor (const path of commonPaths) {\n\t\t\tif (existsSync(path)) {\n\t\t\t\tcachedNodePath = path;\n\t\t\t\treturn path;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Final fallback - use \"node\" and hope PATH is set\n\treturn \"node\";\n}\n\n/**\n * Check if a command is executable (exists in PATH or is absolute path)\n *\n * @param command - Command to check\n * @returns True if command is likely executable\n */\nexport function isCommandExecutable(command: string): boolean {\n\t// If it's an absolute path, check if file exists\n\tif (command.startsWith(\"/\") || command.match(/^[A-Z]:\\\\/i)) {\n\t\treturn existsSync(command);\n\t}\n\n\t// For relative commands, try to find them\n\ttry {\n\t\tconst isWindows = process.platform === \"win32\";\n\t\tconst cmd = isWindows ? `where ${command}` : `which ${command}`;\n\t\texecSync(cmd, { encoding: \"utf-8\", timeout: 5000 });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// =============================================================================\n// CONFIG GENERATION\n// =============================================================================\n\n/**\n * Clients that ONLY support stdio transport (no HTTP/SSE)\n * These clients require command + args, not url\n *\n * @see https://modelcontextprotocol.io/docs/develop/connect-local-servers\n */\nconst STDIO_ONLY_CLIENTS: Set<string> = new Set([\n\t\"claude\", // Claude Desktop only supports stdio transport\n]);\n\n/**\n * Generate SnapBack MCP server configuration\n *\n * @param options - Configuration options\n * @returns MCP server config for SnapBack\n *\n * @example\n * ```ts\n * // RECOMMENDED: NPX mode for npm-installed CLI\n * // Best for users who installed via: npm install -g @snapback/cli\n * const npxConfig = getSnapbackMCPConfig({\n * useNpx: true,\n * workspaceRoot: '/path/to/project'\n * });\n * // Generates: npx @snapback/cli mcp --stdio --workspace /path/to/project\n *\n * // Workspace ID auth (no API key in config)\n * const config = getSnapbackMCPConfig({\n * workspaceId: 'ws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6'\n * });\n *\n * // Legacy: API key auth (still supported)\n * const legacyConfig = getSnapbackMCPConfig({ apiKey: 'sb_live_xxx' });\n *\n * // Local development mode\n * const devConfig = getSnapbackMCPConfig({\n * useLocalDev: true,\n * localCliPath: '/path/to/apps/cli/dist/index.js',\n * workspaceRoot: '/path/to/project'\n * });\n *\n * // Custom remote server\n * const customConfig = getSnapbackMCPConfig({\n * serverUrl: 'https://custom-mcp.example.com',\n * workspaceId: 'ws_xxx'\n * });\n *\n * // Legacy stdio mode (using binary)\n * const stdioConfig = getSnapbackMCPConfig({\n * useBinary: true,\n * apiKey: 'sb_live_xxx'\n * });\n *\n * // Claude Desktop (auto-uses npx since Claude Desktop requires stdio)\n * const claudeConfig = getSnapbackMCPConfig({\n * client: 'claude',\n * workspaceRoot: '/path/to/project'\n * });\n * ```\n */\nexport function getSnapbackMCPConfig(options: SnapbackConfigOptions = {}): MCPServerConfig {\n\tconst {\n\t\tapiKey,\n\t\tworkspaceId,\n\t\tserverUrl,\n\t\tuseBinary = false,\n\t\tcustomCommand,\n\t\tadditionalEnv,\n\t\tworkspaceRoot,\n\t\tuseLocalDev = false,\n\t\tlocalCliPath,\n\t\tclient,\n\t} = options;\n\n\t// Auto-enable npx mode for stdio-only clients (like Claude Desktop)\n\t// These clients don't support HTTP transport, so we MUST use stdio\n\tconst useNpx = options.useNpx ?? (client ? STDIO_ONLY_CLIENTS.has(client) : false);\n\n\t// Build environment variables\n\tconst env: Record<string, string> = { ...additionalEnv };\n\n\t// Workspace ID is preferred over API key for MCP authentication\n\t// When workspaceId is set, tier is resolved server-side via workspace_links table\n\tif (workspaceId) {\n\t\tenv.SNAPBACK_WORKSPACE_ID = workspaceId;\n\t}\n\n\t// API key can still be provided for backwards compatibility or direct auth\n\tif (apiKey) {\n\t\tenv.SNAPBACK_API_KEY = apiKey;\n\t}\n\n\t// Determine command\n\tif (customCommand) {\n\t\treturn {\n\t\t\tcommand: customCommand,\n\t\t\targs: [],\n\t\t\t...(Object.keys(env).length > 0 && { env }),\n\t\t};\n\t}\n\n\t// Priority 1: NPX mode - for npm-installed CLI (recommended for npm users)\n\t// Command: npx @snapback/cli mcp --stdio --workspace <path>\n\tif (useNpx) {\n\t\tconst tier = apiKey ? \"pro\" : \"free\";\n\t\tconst args = [\"@snapback/cli\", \"mcp\", \"--stdio\", \"--tier\", tier];\n\t\tif (workspaceRoot) {\n\t\t\targs.push(\"--workspace\", workspaceRoot);\n\t\t}\n\t\treturn {\n\t\t\tcommand: \"npx\",\n\t\t\targs,\n\t\t\t...(Object.keys(env).length > 0 && { env }),\n\t\t};\n\t}\n\n\t// Priority 2: Remote HTTP server (Fly.io) - DEFAULT for non-explicit modes\n\tif (serverUrl || (!useLocalDev && !useBinary)) {\n\t\tconst url = serverUrl || \"https://snapback-mcp.fly.dev\";\n\t\treturn {\n\t\t\turl,\n\t\t\t...(Object.keys(env).length > 0 && { env }),\n\t\t};\n\t}\n\n\t// Priority 2: Local development mode - direct node execution with workspace\n\tif (useLocalDev && localCliPath) {\n\t\tconst tier = apiKey ? \"pro\" : \"free\";\n\t\tconst args = [localCliPath, \"mcp\", \"--stdio\", \"--tier\", tier];\n\t\tif (workspaceRoot) {\n\t\t\targs.push(\"--workspace\", workspaceRoot);\n\t\t}\n\t\t// CRITICAL: Use absolute path to node to avoid PATH resolution issues\n\t\t// IDE environments often have different PATH than terminal\n\t\tconst nodePath = resolveNodePath();\n\t\treturn {\n\t\t\tcommand: nodePath,\n\t\t\targs,\n\t\t\t...(Object.keys(env).length > 0 && { env }),\n\t\t};\n\t}\n\n\t// Priority 3: Binary mode (legacy stdio transport)\n\tif (useBinary) {\n\t\tconst tier = apiKey ? \"pro\" : \"free\";\n\t\tconst args = [\"mcp\", \"--stdio\", \"--tier\", tier];\n\t\tif (workspaceRoot) {\n\t\t\targs.push(\"--workspace\", workspaceRoot);\n\t\t}\n\t\treturn {\n\t\t\tcommand: \"snapback\",\n\t\t\targs,\n\t\t\t...(Object.keys(env).length > 0 && { env }),\n\t\t};\n\t}\n\n\t// Fallback: Should not reach here due to Priority 1, but kept for safety\n\treturn {\n\t\turl: \"https://snapback-mcp.fly.dev\",\n\t\t...(Object.keys(env).length > 0 && { env }),\n\t};\n}\n\n// =============================================================================\n// CONFIG WRITING\n// =============================================================================\n\n/**\n * Write SnapBack MCP config to an AI client's config file\n *\n * @param client - The AI client to configure\n * @param mcpConfig - The MCP server configuration\n * @returns Result of the write operation\n *\n * @example\n * ```ts\n * const client = getClient('cursor');\n * const mcpConfig = getSnapbackMCPConfig({ apiKey: 'sk_...' });\n *\n * const result = writeClientConfig(client, mcpConfig);\n * if (result.success) {\n * console.log('Configured! Backup at:', result.backup);\n * } else {\n * console.error('Failed:', result.error);\n * }\n * ```\n */\nexport function writeClientConfig(client: AIClientConfig, mcpConfig: MCPServerConfig): WriteResult {\n\ttry {\n\t\t// Ensure directory exists\n\t\tconst configDir = dirname(client.configPath);\n\t\tmkdirSync(configDir, { recursive: true });\n\n\t\t// Read existing config or start fresh\n\t\tlet existingConfig: MCPConfig = { mcpServers: {} };\n\t\tlet hasExistingConfig = false;\n\n\t\tif (existsSync(client.configPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(client.configPath, \"utf-8\");\n\t\t\t\texistingConfig = JSON.parse(content) as MCPConfig;\n\t\t\t\thasExistingConfig = Object.keys(existingConfig).length > 0;\n\t\t\t} catch {\n\t\t\t\t// Invalid JSON, will overwrite\n\t\t\t}\n\t\t}\n\n\t\t// Create backup if there's existing content\n\t\tlet backup: string | undefined;\n\t\tif (hasExistingConfig) {\n\t\t\tbackup = `${client.configPath}.backup.${Date.now()}`;\n\t\t\twriteFileSync(backup, JSON.stringify(existingConfig, null, 2));\n\t\t}\n\n\t\t// Merge configs based on format\n\t\tconst newConfig = mergeConfig(existingConfig, mcpConfig, client.format);\n\n\t\t// Write updated config\n\t\twriteFileSync(client.configPath, JSON.stringify(newConfig, null, 2));\n\n\t\treturn { success: true, backup };\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t};\n\t}\n}\n\n/**\n * Remove SnapBack configuration from an AI client\n * §10.1: Removes namespaced entries (snapback-<client>)\n *\n * @param client - The AI client to remove config from\n * @returns Result of the removal operation\n */\nexport function removeSnapbackConfig(client: AIClientConfig): RemoveResult {\n\ttry {\n\t\tif (!existsSync(client.configPath)) {\n\t\t\treturn { success: true }; // Nothing to remove\n\t\t}\n\n\t\tconst content = readFileSync(client.configPath, \"utf-8\");\n\t\tconst config = JSON.parse(content) as MCPConfig;\n\t\tconst serverKey = getServerKey(client.format);\n\n\t\t// Remove based on format\n\t\tswitch (client.format) {\n\t\t\tcase \"claude\":\n\t\t\tcase \"cursor\":\n\t\t\tcase \"windsurf\":\n\t\t\tcase \"cline\":\n\t\t\tcase \"roo-code\":\n\t\t\tcase \"gemini\":\n\t\t\tcase \"qoder\":\n\t\t\t\t// Remove namespaced key\n\t\t\t\tif (config.mcpServers?.[serverKey]) {\n\t\t\t\t\tdelete config.mcpServers[serverKey];\n\t\t\t\t}\n\t\t\t\t// Also remove legacy \"snapback\" key if present\n\t\t\t\tif (config.mcpServers?.snapback) {\n\t\t\t\t\tdelete config.mcpServers.snapback;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"vscode\": {\n\t\t\t\t// VS Code uses \"servers\" not \"mcpServers\"\n\t\t\t\tconst vscodeConfig = config as unknown as Record<string, unknown>;\n\t\t\t\tconst servers = vscodeConfig.servers as Record<string, unknown> | undefined;\n\t\t\t\tif (servers?.[serverKey]) {\n\t\t\t\t\tdelete servers[serverKey];\n\t\t\t\t}\n\t\t\t\tif (servers?.snapback) {\n\t\t\t\t\tdelete servers.snapback;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"zed\": {\n\t\t\t\t// Zed uses \"context_servers\" not \"mcpServers\"\n\t\t\t\tconst zedConfig = config as unknown as Record<string, unknown>;\n\t\t\t\tconst contextServers = zedConfig.context_servers as Record<string, unknown> | undefined;\n\t\t\t\tif (contextServers?.[serverKey]) {\n\t\t\t\t\tdelete contextServers[serverKey];\n\t\t\t\t}\n\t\t\t\tif (contextServers?.snapback) {\n\t\t\t\t\tdelete contextServers.snapback;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"continue\": {\n\t\t\t\t// Continue uses different structure\n\t\t\t\tconst experimental = (config as unknown as Record<string, unknown>).experimental as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined;\n\t\t\t\tif (experimental?.modelContextProtocolServers) {\n\t\t\t\t\tconst servers = experimental.modelContextProtocolServers as Array<{ name: string }>;\n\t\t\t\t\t// Remove all snapback entries (namespaced and legacy)\n\t\t\t\t\texperimental.modelContextProtocolServers = servers.filter((s) => !s.name.startsWith(\"snapback\"));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\twriteFileSync(client.configPath, JSON.stringify(config, null, 2));\n\n\t\treturn { success: true };\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t};\n\t}\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * §10.1: Generate namespaced server key for client\n * SnapBack SHALL NEVER use just \"snapback\" - always \"snapback-<client>\"\n *\n * @param client - Client format (e.g., \"claude\", \"cursor\")\n * @returns Namespaced server key (e.g., \"snapback-claude\")\n */\nexport function getServerKey(client: AIClientFormat | undefined): string {\n\tif (!client) {\n\t\treturn \"snapback\"; // Legacy fallback - should be avoided\n\t}\n\treturn `snapback-${client}`;\n}\n\n/**\n * Merge SnapBack config into existing config based on format\n * §10.1: Uses namespaced server keys (snapback-<client>)\n */\nfunction mergeConfig(\n\texisting: MCPConfig,\n\tsnapbackConfig: MCPServerConfig,\n\tformat: AIClientConfig[\"format\"],\n): MCPConfig | Record<string, unknown> {\n\t// §10.1: Use namespaced server key\n\tconst serverKey = getServerKey(format);\n\n\tswitch (format) {\n\t\tcase \"claude\":\n\t\tcase \"cursor\":\n\t\tcase \"cline\":\n\t\tcase \"roo-code\":\n\t\tcase \"gemini\":\n\t\t\t// Standard mcpServers format with namespaced key\n\t\t\treturn {\n\t\t\t\t...existing,\n\t\t\t\tmcpServers: {\n\t\t\t\t\t...(existing.mcpServers || {}),\n\t\t\t\t\t[serverKey]: snapbackConfig,\n\t\t\t\t},\n\t\t\t};\n\n\t\tcase \"windsurf\":\n\t\t\t// Windsurf uses standard format but supports disabled and alwaysAllow fields for UX\n\t\t\treturn {\n\t\t\t\t...existing,\n\t\t\t\tmcpServers: {\n\t\t\t\t\t...(existing.mcpServers || {}),\n\t\t\t\t\t[serverKey]: {\n\t\t\t\t\t\t...snapbackConfig,\n\t\t\t\t\t\tdisabled: false, // Explicitly enable\n\t\t\t\t\t\talwaysAllow: [], // Empty by default, user can configure\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\tcase \"qoder\":\n\t\t\t// Qoder requires explicit type field for transport\n\t\t\treturn {\n\t\t\t\t...existing,\n\t\t\t\tmcpServers: {\n\t\t\t\t\t...(existing.mcpServers || {}),\n\t\t\t\t\t[serverKey]: {\n\t\t\t\t\t\ttype: \"stdio\", // Required by Qoder\n\t\t\t\t\t\t...snapbackConfig,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\tcase \"vscode\": {\n\t\t\t// VS Code uses \"servers\" not \"mcpServers\" and requires explicit type\n\t\t\tconst vscodeConfig = existing as unknown as Record<string, unknown>;\n\t\t\tconst servers = (vscodeConfig.servers || {}) as Record<string, unknown>;\n\t\t\t// Remove mcpServers if it exists (shouldn't be there for VS Code)\n\t\t\tconst { mcpServers: _, ...rest } = vscodeConfig;\n\t\t\treturn {\n\t\t\t\t...rest,\n\t\t\t\tservers: {\n\t\t\t\t\t...servers,\n\t\t\t\t\t[serverKey]: {\n\t\t\t\t\t\ttype: \"stdio\", // Required by VS Code\n\t\t\t\t\t\t...snapbackConfig,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tcase \"zed\": {\n\t\t\t// Zed uses \"context_servers\" not \"mcpServers\"\n\t\t\tconst zedConfig = existing as unknown as Record<string, unknown>;\n\t\t\tconst contextServers = (zedConfig.context_servers || {}) as Record<string, unknown>;\n\t\t\t// Remove mcpServers if it exists (shouldn't be there for Zed)\n\t\t\tconst { mcpServers: _, ...rest } = zedConfig;\n\t\t\treturn {\n\t\t\t\t...rest,\n\t\t\t\tcontext_servers: {\n\t\t\t\t\t...contextServers,\n\t\t\t\t\t[serverKey]: snapbackConfig,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tcase \"continue\": {\n\t\t\t// Continue uses experimental.modelContextProtocolServers array\n\t\t\tconst continueConfig = existing as unknown as Record<string, unknown>;\n\t\t\tconst experimental = (continueConfig.experimental || {}) as Record<string, unknown>;\n\t\t\tconst servers = (experimental.modelContextProtocolServers || []) as Array<Record<string, unknown>>;\n\n\t\t\t// Remove existing snapback entries if present\n\t\t\tconst filteredServers = servers.filter((s) => {\n\t\t\t\tconst name = s.name as string;\n\t\t\t\treturn !name?.startsWith(\"snapback\");\n\t\t\t});\n\n\t\t\t// Add new snapback config with namespaced name\n\t\t\tfilteredServers.push({\n\t\t\t\tname: serverKey,\n\t\t\t\t...snapbackConfig,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\t...continueConfig,\n\t\t\t\texperimental: {\n\t\t\t\t\t...experimental,\n\t\t\t\t\tmodelContextProtocolServers: filteredServers,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tcase \"aider\":\n\t\t\t// Aider uses YAML - handled separately (this shouldn't be called)\n\t\t\t// For now, return existing config unchanged\n\t\t\treturn existing;\n\n\t\tdefault:\n\t\t\t// Fallback to standard format with namespaced key\n\t\t\treturn {\n\t\t\t\t...existing,\n\t\t\t\tmcpServers: {\n\t\t\t\t\t...(existing.mcpServers || {}),\n\t\t\t\t\t[serverKey]: snapbackConfig,\n\t\t\t\t},\n\t\t\t};\n\t}\n}\n\n/**\n * Validate that a config was written correctly\n * §10.1: Checks for namespaced server keys (snapback-<client>)\n *\n * @param client - Client to validate\n * @returns True if SnapBack is properly configured\n */\nexport function validateConfig(client: AIClientConfig): boolean {\n\ttry {\n\t\tconst content = readFileSync(client.configPath, \"utf-8\");\n\t\tconst config = JSON.parse(content) as MCPConfig;\n\t\tconst serverKey = getServerKey(client.format);\n\n\t\tswitch (client.format) {\n\t\t\tcase \"claude\":\n\t\t\tcase \"cursor\":\n\t\t\tcase \"windsurf\":\n\t\t\tcase \"cline\":\n\t\t\tcase \"roo-code\":\n\t\t\tcase \"gemini\":\n\t\t\tcase \"qoder\": {\n\t\t\t\t// Check namespaced key first, fall back to legacy \"snapback\" for backwards compat\n\t\t\t\tconst serverConfig = config.mcpServers?.[serverKey] || config.mcpServers?.snapback;\n\t\t\t\treturn Boolean(serverConfig?.command || serverConfig?.url);\n\t\t\t}\n\n\t\t\tcase \"vscode\": {\n\t\t\t\t// VS Code uses \"servers\" not \"mcpServers\"\n\t\t\t\tconst vscodeConfig = config as unknown as Record<string, unknown>;\n\t\t\t\tconst servers = vscodeConfig.servers as Record<string, unknown> | undefined;\n\t\t\t\tconst serverConfig = servers?.[serverKey] || servers?.snapback;\n\t\t\t\tif (typeof serverConfig === \"object\" && serverConfig !== null) {\n\t\t\t\t\tconst cfg = serverConfig as { command?: string; url?: string };\n\t\t\t\t\treturn Boolean(cfg.command || cfg.url);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcase \"zed\": {\n\t\t\t\t// Zed uses \"context_servers\" not \"mcpServers\"\n\t\t\t\tconst zedConfig = config as unknown as Record<string, unknown>;\n\t\t\t\tconst contextServers = zedConfig.context_servers as Record<string, unknown> | undefined;\n\t\t\t\tconst serverConfig = contextServers?.[serverKey] || contextServers?.snapback;\n\t\t\t\tif (typeof serverConfig === \"object\" && serverConfig !== null) {\n\t\t\t\t\tconst cfg = serverConfig as { command?: string; url?: string };\n\t\t\t\t\treturn Boolean(cfg.command || cfg.url);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcase \"continue\": {\n\t\t\t\tconst expCfg = (config as unknown as Record<string, unknown>).experimental as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined;\n\t\t\t\tconst srvs = expCfg?.modelContextProtocolServers as\n\t\t\t\t\t| Array<{ name: string; command?: string; url?: string }>\n\t\t\t\t\t| undefined;\n\t\t\t\t// Check for any snapback entry (namespaced or legacy)\n\t\t\t\treturn Boolean(srvs?.some((s) => s.name.startsWith(\"snapback\") && (s.command || s.url)));\n\t\t\t}\n\n\t\t\tcase \"aider\":\n\t\t\t\t// YAML validation would need a YAML parser\n\t\t\t\treturn false;\n\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n}\n","/**\n * MCP Config Repair Module\n *\n * Automatically repairs broken or incomplete MCP configurations.\n * Provides autonomous recovery for common failure scenarios.\n *\n * @packageDocumentation\n */\n\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport type { AIClientConfig } from \"./types.js\";\nimport { type ValidationResult, validateClientConfig } from \"./validate.js\";\nimport { getSnapbackMCPConfig, resolveNodePath, writeClientConfig } from \"./write.js\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface RepairResult {\n\t/** Whether repair was successful */\n\tsuccess: boolean;\n\t/** Issues that were fixed */\n\tfixed: string[];\n\t/** Issues that remain unfixed */\n\tremaining: string[];\n\t/** Error message if repair failed */\n\terror?: string;\n}\n\nexport interface RepairOptions {\n\t/** API key for Pro features */\n\tapiKey?: string;\n\t/** Workspace ID for tier resolution */\n\tworkspaceId?: string;\n\t/** Workspace root path (auto-detected if not provided) */\n\tworkspaceRoot?: string;\n\t/** Whether to force complete reconfiguration */\n\tforce?: boolean;\n}\n\n// =============================================================================\n// REPAIR FUNCTIONS\n// =============================================================================\n\n/**\n * Automatically repair a client's MCP configuration\n *\n * @param client - The client to repair\n * @param options - Repair options\n * @returns Repair result with fixes applied\n *\n * @example\n * ```ts\n * const client = getClient('qoder');\n * const result = await repairClientConfig(client, {\n * workspaceRoot: process.cwd()\n * });\n *\n * if (result.success) {\n * console.log('Fixed:', result.fixed);\n * } else {\n * console.error('Remaining issues:', result.remaining);\n * }\n * ```\n */\nexport function repairClientConfig(client: AIClientConfig, options: RepairOptions = {}): RepairResult {\n\tconst fixed: string[] = [];\n\tconst remaining: string[] = [];\n\n\t// Validate current config\n\tconst validation = validateClientConfig(client);\n\n\t// If force, just reconfigure completely\n\tif (options.force) {\n\t\treturn performFullReconfiguration(client, options);\n\t}\n\n\t// If no issues, no repair needed\n\tif (validation.valid && validation.issues.length === 0) {\n\t\treturn { success: true, fixed: [], remaining: [] };\n\t}\n\n\t// Try to fix each issue\n\tfor (const issue of validation.issues) {\n\t\tconst fixResult = attemptFix(client, issue, validation, options);\n\t\tif (fixResult.success) {\n\t\t\tfixed.push(issue.message);\n\t\t} else {\n\t\t\tremaining.push(issue.message);\n\t\t}\n\t}\n\n\t// If critical issues remain, do full reconfiguration\n\tconst hasCriticalErrors = remaining.some((msg) =>\n\t\tvalidation.issues.find((i) => i.message === msg && i.severity === \"error\"),\n\t);\n\n\tif (hasCriticalErrors) {\n\t\treturn performFullReconfiguration(client, options);\n\t}\n\n\treturn {\n\t\tsuccess: remaining.length === 0,\n\t\tfixed,\n\t\tremaining,\n\t};\n}\n\n/**\n * Auto-inject workspace path into MCP config\n *\n * This is the most common repair needed - automatically detecting\n * and injecting the correct workspace path when missing.\n *\n * @param client - The client to update\n * @param workspaceRoot - Workspace path (auto-detected if not provided)\n * @returns Result of the injection\n */\nexport function injectWorkspacePath(client: AIClientConfig, workspaceRoot?: string): RepairResult {\n\tconst fixed: string[] = [];\n\tconst remaining: string[] = [];\n\n\t// Detect workspace if not provided\n\tconst detectedWorkspace = workspaceRoot || detectWorkspaceRoot(process.cwd());\n\n\tif (!detectedWorkspace) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tfixed,\n\t\t\tremaining: [\"Could not auto-detect workspace root\"],\n\t\t\terror: \"No workspace markers found (.git, package.json, .snapback)\",\n\t\t};\n\t}\n\n\t// Validate detected workspace\n\tif (!existsSync(detectedWorkspace)) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tfixed,\n\t\t\tremaining: [`Workspace path does not exist: ${detectedWorkspace}`],\n\t\t\terror: \"Invalid workspace path\",\n\t\t};\n\t}\n\n\t// Get current config\n\tconst validation = validateClientConfig(client);\n\tif (!validation.config) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tfixed,\n\t\t\tremaining: [\"No existing SnapBack config found\"],\n\t\t\terror: \"Must run initial configuration first\",\n\t\t};\n\t}\n\n\t// Check if using stdio transport\n\tif (!validation.config.command) {\n\t\t// Using HTTP transport, no workspace injection needed\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tfixed: [\"Config uses HTTP transport - no workspace path needed\"],\n\t\t\tremaining: [],\n\t\t};\n\t}\n\n\t// Check if workspace already set\n\tconst hasWorkspace = validation.config.args?.includes(\"--workspace\");\n\tif (hasWorkspace) {\n\t\tfixed.push(\"Workspace path already configured\");\n\t\treturn { success: true, fixed, remaining };\n\t}\n\n\t// Inject workspace by full reconfiguration\n\tconst result = performFullReconfiguration(client, {\n\t\tworkspaceRoot: detectedWorkspace,\n\t});\n\n\tif (result.success) {\n\t\tfixed.push(`Injected workspace path: ${detectedWorkspace}`);\n\t}\n\n\treturn { success: result.success, fixed, remaining };\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Attempt to fix a specific issue\n */\nfunction attemptFix(\n\tclient: AIClientConfig,\n\tissue: ValidationResult[\"issues\"][0],\n\t_validation: ValidationResult,\n\toptions: RepairOptions,\n): { success: boolean } {\n\tswitch (issue.code) {\n\t\tcase \"CONFIG_NOT_FOUND\":\n\t\tcase \"CONFIG_PARSE_ERROR\":\n\t\tcase \"SNAPBACK_NOT_CONFIGURED\":\n\t\tcase \"MISSING_COMMAND_OR_URL\":\n\t\tcase \"MISSING_ARGS\":\n\t\tcase \"MISSING_MCP_ARG\":\n\t\tcase \"MISSING_STDIO_ARG\":\n\t\tcase \"DEPRECATED_SHIM_COMMAND\":\n\t\tcase \"INVALID_URL\":\n\t\t\t// These require full reconfiguration\n\t\t\treturn performFullReconfiguration(client, options);\n\n\t\tcase \"COMMAND_NOT_EXECUTABLE\": {\n\t\t\t// Auto-fix by resolving correct node path\n\t\t\t// This is the most common issue in IDE environments\n\t\t\treturn performFullReconfiguration(client, options);\n\t\t}\n\n\t\tcase \"CLI_PATH_NOT_FOUND\": {\n\t\t\t// Try to find CLI path automatically\n\t\t\tconst cliPath = findCliPath();\n\t\t\tif (cliPath) {\n\t\t\t\treturn performFullReconfiguration(client, options);\n\t\t\t}\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tcase \"MISSING_WORKSPACE_ARG\": {\n\t\t\t// Try to inject workspace\n\t\t\tconst workspace = options.workspaceRoot || detectWorkspaceRoot(process.cwd());\n\t\t\tif (workspace) {\n\t\t\t\treturn performFullReconfiguration(client, { ...options, workspaceRoot: workspace });\n\t\t\t}\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tcase \"WORKSPACE_NOT_FOUND\": {\n\t\t\t// Try to detect correct workspace\n\t\t\tconst detected = detectWorkspaceRoot(process.cwd());\n\t\t\tif (detected) {\n\t\t\t\treturn performFullReconfiguration(client, { ...options, workspaceRoot: detected });\n\t\t\t}\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tcase \"WORKSPACE_NO_MARKERS\":\n\t\t\t// Warn but don't fail - workspace might be valid\n\t\t\treturn { success: true };\n\n\t\tcase \"NO_AUTH\":\n\t\t\t// Info only, not an error\n\t\t\treturn { success: true };\n\n\t\tdefault:\n\t\t\treturn { success: false };\n\t}\n}\n\n/**\n * Perform full reconfiguration\n * Auto-fixes node path issues by using resolveNodePath()\n */\nfunction performFullReconfiguration(client: AIClientConfig, options: RepairOptions): RepairResult {\n\ttry {\n\t\t// Detect workspace if not provided\n\t\tconst workspaceRoot = options.workspaceRoot || detectWorkspaceRoot(process.cwd());\n\t\tconst cliPath = findCliPath();\n\n\t\t// Determine config mode based on available paths\n\t\tlet mcpConfig;\n\n\t\tif (cliPath && workspaceRoot) {\n\t\t\t// Local dev mode with proper node path resolution\n\t\t\tmcpConfig = getSnapbackMCPConfig({\n\t\t\t\tapiKey: options.apiKey,\n\t\t\t\tworkspaceId: options.workspaceId,\n\t\t\t\tworkspaceRoot,\n\t\t\t\tuseLocalDev: true,\n\t\t\t\tlocalCliPath: cliPath,\n\t\t\t\tclient: client.format, // Pass client format for transport selection\n\t\t\t});\n\n\t\t\t// Log the node path being used for debugging\n\t\t\tconst nodePath = resolveNodePath();\n\t\t\tconsole.error(`[MCP Repair] Using node path: ${nodePath}`);\n\t\t} else {\n\t\t\t// Fallback mode - pass client format so stdio-only clients (like Claude Desktop) use npx\n\t\t\tmcpConfig = getSnapbackMCPConfig({\n\t\t\t\tapiKey: options.apiKey,\n\t\t\t\tworkspaceId: options.workspaceId,\n\t\t\t\tuseLocalDev: false,\n\t\t\t\tclient: client.format, // Pass client format for transport selection\n\t\t\t});\n\t\t\tconsole.error(\"[MCP Repair] Using default mode (CLI not found locally)\");\n\t\t}\n\n\t\t// Write config\n\t\tconst writeResult = writeClientConfig(client, mcpConfig);\n\n\t\tif (writeResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tfixed: [\"Full reconfiguration completed (node path resolved)\"],\n\t\t\t\tremaining: [],\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tfixed: [],\n\t\t\tremaining: [\"Write failed\"],\n\t\t\terror: writeResult.error,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tfixed: [],\n\t\t\tremaining: [\"Reconfiguration failed\"],\n\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t};\n\t}\n}\n\n/**\n * Detect workspace root by traversing upward from current directory\n */\nfunction detectWorkspaceRoot(startPath: string): string | null {\n\tlet currentPath = resolve(startPath);\n\tconst maxIterations = 50;\n\tlet iterations = 0;\n\n\twhile (iterations < maxIterations) {\n\t\titerations++;\n\n\t\t// Check for workspace markers\n\t\tconst hasGit = existsSync(resolve(currentPath, \".git\"));\n\t\tconst hasPackageJson = existsSync(resolve(currentPath, \"package.json\"));\n\t\tconst hasSnapback = existsSync(resolve(currentPath, \".snapback\"));\n\n\t\tif (hasGit || hasPackageJson || hasSnapback) {\n\t\t\treturn currentPath;\n\t\t}\n\n\t\t// Move up one directory\n\t\tconst parent = resolve(currentPath, \"..\");\n\t\tif (parent === currentPath) {\n\t\t\t// Reached filesystem root\n\t\t\tbreak;\n\t\t}\n\n\t\tcurrentPath = parent;\n\t}\n\n\treturn null;\n}\n\n/**\n * Find CLI path for local dev mode\n * Tries common locations relative to current directory\n */\nfunction findCliPath(): string | undefined {\n\tconst cwd = process.cwd();\n\n\t// Try common paths\n\tconst candidates = [\n\t\tresolve(cwd, \"apps/cli/dist/index.js\"), // Monorepo\n\t\tresolve(cwd, \"dist/index.js\"), // Direct CLI repo\n\t\tresolve(cwd, \"../cli/dist/index.js\"), // Sibling directory\n\t\tresolve(cwd, \"../../apps/cli/dist/index.js\"), // Nested monorepo\n\t];\n\n\tfor (const path of candidates) {\n\t\tif (existsSync(path)) {\n\t\t\treturn path;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"]}
|