@snapback/cli 1.0.2 → 1.0.3
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/dist/SkippedTestDetector-B3JZUE5G.js +5 -0
- package/dist/{SkippedTestDetector-JY4EF5BN.js.map → SkippedTestDetector-B3JZUE5G.js.map} +1 -1
- package/dist/{analysis-B4NVULM4.js → analysis-Z53F5FT2.js} +6 -5
- package/dist/{analysis-B4NVULM4.js.map → analysis-Z53F5FT2.js.map} +1 -1
- package/dist/{chunk-BCIXMIPW.js → chunk-6MR2TINI.js} +4 -3
- package/dist/chunk-6MR2TINI.js.map +1 -0
- package/dist/{chunk-WCQVDF3K.js → chunk-BW7RALUZ.js} +3 -2
- package/dist/{chunk-WCQVDF3K.js.map → chunk-BW7RALUZ.js.map} +1 -1
- package/dist/{chunk-VSJ33PLA.js → chunk-G7QXHNGB.js} +5 -4
- package/dist/chunk-G7QXHNGB.js.map +1 -0
- package/dist/{chunk-MTQ6ESQR.js → chunk-ISVRGBWT.js} +6 -5
- package/dist/chunk-ISVRGBWT.js.map +1 -0
- package/dist/{chunk-KSPLKCVF.js → chunk-NKBZIXCN.js} +7 -6
- package/dist/chunk-NKBZIXCN.js.map +1 -0
- package/dist/{chunk-RU7BOXR3.js → chunk-P2F6HU3P.js} +4 -3
- package/dist/chunk-P2F6HU3P.js.map +1 -0
- package/dist/{chunk-BJS6XH2V.js → chunk-QAKFE3NE.js} +4 -3
- package/dist/chunk-QAKFE3NE.js.map +1 -0
- package/dist/{chunk-WALLF2AH.js → chunk-YOVA65PS.js} +4 -3
- package/dist/chunk-YOVA65PS.js.map +1 -0
- package/dist/{dist-FBRR6YHP.js → dist-7UKXVKH3.js} +5 -4
- package/dist/{dist-7GPVXUEA.js.map → dist-7UKXVKH3.js.map} +1 -1
- package/dist/{dist-7GPVXUEA.js → dist-JX77JABV.js} +5 -4
- package/dist/{dist-DVM64QIS.js.map → dist-JX77JABV.js.map} +1 -1
- package/dist/{dist-DVM64QIS.js → dist-WKLJSPJT.js} +8 -7
- package/dist/{dist-FBRR6YHP.js.map → dist-WKLJSPJT.js.map} +1 -1
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/dist/{secure-credentials-YKZHAZNB.js → secure-credentials-6UMEU22H.js} +4 -3
- package/dist/secure-credentials-6UMEU22H.js.map +1 -0
- package/dist/{snapback-dir-4QRR2IPV.js → snapback-dir-T3CRQRY6.js} +6 -5
- package/dist/{snapback-dir-4QRR2IPV.js.map → snapback-dir-T3CRQRY6.js.map} +1 -1
- package/package.json +5 -5
- package/dist/SkippedTestDetector-JY4EF5BN.js +0 -4
- package/dist/chunk-BCIXMIPW.js.map +0 -1
- package/dist/chunk-BJS6XH2V.js.map +0 -1
- package/dist/chunk-KSPLKCVF.js.map +0 -1
- package/dist/chunk-MTQ6ESQR.js.map +0 -1
- package/dist/chunk-RU7BOXR3.js.map +0 -1
- package/dist/chunk-VSJ33PLA.js.map +0 -1
- package/dist/chunk-WALLF2AH.js.map +0 -1
- package/dist/secure-credentials-YKZHAZNB.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name } from './chunk-BW7RALUZ.js';
|
|
2
3
|
import { mkdir, writeFile, access, constants, readFile, appendFile, stat } from 'fs/promises';
|
|
3
4
|
import { homedir } from 'os';
|
|
4
5
|
import { join, dirname } from 'path';
|
|
@@ -212,7 +213,7 @@ async function getViolations(workspaceRoot) {
|
|
|
212
213
|
__name(getViolations, "getViolations");
|
|
213
214
|
async function getCredentials() {
|
|
214
215
|
try {
|
|
215
|
-
const { getCredentialsSecure } = await import('./secure-credentials-
|
|
216
|
+
const { getCredentialsSecure } = await import('./secure-credentials-6UMEU22H.js');
|
|
216
217
|
return await getCredentialsSecure();
|
|
217
218
|
} catch {
|
|
218
219
|
return readGlobalJson("credentials.json");
|
|
@@ -221,7 +222,7 @@ async function getCredentials() {
|
|
|
221
222
|
__name(getCredentials, "getCredentials");
|
|
222
223
|
async function saveCredentials(credentials) {
|
|
223
224
|
try {
|
|
224
|
-
const { saveCredentialsSecure } = await import('./secure-credentials-
|
|
225
|
+
const { saveCredentialsSecure } = await import('./secure-credentials-6UMEU22H.js');
|
|
225
226
|
return await saveCredentialsSecure(credentials);
|
|
226
227
|
} catch {
|
|
227
228
|
await createGlobalDirectory();
|
|
@@ -231,7 +232,7 @@ async function saveCredentials(credentials) {
|
|
|
231
232
|
__name(saveCredentials, "saveCredentials");
|
|
232
233
|
async function clearCredentials() {
|
|
233
234
|
try {
|
|
234
|
-
const { clearCredentialsSecure } = await import('./secure-credentials-
|
|
235
|
+
const { clearCredentialsSecure } = await import('./secure-credentials-6UMEU22H.js');
|
|
235
236
|
return await clearCredentialsSecure();
|
|
236
237
|
} catch {
|
|
237
238
|
await deleteGlobalJson("credentials.json");
|
|
@@ -295,5 +296,5 @@ async function getStats(path) {
|
|
|
295
296
|
__name(getStats, "getStats");
|
|
296
297
|
|
|
297
298
|
export { appendSnapbackJsonl, clearCredentials, createGlobalDirectory, createSnapbackDirectory, deleteGlobalJson, endCurrentSession, findWorkspaceRoot, getCredentials, getCurrentSession, getGlobalConfig, getGlobalDir, getGlobalPath, getLearnings, getProtectedFiles, getStats, getViolations, getWorkspaceConfig, getWorkspaceDir, getWorkspacePath, getWorkspaceVitals, isLoggedIn, isSnapbackInitialized, loadSnapbackJsonl, pathExists, readGlobalJson, readSnapbackJson, recordLearning, recordViolation, saveCredentials, saveCurrentSession, saveGlobalConfig, saveProtectedFiles, saveWorkspaceConfig, saveWorkspaceVitals, writeGlobalJson, writeSnapbackJson };
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
299
|
-
//# sourceMappingURL=chunk-
|
|
299
|
+
//# sourceMappingURL=chunk-NKBZIXCN.js.map
|
|
300
|
+
//# sourceMappingURL=chunk-NKBZIXCN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/snapback-dir.ts"],"names":["SNAPBACK_DIR","GLOBAL_SNAPBACK_DIR","getGlobalDir","join","homedir","getWorkspaceDir","workspaceRoot","process","cwd","getGlobalPath","relativePath","getWorkspacePath","createSnapbackDirectory","baseDir","dirs","dir","mkdir","recursive","gitignore","trim","writeFile","createGlobalDirectory","isSnapbackInitialized","configPath","access","constants","F_OK","isLoggedIn","credentials","readGlobalJson","accessToken","expiresAt","Date","readSnapbackJson","content","readFile","JSON","parse","writeSnapbackJson","data","fullPath","dirname","stringify","appendSnapbackJsonl","appendFile","loadSnapbackJsonl","split","filter","line","map","writeGlobalJson","deleteGlobalJson","unlink","getWorkspaceConfig","saveWorkspaceConfig","config","getWorkspaceVitals","saveWorkspaceVitals","vitals","getProtectedFiles","saveProtectedFiles","files","getCurrentSession","saveCurrentSession","session","endCurrentSession","recordLearning","learning","getLearnings","recordViolation","violation","getViolations","getCredentials","getCredentialsSecure","saveCredentials","saveCredentialsSecure","clearCredentials","clearCredentialsSecure","getGlobalConfig","saveGlobalConfig","findWorkspaceRoot","startDir","currentDir","maxDepth","depth","parentDir","pathExists","path","getStats","stats","stat","size","modifiedAt","mtime"],"mappings":"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","file":"chunk-NKBZIXCN.js","sourcesContent":["/**\n * SnapBack Directory Service\n *\n * Manages .snapback/ workspace directory and ~/.snapback/ global directory.\n * This is the foundation for CLI commands that need persistent storage.\n *\n * Storage Architecture:\n * - ~/.snapback/ (GLOBAL) - credentials, user config, MCP configs\n * - .snapback/ (WORKSPACE) - patterns, learnings, session, snapshots\n *\n * @see implementation_plan.md Section 1.3\n */\n\nimport { access, appendFile, constants, mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst SNAPBACK_DIR = \".snapback\";\nconst GLOBAL_SNAPBACK_DIR = \".snapback\";\n\n// =============================================================================\n// TYPE DEFINITIONS\n// =============================================================================\n\nexport interface WorkspaceConfig {\n\tworkspaceId?: string;\n\ttier?: \"free\" | \"pro\";\n\t/**\n\t * CLI protection preset - user-friendly abstraction layer.\n\t *\n\t * Maps to canonical ProtectionLevel values (@snapback/contracts):\n\t * - \"standard\" → \"watch\" (auto-snapshot, warn on risky changes)\n\t * - \"strict\" → \"block\" (confirmation required, block high-risk)\n\t *\n\t * The CLI uses presets for better UX, while internal operations\n\t * use the canonical \"watch\" | \"warn\" | \"block\" values.\n\t */\n\tprotectionLevel?: \"standard\" | \"strict\";\n\tsyncEnabled?: boolean;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface WorkspaceVitals {\n\tframework?: string;\n\tframeworkConfidence?: number;\n\tpackageManager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\ttypescript?: {\n\t\tenabled: boolean;\n\t\tstrict?: boolean;\n\t\tversion?: string;\n\t};\n\tcriticalFiles?: string[];\n\tdetectedAt: string;\n}\n\nexport interface ProtectedFile {\n\tpattern: string;\n\taddedAt: string;\n\treason?: string;\n}\n\nexport interface SessionState {\n\tid: string;\n\ttask?: string;\n\tstartedAt: string;\n\tsnapshotCount: number;\n\tfilesModified?: number;\n}\n\nexport interface LearningEntry {\n\tid: string;\n\ttype: \"pattern\" | \"pitfall\" | \"efficiency\" | \"discovery\" | \"workflow\";\n\ttrigger: string;\n\taction: string;\n\tsource: string;\n\tcreatedAt: string;\n}\n\nexport interface ViolationEntry {\n\ttype: string;\n\tfile: string;\n\tmessage: string;\n\tcount?: number;\n\tdate: string;\n\tprevention?: string;\n}\n\nexport interface GlobalCredentials {\n\taccessToken: string;\n\trefreshToken?: string;\n\temail: string;\n\ttier: \"free\" | \"pro\";\n\texpiresAt?: string;\n}\n\nexport interface GlobalConfig {\n\tapiUrl?: string;\n\tdefaultWorkspace?: string;\n\tanalytics?: boolean;\n}\n\n// =============================================================================\n// PATH HELPERS\n// =============================================================================\n\n/**\n * Get global snapback directory path (~/.snapback/)\n */\nexport function getGlobalDir(): string {\n\treturn join(homedir(), GLOBAL_SNAPBACK_DIR);\n}\n\n/**\n * Get workspace snapback directory path\n */\nexport function getWorkspaceDir(workspaceRoot?: string): string {\n\treturn join(workspaceRoot || process.cwd(), SNAPBACK_DIR);\n}\n\n/**\n * Get path to a file in the global directory\n */\nexport function getGlobalPath(relativePath: string): string {\n\treturn join(getGlobalDir(), relativePath);\n}\n\n/**\n * Get path to a file in the workspace directory\n */\nexport function getWorkspacePath(relativePath: string, workspaceRoot?: string): string {\n\treturn join(getWorkspaceDir(workspaceRoot), relativePath);\n}\n\n// =============================================================================\n// DIRECTORY MANAGEMENT\n// =============================================================================\n\n/**\n * Create the .snapback/ directory structure in a workspace\n * Mirrors the structure expected by MCP server (context-tools.ts)\n */\nexport async function createSnapbackDirectory(workspaceRoot?: string): Promise<void> {\n\tconst baseDir = getWorkspaceDir(workspaceRoot);\n\n\tconst dirs = [\"\", \"patterns\", \"learnings\", \"session\", \"snapshots\"];\n\n\tfor (const dir of dirs) {\n\t\tawait mkdir(join(baseDir, dir), { recursive: true });\n\t}\n\n\t// Create .gitignore to exclude snapshots but keep patterns\n\tconst gitignore = `# SnapBack Directory\n# Ignore snapshot content (large binary data)\nsnapshots/\nembeddings.db\n\n# Keep these for team sharing\n!patterns/\n!learnings/\n!vitals.json\n!config.json\n!protected.json\n`.trim();\n\n\tawait writeFile(join(baseDir, \".gitignore\"), gitignore);\n}\n\n/**\n * Create the global ~/.snapback/ directory structure\n */\nexport async function createGlobalDirectory(): Promise<void> {\n\tconst baseDir = getGlobalDir();\n\n\tconst dirs = [\"\", \"cache\", \"mcp-configs\"];\n\n\tfor (const dir of dirs) {\n\t\tawait mkdir(join(baseDir, dir), { recursive: true });\n\t}\n}\n\n/**\n * Check if .snapback/ directory exists in workspace\n */\nexport async function isSnapbackInitialized(workspaceRoot?: string): Promise<boolean> {\n\ttry {\n\t\tconst configPath = getWorkspacePath(\"config.json\", workspaceRoot);\n\t\tawait access(configPath, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if user is logged in (has credentials)\n */\nexport async function isLoggedIn(): Promise<boolean> {\n\ttry {\n\t\tconst credentials = await readGlobalJson<GlobalCredentials>(\"credentials.json\");\n\t\tif (!credentials?.accessToken) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if token is expired\n\t\tif (credentials.expiresAt) {\n\t\t\tconst expiresAt = new Date(credentials.expiresAt);\n\t\t\tif (expiresAt < new Date()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// =============================================================================\n// JSON FILE OPERATIONS - WORKSPACE\n// =============================================================================\n\n/**\n * Read JSON file from .snapback/\n */\nexport async function readSnapbackJson<T>(relativePath: string, workspaceRoot?: string): Promise<T | null> {\n\ttry {\n\t\tconst content = await readFile(getWorkspacePath(relativePath, workspaceRoot), \"utf-8\");\n\t\treturn JSON.parse(content) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Write JSON file to .snapback/\n */\nexport async function writeSnapbackJson<T>(relativePath: string, data: T, workspaceRoot?: string): Promise<void> {\n\tconst fullPath = getWorkspacePath(relativePath, workspaceRoot);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait writeFile(fullPath, JSON.stringify(data, null, 2));\n}\n\n/**\n * Append to JSONL file in .snapback/\n */\nexport async function appendSnapbackJsonl<T extends object>(\n\trelativePath: string,\n\tdata: T,\n\tworkspaceRoot?: string,\n): Promise<void> {\n\tconst fullPath = getWorkspacePath(relativePath, workspaceRoot);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait appendFile(fullPath, `${JSON.stringify(data)}\\n`);\n}\n\n/**\n * Load JSONL file from .snapback/\n */\nexport async function loadSnapbackJsonl<T>(relativePath: string, workspaceRoot?: string): Promise<T[]> {\n\ttry {\n\t\tconst content = await readFile(getWorkspacePath(relativePath, workspaceRoot), \"utf-8\");\n\t\treturn content\n\t\t\t.split(\"\\n\")\n\t\t\t.filter((line) => line.trim())\n\t\t\t.map((line) => JSON.parse(line) as T);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n// =============================================================================\n// JSON FILE OPERATIONS - GLOBAL\n// =============================================================================\n\n/**\n * Read JSON file from ~/.snapback/\n */\nexport async function readGlobalJson<T>(relativePath: string): Promise<T | null> {\n\ttry {\n\t\tconst content = await readFile(getGlobalPath(relativePath), \"utf-8\");\n\t\treturn JSON.parse(content) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Write JSON file to ~/.snapback/\n */\nexport async function writeGlobalJson<T>(relativePath: string, data: T): Promise<void> {\n\tconst fullPath = getGlobalPath(relativePath);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait writeFile(fullPath, JSON.stringify(data, null, 2));\n}\n\n/**\n * Delete JSON file from ~/.snapback/\n */\nexport async function deleteGlobalJson(relativePath: string): Promise<void> {\n\tconst fullPath = getGlobalPath(relativePath);\n\ttry {\n\t\tconst { unlink } = await import(\"node:fs/promises\");\n\t\tawait unlink(fullPath);\n\t} catch {\n\t\t// File doesn't exist, that's fine\n\t}\n}\n\n// =============================================================================\n// TYPED ACCESSORS\n// =============================================================================\n\n/**\n * Get workspace configuration\n */\nexport async function getWorkspaceConfig(workspaceRoot?: string): Promise<WorkspaceConfig | null> {\n\treturn readSnapbackJson<WorkspaceConfig>(\"config.json\", workspaceRoot);\n}\n\n/**\n * Save workspace configuration\n */\nexport async function saveWorkspaceConfig(config: WorkspaceConfig, workspaceRoot?: string): Promise<void> {\n\tawait writeSnapbackJson(\"config.json\", config, workspaceRoot);\n}\n\n/**\n * Get workspace vitals\n */\nexport async function getWorkspaceVitals(workspaceRoot?: string): Promise<WorkspaceVitals | null> {\n\treturn readSnapbackJson<WorkspaceVitals>(\"vitals.json\", workspaceRoot);\n}\n\n/**\n * Save workspace vitals\n */\nexport async function saveWorkspaceVitals(vitals: WorkspaceVitals, workspaceRoot?: string): Promise<void> {\n\tawait writeSnapbackJson(\"vitals.json\", vitals, workspaceRoot);\n}\n\n/**\n * Get protected files list\n */\nexport async function getProtectedFiles(workspaceRoot?: string): Promise<ProtectedFile[]> {\n\treturn (await readSnapbackJson<ProtectedFile[]>(\"protected.json\", workspaceRoot)) ?? [];\n}\n\n/**\n * Save protected files list\n */\nexport async function saveProtectedFiles(files: ProtectedFile[], workspaceRoot?: string): Promise<void> {\n\tawait writeSnapbackJson(\"protected.json\", files, workspaceRoot);\n}\n\n/**\n * Get current session state\n */\nexport async function getCurrentSession(workspaceRoot?: string): Promise<SessionState | null> {\n\treturn readSnapbackJson<SessionState>(\"session/current.json\", workspaceRoot);\n}\n\n/**\n * Save current session state\n */\nexport async function saveCurrentSession(session: SessionState, workspaceRoot?: string): Promise<void> {\n\tawait writeSnapbackJson(\"session/current.json\", session, workspaceRoot);\n}\n\n/**\n * End current session (delete current.json)\n */\nexport async function endCurrentSession(workspaceRoot?: string): Promise<void> {\n\tconst fullPath = getWorkspacePath(\"session/current.json\", workspaceRoot);\n\ttry {\n\t\tconst { unlink } = await import(\"node:fs/promises\");\n\t\tawait unlink(fullPath);\n\t} catch {\n\t\t// File doesn't exist, that's fine\n\t}\n}\n\n/**\n * Record a learning\n */\nexport async function recordLearning(learning: LearningEntry, workspaceRoot?: string): Promise<void> {\n\tawait appendSnapbackJsonl(\"learnings/user-learnings.jsonl\", learning, workspaceRoot);\n}\n\n/**\n * Get all learnings\n */\nexport async function getLearnings(workspaceRoot?: string): Promise<LearningEntry[]> {\n\treturn loadSnapbackJsonl<LearningEntry>(\"learnings/user-learnings.jsonl\", workspaceRoot);\n}\n\n/**\n * Record a violation\n */\nexport async function recordViolation(violation: ViolationEntry, workspaceRoot?: string): Promise<void> {\n\tawait appendSnapbackJsonl(\"patterns/violations.jsonl\", violation, workspaceRoot);\n}\n\n/**\n * Get all violations\n */\nexport async function getViolations(workspaceRoot?: string): Promise<ViolationEntry[]> {\n\treturn loadSnapbackJsonl<ViolationEntry>(\"patterns/violations.jsonl\", workspaceRoot);\n}\n\n/**\n * Get credentials\n * @deprecated Use getCredentialsSecure from secure-credentials.ts for production\n */\nexport async function getCredentials(): Promise<GlobalCredentials | null> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { getCredentialsSecure } = await import(\"./secure-credentials\");\n\t\treturn await getCredentialsSecure();\n\t} catch {\n\t\t// Fallback to legacy plain text (development mode)\n\t\treturn readGlobalJson<GlobalCredentials>(\"credentials.json\");\n\t}\n}\n\n/**\n * Save credentials\n * @deprecated Use saveCredentialsSecure from secure-credentials.ts for production\n */\nexport async function saveCredentials(credentials: GlobalCredentials): Promise<void> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { saveCredentialsSecure } = await import(\"./secure-credentials\");\n\t\treturn await saveCredentialsSecure(credentials);\n\t} catch {\n\t\t// Fallback to legacy plain text (development mode)\n\t\tawait createGlobalDirectory();\n\t\tawait writeGlobalJson(\"credentials.json\", credentials);\n\t}\n}\n\n/**\n * Clear credentials (logout)\n * @deprecated Use clearCredentialsSecure from secure-credentials.ts for production\n */\nexport async function clearCredentials(): Promise<void> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { clearCredentialsSecure } = await import(\"./secure-credentials\");\n\t\treturn await clearCredentialsSecure();\n\t} catch {\n\t\t// Fallback to legacy plain text (development mode)\n\t\tawait deleteGlobalJson(\"credentials.json\");\n\t}\n}\n\n/**\n * Get global config\n */\nexport async function getGlobalConfig(): Promise<GlobalConfig | null> {\n\treturn readGlobalJson<GlobalConfig>(\"config.json\");\n}\n\n/**\n * Save global config\n */\nexport async function saveGlobalConfig(config: GlobalConfig): Promise<void> {\n\tawait createGlobalDirectory();\n\tawait writeGlobalJson(\"config.json\", config);\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n// Re-export generateId from @snapback/contracts for backwards compatibility\nexport { generateId } from \"@snapback/contracts/id-generator\";\n\n/**\n * Get workspace root by searching for .snapback/ or package.json\n */\nexport async function findWorkspaceRoot(startDir?: string): Promise<string | null> {\n\tlet currentDir = startDir || process.cwd();\n\n\t// Limit search depth to prevent infinite loops\n\tconst maxDepth = 10;\n\tlet depth = 0;\n\n\twhile (depth < maxDepth) {\n\t\t// Check for .snapback directory\n\t\ttry {\n\t\t\tawait access(join(currentDir, SNAPBACK_DIR), constants.F_OK);\n\t\t\treturn currentDir;\n\t\t} catch {\n\t\t\t// Not found, continue\n\t\t}\n\n\t\t// Check for package.json (workspace root indicator)\n\t\ttry {\n\t\t\tawait access(join(currentDir, \"package.json\"), constants.F_OK);\n\t\t\treturn currentDir;\n\t\t} catch {\n\t\t\t// Not found, continue\n\t\t}\n\n\t\t// Move up one directory\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\t// Reached root\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t\tdepth++;\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if a path exists\n */\nexport async function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get file stats\n */\nexport async function getStats(path: string): Promise<{ size: number; modifiedAt: Date } | null> {\n\ttry {\n\t\tconst stats = await stat(path);\n\t\treturn {\n\t\t\tsize: stats.size,\n\t\t\tmodifiedAt: stats.mtime,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name } from './chunk-BW7RALUZ.js';
|
|
2
3
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
3
4
|
import { homedir, platform } from 'os';
|
|
4
5
|
import { resolve, dirname, join } from 'path';
|
|
@@ -902,5 +903,5 @@ __name(findCliPath, "findCliPath");
|
|
|
902
903
|
__name2(findCliPath, "findCliPath");
|
|
903
904
|
|
|
904
905
|
export { detectAIClients, getClient, getClientConfigPath, getConfiguredClients, getSnapbackMCPConfig, injectWorkspacePath, readClientConfig, removeSnapbackConfig, repairClientConfig, validateClientConfig, validateConfig, validateWorkspacePath, writeClientConfig };
|
|
905
|
-
//# sourceMappingURL=chunk-
|
|
906
|
-
//# sourceMappingURL=chunk-
|
|
906
|
+
//# sourceMappingURL=chunk-P2F6HU3P.js.map
|
|
907
|
+
//# sourceMappingURL=chunk-P2F6HU3P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/mcp-config/src/detect.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","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","experimental","Array","isArray","modelContextProtocolServers","some","server","getClientConfigPath","undefined","readClientConfig","client","validateClientConfig","issues","severity","code","message","fix","valid","configContent","parsedConfig","error","Error","snapbackConfig","extractSnapbackConfig","validateSnapbackConfig","command","args","workspaceIdx","indexOf","length","workspacePath","wsValidation","validateWorkspacePath","hasMarkers","i","absPath","resolve","path","hasGit","hasPackageJson","snapback","s","url","URL","SNAPBACK_API_KEY","SNAPBACK_WORKSPACE_ID","getSnapbackMCPConfig","apiKey","workspaceId","serverUrl","useBinary","customCommand","additionalEnv","workspaceRoot","useLocalDev","localCliPath","keys","tier","writeClientConfig","mcpConfig","configDir","dirname","mkdirSync","recursive","existingConfig","hasExistingConfig","backup","Date","now","writeFileSync","stringify","newConfig","mergeConfig","success","removeSnapbackConfig","existing","continueConfig","filteredServers","validateConfig","Boolean","expCfg","srvs","repairClientConfig","fixed","remaining","validation","force","performFullReconfiguration","issue","fixResult","attemptFix","hasCriticalErrors","msg","injectWorkspacePath","detectedWorkspace","detectWorkspaceRoot","hasWorkspace","_validation","workspace","findCliPath","writeResult","startPath","currentPath","maxIterations","iterations","parent","candidates"],"mappings":"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","file":"chunk-P2F6HU3P.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) => [join(home, \".codeium/windsurf/mcp_config.json\")],\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) => {\n\t\tswitch (platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\treturn [join(home, \"Library/Application Support/Qoder/SharedClientCache/extension/local/mcp.json\")];\n\t\t\tcase \"win32\":\n\t\t\t\treturn [join(process.env.APPDATA || \"\", \"Qoder/mcp.json\")];\n\t\t\tdefault:\n\t\t\t\treturn [join(home, \".config/Qoder/mcp.json\")];\n\t\t}\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 \"vscode\":\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\treturn \"snapback\" in servers;\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase \"gemini\":\n\t\tcase \"zed\":\n\t\t\t// These embed mcpServers inside a settings object\n\t\t\t// Check both top-level and nested mcpServers\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;\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 * 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 { 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\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 tools configure --force\",\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\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 * 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 { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport type {\n\tAIClientConfig,\n\tMCPConfig,\n\tMCPServerConfig,\n\tRemoveResult,\n\tSnapbackConfigOptions,\n\tWriteResult,\n} from \"./types.js\";\n\n// =============================================================================\n// CONFIG GENERATION\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 * // Preferred: 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 */\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} = options;\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: Remote HTTP server (Fly.io) - NEW DEFAULT\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\treturn {\n\t\t\tcommand: \"node\",\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 *\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\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\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 \"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\texperimental.modelContextProtocolServers = servers.filter((s) => s.name !== \"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 * Merge SnapBack config into existing config based on format\n */\nfunction mergeConfig(\n\texisting: MCPConfig,\n\tsnapbackConfig: MCPServerConfig,\n\tformat: AIClientConfig[\"format\"],\n): MCPConfig | Record<string, unknown> {\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 \"gemini\":\n\t\tcase \"zed\":\n\t\tcase \"qoder\":\n\t\t\t// Standard mcpServers format\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\tsnapback: snapbackConfig,\n\t\t\t\t},\n\t\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 if present\n\t\t\tconst filteredServers = servers.filter((s) => s.name !== \"snapback\");\n\n\t\t\t// Add new snapback config\n\t\t\tfilteredServers.push({\n\t\t\t\tname: \"snapback\",\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\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\tsnapback: snapbackConfig,\n\t\t\t\t},\n\t\t\t};\n\t}\n}\n\n/**\n * Validate that a config was written correctly\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\n\t\tswitch (client.format) {\n\t\t\tcase \"claude\":\n\t\t\tcase \"cursor\":\n\t\t\tcase \"windsurf\":\n\t\t\tcase \"vscode\":\n\t\t\tcase \"cline\":\n\t\t\tcase \"roo-code\":\n\t\t\tcase \"gemini\":\n\t\t\tcase \"zed\":\n\t\t\tcase \"qoder\":\n\t\t\t\t// Valid if has either command (stdio) or url (HTTP)\n\t\t\t\treturn Boolean(config.mcpServers?.snapback?.command || config.mcpServers?.snapback?.url);\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\treturn Boolean(srvs?.some((s) => s.name === \"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, 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 \"INVALID_URL\":\n\t\t\t// These require full reconfiguration\n\t\t\treturn performFullReconfiguration(client, options);\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 */\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\n\t\t// Generate new config\n\t\tconst mcpConfig = getSnapbackMCPConfig({\n\t\t\tapiKey: options.apiKey,\n\t\t\tworkspaceId: options.workspaceId,\n\t\t\tworkspaceRoot: workspaceRoot || undefined,\n\t\t\tuseLocalDev: true, // Default to local dev for stdio\n\t\t\tlocalCliPath: findCliPath(),\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\"],\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"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name } from './chunk-BW7RALUZ.js';
|
|
2
3
|
import { parse } from '@babel/parser';
|
|
3
4
|
|
|
4
5
|
function detectSkippedTests(code, filePath) {
|
|
@@ -104,5 +105,5 @@ function getSkippedTestSummary(results) {
|
|
|
104
105
|
__name(getSkippedTestSummary, "getSkippedTestSummary");
|
|
105
106
|
|
|
106
107
|
export { analyzeSkippedTests, detectSkippedTests, getSkippedTestSummary };
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-QAKFE3NE.js.map
|
|
109
|
+
//# sourceMappingURL=chunk-QAKFE3NE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/core/dist/analysis/static/SkippedTestDetector.js"],"names":["detectSkippedTests","code","filePath","skipped","visit","node","type","callee","property","name","object","testType","arguments","length","firstArg","value","quasis","raw","push","line","loc","start","column","file","key","Object","keys","Array","isArray","item","ast","parse","sourceType","plugins","errorRecovery","program","parsed","error","Error","message","String","analyzeSkippedTests","files","results","content","includes","getSkippedTestSummary","summary","totalSkipped","byType","describe","it","test","filesWithSkipped","result"],"mappings":"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","file":"chunk-QAKFE3NE.js","sourcesContent":["/**\n * Skipped Test Detector\n *\n * Uses @babel/parser to detect skipped tests (describe.skip, it.skip, test.skip)\n * in test files. This helps AI agents identify RED PHASE TDD tests that may\n * be ready to enable.\n *\n * @module analysis/static/SkippedTestDetector\n */\nimport { parse } from \"@babel/parser\";\n/**\n * Detect skipped tests in a file's source code\n *\n * @param code - Source code to analyze\n * @param filePath - Path to file (for error reporting)\n * @returns Detection result with skipped tests\n *\n * @example\n * ```typescript\n * const result = detectSkippedTests(`\n * describe.skip(\"Feature\", () => {\n * it(\"should work\", () => {});\n * });\n * `, \"feature.test.ts\");\n *\n * // result.skipped = [{ type: \"describe\", name: \"Feature\", line: 2, ... }]\n * ```\n */\nexport function detectSkippedTests(code, filePath) {\n const skipped = [];\n try {\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\"],\n errorRecovery: true,\n });\n // Simple AST traversal without @babel/traverse (to avoid extra dependency in MCP)\n function visit(node) {\n if (node.type === \"CallExpression\") {\n const callee = node.callee;\n // Check for .skip pattern: describe.skip, it.skip, test.skip\n if (callee.type === \"MemberExpression\" &&\n callee.property.type === \"Identifier\" &&\n callee.property.name === \"skip\" &&\n callee.object.type === \"Identifier\") {\n const testType = callee.object.name;\n if (testType === \"describe\" || testType === \"it\" || testType === \"test\") {\n // Try to extract test name from first argument\n let name;\n if (node.arguments.length > 0) {\n const firstArg = node.arguments[0];\n if (firstArg.type === \"StringLiteral\") {\n name = firstArg.value;\n }\n else if (firstArg.type === \"TemplateLiteral\" && firstArg.quasis.length === 1) {\n name = firstArg.quasis[0].value.raw;\n }\n }\n skipped.push({\n type: testType,\n name,\n line: node.loc?.start.line ?? 0,\n column: node.loc?.start.column ?? 0,\n file: filePath,\n });\n }\n }\n // Also check for skip() as method call: describe(\"name\", () => {}).skip\n // This is less common but supported by some frameworks\n }\n // Recursively visit all properties that could contain nodes\n for (const key of Object.keys(node)) {\n const value = node[key];\n if (value && typeof value === \"object\") {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === \"object\" && \"type\" in item) {\n visit(item);\n }\n }\n }\n else if (\"type\" in value) {\n visit(value);\n }\n }\n }\n }\n visit(ast.program);\n return { file: filePath, skipped, parsed: true };\n }\n catch (error) {\n return {\n file: filePath,\n skipped: [],\n parsed: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n/**\n * Analyze multiple files for skipped tests\n *\n * @param files - Map of file path to content\n * @returns Array of results for each file\n */\nexport function analyzeSkippedTests(files) {\n const results = [];\n for (const [filePath, content] of files) {\n // Only analyze test files\n if (filePath.includes(\".test.\") || filePath.includes(\".spec.\") || filePath.includes(\"__tests__\")) {\n results.push(detectSkippedTests(content, filePath));\n }\n }\n return results;\n}\n/**\n * Get summary of skipped tests across all files\n */\nexport function getSkippedTestSummary(results) {\n const summary = {\n totalSkipped: 0,\n byType: { describe: 0, it: 0, test: 0 },\n filesWithSkipped: [],\n };\n for (const result of results) {\n if (result.skipped.length > 0) {\n summary.filesWithSkipped.push(result.file);\n summary.totalSkipped += result.skipped.length;\n for (const test of result.skipped) {\n summary.byType[test.type]++;\n }\n }\n }\n return summary;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name, __require } from './chunk-BW7RALUZ.js';
|
|
2
3
|
import * as fs6 from 'fs';
|
|
3
4
|
import { existsSync, promises, writeFileSync, renameSync, unlinkSync } from 'fs';
|
|
4
5
|
import * as fs3 from 'fs/promises';
|
|
@@ -12740,5 +12741,5 @@ var DistributedTokenManager = class {
|
|
|
12740
12741
|
*/
|
|
12741
12742
|
|
|
12742
12743
|
export { AIPresenceDetector, AI_EXTENSION_IDS, ApiError, AuthenticationError, AuthorizationError, BurstHeuristicsDetector, ConfigDetector, CorruptedDataError, CursorDetector, DEFAULT_EXPERIENCE_THRESHOLDS, DEFAULT_MAX_SIZE, DEFAULT_RISK_THRESHOLDS, DEFAULT_THRESHOLDS, DefaultRiskAnalyzer, DeviceAuthClient, DiffCalculator, DistributedTokenManager, EncryptionService, ExperienceClassifier, FileChangeAnalyzer, FileConflictResolver, ID_PREFIX, InputValidationError, LRUCache, LocalStorage, MemoryStorage, MissingContentError, NoOpLogger, NodeTimerService, PathValidationError, PrivacySanitizer, PrivacyValidator, ProtectionClient, ProtectionDecisionEngine, ProtectionManager, RISK_FACTOR_DESCRIPTIONS, RateLimitError, RateLimiter, RetryPresets, RiskAnalyzer, SNAPBACK_LAYER_RULES, SessionCoordinator, SessionDeduplication, SessionManager, SessionRecovery, SessionRollback, SessionSummaryGenerator, SessionTagger, SnapBackError, SnapBackRCParser, Snapback, SnapbackClient, SnapshotClient, SnapshotCreationError, SnapshotDeletionService, SnapshotDuplicateError, SnapshotError, SnapshotIconStrategy, SnapshotManager, SnapshotNamingStrategy, SnapshotNotFoundError, SnapshotProtectedError, SnapshotRestoreError, SnapshotVerificationError, SnapshotVersionError, StorageBroker, StorageBrokerAdapter, StorageConnectionError, StorageError, StorageError2, StorageFullError, StorageFullError2, StorageIOError, StorageLockError, StorageLockError2, THRESHOLDS, TokenBucket, ValidationError, all, allOrErrors, analyze, andThen, applyAutomaticFix, areEqual, assertDefined, assertNonEmptyArray, assertNonEmptyString, assertPathWithinRoot, assertPositiveNumber, atomicWriteFile, atomicWriteFileSync, calculateBackoff, configureInvariant, createChangeSummary, createConfig, createDashboardMetricsClient, createDeviceAuthClient, createRule, createScopedInvariant, createSnapshotWithRetry, createSnapshotWithRetrySafe, createThresholds, createTokenBucket, defaultConfig, describeRiskFactor, describeRiskFactors, diagnoseSnapshotFailure, ensureSnapBackError, err, evaluatePolicy, formatDiagnosis, fromPromise, fromPromiseWith, generateAuditId, generateCheckpointId, generateId22 as generateId2, generateSessionId, generateSnapshotId2 as generateSnapshotId, getBlobPath, getDepth, getInvariantConfig, getStandardRiskFactors, getViolationCounts, hashContent, hashFilePath, hashWorkspaceId, ingestTelemetry, invariant, isApiError, isConsumptionAllowed, isConsumptionDenied, isErr, isKnownRiskFactor, isOk, isRateLimitAllowed, isRateLimitDenied, isRetryableError, isSnapBackError, isSnapshotError, isStorageError, isValidId, isValidationError, isWithin, makeSafeSessionFinalizedEvent, makeSafeSessionStartedEvent, map, mapErr, match, normalize, ok, parseIdPrefix, parseIdTimestamp, randomId, resetThresholds, resetViolationCounts, runArchCheck, sequence, sha256, softInvariant, tap, tapErr, toError, toError2, toPromise, tryAll, tryCatch, tryCatchAsync, typeInvariant, unwrap, unwrapOr, unwrapOrElse, updateThresholds, withRetry };
|
|
12743
|
-
//# sourceMappingURL=chunk-
|
|
12744
|
-
//# sourceMappingURL=chunk-
|
|
12744
|
+
//# sourceMappingURL=chunk-YOVA65PS.js.map
|
|
12745
|
+
//# sourceMappingURL=chunk-YOVA65PS.js.map
|