@memoraone/mcp 0.1.37 → 0.1.38
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 +237 -134
- package/package.json +1 -1
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.38",
|
|
34
34
|
type: "module",
|
|
35
35
|
main: "dist/index.cjs",
|
|
36
36
|
bin: {
|
|
@@ -2236,45 +2236,46 @@ function logCursorMcpConfigAudit(prefix, audit) {
|
|
|
2236
2236
|
function logCursorMcpCliSummary(info, dryRun, opts) {
|
|
2237
2237
|
const { repoConfigPath, repoOutcome, npxPath, cliPath, repoBackupPath, globalConfigPath, globalMemoraoneRemoved, globalBackupPath } = info;
|
|
2238
2238
|
const interactive = opts?.forInteractivePostSetup === true;
|
|
2239
|
-
|
|
2239
|
+
const println = opts?.println ?? console.log;
|
|
2240
|
+
println(`[setup-ide-files] Cursor repo MCP config: ${repoConfigPath}`);
|
|
2240
2241
|
if (cliPath) {
|
|
2241
|
-
|
|
2242
|
+
println(`[setup-ide-files] Resolved local CLI: ${cliPath}`);
|
|
2242
2243
|
} else if (npxPath) {
|
|
2243
|
-
|
|
2244
|
+
println(`[setup-ide-files] Resolved npx: ${npxPath}`);
|
|
2244
2245
|
}
|
|
2245
2246
|
if (repoBackupPath) {
|
|
2246
|
-
|
|
2247
|
+
println(`[setup-ide-files] Cursor repo MCP config backup: ${repoBackupPath}`);
|
|
2247
2248
|
}
|
|
2248
2249
|
if (!interactive) {
|
|
2249
2250
|
if (repoOutcome === "created") {
|
|
2250
|
-
|
|
2251
|
+
println(
|
|
2251
2252
|
dryRun ? `[setup-ide-files] Cursor repo MCP config would be created: ${repoConfigPath}` : `[setup-ide-files] Cursor repo MCP config created: ${repoConfigPath}`
|
|
2252
2253
|
);
|
|
2253
2254
|
} else if (repoOutcome === "updated") {
|
|
2254
|
-
|
|
2255
|
+
println(
|
|
2255
2256
|
dryRun ? `[setup-ide-files] Cursor repo MCP config would be updated: ${repoConfigPath}` : `[setup-ide-files] Cursor repo MCP config updated: ${repoConfigPath}`
|
|
2256
2257
|
);
|
|
2257
2258
|
} else if (repoOutcome === "skipped") {
|
|
2258
|
-
|
|
2259
|
+
println(`[setup-ide-files] Cursor repo MCP config unchanged: ${repoConfigPath}`);
|
|
2259
2260
|
}
|
|
2260
2261
|
}
|
|
2261
2262
|
if (globalMemoraoneRemoved && globalConfigPath) {
|
|
2262
|
-
|
|
2263
|
+
println(
|
|
2263
2264
|
dryRun ? `[setup-ide-files] Would remove memoraone from Cursor global MCP config: ${globalConfigPath}` : `[setup-ide-files] Removed memoraone from Cursor global MCP config: ${globalConfigPath}`
|
|
2264
2265
|
);
|
|
2265
2266
|
if (globalBackupPath) {
|
|
2266
|
-
|
|
2267
|
+
println(`[setup-ide-files] Cursor global MCP config backup: ${globalBackupPath}`);
|
|
2267
2268
|
}
|
|
2268
2269
|
} else if (globalConfigPath) {
|
|
2269
|
-
|
|
2270
|
+
println(
|
|
2270
2271
|
`[setup-ide-files] Cursor global MCP config unchanged (no managed memoraone to remove): ${globalConfigPath}`
|
|
2271
2272
|
);
|
|
2272
2273
|
}
|
|
2273
|
-
|
|
2274
|
+
println(
|
|
2274
2275
|
"[setup-ide-files] Each Cursor window uses this repo\u2019s .cursor/mcp.json (separate MCP process per repo)."
|
|
2275
2276
|
);
|
|
2276
2277
|
if (!interactive) {
|
|
2277
|
-
|
|
2278
|
+
println(
|
|
2278
2279
|
"[setup-ide-files] Fully quit Cursor and reopen this repo for MCP changes to take effect."
|
|
2279
2280
|
);
|
|
2280
2281
|
}
|
|
@@ -3472,12 +3473,21 @@ async function buildJetBrainsMemoraoneServer(options) {
|
|
|
3472
3473
|
apiUrl: options.apiUrl
|
|
3473
3474
|
});
|
|
3474
3475
|
}
|
|
3476
|
+
function isOptionalJetBrainsHandshakeUnavailable(detail) {
|
|
3477
|
+
if (!detail) return false;
|
|
3478
|
+
if (detail.includes("-32601")) return true;
|
|
3479
|
+
if (/Method not found/i.test(detail)) return true;
|
|
3480
|
+
return false;
|
|
3481
|
+
}
|
|
3482
|
+
function formatOptionalJetBrainsHandshakeUnavailableDetail(detail) {
|
|
3483
|
+
return "MCP handshake optional verification unavailable while configuration succeeded" + (detail ? ` (${detail})` : "");
|
|
3484
|
+
}
|
|
3475
3485
|
async function verifyJetBrainsMcpHandshake(options) {
|
|
3476
3486
|
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
3477
3487
|
const { server } = options;
|
|
3478
3488
|
return new Promise((resolve17) => {
|
|
3479
3489
|
let settled = false;
|
|
3480
|
-
const finish = (ok, detail) => {
|
|
3490
|
+
const finish = (ok, detail, optionalUnavailable) => {
|
|
3481
3491
|
if (settled) return;
|
|
3482
3492
|
settled = true;
|
|
3483
3493
|
clearTimeout(timer);
|
|
@@ -3485,7 +3495,7 @@ async function verifyJetBrainsMcpHandshake(options) {
|
|
|
3485
3495
|
child.kill();
|
|
3486
3496
|
} catch {
|
|
3487
3497
|
}
|
|
3488
|
-
resolve17({ ok, detail });
|
|
3498
|
+
resolve17({ ok, detail, optionalUnavailable });
|
|
3489
3499
|
};
|
|
3490
3500
|
const child = (0, import_node_child_process5.spawn)(server.command, [...server.args], {
|
|
3491
3501
|
env: { ...process.env, ...server.env },
|
|
@@ -3525,7 +3535,12 @@ async function verifyJetBrainsMcpHandshake(options) {
|
|
|
3525
3535
|
finish(true, "initialize OK; tools/list OK");
|
|
3526
3536
|
}
|
|
3527
3537
|
if (msg.error) {
|
|
3528
|
-
|
|
3538
|
+
const errDetail = `JSON-RPC error: ${JSON.stringify(msg.error)}`;
|
|
3539
|
+
if (isOptionalJetBrainsHandshakeUnavailable(errDetail)) {
|
|
3540
|
+
finish(true, errDetail, true);
|
|
3541
|
+
} else {
|
|
3542
|
+
finish(false, errDetail);
|
|
3543
|
+
}
|
|
3529
3544
|
}
|
|
3530
3545
|
}
|
|
3531
3546
|
});
|
|
@@ -3637,47 +3652,60 @@ async function setupJetBrainsMcpConfig(options) {
|
|
|
3637
3652
|
if (options.verify !== false) {
|
|
3638
3653
|
const verify = await verifyJetBrainsMcpHandshake({ server: memoraone });
|
|
3639
3654
|
verifyOk = verify.ok;
|
|
3640
|
-
verifyDetail = verify.detail;
|
|
3641
|
-
repairActions.push({
|
|
3655
|
+
verifyDetail = verify.optionalUnavailable ? formatOptionalJetBrainsHandshakeUnavailableDetail(verify.detail) : verify.detail;
|
|
3656
|
+
repairActions.push({
|
|
3657
|
+
type: "verify-handshake",
|
|
3658
|
+
ok: verify.ok,
|
|
3659
|
+
detail: verifyDetail ?? verify.detail
|
|
3660
|
+
});
|
|
3642
3661
|
}
|
|
3643
3662
|
return { outcome, backupPath, repairActions, verifyOk, verifyDetail, memoraone };
|
|
3644
3663
|
}
|
|
3645
|
-
function
|
|
3664
|
+
function formatJetBrainsHandshakeLogLine(action) {
|
|
3665
|
+
const optional = /optional verification unavailable/i.test(action.detail) || isOptionalJetBrainsHandshakeUnavailable(action.detail);
|
|
3666
|
+
if (optional) {
|
|
3667
|
+
if (/optional verification unavailable/i.test(action.detail)) {
|
|
3668
|
+
return `[setup-ide-files] ${action.detail}`;
|
|
3669
|
+
}
|
|
3670
|
+
return `[setup-ide-files] ${formatOptionalJetBrainsHandshakeUnavailableDetail(action.detail)}`;
|
|
3671
|
+
}
|
|
3672
|
+
if (action.ok) {
|
|
3673
|
+
return `[setup-ide-files] MCP handshake verification: ${action.detail}`;
|
|
3674
|
+
}
|
|
3675
|
+
return `[setup-ide-files] MCP handshake verification skipped/failed: ${action.detail}`;
|
|
3676
|
+
}
|
|
3677
|
+
function logJetBrainsMcpCliSummary(info, dryRun, println = console.log) {
|
|
3646
3678
|
for (const action of info.repairActions) {
|
|
3647
3679
|
if (action.type === "found-config") {
|
|
3648
|
-
|
|
3680
|
+
println(`[setup-ide-files] Found JetBrains MCP config (${action.location.kind}): ${action.location.path}`);
|
|
3649
3681
|
} else if (action.type === "repaired-zero-byte") {
|
|
3650
|
-
|
|
3651
|
-
|
|
3682
|
+
println(`[setup-ide-files] Repaired zero-byte MCP config: ${action.path}`);
|
|
3683
|
+
println(`[setup-ide-files] Backup: ${action.backupPath}`);
|
|
3652
3684
|
} else if (action.type === "backed-up-conflicting-project-config") {
|
|
3653
|
-
|
|
3654
|
-
|
|
3685
|
+
println(`[setup-ide-files] Backed up conflicting project MCP config: ${action.path}`);
|
|
3686
|
+
println(`[setup-ide-files] Backup: ${action.backupPath}`);
|
|
3655
3687
|
} else if (action.type === "removed-project-memoraone") {
|
|
3656
|
-
|
|
3688
|
+
println(`[setup-ide-files] Removed project-scoped memoraone definition: ${action.path}`);
|
|
3657
3689
|
} else if (action.type === "verify-handshake") {
|
|
3658
|
-
|
|
3659
|
-
console.log(`[setup-ide-files] MCP handshake verification: ${action.detail}`);
|
|
3660
|
-
} else {
|
|
3661
|
-
console.log(`[setup-ide-files] MCP handshake verification skipped/failed: ${action.detail}`);
|
|
3662
|
-
}
|
|
3690
|
+
println(formatJetBrainsHandshakeLogLine(action));
|
|
3663
3691
|
}
|
|
3664
3692
|
}
|
|
3665
3693
|
const prefix = dryRun ? "would be " : "";
|
|
3666
3694
|
if (info.outcome === "created") {
|
|
3667
|
-
|
|
3695
|
+
println(`[setup-ide-files] JetBrains global MCP config ${prefix}created: ${info.activeConfigPath}`);
|
|
3668
3696
|
} else if (info.outcome === "updated") {
|
|
3669
|
-
|
|
3697
|
+
println(`[setup-ide-files] JetBrains global MCP config ${prefix}updated: ${info.activeConfigPath}`);
|
|
3670
3698
|
} else {
|
|
3671
|
-
|
|
3699
|
+
println(`[setup-ide-files] JetBrains global MCP config unchanged: ${info.activeConfigPath}`);
|
|
3672
3700
|
}
|
|
3673
3701
|
if (info.backupPath) {
|
|
3674
|
-
|
|
3702
|
+
println(`[setup-ide-files] JetBrains global MCP config backup: ${info.backupPath}`);
|
|
3675
3703
|
}
|
|
3676
3704
|
if (info.npxPath) {
|
|
3677
|
-
|
|
3705
|
+
println(`[setup-ide-files] Resolved npx: ${info.npxPath}`);
|
|
3678
3706
|
}
|
|
3679
|
-
|
|
3680
|
-
|
|
3707
|
+
println(`[setup-ide-files] Final active JetBrains MCP config: ${info.activeConfigPath}`);
|
|
3708
|
+
println(
|
|
3681
3709
|
"[setup-ide-files] Fully quit JetBrains IDE and reopen this repo for MCP changes to take effect."
|
|
3682
3710
|
);
|
|
3683
3711
|
}
|
|
@@ -3750,6 +3778,7 @@ function createTerminalPresentation(opts = {}) {
|
|
|
3750
3778
|
warningSymbol,
|
|
3751
3779
|
nextActionPrefix,
|
|
3752
3780
|
successLine: (message) => paint(color, ANSI.green, `${successSymbol} ${message}`),
|
|
3781
|
+
checkLine: (message) => `${paint(color, ANSI.green, successSymbol)} ${message}`,
|
|
3753
3782
|
warningLine: (message) => paint(color, ANSI.yellow, `${warningSymbol} ${message}`),
|
|
3754
3783
|
nextActionLine: (message) => `${nextActionPrefix} ${message}`,
|
|
3755
3784
|
heading: (text) => paint(color, ANSI.bold, text),
|
|
@@ -3802,44 +3831,6 @@ async function confirmYesDefault(question, deps = {}) {
|
|
|
3802
3831
|
rl.close();
|
|
3803
3832
|
}
|
|
3804
3833
|
}
|
|
3805
|
-
function collectOutcomePaths(outcomes) {
|
|
3806
|
-
const created = [];
|
|
3807
|
-
const updated = [];
|
|
3808
|
-
for (const [file, outcome] of Object.entries(outcomes)) {
|
|
3809
|
-
if (outcome === "created") created.push(file);
|
|
3810
|
-
else if (outcome === "updated") updated.push(file);
|
|
3811
|
-
}
|
|
3812
|
-
return { created, updated };
|
|
3813
|
-
}
|
|
3814
|
-
function formatCursorSetupCompletedSummary(opts, presentation = createTerminalPresentation({ color: false, unicode: false })) {
|
|
3815
|
-
const { created, updated } = collectOutcomePaths(opts.outcomes);
|
|
3816
|
-
const tp = presentation;
|
|
3817
|
-
const lines = [
|
|
3818
|
-
tp.successLine("MemoraOne setup completed for Cursor"),
|
|
3819
|
-
"",
|
|
3820
|
-
tp.heading("Repository"),
|
|
3821
|
-
tp.indent(tp.cyan(opts.repoRoot)),
|
|
3822
|
-
"",
|
|
3823
|
-
tp.heading("Changes")
|
|
3824
|
-
];
|
|
3825
|
-
if (created.length === 0 && updated.length === 0) {
|
|
3826
|
-
lines.push(tp.indent(tp.dim("No file changes needed")));
|
|
3827
|
-
} else {
|
|
3828
|
-
if (created.length) {
|
|
3829
|
-
lines.push(tp.indent(`Created: ${created.join(", ")}`));
|
|
3830
|
-
}
|
|
3831
|
-
if (updated.length) {
|
|
3832
|
-
lines.push(tp.indent(`Updated: ${updated.join(", ")}`));
|
|
3833
|
-
}
|
|
3834
|
-
}
|
|
3835
|
-
return lines;
|
|
3836
|
-
}
|
|
3837
|
-
function printCursorSetupCompletedSummary(opts, println = console.log, presentation) {
|
|
3838
|
-
const tp = presentation ?? createTerminalPresentation();
|
|
3839
|
-
for (const line of formatCursorSetupCompletedSummary(opts, tp)) {
|
|
3840
|
-
println(line);
|
|
3841
|
-
}
|
|
3842
|
-
}
|
|
3843
3834
|
function macosOpenCursorMcpSettingsAppleScript() {
|
|
3844
3835
|
return [
|
|
3845
3836
|
'tell application "Cursor" to activate',
|
|
@@ -3910,6 +3901,39 @@ async function runOpenCursorMcpSettingsFlow(deps = {}) {
|
|
|
3910
3901
|
printManualCursorMcpSettingsSteps(platform2, println);
|
|
3911
3902
|
}
|
|
3912
3903
|
|
|
3904
|
+
// src/setupSuccessOutput.ts
|
|
3905
|
+
var RESTART_LINE = "Restart your IDEs to finish setup.";
|
|
3906
|
+
function formatSetupSuccessLines(opts = {}) {
|
|
3907
|
+
const tp = opts.presentation ?? createTerminalPresentation(opts.presentationOptions ?? { color: false, unicode: true });
|
|
3908
|
+
const targets = opts.targets ?? {};
|
|
3909
|
+
const lines = [];
|
|
3910
|
+
if (opts.repositoryConnected) {
|
|
3911
|
+
lines.push(tp.checkLine("Repository connected"));
|
|
3912
|
+
}
|
|
3913
|
+
if (targets.cursor) {
|
|
3914
|
+
lines.push(tp.checkLine("Cursor configured"));
|
|
3915
|
+
}
|
|
3916
|
+
if (targets.vscode) {
|
|
3917
|
+
lines.push(tp.checkLine("VS Code configured"));
|
|
3918
|
+
}
|
|
3919
|
+
if (targets.jetbrains) {
|
|
3920
|
+
lines.push(tp.checkLine("JetBrains configured"));
|
|
3921
|
+
}
|
|
3922
|
+
const hasIde = Boolean(targets.cursor || targets.vscode || targets.jetbrains);
|
|
3923
|
+
lines.push("");
|
|
3924
|
+
lines.push(tp.checkLine("MemoraOne is ready"));
|
|
3925
|
+
if (hasIde) {
|
|
3926
|
+
lines.push("");
|
|
3927
|
+
lines.push(RESTART_LINE);
|
|
3928
|
+
}
|
|
3929
|
+
return lines;
|
|
3930
|
+
}
|
|
3931
|
+
function printSetupSuccess(opts, println = console.log) {
|
|
3932
|
+
for (const line of formatSetupSuccessLines(opts)) {
|
|
3933
|
+
println(line);
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
|
|
3913
3937
|
// src/setupIdeFiles.ts
|
|
3914
3938
|
var MANAGED_MARKER = "<!-- MemoraOne managed IDE helper -->";
|
|
3915
3939
|
function buildMemoraoneMcpServer(ideType, options = {}) {
|
|
@@ -4130,6 +4154,7 @@ function parseSetupIdeFlags(argv) {
|
|
|
4130
4154
|
let repair = false;
|
|
4131
4155
|
let local = false;
|
|
4132
4156
|
let staging = false;
|
|
4157
|
+
let verbose = false;
|
|
4133
4158
|
let workspaceRoot;
|
|
4134
4159
|
let apiUrl;
|
|
4135
4160
|
const unknown = [];
|
|
@@ -4148,6 +4173,7 @@ function parseSetupIdeFlags(argv) {
|
|
|
4148
4173
|
else if (a === "--repair") repair = true;
|
|
4149
4174
|
else if (a === "--local") local = true;
|
|
4150
4175
|
else if (a === "--staging") staging = true;
|
|
4176
|
+
else if (a === "--verbose") verbose = true;
|
|
4151
4177
|
else if (a === "--workspace-root") {
|
|
4152
4178
|
const value = argv[++i];
|
|
4153
4179
|
if (!value || value.startsWith("-")) {
|
|
@@ -4205,10 +4231,37 @@ function parseSetupIdeFlags(argv) {
|
|
|
4205
4231
|
workspaceRoot,
|
|
4206
4232
|
apiUrl,
|
|
4207
4233
|
explicitCursor: cursor,
|
|
4234
|
+
verbose,
|
|
4208
4235
|
unknown,
|
|
4209
4236
|
flagError
|
|
4210
4237
|
};
|
|
4211
4238
|
}
|
|
4239
|
+
function logSetupIdeFilesVerboseSuccess(opts, println = console.log) {
|
|
4240
|
+
const { targets, dryRun, result } = opts;
|
|
4241
|
+
if (result.repoRoot) {
|
|
4242
|
+
println(`[setup-ide-files] Repo root: ${result.repoRoot}`);
|
|
4243
|
+
}
|
|
4244
|
+
if (result.daemonCleanup && !result.daemonCleanup.skipped) {
|
|
4245
|
+
logSetupIdeCleanupSummary(result.daemonCleanup, println);
|
|
4246
|
+
}
|
|
4247
|
+
if (targets.cursor && result.cursorMcp) {
|
|
4248
|
+
logCursorMcpCliSummary(result.cursorMcp, dryRun, {
|
|
4249
|
+
forInteractivePostSetup: opts.forInteractivePostSetup,
|
|
4250
|
+
println
|
|
4251
|
+
});
|
|
4252
|
+
}
|
|
4253
|
+
if (targets.jetbrains && result.jetbrainsMcp) {
|
|
4254
|
+
logJetBrainsMcpCliSummary(result.jetbrainsMcp, dryRun, println);
|
|
4255
|
+
}
|
|
4256
|
+
summarizeOutcomes(result.outcomes, println);
|
|
4257
|
+
if (dryRun) {
|
|
4258
|
+
println("[setup-ide-files] Dry run: no files written.");
|
|
4259
|
+
if (result.daemonCleanup && !result.daemonCleanup.skipped) {
|
|
4260
|
+
println("[setup-ide-files] Dry run: no daemons stopped, no sockets removed.");
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
println(`[setup-ide-files] ${restartIdeInstruction(targets)}`);
|
|
4264
|
+
}
|
|
4212
4265
|
async function resolveSetupApiUrl(o, repoRoot) {
|
|
4213
4266
|
if (o.apiUrl) return normalizeApiUrl2(o.apiUrl);
|
|
4214
4267
|
const binding = await findBindingRecordByWorkspaceRoot(repoRoot, o.homeDir);
|
|
@@ -4235,7 +4288,7 @@ function cursorEnvironmentFromFlags(local, staging) {
|
|
|
4235
4288
|
if (staging) return "staging";
|
|
4236
4289
|
return "production";
|
|
4237
4290
|
}
|
|
4238
|
-
function summarizeOutcomes(outcomes) {
|
|
4291
|
+
function summarizeOutcomes(outcomes, println = console.log) {
|
|
4239
4292
|
const created = [];
|
|
4240
4293
|
const updated = [];
|
|
4241
4294
|
const skipped = [];
|
|
@@ -4253,7 +4306,7 @@ function summarizeOutcomes(outcomes) {
|
|
|
4253
4306
|
if (skippedUntracked.length) {
|
|
4254
4307
|
lines.push(` skipped (unmanaged existing file, use --force): ${skippedUntracked.join(", ")}`);
|
|
4255
4308
|
}
|
|
4256
|
-
|
|
4309
|
+
println(lines.join("\n"));
|
|
4257
4310
|
}
|
|
4258
4311
|
function ideTypesFromSetupTargets(targets) {
|
|
4259
4312
|
const ides = [];
|
|
@@ -4294,28 +4347,28 @@ function aggregateCleanupResults(results) {
|
|
|
4294
4347
|
error
|
|
4295
4348
|
};
|
|
4296
4349
|
}
|
|
4297
|
-
function logSetupIdeCleanupSummary(cleanup) {
|
|
4350
|
+
function logSetupIdeCleanupSummary(cleanup, println = console.log) {
|
|
4298
4351
|
if (cleanup.skipped) return;
|
|
4299
|
-
|
|
4352
|
+
println(`[setup-ide-files] Project id: ${cleanup.projectId}`);
|
|
4300
4353
|
if (cleanup.foundDaemonCount > 0) {
|
|
4301
|
-
|
|
4354
|
+
println(`[setup-ide-files] Found ${cleanup.foundDaemonCount} stale daemon(s)`);
|
|
4302
4355
|
if (cleanup.dryRun) {
|
|
4303
|
-
|
|
4356
|
+
println(`[setup-ide-files] Would stop ${cleanup.foundDaemonCount} stale daemon(s)`);
|
|
4304
4357
|
} else if (cleanup.stoppedDaemonCount > 0) {
|
|
4305
|
-
|
|
4358
|
+
println(`[setup-ide-files] Stopped ${cleanup.stoppedDaemonCount} stale daemon(s)`);
|
|
4306
4359
|
}
|
|
4307
4360
|
} else {
|
|
4308
|
-
|
|
4361
|
+
println("[setup-ide-files] No stale daemons found for this project and IDE target(s).");
|
|
4309
4362
|
}
|
|
4310
4363
|
if (cleanup.removedSocketCount > 0) {
|
|
4311
4364
|
if (cleanup.dryRun) {
|
|
4312
|
-
|
|
4365
|
+
println(`[setup-ide-files] Would remove ${cleanup.removedSocketCount} stale socket(s)`);
|
|
4313
4366
|
} else {
|
|
4314
|
-
|
|
4367
|
+
println(`[setup-ide-files] Removed ${cleanup.removedSocketCount} stale socket(s)`);
|
|
4315
4368
|
}
|
|
4316
4369
|
}
|
|
4317
4370
|
if (cleanup.skippedUnrelatedDaemonCount > 0) {
|
|
4318
|
-
|
|
4371
|
+
println(
|
|
4319
4372
|
`[setup-ide-files] Skipped ${cleanup.skippedUnrelatedDaemonCount} unrelated project daemon(s)`
|
|
4320
4373
|
);
|
|
4321
4374
|
}
|
|
@@ -4672,6 +4725,7 @@ async function cliSetupIdeFiles(argv, options = {}) {
|
|
|
4672
4725
|
workspaceRoot,
|
|
4673
4726
|
apiUrl,
|
|
4674
4727
|
explicitCursor,
|
|
4728
|
+
verbose,
|
|
4675
4729
|
unknown,
|
|
4676
4730
|
flagError
|
|
4677
4731
|
} = parseSetupIdeFlags(argv);
|
|
@@ -4687,6 +4741,7 @@ async function cliSetupIdeFiles(argv, options = {}) {
|
|
|
4687
4741
|
const openDeps = options.openCursorMcpSettings ?? {};
|
|
4688
4742
|
const stdinIsTty = openDeps.stdinIsTty ?? process.stdin.isTTY === true;
|
|
4689
4743
|
const env2 = openDeps.env ?? process.env;
|
|
4744
|
+
const println = options.println ?? openDeps.println ?? console.log;
|
|
4690
4745
|
const promptOpenCursorSettings = shouldPromptOpenCursorMcpSettings({
|
|
4691
4746
|
explicitCursor,
|
|
4692
4747
|
all,
|
|
@@ -4712,55 +4767,42 @@ async function cliSetupIdeFiles(argv, options = {}) {
|
|
|
4712
4767
|
if (result.error) {
|
|
4713
4768
|
console.error(result.error);
|
|
4714
4769
|
if (result.repoRoot) {
|
|
4715
|
-
|
|
4770
|
+
println(`[setup-ide-files] Repo root: ${result.repoRoot}`);
|
|
4716
4771
|
}
|
|
4717
4772
|
summarizeOutcomes(result.outcomes);
|
|
4718
4773
|
return result.exitCode;
|
|
4719
4774
|
}
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
}
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4775
|
+
const presentation = openDeps.presentation ?? createTerminalPresentation({
|
|
4776
|
+
env: env2,
|
|
4777
|
+
stdoutIsTty: openDeps.stdoutIsTty ?? process.stdout.isTTY === true,
|
|
4778
|
+
color: openDeps.color,
|
|
4779
|
+
unicode: openDeps.unicode
|
|
4780
|
+
});
|
|
4781
|
+
const showVerbose = verbose || dryRun;
|
|
4782
|
+
if (showVerbose) {
|
|
4783
|
+
logSetupIdeFilesVerboseSuccess(
|
|
4784
|
+
{
|
|
4785
|
+
targets,
|
|
4786
|
+
dryRun,
|
|
4787
|
+
result,
|
|
4788
|
+
forInteractivePostSetup: promptOpenCursorSettings
|
|
4789
|
+
},
|
|
4790
|
+
println
|
|
4791
|
+
);
|
|
4792
|
+
} else {
|
|
4793
|
+
printSetupSuccess({ targets, presentation }, println);
|
|
4733
4794
|
}
|
|
4734
4795
|
if (promptOpenCursorSettings && result.repoRoot) {
|
|
4735
|
-
const presentation = openDeps.presentation ?? createTerminalPresentation({
|
|
4736
|
-
env: env2,
|
|
4737
|
-
stdoutIsTty: openDeps.stdoutIsTty ?? process.stdout.isTTY === true,
|
|
4738
|
-
color: openDeps.color,
|
|
4739
|
-
unicode: openDeps.unicode
|
|
4740
|
-
});
|
|
4741
|
-
printCursorSetupCompletedSummary(
|
|
4742
|
-
{ repoRoot: result.repoRoot, outcomes: result.outcomes },
|
|
4743
|
-
openDeps.println,
|
|
4744
|
-
presentation
|
|
4745
|
-
);
|
|
4746
4796
|
await runOpenCursorMcpSettingsFlow({
|
|
4747
4797
|
...openDeps,
|
|
4748
4798
|
stdinIsTty,
|
|
4749
4799
|
env: env2,
|
|
4750
|
-
presentation
|
|
4800
|
+
presentation,
|
|
4801
|
+
println
|
|
4751
4802
|
});
|
|
4752
|
-
} else {
|
|
4753
|
-
summarizeOutcomes(result.outcomes);
|
|
4754
|
-
if (dryRun) {
|
|
4755
|
-
console.log("[setup-ide-files] Dry run: no files written.");
|
|
4756
|
-
if (result.daemonCleanup && !result.daemonCleanup.skipped) {
|
|
4757
|
-
console.log("[setup-ide-files] Dry run: no daemons stopped, no sockets removed.");
|
|
4758
|
-
}
|
|
4759
|
-
}
|
|
4760
|
-
console.log(`[setup-ide-files] ${restartIdeInstruction(targets)}`);
|
|
4761
4803
|
}
|
|
4762
4804
|
if (cleanup) {
|
|
4763
|
-
|
|
4805
|
+
println("[setup-ide-files] Running additional full-project cleanup (--cleanup)...");
|
|
4764
4806
|
const cleanupResult = await runCleanup({
|
|
4765
4807
|
cwd: cwd2,
|
|
4766
4808
|
dryRun,
|
|
@@ -5146,6 +5188,19 @@ async function runConnectCommand(options) {
|
|
|
5146
5188
|
message: `Repository connection exists for binding ${ensured.repositoryBindingId} (project ${redeemed.project_id}), but IDE configuration failed: ${detail}. Credentials and binding were kept. ${repair}`
|
|
5147
5189
|
};
|
|
5148
5190
|
}
|
|
5191
|
+
return {
|
|
5192
|
+
exitCode: 0,
|
|
5193
|
+
repositoryBindingId: ensured.repositoryBindingId,
|
|
5194
|
+
projectId: redeemed.project_id,
|
|
5195
|
+
installationPublicId: redeemed.installation_public_id,
|
|
5196
|
+
recovered: redeemed.recovered,
|
|
5197
|
+
createdBinding: ensured.created,
|
|
5198
|
+
legacyM1WarningPath: ensured.legacyM1WarningPath,
|
|
5199
|
+
executionMode: resolvedMode,
|
|
5200
|
+
configuredTargets: targets,
|
|
5201
|
+
setupResult,
|
|
5202
|
+
message: baseSuccess
|
|
5203
|
+
};
|
|
5149
5204
|
}
|
|
5150
5205
|
return {
|
|
5151
5206
|
exitCode: 0,
|
|
@@ -5162,12 +5217,20 @@ async function runConnectCommand(options) {
|
|
|
5162
5217
|
function parseConnectArgv(argv) {
|
|
5163
5218
|
let code;
|
|
5164
5219
|
let apiUrl;
|
|
5220
|
+
let verbose = false;
|
|
5165
5221
|
for (let i = 0; i < argv.length; i++) {
|
|
5166
5222
|
const a = argv[i];
|
|
5223
|
+
if (a === "--verbose") {
|
|
5224
|
+
verbose = true;
|
|
5225
|
+
continue;
|
|
5226
|
+
}
|
|
5167
5227
|
if (a === "--api-url") {
|
|
5168
5228
|
const value = argv[++i];
|
|
5169
5229
|
if (!value || value.startsWith("-")) {
|
|
5170
|
-
return {
|
|
5230
|
+
return {
|
|
5231
|
+
verbose,
|
|
5232
|
+
error: "Usage: memoraone-mcp connect <code> [--api-url <url>] [--verbose]"
|
|
5233
|
+
};
|
|
5171
5234
|
}
|
|
5172
5235
|
apiUrl = value;
|
|
5173
5236
|
continue;
|
|
@@ -5175,23 +5238,29 @@ function parseConnectArgv(argv) {
|
|
|
5175
5238
|
if (a.startsWith("--api-url=")) {
|
|
5176
5239
|
const value = a.slice("--api-url=".length);
|
|
5177
5240
|
if (!value) {
|
|
5178
|
-
return {
|
|
5241
|
+
return {
|
|
5242
|
+
verbose,
|
|
5243
|
+
error: "Usage: memoraone-mcp connect <code> [--api-url <url>] [--verbose]"
|
|
5244
|
+
};
|
|
5179
5245
|
}
|
|
5180
5246
|
apiUrl = value;
|
|
5181
5247
|
continue;
|
|
5182
5248
|
}
|
|
5183
5249
|
if (a.startsWith("-")) {
|
|
5184
|
-
return { error: `Unknown connect option: ${a}` };
|
|
5250
|
+
return { verbose, error: `Unknown connect option: ${a}` };
|
|
5185
5251
|
}
|
|
5186
5252
|
if (!code) {
|
|
5187
5253
|
code = a;
|
|
5188
5254
|
continue;
|
|
5189
5255
|
}
|
|
5190
|
-
return {
|
|
5256
|
+
return {
|
|
5257
|
+
verbose,
|
|
5258
|
+
error: "Usage: memoraone-mcp connect <code> [--api-url <url>] [--verbose]"
|
|
5259
|
+
};
|
|
5191
5260
|
}
|
|
5192
|
-
return { code, apiUrl };
|
|
5261
|
+
return { code, apiUrl, verbose };
|
|
5193
5262
|
}
|
|
5194
|
-
async function cliConnect(argv) {
|
|
5263
|
+
async function cliConnect(argv, options = {}) {
|
|
5195
5264
|
const parsed2 = parseConnectArgv(argv);
|
|
5196
5265
|
if (parsed2.error) {
|
|
5197
5266
|
process.stderr.write(`${parsed2.error}
|
|
@@ -5199,19 +5268,53 @@ async function cliConnect(argv) {
|
|
|
5199
5268
|
return 1;
|
|
5200
5269
|
}
|
|
5201
5270
|
if (!parsed2.code) {
|
|
5202
|
-
process.stderr.write("Usage: memoraone-mcp connect <code> [--api-url <url>]\n");
|
|
5271
|
+
process.stderr.write("Usage: memoraone-mcp connect <code> [--api-url <url>] [--verbose]\n");
|
|
5203
5272
|
return 1;
|
|
5204
5273
|
}
|
|
5274
|
+
const println = options.println ?? ((line) => process.stdout.write(`${line}
|
|
5275
|
+
`));
|
|
5205
5276
|
try {
|
|
5206
5277
|
const result = await runConnectCommand({
|
|
5207
5278
|
code: parsed2.code,
|
|
5208
|
-
cwd: process.cwd(),
|
|
5279
|
+
cwd: options.cwd ?? process.cwd(),
|
|
5209
5280
|
apiUrl: parsed2.apiUrl,
|
|
5210
|
-
packageVersion: process.env.npm_package_version ?? null
|
|
5281
|
+
packageVersion: process.env.npm_package_version ?? null,
|
|
5282
|
+
env: options.env,
|
|
5283
|
+
...options.connectOptions
|
|
5211
5284
|
});
|
|
5212
5285
|
if (result.exitCode === 0) {
|
|
5213
|
-
|
|
5214
|
-
|
|
5286
|
+
if (parsed2.verbose) {
|
|
5287
|
+
println(result.message);
|
|
5288
|
+
if (result.projectId) {
|
|
5289
|
+
println(`[memoraone-mcp] Project id: ${result.projectId}`);
|
|
5290
|
+
}
|
|
5291
|
+
println(`[memoraone-mcp] Repository root: ${options.cwd ?? process.cwd()}`);
|
|
5292
|
+
if (result.setupResult && result.configuredTargets) {
|
|
5293
|
+
logSetupIdeFilesVerboseSuccess(
|
|
5294
|
+
{
|
|
5295
|
+
targets: result.configuredTargets,
|
|
5296
|
+
dryRun: false,
|
|
5297
|
+
result: result.setupResult
|
|
5298
|
+
},
|
|
5299
|
+
println
|
|
5300
|
+
);
|
|
5301
|
+
}
|
|
5302
|
+
} else {
|
|
5303
|
+
const presentation = createTerminalPresentation({
|
|
5304
|
+
env: options.env ?? process.env,
|
|
5305
|
+
stdoutIsTty: options.stdoutIsTty ?? process.stdout.isTTY === true,
|
|
5306
|
+
color: options.color,
|
|
5307
|
+
unicode: options.unicode
|
|
5308
|
+
});
|
|
5309
|
+
printSetupSuccess(
|
|
5310
|
+
{
|
|
5311
|
+
repositoryConnected: true,
|
|
5312
|
+
targets: result.configuredTargets,
|
|
5313
|
+
presentation
|
|
5314
|
+
},
|
|
5315
|
+
println
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5215
5318
|
} else {
|
|
5216
5319
|
process.stderr.write(`[memoraone-mcp] ${result.message}
|
|
5217
5320
|
`);
|
|
@@ -5233,7 +5336,7 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
5233
5336
|
}
|
|
5234
5337
|
if (args.includes("--help") || args.includes("-h")) {
|
|
5235
5338
|
console.log(
|
|
5236
|
-
"Usage: memoraone-mcp [--version] [--help]\n memoraone-mcp connect <code> [--api-url <url>]\n memoraone-mcp [--daemon --binding-id <mrb_\u2026> [--ide cursor|copilot-vscode|jetbrains]]\n memoraone-mcp setup-ide-files [--all|--cursor|--vscode|--jetbrains] [--force] [--dry-run] [--no-gitignore] [--cleanup] [--dev] [--repair] [--workspace-root <path>] [--api-url <url>]\n Cursor API environment (with --cursor or --all): --local (node + built cli.cjs + local API) | --staging (npx + staging API)\n --workspace-root: configure an explicit bound workspace (skips .git discovery; for fileless Local MCP repair)\n --api-url: developer-only local/dev API endpoint (defaults from binding or http://localhost:3001; never Studio :3000)\n memoraone-mcp cleanup [--project-id <uuid>] [--ide cursor|copilot-vscode|jetbrains] [--dry-run] [--all-projects] [--yes]"
|
|
5339
|
+
"Usage: memoraone-mcp [--version] [--help]\n memoraone-mcp connect <code> [--api-url <url>] [--verbose]\n memoraone-mcp [--daemon --binding-id <mrb_\u2026> [--ide cursor|copilot-vscode|jetbrains]]\n memoraone-mcp setup-ide-files [--all|--cursor|--vscode|--jetbrains] [--force] [--dry-run] [--no-gitignore] [--cleanup] [--dev] [--repair] [--workspace-root <path>] [--api-url <url>] [--verbose]\n Cursor API environment (with --cursor or --all): --local (node + built cli.cjs + local API) | --staging (npx + staging API)\n --workspace-root: configure an explicit bound workspace (skips .git discovery; for fileless Local MCP repair)\n --api-url: developer-only local/dev API endpoint (defaults from binding or http://localhost:3001; never Studio :3000)\n --verbose: show developer diagnostics (paths, backups, daemon cleanup, handshake)\n memoraone-mcp cleanup [--project-id <uuid>] [--ide cursor|copilot-vscode|jetbrains] [--dry-run] [--all-projects] [--yes]"
|
|
5237
5340
|
);
|
|
5238
5341
|
process.exit(0);
|
|
5239
5342
|
}
|