@mnemonik/cli 7.100.0 → 7.101.3
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/auth/pkce.d.ts +2 -0
- package/dist/auth/pkce.d.ts.map +1 -1
- package/dist/auth/pkce.js +57 -6
- package/dist/auth/pkce.js.map +1 -1
- package/dist/auth/status.d.ts +1 -5
- package/dist/auth/status.d.ts.map +1 -1
- package/dist/auth/status.js +1 -71
- package/dist/auth/status.js.map +1 -1
- package/dist/digests.json +91 -91
- package/dist/install/hosts.d.ts +2 -12
- package/dist/install/hosts.d.ts.map +1 -1
- package/dist/install/hosts.js +57 -356
- package/dist/install/hosts.js.map +1 -1
- package/dist/install/journal.d.ts +2 -10
- package/dist/install/journal.d.ts.map +1 -1
- package/dist/install/journal.js +0 -4
- package/dist/install/journal.js.map +1 -1
- package/dist/install/journey.d.ts.map +1 -1
- package/dist/install/journey.js +185 -158
- package/dist/install/journey.js.map +1 -1
- package/dist/install/transaction.d.ts +2 -3
- package/dist/install/transaction.d.ts.map +1 -1
- package/dist/install/transaction.js +1 -90
- package/dist/install/transaction.js.map +1 -1
- package/dist/install/ui.d.ts.map +1 -1
- package/dist/install/ui.js +15 -33
- package/dist/install/ui.js.map +1 -1
- package/dist/installSession.js +0 -4
- package/dist/launcher.d.ts.map +1 -1
- package/dist/launcher.js +16 -7
- package/dist/launcher.js.map +1 -1
- package/dist/output.d.ts +1 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +3 -0
- package/dist/output.js.map +1 -1
- package/dist/preflight.d.ts +2 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +64 -209
- package/dist/preflight.js.map +1 -1
- package/dist/project/eligibility.d.ts +11 -1
- package/dist/project/eligibility.d.ts.map +1 -1
- package/dist/project/eligibility.js +12 -1
- package/dist/project/eligibility.js.map +1 -1
- package/dist/project.d.ts +3 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +56 -21
- package/dist/project.js.map +1 -1
- package/dist/router.d.ts +5 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +201 -93
- package/dist/router.js.map +1 -1
- package/dist/runtime/releaseSource.d.ts +10 -0
- package/dist/runtime/releaseSource.d.ts.map +1 -1
- package/dist/runtime/releaseSource.js +82 -6
- package/dist/runtime/releaseSource.js.map +1 -1
- package/dist/runtime/selfUpdate.d.ts +4 -1
- package/dist/runtime/selfUpdate.d.ts.map +1 -1
- package/dist/runtime/selfUpdate.js +12 -6
- package/dist/runtime/selfUpdate.js.map +1 -1
- package/dist/runtime/signers.js +15 -7
- package/dist/runtime/store.d.ts +2 -1
- package/dist/runtime/store.d.ts.map +1 -1
- package/dist/runtime/store.js +20 -9
- package/dist/runtime/store.js.map +1 -1
- package/dist/sbom.json +21 -23
- package/dist/scanner/discover.d.ts +12 -1
- package/dist/scanner/discover.d.ts.map +1 -1
- package/dist/scanner/discover.js +37 -6
- package/dist/scanner/discover.js.map +1 -1
- package/dist/scanner/enable.d.ts +23 -5
- package/dist/scanner/enable.d.ts.map +1 -1
- package/dist/scanner/enable.js +93 -21
- package/dist/scanner/enable.js.map +1 -1
- package/dist/scanner/picker.d.ts +7 -1
- package/dist/scanner/picker.d.ts.map +1 -1
- package/dist/scanner/picker.js +64 -13
- package/dist/scanner/picker.js.map +1 -1
- package/dist/scanner-release.json +25 -25
- package/dist/screens/journey.d.ts +13 -3
- package/dist/screens/journey.d.ts.map +1 -1
- package/dist/screens/journey.js +145 -53
- package/dist/screens/journey.js.map +1 -1
- package/dist/screens.d.ts +2 -3
- package/dist/screens.d.ts.map +1 -1
- package/dist/screens.js +6 -16
- package/dist/screens.js.map +1 -1
- package/dist/status.d.ts +5 -3
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +194 -110
- package/dist/status.js.map +1 -1
- package/dist/vendor/local-setup.js +124 -27
- package/dist/vendor/shared/runtimeSigners.js +11 -6
- package/package.json +45 -41
package/dist/router.js
CHANGED
|
@@ -562,7 +562,7 @@ var init_hookRuntime = __esm({
|
|
|
562
562
|
});
|
|
563
563
|
|
|
564
564
|
// packages/cli/src/router.ts
|
|
565
|
-
import { enableScanner } from "./scanner/enable.js";
|
|
565
|
+
import { enableScanner, updateScannerRoots } from "./scanner/enable.js";
|
|
566
566
|
import { controlScanner, scannerReceipt } from "./scanner/control.js";
|
|
567
567
|
import { updateScanner } from "./scanner/update.js";
|
|
568
568
|
import { deleteScannerIndex } from "./scanner/data.js";
|
|
@@ -4774,8 +4774,6 @@ var stateFor = {
|
|
|
4774
4774
|
scanner_not_verified: "LIMITED",
|
|
4775
4775
|
hook_not_verified: "LIMITED",
|
|
4776
4776
|
hooks_missing: "ACTION_REQUIRED",
|
|
4777
|
-
host_grant_unbound: "LIMITED",
|
|
4778
|
-
host_not_connected: "LIMITED",
|
|
4779
4777
|
scanner_omitted: "LIMITED",
|
|
4780
4778
|
project_uncovered: "LIMITED",
|
|
4781
4779
|
host_skipped: "LIMITED",
|
|
@@ -4791,8 +4789,6 @@ var rank = {
|
|
|
4791
4789
|
FAILED: 3
|
|
4792
4790
|
};
|
|
4793
4791
|
function defaultAction(condition) {
|
|
4794
|
-
if (condition.kind === "host_skipped" && condition.component)
|
|
4795
|
-
return `Connect it later: mnemonik connect ${condition.component}`;
|
|
4796
4792
|
if (condition.kind === "windows_task_creation_failed")
|
|
4797
4793
|
return "Run mnemonik scanner enable to try again.";
|
|
4798
4794
|
return condition.action;
|
|
@@ -4821,7 +4817,7 @@ function remainingReadinessCount(summary2) {
|
|
|
4821
4817
|
}
|
|
4822
4818
|
function describeReadiness(summary2) {
|
|
4823
4819
|
if (summary2.state === "READY")
|
|
4824
|
-
return "Done.
|
|
4820
|
+
return "Done.";
|
|
4825
4821
|
const count = remainingReadinessCount(summary2);
|
|
4826
4822
|
const opening = summary2.state === "FAILED" ? "Setup failed." : count === 0 ? "Done." : summary2.state === "ACTION_REQUIRED" ? `Setup needs ${count === 1 ? "one action" : `${count} actions`}.` : `Done, with ${count === 1 ? "one thing" : `${count} things`} left.`;
|
|
4827
4823
|
return [opening, ...summary2.reasons.map(sentence), ...summary2.actions].join(" ");
|
|
@@ -4960,18 +4956,23 @@ import {
|
|
|
4960
4956
|
import { hostOrder } from "./install/adapters.js";
|
|
4961
4957
|
import { readInstallVersions } from "./install/ownership.js";
|
|
4962
4958
|
import { ensureLauncher, removeLauncher, LauncherError } from "./launcher.js";
|
|
4963
|
-
import { readFile } from "node:fs/promises";
|
|
4959
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
4960
|
+
import { createInterface } from "node:readline";
|
|
4964
4961
|
import { RuntimeStore, updateRuntime } from "./runtime/store.js";
|
|
4965
|
-
import { updateCli,
|
|
4962
|
+
import { updateCli, cliUpdateHint } from "./runtime/selfUpdate.js";
|
|
4966
4963
|
import { homedir as homedir2 } from "node:os";
|
|
4967
4964
|
import { join as join3 } from "node:path";
|
|
4968
4965
|
import { Output } from "./output.js";
|
|
4969
4966
|
import { renderPreflight, runPreflight } from "./preflight.js";
|
|
4970
4967
|
import { postCurrentReadiness } from "./installSession.js";
|
|
4971
4968
|
import {
|
|
4969
|
+
createRealProjectRuntime,
|
|
4970
|
+
ensureProjectRoot,
|
|
4972
4971
|
ensureProjectForAgent,
|
|
4972
|
+
projectLimitMessage,
|
|
4973
4973
|
runProjectCommand
|
|
4974
4974
|
} from "./project.js";
|
|
4975
|
+
import { evaluateRoot } from "./project/eligibility.js";
|
|
4975
4976
|
import { grantTransport, grantHost } from "./auth/status.js";
|
|
4976
4977
|
import { createCliAuth } from "./auth/index.js";
|
|
4977
4978
|
import { currentInstallSession, ensureInstallSession } from "./auth/installSession.js";
|
|
@@ -4994,6 +4995,16 @@ import {
|
|
|
4994
4995
|
sendDiagnostics
|
|
4995
4996
|
} from "./diagnostics.js";
|
|
4996
4997
|
var supportedHosts = ["claude-code", "codex", "cursor", "grok"];
|
|
4998
|
+
var editorNames = {
|
|
4999
|
+
"claude-code": "Claude Code",
|
|
5000
|
+
codex: "Codex",
|
|
5001
|
+
cursor: "Cursor",
|
|
5002
|
+
grok: "Grok"
|
|
5003
|
+
};
|
|
5004
|
+
var connectFolderPrompt = (name2) => `Connect ${name2} to Mnemonik? [Y/n]`;
|
|
5005
|
+
var removeFolderPrompt = (name2) => `Stop indexing ${name2}? Its memories stay in your account. [y/N]`;
|
|
5006
|
+
var connectedFolderLine = (name2) => ` \u2713 Connected ${name2}.`;
|
|
5007
|
+
var removedFolderLine = (name2) => ` \u2713 ${name2} is no longer connected.`;
|
|
4997
5008
|
function maintenanceExitCode(results) {
|
|
4998
5009
|
if (results.some((result) => result.status === "FAILED")) return 1;
|
|
4999
5010
|
return results.every((result) => result.status === "READY") ? 0 : 3;
|
|
@@ -5003,9 +5014,9 @@ var booleans = /* @__PURE__ */ new Set([
|
|
|
5003
5014
|
"non-interactive",
|
|
5004
5015
|
"agent",
|
|
5005
5016
|
"accept-scanner",
|
|
5017
|
+
"accept-indexing",
|
|
5006
5018
|
"accept-limited",
|
|
5007
5019
|
"apply",
|
|
5008
|
-
"approve-host",
|
|
5009
5020
|
"confirm",
|
|
5010
5021
|
"without-scanner",
|
|
5011
5022
|
"non-git",
|
|
@@ -5016,12 +5027,12 @@ var booleans = /* @__PURE__ */ new Set([
|
|
|
5016
5027
|
"backup",
|
|
5017
5028
|
"verify",
|
|
5018
5029
|
"dry-run",
|
|
5019
|
-
"reopen-install"
|
|
5030
|
+
"reopen-install",
|
|
5031
|
+
"automatic"
|
|
5020
5032
|
]);
|
|
5021
5033
|
var values = /* @__PURE__ */ new Set([
|
|
5022
5034
|
"components",
|
|
5023
5035
|
"hosts",
|
|
5024
|
-
"integration-scope",
|
|
5025
5036
|
"scan-roots",
|
|
5026
5037
|
"host",
|
|
5027
5038
|
"scope",
|
|
@@ -5039,8 +5050,8 @@ Commands:
|
|
|
5039
5050
|
status
|
|
5040
5051
|
connect <claude-code|codex|cursor|grok>
|
|
5041
5052
|
project <init|setup|status|link|ensure>
|
|
5042
|
-
|
|
5043
|
-
|
|
5053
|
+
add <folder>
|
|
5054
|
+
remove <folder>
|
|
5044
5055
|
data delete --project <id>
|
|
5045
5056
|
diagnostics <preview|send>
|
|
5046
5057
|
doctor
|
|
@@ -5053,7 +5064,7 @@ Commands:
|
|
|
5053
5064
|
logout
|
|
5054
5065
|
|
|
5055
5066
|
Global options: --json --non-interactive --no-browser --help --version
|
|
5056
|
-
Install consent: --accept-
|
|
5067
|
+
Install consent: --accept-indexing --accept-limited --apply`;
|
|
5057
5068
|
function parse(args2) {
|
|
5058
5069
|
const positionals = [];
|
|
5059
5070
|
const flags2 = /* @__PURE__ */ new Map();
|
|
@@ -5071,7 +5082,7 @@ function parse(args2) {
|
|
|
5071
5082
|
}
|
|
5072
5083
|
if (booleans.has(name2)) {
|
|
5073
5084
|
if (inline !== void 0) return { positionals, flags: flags2, error: `Unknown flag: ${argument}` };
|
|
5074
|
-
flags2.set(name2, true);
|
|
5085
|
+
flags2.set(name2 === "accept-scanner" ? "accept-indexing" : name2, true);
|
|
5075
5086
|
continue;
|
|
5076
5087
|
}
|
|
5077
5088
|
if (values.has(name2)) {
|
|
@@ -5141,22 +5152,39 @@ async function hostDependencies(deps, output, state) {
|
|
|
5141
5152
|
if (deps.hostManagement) return deps.hostManagement;
|
|
5142
5153
|
const cliAuth = auth(deps, output, false);
|
|
5143
5154
|
const grants = grantTransport(async () => {
|
|
5144
|
-
const
|
|
5145
|
-
if (typeof
|
|
5146
|
-
return
|
|
5155
|
+
const bearer2 = await cliAuth.getCliBearer();
|
|
5156
|
+
if (typeof bearer2 !== "string") throw new Error(bearer2.reason);
|
|
5157
|
+
return bearer2;
|
|
5147
5158
|
}, deps.grantFetch);
|
|
5159
|
+
const bearer = await cliAuth.getCliBearer();
|
|
5160
|
+
if (typeof bearer !== "string") throw new Error(bearer.reason);
|
|
5161
|
+
if (!cliAuth.accountEmail) throw new Error("account_identity_failed");
|
|
5162
|
+
const email = await cliAuth.accountEmail(bearer);
|
|
5163
|
+
const installation = JSON.parse(
|
|
5164
|
+
await readFile(join3(state, "installation.json"), "utf8").catch(() => "{}")
|
|
5165
|
+
);
|
|
5148
5166
|
return {
|
|
5149
5167
|
stateDir: state,
|
|
5150
|
-
account:
|
|
5168
|
+
account: typeof installation.account === "string" ? installation.account : email,
|
|
5151
5169
|
grants,
|
|
5152
5170
|
getCliBearer: async () => {
|
|
5153
|
-
const
|
|
5154
|
-
if (typeof
|
|
5155
|
-
return
|
|
5171
|
+
const bearer2 = await cliAuth.getCliBearer();
|
|
5172
|
+
if (typeof bearer2 !== "string") throw new Error(bearer2.reason);
|
|
5173
|
+
return bearer2;
|
|
5156
5174
|
},
|
|
5157
5175
|
credentialFetch: deps.grantFetch
|
|
5158
5176
|
};
|
|
5159
5177
|
}
|
|
5178
|
+
async function updateHostDependencies(deps, state) {
|
|
5179
|
+
if (deps.hostManagement) return { ...deps.hostManagement, stateDir: state };
|
|
5180
|
+
const installation = JSON.parse(
|
|
5181
|
+
await readFile(join3(state, "installation.json"), "utf8").catch(() => "{}")
|
|
5182
|
+
);
|
|
5183
|
+
return {
|
|
5184
|
+
stateDir: state,
|
|
5185
|
+
account: typeof installation.account === "string" ? installation.account : ""
|
|
5186
|
+
};
|
|
5187
|
+
}
|
|
5160
5188
|
async function packageVersion() {
|
|
5161
5189
|
const contents = await readFile(new URL("../package.json", import.meta.url), "utf8");
|
|
5162
5190
|
return JSON.parse(contents).version;
|
|
@@ -5164,7 +5192,7 @@ async function packageVersion() {
|
|
|
5164
5192
|
async function runHostCommand(command, parsed, deps, output, scannerSelected = false) {
|
|
5165
5193
|
const json = parsed.flags.has("json");
|
|
5166
5194
|
const state = deps.hostManagement?.stateDir ?? deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home);
|
|
5167
|
-
const scope =
|
|
5195
|
+
const scope = command === "install" ? void 0 : parsed.flags.get("scope");
|
|
5168
5196
|
const host = parsed.flags.get("host");
|
|
5169
5197
|
const component = parsed.flags.get("component");
|
|
5170
5198
|
const fullUninstall = command === "uninstall" && !host && !scope && !component;
|
|
@@ -5179,7 +5207,6 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5179
5207
|
if (components.some((c) => !["hooks", "mcp"].includes(c)))
|
|
5180
5208
|
return placeholder(output, json, "install scanner", "scanner setup");
|
|
5181
5209
|
const missing = requireConsent(parsed, output, [
|
|
5182
|
-
"integration-scope",
|
|
5183
5210
|
...scannerSelected ? [] : ["accept-limited"],
|
|
5184
5211
|
"apply"
|
|
5185
5212
|
]);
|
|
@@ -5189,7 +5216,7 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5189
5216
|
(name2) => [...new Set(components)].map((component2) => ({
|
|
5190
5217
|
component: component2,
|
|
5191
5218
|
host: name2,
|
|
5192
|
-
scope,
|
|
5219
|
+
scope: "user",
|
|
5193
5220
|
home: deps.home ?? homedir2(),
|
|
5194
5221
|
projectRoot: deps.cwd ?? process.cwd()
|
|
5195
5222
|
}))
|
|
@@ -5201,6 +5228,8 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5201
5228
|
scope ? String(scope) : void 0,
|
|
5202
5229
|
component ? String(component) : void 0
|
|
5203
5230
|
);
|
|
5231
|
+
if (command === "update")
|
|
5232
|
+
resolved.selected = resolved.selected.filter((target) => target.component === "hooks");
|
|
5204
5233
|
if (resolved.ambiguous.length && !json && !parsed.flags.has("non-interactive")) {
|
|
5205
5234
|
const profile = await chooseHostProfile(
|
|
5206
5235
|
deps.input ?? process.stdin,
|
|
@@ -5238,7 +5267,7 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5238
5267
|
const store = new RuntimeStore(state);
|
|
5239
5268
|
const cli = all ? await updateCli(store) : void 0;
|
|
5240
5269
|
const updatedCli = selections.length && (cli?.status === "UPDATED" || cli?.status === "UP_TO_DATE") ? await store.verifyRuntime("cli") : void 0;
|
|
5241
|
-
const managed = selections.length || (await interrupted(state)).length ? await hostDependencies(deps, output, state) : void 0;
|
|
5270
|
+
const managed = selections.length || (await interrupted(state)).length ? command === "update" ? await updateHostDependencies(deps, state) : await hostDependencies(deps, output, state) : void 0;
|
|
5242
5271
|
const result = managed ? await runHosts(
|
|
5243
5272
|
command,
|
|
5244
5273
|
selections,
|
|
@@ -5250,17 +5279,9 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5250
5279
|
join3(updatedCli.directory, "node_modules/@mnemonik/cli/package.json")
|
|
5251
5280
|
) : void 0),
|
|
5252
5281
|
instruction: json ? void 0 : (text) => output.line(text),
|
|
5253
|
-
|
|
5254
|
-
`Retry ${host2}`,
|
|
5255
|
-
`Skip ${host2}`
|
|
5256
|
-
]))?.startsWith("Retry") ? "retry" : "skip"),
|
|
5257
|
-
apply: parsed.flags.has("apply"),
|
|
5258
|
-
offerRevoke: managed.offerRevoke ?? (json || parsed.flags.has("non-interactive") ? void 0 : async (host2) => (await chooseHostProfile(deps.input ?? process.stdin, output, [
|
|
5259
|
-
`Keep ${host2} grant`,
|
|
5260
|
-
`Revoke ${host2} grant`
|
|
5261
|
-
]))?.startsWith("Revoke") ?? false)
|
|
5282
|
+
apply: parsed.flags.has("apply")
|
|
5262
5283
|
},
|
|
5263
|
-
|
|
5284
|
+
false
|
|
5264
5285
|
) : { journal: { state: "READY" }, results: [], reports: [] };
|
|
5265
5286
|
let scanner;
|
|
5266
5287
|
let launcher;
|
|
@@ -5269,11 +5290,15 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5269
5290
|
() => false
|
|
5270
5291
|
)) {
|
|
5271
5292
|
try {
|
|
5293
|
+
const before = await store.verifyRuntime("scanner").catch(() => void 0);
|
|
5272
5294
|
const runtime = await updateScanner(
|
|
5273
5295
|
{ stateDir: state, ...deps.scannerService },
|
|
5274
5296
|
deps.scannerEnable?.source
|
|
5275
5297
|
);
|
|
5276
|
-
scanner = {
|
|
5298
|
+
scanner = {
|
|
5299
|
+
status: before?.reference.version === runtime.reference.version ? "UP_TO_DATE" : "UPDATED",
|
|
5300
|
+
version: runtime.manifest.version
|
|
5301
|
+
};
|
|
5277
5302
|
} catch (error) {
|
|
5278
5303
|
scanner = { status: "FAILED", reason: error.message };
|
|
5279
5304
|
}
|
|
@@ -5315,7 +5340,13 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5315
5340
|
...launcher ? { launcher } : {},
|
|
5316
5341
|
...cli ? { cli } : {}
|
|
5317
5342
|
});
|
|
5318
|
-
else {
|
|
5343
|
+
else if (command === "update") {
|
|
5344
|
+
if (failed || hostExit !== 0)
|
|
5345
|
+
output.error("Mnemonik could not update. Run mnemonik update again.");
|
|
5346
|
+
else if (cli?.status === "UPDATED" || result.reports.length > 0 || scanner?.status === "UPDATED")
|
|
5347
|
+
output.line("Mnemonik updated.");
|
|
5348
|
+
else output.line("Mnemonik is up to date.");
|
|
5349
|
+
} else {
|
|
5319
5350
|
for (const target of result.results)
|
|
5320
5351
|
output.line(
|
|
5321
5352
|
`${target.target}: ${target.status} (${target.reason}${target.detail ? `: ${target.detail}` : ""})`
|
|
@@ -5328,11 +5359,14 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5328
5359
|
);
|
|
5329
5360
|
else if (scanner)
|
|
5330
5361
|
output.line(`Scanner ${scanner.status}: ${scanner.version ?? scanner.reason}.`);
|
|
5331
|
-
if (cli) output.line(cliUpdateLine(cli));
|
|
5332
5362
|
}
|
|
5333
5363
|
if (scanner?.status === "failed") output.error(scanner.reason ?? "scanner_uninstall_failed");
|
|
5334
5364
|
return failed ? 1 : hostExit;
|
|
5335
5365
|
} catch (error) {
|
|
5366
|
+
if (command === "update" && !json) {
|
|
5367
|
+
output.error("Mnemonik could not update. Run mnemonik update again.");
|
|
5368
|
+
return error instanceof LauncherError ? 3 : 1;
|
|
5369
|
+
}
|
|
5336
5370
|
if (error instanceof LauncherError) {
|
|
5337
5371
|
if (json)
|
|
5338
5372
|
output.json({ status: error.status, reason: error.message, launcher: error.launcher });
|
|
@@ -5349,13 +5383,13 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
5349
5383
|
}
|
|
5350
5384
|
async function hostCommand(command, parsed, deps, output, scannerSelected = false) {
|
|
5351
5385
|
const code = await runHostCommand(command, parsed, deps, output, scannerSelected);
|
|
5352
|
-
if (command === "
|
|
5386
|
+
if (command === "repair") await reportCurrentInstallation(deps, output);
|
|
5353
5387
|
return code;
|
|
5354
5388
|
}
|
|
5355
5389
|
async function enableCommand(parsed, deps, output) {
|
|
5356
5390
|
const json = parsed.flags.has("json");
|
|
5357
5391
|
if (parsed.flags.has("non-interactive") || json) {
|
|
5358
|
-
const missing = requireConsent(parsed, output, ["accept-
|
|
5392
|
+
const missing = requireConsent(parsed, output, ["accept-indexing", "apply"]);
|
|
5359
5393
|
if (missing !== void 0) return missing;
|
|
5360
5394
|
if (!parsed.flags.has("scan-roots"))
|
|
5361
5395
|
return actionRequired2(
|
|
@@ -5371,6 +5405,7 @@ async function enableCommand(parsed, deps, output) {
|
|
|
5371
5405
|
const result = await enableScanner({
|
|
5372
5406
|
stateDir: deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home),
|
|
5373
5407
|
cwd: deps.cwd ?? process.cwd(),
|
|
5408
|
+
home: deps.home,
|
|
5374
5409
|
input: deps.input ?? process.stdin,
|
|
5375
5410
|
output,
|
|
5376
5411
|
nonInteractive: parsed.flags.has("non-interactive") || json,
|
|
@@ -5378,7 +5413,9 @@ async function enableCommand(parsed, deps, output) {
|
|
|
5378
5413
|
...typeof roots === "string" ? { roots: roots.split(",").filter(Boolean) } : {},
|
|
5379
5414
|
...typeof exclusions === "string" ? { exclusions: exclusions.split(",").filter(Boolean) } : {},
|
|
5380
5415
|
...deps.scannerService,
|
|
5381
|
-
...deps.scannerEnable
|
|
5416
|
+
...deps.scannerEnable,
|
|
5417
|
+
projectExecutor: deps.projectExecutor,
|
|
5418
|
+
projectStateDir: deps.projectStateDir
|
|
5382
5419
|
});
|
|
5383
5420
|
if (json) output.json(result);
|
|
5384
5421
|
else renderStatusSummaries(result, output);
|
|
@@ -5398,10 +5435,9 @@ async function installCommand(parsed, deps, output) {
|
|
|
5398
5435
|
const invalid = allowed(parsed, [
|
|
5399
5436
|
"components",
|
|
5400
5437
|
"hosts",
|
|
5401
|
-
"integration-scope",
|
|
5402
5438
|
"scan-roots",
|
|
5403
5439
|
"exclusions",
|
|
5404
|
-
"accept-
|
|
5440
|
+
"accept-indexing",
|
|
5405
5441
|
"accept-limited",
|
|
5406
5442
|
"without-scanner",
|
|
5407
5443
|
"apply",
|
|
@@ -5416,7 +5452,7 @@ async function installCommand(parsed, deps, output) {
|
|
|
5416
5452
|
parsed.flags,
|
|
5417
5453
|
deps,
|
|
5418
5454
|
output,
|
|
5419
|
-
() => ensureCliAuth(deps, output, parsed.flags.has("no-browser"),
|
|
5455
|
+
() => ensureCliAuth(deps, output, parsed.flags.has("no-browser"), false),
|
|
5420
5456
|
() => hostDependencies(deps, output, state)
|
|
5421
5457
|
);
|
|
5422
5458
|
}
|
|
@@ -5485,7 +5521,7 @@ async function doctorCommand(parsed, deps, output) {
|
|
|
5485
5521
|
if (parsed.flags.has("json")) output.json(document);
|
|
5486
5522
|
else {
|
|
5487
5523
|
renderPreflight(result, output);
|
|
5488
|
-
renderStatusSummaries(document, output);
|
|
5524
|
+
renderStatusSummaries(document, output, { diagnostics: true });
|
|
5489
5525
|
}
|
|
5490
5526
|
return document.installation.state === "READY" ? 0 : document.installation.state === "FAILED" ? 1 : 3;
|
|
5491
5527
|
}
|
|
@@ -5513,11 +5549,6 @@ async function collectCurrentInstallation(deps, output) {
|
|
|
5513
5549
|
projectHookConditions: deps.projectHookConditions,
|
|
5514
5550
|
configuredHosts: deps.configuredHosts ?? deps.install?.input.hosts,
|
|
5515
5551
|
details: deps.statusDetails,
|
|
5516
|
-
grants: deps.hostManagement?.grants ?? grantTransport(async () => {
|
|
5517
|
-
const bearer = await auth(deps, output, false).getCliBearer();
|
|
5518
|
-
if (typeof bearer !== "string") throw new Error(bearer.reason);
|
|
5519
|
-
return bearer;
|
|
5520
|
-
}, deps.grantFetch),
|
|
5521
5552
|
generatedAt: deps.statusGeneratedAt,
|
|
5522
5553
|
launcher: { ...deps.launcher, stateDir: hostStateDir, home: deps.home }
|
|
5523
5554
|
});
|
|
@@ -5540,14 +5571,19 @@ async function reportCurrentInstallation(deps, output, document) {
|
|
|
5540
5571
|
}
|
|
5541
5572
|
}
|
|
5542
5573
|
async function runCli(args2, deps = {}) {
|
|
5543
|
-
const
|
|
5574
|
+
const parsed = parse(args2);
|
|
5575
|
+
const silent = parsed.flags.has("automatic");
|
|
5576
|
+
const discard = { write: () => {
|
|
5577
|
+
} };
|
|
5578
|
+
const stdout = silent ? discard : deps.stdout ?? process.stdout;
|
|
5579
|
+
const stderr = silent ? discard : deps.stderr ?? process.stderr;
|
|
5580
|
+
const output = new Output(stdout, stderr, {
|
|
5544
5581
|
home: deps.home ?? homedir2()
|
|
5545
5582
|
});
|
|
5546
|
-
if (process.env.MNEMONIK_DEV_RELEASE_DIR)
|
|
5547
|
-
|
|
5583
|
+
if (process.env.MNEMONIK_DEV_RELEASE_DIR && !silent)
|
|
5584
|
+
stderr.write(
|
|
5548
5585
|
"WARNING: MNEMONIK_DEV_RELEASE_DIR uses development artifacts; readiness remains LIMITED (dev_release_source).\n"
|
|
5549
5586
|
);
|
|
5550
|
-
const parsed = parse(args2);
|
|
5551
5587
|
if (parsed.error) return output.error(parsed.error), 2;
|
|
5552
5588
|
if (parsed.flags.has("version")) {
|
|
5553
5589
|
if (parsed.positionals.length || parsed.flags.size !== 1)
|
|
@@ -5566,21 +5602,84 @@ async function runCli(args2, deps = {}) {
|
|
|
5566
5602
|
if (subcommand) return output.error(`Unexpected argument: ${subcommand}`), 2;
|
|
5567
5603
|
return installCommand(parsed, deps, output);
|
|
5568
5604
|
}
|
|
5569
|
-
if (command === "roots") {
|
|
5570
|
-
const
|
|
5571
|
-
|
|
5572
|
-
|
|
5605
|
+
if (command === "roots" || command === "add" || command === "remove") {
|
|
5606
|
+
const action = command === "roots" ? subcommand : command;
|
|
5607
|
+
const actionArguments = command === "roots" ? rest : [subcommand, ...rest].filter(Boolean);
|
|
5608
|
+
const invalid = allowed(parsed, ["accept-indexing", "apply", "no-browser"]);
|
|
5609
|
+
if (invalid || !["add", "remove", "list"].includes(action ?? "") || actionArguments.length !== (action === "list" ? 0 : 1))
|
|
5610
|
+
return output.error(invalid ?? "Usage: mnemonik add <folder> or mnemonik remove <folder>"), 2;
|
|
5573
5611
|
const stateDir = deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home);
|
|
5574
5612
|
const saved = JSON.parse(
|
|
5575
5613
|
await readFile(`${stateDir}/scanner/state.json`, "utf8").catch(() => "null")
|
|
5576
5614
|
);
|
|
5577
|
-
if (!saved) return actionRequired2(output, parsed.flags.has("json"), "mnemonik
|
|
5578
|
-
if (
|
|
5615
|
+
if (!saved) return actionRequired2(output, parsed.flags.has("json"), "mnemonik install");
|
|
5616
|
+
if (action === "list") {
|
|
5579
5617
|
if (parsed.flags.has("json")) output.json(saved.config.roots);
|
|
5580
5618
|
else for (const root of saved.config.roots) output.line(root);
|
|
5581
5619
|
return 0;
|
|
5582
5620
|
}
|
|
5583
|
-
|
|
5621
|
+
if (action === "add" && (parsed.flags.has("non-interactive") || parsed.flags.has("json")) && !parsed.flags.has("apply"))
|
|
5622
|
+
return actionRequired2(output, parsed.flags.has("json"), "Rerun with --apply", "--apply");
|
|
5623
|
+
const pathArgument = actionArguments[0] ?? "";
|
|
5624
|
+
const requested = action === "add" ? await realpath(pathArgument) : saved.config.roots.find((root) => root === pathArgument) ?? pathArgument;
|
|
5625
|
+
const name2 = requested.split(/[\\/]/u).filter(Boolean).at(-1) ?? requested;
|
|
5626
|
+
if (!parsed.flags.has("non-interactive") && !parsed.flags.has("json")) {
|
|
5627
|
+
output.line(action === "add" ? connectFolderPrompt(name2) : removeFolderPrompt(name2));
|
|
5628
|
+
const readline = createInterface({ input: deps.input ?? process.stdin, terminal: false });
|
|
5629
|
+
const answer = String((await readline[Symbol.asyncIterator]().next()).value ?? "").trim();
|
|
5630
|
+
readline.close();
|
|
5631
|
+
if (action === "add" && /^(?:n|no)$/iu.test(answer) || action === "remove" && !/^(?:y|yes)$/iu.test(answer))
|
|
5632
|
+
return 130;
|
|
5633
|
+
}
|
|
5634
|
+
const bearer = await ensureCliAuth(deps, output, parsed.flags.has("no-browser"), false);
|
|
5635
|
+
if (action === "add") {
|
|
5636
|
+
let executor = deps.projectExecutor;
|
|
5637
|
+
if (!executor)
|
|
5638
|
+
executor = (await createRealProjectRuntime({
|
|
5639
|
+
stateDir: deps.projectStateDir ?? stateDir,
|
|
5640
|
+
getCliBearer: async () => bearer,
|
|
5641
|
+
fetch: deps.grantFetch
|
|
5642
|
+
})).executor;
|
|
5643
|
+
const resolution = await executor.resolveProjectIdentity(requested);
|
|
5644
|
+
const decision = await evaluateRoot(resolution, {
|
|
5645
|
+
cwd: requested,
|
|
5646
|
+
home: deps.home,
|
|
5647
|
+
nonGitSelected: true
|
|
5648
|
+
});
|
|
5649
|
+
if (!decision.allowed)
|
|
5650
|
+
return actionRequired2(output, parsed.flags.has("json"), decision.reason);
|
|
5651
|
+
const project = await ensureProjectRoot(requested, executor);
|
|
5652
|
+
const limit = projectLimitMessage(project, requested);
|
|
5653
|
+
if (limit) {
|
|
5654
|
+
if (parsed.flags.has("json"))
|
|
5655
|
+
output.json({
|
|
5656
|
+
status: "ACTION_REQUIRED",
|
|
5657
|
+
state: "project_limit_reached",
|
|
5658
|
+
message: limit.join(" ")
|
|
5659
|
+
});
|
|
5660
|
+
else for (const line of limit) output.line(line);
|
|
5661
|
+
return 3;
|
|
5662
|
+
}
|
|
5663
|
+
if (project.status !== "done") {
|
|
5664
|
+
output.error(
|
|
5665
|
+
`Project action required: ${"state" in project ? project.state : project.status}`
|
|
5666
|
+
);
|
|
5667
|
+
return 3;
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5670
|
+
const updated = await updateScannerRoots({
|
|
5671
|
+
stateDir,
|
|
5672
|
+
bearer,
|
|
5673
|
+
add: action === "add" ? [requested] : [],
|
|
5674
|
+
remove: action === "remove" ? [requested] : [],
|
|
5675
|
+
fetch: deps.grantFetch
|
|
5676
|
+
});
|
|
5677
|
+
if (updated.status === "updated") {
|
|
5678
|
+
if (parsed.flags.has("json")) output.json(updated.state.config.roots);
|
|
5679
|
+
else output.line(action === "add" ? connectedFolderLine(name2) : removedFolderLine(name2));
|
|
5680
|
+
return 0;
|
|
5681
|
+
}
|
|
5682
|
+
const roots = action === "add" ? [.../* @__PURE__ */ new Set([...saved.config.roots, requested])] : saved.config.roots.filter((root) => root !== requested);
|
|
5584
5683
|
parsed.flags.set("scan-roots", roots.join(","));
|
|
5585
5684
|
parsed.flags.set("exclusions", (saved.config.exclusions ?? []).join(","));
|
|
5586
5685
|
return enableCommand(parsed, deps, output);
|
|
@@ -5642,15 +5741,20 @@ async function runCli(args2, deps = {}) {
|
|
|
5642
5741
|
...deps.scannerService
|
|
5643
5742
|
};
|
|
5644
5743
|
if (command === "update") {
|
|
5744
|
+
const store = new RuntimeStore(options.stateDir);
|
|
5745
|
+
const before = await store.verifyRuntime("scanner").catch(() => void 0);
|
|
5645
5746
|
const runtime = await updateScanner(options, deps.scannerEnable?.source);
|
|
5646
5747
|
const result = {
|
|
5647
|
-
status: "updated",
|
|
5748
|
+
status: before?.reference.version === runtime.reference.version ? "up_to_date" : "updated",
|
|
5648
5749
|
version: runtime.manifest.version,
|
|
5649
5750
|
cli: { status: "NOT_SELECTED" },
|
|
5650
5751
|
...process.env.MNEMONIK_DEV_RELEASE_DIR ? { status: "LIMITED", reason: "dev_release_source" } : {}
|
|
5651
5752
|
};
|
|
5652
5753
|
if (parsed.flags.has("json")) output.json(result);
|
|
5653
|
-
else
|
|
5754
|
+
else
|
|
5755
|
+
output.line(
|
|
5756
|
+
result.status === "updated" ? "Mnemonik updated." : "Mnemonik is up to date."
|
|
5757
|
+
);
|
|
5654
5758
|
} else {
|
|
5655
5759
|
await scannerService(options).uninstall();
|
|
5656
5760
|
const result = {
|
|
@@ -5664,16 +5768,23 @@ async function runCli(args2, deps = {}) {
|
|
|
5664
5768
|
"Stopped collection; removed local software. Credentials, cloud data and consent retained."
|
|
5665
5769
|
);
|
|
5666
5770
|
}
|
|
5667
|
-
if (command === "update") await reportCurrentInstallation(deps, output);
|
|
5668
5771
|
return 0;
|
|
5669
5772
|
} catch (error) {
|
|
5670
|
-
output.error(
|
|
5671
|
-
|
|
5773
|
+
output.error(
|
|
5774
|
+
command === "update" ? "Mnemonik could not update. Run mnemonik update again." : error.message
|
|
5775
|
+
);
|
|
5672
5776
|
return 3;
|
|
5673
5777
|
}
|
|
5674
5778
|
}
|
|
5675
5779
|
if (command === "repair" || command === "update" || command === "uninstall") {
|
|
5676
|
-
const invalid = allowed(parsed, [
|
|
5780
|
+
const invalid = allowed(parsed, [
|
|
5781
|
+
"host",
|
|
5782
|
+
"scope",
|
|
5783
|
+
"component",
|
|
5784
|
+
"confirm",
|
|
5785
|
+
"apply",
|
|
5786
|
+
...command === "update" ? ["automatic"] : []
|
|
5787
|
+
]);
|
|
5677
5788
|
if (invalid || subcommand)
|
|
5678
5789
|
return output.error(invalid ?? `Unexpected argument: ${subcommand}`), 2;
|
|
5679
5790
|
if (command === "uninstall" && parsed.flags.has("non-interactive")) {
|
|
@@ -5684,7 +5795,7 @@ async function runCli(args2, deps = {}) {
|
|
|
5684
5795
|
return hostCommand(command, parsed, deps, output);
|
|
5685
5796
|
}
|
|
5686
5797
|
if (command === "update") {
|
|
5687
|
-
const invalid = allowed(parsed, []);
|
|
5798
|
+
const invalid = allowed(parsed, ["automatic"]);
|
|
5688
5799
|
if (invalid || subcommand)
|
|
5689
5800
|
return output.error(invalid ?? `Unexpected argument: ${subcommand}`), 2;
|
|
5690
5801
|
if (!deps.runtimeUpdate)
|
|
@@ -5701,8 +5812,7 @@ async function runCli(args2, deps = {}) {
|
|
|
5701
5812
|
artifact: runtime.manifest.artifact,
|
|
5702
5813
|
version: runtime.manifest.version
|
|
5703
5814
|
});
|
|
5704
|
-
else output.line(
|
|
5705
|
-
await reportCurrentInstallation(deps, output);
|
|
5815
|
+
else output.line("Mnemonik updated.");
|
|
5706
5816
|
return 0;
|
|
5707
5817
|
}
|
|
5708
5818
|
if (command === "doctor") {
|
|
@@ -5754,7 +5864,6 @@ Preview: ${preview.path}
|
|
|
5754
5864
|
deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home)
|
|
5755
5865
|
);
|
|
5756
5866
|
if (!parsed.flags.has("json")) {
|
|
5757
|
-
output.line(`CLI ${version}.`);
|
|
5758
5867
|
renderStatusSummaries(document, output);
|
|
5759
5868
|
}
|
|
5760
5869
|
const hint = await cliUpdateHint(store, version);
|
|
@@ -5765,15 +5874,10 @@ Preview: ${preview.path}
|
|
|
5765
5874
|
return statusExitCode(document);
|
|
5766
5875
|
}
|
|
5767
5876
|
if (command === "connect") {
|
|
5768
|
-
const invalid = allowed(parsed, ["
|
|
5877
|
+
const invalid = allowed(parsed, ["scope"]);
|
|
5769
5878
|
if (invalid) return output.error(invalid), 2;
|
|
5770
5879
|
if (!subcommand || rest.length || !supportedHosts.includes(subcommand))
|
|
5771
5880
|
return output.error("Usage: mnemonik connect <claude-code|codex|cursor|grok>"), 2;
|
|
5772
|
-
if (parsed.flags.has("non-interactive") || parsed.flags.has("json")) {
|
|
5773
|
-
const missing = requireConsent(parsed, output, ["approve-host"]);
|
|
5774
|
-
if (missing !== void 0) return missing;
|
|
5775
|
-
}
|
|
5776
|
-
await ensureCliAuth(deps, output, parsed.flags.has("no-browser"), false);
|
|
5777
5881
|
const state = deps.hostManagement?.stateDir ?? deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home);
|
|
5778
5882
|
const owned = await selectOwned(
|
|
5779
5883
|
state,
|
|
@@ -5781,33 +5885,33 @@ Preview: ${preview.path}
|
|
|
5781
5885
|
parsed.flags.get("scope"),
|
|
5782
5886
|
"mcp"
|
|
5783
5887
|
);
|
|
5888
|
+
if (!owned.selected.length && !parsed.flags.has("json")) {
|
|
5889
|
+
output.line(
|
|
5890
|
+
`${editorNames[subcommand]} will ask you to sign in to Mnemonik the first time you use it.`
|
|
5891
|
+
);
|
|
5892
|
+
return 3;
|
|
5893
|
+
}
|
|
5784
5894
|
if (owned.selected.length !== 1)
|
|
5785
5895
|
return actionRequired2(
|
|
5786
5896
|
output,
|
|
5787
5897
|
parsed.flags.has("json"),
|
|
5788
5898
|
owned.selected.length ? "ambiguous_profile" : "no_recorded_targets"
|
|
5789
5899
|
);
|
|
5790
|
-
const managed =
|
|
5900
|
+
const managed = deps.hostManagement ?? { stateDir: state, account: "" };
|
|
5791
5901
|
const selected = owned.selected[0];
|
|
5792
5902
|
if (!selected) throw new Error("no_recorded_targets");
|
|
5793
|
-
let
|
|
5903
|
+
let instructionShown = false;
|
|
5794
5904
|
const result = await connectHost(selected, {
|
|
5795
5905
|
...managed,
|
|
5796
|
-
noBrowser: parsed.flags.has("no-browser"),
|
|
5797
|
-
approveHost: async () => approval ??= (await chooseHostProfile(deps.input ?? process.stdin, output, [
|
|
5798
|
-
`Approve ${subcommand} for account ${managed.account} on this machine`,
|
|
5799
|
-
"Cancel"
|
|
5800
|
-
]))?.startsWith("Approve") ?? false,
|
|
5801
5906
|
instruction: (text) => {
|
|
5802
|
-
if (!parsed.flags.has("json"))
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
]))?.startsWith("Retry") ? "retry" : "skip")
|
|
5907
|
+
if (!parsed.flags.has("json")) {
|
|
5908
|
+
output.line(text);
|
|
5909
|
+
instructionShown = true;
|
|
5910
|
+
}
|
|
5911
|
+
}
|
|
5808
5912
|
});
|
|
5809
5913
|
if (parsed.flags.has("json")) output.json(result);
|
|
5810
|
-
else
|
|
5914
|
+
else if (!instructionShown)
|
|
5811
5915
|
output.line(`${result.status}: ${result.reason}${result.action ? `. ${result.action}` : ""}`);
|
|
5812
5916
|
return result.status === "READY" ? 0 : 3;
|
|
5813
5917
|
}
|
|
@@ -5926,7 +6030,7 @@ Preview: ${preview.path}
|
|
|
5926
6030
|
return output.error("Usage: mnemonik scanner <enable|start|stop|uninstall|status>"), 2;
|
|
5927
6031
|
const invalid = allowed(
|
|
5928
6032
|
parsed,
|
|
5929
|
-
subcommand === "enable" ? ["accept-
|
|
6033
|
+
subcommand === "enable" ? ["accept-indexing", "apply", "scan-roots", "exclusions", "no-browser"] : subcommand === "export-preview" ? ["out"] : []
|
|
5930
6034
|
);
|
|
5931
6035
|
if (invalid) return output.error(invalid), 2;
|
|
5932
6036
|
if (subcommand === "enable") return enableCommand(parsed, deps, output);
|
|
@@ -6162,7 +6266,11 @@ Preview: ${preview.path}
|
|
|
6162
6266
|
}
|
|
6163
6267
|
var serializeReadiness2 = (input) => devReadiness(serializeReadiness(input));
|
|
6164
6268
|
export {
|
|
6269
|
+
connectFolderPrompt,
|
|
6270
|
+
connectedFolderLine,
|
|
6165
6271
|
help,
|
|
6166
6272
|
maintenanceExitCode,
|
|
6273
|
+
removeFolderPrompt,
|
|
6274
|
+
removedFolderLine,
|
|
6167
6275
|
runCli
|
|
6168
6276
|
};
|