@snapback/cli 1.6.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +121 -22
  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-UA7I3YE4.js +1446 -0
  7. package/dist/auto-provision-organization-6YF463TK.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-BE3HNVSV.js +2300 -0
  13. package/dist/chunk-BWWPGNZ5.js +5842 -0
  14. package/dist/chunk-CBGOC6RV.js +293 -0
  15. package/dist/{chunk-7JX6Y4TL.js → chunk-DPWFZNMY.js} +21 -34
  16. package/dist/{chunk-R7CUQ7CU.js → chunk-E6V6QKS7.js} +317 -33
  17. package/dist/chunk-GT4ZUCFR.js +111 -0
  18. package/dist/chunk-NOWJBG6X.js +3654 -0
  19. package/dist/chunk-O7HMAZ7L.js +3497 -0
  20. package/dist/chunk-PL4HF4M2.js +593 -0
  21. package/dist/chunk-V7B37PPD.js +4075 -0
  22. package/dist/chunk-YVZXPBSV.js +314 -0
  23. package/dist/chunk-ZBQDE6WJ.js +108 -0
  24. package/dist/client-RHDS6NOB.js +8 -0
  25. package/dist/dist-5LR7APG5.js +5 -0
  26. package/dist/dist-CUHOKNLS.js +12 -0
  27. package/dist/dist-RJE4RSZJ.js +9 -0
  28. package/dist/index.js +60568 -36578
  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,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 };
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node --no-warnings=ExperimentalWarning
2
+ import { logger } from './chunk-PL4HF4M2.js';
3
+ import { __name } from './chunk-7ADPL4Q3.js';
4
+
5
+ process.env.SNAPBACK_CLI='true';
6
+
7
+ // ../../packages/auth/dist/lib/audit.js
8
+ var POSTHOG_API_KEY = process.env.POSTHOG_API_KEY || "";
9
+ var POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.posthog.com";
10
+ var POSTHOG_ENABLED = !!POSTHOG_API_KEY;
11
+ async function emitPostHogEvent(eventType, metadata) {
12
+ if (!POSTHOG_ENABLED) {
13
+ return;
14
+ }
15
+ try {
16
+ const event = {
17
+ api_key: POSTHOG_API_KEY,
18
+ event: eventType,
19
+ distinct_id: metadata.userId || metadata.ip || "anonymous",
20
+ properties: {
21
+ ...metadata,
22
+ $ip: metadata.ip,
23
+ $set: {
24
+ email: metadata.userId ? `user_${metadata.userId}` : void 0
25
+ }
26
+ },
27
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
28
+ };
29
+ const response = await fetch(`${POSTHOG_HOST}/capture/`, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json"
33
+ },
34
+ body: JSON.stringify(event)
35
+ });
36
+ if (!response.ok) {
37
+ logger.error("Failed to emit PostHog event", {
38
+ eventType,
39
+ status: response.status,
40
+ statusText: response.statusText
41
+ });
42
+ }
43
+ } catch (error) {
44
+ logger.error("Error emitting PostHog event", {
45
+ error,
46
+ eventType
47
+ });
48
+ }
49
+ }
50
+ __name(emitPostHogEvent, "emitPostHogEvent");
51
+ async function writeAuditLog(eventType, metadata) {
52
+ try {
53
+ const { db, snapbackSchema } = await import('./dist-CUHOKNLS.js');
54
+ if (!db) {
55
+ logger.warn("Database not available for audit logging", {
56
+ eventType
57
+ });
58
+ return;
59
+ }
60
+ const { telemetryEvents } = snapbackSchema;
61
+ await db.insert(telemetryEvents).values({
62
+ eventType,
63
+ eventCategory: "audit",
64
+ userId: metadata.userId,
65
+ properties: {
66
+ ip: metadata.ip,
67
+ userAgent: metadata.userAgent,
68
+ method: metadata.method,
69
+ path: metadata.path,
70
+ statusCode: metadata.statusCode,
71
+ errorMessage: metadata.errorMessage,
72
+ ...metadata
73
+ }
74
+ });
75
+ logger.debug("Audit log written", {
76
+ eventType,
77
+ userId: metadata.userId,
78
+ orgId: metadata.orgId
79
+ });
80
+ } catch (error) {
81
+ logger.error("Failed to write audit log", {
82
+ error,
83
+ eventType,
84
+ metadata
85
+ });
86
+ }
87
+ }
88
+ __name(writeAuditLog, "writeAuditLog");
89
+ async function trackEvent(eventType, metadata) {
90
+ logger.info("Audit event", {
91
+ eventType,
92
+ userId: metadata.userId,
93
+ orgId: metadata.orgId,
94
+ path: metadata.path
95
+ });
96
+ emitPostHogEvent(eventType, metadata).catch((error) => {
97
+ logger.error("PostHog emit failed", {
98
+ error,
99
+ eventType
100
+ });
101
+ });
102
+ writeAuditLog(eventType, metadata).catch((error) => {
103
+ logger.error("Audit log write failed", {
104
+ error,
105
+ eventType
106
+ });
107
+ });
108
+ }
109
+ __name(trackEvent, "trackEvent");
110
+
111
+ export { trackEvent };