@snapback/cli 1.6.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +120 -21
  2. package/dist/SkippedTestDetector-AXTMWWHC.js +5 -0
  3. package/dist/SkippedTestDetector-QLSQV7K7.js +5 -0
  4. package/dist/analysis-6WTBZJH3.js +6 -0
  5. package/dist/analysis-C472LUGW.js +2475 -0
  6. package/dist/auth-TDIHGKKL.js +1446 -0
  7. package/dist/auto-provision-organization-CXHL46P3.js +161 -0
  8. package/dist/{chunk-FVIYXFCL.js → chunk-4YTE4JEW.js} +2 -3
  9. package/dist/chunk-5EOPYJ4Y.js +12 -0
  10. package/dist/{chunk-ARVV3F4K.js → chunk-5SQA44V7.js} +1085 -18
  11. package/dist/{chunk-RB7H4UQJ.js → chunk-7ADPL4Q3.js} +10 -3
  12. package/dist/chunk-CBGOC6RV.js +293 -0
  13. package/dist/chunk-CPZWXRP2.js +4432 -0
  14. package/dist/{chunk-7JX6Y4TL.js → chunk-DPWFZNMY.js} +21 -34
  15. package/dist/{chunk-R7CUQ7CU.js → chunk-E6V6QKS7.js} +317 -33
  16. package/dist/chunk-FMWCFAY7.js +111 -0
  17. package/dist/chunk-GQ73B37K.js +314 -0
  18. package/dist/chunk-LIBBDBW5.js +6136 -0
  19. package/dist/chunk-O7HMAZ7L.js +3497 -0
  20. package/dist/chunk-PL4HF4M2.js +593 -0
  21. package/dist/chunk-Q4VC7GND.js +2300 -0
  22. package/dist/chunk-WS36HDEU.js +3735 -0
  23. package/dist/chunk-ZBQDE6WJ.js +108 -0
  24. package/dist/client-62E3L6DW.js +8 -0
  25. package/dist/dist-5LR7APG5.js +5 -0
  26. package/dist/dist-NFU5UJEW.js +9 -0
  27. package/dist/dist-OO5LJHL6.js +12 -0
  28. package/dist/index.js +61644 -37198
  29. package/dist/local-service-adapter-AB3UYRUK.js +6 -0
  30. package/dist/pioneer-oauth-hook-V2JKEXM7.js +12 -0
  31. package/dist/{secure-credentials-IWQB6KU4.js → secure-credentials-UEPG7GWW.js} +2 -3
  32. package/dist/snapback-dir-MG7DTRMF.js +6 -0
  33. package/package.json +12 -11
  34. package/scripts/postinstall.mjs +2 -3
  35. package/dist/SkippedTestDetector-5WJZKZQ3.js +0 -5
  36. package/dist/SkippedTestDetector-5WJZKZQ3.js.map +0 -1
  37. package/dist/analysis-YI4UNUCM.js +0 -6
  38. package/dist/analysis-YI4UNUCM.js.map +0 -1
  39. package/dist/chunk-7JX6Y4TL.js.map +0 -1
  40. package/dist/chunk-ARVV3F4K.js.map +0 -1
  41. package/dist/chunk-EU2IZPOK.js +0 -13002
  42. package/dist/chunk-EU2IZPOK.js.map +0 -1
  43. package/dist/chunk-FVIYXFCL.js.map +0 -1
  44. package/dist/chunk-R7CUQ7CU.js.map +0 -1
  45. package/dist/chunk-RB7H4UQJ.js.map +0 -1
  46. package/dist/chunk-SOABQWAU.js +0 -385
  47. package/dist/chunk-SOABQWAU.js.map +0 -1
  48. package/dist/dist-O6EBXLN6.js +0 -5
  49. package/dist/dist-O6EBXLN6.js.map +0 -1
  50. package/dist/dist-PJVBBZTF.js +0 -5
  51. package/dist/dist-PJVBBZTF.js.map +0 -1
  52. package/dist/index.js.map +0 -1
  53. package/dist/learning-pruner-QC4CTJDX.js +0 -5
  54. package/dist/learning-pruner-QC4CTJDX.js.map +0 -1
  55. package/dist/secure-credentials-IWQB6KU4.js.map +0 -1
  56. package/dist/snapback-dir-V6MWXIW4.js +0 -5
  57. package/dist/snapback-dir-V6MWXIW4.js.map +0 -1
@@ -1,32 +1,11 @@
1
1
  #!/usr/bin/env node --no-warnings=ExperimentalWarning
2
- import { __name } from './chunk-RB7H4UQJ.js';
2
+ import { __name } from './chunk-7ADPL4Q3.js';
3
3
  import { mkdir, writeFile, access, constants, readFile, appendFile, stat } from 'fs/promises';
4
4
  import { homedir } from 'os';
5
5
  import { join, dirname } from 'path';
6
6
  import { z } from 'zod';
7
- import { nanoid } from 'nanoid';
8
7
 
9
- function generateId(prefix) {
10
- const id = nanoid();
11
- return prefix ? `${prefix}-${id}` : id;
12
- }
13
- __name(generateId, "generateId");
14
- function slugify(description, maxLength = 30) {
15
- return description.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, maxLength);
16
- }
17
- __name(slugify, "slugify");
18
- function generateSnapshotId(description) {
19
- if (description && description.length > 0) {
20
- const slug = slugify(description);
21
- if (slug.length > 0) {
22
- return `snapshot-${slug}-${Date.now()}-${nanoid(9)}`;
23
- }
24
- }
25
- return `snapshot-${Date.now()}-${nanoid(9)}`;
26
- }
27
- __name(generateSnapshotId, "generateSnapshotId");
28
-
29
- // src/services/snapback-dir.ts
8
+ process.env.SNAPBACK_CLI='true';
30
9
  var SNAPBACK_DIR = ".snapback";
31
10
  var GLOBAL_SNAPBACK_DIR = ".snapback";
32
11
  var WorkspaceConfigSchema = z.object({
@@ -259,7 +238,9 @@ async function deleteGlobalJson(relativePath) {
259
238
  __name(deleteGlobalJson, "deleteGlobalJson");
260
239
  async function getWorkspaceConfig(workspaceRoot) {
261
240
  const data = await readSnapbackJson("config.json", workspaceRoot);
262
- if (!data) return null;
241
+ if (!data) {
242
+ return null;
243
+ }
263
244
  const result = WorkspaceConfigSchema.safeParse(data);
264
245
  return result.success ? result.data : null;
265
246
  }
@@ -270,7 +251,9 @@ async function saveWorkspaceConfig(config, workspaceRoot) {
270
251
  __name(saveWorkspaceConfig, "saveWorkspaceConfig");
271
252
  async function getWorkspaceVitals(workspaceRoot) {
272
253
  const data = await readSnapbackJson("vitals.json", workspaceRoot);
273
- if (!data) return null;
254
+ if (!data) {
255
+ return null;
256
+ }
274
257
  const result = WorkspaceVitalsSchema.safeParse(data);
275
258
  return result.success ? result.data : null;
276
259
  }
@@ -281,7 +264,9 @@ async function saveWorkspaceVitals(vitals, workspaceRoot) {
281
264
  __name(saveWorkspaceVitals, "saveWorkspaceVitals");
282
265
  async function getProtectedFiles(workspaceRoot) {
283
266
  const data = await readSnapbackJson("protected.json", workspaceRoot);
284
- if (!data) return [];
267
+ if (!data) {
268
+ return [];
269
+ }
285
270
  const result = z.array(ProtectedFileSchema).safeParse(data);
286
271
  return result.success ? result.data : [];
287
272
  }
@@ -292,7 +277,9 @@ async function saveProtectedFiles(files, workspaceRoot) {
292
277
  __name(saveProtectedFiles, "saveProtectedFiles");
293
278
  async function getCurrentSession(workspaceRoot) {
294
279
  const data = await readSnapbackJson("session/current.json", workspaceRoot);
295
- if (!data) return null;
280
+ if (!data) {
281
+ return null;
282
+ }
296
283
  const result = SessionStateSchema.safeParse(data);
297
284
  return result.success ? result.data : null;
298
285
  }
@@ -330,7 +317,7 @@ async function getViolations(workspaceRoot) {
330
317
  __name(getViolations, "getViolations");
331
318
  async function getCredentials() {
332
319
  try {
333
- const { getCredentialsSecure } = await import('./secure-credentials-IWQB6KU4.js');
320
+ const { getCredentialsSecure } = await import('./secure-credentials-UEPG7GWW.js');
334
321
  return await getCredentialsSecure();
335
322
  } catch {
336
323
  return readGlobalJson("credentials.json");
@@ -339,7 +326,7 @@ async function getCredentials() {
339
326
  __name(getCredentials, "getCredentials");
340
327
  async function saveCredentials(credentials) {
341
328
  try {
342
- const { saveCredentialsSecure } = await import('./secure-credentials-IWQB6KU4.js');
329
+ const { saveCredentialsSecure } = await import('./secure-credentials-UEPG7GWW.js');
343
330
  return await saveCredentialsSecure(credentials);
344
331
  } catch {
345
332
  await createGlobalDirectory();
@@ -349,7 +336,7 @@ async function saveCredentials(credentials) {
349
336
  __name(saveCredentials, "saveCredentials");
350
337
  async function clearCredentials() {
351
338
  try {
352
- const { clearCredentialsSecure } = await import('./secure-credentials-IWQB6KU4.js');
339
+ const { clearCredentialsSecure } = await import('./secure-credentials-UEPG7GWW.js');
353
340
  return await clearCredentialsSecure();
354
341
  } catch {
355
342
  await deleteGlobalJson("credentials.json");
@@ -358,7 +345,9 @@ async function clearCredentials() {
358
345
  __name(clearCredentials, "clearCredentials");
359
346
  async function getGlobalConfig() {
360
347
  const data = await readGlobalJson("config.json");
361
- if (!data) return null;
348
+ if (!data) {
349
+ return null;
350
+ }
362
351
  const result = GlobalConfigSchema.safeParse(data);
363
352
  return result.success ? result.data : null;
364
353
  }
@@ -415,6 +404,4 @@ async function getStats(path) {
415
404
  }
416
405
  __name(getStats, "getStats");
417
406
 
418
- export { GlobalConfigSchema, GlobalCredentialsSchema, LearningEntrySchema, ProtectedFileSchema, SessionStateSchema, ViolationEntrySchema, WorkspaceConfigSchema, WorkspaceVitalsSchema, appendSnapbackJsonl, clearCredentials, createGlobalDirectory, createSnapbackDirectory, deleteGlobalJson, endCurrentSession, findWorkspaceRoot, generateId, generateSnapshotId, 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 };
419
- //# sourceMappingURL=chunk-7JX6Y4TL.js.map
420
- //# sourceMappingURL=chunk-7JX6Y4TL.js.map
407
+ export { GlobalConfigSchema, GlobalCredentialsSchema, LearningEntrySchema, ProtectedFileSchema, SessionStateSchema, ViolationEntrySchema, WorkspaceConfigSchema, WorkspaceVitalsSchema, 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 };
@@ -1,17 +1,92 @@
1
1
  #!/usr/bin/env node --no-warnings=ExperimentalWarning
2
- import { __name } from './chunk-RB7H4UQJ.js';
3
- import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
2
+ import { __name } from './chunk-7ADPL4Q3.js';
3
+ import { readFileSync, mkdirSync, writeFileSync, existsSync } from 'fs';
4
4
  import { homedir, platform } from 'os';
5
5
  import { join, resolve, dirname } from 'path';
6
6
  import { randomUUID } from 'crypto';
7
7
  import { exec, execSync } from 'child_process';
8
8
  import { promisify } from 'util';
9
9
 
10
+ process.env.SNAPBACK_CLI='true';
10
11
  var __defProp = Object.defineProperty;
11
12
  var __name2 = /* @__PURE__ */ __name((target, value) => __defProp(target, "name", {
12
13
  value,
13
14
  configurable: true
14
15
  }), "__name");
16
+ var CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
17
+ function getCacheFilePath() {
18
+ return join(homedir(), ".snapback", "mcp-configs", "paths.json");
19
+ }
20
+ __name(getCacheFilePath, "getCacheFilePath");
21
+ __name2(getCacheFilePath, "getCacheFilePath");
22
+ function readCache() {
23
+ try {
24
+ const raw = readFileSync(getCacheFilePath(), "utf-8");
25
+ const parsed = JSON.parse(raw);
26
+ if (parsed.version === 1 && typeof parsed.discovered === "object") {
27
+ return parsed;
28
+ }
29
+ } catch {
30
+ }
31
+ return {
32
+ version: 1,
33
+ discovered: {}
34
+ };
35
+ }
36
+ __name(readCache, "readCache");
37
+ __name2(readCache, "readCache");
38
+ function writeCache(cache) {
39
+ try {
40
+ const dir = join(homedir(), ".snapback", "mcp-configs");
41
+ mkdirSync(dir, {
42
+ recursive: true
43
+ });
44
+ writeFileSync(getCacheFilePath(), JSON.stringify(cache, null, 2));
45
+ } catch {
46
+ }
47
+ }
48
+ __name(writeCache, "writeCache");
49
+ __name2(writeCache, "writeCache");
50
+ function getCachedPath(clientName) {
51
+ const cache = readCache();
52
+ const entry = cache.discovered[clientName];
53
+ if (!entry) return null;
54
+ const age = Date.now() - new Date(entry.discoveredAt).getTime();
55
+ if (age > CACHE_TTL_MS) return null;
56
+ if (!existsSync(entry.path)) {
57
+ delete cache.discovered[clientName];
58
+ writeCache(cache);
59
+ return null;
60
+ }
61
+ return entry.path;
62
+ }
63
+ __name(getCachedPath, "getCachedPath");
64
+ __name2(getCachedPath, "getCachedPath");
65
+ function setCachedPath(clientName, configPath) {
66
+ const cache = readCache();
67
+ cache.discovered[clientName] = {
68
+ path: configPath,
69
+ discoveredAt: /* @__PURE__ */ (/* @__PURE__ */ new Date()).toISOString(),
70
+ platform: process.platform
71
+ };
72
+ writeCache(cache);
73
+ }
74
+ __name(setCachedPath, "setCachedPath");
75
+ __name2(setCachedPath, "setCachedPath");
76
+ function evictCachedPath(clientName) {
77
+ const cache = readCache();
78
+ if (cache.discovered[clientName]) {
79
+ delete cache.discovered[clientName];
80
+ writeCache(cache);
81
+ }
82
+ }
83
+ __name(evictCachedPath, "evictCachedPath");
84
+ __name2(evictCachedPath, "evictCachedPath");
85
+ function getAllCachedPaths() {
86
+ return readCache().discovered;
87
+ }
88
+ __name(getAllCachedPaths, "getAllCachedPaths");
89
+ __name2(getAllCachedPaths, "getAllCachedPaths");
15
90
  var CLIENT_CONFIGS = {
16
91
  claude: /* @__PURE__ */ __name2((home) => {
17
92
  switch (platform()) {
@@ -36,14 +111,17 @@ var CLIENT_CONFIGS = {
36
111
  ] : [],
37
112
  join(_home, ".cursor/mcp.json")
38
113
  ], "cursor"),
39
- windsurf: /* @__PURE__ */ __name2((home, cwd) => [
40
- ...cwd ? [
41
- join(cwd, ".windsurf/mcp.json")
42
- ] : [],
114
+ // Windsurf only has a global config — no project-level support (confirmed by Windsurf docs, June 2025)
115
+ windsurf: /* @__PURE__ */ __name2((home) => [
43
116
  join(home, ".codeium/windsurf/mcp_config.json")
44
117
  ], "windsurf"),
45
- continue: /* @__PURE__ */ __name2((home) => [
46
- join(home, ".continue/config.json")
118
+ // Continue: global config.json or config.yaml; project-level .continue/mcpServers/mcp.json
119
+ continue: /* @__PURE__ */ __name2((home, cwd) => [
120
+ ...cwd ? [
121
+ join(cwd, ".continue/mcpServers/mcp.json")
122
+ ] : [],
123
+ join(home, ".continue/config.json"),
124
+ join(home, ".continue/config.yaml")
47
125
  ], "continue"),
48
126
  // New clients
49
127
  vscode: /* @__PURE__ */ __name2((_home, cwd) => [
@@ -51,9 +129,16 @@ var CLIENT_CONFIGS = {
51
129
  join(cwd, ".vscode/mcp.json")
52
130
  ] : []
53
131
  ], "vscode"),
54
- zed: /* @__PURE__ */ __name2((home) => [
132
+ // Zed: global ~/.config/zed/settings.json, plus project-level .zed/settings.json
133
+ zed: /* @__PURE__ */ __name2((home, cwd) => [
134
+ ...cwd ? [
135
+ join(cwd, ".zed/settings.json")
136
+ ] : [],
55
137
  join(home, ".config/zed/settings.json")
56
138
  ], "zed"),
139
+ // Cline / Roo Code store their actual settings in VS Code extension globalStorage,
140
+ // but `snap tools configure --cline/--roo-code` writes to these paths as a side-channel.
141
+ // Detection via these paths is best-effort; users may need `snap mcp link --client cline` instead.
57
142
  cline: /* @__PURE__ */ __name2((home) => [
58
143
  join(home, ".cline/mcp.json")
59
144
  ], "cline"),
@@ -71,19 +156,26 @@ var CLIENT_CONFIGS = {
71
156
  const workspaceConfig = cwd ? [
72
157
  join(cwd, ".qoder-mcp-config.json")
73
158
  ] : [];
74
- const globalConfig = (() => {
159
+ const globalConfigs = (() => {
75
160
  switch (platform()) {
76
161
  case "darwin":
77
- return join(home, "Library/Application Support/Qoder/SharedClientCache/extension/local/mcp.json");
162
+ return [
163
+ join(home, "Library/Application Support/Qoder/SharedClientCache/mcp.json"),
164
+ join(home, "Library/Application Support/Qoder/SharedClientCache/extension/local/mcp.json")
165
+ ];
78
166
  case "win32":
79
- return join(process.env.APPDATA || "", "Qoder/mcp.json");
167
+ return [
168
+ join(process.env.APPDATA || "", "Qoder/mcp.json")
169
+ ];
80
170
  default:
81
- return join(home, ".config/Qoder/mcp.json");
171
+ return [
172
+ join(home, ".config/Qoder/mcp.json")
173
+ ];
82
174
  }
83
175
  })();
84
176
  return [
85
177
  ...workspaceConfig,
86
- globalConfig
178
+ ...globalConfigs
87
179
  ];
88
180
  }, "qoder")
89
181
  };
@@ -106,7 +198,12 @@ function detectAIClients(options = {}) {
106
198
  const clients = [];
107
199
  const seenPaths = /* @__PURE__ */ new Set();
108
200
  for (const [name, getPaths] of Object.entries(CLIENT_CONFIGS)) {
109
- const paths = getPaths(home, cwd);
201
+ const candidates = getPaths(home, cwd);
202
+ const cachedPath = getCachedPath(name);
203
+ const paths = cachedPath && candidates.includes(cachedPath) ? [
204
+ cachedPath,
205
+ ...candidates.filter((p) => p !== cachedPath)
206
+ ] : candidates;
110
207
  for (const configPath of paths) {
111
208
  if (seenPaths.has(configPath)) {
112
209
  continue;
@@ -115,6 +212,7 @@ function detectAIClients(options = {}) {
115
212
  const exists = existsSync(configPath);
116
213
  let hasSnapback = false;
117
214
  if (exists) {
215
+ setCachedPath(name, configPath);
118
216
  try {
119
217
  const content = readFileSync(configPath, "utf-8");
120
218
  if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
@@ -169,12 +267,17 @@ function checkForSnapback(config, format) {
169
267
  case "windsurf":
170
268
  case "cline":
171
269
  case "roo-code":
172
- case "qoder":
173
270
  if ("mcpServers" in configObj && typeof configObj.mcpServers === "object" && configObj.mcpServers !== null) {
174
271
  const servers = configObj.mcpServers;
175
272
  return "snapback" in servers || `snapback-${format}` in servers;
176
273
  }
177
274
  return false;
275
+ case "qoder":
276
+ if ("mcpServers" in configObj && typeof configObj.mcpServers === "object" && configObj.mcpServers !== null) {
277
+ const servers = configObj.mcpServers;
278
+ return Object.keys(servers).some((k) => k === "snapback" || k.startsWith("snapback-"));
279
+ }
280
+ return false;
178
281
  case "vscode":
179
282
  if ("servers" in configObj && typeof configObj.servers === "object" && configObj.servers !== null) {
180
283
  const servers = configObj.servers;
@@ -771,6 +874,32 @@ function resolveNodePath() {
771
874
  }
772
875
  __name(resolveNodePath, "resolveNodePath");
773
876
  __name2(resolveNodePath, "resolveNodePath");
877
+ function resolveSnapbackBinaryPath() {
878
+ try {
879
+ const isWindows = process.platform === "win32";
880
+ const command = isWindows ? "where snapback" : "which snapback";
881
+ const result = execSync(command, {
882
+ encoding: "utf-8",
883
+ timeout: 5e3
884
+ }).trim();
885
+ const binaryPath = result.split(/\r?\n/)[0].trim();
886
+ if (binaryPath && existsSync(binaryPath)) {
887
+ return binaryPath;
888
+ }
889
+ } catch {
890
+ }
891
+ const commonPaths = [
892
+ "/opt/homebrew/bin/snapback",
893
+ "/usr/local/bin/snapback",
894
+ "/usr/bin/snapback"
895
+ ];
896
+ for (const p of commonPaths) {
897
+ if (existsSync(p)) return p;
898
+ }
899
+ return "snapback";
900
+ }
901
+ __name(resolveSnapbackBinaryPath, "resolveSnapbackBinaryPath");
902
+ __name2(resolveSnapbackBinaryPath, "resolveSnapbackBinaryPath");
774
903
  function isCommandExecutable2(command) {
775
904
  if (command.startsWith("/") || command.match(/^[A-Z]:\\/i)) {
776
905
  return existsSync(command);
@@ -793,14 +922,11 @@ var STDIO_ONLY_CLIENTS = /* @__PURE__ */ new Set([
793
922
  "claude"
794
923
  ]);
795
924
  function getSnapbackMCPConfig(options = {}) {
796
- const { apiKey, workspaceId, serverUrl, useBinary = false, customCommand, additionalEnv, workspaceRoot, useLocalDev = false, localCliPath, client } = options;
925
+ const { apiKey, workspaceId, serverUrl, useBinary = false, customCommand, additionalEnv, workspaceRoot, useLocalDev = false, localCliPath, client, useDoppler = false, dopplerProject = "snapback-shared", dopplerConfig = "dev", useSse = false, useStreamableHttp = false } = options;
797
926
  const useNpx = options.useNpx ?? (client ? STDIO_ONLY_CLIENTS.has(client) : false);
798
927
  const env = {
799
928
  ...additionalEnv
800
929
  };
801
- if (workspaceId) {
802
- env.SNAPBACK_WORKSPACE_ID = workspaceId;
803
- }
804
930
  if (apiKey) {
805
931
  env.SNAPBACK_API_KEY = apiKey;
806
932
  }
@@ -813,9 +939,65 @@ function getSnapbackMCPConfig(options = {}) {
813
939
  }
814
940
  };
815
941
  }
942
+ if (useSse || useStreamableHttp) {
943
+ const url = serverUrl || "https://mcp.snapback.dev/mcp";
944
+ const headers2 = {};
945
+ if (workspaceId) {
946
+ headers2["x-workspace-id"] = workspaceId;
947
+ }
948
+ if (apiKey) {
949
+ headers2["x-api-key"] = apiKey;
950
+ }
951
+ return {
952
+ url,
953
+ ...Object.keys(headers2).length > 0 && {
954
+ headers: headers2
955
+ }
956
+ };
957
+ }
958
+ if (useDoppler && localCliPath) {
959
+ const tier = apiKey ? "pro" : "free";
960
+ const nodePath = resolveNodePath();
961
+ const dopplerArgs = [
962
+ "run",
963
+ "--project",
964
+ dopplerProject,
965
+ "--config",
966
+ dopplerConfig,
967
+ "--",
968
+ nodePath,
969
+ localCliPath,
970
+ "mcp",
971
+ "--stdio",
972
+ "--tier",
973
+ tier
974
+ ];
975
+ if (workspaceRoot) {
976
+ dopplerArgs.push("--workspace", workspaceRoot);
977
+ }
978
+ return {
979
+ command: "doppler",
980
+ args: dopplerArgs
981
+ };
982
+ }
816
983
  if (useNpx) {
984
+ const isClaudeDesktop = client === "claude";
985
+ if (isClaudeDesktop) {
986
+ const args2 = [
987
+ "--yes",
988
+ "@snapback/mcpb"
989
+ ];
990
+ if (workspaceRoot) {
991
+ args2.push(workspaceRoot);
992
+ }
993
+ return {
994
+ command: "npx",
995
+ args: args2
996
+ };
997
+ }
817
998
  const tier = apiKey ? "pro" : "free";
818
999
  const args = [
1000
+ "--yes",
819
1001
  "@snapback/cli",
820
1002
  "mcp",
821
1003
  "--stdio",
@@ -833,12 +1015,19 @@ function getSnapbackMCPConfig(options = {}) {
833
1015
  }
834
1016
  };
835
1017
  }
836
- if (serverUrl || !useLocalDev && !useBinary) {
837
- const url = serverUrl || "https://snapback-mcp.fly.dev";
1018
+ if (serverUrl || !useLocalDev && !useBinary && !useDoppler) {
1019
+ const url = serverUrl || "https://mcp.snapback.dev/mcp";
1020
+ const headers2 = {};
1021
+ if (workspaceId) {
1022
+ headers2["x-workspace-id"] = workspaceId;
1023
+ }
1024
+ if (apiKey) {
1025
+ headers2["x-api-key"] = apiKey;
1026
+ }
838
1027
  return {
839
1028
  url,
840
- ...Object.keys(env).length > 0 && {
841
- env
1029
+ ...Object.keys(headers2).length > 0 && {
1030
+ headers: headers2
842
1031
  }
843
1032
  };
844
1033
  }
@@ -875,17 +1064,24 @@ function getSnapbackMCPConfig(options = {}) {
875
1064
  args.push("--workspace", workspaceRoot);
876
1065
  }
877
1066
  return {
878
- command: "snapback",
1067
+ command: resolveSnapbackBinaryPath(),
879
1068
  args,
880
1069
  ...Object.keys(env).length > 0 && {
881
1070
  env
882
1071
  }
883
1072
  };
884
1073
  }
1074
+ const headers = {};
1075
+ if (workspaceId) {
1076
+ headers["x-workspace-id"] = workspaceId;
1077
+ }
1078
+ if (apiKey) {
1079
+ headers["x-api-key"] = apiKey;
1080
+ }
885
1081
  return {
886
- url: "https://snapback-mcp.fly.dev",
887
- ...Object.keys(env).length > 0 && {
888
- env
1082
+ url: "https://mcp.snapback.dev/mcp",
1083
+ ...Object.keys(headers).length > 0 && {
1084
+ headers
889
1085
  }
890
1086
  };
891
1087
  }
@@ -986,6 +1182,7 @@ function removeSnapbackConfig(client) {
986
1182
  }
987
1183
  }
988
1184
  writeFileSync(client.configPath, JSON.stringify(config, null, 2));
1185
+ evictCachedPath(client.name);
989
1186
  return {
990
1187
  success: true
991
1188
  };
@@ -1033,17 +1230,25 @@ function mergeConfig(existing, snapbackConfig, format) {
1033
1230
  }
1034
1231
  }
1035
1232
  };
1036
- case "qoder":
1233
+ case "qoder": {
1234
+ let qoderType;
1235
+ if (snapbackConfig.url) {
1236
+ const isLocal = snapbackConfig.url.startsWith("http://localhost") || snapbackConfig.url.startsWith("http://127.0.0.1");
1237
+ qoderType = isLocal ? "sse" : "http";
1238
+ } else {
1239
+ qoderType = "stdio";
1240
+ }
1037
1241
  return {
1038
1242
  ...existing,
1039
1243
  mcpServers: {
1040
1244
  ...existing.mcpServers || {},
1041
1245
  [serverKey]: {
1042
- type: "stdio",
1246
+ type: qoderType,
1043
1247
  ...snapbackConfig
1044
1248
  }
1045
1249
  }
1046
1250
  };
1251
+ }
1047
1252
  case "vscode": {
1048
1253
  const vscodeConfig = existing;
1049
1254
  const servers = vscodeConfig.servers || {};
@@ -1105,6 +1310,87 @@ function mergeConfig(existing, snapbackConfig, format) {
1105
1310
  }
1106
1311
  __name(mergeConfig, "mergeConfig");
1107
1312
  __name2(mergeConfig, "mergeConfig");
1313
+ function patchApiKeyInClientConfig(client, apiKey) {
1314
+ try {
1315
+ if (!existsSync(client.configPath)) return false;
1316
+ const raw = readFileSync(client.configPath, "utf-8");
1317
+ const config = JSON.parse(raw);
1318
+ const serverKey = getServerKey(client.format);
1319
+ let patched = false;
1320
+ const patchEntry = /* @__PURE__ */ __name2((entry) => {
1321
+ if (typeof entry !== "object" || entry === null) return false;
1322
+ const e = entry;
1323
+ if (e.url && typeof e.url === "string") {
1324
+ if (!e.headers || typeof e.headers !== "object") {
1325
+ e.headers = {};
1326
+ }
1327
+ e.headers["x-api-key"] = apiKey;
1328
+ const headers = e.headers;
1329
+ if (headers.Authorization?.includes("<your-token>")) {
1330
+ delete headers.Authorization;
1331
+ }
1332
+ return true;
1333
+ }
1334
+ if (!e.env || typeof e.env !== "object") {
1335
+ e.env = {};
1336
+ }
1337
+ e.env.SNAPBACK_API_KEY = apiKey;
1338
+ return true;
1339
+ }, "patchEntry");
1340
+ switch (client.format) {
1341
+ case "claude":
1342
+ case "cursor":
1343
+ case "windsurf":
1344
+ case "cline":
1345
+ case "roo-code":
1346
+ case "gemini": {
1347
+ const servers = config.mcpServers || {};
1348
+ const entry = servers[serverKey] ?? servers.snapback;
1349
+ if (entry) patched = patchEntry(entry);
1350
+ break;
1351
+ }
1352
+ case "qoder": {
1353
+ const servers = config.mcpServers || {};
1354
+ for (const key of Object.keys(servers)) {
1355
+ if (key === "snapback" || key.startsWith("snapback-")) {
1356
+ patched = patchEntry(servers[key]) || patched;
1357
+ }
1358
+ }
1359
+ break;
1360
+ }
1361
+ case "vscode": {
1362
+ const servers = config.servers || {};
1363
+ const entry = servers[serverKey] ?? servers.snapback;
1364
+ if (entry) patched = patchEntry(entry);
1365
+ break;
1366
+ }
1367
+ case "zed": {
1368
+ const servers = config.context_servers || {};
1369
+ const entry = servers[serverKey] ?? servers.snapback;
1370
+ if (entry) patched = patchEntry(entry);
1371
+ break;
1372
+ }
1373
+ case "continue": {
1374
+ const exp = config.experimental || {};
1375
+ const list = exp.modelContextProtocolServers || [];
1376
+ for (const item of list) {
1377
+ if (typeof item.name === "string" && item.name.startsWith("snapback")) {
1378
+ patched = patchEntry(item) || patched;
1379
+ }
1380
+ }
1381
+ break;
1382
+ }
1383
+ }
1384
+ if (patched) {
1385
+ writeFileSync(client.configPath, JSON.stringify(config, null, 2));
1386
+ }
1387
+ return patched;
1388
+ } catch {
1389
+ return false;
1390
+ }
1391
+ }
1392
+ __name(patchApiKeyInClientConfig, "patchApiKeyInClientConfig");
1393
+ __name2(patchApiKeyInClientConfig, "patchApiKeyInClientConfig");
1108
1394
  function validateConfig(client) {
1109
1395
  try {
1110
1396
  const content = readFileSync(client.configPath, "utf-8");
@@ -1418,6 +1704,4 @@ function findCliPath() {
1418
1704
  __name(findCliPath, "findCliPath");
1419
1705
  __name2(findCliPath, "findCliPath");
1420
1706
 
1421
- export { createManagedMetadata, detectAIClients, detectMCPProcesses, detectWorkspaceConfig, getClient, getClientConfigPath, getConfiguredClients, getOrCreateIdentity, getServerKey, getSnapbackConfigDir, getSnapbackMCPConfig, injectWorkspacePath, isCommandExecutable2, isOwnedByThisInstall, isSnapbackMCPRunning, readClientConfig, removeSnapbackConfig, repairClientConfig, resetIdentityCache, resolveNodePath, validateClientConfig, validateConfig, validateWorkspacePath, writeClientConfig };
1422
- //# sourceMappingURL=chunk-R7CUQ7CU.js.map
1423
- //# sourceMappingURL=chunk-R7CUQ7CU.js.map
1707
+ export { createManagedMetadata, detectAIClients, detectMCPProcesses, detectWorkspaceConfig, evictCachedPath, getAllCachedPaths, getCachedPath, getClient, getClientConfigPath, getConfiguredClients, getOrCreateIdentity, getServerKey, getSnapbackConfigDir, getSnapbackMCPConfig, injectWorkspacePath, isCommandExecutable2, isOwnedByThisInstall, isSnapbackMCPRunning, patchApiKeyInClientConfig, readClientConfig, removeSnapbackConfig, repairClientConfig, resetIdentityCache, resolveNodePath, setCachedPath, validateClientConfig, validateConfig, validateWorkspacePath, writeClientConfig };