@memoraone/mcp 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +584 -57
- package/dist/daemon.cjs +204 -69
- package/dist/index.cjs +93 -66
- package/package.json +11 -10
package/dist/cli.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var require_package = __commonJS({
|
|
|
30
30
|
"package.json"(exports2, module2) {
|
|
31
31
|
module2.exports = {
|
|
32
32
|
name: "@memoraone/mcp",
|
|
33
|
-
version: "0.1.
|
|
33
|
+
version: "0.1.24",
|
|
34
34
|
type: "module",
|
|
35
35
|
main: "dist/index.cjs",
|
|
36
36
|
bin: {
|
|
@@ -67,22 +67,84 @@ var require_package = __commonJS({
|
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
// src/cli.ts
|
|
70
|
-
var
|
|
70
|
+
var path5 = __toESM(require("path"), 1);
|
|
71
71
|
var net = __toESM(require("net"), 1);
|
|
72
|
-
var
|
|
72
|
+
var import_node_child_process2 = require("child_process");
|
|
73
73
|
|
|
74
74
|
// src/socketPaths.ts
|
|
75
75
|
var os = __toESM(require("os"), 1);
|
|
76
76
|
var path = __toESM(require("path"), 1);
|
|
77
77
|
var fs = __toESM(require("fs"), 1);
|
|
78
78
|
var BASE_DIR = process.env.MEMORAONE_MCP_LOCK_DIR || path.join(os.homedir(), ".memoraone-mcp");
|
|
79
|
-
|
|
79
|
+
var SOCKET_PROJECT_ID_RE = /^mcp-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:-([a-z-]+))?\.sock$/i;
|
|
80
|
+
function getMcpBaseDir() {
|
|
81
|
+
return BASE_DIR;
|
|
82
|
+
}
|
|
83
|
+
var IDE_TYPES = ["cursor", "copilot-vscode", "jetbrains"];
|
|
84
|
+
var IDE_TYPE_SET = new Set(IDE_TYPES);
|
|
85
|
+
function parseIdeType(value) {
|
|
86
|
+
if (value === void 0 || value.trim() === "" || !IDE_TYPE_SET.has(value)) {
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
function resolveIdeTypeFromEnv(env = process.env) {
|
|
92
|
+
return parseIdeType(env.MEMORAONE_IDE_TYPE);
|
|
93
|
+
}
|
|
94
|
+
function parseIdeTypeFromCommandLine(commandLine) {
|
|
95
|
+
const match = commandLine.match(/--ide\s+(cursor|copilot-vscode|jetbrains)(?:\s|$)/);
|
|
96
|
+
return match ? match[1] : void 0;
|
|
97
|
+
}
|
|
98
|
+
function buildDaemonSpawnArgs(scriptPath, projectId, env = process.env) {
|
|
99
|
+
const args2 = [scriptPath, "--daemon", "--project-id", projectId];
|
|
100
|
+
const ideType = resolveIdeTypeFromEnv(env);
|
|
101
|
+
if (ideType) {
|
|
102
|
+
args2.push("--ide", ideType);
|
|
103
|
+
}
|
|
104
|
+
return args2;
|
|
105
|
+
}
|
|
106
|
+
function getSocketPath(projectId, ideType) {
|
|
107
|
+
if (ideType) {
|
|
108
|
+
return path.join(BASE_DIR, `mcp-${projectId}-${ideType}.sock`);
|
|
109
|
+
}
|
|
80
110
|
return path.join(BASE_DIR, `mcp-${projectId}.sock`);
|
|
81
111
|
}
|
|
112
|
+
function getDaemonSocketPath(projectId, env = process.env) {
|
|
113
|
+
return getSocketPath(projectId, resolveIdeTypeFromEnv(env));
|
|
114
|
+
}
|
|
82
115
|
function ensureBaseDir() {
|
|
83
116
|
fs.mkdirSync(BASE_DIR, { recursive: true });
|
|
84
117
|
return BASE_DIR;
|
|
85
118
|
}
|
|
119
|
+
function isMemoraoneSocketFilename(filename) {
|
|
120
|
+
return SOCKET_PROJECT_ID_RE.test(path.basename(filename));
|
|
121
|
+
}
|
|
122
|
+
function extractProjectIdFromSocketFilename(filename) {
|
|
123
|
+
const match = path.basename(filename).match(SOCKET_PROJECT_ID_RE);
|
|
124
|
+
return match ? match[1].toLowerCase() : null;
|
|
125
|
+
}
|
|
126
|
+
function isSocketFilenameForProject(filename, projectId) {
|
|
127
|
+
const extracted = extractProjectIdFromSocketFilename(filename);
|
|
128
|
+
return extracted !== null && extracted === projectId.trim().toLowerCase();
|
|
129
|
+
}
|
|
130
|
+
function extractIdeTypeFromSocketFilename(filename) {
|
|
131
|
+
const match = path.basename(filename).match(SOCKET_PROJECT_ID_RE);
|
|
132
|
+
if (!match) return null;
|
|
133
|
+
const suffix = match[2];
|
|
134
|
+
if (suffix === void 0) return "legacy";
|
|
135
|
+
if (IDE_TYPE_SET.has(suffix)) return suffix;
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
function isSocketFilenameForProjectAndIde(filename, projectId, ide) {
|
|
139
|
+
if (!isSocketFilenameForProject(filename, projectId)) return false;
|
|
140
|
+
if (ide === void 0) return true;
|
|
141
|
+
const socketIde = extractIdeTypeFromSocketFilename(filename);
|
|
142
|
+
if (socketIde === null) return false;
|
|
143
|
+
if (ide === "cursor") {
|
|
144
|
+
return socketIde === "cursor" || socketIde === "legacy";
|
|
145
|
+
}
|
|
146
|
+
return socketIde === ide;
|
|
147
|
+
}
|
|
86
148
|
|
|
87
149
|
// src/projectBinding.ts
|
|
88
150
|
var fs2 = __toESM(require("fs/promises"), 1);
|
|
@@ -230,25 +292,447 @@ function encodeResolvedBinding(binding) {
|
|
|
230
292
|
}
|
|
231
293
|
|
|
232
294
|
// src/setupIdeFiles.ts
|
|
295
|
+
var fs4 = __toESM(require("fs/promises"), 1);
|
|
296
|
+
var path4 = __toESM(require("path"), 1);
|
|
297
|
+
|
|
298
|
+
// src/cleanup.ts
|
|
233
299
|
var fs3 = __toESM(require("fs/promises"), 1);
|
|
234
300
|
var path3 = __toESM(require("path"), 1);
|
|
301
|
+
var readline = __toESM(require("readline/promises"), 1);
|
|
302
|
+
var import_node_child_process = require("child_process");
|
|
303
|
+
var import_node_util = require("util");
|
|
304
|
+
var import_node_process = require("process");
|
|
305
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
306
|
+
var DAEMON_PROJECT_ID_RE = /--project-id\s+([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
307
|
+
var PROJECT_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
308
|
+
var MEMORAONE_MCP_COMMAND_RE = /memoraone-mcp|memoraOne-mcp|@memoraone\/mcp/;
|
|
309
|
+
var CLEANUP_PROJECT_ID_REQUIRED_ERROR = "Provide --project-id <id> or run from a folder containing memoraone.m1.";
|
|
310
|
+
function isMemoraoneMcpCommandLine(commandLine) {
|
|
311
|
+
return MEMORAONE_MCP_COMMAND_RE.test(commandLine);
|
|
312
|
+
}
|
|
313
|
+
function parseDaemonProjectIdFromCommandLine(commandLine) {
|
|
314
|
+
if (!commandLine.includes("--daemon")) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
const match = commandLine.match(DAEMON_PROJECT_ID_RE);
|
|
318
|
+
return match ? match[1].toLowerCase() : null;
|
|
319
|
+
}
|
|
320
|
+
function parseDaemonIdeFromCommandLine(commandLine) {
|
|
321
|
+
if (!commandLine.includes("--daemon")) {
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
return parseIdeTypeFromCommandLine(commandLine);
|
|
325
|
+
}
|
|
326
|
+
function parseDaemonProcessLines(lines) {
|
|
327
|
+
const processes = [];
|
|
328
|
+
for (const line of lines) {
|
|
329
|
+
const trimmed = line.trim();
|
|
330
|
+
if (!trimmed) continue;
|
|
331
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
332
|
+
if (spaceIdx <= 0) continue;
|
|
333
|
+
const pid = Number.parseInt(trimmed.slice(0, spaceIdx), 10);
|
|
334
|
+
if (!Number.isFinite(pid) || pid <= 0) continue;
|
|
335
|
+
const command = trimmed.slice(spaceIdx + 1);
|
|
336
|
+
if (!isMemoraoneMcpCommandLine(command)) continue;
|
|
337
|
+
const projectId = parseDaemonProjectIdFromCommandLine(command);
|
|
338
|
+
if (projectId === null) continue;
|
|
339
|
+
const ide = parseDaemonIdeFromCommandLine(command);
|
|
340
|
+
processes.push({ pid, command, projectId, ...ide !== void 0 ? { ide } : {} });
|
|
341
|
+
}
|
|
342
|
+
return processes;
|
|
343
|
+
}
|
|
344
|
+
function normalizeCleanupProjectId(projectId) {
|
|
345
|
+
const trimmed = projectId.trim();
|
|
346
|
+
if (!PROJECT_ID_RE.test(trimmed)) {
|
|
347
|
+
return { error: `Invalid project id: ${projectId}` };
|
|
348
|
+
}
|
|
349
|
+
return trimmed.toLowerCase();
|
|
350
|
+
}
|
|
351
|
+
async function defaultListDaemonProcesses() {
|
|
352
|
+
const { stdout } = await execFileAsync("ps", ["-eo", "pid=,args="], {
|
|
353
|
+
maxBuffer: 10 * 1024 * 1024
|
|
354
|
+
});
|
|
355
|
+
return parseDaemonProcessLines(stdout.split("\n"));
|
|
356
|
+
}
|
|
357
|
+
async function defaultListSocketPaths(projectId) {
|
|
358
|
+
const baseDir = getMcpBaseDir();
|
|
359
|
+
let entries;
|
|
360
|
+
try {
|
|
361
|
+
entries = await fs3.readdir(baseDir);
|
|
362
|
+
} catch (err) {
|
|
363
|
+
const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
|
|
364
|
+
if (code === "ENOENT") {
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
throw err;
|
|
368
|
+
}
|
|
369
|
+
const paths = [];
|
|
370
|
+
for (const name of entries) {
|
|
371
|
+
if (projectId === null) {
|
|
372
|
+
if (isMemoraoneSocketFilename(name)) {
|
|
373
|
+
paths.push(path3.join(baseDir, name));
|
|
374
|
+
}
|
|
375
|
+
} else if (isSocketFilenameForProject(name, projectId)) {
|
|
376
|
+
paths.push(path3.join(baseDir, name));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return paths.sort();
|
|
380
|
+
}
|
|
381
|
+
function filterSocketPathsByIde(socketPaths, projectId, ide) {
|
|
382
|
+
if (ide === void 0) return socketPaths;
|
|
383
|
+
return socketPaths.filter(
|
|
384
|
+
(socketPath) => isSocketFilenameForProjectAndIde(path3.basename(socketPath), projectId, ide)
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
async function defaultKillProcess(pid) {
|
|
388
|
+
process.kill(pid, "SIGTERM");
|
|
389
|
+
}
|
|
390
|
+
async function defaultRemoveSocket(socketPath) {
|
|
391
|
+
await fs3.unlink(socketPath);
|
|
392
|
+
}
|
|
393
|
+
async function defaultConfirm(message) {
|
|
394
|
+
if (!import_node_process.stdin.isTTY) {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
const rl = readline.createInterface({ input: import_node_process.stdin, output: import_node_process.stdout });
|
|
398
|
+
try {
|
|
399
|
+
const answer = await rl.question(`${message} [y/N] `);
|
|
400
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
401
|
+
} finally {
|
|
402
|
+
rl.close();
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async function resolveCleanupTarget(cwd) {
|
|
406
|
+
try {
|
|
407
|
+
const binding = await resolveAuthoritativeBinding([path3.resolve(cwd)]);
|
|
408
|
+
return {
|
|
409
|
+
workspaceRoot: binding.workspaceRoot,
|
|
410
|
+
m1Path: binding.m1Path,
|
|
411
|
+
projectId: binding.projectId
|
|
412
|
+
};
|
|
413
|
+
} catch {
|
|
414
|
+
return { error: CLEANUP_PROJECT_ID_REQUIRED_ERROR };
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function filterProcessesForScope(processes, projectId) {
|
|
418
|
+
if (projectId === null) {
|
|
419
|
+
return { matching: processes, skipped: [] };
|
|
420
|
+
}
|
|
421
|
+
const normalized = projectId.toLowerCase();
|
|
422
|
+
const matching = [];
|
|
423
|
+
const skipped = [];
|
|
424
|
+
for (const proc of processes) {
|
|
425
|
+
if (proc.projectId === normalized) {
|
|
426
|
+
matching.push(proc);
|
|
427
|
+
} else {
|
|
428
|
+
skipped.push(proc);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return { matching, skipped };
|
|
432
|
+
}
|
|
433
|
+
function logPrefix(dryRun) {
|
|
434
|
+
return dryRun ? "[cleanup][dry-run]" : "[cleanup]";
|
|
435
|
+
}
|
|
436
|
+
function logReconnectNotice(prefix, ide) {
|
|
437
|
+
if (ide) {
|
|
438
|
+
console.log(
|
|
439
|
+
`${prefix} Note: Valid ${ide} connections for this project may disconnect temporarily; they should reconnect automatically. Stale connections will remain cleared.`
|
|
440
|
+
);
|
|
441
|
+
} else {
|
|
442
|
+
console.log(
|
|
443
|
+
`${prefix} Note: Valid IDE connections for this project may disconnect temporarily; they should reconnect automatically. Stale connections will remain cleared.`
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
async function runCleanup(opts) {
|
|
448
|
+
const listProcesses = opts.listProcesses ?? defaultListDaemonProcesses;
|
|
449
|
+
const listSocketPaths = opts.listSocketPaths ?? defaultListSocketPaths;
|
|
450
|
+
const killProcess = opts.killProcess ?? defaultKillProcess;
|
|
451
|
+
const removeSocket = opts.removeSocket ?? defaultRemoveSocket;
|
|
452
|
+
const confirm = opts.confirm ?? defaultConfirm;
|
|
453
|
+
const prefix = logPrefix(opts.dryRun);
|
|
454
|
+
let targetProjectId = null;
|
|
455
|
+
let workspaceRoot;
|
|
456
|
+
let m1Path;
|
|
457
|
+
if (opts.allProjects) {
|
|
458
|
+
if (opts.projectId) {
|
|
459
|
+
return {
|
|
460
|
+
exitCode: 1,
|
|
461
|
+
killedPids: [],
|
|
462
|
+
removedSockets: [],
|
|
463
|
+
skippedProcesses: [],
|
|
464
|
+
error: "Cannot combine --all-projects with --project-id."
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
console.log(`${prefix} Mode: all projects (--all-projects)`);
|
|
468
|
+
console.warn(
|
|
469
|
+
`${prefix} WARNING: This stops every MemoraOne MCP daemon and removes all project sockets under ${getMcpBaseDir()}.`
|
|
470
|
+
);
|
|
471
|
+
} else if (opts.projectId) {
|
|
472
|
+
const normalized = normalizeCleanupProjectId(opts.projectId);
|
|
473
|
+
if (typeof normalized !== "string") {
|
|
474
|
+
return { exitCode: 1, killedPids: [], removedSockets: [], skippedProcesses: [], error: normalized.error };
|
|
475
|
+
}
|
|
476
|
+
targetProjectId = normalized;
|
|
477
|
+
console.log(`${prefix} Project id: ${targetProjectId}`);
|
|
478
|
+
if (opts.ide) {
|
|
479
|
+
console.log(`${prefix} IDE filter: ${opts.ide}`);
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
const target = await resolveCleanupTarget(opts.cwd);
|
|
483
|
+
if ("error" in target) {
|
|
484
|
+
return { exitCode: 1, killedPids: [], removedSockets: [], skippedProcesses: [], error: target.error };
|
|
485
|
+
}
|
|
486
|
+
targetProjectId = target.projectId;
|
|
487
|
+
workspaceRoot = target.workspaceRoot;
|
|
488
|
+
m1Path = target.m1Path;
|
|
489
|
+
console.log(`${prefix} Workspace root: ${workspaceRoot}`);
|
|
490
|
+
console.log(`${prefix} memoraone.m1: ${m1Path}`);
|
|
491
|
+
console.log(`${prefix} Project id: ${targetProjectId}`);
|
|
492
|
+
if (opts.ide) {
|
|
493
|
+
console.log(`${prefix} IDE filter: ${opts.ide}`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (targetProjectId !== null || opts.ide) {
|
|
497
|
+
logReconnectNotice(prefix, opts.ide);
|
|
498
|
+
}
|
|
499
|
+
const allDaemonProcesses = await listProcesses();
|
|
500
|
+
const { matching: projectProcesses, skipped: skippedProcesses } = filterProcessesForScope(
|
|
501
|
+
allDaemonProcesses,
|
|
502
|
+
targetProjectId
|
|
503
|
+
);
|
|
504
|
+
let processesToStop = projectProcesses;
|
|
505
|
+
const ideSkippedProcesses = [];
|
|
506
|
+
if (opts.ide && targetProjectId !== null) {
|
|
507
|
+
processesToStop = [];
|
|
508
|
+
for (const proc of projectProcesses) {
|
|
509
|
+
if (proc.ide === opts.ide) {
|
|
510
|
+
processesToStop.push(proc);
|
|
511
|
+
} else if (proc.ide === void 0) {
|
|
512
|
+
ideSkippedProcesses.push(proc);
|
|
513
|
+
console.log(
|
|
514
|
+
`${prefix} Skipped daemon pid=${proc.pid} because IDE could not be safely determined.`
|
|
515
|
+
);
|
|
516
|
+
} else {
|
|
517
|
+
ideSkippedProcesses.push(proc);
|
|
518
|
+
console.log(
|
|
519
|
+
`${prefix} Skipped daemon pid=${proc.pid} (IDE ${proc.ide} does not match filter ${opts.ide}).`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const allSocketPaths = await listSocketPaths(targetProjectId);
|
|
525
|
+
const socketPaths = targetProjectId === null ? allSocketPaths : filterSocketPathsByIde(allSocketPaths, targetProjectId, opts.ide);
|
|
526
|
+
if (opts.allProjects) {
|
|
527
|
+
const projectIds = /* @__PURE__ */ new Set();
|
|
528
|
+
for (const proc of processesToStop) {
|
|
529
|
+
projectIds.add(proc.projectId);
|
|
530
|
+
}
|
|
531
|
+
for (const socketPath of socketPaths) {
|
|
532
|
+
const id = extractProjectIdFromSocketFilename(path3.basename(socketPath));
|
|
533
|
+
if (id) projectIds.add(id);
|
|
534
|
+
}
|
|
535
|
+
console.log(`${prefix} Projects affected: ${projectIds.size ? [...projectIds].sort().join(", ") : "(none found)"}`);
|
|
536
|
+
}
|
|
537
|
+
if (processesToStop.length) {
|
|
538
|
+
console.log(`${prefix} Daemon processes to stop:`);
|
|
539
|
+
for (const proc of processesToStop) {
|
|
540
|
+
const ideLabel = proc.ide ? ` ide=${proc.ide}` : "";
|
|
541
|
+
console.log(`${prefix} pid=${proc.pid} project=${proc.projectId}${ideLabel}`);
|
|
542
|
+
}
|
|
543
|
+
} else if (ideSkippedProcesses.length) {
|
|
544
|
+
console.log(`${prefix} No matching daemon processes for IDE filter ${opts.ide}.`);
|
|
545
|
+
} else {
|
|
546
|
+
console.log(`${prefix} No matching daemon processes found.`);
|
|
547
|
+
}
|
|
548
|
+
if (socketPaths.length) {
|
|
549
|
+
console.log(`${prefix} Sockets to remove:`);
|
|
550
|
+
for (const socketPath of socketPaths) {
|
|
551
|
+
console.log(`${prefix} ${socketPath}`);
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
console.log(`${prefix} No matching sockets found under ${getMcpBaseDir()}.`);
|
|
555
|
+
}
|
|
556
|
+
if (skippedProcesses.length) {
|
|
557
|
+
console.log(`${prefix} Skipped unrelated daemon processes:`);
|
|
558
|
+
for (const proc of skippedProcesses) {
|
|
559
|
+
console.log(`${prefix} pid=${proc.pid} project=${proc.projectId}`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (opts.allProjects && !opts.dryRun) {
|
|
563
|
+
const ok = opts.assumeYes ? true : await confirm(`${prefix} Proceed with cleanup for ALL projects?`);
|
|
564
|
+
if (!ok) {
|
|
565
|
+
console.log(`${prefix} Aborted.`);
|
|
566
|
+
return {
|
|
567
|
+
exitCode: 1,
|
|
568
|
+
workspaceRoot,
|
|
569
|
+
m1Path,
|
|
570
|
+
projectId: targetProjectId ?? void 0,
|
|
571
|
+
killedPids: [],
|
|
572
|
+
removedSockets: [],
|
|
573
|
+
skippedProcesses: [...skippedProcesses, ...ideSkippedProcesses],
|
|
574
|
+
error: opts.assumeYes ? void 0 : "Aborted (--all requires --yes in non-interactive mode)"
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const killedPids = [];
|
|
579
|
+
const removedSockets = [];
|
|
580
|
+
if (opts.dryRun) {
|
|
581
|
+
console.log(`${prefix} Dry run complete \u2014 no processes stopped, no sockets removed.`);
|
|
582
|
+
return {
|
|
583
|
+
exitCode: 0,
|
|
584
|
+
workspaceRoot,
|
|
585
|
+
m1Path,
|
|
586
|
+
projectId: targetProjectId ?? void 0,
|
|
587
|
+
killedPids: processesToStop.map((p) => p.pid),
|
|
588
|
+
removedSockets: socketPaths,
|
|
589
|
+
skippedProcesses: [...skippedProcesses, ...ideSkippedProcesses]
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
for (const proc of processesToStop) {
|
|
593
|
+
try {
|
|
594
|
+
await killProcess(proc.pid);
|
|
595
|
+
killedPids.push(proc.pid);
|
|
596
|
+
console.log(`${prefix} Stopped daemon pid=${proc.pid} project=${proc.projectId}`);
|
|
597
|
+
} catch (err) {
|
|
598
|
+
console.warn(`${prefix} Could not stop pid=${proc.pid}: ${String(err)}`);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (killedPids.length) {
|
|
602
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
603
|
+
}
|
|
604
|
+
for (const socketPath of socketPaths) {
|
|
605
|
+
try {
|
|
606
|
+
await removeSocket(socketPath);
|
|
607
|
+
removedSockets.push(socketPath);
|
|
608
|
+
console.log(`${prefix} Removed socket ${socketPath}`);
|
|
609
|
+
} catch (err) {
|
|
610
|
+
const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
|
|
611
|
+
if (code !== "ENOENT") {
|
|
612
|
+
console.warn(`${prefix} Could not remove socket ${socketPath}: ${String(err)}`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
console.log(`${prefix} Done. stopped=${killedPids.length} socketsRemoved=${removedSockets.length}`);
|
|
617
|
+
return {
|
|
618
|
+
exitCode: 0,
|
|
619
|
+
workspaceRoot,
|
|
620
|
+
m1Path,
|
|
621
|
+
projectId: targetProjectId ?? void 0,
|
|
622
|
+
killedPids,
|
|
623
|
+
removedSockets,
|
|
624
|
+
skippedProcesses: [...skippedProcesses, ...ideSkippedProcesses]
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
function parseCleanupFlags(argv) {
|
|
628
|
+
let dryRun = false;
|
|
629
|
+
let allProjects = false;
|
|
630
|
+
let assumeYes = false;
|
|
631
|
+
let projectId;
|
|
632
|
+
let ide;
|
|
633
|
+
let invalidIde;
|
|
634
|
+
const unknown = [];
|
|
635
|
+
for (let i = 0; i < argv.length; i++) {
|
|
636
|
+
const arg = argv[i];
|
|
637
|
+
if (arg === "--dry-run") dryRun = true;
|
|
638
|
+
else if (arg === "--all-projects" || arg === "--all") allProjects = true;
|
|
639
|
+
else if (arg === "--yes" || arg === "-y") assumeYes = true;
|
|
640
|
+
else if (arg === "--project-id") {
|
|
641
|
+
if (i + 1 >= argv.length) {
|
|
642
|
+
unknown.push("--project-id (missing value)");
|
|
643
|
+
} else {
|
|
644
|
+
projectId = argv[++i];
|
|
645
|
+
}
|
|
646
|
+
} else if (arg === "--ide") {
|
|
647
|
+
if (i + 1 >= argv.length) {
|
|
648
|
+
unknown.push("--ide (missing value)");
|
|
649
|
+
} else {
|
|
650
|
+
const value = argv[++i];
|
|
651
|
+
if (IDE_TYPES.includes(value)) {
|
|
652
|
+
ide = value;
|
|
653
|
+
} else {
|
|
654
|
+
invalidIde = value;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
} else if (arg.startsWith("-")) unknown.push(arg);
|
|
658
|
+
else unknown.push(arg);
|
|
659
|
+
}
|
|
660
|
+
return { dryRun, allProjects, assumeYes, projectId, ide, invalidIde, unknown };
|
|
661
|
+
}
|
|
662
|
+
async function cliCleanup(argv) {
|
|
663
|
+
const { dryRun, allProjects, assumeYes, projectId, ide, invalidIde, unknown } = parseCleanupFlags(argv);
|
|
664
|
+
if (invalidIde) {
|
|
665
|
+
console.error(
|
|
666
|
+
`[cleanup] Invalid --ide value: ${invalidIde}. Expected one of: ${IDE_TYPES.join(", ")}.`
|
|
667
|
+
);
|
|
668
|
+
return 1;
|
|
669
|
+
}
|
|
670
|
+
if (unknown.length) {
|
|
671
|
+
console.error(`[cleanup] Unknown option(s): ${unknown.join(", ")}`);
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
const result = await runCleanup({
|
|
675
|
+
cwd: process.cwd(),
|
|
676
|
+
dryRun,
|
|
677
|
+
allProjects,
|
|
678
|
+
assumeYes,
|
|
679
|
+
projectId,
|
|
680
|
+
ide
|
|
681
|
+
});
|
|
682
|
+
if (result.error) {
|
|
683
|
+
console.error(`[cleanup] ${result.error}`);
|
|
684
|
+
}
|
|
685
|
+
return result.exitCode;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// src/configUtils.ts
|
|
689
|
+
var PROD_API_URL = "https://api.memoraone.com";
|
|
690
|
+
|
|
691
|
+
// src/setupIdeFiles.ts
|
|
235
692
|
var MANAGED_MARKER = "<!-- MemoraOne managed IDE helper -->";
|
|
236
693
|
var GITIGNORE_MEMORAONE_COMMENT = "# MemoraOne local project binding / API key";
|
|
237
694
|
var GITIGNORE_MEMORAONE_ENTRY = "memoraone.m1";
|
|
238
|
-
var
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
695
|
+
var MCP_PACKAGE_ARG = "@memoraone/mcp@latest";
|
|
696
|
+
var VSCODE_MCP_SERVERS_KEY = "servers";
|
|
697
|
+
function isProdBoundEnvironment(environment) {
|
|
698
|
+
if (environment === void 0) return true;
|
|
699
|
+
const lower = environment.toLowerCase();
|
|
700
|
+
return lower === "production" || lower === "prod";
|
|
701
|
+
}
|
|
702
|
+
async function readMemoraoneM1Environment(repoRoot) {
|
|
703
|
+
const m1Path = path4.join(repoRoot, "memoraone.m1");
|
|
704
|
+
try {
|
|
705
|
+
const content = await fs4.readFile(m1Path, "utf8");
|
|
706
|
+
const parsed = JSON.parse(content);
|
|
707
|
+
if (typeof parsed?.environment === "string") {
|
|
708
|
+
const trimmed = parsed.environment.trim();
|
|
709
|
+
if (trimmed !== "") return trimmed;
|
|
710
|
+
}
|
|
711
|
+
} catch {
|
|
712
|
+
}
|
|
713
|
+
return void 0;
|
|
714
|
+
}
|
|
715
|
+
async function buildMemoraoneMcpServerEntry(repoRoot) {
|
|
716
|
+
const entry = {
|
|
717
|
+
command: "npx",
|
|
718
|
+
args: ["-y", MCP_PACKAGE_ARG]
|
|
719
|
+
};
|
|
720
|
+
const environment = await readMemoraoneM1Environment(repoRoot);
|
|
721
|
+
if (isProdBoundEnvironment(environment)) {
|
|
722
|
+
entry.env = { MEMORAONE_API_URL: PROD_API_URL };
|
|
723
|
+
}
|
|
724
|
+
return entry;
|
|
725
|
+
}
|
|
242
726
|
function assertUnderRepoRoot(repoRoot, absPath) {
|
|
243
|
-
const normRoot =
|
|
244
|
-
const normPath =
|
|
245
|
-
if (normPath !==
|
|
727
|
+
const normRoot = path4.resolve(repoRoot) + path4.sep;
|
|
728
|
+
const normPath = path4.resolve(absPath);
|
|
729
|
+
if (normPath !== path4.resolve(repoRoot) && !normPath.startsWith(normRoot)) {
|
|
246
730
|
throw new Error(`[setup-ide-files] Refusing to write outside repo root: ${absPath}`);
|
|
247
731
|
}
|
|
248
732
|
}
|
|
249
733
|
async function pathExists(filePath) {
|
|
250
734
|
try {
|
|
251
|
-
await
|
|
735
|
+
await fs4.access(filePath);
|
|
252
736
|
return true;
|
|
253
737
|
} catch {
|
|
254
738
|
return false;
|
|
@@ -269,12 +753,12 @@ ${GITIGNORE_MEMORAONE_ENTRY}
|
|
|
269
753
|
}
|
|
270
754
|
async function ensureGitignoreMemoraone(repoRoot, opts) {
|
|
271
755
|
if (opts.noGitignore) return "skipped";
|
|
272
|
-
const abs =
|
|
756
|
+
const abs = path4.join(repoRoot, ".gitignore");
|
|
273
757
|
assertUnderRepoRoot(repoRoot, abs);
|
|
274
758
|
let prior = "";
|
|
275
759
|
let existed = false;
|
|
276
760
|
try {
|
|
277
|
-
prior = await
|
|
761
|
+
prior = await fs4.readFile(abs, "utf8");
|
|
278
762
|
existed = true;
|
|
279
763
|
} catch (err) {
|
|
280
764
|
const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
|
|
@@ -285,22 +769,22 @@ async function ensureGitignoreMemoraone(repoRoot, opts) {
|
|
|
285
769
|
const separator = existed && prior.length > 0 ? prior.endsWith("\n") ? "\n" : "\n\n" : "";
|
|
286
770
|
const next = (existed ? prior : "") + separator + block;
|
|
287
771
|
if (opts.dryRun) return existed ? "updated" : "created";
|
|
288
|
-
await
|
|
772
|
+
await fs4.writeFile(abs, next, "utf8");
|
|
289
773
|
return existed ? "updated" : "created";
|
|
290
774
|
}
|
|
291
775
|
async function findRepoRoot(startDir) {
|
|
292
|
-
let current =
|
|
293
|
-
const root =
|
|
776
|
+
let current = path4.resolve(startDir);
|
|
777
|
+
const root = path4.parse(current).root;
|
|
294
778
|
while (true) {
|
|
295
|
-
const gitPath =
|
|
296
|
-
const m1Path =
|
|
779
|
+
const gitPath = path4.join(current, ".git");
|
|
780
|
+
const m1Path = path4.join(current, "memoraone.m1");
|
|
297
781
|
if (await pathExists(gitPath) || await pathExists(m1Path)) {
|
|
298
782
|
return current;
|
|
299
783
|
}
|
|
300
784
|
if (current === root) {
|
|
301
785
|
return null;
|
|
302
786
|
}
|
|
303
|
-
current =
|
|
787
|
+
current = path4.dirname(current);
|
|
304
788
|
}
|
|
305
789
|
}
|
|
306
790
|
function stripLeadingLineComments(text) {
|
|
@@ -346,59 +830,70 @@ function mcpJsonHeader() {
|
|
|
346
830
|
return `// ${MANAGED_MARKER}
|
|
347
831
|
`;
|
|
348
832
|
}
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
833
|
+
function extractExistingMcpServers(existing) {
|
|
834
|
+
if (typeof existing.servers === "object" && existing.servers !== null && !Array.isArray(existing.servers)) {
|
|
835
|
+
return { ...existing.servers };
|
|
836
|
+
}
|
|
837
|
+
if (typeof existing.mcpServers === "object" && existing.mcpServers !== null && !Array.isArray(existing.mcpServers)) {
|
|
838
|
+
return { ...existing.mcpServers };
|
|
839
|
+
}
|
|
840
|
+
return {};
|
|
841
|
+
}
|
|
842
|
+
function buildMcpJsonBody(existing, memoraoneServer) {
|
|
843
|
+
const base = existing && typeof existing === "object" ? { ...existing } : { [VSCODE_MCP_SERVERS_KEY]: {} };
|
|
844
|
+
const servers = extractExistingMcpServers(base);
|
|
845
|
+
servers.memoraone = memoraoneServer;
|
|
846
|
+
const { mcpServers: _legacy, ...rest } = base;
|
|
847
|
+
const merged = { ...rest, [VSCODE_MCP_SERVERS_KEY]: servers };
|
|
354
848
|
return mcpJsonHeader() + JSON.stringify(merged, null, 2) + "\n";
|
|
355
849
|
}
|
|
356
850
|
async function writeManagedMarkdown(repoRoot, relPath, fullContent, opts) {
|
|
357
|
-
const abs =
|
|
851
|
+
const abs = path4.join(repoRoot, relPath);
|
|
358
852
|
assertUnderRepoRoot(repoRoot, abs);
|
|
359
853
|
let prior = "";
|
|
360
854
|
let existed = false;
|
|
361
855
|
try {
|
|
362
|
-
prior = await
|
|
856
|
+
prior = await fs4.readFile(abs, "utf8");
|
|
363
857
|
existed = true;
|
|
364
858
|
} catch (err) {
|
|
365
859
|
if (err?.code !== "ENOENT") throw err;
|
|
366
860
|
}
|
|
367
861
|
if (!existed) {
|
|
368
862
|
if (opts.dryRun) return "created";
|
|
369
|
-
await
|
|
370
|
-
await
|
|
863
|
+
await fs4.mkdir(path4.dirname(abs), { recursive: true });
|
|
864
|
+
await fs4.writeFile(abs, fullContent, "utf8");
|
|
371
865
|
return "created";
|
|
372
866
|
}
|
|
373
867
|
if (prior.includes(MANAGED_MARKER)) {
|
|
374
868
|
if (prior === fullContent) return "skipped";
|
|
375
869
|
if (opts.dryRun) return "updated";
|
|
376
|
-
await
|
|
377
|
-
await
|
|
870
|
+
await fs4.mkdir(path4.dirname(abs), { recursive: true });
|
|
871
|
+
await fs4.writeFile(abs, fullContent, "utf8");
|
|
378
872
|
return "updated";
|
|
379
873
|
}
|
|
380
874
|
if (!opts.force) return "skipped-untracked";
|
|
381
875
|
if (opts.dryRun) return "updated";
|
|
382
|
-
await
|
|
383
|
-
await
|
|
876
|
+
await fs4.mkdir(path4.dirname(abs), { recursive: true });
|
|
877
|
+
await fs4.writeFile(abs, fullContent, "utf8");
|
|
384
878
|
return "updated";
|
|
385
879
|
}
|
|
386
880
|
async function writeMcpJson(repoRoot, opts) {
|
|
387
|
-
const abs =
|
|
881
|
+
const abs = path4.join(repoRoot, ".vscode/mcp.json");
|
|
388
882
|
assertUnderRepoRoot(repoRoot, abs);
|
|
389
883
|
let raw = "";
|
|
390
884
|
let existed = false;
|
|
391
885
|
try {
|
|
392
|
-
raw = await
|
|
886
|
+
raw = await fs4.readFile(abs, "utf8");
|
|
393
887
|
existed = true;
|
|
394
888
|
} catch (err) {
|
|
395
889
|
if (err?.code !== "ENOENT") throw err;
|
|
396
890
|
}
|
|
891
|
+
const memoraoneServer = await buildMemoraoneMcpServerEntry(repoRoot);
|
|
397
892
|
if (!existed) {
|
|
398
|
-
const body = buildMcpJsonBody(null);
|
|
893
|
+
const body = buildMcpJsonBody(null, memoraoneServer);
|
|
399
894
|
if (opts.dryRun) return "created";
|
|
400
|
-
await
|
|
401
|
-
await
|
|
895
|
+
await fs4.mkdir(path4.dirname(abs), { recursive: true });
|
|
896
|
+
await fs4.writeFile(abs, body, "utf8");
|
|
402
897
|
return "created";
|
|
403
898
|
}
|
|
404
899
|
const managed = raw.includes(MANAGED_MARKER);
|
|
@@ -410,11 +905,11 @@ async function writeMcpJson(repoRoot, opts) {
|
|
|
410
905
|
parsed = null;
|
|
411
906
|
}
|
|
412
907
|
if (!parsed && !opts.force) return "skipped-untracked";
|
|
413
|
-
const next = buildMcpJsonBody(parsed);
|
|
908
|
+
const next = buildMcpJsonBody(parsed, memoraoneServer);
|
|
414
909
|
if (managed && next === raw) return "skipped";
|
|
415
910
|
if (opts.dryRun) return "updated";
|
|
416
|
-
await
|
|
417
|
-
await
|
|
911
|
+
await fs4.mkdir(path4.dirname(abs), { recursive: true });
|
|
912
|
+
await fs4.writeFile(abs, next, "utf8");
|
|
418
913
|
return "updated";
|
|
419
914
|
}
|
|
420
915
|
function parseSetupIdeFlags(argv) {
|
|
@@ -425,6 +920,7 @@ function parseSetupIdeFlags(argv) {
|
|
|
425
920
|
let force = false;
|
|
426
921
|
let dryRun = false;
|
|
427
922
|
let noGitignore = false;
|
|
923
|
+
let cleanup = false;
|
|
428
924
|
const unknown = [];
|
|
429
925
|
for (const a of argv) {
|
|
430
926
|
if (a === "--cursor") cursor = true;
|
|
@@ -434,6 +930,7 @@ function parseSetupIdeFlags(argv) {
|
|
|
434
930
|
else if (a === "--force") force = true;
|
|
435
931
|
else if (a === "--dry-run") dryRun = true;
|
|
436
932
|
else if (a === "--no-gitignore") noGitignore = true;
|
|
933
|
+
else if (a === "--cleanup") cleanup = true;
|
|
437
934
|
else if (a.startsWith("-")) unknown.push(a);
|
|
438
935
|
}
|
|
439
936
|
const specific = cursor || vscode || jetbrains;
|
|
@@ -443,7 +940,7 @@ function parseSetupIdeFlags(argv) {
|
|
|
443
940
|
} else {
|
|
444
941
|
targets = { cursor, vscode, jetbrains };
|
|
445
942
|
}
|
|
446
|
-
return { targets, force, dryRun, noGitignore, unknown };
|
|
943
|
+
return { targets, force, dryRun, noGitignore, cleanup, unknown };
|
|
447
944
|
}
|
|
448
945
|
function summarizeOutcomes(outcomes) {
|
|
449
946
|
const created = [];
|
|
@@ -516,7 +1013,7 @@ description: MemoraOne MCP \u2014 IDE agent instructions
|
|
|
516
1013
|
return { exitCode: 0, repoRoot, outcomes };
|
|
517
1014
|
}
|
|
518
1015
|
async function cliSetupIdeFiles(argv) {
|
|
519
|
-
const { targets, force, dryRun, noGitignore, unknown } = parseSetupIdeFlags(argv);
|
|
1016
|
+
const { targets, force, dryRun, noGitignore, cleanup, unknown } = parseSetupIdeFlags(argv);
|
|
520
1017
|
if (unknown.length) {
|
|
521
1018
|
console.error(`[setup-ide-files] Unknown option(s): ${unknown.join(", ")}`);
|
|
522
1019
|
return 1;
|
|
@@ -539,6 +1036,26 @@ async function cliSetupIdeFiles(argv) {
|
|
|
539
1036
|
if (dryRun) {
|
|
540
1037
|
console.log("[setup-ide-files] Dry run: no files written.");
|
|
541
1038
|
}
|
|
1039
|
+
if (cleanup) {
|
|
1040
|
+
console.log("[setup-ide-files] Running project-scoped cleanup...");
|
|
1041
|
+
const cleanupResult = await runCleanup({
|
|
1042
|
+
cwd: process.cwd(),
|
|
1043
|
+
dryRun,
|
|
1044
|
+
allProjects: false,
|
|
1045
|
+
assumeYes: true
|
|
1046
|
+
});
|
|
1047
|
+
if (cleanupResult.error) {
|
|
1048
|
+
console.error(`[setup-ide-files] cleanup failed: ${cleanupResult.error}`);
|
|
1049
|
+
return cleanupResult.exitCode;
|
|
1050
|
+
}
|
|
1051
|
+
} else {
|
|
1052
|
+
console.log(
|
|
1053
|
+
"[setup-ide-files] If Studio shows stale connections, run: npx -y @memoraone/mcp@latest cleanup --project-id <projectId>"
|
|
1054
|
+
);
|
|
1055
|
+
console.log(
|
|
1056
|
+
"[setup-ide-files] From this repo (uses memoraone.m1): npx -y @memoraone/mcp@latest cleanup"
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
542
1059
|
return 0;
|
|
543
1060
|
}
|
|
544
1061
|
|
|
@@ -551,11 +1068,17 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
551
1068
|
}
|
|
552
1069
|
if (args.includes("--help") || args.includes("-h")) {
|
|
553
1070
|
console.log(
|
|
554
|
-
"Usage: memoraone-mcp [--version] [--help] [--daemon --project-id <uuid>]\n memoraone-mcp setup-ide-files [--all|--cursor|--vscode|--jetbrains] [--force] [--dry-run] [--no-gitignore]"
|
|
1071
|
+
"Usage: memoraone-mcp [--version] [--help] [--daemon --project-id <uuid> [--ide cursor|copilot-vscode|jetbrains]]\n memoraone-mcp setup-ide-files [--all|--cursor|--vscode|--jetbrains] [--force] [--dry-run] [--no-gitignore] [--cleanup]\n memoraone-mcp cleanup [--project-id <uuid>] [--ide cursor|copilot-vscode|jetbrains] [--dry-run] [--all-projects] [--yes]"
|
|
555
1072
|
);
|
|
556
1073
|
process.exit(0);
|
|
557
1074
|
}
|
|
558
|
-
if (args[0] === "
|
|
1075
|
+
if (args[0] === "cleanup") {
|
|
1076
|
+
cliCleanup(args.slice(1)).then((code) => process.exit(code)).catch((err) => {
|
|
1077
|
+
process.stderr.write(`[memoraone-mcp] cleanup fatal: ${String(err)}
|
|
1078
|
+
`);
|
|
1079
|
+
process.exit(1);
|
|
1080
|
+
});
|
|
1081
|
+
} else if (args[0] === "setup-ide-files") {
|
|
559
1082
|
cliSetupIdeFiles(args.slice(1)).then((code) => process.exit(code)).catch((err) => {
|
|
560
1083
|
process.stderr.write(`[memoraone-mcp] setup-ide-files fatal: ${String(err)}
|
|
561
1084
|
`);
|
|
@@ -572,8 +1095,8 @@ if (args[0] === "setup-ide-files") {
|
|
|
572
1095
|
const raw = process.env.WORKSPACE_FOLDER_PATHS;
|
|
573
1096
|
const parts = [];
|
|
574
1097
|
if (raw !== void 0 && raw.trim() !== "") {
|
|
575
|
-
for (const p of raw.split(
|
|
576
|
-
parts.push(
|
|
1098
|
+
for (const p of raw.split(path5.delimiter).map((s) => s.trim()).filter(Boolean)) {
|
|
1099
|
+
parts.push(path5.resolve(p));
|
|
577
1100
|
}
|
|
578
1101
|
}
|
|
579
1102
|
parts.push(process.cwd());
|
|
@@ -587,10 +1110,10 @@ if (args[0] === "setup-ide-files") {
|
|
|
587
1110
|
}
|
|
588
1111
|
return deduped;
|
|
589
1112
|
}, connectWithRetry = function(socketPath) {
|
|
590
|
-
return new Promise((
|
|
1113
|
+
return new Promise((resolve5, reject) => {
|
|
591
1114
|
const tryConnect = (attempt) => {
|
|
592
1115
|
const socket = net.connect(socketPath, () => {
|
|
593
|
-
|
|
1116
|
+
resolve5(socket);
|
|
594
1117
|
});
|
|
595
1118
|
socket.on("error", (err) => {
|
|
596
1119
|
if (attempt >= MAX_RETRIES) {
|
|
@@ -616,7 +1139,7 @@ if (args[0] === "setup-ide-files") {
|
|
|
616
1139
|
async function runBridge() {
|
|
617
1140
|
ensureBaseDir();
|
|
618
1141
|
const binding = await resolveBinding();
|
|
619
|
-
const socketPath =
|
|
1142
|
+
const socketPath = getDaemonSocketPath(binding.projectId);
|
|
620
1143
|
const environmentLog = binding.environment !== void 0 ? ` environment=${binding.environment}` : "";
|
|
621
1144
|
log(
|
|
622
1145
|
`authoritative binding project=${binding.projectId} workspace=${binding.workspaceRoot} m1=${binding.m1Path} source=${binding.bindingSource} apiKeySource=${binding.apiKeySource}${environmentLog}`
|
|
@@ -626,14 +1149,18 @@ if (args[0] === "setup-ide-files") {
|
|
|
626
1149
|
socket = await connectWithRetry(socketPath);
|
|
627
1150
|
} catch {
|
|
628
1151
|
log("daemon not running, spawning...");
|
|
629
|
-
const child = (0,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
1152
|
+
const child = (0, import_node_child_process2.spawn)(
|
|
1153
|
+
process.execPath,
|
|
1154
|
+
buildDaemonSpawnArgs(process.argv[1], binding.projectId),
|
|
1155
|
+
{
|
|
1156
|
+
detached: true,
|
|
1157
|
+
stdio: "ignore",
|
|
1158
|
+
env: {
|
|
1159
|
+
...process.env,
|
|
1160
|
+
MEMORAONE_DAEMON_BINDING_B64: encodeResolvedBinding(binding)
|
|
1161
|
+
}
|
|
635
1162
|
}
|
|
636
|
-
|
|
1163
|
+
);
|
|
637
1164
|
child.unref();
|
|
638
1165
|
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
639
1166
|
socket = await connectWithRetry(socketPath);
|