@llmnesia/mcp 0.1.0 → 0.1.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/README.md +14 -9
- package/THIRD_PARTY_NOTICES +70 -0
- package/dist/{chunk-OBJD6H4A.js → chunk-4CBIA42T.js} +12 -3
- package/dist/{chunk-OBJD6H4A.js.map → chunk-4CBIA42T.js.map} +1 -1
- package/dist/cli.js +708 -17
- package/dist/cli.js.map +1 -1
- package/dist/mcp.js +3 -1
- package/dist/mcp.js.map +1 -1
- package/package.json +2 -1
- package/server.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,520 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __llmnesiaCreateRequire } from "node:module";
|
|
3
|
+
const require = __llmnesiaCreateRequire(import.meta.url);
|
|
2
4
|
import {
|
|
3
5
|
Corpus,
|
|
4
6
|
SearchIndex,
|
|
5
7
|
VERSION,
|
|
8
|
+
__commonJS,
|
|
9
|
+
__require,
|
|
10
|
+
__toESM,
|
|
6
11
|
deleteIndexDb,
|
|
7
12
|
drainInbox,
|
|
8
13
|
ingestFile,
|
|
9
14
|
openSearchIndex,
|
|
10
15
|
resolveCorpusDir
|
|
11
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4CBIA42T.js";
|
|
17
|
+
|
|
18
|
+
// ../node_modules/isexe/windows.js
|
|
19
|
+
var require_windows = __commonJS({
|
|
20
|
+
"../node_modules/isexe/windows.js"(exports, module) {
|
|
21
|
+
"use strict";
|
|
22
|
+
module.exports = isexe;
|
|
23
|
+
isexe.sync = sync;
|
|
24
|
+
var fs = __require("fs");
|
|
25
|
+
function checkPathExt(path, options) {
|
|
26
|
+
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
27
|
+
if (!pathext) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
pathext = pathext.split(";");
|
|
31
|
+
if (pathext.indexOf("") !== -1) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
for (var i = 0; i < pathext.length; i++) {
|
|
35
|
+
var p = pathext[i].toLowerCase();
|
|
36
|
+
if (p && path.substr(-p.length).toLowerCase() === p) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function checkStat(stat6, path, options) {
|
|
43
|
+
if (!stat6.isSymbolicLink() && !stat6.isFile()) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return checkPathExt(path, options);
|
|
47
|
+
}
|
|
48
|
+
function isexe(path, options, cb) {
|
|
49
|
+
fs.stat(path, function(er, stat6) {
|
|
50
|
+
cb(er, er ? false : checkStat(stat6, path, options));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function sync(path, options) {
|
|
54
|
+
return checkStat(fs.statSync(path), path, options);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// ../node_modules/isexe/mode.js
|
|
60
|
+
var require_mode = __commonJS({
|
|
61
|
+
"../node_modules/isexe/mode.js"(exports, module) {
|
|
62
|
+
"use strict";
|
|
63
|
+
module.exports = isexe;
|
|
64
|
+
isexe.sync = sync;
|
|
65
|
+
var fs = __require("fs");
|
|
66
|
+
function isexe(path, options, cb) {
|
|
67
|
+
fs.stat(path, function(er, stat6) {
|
|
68
|
+
cb(er, er ? false : checkStat(stat6, options));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function sync(path, options) {
|
|
72
|
+
return checkStat(fs.statSync(path), options);
|
|
73
|
+
}
|
|
74
|
+
function checkStat(stat6, options) {
|
|
75
|
+
return stat6.isFile() && checkMode(stat6, options);
|
|
76
|
+
}
|
|
77
|
+
function checkMode(stat6, options) {
|
|
78
|
+
var mod = stat6.mode;
|
|
79
|
+
var uid = stat6.uid;
|
|
80
|
+
var gid = stat6.gid;
|
|
81
|
+
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
82
|
+
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
83
|
+
var u = parseInt("100", 8);
|
|
84
|
+
var g = parseInt("010", 8);
|
|
85
|
+
var o = parseInt("001", 8);
|
|
86
|
+
var ug = u | g;
|
|
87
|
+
var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
|
|
88
|
+
return ret;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// ../node_modules/isexe/index.js
|
|
94
|
+
var require_isexe = __commonJS({
|
|
95
|
+
"../node_modules/isexe/index.js"(exports, module) {
|
|
96
|
+
"use strict";
|
|
97
|
+
var fs = __require("fs");
|
|
98
|
+
var core;
|
|
99
|
+
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
100
|
+
core = require_windows();
|
|
101
|
+
} else {
|
|
102
|
+
core = require_mode();
|
|
103
|
+
}
|
|
104
|
+
module.exports = isexe;
|
|
105
|
+
isexe.sync = sync;
|
|
106
|
+
function isexe(path, options, cb) {
|
|
107
|
+
if (typeof options === "function") {
|
|
108
|
+
cb = options;
|
|
109
|
+
options = {};
|
|
110
|
+
}
|
|
111
|
+
if (!cb) {
|
|
112
|
+
if (typeof Promise !== "function") {
|
|
113
|
+
throw new TypeError("callback not provided");
|
|
114
|
+
}
|
|
115
|
+
return new Promise(function(resolve4, reject) {
|
|
116
|
+
isexe(path, options || {}, function(er, is) {
|
|
117
|
+
if (er) {
|
|
118
|
+
reject(er);
|
|
119
|
+
} else {
|
|
120
|
+
resolve4(is);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
core(path, options || {}, function(er, is) {
|
|
126
|
+
if (er) {
|
|
127
|
+
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
128
|
+
er = null;
|
|
129
|
+
is = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
cb(er, is);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function sync(path, options) {
|
|
136
|
+
try {
|
|
137
|
+
return core.sync(path, options || {});
|
|
138
|
+
} catch (er) {
|
|
139
|
+
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
140
|
+
return false;
|
|
141
|
+
} else {
|
|
142
|
+
throw er;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// ../node_modules/which/which.js
|
|
150
|
+
var require_which = __commonJS({
|
|
151
|
+
"../node_modules/which/which.js"(exports, module) {
|
|
152
|
+
"use strict";
|
|
153
|
+
var isWindows2 = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
154
|
+
var path = __require("path");
|
|
155
|
+
var COLON = isWindows2 ? ";" : ":";
|
|
156
|
+
var isexe = require_isexe();
|
|
157
|
+
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
158
|
+
var getPathInfo = (cmd, opt) => {
|
|
159
|
+
const colon = opt.colon || COLON;
|
|
160
|
+
const pathEnv = cmd.match(/\//) || isWindows2 && cmd.match(/\\/) ? [""] : [
|
|
161
|
+
// windows always checks the cwd first
|
|
162
|
+
...isWindows2 ? [process.cwd()] : [],
|
|
163
|
+
...(opt.path || process.env.PATH || /* istanbul ignore next: very unusual */
|
|
164
|
+
"").split(colon)
|
|
165
|
+
];
|
|
166
|
+
const pathExtExe = isWindows2 ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
167
|
+
const pathExt = isWindows2 ? pathExtExe.split(colon) : [""];
|
|
168
|
+
if (isWindows2) {
|
|
169
|
+
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
|
|
170
|
+
pathExt.unshift("");
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
pathEnv,
|
|
174
|
+
pathExt,
|
|
175
|
+
pathExtExe
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
var which = (cmd, opt, cb) => {
|
|
179
|
+
if (typeof opt === "function") {
|
|
180
|
+
cb = opt;
|
|
181
|
+
opt = {};
|
|
182
|
+
}
|
|
183
|
+
if (!opt)
|
|
184
|
+
opt = {};
|
|
185
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
186
|
+
const found = [];
|
|
187
|
+
const step = (i) => new Promise((resolve4, reject) => {
|
|
188
|
+
if (i === pathEnv.length)
|
|
189
|
+
return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
|
|
190
|
+
const ppRaw = pathEnv[i];
|
|
191
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
192
|
+
const pCmd = path.join(pathPart, cmd);
|
|
193
|
+
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
194
|
+
resolve4(subStep(p, i, 0));
|
|
195
|
+
});
|
|
196
|
+
const subStep = (p, i, ii) => new Promise((resolve4, reject) => {
|
|
197
|
+
if (ii === pathExt.length)
|
|
198
|
+
return resolve4(step(i + 1));
|
|
199
|
+
const ext = pathExt[ii];
|
|
200
|
+
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
201
|
+
if (!er && is) {
|
|
202
|
+
if (opt.all)
|
|
203
|
+
found.push(p + ext);
|
|
204
|
+
else
|
|
205
|
+
return resolve4(p + ext);
|
|
206
|
+
}
|
|
207
|
+
return resolve4(subStep(p, i, ii + 1));
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
211
|
+
};
|
|
212
|
+
var whichSync = (cmd, opt) => {
|
|
213
|
+
opt = opt || {};
|
|
214
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
215
|
+
const found = [];
|
|
216
|
+
for (let i = 0; i < pathEnv.length; i++) {
|
|
217
|
+
const ppRaw = pathEnv[i];
|
|
218
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
219
|
+
const pCmd = path.join(pathPart, cmd);
|
|
220
|
+
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
221
|
+
for (let j = 0; j < pathExt.length; j++) {
|
|
222
|
+
const cur = p + pathExt[j];
|
|
223
|
+
try {
|
|
224
|
+
const is = isexe.sync(cur, { pathExt: pathExtExe });
|
|
225
|
+
if (is) {
|
|
226
|
+
if (opt.all)
|
|
227
|
+
found.push(cur);
|
|
228
|
+
else
|
|
229
|
+
return cur;
|
|
230
|
+
}
|
|
231
|
+
} catch (ex) {
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (opt.all && found.length)
|
|
236
|
+
return found;
|
|
237
|
+
if (opt.nothrow)
|
|
238
|
+
return null;
|
|
239
|
+
throw getNotFoundError(cmd);
|
|
240
|
+
};
|
|
241
|
+
module.exports = which;
|
|
242
|
+
which.sync = whichSync;
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// ../node_modules/path-key/index.js
|
|
247
|
+
var require_path_key = __commonJS({
|
|
248
|
+
"../node_modules/path-key/index.js"(exports, module) {
|
|
249
|
+
"use strict";
|
|
250
|
+
var pathKey = (options = {}) => {
|
|
251
|
+
const environment = options.env || process.env;
|
|
252
|
+
const platform4 = options.platform || process.platform;
|
|
253
|
+
if (platform4 !== "win32") {
|
|
254
|
+
return "PATH";
|
|
255
|
+
}
|
|
256
|
+
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
257
|
+
};
|
|
258
|
+
module.exports = pathKey;
|
|
259
|
+
module.exports.default = pathKey;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// ../node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
264
|
+
var require_resolveCommand = __commonJS({
|
|
265
|
+
"../node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
|
|
266
|
+
"use strict";
|
|
267
|
+
var path = __require("path");
|
|
268
|
+
var which = require_which();
|
|
269
|
+
var getPathKey = require_path_key();
|
|
270
|
+
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
271
|
+
const env = parsed.options.env || process.env;
|
|
272
|
+
const cwd = process.cwd();
|
|
273
|
+
const hasCustomCwd = parsed.options.cwd != null;
|
|
274
|
+
const shouldSwitchCwd = hasCustomCwd && process.chdir !== void 0 && !process.chdir.disabled;
|
|
275
|
+
if (shouldSwitchCwd) {
|
|
276
|
+
try {
|
|
277
|
+
process.chdir(parsed.options.cwd);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
let resolved;
|
|
282
|
+
try {
|
|
283
|
+
resolved = which.sync(parsed.command, {
|
|
284
|
+
path: env[getPathKey({ env })],
|
|
285
|
+
pathExt: withoutPathExt ? path.delimiter : void 0
|
|
286
|
+
});
|
|
287
|
+
} catch (e) {
|
|
288
|
+
} finally {
|
|
289
|
+
if (shouldSwitchCwd) {
|
|
290
|
+
process.chdir(cwd);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (resolved) {
|
|
294
|
+
resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
295
|
+
}
|
|
296
|
+
return resolved;
|
|
297
|
+
}
|
|
298
|
+
function resolveCommand(parsed) {
|
|
299
|
+
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
300
|
+
}
|
|
301
|
+
module.exports = resolveCommand;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// ../node_modules/cross-spawn/lib/util/escape.js
|
|
306
|
+
var require_escape = __commonJS({
|
|
307
|
+
"../node_modules/cross-spawn/lib/util/escape.js"(exports, module) {
|
|
308
|
+
"use strict";
|
|
309
|
+
var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
|
|
310
|
+
function escapeCommand(arg) {
|
|
311
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
312
|
+
return arg;
|
|
313
|
+
}
|
|
314
|
+
function escapeArgument(arg, doubleEscapeMetaChars) {
|
|
315
|
+
arg = `${arg}`;
|
|
316
|
+
arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
|
|
317
|
+
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
318
|
+
arg = `"${arg}"`;
|
|
319
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
320
|
+
if (doubleEscapeMetaChars) {
|
|
321
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
322
|
+
}
|
|
323
|
+
return arg;
|
|
324
|
+
}
|
|
325
|
+
module.exports.command = escapeCommand;
|
|
326
|
+
module.exports.argument = escapeArgument;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// ../node_modules/shebang-regex/index.js
|
|
331
|
+
var require_shebang_regex = __commonJS({
|
|
332
|
+
"../node_modules/shebang-regex/index.js"(exports, module) {
|
|
333
|
+
"use strict";
|
|
334
|
+
module.exports = /^#!(.*)/;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// ../node_modules/shebang-command/index.js
|
|
339
|
+
var require_shebang_command = __commonJS({
|
|
340
|
+
"../node_modules/shebang-command/index.js"(exports, module) {
|
|
341
|
+
"use strict";
|
|
342
|
+
var shebangRegex = require_shebang_regex();
|
|
343
|
+
module.exports = (string = "") => {
|
|
344
|
+
const match = string.match(shebangRegex);
|
|
345
|
+
if (!match) {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
349
|
+
const binary = path.split("/").pop();
|
|
350
|
+
if (binary === "env") {
|
|
351
|
+
return argument;
|
|
352
|
+
}
|
|
353
|
+
return argument ? `${binary} ${argument}` : binary;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// ../node_modules/cross-spawn/lib/util/readShebang.js
|
|
359
|
+
var require_readShebang = __commonJS({
|
|
360
|
+
"../node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
|
|
361
|
+
"use strict";
|
|
362
|
+
var fs = __require("fs");
|
|
363
|
+
var shebangCommand = require_shebang_command();
|
|
364
|
+
function readShebang(command) {
|
|
365
|
+
const size = 150;
|
|
366
|
+
const buffer = Buffer.alloc(size);
|
|
367
|
+
let fd;
|
|
368
|
+
try {
|
|
369
|
+
fd = fs.openSync(command, "r");
|
|
370
|
+
fs.readSync(fd, buffer, 0, size, 0);
|
|
371
|
+
fs.closeSync(fd);
|
|
372
|
+
} catch (e) {
|
|
373
|
+
}
|
|
374
|
+
return shebangCommand(buffer.toString());
|
|
375
|
+
}
|
|
376
|
+
module.exports = readShebang;
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// ../node_modules/cross-spawn/lib/parse.js
|
|
381
|
+
var require_parse = __commonJS({
|
|
382
|
+
"../node_modules/cross-spawn/lib/parse.js"(exports, module) {
|
|
383
|
+
"use strict";
|
|
384
|
+
var path = __require("path");
|
|
385
|
+
var resolveCommand = require_resolveCommand();
|
|
386
|
+
var escape = require_escape();
|
|
387
|
+
var readShebang = require_readShebang();
|
|
388
|
+
var isWin = process.platform === "win32";
|
|
389
|
+
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
390
|
+
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
391
|
+
function detectShebang(parsed) {
|
|
392
|
+
parsed.file = resolveCommand(parsed);
|
|
393
|
+
const shebang = parsed.file && readShebang(parsed.file);
|
|
394
|
+
if (shebang) {
|
|
395
|
+
parsed.args.unshift(parsed.file);
|
|
396
|
+
parsed.command = shebang;
|
|
397
|
+
return resolveCommand(parsed);
|
|
398
|
+
}
|
|
399
|
+
return parsed.file;
|
|
400
|
+
}
|
|
401
|
+
function parseNonShell(parsed) {
|
|
402
|
+
if (!isWin) {
|
|
403
|
+
return parsed;
|
|
404
|
+
}
|
|
405
|
+
const commandFile = detectShebang(parsed);
|
|
406
|
+
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
407
|
+
if (parsed.options.forceShell || needsShell) {
|
|
408
|
+
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
409
|
+
parsed.command = path.normalize(parsed.command);
|
|
410
|
+
parsed.command = escape.command(parsed.command);
|
|
411
|
+
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
412
|
+
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
413
|
+
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
414
|
+
parsed.command = process.env.comspec || "cmd.exe";
|
|
415
|
+
parsed.options.windowsVerbatimArguments = true;
|
|
416
|
+
}
|
|
417
|
+
return parsed;
|
|
418
|
+
}
|
|
419
|
+
function parse(command, args, options) {
|
|
420
|
+
if (args && !Array.isArray(args)) {
|
|
421
|
+
options = args;
|
|
422
|
+
args = null;
|
|
423
|
+
}
|
|
424
|
+
args = args ? args.slice(0) : [];
|
|
425
|
+
options = Object.assign({}, options);
|
|
426
|
+
const parsed = {
|
|
427
|
+
command,
|
|
428
|
+
args,
|
|
429
|
+
options,
|
|
430
|
+
file: void 0,
|
|
431
|
+
original: {
|
|
432
|
+
command,
|
|
433
|
+
args
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
return options.shell ? parsed : parseNonShell(parsed);
|
|
437
|
+
}
|
|
438
|
+
module.exports = parse;
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// ../node_modules/cross-spawn/lib/enoent.js
|
|
443
|
+
var require_enoent = __commonJS({
|
|
444
|
+
"../node_modules/cross-spawn/lib/enoent.js"(exports, module) {
|
|
445
|
+
"use strict";
|
|
446
|
+
var isWin = process.platform === "win32";
|
|
447
|
+
function notFoundError(original, syscall) {
|
|
448
|
+
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
449
|
+
code: "ENOENT",
|
|
450
|
+
errno: "ENOENT",
|
|
451
|
+
syscall: `${syscall} ${original.command}`,
|
|
452
|
+
path: original.command,
|
|
453
|
+
spawnargs: original.args
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function hookChildProcess(cp2, parsed) {
|
|
457
|
+
if (!isWin) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const originalEmit = cp2.emit;
|
|
461
|
+
cp2.emit = function(name, arg1) {
|
|
462
|
+
if (name === "exit") {
|
|
463
|
+
const err = verifyENOENT(arg1, parsed);
|
|
464
|
+
if (err) {
|
|
465
|
+
return originalEmit.call(cp2, "error", err);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return originalEmit.apply(cp2, arguments);
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
function verifyENOENT(status, parsed) {
|
|
472
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
473
|
+
return notFoundError(parsed.original, "spawn");
|
|
474
|
+
}
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
function verifyENOENTSync(status, parsed) {
|
|
478
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
479
|
+
return notFoundError(parsed.original, "spawnSync");
|
|
480
|
+
}
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
module.exports = {
|
|
484
|
+
hookChildProcess,
|
|
485
|
+
verifyENOENT,
|
|
486
|
+
verifyENOENTSync,
|
|
487
|
+
notFoundError
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// ../node_modules/cross-spawn/index.js
|
|
493
|
+
var require_cross_spawn = __commonJS({
|
|
494
|
+
"../node_modules/cross-spawn/index.js"(exports, module) {
|
|
495
|
+
"use strict";
|
|
496
|
+
var cp2 = __require("child_process");
|
|
497
|
+
var parse = require_parse();
|
|
498
|
+
var enoent = require_enoent();
|
|
499
|
+
function spawn(command, args, options) {
|
|
500
|
+
const parsed = parse(command, args, options);
|
|
501
|
+
const spawned = cp2.spawn(parsed.command, parsed.args, parsed.options);
|
|
502
|
+
enoent.hookChildProcess(spawned, parsed);
|
|
503
|
+
return spawned;
|
|
504
|
+
}
|
|
505
|
+
function spawnSync(command, args, options) {
|
|
506
|
+
const parsed = parse(command, args, options);
|
|
507
|
+
const result = cp2.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
508
|
+
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
509
|
+
return result;
|
|
510
|
+
}
|
|
511
|
+
module.exports = spawn;
|
|
512
|
+
module.exports.spawn = spawn;
|
|
513
|
+
module.exports.sync = spawnSync;
|
|
514
|
+
module.exports._parse = parse;
|
|
515
|
+
module.exports._enoent = enoent;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
12
518
|
|
|
13
519
|
// src/cli.ts
|
|
14
520
|
import { createInterface } from "readline/promises";
|
|
@@ -1984,27 +2490,129 @@ async function watchInbox(corpus, onDrain) {
|
|
|
1984
2490
|
}
|
|
1985
2491
|
|
|
1986
2492
|
// src/clientRegistration.ts
|
|
2493
|
+
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
1987
2494
|
import { execFile as execFile2 } from "child_process";
|
|
1988
|
-
import { readFile as readFile2, stat as stat5, writeFile as writeFile2 } from "fs/promises";
|
|
2495
|
+
import { access, readFile as readFile2, stat as stat5, writeFile as writeFile2 } from "fs/promises";
|
|
1989
2496
|
import { homedir as homedir2, platform as platform2 } from "os";
|
|
1990
2497
|
import { dirname as dirname4, join as join4 } from "path";
|
|
1991
2498
|
import { promisify as promisify2 } from "util";
|
|
1992
2499
|
var execFileAsync2 = promisify2(execFile2);
|
|
1993
2500
|
var SERVER_NAME = "llmnesia";
|
|
2501
|
+
async function commandOnPath(name) {
|
|
2502
|
+
try {
|
|
2503
|
+
const { stdout } = await execFileAsync2(process.platform === "win32" ? "where" : "which", [name]);
|
|
2504
|
+
return stdout.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? null;
|
|
2505
|
+
} catch {
|
|
2506
|
+
return null;
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
async function runExecutable(executable, args) {
|
|
2510
|
+
return new Promise((resolve4, reject) => {
|
|
2511
|
+
const child = (0, import_cross_spawn.default)(executable, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
2512
|
+
let stdout = "";
|
|
2513
|
+
let stderr = "";
|
|
2514
|
+
child.stdout?.setEncoding("utf8");
|
|
2515
|
+
child.stderr?.setEncoding("utf8");
|
|
2516
|
+
child.stdout?.on("data", (chunk) => {
|
|
2517
|
+
stdout += chunk;
|
|
2518
|
+
});
|
|
2519
|
+
child.stderr?.on("data", (chunk) => {
|
|
2520
|
+
stderr += chunk;
|
|
2521
|
+
});
|
|
2522
|
+
child.once("error", reject);
|
|
2523
|
+
child.once("close", (code, signal) => {
|
|
2524
|
+
if (code === 0) {
|
|
2525
|
+
resolve4({ stdout, stderr });
|
|
2526
|
+
return;
|
|
2527
|
+
}
|
|
2528
|
+
reject(
|
|
2529
|
+
Object.assign(new Error(`Command failed with ${signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`}`), {
|
|
2530
|
+
code,
|
|
2531
|
+
signal,
|
|
2532
|
+
stdout,
|
|
2533
|
+
stderr
|
|
2534
|
+
})
|
|
2535
|
+
);
|
|
2536
|
+
});
|
|
2537
|
+
});
|
|
2538
|
+
}
|
|
2539
|
+
async function runPathCli(name, args) {
|
|
2540
|
+
const executable = await commandOnPath(name);
|
|
2541
|
+
if (!executable) {
|
|
2542
|
+
throw new Error(`\`${name}\` was not found on PATH`);
|
|
2543
|
+
}
|
|
2544
|
+
return runExecutable(executable, args);
|
|
2545
|
+
}
|
|
2546
|
+
async function resolveCodexExecutable() {
|
|
2547
|
+
const onPath = await commandOnPath("codex");
|
|
2548
|
+
if (onPath) {
|
|
2549
|
+
return onPath;
|
|
2550
|
+
}
|
|
2551
|
+
if (process.platform === "darwin") {
|
|
2552
|
+
const candidates = [
|
|
2553
|
+
"/Applications/ChatGPT.app/Contents/Resources/codex",
|
|
2554
|
+
"/Applications/Codex.app/Contents/Resources/codex",
|
|
2555
|
+
join4(homedir2(), "Applications", "ChatGPT.app", "Contents", "Resources", "codex"),
|
|
2556
|
+
join4(homedir2(), "Applications", "Codex.app", "Contents", "Resources", "codex")
|
|
2557
|
+
];
|
|
2558
|
+
for (const candidate of candidates) {
|
|
2559
|
+
try {
|
|
2560
|
+
await access(candidate);
|
|
2561
|
+
return candidate;
|
|
2562
|
+
} catch {
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
return null;
|
|
2567
|
+
}
|
|
1994
2568
|
var realClaudeCli = {
|
|
1995
2569
|
detect: async () => {
|
|
2570
|
+
return await commandOnPath("claude") !== null;
|
|
2571
|
+
},
|
|
2572
|
+
add: async (name, serve) => {
|
|
2573
|
+
await runPathCli("claude", ["mcp", "add", name, "--", serve.command, ...serve.args]);
|
|
2574
|
+
},
|
|
2575
|
+
remove: async (name) => {
|
|
2576
|
+
await runPathCli("claude", ["mcp", "remove", name]);
|
|
2577
|
+
}
|
|
2578
|
+
};
|
|
2579
|
+
async function runCodex(args) {
|
|
2580
|
+
const executable = await resolveCodexExecutable();
|
|
2581
|
+
if (!executable) {
|
|
2582
|
+
throw new Error("`codex` was not found on PATH or in a supported desktop app location");
|
|
2583
|
+
}
|
|
2584
|
+
return runExecutable(executable, args);
|
|
2585
|
+
}
|
|
2586
|
+
function parseCodexRegistration(raw) {
|
|
2587
|
+
const value = JSON.parse(raw);
|
|
2588
|
+
const transport = value.transport && typeof value.transport === "object" ? value.transport : value;
|
|
2589
|
+
const command = transport.command;
|
|
2590
|
+
const rawArgs = transport.args;
|
|
2591
|
+
if (typeof command !== "string" || !Array.isArray(rawArgs) || !rawArgs.every((arg) => typeof arg === "string")) {
|
|
2592
|
+
return { serve: null };
|
|
2593
|
+
}
|
|
2594
|
+
return { serve: { command, args: rawArgs } };
|
|
2595
|
+
}
|
|
2596
|
+
var realCodexCli = {
|
|
2597
|
+
detect: async () => await resolveCodexExecutable() !== null,
|
|
2598
|
+
get: async (name) => {
|
|
1996
2599
|
try {
|
|
1997
|
-
|
|
1998
|
-
return
|
|
1999
|
-
} catch {
|
|
2000
|
-
|
|
2600
|
+
const { stdout } = await runCodex(["mcp", "get", name, "--json"]);
|
|
2601
|
+
return parseCodexRegistration(stdout);
|
|
2602
|
+
} catch (err) {
|
|
2603
|
+
const output = err && typeof err === "object" ? `${"stdout" in err ? String(err.stdout) : ""}
|
|
2604
|
+
${"stderr" in err ? String(err.stderr) : ""}` : errorMessage(err);
|
|
2605
|
+
if (/No MCP server named/i.test(output)) {
|
|
2606
|
+
return null;
|
|
2607
|
+
}
|
|
2608
|
+
throw err;
|
|
2001
2609
|
}
|
|
2002
2610
|
},
|
|
2003
2611
|
add: async (name, serve) => {
|
|
2004
|
-
await
|
|
2612
|
+
await runCodex(["mcp", "add", name, "--", serve.command, ...serve.args]);
|
|
2005
2613
|
},
|
|
2006
2614
|
remove: async (name) => {
|
|
2007
|
-
await
|
|
2615
|
+
await runCodex(["mcp", "remove", name]);
|
|
2008
2616
|
}
|
|
2009
2617
|
};
|
|
2010
2618
|
function paths(home2, osPlatform2) {
|
|
@@ -2068,6 +2676,78 @@ async function registerClaudeCode(serve, cli) {
|
|
|
2068
2676
|
};
|
|
2069
2677
|
}
|
|
2070
2678
|
}
|
|
2679
|
+
function sameServeCommand(left, right) {
|
|
2680
|
+
return left.command === right.command && JSON.stringify(left.args) === JSON.stringify(right.args);
|
|
2681
|
+
}
|
|
2682
|
+
async function registerCodex(serve, cli, configPath, confirm) {
|
|
2683
|
+
if (!await cli.detect()) {
|
|
2684
|
+
if (!await clientDirExists(configPath)) {
|
|
2685
|
+
return {
|
|
2686
|
+
client: "Codex",
|
|
2687
|
+
action: "skipped",
|
|
2688
|
+
detail: `Not installed (no Codex CLI and no ${dirname4(configPath)}).`
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
return {
|
|
2692
|
+
client: "Codex",
|
|
2693
|
+
action: "printed",
|
|
2694
|
+
detail: `Codex's CLI was not found. Add this to ${configPath}:
|
|
2695
|
+
${codexBlock(serve)}Then fully quit and reopen Codex.`
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2698
|
+
let existing;
|
|
2699
|
+
try {
|
|
2700
|
+
existing = await cli.get(SERVER_NAME);
|
|
2701
|
+
} catch (err) {
|
|
2702
|
+
return { client: "Codex", action: "error", detail: `Could not inspect Codex MCP settings: ${errorMessage(err)}` };
|
|
2703
|
+
}
|
|
2704
|
+
if (existing?.serve && sameServeCommand(existing.serve, serve)) {
|
|
2705
|
+
return { client: "Codex", action: "skipped", detail: "Already registered." };
|
|
2706
|
+
}
|
|
2707
|
+
if (existing && !existing.serve) {
|
|
2708
|
+
return {
|
|
2709
|
+
client: "Codex",
|
|
2710
|
+
action: "error",
|
|
2711
|
+
detail: `A non-stdio or unrecognised "${SERVER_NAME}" entry already exists. It was left unchanged.`
|
|
2712
|
+
};
|
|
2713
|
+
}
|
|
2714
|
+
const verb = existing ? "replace its existing LLMnesia MCP registration" : "register the LLMnesia MCP server";
|
|
2715
|
+
const ok = await confirm(
|
|
2716
|
+
`Codex: ${verb}?
|
|
2717
|
+
codex mcp add ${SERVER_NAME} -- ${serve.command} ${serve.args.join(" ")}`
|
|
2718
|
+
);
|
|
2719
|
+
if (!ok) {
|
|
2720
|
+
return { client: "Codex", action: "declined", detail: "Skipped by user." };
|
|
2721
|
+
}
|
|
2722
|
+
if (existing) {
|
|
2723
|
+
try {
|
|
2724
|
+
await cli.remove(SERVER_NAME);
|
|
2725
|
+
} catch (err) {
|
|
2726
|
+
return { client: "Codex", action: "error", detail: `Could not remove the old registration: ${errorMessage(err)}` };
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
try {
|
|
2730
|
+
await cli.add(SERVER_NAME, serve);
|
|
2731
|
+
} catch (err) {
|
|
2732
|
+
if (existing?.serve) {
|
|
2733
|
+
try {
|
|
2734
|
+
await cli.add(SERVER_NAME, existing.serve);
|
|
2735
|
+
} catch (restoreErr) {
|
|
2736
|
+
return {
|
|
2737
|
+
client: "Codex",
|
|
2738
|
+
action: "error",
|
|
2739
|
+
detail: `Registration failed (${errorMessage(err)}) and restoring the previous entry also failed (${errorMessage(restoreErr)}).`
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
return { client: "Codex", action: "error", detail: `codex mcp add failed: ${errorMessage(err)}` };
|
|
2744
|
+
}
|
|
2745
|
+
return {
|
|
2746
|
+
client: "Codex",
|
|
2747
|
+
action: "registered",
|
|
2748
|
+
detail: `Ran: codex mcp add ${SERVER_NAME} -- ${serve.command} ${serve.args.join(" ")}`
|
|
2749
|
+
};
|
|
2750
|
+
}
|
|
2071
2751
|
async function registerJsonClient(clientLabel, configPath, serve, confirm, now) {
|
|
2072
2752
|
if (!await clientDirExists(configPath)) {
|
|
2073
2753
|
return {
|
|
@@ -2127,12 +2807,7 @@ async function registerClients(options) {
|
|
|
2127
2807
|
results.push(await registerJsonClient("Claude Desktop", claudeDesktop, options.serve, options.confirm, now));
|
|
2128
2808
|
}
|
|
2129
2809
|
results.push(await registerJsonClient("Cursor", cursor, options.serve, options.confirm, now));
|
|
2130
|
-
results.push(
|
|
2131
|
-
client: "Codex",
|
|
2132
|
-
action: "printed",
|
|
2133
|
-
detail: `Add this to ${codex} yourself (TOML is fragile to auto-edit):
|
|
2134
|
-
${codexBlock(options.serve)}`
|
|
2135
|
-
});
|
|
2810
|
+
results.push(await registerCodex(options.serve, options.codexCli ?? realCodexCli, codex, options.confirm));
|
|
2136
2811
|
results.push({
|
|
2137
2812
|
client: "Other MCP clients (Windsurf, Zed, LM Studio, ...)",
|
|
2138
2813
|
action: "printed",
|
|
@@ -2157,6 +2832,21 @@ async function unregisterClaudeCode(cli) {
|
|
|
2157
2832
|
};
|
|
2158
2833
|
}
|
|
2159
2834
|
}
|
|
2835
|
+
async function unregisterCodex(cli) {
|
|
2836
|
+
if (!await cli.detect()) {
|
|
2837
|
+
return { client: "Codex", action: "skipped", detail: "`codex` not found; no automatic registration to remove." };
|
|
2838
|
+
}
|
|
2839
|
+
try {
|
|
2840
|
+
const existing = await cli.get(SERVER_NAME);
|
|
2841
|
+
if (!existing) {
|
|
2842
|
+
return { client: "Codex", action: "skipped", detail: "Not registered." };
|
|
2843
|
+
}
|
|
2844
|
+
await cli.remove(SERVER_NAME);
|
|
2845
|
+
return { client: "Codex", action: "registered", detail: `Ran: codex mcp remove ${SERVER_NAME}` };
|
|
2846
|
+
} catch (err) {
|
|
2847
|
+
return { client: "Codex", action: "error", detail: `codex mcp remove failed: ${errorMessage(err)}` };
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2160
2850
|
async function unregisterJsonClient(clientLabel, configPath, now) {
|
|
2161
2851
|
let data;
|
|
2162
2852
|
let existed;
|
|
@@ -2190,10 +2880,11 @@ async function unregisterClients(options = {}) {
|
|
|
2190
2880
|
results.push(await unregisterJsonClient("Claude Desktop", claudeDesktop, now));
|
|
2191
2881
|
}
|
|
2192
2882
|
results.push(await unregisterJsonClient("Cursor", cursor, now));
|
|
2883
|
+
results.push(await unregisterCodex(options.codexCli ?? realCodexCli));
|
|
2193
2884
|
results.push({
|
|
2194
|
-
client: "
|
|
2885
|
+
client: "Other MCP clients",
|
|
2195
2886
|
action: "skipped",
|
|
2196
|
-
detail: "These were only
|
|
2887
|
+
detail: "These were only shown as copy-paste blocks, never auto-edited \u2014 remove the block yourself if you added it."
|
|
2197
2888
|
});
|
|
2198
2889
|
return results;
|
|
2199
2890
|
}
|
|
@@ -2468,7 +3159,7 @@ function checkCodex(home2) {
|
|
|
2468
3159
|
return {
|
|
2469
3160
|
name: "Codex",
|
|
2470
3161
|
status: "missing",
|
|
2471
|
-
detail: `Codex is installed but not configured. llmnesia-mcp install
|
|
3162
|
+
detail: `Codex is installed but not configured. Run: llmnesia-mcp install (it uses Codex's CLI when available).`
|
|
2472
3163
|
};
|
|
2473
3164
|
}
|
|
2474
3165
|
async function runDoctor(options = {}) {
|