@vreko/cli 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.
- package/LICENSE +201 -0
- package/README.md +45 -0
- package/dist/CeremonyView-LQS7FTMK.js +134 -0
- package/dist/CeremonyView-LQS7FTMK.js.map +1 -0
- package/dist/InitApp-7K5DTYSW.js +1479 -0
- package/dist/InitApp-7K5DTYSW.js.map +1 -0
- package/dist/SkippedTestDetector-PJSKSOZR.js +7 -0
- package/dist/SkippedTestDetector-PJSKSOZR.js.map +1 -0
- package/dist/TuiApp-FX23XQBK.js +8 -0
- package/dist/TuiApp-FX23XQBK.js.map +1 -0
- package/dist/analysis-ABEO6RTN.js +8 -0
- package/dist/analysis-ABEO6RTN.js.map +1 -0
- package/dist/auth-XNBEBNPY.js +7669 -0
- package/dist/auth-XNBEBNPY.js.map +1 -0
- package/dist/ceremony-M7CXVBVA.js +45 -0
- package/dist/ceremony-M7CXVBVA.js.map +1 -0
- package/dist/chunk-A3QSZJPD.js +3147 -0
- package/dist/chunk-A3QSZJPD.js.map +1 -0
- package/dist/chunk-ASGZ5B6C.js +3969 -0
- package/dist/chunk-ASGZ5B6C.js.map +1 -0
- package/dist/chunk-DMXC2JTC.js +58 -0
- package/dist/chunk-DMXC2JTC.js.map +1 -0
- package/dist/chunk-EEBSK2IH.js +161 -0
- package/dist/chunk-EEBSK2IH.js.map +1 -0
- package/dist/chunk-EWOJGXRX.js +22 -0
- package/dist/chunk-EWOJGXRX.js.map +1 -0
- package/dist/chunk-F7GEJLP7.js +2389 -0
- package/dist/chunk-F7GEJLP7.js.map +1 -0
- package/dist/chunk-GOYL3F4T.js +605 -0
- package/dist/chunk-GOYL3F4T.js.map +1 -0
- package/dist/chunk-GRMRYWYS.js +17 -0
- package/dist/chunk-GRMRYWYS.js.map +1 -0
- package/dist/chunk-GSUGROXB.js +1951 -0
- package/dist/chunk-GSUGROXB.js.map +1 -0
- package/dist/chunk-H7773ONB.js +50 -0
- package/dist/chunk-H7773ONB.js.map +1 -0
- package/dist/chunk-HFQHU5LC.js +445 -0
- package/dist/chunk-HFQHU5LC.js.map +1 -0
- package/dist/chunk-IVHUBLJD.js +318 -0
- package/dist/chunk-IVHUBLJD.js.map +1 -0
- package/dist/chunk-KJWKY4L4.js +14 -0
- package/dist/chunk-KJWKY4L4.js.map +1 -0
- package/dist/chunk-MJVY2XUN.js +1793 -0
- package/dist/chunk-MJVY2XUN.js.map +1 -0
- package/dist/chunk-QWZVCJII.js +1797 -0
- package/dist/chunk-QWZVCJII.js.map +1 -0
- package/dist/chunk-VTSNRV3V.js +3237 -0
- package/dist/chunk-VTSNRV3V.js.map +1 -0
- package/dist/chunk-W5B4GTXR.js +1466 -0
- package/dist/chunk-W5B4GTXR.js.map +1 -0
- package/dist/chunk-WZEZLVOW.js +4995 -0
- package/dist/chunk-WZEZLVOW.js.map +1 -0
- package/dist/chunk-YPTTIXKC.js +199 -0
- package/dist/chunk-YPTTIXKC.js.map +1 -0
- package/dist/chunk-Z55UGM6X.js +6360 -0
- package/dist/chunk-Z55UGM6X.js.map +1 -0
- package/dist/chunk-ZIIRQODJ.js +110 -0
- package/dist/chunk-ZIIRQODJ.js.map +1 -0
- package/dist/chunk-ZSUQ4FMB.js +77 -0
- package/dist/chunk-ZSUQ4FMB.js.map +1 -0
- package/dist/client-JMTSZS3V.js +10 -0
- package/dist/client-JMTSZS3V.js.map +1 -0
- package/dist/deprecated-snap.js +19 -0
- package/dist/deprecated-snap.js.map +1 -0
- package/dist/dist-2KWBZFLA.js +14 -0
- package/dist/dist-2KWBZFLA.js.map +1 -0
- package/dist/dist-5ZYKNNU3.js +7 -0
- package/dist/dist-5ZYKNNU3.js.map +1 -0
- package/dist/dist-CP3RFHPI.js +11 -0
- package/dist/dist-CP3RFHPI.js.map +1 -0
- package/dist/gecko-53ITAGG6.js +56 -0
- package/dist/gecko-53ITAGG6.js.map +1 -0
- package/dist/guards-QAFC64NO.js +7 -0
- package/dist/guards-QAFC64NO.js.map +1 -0
- package/dist/index.js +57785 -0
- package/dist/index.js.map +1 -0
- package/dist/init-command-246JIVXM.js +7 -0
- package/dist/init-command-246JIVXM.js.map +1 -0
- package/dist/init-core-KAI7LCXZ.js +12 -0
- package/dist/init-core-KAI7LCXZ.js.map +1 -0
- package/dist/init-scan-RZNYDTUV.js +1919 -0
- package/dist/init-scan-RZNYDTUV.js.map +1 -0
- package/dist/local-service-adapter-6KNN6WQL.js +8 -0
- package/dist/local-service-adapter-6KNN6WQL.js.map +1 -0
- package/dist/secure-credentials-JXWAQLS2.js +306 -0
- package/dist/secure-credentials-JXWAQLS2.js.map +1 -0
- package/dist/tui-TPJPUS2R.js +111 -0
- package/dist/tui-TPJPUS2R.js.map +1 -0
- package/dist/vreko-dir-O3RLG7PI.js +8 -0
- package/dist/vreko-dir-O3RLG7PI.js.map +1 -0
- package/package.json +132 -0
- package/scripts/check-banned-words.ts +152 -0
- package/scripts/hooks/posttooluse-file-notify.sh +108 -0
- package/scripts/hooks/pretooluse-fragile-guard.sh +82 -0
- package/scripts/post-install-notice.js +24 -0
- package/scripts/postinstall.mjs +84 -0
- package/scripts/preuninstall.mjs +34 -0
- package/scripts/verify-jsx-transform.mjs +55 -0
|
@@ -0,0 +1,1793 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name } from './chunk-EWOJGXRX.js';
|
|
3
|
+
import { readFileSync, mkdirSync, writeFileSync, existsSync, statSync, copyFileSync } from 'fs';
|
|
4
|
+
import { homedir, platform } from 'os';
|
|
5
|
+
import { join, resolve, dirname } from 'path';
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
7
|
+
import { exec, execSync } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
|
|
10
|
+
process.env.VREKO_CLI='true';process.env.NODE_NO_WARNINGS='1';
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp(target, "name", {
|
|
13
|
+
value,
|
|
14
|
+
configurable: true
|
|
15
|
+
}), "__name");
|
|
16
|
+
var CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
17
|
+
function getCacheFilePath() {
|
|
18
|
+
return join(homedir(), ".vreko", "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(), ".vreko", "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) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const age = Date.now() - new Date(entry.discoveredAt).getTime();
|
|
57
|
+
if (age > CACHE_TTL_MS) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (!existsSync(entry.path)) {
|
|
61
|
+
delete cache.discovered[clientName];
|
|
62
|
+
writeCache(cache);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return entry.path;
|
|
66
|
+
}
|
|
67
|
+
__name(getCachedPath, "getCachedPath");
|
|
68
|
+
__name2(getCachedPath, "getCachedPath");
|
|
69
|
+
function setCachedPath(clientName, configPath) {
|
|
70
|
+
const cache = readCache();
|
|
71
|
+
cache.discovered[clientName] = {
|
|
72
|
+
path: configPath,
|
|
73
|
+
discoveredAt: /* @__PURE__ */ (/* @__PURE__ */ new Date()).toISOString(),
|
|
74
|
+
platform: process.platform
|
|
75
|
+
};
|
|
76
|
+
writeCache(cache);
|
|
77
|
+
}
|
|
78
|
+
__name(setCachedPath, "setCachedPath");
|
|
79
|
+
__name2(setCachedPath, "setCachedPath");
|
|
80
|
+
function evictCachedPath(clientName) {
|
|
81
|
+
const cache = readCache();
|
|
82
|
+
if (cache.discovered[clientName]) {
|
|
83
|
+
delete cache.discovered[clientName];
|
|
84
|
+
writeCache(cache);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
__name(evictCachedPath, "evictCachedPath");
|
|
88
|
+
__name2(evictCachedPath, "evictCachedPath");
|
|
89
|
+
function getAllCachedPaths() {
|
|
90
|
+
return readCache().discovered;
|
|
91
|
+
}
|
|
92
|
+
__name(getAllCachedPaths, "getAllCachedPaths");
|
|
93
|
+
__name2(getAllCachedPaths, "getAllCachedPaths");
|
|
94
|
+
var CLIENT_CONFIGS = {
|
|
95
|
+
claude: /* @__PURE__ */ __name2((home) => {
|
|
96
|
+
switch (platform()) {
|
|
97
|
+
case "darwin":
|
|
98
|
+
return [
|
|
99
|
+
join(home, "Library/Application Support/Claude/claude_desktop_config.json")
|
|
100
|
+
];
|
|
101
|
+
case "win32":
|
|
102
|
+
return [
|
|
103
|
+
join(process.env.APPDATA || "", "Claude/claude_desktop_config.json")
|
|
104
|
+
];
|
|
105
|
+
default:
|
|
106
|
+
return [
|
|
107
|
+
join(home, ".config/Claude/claude_desktop_config.json")
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
}, "claude"),
|
|
111
|
+
// Project-level first (user preference), then global fallback
|
|
112
|
+
cursor: /* @__PURE__ */ __name2((_home, cwd) => [
|
|
113
|
+
...cwd ? [
|
|
114
|
+
join(cwd, ".cursor/mcp.json")
|
|
115
|
+
] : [],
|
|
116
|
+
join(_home, ".cursor/mcp.json")
|
|
117
|
+
], "cursor"),
|
|
118
|
+
// Windsurf only has a global config - no project-level support (confirmed by Windsurf docs, June 2025)
|
|
119
|
+
windsurf: /* @__PURE__ */ __name2((home) => [
|
|
120
|
+
join(home, ".codeium/windsurf/mcp_config.json")
|
|
121
|
+
], "windsurf"),
|
|
122
|
+
// Continue: global config.json or config.yaml; project-level .continue/mcpServers/mcp.json
|
|
123
|
+
continue: /* @__PURE__ */ __name2((home, cwd) => [
|
|
124
|
+
...cwd ? [
|
|
125
|
+
join(cwd, ".continue/mcpServers/mcp.json")
|
|
126
|
+
] : [],
|
|
127
|
+
join(home, ".continue/config.json"),
|
|
128
|
+
join(home, ".continue/config.yaml")
|
|
129
|
+
], "continue"),
|
|
130
|
+
// New clients
|
|
131
|
+
vscode: /* @__PURE__ */ __name2((_home, cwd) => [
|
|
132
|
+
...cwd ? [
|
|
133
|
+
join(cwd, ".vscode/mcp.json")
|
|
134
|
+
] : []
|
|
135
|
+
], "vscode"),
|
|
136
|
+
// Zed: global ~/.config/zed/settings.json, plus project-level .zed/settings.json
|
|
137
|
+
zed: /* @__PURE__ */ __name2((home, cwd) => [
|
|
138
|
+
...cwd ? [
|
|
139
|
+
join(cwd, ".zed/settings.json")
|
|
140
|
+
] : [],
|
|
141
|
+
join(home, ".config/zed/settings.json")
|
|
142
|
+
], "zed"),
|
|
143
|
+
// Cline / Roo Code store their actual settings in VS Code extension globalStorage,
|
|
144
|
+
// but `vreko tools configure --cline/--roo-code` writes to these paths as a side-channel.
|
|
145
|
+
// Detection via these paths is best-effort; users may need `vreko mcp link --client cline` instead.
|
|
146
|
+
cline: /* @__PURE__ */ __name2((home) => [
|
|
147
|
+
join(home, ".cline/mcp.json")
|
|
148
|
+
], "cline"),
|
|
149
|
+
gemini: /* @__PURE__ */ __name2((home) => [
|
|
150
|
+
join(home, ".gemini/settings.json")
|
|
151
|
+
], "gemini"),
|
|
152
|
+
aider: /* @__PURE__ */ __name2((home) => [
|
|
153
|
+
join(home, ".aider/mcp.yaml")
|
|
154
|
+
], "aider"),
|
|
155
|
+
"roo-code": /* @__PURE__ */ __name2((home) => [
|
|
156
|
+
join(home, ".roo-code/mcp.json")
|
|
157
|
+
], "roo-code"),
|
|
158
|
+
// Qoder (VS Code fork) - supports both project-level and global configs
|
|
159
|
+
qoder: /* @__PURE__ */ __name2((home, cwd) => {
|
|
160
|
+
const workspaceConfig = cwd ? [
|
|
161
|
+
join(cwd, ".qoder-mcp-config.json")
|
|
162
|
+
] : [];
|
|
163
|
+
const globalConfigs = (() => {
|
|
164
|
+
switch (platform()) {
|
|
165
|
+
case "darwin":
|
|
166
|
+
return [
|
|
167
|
+
join(home, "Library/Application Support/Qoder/SharedClientCache/mcp.json"),
|
|
168
|
+
join(home, "Library/Application Support/Qoder/SharedClientCache/extension/local/mcp.json")
|
|
169
|
+
];
|
|
170
|
+
case "win32":
|
|
171
|
+
return [
|
|
172
|
+
join(process.env.APPDATA || "", "Qoder/mcp.json")
|
|
173
|
+
];
|
|
174
|
+
default:
|
|
175
|
+
return [
|
|
176
|
+
join(home, ".config/Qoder/mcp.json")
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
})();
|
|
180
|
+
return [
|
|
181
|
+
...workspaceConfig,
|
|
182
|
+
...globalConfigs
|
|
183
|
+
];
|
|
184
|
+
}, "qoder"),
|
|
185
|
+
// Claude Code CLI - project-scoped .mcp.json at workspace root
|
|
186
|
+
"claude-code": /* @__PURE__ */ __name2((_home, cwd) => [
|
|
187
|
+
...cwd ? [
|
|
188
|
+
join(cwd, ".mcp.json")
|
|
189
|
+
] : [
|
|
190
|
+
join(process.cwd(), ".mcp.json")
|
|
191
|
+
]
|
|
192
|
+
], "claude-code")
|
|
193
|
+
};
|
|
194
|
+
var CLIENT_DISPLAY_NAMES = {
|
|
195
|
+
claude: "Claude Desktop",
|
|
196
|
+
cursor: "Cursor",
|
|
197
|
+
windsurf: "Windsurf",
|
|
198
|
+
continue: "Continue",
|
|
199
|
+
vscode: "VS Code",
|
|
200
|
+
zed: "Zed",
|
|
201
|
+
cline: "Cline",
|
|
202
|
+
gemini: "Gemini/Antigravity",
|
|
203
|
+
aider: "Aider",
|
|
204
|
+
"roo-code": "Roo Code",
|
|
205
|
+
qoder: "Qoder",
|
|
206
|
+
"claude-code": "Claude Code"
|
|
207
|
+
};
|
|
208
|
+
var UNSUPPORTED_DEFAULT_INIT_CLIENTS = /* @__PURE__ */ new Set([
|
|
209
|
+
"zed",
|
|
210
|
+
"continue"
|
|
211
|
+
]);
|
|
212
|
+
function hasVrekoServerName(name, format) {
|
|
213
|
+
if (name === "vreko") {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
if (format && name === `vreko-${format}`) {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
return name.startsWith("vreko-");
|
|
220
|
+
}
|
|
221
|
+
__name(hasVrekoServerName, "hasVrekoServerName");
|
|
222
|
+
__name2(hasVrekoServerName, "hasVrekoServerName");
|
|
223
|
+
function detectAIClients(options = {}) {
|
|
224
|
+
const home = homedir();
|
|
225
|
+
const cwd = options.cwd || process.cwd();
|
|
226
|
+
const clients = [];
|
|
227
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
228
|
+
for (const [name, getPaths] of Object.entries(CLIENT_CONFIGS)) {
|
|
229
|
+
const candidates = getPaths(home, cwd);
|
|
230
|
+
const cachedPath = getCachedPath(name);
|
|
231
|
+
const paths = cachedPath && candidates.includes(cachedPath) ? [
|
|
232
|
+
cachedPath,
|
|
233
|
+
...candidates.filter((p) => p !== cachedPath)
|
|
234
|
+
] : candidates;
|
|
235
|
+
for (const configPath of paths) {
|
|
236
|
+
if (seenPaths.has(configPath)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
seenPaths.add(configPath);
|
|
240
|
+
const exists = existsSync(configPath);
|
|
241
|
+
let hasVreko = false;
|
|
242
|
+
if (exists) {
|
|
243
|
+
setCachedPath(name, configPath);
|
|
244
|
+
try {
|
|
245
|
+
const content = readFileSync(configPath, "utf-8");
|
|
246
|
+
if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
|
|
247
|
+
hasVreko = content.includes("vreko");
|
|
248
|
+
} else {
|
|
249
|
+
const parsed = JSON.parse(content);
|
|
250
|
+
hasVreko = checkForVreko(parsed, name);
|
|
251
|
+
}
|
|
252
|
+
} catch {
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
clients.push({
|
|
256
|
+
name,
|
|
257
|
+
displayName: CLIENT_DISPLAY_NAMES[name] || name,
|
|
258
|
+
configPath,
|
|
259
|
+
exists,
|
|
260
|
+
hasVreko,
|
|
261
|
+
format: name
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const detected = clients.filter((c) => c.exists);
|
|
266
|
+
const needsSetup = detected.filter((c) => !c.hasVreko && !UNSUPPORTED_DEFAULT_INIT_CLIENTS.has(c.name));
|
|
267
|
+
return {
|
|
268
|
+
clients,
|
|
269
|
+
detected,
|
|
270
|
+
needsSetup
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
__name(detectAIClients, "detectAIClients");
|
|
274
|
+
__name2(detectAIClients, "detectAIClients");
|
|
275
|
+
function getClient(clientName) {
|
|
276
|
+
const result = detectAIClients();
|
|
277
|
+
return result.clients.find((c) => c.name === clientName && c.exists);
|
|
278
|
+
}
|
|
279
|
+
__name(getClient, "getClient");
|
|
280
|
+
__name2(getClient, "getClient");
|
|
281
|
+
function getConfiguredClients() {
|
|
282
|
+
const result = detectAIClients();
|
|
283
|
+
return result.detected.filter((c) => c.hasVreko);
|
|
284
|
+
}
|
|
285
|
+
__name(getConfiguredClients, "getConfiguredClients");
|
|
286
|
+
__name2(getConfiguredClients, "getConfiguredClients");
|
|
287
|
+
function checkForVreko(config, format) {
|
|
288
|
+
if (!config || typeof config !== "object") {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
const configObj = config;
|
|
292
|
+
switch (format) {
|
|
293
|
+
case "claude":
|
|
294
|
+
case "cursor":
|
|
295
|
+
case "windsurf":
|
|
296
|
+
case "cline":
|
|
297
|
+
case "roo-code":
|
|
298
|
+
case "claude-code":
|
|
299
|
+
if ("mcpServers" in configObj && typeof configObj.mcpServers === "object" && configObj.mcpServers !== null) {
|
|
300
|
+
const servers = configObj.mcpServers;
|
|
301
|
+
return Object.keys(servers).some((serverName) => hasVrekoServerName(serverName, format));
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
case "qoder":
|
|
305
|
+
if ("mcpServers" in configObj && typeof configObj.mcpServers === "object" && configObj.mcpServers !== null) {
|
|
306
|
+
const servers = configObj.mcpServers;
|
|
307
|
+
return Object.keys(servers).some((k) => hasVrekoServerName(k));
|
|
308
|
+
}
|
|
309
|
+
return false;
|
|
310
|
+
case "vscode":
|
|
311
|
+
if ("servers" in configObj && typeof configObj.servers === "object" && configObj.servers !== null) {
|
|
312
|
+
const servers = configObj.servers;
|
|
313
|
+
return Object.keys(servers).some((serverName) => hasVrekoServerName(serverName, "vscode"));
|
|
314
|
+
}
|
|
315
|
+
return false;
|
|
316
|
+
case "gemini":
|
|
317
|
+
case "zed":
|
|
318
|
+
if ("context_servers" in configObj && typeof configObj.context_servers === "object" && configObj.context_servers !== null) {
|
|
319
|
+
const servers = configObj.context_servers;
|
|
320
|
+
return Object.keys(servers).some((serverName) => hasVrekoServerName(serverName, "zed"));
|
|
321
|
+
}
|
|
322
|
+
if ("mcpServers" in configObj && typeof configObj.mcpServers === "object" && configObj.mcpServers !== null) {
|
|
323
|
+
const servers = configObj.mcpServers;
|
|
324
|
+
return Object.keys(servers).some((serverName) => hasVrekoServerName(serverName, format));
|
|
325
|
+
}
|
|
326
|
+
return false;
|
|
327
|
+
case "continue":
|
|
328
|
+
if ("experimental" in configObj && typeof configObj.experimental === "object" && configObj.experimental !== null) {
|
|
329
|
+
const experimental = configObj.experimental;
|
|
330
|
+
if ("modelContextProtocolServers" in experimental && Array.isArray(experimental.modelContextProtocolServers)) {
|
|
331
|
+
return experimental.modelContextProtocolServers.some((server) => typeof server === "object" && server !== null && typeof server.name === "string" && hasVrekoServerName(server.name));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return false;
|
|
335
|
+
case "aider":
|
|
336
|
+
return false;
|
|
337
|
+
default:
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
__name(checkForVreko, "checkForVreko");
|
|
342
|
+
__name2(checkForVreko, "checkForVreko");
|
|
343
|
+
function getClientConfigPath(clientName, cwd) {
|
|
344
|
+
const getPaths = CLIENT_CONFIGS[clientName];
|
|
345
|
+
if (!getPaths) {
|
|
346
|
+
return void 0;
|
|
347
|
+
}
|
|
348
|
+
const paths = getPaths(homedir(), cwd);
|
|
349
|
+
return paths[0];
|
|
350
|
+
}
|
|
351
|
+
__name(getClientConfigPath, "getClientConfigPath");
|
|
352
|
+
__name2(getClientConfigPath, "getClientConfigPath");
|
|
353
|
+
function readClientConfig(client) {
|
|
354
|
+
try {
|
|
355
|
+
const content = readFileSync(client.configPath, "utf-8");
|
|
356
|
+
return JSON.parse(content);
|
|
357
|
+
} catch {
|
|
358
|
+
return void 0;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
__name(readClientConfig, "readClientConfig");
|
|
362
|
+
__name2(readClientConfig, "readClientConfig");
|
|
363
|
+
function detectWorkspaceConfig(workspaceRoot) {
|
|
364
|
+
const root = workspaceRoot || process.cwd();
|
|
365
|
+
const claudeCodeConfig = join(root, ".mcp.json");
|
|
366
|
+
if (existsSync(claudeCodeConfig)) {
|
|
367
|
+
try {
|
|
368
|
+
const content = readFileSync(claudeCodeConfig, "utf-8");
|
|
369
|
+
if (content.includes("vreko")) {
|
|
370
|
+
return {
|
|
371
|
+
path: claudeCodeConfig,
|
|
372
|
+
type: "claude-code"
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
} catch {
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const qoderConfig = join(root, ".qoder-mcp-config.json");
|
|
379
|
+
if (existsSync(qoderConfig)) {
|
|
380
|
+
try {
|
|
381
|
+
const content = readFileSync(qoderConfig, "utf-8");
|
|
382
|
+
if (content.includes("vreko")) {
|
|
383
|
+
return {
|
|
384
|
+
path: qoderConfig,
|
|
385
|
+
type: "qoder"
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
} catch {
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const cursorConfig = join(root, ".cursor", "mcp.json");
|
|
392
|
+
if (existsSync(cursorConfig)) {
|
|
393
|
+
try {
|
|
394
|
+
const content = readFileSync(cursorConfig, "utf-8");
|
|
395
|
+
if (content.includes("vreko")) {
|
|
396
|
+
return {
|
|
397
|
+
path: cursorConfig,
|
|
398
|
+
type: "cursor"
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const vscodeConfig = join(root, ".vscode", "mcp.json");
|
|
405
|
+
if (existsSync(vscodeConfig)) {
|
|
406
|
+
try {
|
|
407
|
+
const content = readFileSync(vscodeConfig, "utf-8");
|
|
408
|
+
if (content.includes("vreko")) {
|
|
409
|
+
return {
|
|
410
|
+
path: vscodeConfig,
|
|
411
|
+
type: "vscode"
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const windsurfConfig = join(root, ".windsurf", "mcp.json");
|
|
418
|
+
if (existsSync(windsurfConfig)) {
|
|
419
|
+
try {
|
|
420
|
+
const content = readFileSync(windsurfConfig, "utf-8");
|
|
421
|
+
if (content.includes("vreko")) {
|
|
422
|
+
return {
|
|
423
|
+
path: windsurfConfig,
|
|
424
|
+
type: "windsurf"
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
} catch {
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
__name(detectWorkspaceConfig, "detectWorkspaceConfig");
|
|
433
|
+
__name2(detectWorkspaceConfig, "detectWorkspaceConfig");
|
|
434
|
+
function getVrekoConfigDir() {
|
|
435
|
+
const isWindows = process.platform === "win32";
|
|
436
|
+
if (isWindows) {
|
|
437
|
+
return join(process.env.APPDATA || homedir(), "Vreko");
|
|
438
|
+
}
|
|
439
|
+
return join(homedir(), ".vreko");
|
|
440
|
+
}
|
|
441
|
+
__name(getVrekoConfigDir, "getVrekoConfigDir");
|
|
442
|
+
__name2(getVrekoConfigDir, "getVrekoConfigDir");
|
|
443
|
+
function getConfigDirWithMigration() {
|
|
444
|
+
const newDir = getVrekoConfigDir();
|
|
445
|
+
const oldDir = join(homedir(), ".snapback");
|
|
446
|
+
if (!existsSync(newDir) && existsSync(oldDir)) {
|
|
447
|
+
try {
|
|
448
|
+
const stat = statSync(oldDir);
|
|
449
|
+
if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
450
|
+
mkdirSync(newDir, {
|
|
451
|
+
recursive: true
|
|
452
|
+
});
|
|
453
|
+
const oldIdentity = join(oldDir, "identity.json");
|
|
454
|
+
if (existsSync(oldIdentity)) {
|
|
455
|
+
copyFileSync(oldIdentity, join(newDir, "identity.json"));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
} catch {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return newDir;
|
|
462
|
+
}
|
|
463
|
+
__name(getConfigDirWithMigration, "getConfigDirWithMigration");
|
|
464
|
+
__name2(getConfigDirWithMigration, "getConfigDirWithMigration");
|
|
465
|
+
function getIdentityFilePath() {
|
|
466
|
+
return join(getVrekoConfigDir(), "identity.json");
|
|
467
|
+
}
|
|
468
|
+
__name(getIdentityFilePath, "getIdentityFilePath");
|
|
469
|
+
__name2(getIdentityFilePath, "getIdentityFilePath");
|
|
470
|
+
var cachedIdentity = null;
|
|
471
|
+
function getOrCreateIdentity() {
|
|
472
|
+
if (cachedIdentity) {
|
|
473
|
+
return cachedIdentity;
|
|
474
|
+
}
|
|
475
|
+
const identityPath = getIdentityFilePath();
|
|
476
|
+
if (existsSync(identityPath)) {
|
|
477
|
+
try {
|
|
478
|
+
const content = readFileSync(identityPath, "utf-8");
|
|
479
|
+
const identity2 = JSON.parse(content);
|
|
480
|
+
if (identity2.userId && identity2.installId) {
|
|
481
|
+
cachedIdentity = identity2;
|
|
482
|
+
return identity2;
|
|
483
|
+
}
|
|
484
|
+
} catch {
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const identity = {
|
|
488
|
+
userId: randomUUID(),
|
|
489
|
+
installId: randomUUID(),
|
|
490
|
+
createdAt: /* @__PURE__ */ (/* @__PURE__ */ new Date()).toISOString()
|
|
491
|
+
};
|
|
492
|
+
const configDir = getVrekoConfigDir();
|
|
493
|
+
mkdirSync(configDir, {
|
|
494
|
+
recursive: true
|
|
495
|
+
});
|
|
496
|
+
writeFileSync(identityPath, JSON.stringify(identity, null, 2));
|
|
497
|
+
cachedIdentity = identity;
|
|
498
|
+
return identity;
|
|
499
|
+
}
|
|
500
|
+
__name(getOrCreateIdentity, "getOrCreateIdentity");
|
|
501
|
+
__name2(getOrCreateIdentity, "getOrCreateIdentity");
|
|
502
|
+
function getCLIVersion() {
|
|
503
|
+
try {
|
|
504
|
+
const packagePaths = [
|
|
505
|
+
join(__dirname, "../package.json"),
|
|
506
|
+
join(__dirname, "../../package.json"),
|
|
507
|
+
join(process.cwd(), "package.json")
|
|
508
|
+
];
|
|
509
|
+
for (const pkgPath of packagePaths) {
|
|
510
|
+
if (existsSync(pkgPath)) {
|
|
511
|
+
const content = readFileSync(pkgPath, "utf-8");
|
|
512
|
+
const pkg = JSON.parse(content);
|
|
513
|
+
if (pkg.name?.includes("vreko") || pkg.name?.includes("vreko")) {
|
|
514
|
+
return pkg.version || "1.0.0";
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
} catch {
|
|
519
|
+
}
|
|
520
|
+
return "1.0.0";
|
|
521
|
+
}
|
|
522
|
+
__name(getCLIVersion, "getCLIVersion");
|
|
523
|
+
__name2(getCLIVersion, "getCLIVersion");
|
|
524
|
+
function createManagedMetadata(client, options) {
|
|
525
|
+
const identity = getOrCreateIdentity();
|
|
526
|
+
return {
|
|
527
|
+
userId: identity.userId,
|
|
528
|
+
installId: identity.installId,
|
|
529
|
+
client,
|
|
530
|
+
workspaceId: options.workspaceId,
|
|
531
|
+
cliVersion: getCLIVersion(),
|
|
532
|
+
updatedAt: /* @__PURE__ */ (/* @__PURE__ */ new Date()).toISOString(),
|
|
533
|
+
transport: options.transport
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
__name(createManagedMetadata, "createManagedMetadata");
|
|
537
|
+
__name2(createManagedMetadata, "createManagedMetadata");
|
|
538
|
+
function isOwnedByThisInstall(metadata) {
|
|
539
|
+
if (!metadata?.installId) {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
const identity = getOrCreateIdentity();
|
|
543
|
+
return metadata.installId === identity.installId;
|
|
544
|
+
}
|
|
545
|
+
__name(isOwnedByThisInstall, "isOwnedByThisInstall");
|
|
546
|
+
__name2(isOwnedByThisInstall, "isOwnedByThisInstall");
|
|
547
|
+
function resetIdentityCache() {
|
|
548
|
+
cachedIdentity = null;
|
|
549
|
+
}
|
|
550
|
+
__name(resetIdentityCache, "resetIdentityCache");
|
|
551
|
+
__name2(resetIdentityCache, "resetIdentityCache");
|
|
552
|
+
var execAsync = promisify(exec);
|
|
553
|
+
async function detectMCPProcesses() {
|
|
554
|
+
try {
|
|
555
|
+
const { stdout } = await execAsync('ps aux | grep -E "(mcp.*--stdio|--stdio.*mcp|uvx.*mcp-server|npx.*mcp|node.*mcp)" | grep -v grep', {
|
|
556
|
+
timeout: 5e3
|
|
557
|
+
});
|
|
558
|
+
const processes = parseProcessOutput(stdout);
|
|
559
|
+
const vrekoProcesses = processes.filter((p) => p.isVreko);
|
|
560
|
+
return {
|
|
561
|
+
allProcesses: processes,
|
|
562
|
+
vrekoProcesses,
|
|
563
|
+
vrekoRunning: vrekoProcesses.length > 0,
|
|
564
|
+
totalCount: processes.length,
|
|
565
|
+
checkedAt: /* @__PURE__ */ new Date()
|
|
566
|
+
};
|
|
567
|
+
} catch {
|
|
568
|
+
return {
|
|
569
|
+
allProcesses: [],
|
|
570
|
+
vrekoProcesses: [],
|
|
571
|
+
vrekoRunning: false,
|
|
572
|
+
totalCount: 0,
|
|
573
|
+
checkedAt: /* @__PURE__ */ new Date()
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
__name(detectMCPProcesses, "detectMCPProcesses");
|
|
578
|
+
__name2(detectMCPProcesses, "detectMCPProcesses");
|
|
579
|
+
function parseProcessOutput(output) {
|
|
580
|
+
const lines = output.trim().split("\n").filter((line) => line.trim());
|
|
581
|
+
const processes = [];
|
|
582
|
+
for (const line of lines) {
|
|
583
|
+
const match = line.match(/^(\S+)\s+(\d+)\s+.*?\s+(.+)$/);
|
|
584
|
+
if (!match) {
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
const [, , pidStr, command] = match;
|
|
588
|
+
const pid = Number.parseInt(pidStr, 10);
|
|
589
|
+
if (Number.isNaN(pid)) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const serverName = extractServerName(command);
|
|
593
|
+
const isVreko = command.toLowerCase().includes("vreko");
|
|
594
|
+
processes.push({
|
|
595
|
+
pid,
|
|
596
|
+
command: command.trim(),
|
|
597
|
+
serverName,
|
|
598
|
+
isVreko
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
return processes;
|
|
602
|
+
}
|
|
603
|
+
__name(parseProcessOutput, "parseProcessOutput");
|
|
604
|
+
__name2(parseProcessOutput, "parseProcessOutput");
|
|
605
|
+
function extractServerName(command) {
|
|
606
|
+
const patterns = [
|
|
607
|
+
// vreko mcp --stdio
|
|
608
|
+
/vreko[/\s]/i,
|
|
609
|
+
// mcp-server-fetch
|
|
610
|
+
/mcp-server-(\w+)/,
|
|
611
|
+
// @modelcontextprotocol/server-sequential-thinking
|
|
612
|
+
/server-(\w+)/,
|
|
613
|
+
// context7-mcp
|
|
614
|
+
/(\w+)-mcp/,
|
|
615
|
+
// fly mcp server
|
|
616
|
+
/fly.*mcp/i,
|
|
617
|
+
// supabase-mcp
|
|
618
|
+
/supabase-mcp/i
|
|
619
|
+
];
|
|
620
|
+
for (const pattern of patterns) {
|
|
621
|
+
const match = command.match(pattern);
|
|
622
|
+
if (match) {
|
|
623
|
+
return match[1] || match[0];
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return "mcp";
|
|
627
|
+
}
|
|
628
|
+
__name(extractServerName, "extractServerName");
|
|
629
|
+
__name2(extractServerName, "extractServerName");
|
|
630
|
+
async function isVrekoMCPRunning() {
|
|
631
|
+
const health = await detectMCPProcesses();
|
|
632
|
+
return health.vrekoRunning;
|
|
633
|
+
}
|
|
634
|
+
__name(isVrekoMCPRunning, "isVrekoMCPRunning");
|
|
635
|
+
__name2(isVrekoMCPRunning, "isVrekoMCPRunning");
|
|
636
|
+
function isVrekoServerName(name, format) {
|
|
637
|
+
if (name === "vreko") {
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
if (format && name === `vreko-${format}`) {
|
|
641
|
+
return true;
|
|
642
|
+
}
|
|
643
|
+
return name.startsWith("vreko-");
|
|
644
|
+
}
|
|
645
|
+
__name(isVrekoServerName, "isVrekoServerName");
|
|
646
|
+
__name2(isVrekoServerName, "isVrekoServerName");
|
|
647
|
+
function validateClientConfig(client) {
|
|
648
|
+
const issues = [];
|
|
649
|
+
if (!existsSync(client.configPath)) {
|
|
650
|
+
issues.push({
|
|
651
|
+
severity: "error",
|
|
652
|
+
code: "CONFIG_NOT_FOUND",
|
|
653
|
+
message: `Config file not found: ${client.configPath}`,
|
|
654
|
+
fix: `Run: vreko tools configure --${client.name}`
|
|
655
|
+
});
|
|
656
|
+
return {
|
|
657
|
+
valid: false,
|
|
658
|
+
issues
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
let configContent;
|
|
662
|
+
let parsedConfig;
|
|
663
|
+
try {
|
|
664
|
+
configContent = readFileSync(client.configPath, "utf-8");
|
|
665
|
+
} catch (error) {
|
|
666
|
+
issues.push({
|
|
667
|
+
severity: "error",
|
|
668
|
+
code: "CONFIG_READ_ERROR",
|
|
669
|
+
message: `Cannot read config file: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
670
|
+
fix: "Check file permissions"
|
|
671
|
+
});
|
|
672
|
+
return {
|
|
673
|
+
valid: false,
|
|
674
|
+
issues
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
try {
|
|
678
|
+
parsedConfig = JSON.parse(configContent);
|
|
679
|
+
} catch (error) {
|
|
680
|
+
issues.push({
|
|
681
|
+
severity: "error",
|
|
682
|
+
code: "CONFIG_PARSE_ERROR",
|
|
683
|
+
message: `Invalid JSON in config file: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
684
|
+
fix: `Edit ${client.configPath} to fix JSON syntax, or run: vreko tools configure --${client.name} --force`
|
|
685
|
+
});
|
|
686
|
+
return {
|
|
687
|
+
valid: false,
|
|
688
|
+
issues
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
if (!client.hasVreko) {
|
|
692
|
+
issues.push({
|
|
693
|
+
severity: "warning",
|
|
694
|
+
code: "VREKO_NOT_CONFIGURED",
|
|
695
|
+
message: "Vreko MCP server not found in config",
|
|
696
|
+
fix: `Run: vreko tools configure --${client.name}`
|
|
697
|
+
});
|
|
698
|
+
return {
|
|
699
|
+
valid: false,
|
|
700
|
+
issues
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
const vrekoConfig = extractVrekoConfig(parsedConfig, client.format);
|
|
704
|
+
if (!vrekoConfig) {
|
|
705
|
+
issues.push({
|
|
706
|
+
severity: "error",
|
|
707
|
+
code: "VREKO_CONFIG_INVALID",
|
|
708
|
+
message: "Vreko config found but cannot be parsed"
|
|
709
|
+
});
|
|
710
|
+
return {
|
|
711
|
+
valid: false,
|
|
712
|
+
issues
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
validateVrekoConfig(vrekoConfig, issues);
|
|
716
|
+
if (vrekoConfig.command && vrekoConfig.args) {
|
|
717
|
+
const workspaceIdx = vrekoConfig.args.indexOf("--workspace");
|
|
718
|
+
if (workspaceIdx !== -1 && workspaceIdx + 1 < vrekoConfig.args.length) {
|
|
719
|
+
const workspacePath = vrekoConfig.args[workspaceIdx + 1];
|
|
720
|
+
const wsValidation = validateWorkspacePath(workspacePath);
|
|
721
|
+
if (!wsValidation.exists) {
|
|
722
|
+
issues.push({
|
|
723
|
+
severity: "error",
|
|
724
|
+
code: "WORKSPACE_NOT_FOUND",
|
|
725
|
+
message: `Workspace path does not exist: ${workspacePath}`,
|
|
726
|
+
fix: "Update workspace path or run: vreko tools configure --force"
|
|
727
|
+
});
|
|
728
|
+
} else if (!wsValidation.hasMarkers) {
|
|
729
|
+
issues.push({
|
|
730
|
+
severity: "warning",
|
|
731
|
+
code: "WORKSPACE_NO_MARKERS",
|
|
732
|
+
message: `Workspace path has no markers (.git, package.json, .vreko): ${workspacePath}`,
|
|
733
|
+
fix: "Run: vreko init"
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return {
|
|
739
|
+
valid: issues.filter((i) => i.severity === "error").length === 0,
|
|
740
|
+
issues,
|
|
741
|
+
config: vrekoConfig
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
__name(validateClientConfig, "validateClientConfig");
|
|
745
|
+
__name2(validateClientConfig, "validateClientConfig");
|
|
746
|
+
function validateWorkspacePath(workspacePath) {
|
|
747
|
+
const absPath = resolve(workspacePath);
|
|
748
|
+
if (!existsSync(absPath)) {
|
|
749
|
+
return {
|
|
750
|
+
exists: false,
|
|
751
|
+
hasMarkers: false,
|
|
752
|
+
path: absPath
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
const hasGit = existsSync(resolve(absPath, ".git"));
|
|
756
|
+
const hasPackageJson = existsSync(resolve(absPath, "package.json"));
|
|
757
|
+
const hasVreko = existsSync(resolve(absPath, ".vreko"));
|
|
758
|
+
return {
|
|
759
|
+
exists: true,
|
|
760
|
+
hasMarkers: hasGit || hasPackageJson || hasVreko,
|
|
761
|
+
path: absPath
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
__name(validateWorkspacePath, "validateWorkspacePath");
|
|
765
|
+
__name2(validateWorkspacePath, "validateWorkspacePath");
|
|
766
|
+
function extractVrekoConfig(parsed, format) {
|
|
767
|
+
if (!parsed || typeof parsed !== "object") {
|
|
768
|
+
return null;
|
|
769
|
+
}
|
|
770
|
+
const config = parsed;
|
|
771
|
+
switch (format) {
|
|
772
|
+
case "vscode":
|
|
773
|
+
if ("servers" in config && typeof config.servers === "object" && config.servers !== null) {
|
|
774
|
+
const servers = config.servers;
|
|
775
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
776
|
+
if (isVrekoServerName(name, format) && typeof server === "object" && server !== null) {
|
|
777
|
+
return server;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return null;
|
|
782
|
+
case "claude":
|
|
783
|
+
case "cursor":
|
|
784
|
+
case "windsurf":
|
|
785
|
+
case "cline":
|
|
786
|
+
case "roo-code":
|
|
787
|
+
case "qoder":
|
|
788
|
+
case "gemini":
|
|
789
|
+
case "zed":
|
|
790
|
+
case "claude-code":
|
|
791
|
+
if ("mcpServers" in config && typeof config.mcpServers === "object" && config.mcpServers !== null) {
|
|
792
|
+
const servers = config.mcpServers;
|
|
793
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
794
|
+
if (isVrekoServerName(name, format) && typeof server === "object" && server !== null) {
|
|
795
|
+
return server;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return null;
|
|
800
|
+
case "continue":
|
|
801
|
+
if ("experimental" in config && typeof config.experimental === "object" && config.experimental !== null) {
|
|
802
|
+
const experimental = config.experimental;
|
|
803
|
+
if ("modelContextProtocolServers" in experimental && Array.isArray(experimental.modelContextProtocolServers)) {
|
|
804
|
+
const server = experimental.modelContextProtocolServers.find((s) => typeof s === "object" && s !== null && typeof s.name === "string" && isVrekoServerName(s.name));
|
|
805
|
+
return server ? server : null;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
return null;
|
|
809
|
+
default:
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
__name(extractVrekoConfig, "extractVrekoConfig");
|
|
814
|
+
__name2(extractVrekoConfig, "extractVrekoConfig");
|
|
815
|
+
function validateVrekoConfig(config, issues) {
|
|
816
|
+
if (!config.command && !config.url) {
|
|
817
|
+
issues.push({
|
|
818
|
+
severity: "error",
|
|
819
|
+
code: "MISSING_COMMAND_OR_URL",
|
|
820
|
+
message: "Config must have either 'command' (stdio) or 'url' (HTTP)",
|
|
821
|
+
fix: "Run: vreko tools configure --force"
|
|
822
|
+
});
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
if (config.command) {
|
|
826
|
+
if (!isCommandExecutable(config.command)) {
|
|
827
|
+
issues.push({
|
|
828
|
+
severity: "error",
|
|
829
|
+
code: "COMMAND_NOT_EXECUTABLE",
|
|
830
|
+
message: `Command not found or not executable: ${config.command}`,
|
|
831
|
+
fix: "Run: vreko tools repair (will auto-fix node path)"
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
if (!config.args || !Array.isArray(config.args)) {
|
|
835
|
+
issues.push({
|
|
836
|
+
severity: "error",
|
|
837
|
+
code: "MISSING_ARGS",
|
|
838
|
+
message: "Command-based config must have 'args' array",
|
|
839
|
+
fix: "Run: vreko tools configure --force"
|
|
840
|
+
});
|
|
841
|
+
} else {
|
|
842
|
+
if (!config.args.includes("mcp")) {
|
|
843
|
+
issues.push({
|
|
844
|
+
severity: "error",
|
|
845
|
+
code: "MISSING_MCP_ARG",
|
|
846
|
+
message: "Args must include 'mcp' command",
|
|
847
|
+
fix: "Run: vreko tools configure --force"
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
if (!config.args.includes("--stdio")) {
|
|
851
|
+
issues.push({
|
|
852
|
+
severity: "error",
|
|
853
|
+
code: "MISSING_STDIO_ARG",
|
|
854
|
+
message: "Args must include '--stdio' flag",
|
|
855
|
+
fix: "Run: vreko mcp repair --client <name>"
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
if (config.args.includes("shim")) {
|
|
859
|
+
issues.push({
|
|
860
|
+
severity: "error",
|
|
861
|
+
code: "DEPRECATED_SHIM_COMMAND",
|
|
862
|
+
message: "Args contain deprecated 'shim' command - use '--stdio' instead",
|
|
863
|
+
fix: "Run: vreko mcp repair --client <name>"
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
if (!config.args.includes("--workspace")) {
|
|
867
|
+
issues.push({
|
|
868
|
+
severity: "warning",
|
|
869
|
+
code: "MISSING_WORKSPACE_ARG",
|
|
870
|
+
message: "Args should include '--workspace' path for reliability",
|
|
871
|
+
fix: "Run: vreko tools configure --force"
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
if (config.args.length > 0) {
|
|
875
|
+
const cliPath = config.args[0];
|
|
876
|
+
if (cliPath?.endsWith(".js") && !existsSync(cliPath)) {
|
|
877
|
+
issues.push({
|
|
878
|
+
severity: "error",
|
|
879
|
+
code: "CLI_PATH_NOT_FOUND",
|
|
880
|
+
message: `CLI script not found: ${cliPath}`,
|
|
881
|
+
fix: "Rebuild CLI: pnpm --filter @vreko/cli build"
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
if (config.url) {
|
|
888
|
+
try {
|
|
889
|
+
new URL(config.url);
|
|
890
|
+
} catch {
|
|
891
|
+
issues.push({
|
|
892
|
+
severity: "error",
|
|
893
|
+
code: "INVALID_URL",
|
|
894
|
+
message: `Invalid server URL: ${config.url}`,
|
|
895
|
+
fix: "Run: vreko tools configure --force"
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
if (config.env) {
|
|
900
|
+
if (!config.env.VREKO_API_KEY && !config.env.VREKO_WORKSPACE_ID) {
|
|
901
|
+
issues.push({
|
|
902
|
+
severity: "info",
|
|
903
|
+
code: "NO_AUTH",
|
|
904
|
+
message: "No API key or workspace ID found (free tier will be used)"
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
__name(validateVrekoConfig, "validateVrekoConfig");
|
|
910
|
+
__name2(validateVrekoConfig, "validateVrekoConfig");
|
|
911
|
+
function isCommandExecutable(command) {
|
|
912
|
+
if (command.startsWith("/") || command.match(/^[A-Z]:\\/i)) {
|
|
913
|
+
return existsSync(command);
|
|
914
|
+
}
|
|
915
|
+
try {
|
|
916
|
+
const isWindows = process.platform === "win32";
|
|
917
|
+
const cmd = isWindows ? `where ${command}` : `which ${command}`;
|
|
918
|
+
execSync(cmd, {
|
|
919
|
+
encoding: "utf-8",
|
|
920
|
+
timeout: 5e3
|
|
921
|
+
});
|
|
922
|
+
return true;
|
|
923
|
+
} catch {
|
|
924
|
+
return false;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
__name(isCommandExecutable, "isCommandExecutable");
|
|
928
|
+
__name2(isCommandExecutable, "isCommandExecutable");
|
|
929
|
+
var cachedNodePath = null;
|
|
930
|
+
function resolveNodePath() {
|
|
931
|
+
if (cachedNodePath) {
|
|
932
|
+
return cachedNodePath;
|
|
933
|
+
}
|
|
934
|
+
try {
|
|
935
|
+
const isWindows = process.platform === "win32";
|
|
936
|
+
const command = isWindows ? "where node" : "which node";
|
|
937
|
+
const result = execSync(command, {
|
|
938
|
+
encoding: "utf-8",
|
|
939
|
+
timeout: 5e3
|
|
940
|
+
}).trim();
|
|
941
|
+
const nodePath = result.split(/\r?\n/)[0].trim();
|
|
942
|
+
if (nodePath && existsSync(nodePath)) {
|
|
943
|
+
cachedNodePath = nodePath;
|
|
944
|
+
return nodePath;
|
|
945
|
+
}
|
|
946
|
+
} catch {
|
|
947
|
+
const commonPaths = [
|
|
948
|
+
"/opt/homebrew/bin/node",
|
|
949
|
+
"/usr/local/bin/node",
|
|
950
|
+
"/usr/bin/node",
|
|
951
|
+
"C:\\Program Files\\nodejs\\node.exe"
|
|
952
|
+
];
|
|
953
|
+
for (const path of commonPaths) {
|
|
954
|
+
if (existsSync(path)) {
|
|
955
|
+
cachedNodePath = path;
|
|
956
|
+
return path;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return "node";
|
|
961
|
+
}
|
|
962
|
+
__name(resolveNodePath, "resolveNodePath");
|
|
963
|
+
__name2(resolveNodePath, "resolveNodePath");
|
|
964
|
+
function resolveVrekoBinaryPath() {
|
|
965
|
+
try {
|
|
966
|
+
const isWindows = process.platform === "win32";
|
|
967
|
+
const command = isWindows ? "where vreko" : "which vreko";
|
|
968
|
+
const result = execSync(command, {
|
|
969
|
+
encoding: "utf-8",
|
|
970
|
+
timeout: 5e3
|
|
971
|
+
}).trim();
|
|
972
|
+
const binaryPath = result.split(/\r?\n/)[0].trim();
|
|
973
|
+
if (binaryPath && existsSync(binaryPath)) {
|
|
974
|
+
return binaryPath;
|
|
975
|
+
}
|
|
976
|
+
} catch {
|
|
977
|
+
}
|
|
978
|
+
const commonPaths = [
|
|
979
|
+
"/opt/homebrew/bin/vreko",
|
|
980
|
+
"/usr/local/bin/vreko",
|
|
981
|
+
"/usr/bin/vreko"
|
|
982
|
+
];
|
|
983
|
+
for (const p of commonPaths) {
|
|
984
|
+
if (existsSync(p)) {
|
|
985
|
+
return p;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return "vreko";
|
|
989
|
+
}
|
|
990
|
+
__name(resolveVrekoBinaryPath, "resolveVrekoBinaryPath");
|
|
991
|
+
__name2(resolveVrekoBinaryPath, "resolveVrekoBinaryPath");
|
|
992
|
+
function isCommandExecutable2(command) {
|
|
993
|
+
if (command.startsWith("/") || command.match(/^[A-Z]:\\/i)) {
|
|
994
|
+
return existsSync(command);
|
|
995
|
+
}
|
|
996
|
+
try {
|
|
997
|
+
const isWindows = process.platform === "win32";
|
|
998
|
+
const cmd = isWindows ? `where ${command}` : `which ${command}`;
|
|
999
|
+
execSync(cmd, {
|
|
1000
|
+
encoding: "utf-8",
|
|
1001
|
+
timeout: 5e3
|
|
1002
|
+
});
|
|
1003
|
+
return true;
|
|
1004
|
+
} catch {
|
|
1005
|
+
return false;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
__name(isCommandExecutable2, "isCommandExecutable2");
|
|
1009
|
+
__name2(isCommandExecutable2, "isCommandExecutable");
|
|
1010
|
+
function getVrekoMCPConfig(options = {}) {
|
|
1011
|
+
const { apiKey, workspaceId, serverUrl, useBinary = false, customCommand, additionalEnv, workspaceRoot, useLocalDev = false, localCliPath, useDoppler = false, dopplerProject = "vreko-shared", dopplerConfig = "dev", useSse = false, useStreamableHttp = false, client } = options;
|
|
1012
|
+
const useNpx = options.useNpx === true;
|
|
1013
|
+
const env = {
|
|
1014
|
+
...additionalEnv
|
|
1015
|
+
};
|
|
1016
|
+
if (apiKey) {
|
|
1017
|
+
env.VREKO_API_KEY = apiKey;
|
|
1018
|
+
}
|
|
1019
|
+
if (customCommand) {
|
|
1020
|
+
return {
|
|
1021
|
+
command: customCommand,
|
|
1022
|
+
args: [],
|
|
1023
|
+
...Object.keys(env).length > 0 && {
|
|
1024
|
+
env
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
if (client === "claude" && !customCommand && !useSse && !useStreamableHttp && !useDoppler && !useNpx && !localCliPath) {
|
|
1029
|
+
const tier = apiKey ? "pro" : "free";
|
|
1030
|
+
const args = [
|
|
1031
|
+
"--yes",
|
|
1032
|
+
"@vreko/cli",
|
|
1033
|
+
"mcp",
|
|
1034
|
+
"--stdio",
|
|
1035
|
+
"--tier",
|
|
1036
|
+
tier
|
|
1037
|
+
];
|
|
1038
|
+
if (workspaceRoot) {
|
|
1039
|
+
args.push("--workspace", workspaceRoot);
|
|
1040
|
+
}
|
|
1041
|
+
return {
|
|
1042
|
+
command: "npx",
|
|
1043
|
+
args
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
if (useSse || useStreamableHttp) {
|
|
1047
|
+
const url2 = serverUrl || "https://mcp.vreko.dev/mcp";
|
|
1048
|
+
const headers2 = {};
|
|
1049
|
+
if (workspaceId) {
|
|
1050
|
+
headers2["x-workspace-id"] = workspaceId;
|
|
1051
|
+
}
|
|
1052
|
+
if (apiKey) {
|
|
1053
|
+
headers2["x-api-key"] = apiKey;
|
|
1054
|
+
}
|
|
1055
|
+
return {
|
|
1056
|
+
url: url2,
|
|
1057
|
+
...Object.keys(headers2).length > 0 && {
|
|
1058
|
+
headers: headers2
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
if (useDoppler && localCliPath) {
|
|
1063
|
+
const nodePath = resolveNodePath();
|
|
1064
|
+
const dopplerBase = [
|
|
1065
|
+
"run",
|
|
1066
|
+
"--project",
|
|
1067
|
+
dopplerProject,
|
|
1068
|
+
"--config",
|
|
1069
|
+
dopplerConfig,
|
|
1070
|
+
"--"
|
|
1071
|
+
];
|
|
1072
|
+
const tier = apiKey ? "pro" : "free";
|
|
1073
|
+
const dopplerArgs = [
|
|
1074
|
+
...dopplerBase,
|
|
1075
|
+
nodePath,
|
|
1076
|
+
localCliPath,
|
|
1077
|
+
"mcp",
|
|
1078
|
+
"--stdio",
|
|
1079
|
+
"--tier",
|
|
1080
|
+
tier
|
|
1081
|
+
];
|
|
1082
|
+
if (workspaceRoot) {
|
|
1083
|
+
dopplerArgs.push("--workspace", workspaceRoot);
|
|
1084
|
+
}
|
|
1085
|
+
return {
|
|
1086
|
+
command: "doppler",
|
|
1087
|
+
args: dopplerArgs
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
if (useNpx) {
|
|
1091
|
+
const tier = apiKey ? "pro" : "free";
|
|
1092
|
+
const args = [
|
|
1093
|
+
"--yes",
|
|
1094
|
+
"@vreko/cli",
|
|
1095
|
+
"mcp",
|
|
1096
|
+
"--stdio",
|
|
1097
|
+
"--tier",
|
|
1098
|
+
tier
|
|
1099
|
+
];
|
|
1100
|
+
if (workspaceRoot) {
|
|
1101
|
+
args.push("--workspace", workspaceRoot);
|
|
1102
|
+
}
|
|
1103
|
+
return {
|
|
1104
|
+
command: "npx",
|
|
1105
|
+
args,
|
|
1106
|
+
...Object.keys(env).length > 0 && {
|
|
1107
|
+
env
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
if (useLocalDev && localCliPath) {
|
|
1112
|
+
const tier = apiKey ? "pro" : "free";
|
|
1113
|
+
const args = [
|
|
1114
|
+
localCliPath,
|
|
1115
|
+
"mcp",
|
|
1116
|
+
"--stdio",
|
|
1117
|
+
"--tier",
|
|
1118
|
+
tier
|
|
1119
|
+
];
|
|
1120
|
+
if (workspaceRoot) {
|
|
1121
|
+
args.push("--workspace", workspaceRoot);
|
|
1122
|
+
}
|
|
1123
|
+
const nodePath = resolveNodePath();
|
|
1124
|
+
return {
|
|
1125
|
+
command: nodePath,
|
|
1126
|
+
args,
|
|
1127
|
+
...Object.keys(env).length > 0 && {
|
|
1128
|
+
env
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
if (useBinary) {
|
|
1133
|
+
const tier = apiKey ? "pro" : "free";
|
|
1134
|
+
const args = [
|
|
1135
|
+
"mcp",
|
|
1136
|
+
"--stdio",
|
|
1137
|
+
"--tier",
|
|
1138
|
+
tier
|
|
1139
|
+
];
|
|
1140
|
+
if (workspaceRoot) {
|
|
1141
|
+
args.push("--workspace", workspaceRoot);
|
|
1142
|
+
}
|
|
1143
|
+
return {
|
|
1144
|
+
command: resolveVrekoBinaryPath(),
|
|
1145
|
+
args,
|
|
1146
|
+
...Object.keys(env).length > 0 && {
|
|
1147
|
+
env
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
const url = serverUrl || "https://mcp.vreko.dev/mcp";
|
|
1152
|
+
const headers = {};
|
|
1153
|
+
if (workspaceId) {
|
|
1154
|
+
headers["x-workspace-id"] = workspaceId;
|
|
1155
|
+
}
|
|
1156
|
+
if (apiKey) {
|
|
1157
|
+
headers["x-api-key"] = apiKey;
|
|
1158
|
+
}
|
|
1159
|
+
return {
|
|
1160
|
+
url,
|
|
1161
|
+
...Object.keys(headers).length > 0 && {
|
|
1162
|
+
headers
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
__name(getVrekoMCPConfig, "getVrekoMCPConfig");
|
|
1167
|
+
__name2(getVrekoMCPConfig, "getVrekoMCPConfig");
|
|
1168
|
+
function writeClientConfig(client, mcpConfig) {
|
|
1169
|
+
try {
|
|
1170
|
+
const configDir = dirname(client.configPath);
|
|
1171
|
+
mkdirSync(configDir, {
|
|
1172
|
+
recursive: true
|
|
1173
|
+
});
|
|
1174
|
+
let existingConfig = {
|
|
1175
|
+
mcpServers: {}
|
|
1176
|
+
};
|
|
1177
|
+
let hasExistingConfig = false;
|
|
1178
|
+
if (existsSync(client.configPath)) {
|
|
1179
|
+
try {
|
|
1180
|
+
const content = readFileSync(client.configPath, "utf-8");
|
|
1181
|
+
existingConfig = JSON.parse(content);
|
|
1182
|
+
hasExistingConfig = Object.keys(existingConfig).length > 0;
|
|
1183
|
+
} catch {
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
let backup;
|
|
1187
|
+
if (hasExistingConfig) {
|
|
1188
|
+
backup = `${client.configPath}.backup.${Date.now()}`;
|
|
1189
|
+
writeFileSync(backup, JSON.stringify(existingConfig, null, 2));
|
|
1190
|
+
}
|
|
1191
|
+
const newConfig = mergeConfig(existingConfig, mcpConfig, client.format);
|
|
1192
|
+
writeFileSync(client.configPath, JSON.stringify(newConfig, null, 2));
|
|
1193
|
+
return {
|
|
1194
|
+
success: true,
|
|
1195
|
+
backup
|
|
1196
|
+
};
|
|
1197
|
+
} catch (error) {
|
|
1198
|
+
return {
|
|
1199
|
+
success: false,
|
|
1200
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
__name(writeClientConfig, "writeClientConfig");
|
|
1205
|
+
__name2(writeClientConfig, "writeClientConfig");
|
|
1206
|
+
function removeVrekoConfig(client) {
|
|
1207
|
+
try {
|
|
1208
|
+
if (!existsSync(client.configPath)) {
|
|
1209
|
+
return {
|
|
1210
|
+
success: true
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
const content = readFileSync(client.configPath, "utf-8");
|
|
1214
|
+
const config = JSON.parse(content);
|
|
1215
|
+
switch (client.format) {
|
|
1216
|
+
case "claude":
|
|
1217
|
+
case "cursor":
|
|
1218
|
+
case "windsurf":
|
|
1219
|
+
case "cline":
|
|
1220
|
+
case "roo-code":
|
|
1221
|
+
case "gemini":
|
|
1222
|
+
case "claude-code":
|
|
1223
|
+
case "qoder": {
|
|
1224
|
+
for (const key of Object.keys(config.mcpServers ?? {})) {
|
|
1225
|
+
if (isVrekoServerName2(key, client.format)) {
|
|
1226
|
+
delete config.mcpServers[key];
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
break;
|
|
1230
|
+
}
|
|
1231
|
+
case "vscode": {
|
|
1232
|
+
const vscodeConfig = config;
|
|
1233
|
+
const servers = vscodeConfig.servers;
|
|
1234
|
+
for (const key of Object.keys(servers ?? {})) {
|
|
1235
|
+
if (servers && isVrekoServerName2(key, client.format)) {
|
|
1236
|
+
delete servers[key];
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
break;
|
|
1240
|
+
}
|
|
1241
|
+
case "zed": {
|
|
1242
|
+
const zedConfig = config;
|
|
1243
|
+
const contextServers = zedConfig.context_servers;
|
|
1244
|
+
for (const key of Object.keys(contextServers ?? {})) {
|
|
1245
|
+
if (contextServers && isVrekoServerName2(key, client.format)) {
|
|
1246
|
+
delete contextServers[key];
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
break;
|
|
1250
|
+
}
|
|
1251
|
+
case "continue": {
|
|
1252
|
+
const experimental = config.experimental;
|
|
1253
|
+
if (experimental?.modelContextProtocolServers) {
|
|
1254
|
+
const servers = experimental.modelContextProtocolServers;
|
|
1255
|
+
experimental.modelContextProtocolServers = servers.filter((s) => !isVrekoServerName2(s.name, "continue"));
|
|
1256
|
+
}
|
|
1257
|
+
break;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
writeFileSync(client.configPath, JSON.stringify(config, null, 2));
|
|
1261
|
+
evictCachedPath(client.name);
|
|
1262
|
+
return {
|
|
1263
|
+
success: true
|
|
1264
|
+
};
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
return {
|
|
1267
|
+
success: false,
|
|
1268
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
__name(removeVrekoConfig, "removeVrekoConfig");
|
|
1273
|
+
__name2(removeVrekoConfig, "removeVrekoConfig");
|
|
1274
|
+
function getServerKey(client) {
|
|
1275
|
+
if (!client) {
|
|
1276
|
+
return "vreko";
|
|
1277
|
+
}
|
|
1278
|
+
return `vreko-${client}`;
|
|
1279
|
+
}
|
|
1280
|
+
__name(getServerKey, "getServerKey");
|
|
1281
|
+
__name2(getServerKey, "getServerKey");
|
|
1282
|
+
function isVrekoServerName2(name, client) {
|
|
1283
|
+
const serverKey = getServerKey(client);
|
|
1284
|
+
return name === serverKey || name === "vreko" || name.startsWith("vreko-");
|
|
1285
|
+
}
|
|
1286
|
+
__name(isVrekoServerName2, "isVrekoServerName2");
|
|
1287
|
+
__name2(isVrekoServerName2, "isVrekoServerName");
|
|
1288
|
+
function mergeConfig(existing, vrekoConfig, format) {
|
|
1289
|
+
const serverKey = getServerKey(format);
|
|
1290
|
+
switch (format) {
|
|
1291
|
+
case "claude":
|
|
1292
|
+
case "cursor":
|
|
1293
|
+
case "cline":
|
|
1294
|
+
case "roo-code":
|
|
1295
|
+
case "gemini":
|
|
1296
|
+
case "claude-code":
|
|
1297
|
+
return {
|
|
1298
|
+
...existing,
|
|
1299
|
+
mcpServers: {
|
|
1300
|
+
...existing.mcpServers || {},
|
|
1301
|
+
[serverKey]: vrekoConfig
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
case "windsurf":
|
|
1305
|
+
return {
|
|
1306
|
+
...existing,
|
|
1307
|
+
mcpServers: {
|
|
1308
|
+
...existing.mcpServers || {},
|
|
1309
|
+
[serverKey]: {
|
|
1310
|
+
...vrekoConfig,
|
|
1311
|
+
disabled: false,
|
|
1312
|
+
alwaysAllow: []
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
case "qoder": {
|
|
1317
|
+
let qoderType;
|
|
1318
|
+
if (vrekoConfig.url) {
|
|
1319
|
+
const isLocal = vrekoConfig.url.startsWith("http://localhost") || vrekoConfig.url.startsWith("http://127.0.0.1");
|
|
1320
|
+
qoderType = isLocal ? "sse" : "http";
|
|
1321
|
+
} else {
|
|
1322
|
+
qoderType = "stdio";
|
|
1323
|
+
}
|
|
1324
|
+
return {
|
|
1325
|
+
...existing,
|
|
1326
|
+
mcpServers: {
|
|
1327
|
+
...existing.mcpServers || {},
|
|
1328
|
+
[serverKey]: {
|
|
1329
|
+
type: qoderType,
|
|
1330
|
+
...vrekoConfig
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
case "vscode": {
|
|
1336
|
+
const vscodeConfig = existing;
|
|
1337
|
+
const servers = vscodeConfig.servers || {};
|
|
1338
|
+
const { mcpServers: _, ...rest } = vscodeConfig;
|
|
1339
|
+
return {
|
|
1340
|
+
...rest,
|
|
1341
|
+
servers: {
|
|
1342
|
+
...servers,
|
|
1343
|
+
[serverKey]: {
|
|
1344
|
+
type: "stdio",
|
|
1345
|
+
...vrekoConfig
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
case "zed": {
|
|
1351
|
+
const zedConfig = existing;
|
|
1352
|
+
const contextServers = zedConfig.context_servers || {};
|
|
1353
|
+
const { mcpServers: _, ...rest } = zedConfig;
|
|
1354
|
+
return {
|
|
1355
|
+
...rest,
|
|
1356
|
+
context_servers: {
|
|
1357
|
+
...contextServers,
|
|
1358
|
+
[serverKey]: vrekoConfig
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
case "continue": {
|
|
1363
|
+
const continueConfig = existing;
|
|
1364
|
+
const experimental = continueConfig.experimental || {};
|
|
1365
|
+
const servers = experimental.modelContextProtocolServers || [];
|
|
1366
|
+
const filteredServers = servers.filter((s) => {
|
|
1367
|
+
const name = s.name;
|
|
1368
|
+
return !name?.startsWith("vreko");
|
|
1369
|
+
});
|
|
1370
|
+
filteredServers.push({
|
|
1371
|
+
name: serverKey,
|
|
1372
|
+
...vrekoConfig
|
|
1373
|
+
});
|
|
1374
|
+
return {
|
|
1375
|
+
...continueConfig,
|
|
1376
|
+
experimental: {
|
|
1377
|
+
...experimental,
|
|
1378
|
+
modelContextProtocolServers: filteredServers
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
case "aider":
|
|
1383
|
+
return existing;
|
|
1384
|
+
default:
|
|
1385
|
+
return {
|
|
1386
|
+
...existing,
|
|
1387
|
+
mcpServers: {
|
|
1388
|
+
...existing.mcpServers || {},
|
|
1389
|
+
[serverKey]: vrekoConfig
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
__name(mergeConfig, "mergeConfig");
|
|
1395
|
+
__name2(mergeConfig, "mergeConfig");
|
|
1396
|
+
function patchApiKeyInClientConfig(client, apiKey) {
|
|
1397
|
+
try {
|
|
1398
|
+
if (!existsSync(client.configPath)) {
|
|
1399
|
+
return false;
|
|
1400
|
+
}
|
|
1401
|
+
const raw = readFileSync(client.configPath, "utf-8");
|
|
1402
|
+
const config = JSON.parse(raw);
|
|
1403
|
+
let patched = false;
|
|
1404
|
+
const patchEntry = /* @__PURE__ */ __name2((entry) => {
|
|
1405
|
+
if (typeof entry !== "object" || entry === null) {
|
|
1406
|
+
return false;
|
|
1407
|
+
}
|
|
1408
|
+
const e = entry;
|
|
1409
|
+
if (e.url && typeof e.url === "string") {
|
|
1410
|
+
if (!e.headers || typeof e.headers !== "object") {
|
|
1411
|
+
e.headers = {};
|
|
1412
|
+
}
|
|
1413
|
+
e.headers["x-api-key"] = apiKey;
|
|
1414
|
+
const headers = e.headers;
|
|
1415
|
+
if (headers.Authorization?.includes("<your-token>")) {
|
|
1416
|
+
delete headers.Authorization;
|
|
1417
|
+
}
|
|
1418
|
+
return true;
|
|
1419
|
+
}
|
|
1420
|
+
if (!e.env || typeof e.env !== "object") {
|
|
1421
|
+
e.env = {};
|
|
1422
|
+
}
|
|
1423
|
+
e.env.VREKO_API_KEY = apiKey;
|
|
1424
|
+
return true;
|
|
1425
|
+
}, "patchEntry");
|
|
1426
|
+
switch (client.format) {
|
|
1427
|
+
case "claude":
|
|
1428
|
+
case "cursor":
|
|
1429
|
+
case "windsurf":
|
|
1430
|
+
case "cline":
|
|
1431
|
+
case "roo-code":
|
|
1432
|
+
case "gemini":
|
|
1433
|
+
case "claude-code": {
|
|
1434
|
+
const servers = config.mcpServers || {};
|
|
1435
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
1436
|
+
if (isVrekoServerName2(name, client.format)) {
|
|
1437
|
+
patched = patchEntry(entry) || patched;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
case "qoder": {
|
|
1443
|
+
const servers = config.mcpServers || {};
|
|
1444
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
1445
|
+
if (isVrekoServerName2(name, client.format)) {
|
|
1446
|
+
patched = patchEntry(entry) || patched;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
break;
|
|
1450
|
+
}
|
|
1451
|
+
case "vscode": {
|
|
1452
|
+
const servers = config.servers || {};
|
|
1453
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
1454
|
+
if (isVrekoServerName2(name, client.format)) {
|
|
1455
|
+
patched = patchEntry(entry) || patched;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
case "zed": {
|
|
1461
|
+
const servers = config.context_servers || {};
|
|
1462
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
1463
|
+
if (isVrekoServerName2(name, client.format)) {
|
|
1464
|
+
patched = patchEntry(entry) || patched;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
break;
|
|
1468
|
+
}
|
|
1469
|
+
case "continue": {
|
|
1470
|
+
const exp = config.experimental || {};
|
|
1471
|
+
const list = exp.modelContextProtocolServers || [];
|
|
1472
|
+
for (const item of list) {
|
|
1473
|
+
if (typeof item.name === "string" && isVrekoServerName2(item.name, "continue")) {
|
|
1474
|
+
patched = patchEntry(item) || patched;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
if (patched) {
|
|
1481
|
+
writeFileSync(client.configPath, JSON.stringify(config, null, 2));
|
|
1482
|
+
}
|
|
1483
|
+
return patched;
|
|
1484
|
+
} catch {
|
|
1485
|
+
return false;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
__name(patchApiKeyInClientConfig, "patchApiKeyInClientConfig");
|
|
1489
|
+
__name2(patchApiKeyInClientConfig, "patchApiKeyInClientConfig");
|
|
1490
|
+
function validateConfig(client) {
|
|
1491
|
+
try {
|
|
1492
|
+
const content = readFileSync(client.configPath, "utf-8");
|
|
1493
|
+
const config = JSON.parse(content);
|
|
1494
|
+
switch (client.format) {
|
|
1495
|
+
case "claude":
|
|
1496
|
+
case "cursor":
|
|
1497
|
+
case "windsurf":
|
|
1498
|
+
case "cline":
|
|
1499
|
+
case "roo-code":
|
|
1500
|
+
case "gemini":
|
|
1501
|
+
case "claude-code":
|
|
1502
|
+
case "qoder": {
|
|
1503
|
+
const servers = config.mcpServers ?? {};
|
|
1504
|
+
return Object.entries(servers).some(([name, serverConfig]) => isVrekoServerName2(name, client.format) && typeof serverConfig === "object" && serverConfig !== null && Boolean(serverConfig.command || serverConfig.url));
|
|
1505
|
+
}
|
|
1506
|
+
case "vscode": {
|
|
1507
|
+
const vscodeConfig = config;
|
|
1508
|
+
const servers = vscodeConfig.servers;
|
|
1509
|
+
return Boolean(Object.entries(servers ?? {}).some(([name, serverConfig]) => isVrekoServerName2(name, client.format) && typeof serverConfig === "object" && serverConfig !== null && Boolean(serverConfig.command || serverConfig.url)));
|
|
1510
|
+
}
|
|
1511
|
+
case "zed": {
|
|
1512
|
+
const zedConfig = config;
|
|
1513
|
+
const contextServers = zedConfig.context_servers;
|
|
1514
|
+
return Boolean(Object.entries(contextServers ?? {}).some(([name, serverConfig]) => isVrekoServerName2(name, client.format) && typeof serverConfig === "object" && serverConfig !== null && Boolean(serverConfig.command || serverConfig.url)));
|
|
1515
|
+
}
|
|
1516
|
+
case "continue": {
|
|
1517
|
+
const expCfg = config.experimental;
|
|
1518
|
+
const srvs = expCfg?.modelContextProtocolServers;
|
|
1519
|
+
return Boolean(srvs?.some((s) => isVrekoServerName2(s.name, "continue") && (s.command || s.url)));
|
|
1520
|
+
}
|
|
1521
|
+
case "aider":
|
|
1522
|
+
return false;
|
|
1523
|
+
default:
|
|
1524
|
+
return false;
|
|
1525
|
+
}
|
|
1526
|
+
} catch {
|
|
1527
|
+
return false;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
__name(validateConfig, "validateConfig");
|
|
1531
|
+
__name2(validateConfig, "validateConfig");
|
|
1532
|
+
function repairClientConfig(client, options = {}) {
|
|
1533
|
+
const fixed = [];
|
|
1534
|
+
const remaining = [];
|
|
1535
|
+
const validation = validateClientConfig(client);
|
|
1536
|
+
if (options.force) {
|
|
1537
|
+
return performFullReconfiguration(client, options);
|
|
1538
|
+
}
|
|
1539
|
+
if (validation.valid && validation.issues.length === 0) {
|
|
1540
|
+
return {
|
|
1541
|
+
success: true,
|
|
1542
|
+
fixed: [],
|
|
1543
|
+
remaining: []
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
for (const issue of validation.issues) {
|
|
1547
|
+
const fixResult = attemptFix(client, issue, validation, options);
|
|
1548
|
+
if (fixResult.success) {
|
|
1549
|
+
fixed.push(issue.message);
|
|
1550
|
+
} else {
|
|
1551
|
+
remaining.push(issue.message);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
const hasCriticalErrors = remaining.some((msg) => validation.issues.find((i) => i.message === msg && i.severity === "error"));
|
|
1555
|
+
if (hasCriticalErrors) {
|
|
1556
|
+
return performFullReconfiguration(client, options);
|
|
1557
|
+
}
|
|
1558
|
+
return {
|
|
1559
|
+
success: remaining.length === 0,
|
|
1560
|
+
fixed,
|
|
1561
|
+
remaining
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
__name(repairClientConfig, "repairClientConfig");
|
|
1565
|
+
__name2(repairClientConfig, "repairClientConfig");
|
|
1566
|
+
function injectWorkspacePath(client, workspaceRoot) {
|
|
1567
|
+
const fixed = [];
|
|
1568
|
+
const remaining = [];
|
|
1569
|
+
const detectedWorkspace = workspaceRoot || detectWorkspaceRoot(process.cwd());
|
|
1570
|
+
if (!detectedWorkspace) {
|
|
1571
|
+
return {
|
|
1572
|
+
success: false,
|
|
1573
|
+
fixed,
|
|
1574
|
+
remaining: [
|
|
1575
|
+
"Could not auto-detect workspace root"
|
|
1576
|
+
],
|
|
1577
|
+
error: "No workspace markers found (.git, package.json, .vreko)"
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
if (!existsSync(detectedWorkspace)) {
|
|
1581
|
+
return {
|
|
1582
|
+
success: false,
|
|
1583
|
+
fixed,
|
|
1584
|
+
remaining: [
|
|
1585
|
+
`Workspace path does not exist: ${detectedWorkspace}`
|
|
1586
|
+
],
|
|
1587
|
+
error: "Invalid workspace path"
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
const validation = validateClientConfig(client);
|
|
1591
|
+
if (!validation.config) {
|
|
1592
|
+
return {
|
|
1593
|
+
success: false,
|
|
1594
|
+
fixed,
|
|
1595
|
+
remaining: [
|
|
1596
|
+
"No existing Vreko config found"
|
|
1597
|
+
],
|
|
1598
|
+
error: "Must run initial configuration first"
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
if (!validation.config.command) {
|
|
1602
|
+
return {
|
|
1603
|
+
success: true,
|
|
1604
|
+
fixed: [
|
|
1605
|
+
"Config uses HTTP transport - no workspace path needed"
|
|
1606
|
+
],
|
|
1607
|
+
remaining: []
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
const hasWorkspace = validation.config.args?.includes("--workspace");
|
|
1611
|
+
if (hasWorkspace) {
|
|
1612
|
+
fixed.push("Workspace path already configured");
|
|
1613
|
+
return {
|
|
1614
|
+
success: true,
|
|
1615
|
+
fixed,
|
|
1616
|
+
remaining
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
const result = performFullReconfiguration(client, {
|
|
1620
|
+
workspaceRoot: detectedWorkspace
|
|
1621
|
+
});
|
|
1622
|
+
if (result.success) {
|
|
1623
|
+
fixed.push(`Injected workspace path: ${detectedWorkspace}`);
|
|
1624
|
+
}
|
|
1625
|
+
return {
|
|
1626
|
+
success: result.success,
|
|
1627
|
+
fixed,
|
|
1628
|
+
remaining
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
__name(injectWorkspacePath, "injectWorkspacePath");
|
|
1632
|
+
__name2(injectWorkspacePath, "injectWorkspacePath");
|
|
1633
|
+
function attemptFix(client, issue, _validation, options) {
|
|
1634
|
+
switch (issue.code) {
|
|
1635
|
+
case "CONFIG_NOT_FOUND":
|
|
1636
|
+
case "CONFIG_PARSE_ERROR":
|
|
1637
|
+
case "VREKO_NOT_CONFIGURED":
|
|
1638
|
+
case "MISSING_COMMAND_OR_URL":
|
|
1639
|
+
case "MISSING_ARGS":
|
|
1640
|
+
case "MISSING_MCP_ARG":
|
|
1641
|
+
case "MISSING_STDIO_ARG":
|
|
1642
|
+
case "DEPRECATED_SHIM_COMMAND":
|
|
1643
|
+
case "INVALID_URL":
|
|
1644
|
+
return performFullReconfiguration(client, options);
|
|
1645
|
+
case "COMMAND_NOT_EXECUTABLE": {
|
|
1646
|
+
return performFullReconfiguration(client, options);
|
|
1647
|
+
}
|
|
1648
|
+
case "CLI_PATH_NOT_FOUND": {
|
|
1649
|
+
const cliPath = findCliPath();
|
|
1650
|
+
if (cliPath) {
|
|
1651
|
+
return performFullReconfiguration(client, options);
|
|
1652
|
+
}
|
|
1653
|
+
return {
|
|
1654
|
+
success: false
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
case "MISSING_WORKSPACE_ARG": {
|
|
1658
|
+
const workspace = options.workspaceRoot || detectWorkspaceRoot(process.cwd());
|
|
1659
|
+
if (workspace) {
|
|
1660
|
+
return performFullReconfiguration(client, {
|
|
1661
|
+
...options,
|
|
1662
|
+
workspaceRoot: workspace
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
return {
|
|
1666
|
+
success: false
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1669
|
+
case "WORKSPACE_NOT_FOUND": {
|
|
1670
|
+
const detected = detectWorkspaceRoot(process.cwd());
|
|
1671
|
+
if (detected) {
|
|
1672
|
+
return performFullReconfiguration(client, {
|
|
1673
|
+
...options,
|
|
1674
|
+
workspaceRoot: detected
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
return {
|
|
1678
|
+
success: false
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
case "WORKSPACE_NO_MARKERS":
|
|
1682
|
+
return {
|
|
1683
|
+
success: true
|
|
1684
|
+
};
|
|
1685
|
+
case "NO_AUTH":
|
|
1686
|
+
return {
|
|
1687
|
+
success: true
|
|
1688
|
+
};
|
|
1689
|
+
default:
|
|
1690
|
+
return {
|
|
1691
|
+
success: false
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
__name(attemptFix, "attemptFix");
|
|
1696
|
+
__name2(attemptFix, "attemptFix");
|
|
1697
|
+
function performFullReconfiguration(client, options) {
|
|
1698
|
+
try {
|
|
1699
|
+
const workspaceRoot = options.workspaceRoot || detectWorkspaceRoot(process.cwd());
|
|
1700
|
+
const cliPath = findCliPath();
|
|
1701
|
+
let mcpConfig;
|
|
1702
|
+
if (cliPath && workspaceRoot) {
|
|
1703
|
+
mcpConfig = getVrekoMCPConfig({
|
|
1704
|
+
apiKey: options.apiKey,
|
|
1705
|
+
workspaceId: options.workspaceId,
|
|
1706
|
+
workspaceRoot,
|
|
1707
|
+
useLocalDev: true,
|
|
1708
|
+
localCliPath: cliPath,
|
|
1709
|
+
client: client.format
|
|
1710
|
+
});
|
|
1711
|
+
const _nodePath = resolveNodePath();
|
|
1712
|
+
} else {
|
|
1713
|
+
mcpConfig = getVrekoMCPConfig({
|
|
1714
|
+
apiKey: options.apiKey,
|
|
1715
|
+
workspaceId: options.workspaceId,
|
|
1716
|
+
useLocalDev: false,
|
|
1717
|
+
client: client.format
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
const writeResult = writeClientConfig(client, mcpConfig);
|
|
1721
|
+
if (writeResult.success) {
|
|
1722
|
+
return {
|
|
1723
|
+
success: true,
|
|
1724
|
+
fixed: [
|
|
1725
|
+
"Full reconfiguration completed (node path resolved)"
|
|
1726
|
+
],
|
|
1727
|
+
remaining: []
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
return {
|
|
1731
|
+
success: false,
|
|
1732
|
+
fixed: [],
|
|
1733
|
+
remaining: [
|
|
1734
|
+
"Write failed"
|
|
1735
|
+
],
|
|
1736
|
+
error: writeResult.error
|
|
1737
|
+
};
|
|
1738
|
+
} catch (error) {
|
|
1739
|
+
return {
|
|
1740
|
+
success: false,
|
|
1741
|
+
fixed: [],
|
|
1742
|
+
remaining: [
|
|
1743
|
+
"Reconfiguration failed"
|
|
1744
|
+
],
|
|
1745
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
__name(performFullReconfiguration, "performFullReconfiguration");
|
|
1750
|
+
__name2(performFullReconfiguration, "performFullReconfiguration");
|
|
1751
|
+
function detectWorkspaceRoot(startPath) {
|
|
1752
|
+
let currentPath = resolve(startPath);
|
|
1753
|
+
const maxIterations = 50;
|
|
1754
|
+
let iterations = 0;
|
|
1755
|
+
while (iterations < maxIterations) {
|
|
1756
|
+
iterations++;
|
|
1757
|
+
const hasGit = existsSync(resolve(currentPath, ".git"));
|
|
1758
|
+
const hasPackageJson = existsSync(resolve(currentPath, "package.json"));
|
|
1759
|
+
const hasVreko = existsSync(resolve(currentPath, ".vreko"));
|
|
1760
|
+
if (hasGit || hasPackageJson || hasVreko) {
|
|
1761
|
+
return currentPath;
|
|
1762
|
+
}
|
|
1763
|
+
const parent = resolve(currentPath, "..");
|
|
1764
|
+
if (parent === currentPath) {
|
|
1765
|
+
break;
|
|
1766
|
+
}
|
|
1767
|
+
currentPath = parent;
|
|
1768
|
+
}
|
|
1769
|
+
return null;
|
|
1770
|
+
}
|
|
1771
|
+
__name(detectWorkspaceRoot, "detectWorkspaceRoot");
|
|
1772
|
+
__name2(detectWorkspaceRoot, "detectWorkspaceRoot");
|
|
1773
|
+
function findCliPath() {
|
|
1774
|
+
const cwd = process.cwd();
|
|
1775
|
+
const candidates = [
|
|
1776
|
+
resolve(cwd, "apps/cli/dist/index.js"),
|
|
1777
|
+
resolve(cwd, "dist/index.js"),
|
|
1778
|
+
resolve(cwd, "../cli/dist/index.js"),
|
|
1779
|
+
resolve(cwd, "../../apps/cli/dist/index.js")
|
|
1780
|
+
];
|
|
1781
|
+
for (const path of candidates) {
|
|
1782
|
+
if (existsSync(path)) {
|
|
1783
|
+
return path;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
return void 0;
|
|
1787
|
+
}
|
|
1788
|
+
__name(findCliPath, "findCliPath");
|
|
1789
|
+
__name2(findCliPath, "findCliPath");
|
|
1790
|
+
|
|
1791
|
+
export { createManagedMetadata, detectAIClients, detectMCPProcesses, detectWorkspaceConfig, evictCachedPath, getAllCachedPaths, getCachedPath, getClient, getClientConfigPath, getConfigDirWithMigration, getConfiguredClients, getOrCreateIdentity, getServerKey, getVrekoConfigDir, getVrekoMCPConfig, injectWorkspacePath, isCommandExecutable2, isOwnedByThisInstall, isVrekoMCPRunning, patchApiKeyInClientConfig, readClientConfig, removeVrekoConfig, repairClientConfig, resetIdentityCache, resolveNodePath, resolveVrekoBinaryPath, setCachedPath, validateClientConfig, validateConfig, validateWorkspacePath, writeClientConfig };
|
|
1792
|
+
//# sourceMappingURL=chunk-MJVY2XUN.js.map
|
|
1793
|
+
//# sourceMappingURL=chunk-MJVY2XUN.js.map
|