@mnemonik/cli 7.100.0 → 7.101.4
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 +48 -14
- 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/install/journey.js
CHANGED
|
@@ -562,8 +562,8 @@ var init_hookRuntime = __esm({
|
|
|
562
562
|
});
|
|
563
563
|
|
|
564
564
|
// packages/cli/src/install/journey.ts
|
|
565
|
-
import {
|
|
566
|
-
import { join as join3
|
|
565
|
+
import { appendFile, mkdir, readFile } from "node:fs/promises";
|
|
566
|
+
import { join as join3 } from "node:path";
|
|
567
567
|
import { homedir as homedir2 } from "node:os";
|
|
568
568
|
import { setTimeout as delay } from "node:timers/promises";
|
|
569
569
|
|
|
@@ -4769,8 +4769,6 @@ var stateFor = {
|
|
|
4769
4769
|
scanner_not_verified: "LIMITED",
|
|
4770
4770
|
hook_not_verified: "LIMITED",
|
|
4771
4771
|
hooks_missing: "ACTION_REQUIRED",
|
|
4772
|
-
host_grant_unbound: "LIMITED",
|
|
4773
|
-
host_not_connected: "LIMITED",
|
|
4774
4772
|
scanner_omitted: "LIMITED",
|
|
4775
4773
|
project_uncovered: "LIMITED",
|
|
4776
4774
|
host_skipped: "LIMITED",
|
|
@@ -4786,8 +4784,6 @@ var rank = {
|
|
|
4786
4784
|
FAILED: 3
|
|
4787
4785
|
};
|
|
4788
4786
|
function defaultAction(condition) {
|
|
4789
|
-
if (condition.kind === "host_skipped" && condition.component)
|
|
4790
|
-
return `Connect it later: mnemonik connect ${condition.component}`;
|
|
4791
4787
|
if (condition.kind === "windows_task_creation_failed")
|
|
4792
4788
|
return "Run mnemonik scanner enable to try again.";
|
|
4793
4789
|
return condition.action;
|
|
@@ -4874,38 +4870,37 @@ var recordPath = (root, state = stateDirectory()) => join2(state, "project-setup
|
|
|
4874
4870
|
var MAX_ORIGINAL_BYTES = 64 * 1024;
|
|
4875
4871
|
|
|
4876
4872
|
// packages/cli/src/install/journey.ts
|
|
4877
|
-
import { runPreflight } from "../preflight.js";
|
|
4878
|
-
import {
|
|
4879
|
-
|
|
4873
|
+
import { nodeVersionHelp, runPreflight } from "../preflight.js";
|
|
4874
|
+
import {
|
|
4875
|
+
connectedProjectsMessage,
|
|
4876
|
+
createRealProjectRuntime,
|
|
4877
|
+
projectLimitMessage
|
|
4878
|
+
} from "../project.js";
|
|
4879
|
+
import { classifyRepository } from "../scanner/discover.js";
|
|
4880
4880
|
import { prepareScanner, restoreScannerInstall } from "../scanner/enable.js";
|
|
4881
4881
|
import { ScannerServiceLimited } from "../scanner/service.js";
|
|
4882
|
-
import { collectStatusDocument
|
|
4882
|
+
import { collectStatusDocument } from "../status.js";
|
|
4883
4883
|
import { devReadiness } from "../runtime/releaseSource.js";
|
|
4884
|
-
import {
|
|
4884
|
+
import {
|
|
4885
|
+
completedStep,
|
|
4886
|
+
completedLine,
|
|
4887
|
+
renderCustomize,
|
|
4888
|
+
renderJourney,
|
|
4889
|
+
journeyAnswers
|
|
4890
|
+
} from "../screens/journey.js";
|
|
4885
4891
|
import { interrupted } from "./journal.js";
|
|
4886
4892
|
import {
|
|
4887
4893
|
runHosts,
|
|
4888
|
-
hostNotConnectedCondition,
|
|
4889
4894
|
hookStatusConditions
|
|
4890
4895
|
} from "./hosts.js";
|
|
4891
4896
|
import { compensate, revokeInstallComponent } from "./transaction.js";
|
|
4892
4897
|
import * as ownership from "./ownership.js";
|
|
4893
4898
|
import { ensureLauncher, launcherPathAction, LauncherError } from "../launcher.js";
|
|
4894
4899
|
var labels = { "claude-code": "Claude Code", codex: "Codex", cursor: "Cursor", grok: "Grok" };
|
|
4895
|
-
var launchHosts = ["claude-code", "codex", "cursor"];
|
|
4896
|
-
var notOfferedHosts = ["
|
|
4900
|
+
var launchHosts = ["claude-code", "codex", "cursor", "grok"];
|
|
4901
|
+
var notOfferedHosts = ["vscode-copilot"];
|
|
4897
4902
|
function hostReadinessConditions(results, scanner) {
|
|
4898
4903
|
return results.filter((r) => r.status !== "READY").map((r) => {
|
|
4899
|
-
const host = r.target.split(":")[0];
|
|
4900
|
-
const notConnected = hostNotConnectedCondition(host);
|
|
4901
|
-
if (r.reason === notConnected.reason) return notConnected;
|
|
4902
|
-
if (r.reason === "login_pending") {
|
|
4903
|
-
return {
|
|
4904
|
-
kind: "login_pending",
|
|
4905
|
-
reason: `${labels[host]} is still connecting. Finish the sign-in in the app, then run mnemonik status.`,
|
|
4906
|
-
action: "mnemonik status"
|
|
4907
|
-
};
|
|
4908
|
-
}
|
|
4909
4904
|
return {
|
|
4910
4905
|
kind: scanner ? "host_skipped" : "host_trust_pending",
|
|
4911
4906
|
reason: scanner ? `${r.target}: ${r.reason}` : r.reason,
|
|
@@ -4941,6 +4936,7 @@ async function waitForInstallation(check, timeout, clock = {}) {
|
|
|
4941
4936
|
}
|
|
4942
4937
|
}
|
|
4943
4938
|
async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
4939
|
+
if (flags2.has("accept-scanner")) flags2.set("accept-indexing", true);
|
|
4944
4940
|
const json = flags2.has("json");
|
|
4945
4941
|
const automatic = json || flags2.has("non-interactive");
|
|
4946
4942
|
let components = String(
|
|
@@ -4948,20 +4944,18 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
4948
4944
|
).split(",");
|
|
4949
4945
|
if (flags2.has("without-scanner")) components = components.filter((c) => c !== "scanner");
|
|
4950
4946
|
let scanner = components.includes("scanner");
|
|
4951
|
-
let scope = String(flags2.get("integration-scope") ?? "user");
|
|
4952
4947
|
let names = flags2.has("hosts") ? String(flags2.get("hosts")).split(",") : [];
|
|
4953
|
-
if (components.some((c) => !["hooks", "mcp", "scanner"].includes(c)) || names.some((h) => !launchHosts.includes(h))
|
|
4948
|
+
if (components.some((c) => !["hooks", "mcp", "scanner"].includes(c)) || names.some((h) => !launchHosts.includes(h))) {
|
|
4954
4949
|
output.error(
|
|
4955
|
-
`Invalid hosts
|
|
4950
|
+
`Invalid hosts or components. Launch hosts: ${launchHosts.join(", ")}. Not offered at launch: ${notOfferedHosts.join(", ")}.`
|
|
4956
4951
|
);
|
|
4957
4952
|
return 2;
|
|
4958
4953
|
}
|
|
4959
4954
|
if (automatic || flags2.has("hosts") || flags2.has("components")) {
|
|
4960
4955
|
const required = [
|
|
4961
|
-
scanner ? "accept-
|
|
4956
|
+
scanner ? "accept-indexing" : "accept-limited",
|
|
4962
4957
|
"apply",
|
|
4963
|
-
...automatic && scanner ? ["scan-roots"] : []
|
|
4964
|
-
...names.length ? ["integration-scope"] : []
|
|
4958
|
+
...automatic && scanner ? ["scan-roots"] : []
|
|
4965
4959
|
];
|
|
4966
4960
|
for (const flag of required)
|
|
4967
4961
|
if (!flags2.has(flag)) {
|
|
@@ -4998,7 +4992,6 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
4998
4992
|
components = previous.data.components;
|
|
4999
4993
|
scanner = components.includes("scanner");
|
|
5000
4994
|
names = [...new Set(previous.data.hostRequest?.selections.map((s) => s.host) ?? [])];
|
|
5001
|
-
scope = previous.data.hostRequest?.selections[0]?.scope ?? scope;
|
|
5002
4995
|
}
|
|
5003
4996
|
const preflight = await runPreflight({
|
|
5004
4997
|
cwd,
|
|
@@ -5007,16 +5000,35 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5007
5000
|
...deps.preflight
|
|
5008
5001
|
});
|
|
5009
5002
|
const root = preflight.project.root ?? cwd;
|
|
5010
|
-
|
|
5003
|
+
const logPath = join3(stateDir, "install.log");
|
|
5004
|
+
const log = async (detail) => {
|
|
5005
|
+
await mkdir(stateDir, { recursive: true, mode: 448 });
|
|
5006
|
+
await appendFile(logPath, `${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), detail })}
|
|
5007
|
+
`, {
|
|
5008
|
+
mode: 384
|
|
5009
|
+
});
|
|
5010
|
+
};
|
|
5011
|
+
let roots = String(flags2.get("scan-roots") ?? previous?.data.roots.join(",") ?? "").split(",").filter(Boolean);
|
|
5011
5012
|
output.setContext({ home, projectRoot: root });
|
|
5012
5013
|
if (!names.length)
|
|
5013
|
-
names = preflight.hosts.filter((h) => h.supported
|
|
5014
|
+
names = preflight.hosts.filter((h) => h.supported).map(
|
|
5014
5015
|
(h) => Object.keys(labels).find((key) => labels[key] === h.name) ?? ""
|
|
5015
5016
|
).filter(Boolean);
|
|
5016
|
-
const answers = automatic ? void 0 : journeyAnswers(deps.input ?? process.stdin);
|
|
5017
|
+
const answers = automatic ? void 0 : journeyAnswers(deps.input ?? process.stdin, output);
|
|
5018
|
+
const interactive = Boolean(
|
|
5019
|
+
(deps.input ?? process.stdin).isTTY
|
|
5020
|
+
);
|
|
5021
|
+
const replaceScreen = (lines, replacement) => {
|
|
5022
|
+
if (!interactive) return;
|
|
5023
|
+
output.write(`\x1B[${lines}A\r\x1B[J`);
|
|
5024
|
+
if (replacement) output.line(replacement);
|
|
5025
|
+
};
|
|
5017
5026
|
const choose = async (title, choices) => {
|
|
5018
5027
|
output.line(` ${title}`);
|
|
5028
|
+
output.line(" Use the Up/Down arrow keys and Enter.");
|
|
5029
|
+
output.line();
|
|
5019
5030
|
choices.forEach((c, i2) => output.line(` ${i2 === 0 ? ">" : " "} ${c}`));
|
|
5031
|
+
output.line();
|
|
5020
5032
|
return answers ? answers.choose(choices) : "Skip";
|
|
5021
5033
|
};
|
|
5022
5034
|
let prepared;
|
|
@@ -5094,39 +5106,52 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5094
5106
|
return restored.journal.phase === "rolled_back" ? 130 : 1;
|
|
5095
5107
|
}
|
|
5096
5108
|
if (!previous && !automatic && !flags2.has("hosts") && !flags2.has("components")) {
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
()
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
if (
|
|
5123
|
-
|
|
5124
|
-
|
|
5109
|
+
for (; ; ) {
|
|
5110
|
+
const recommendedLines = renderJourney("recommended", output, {
|
|
5111
|
+
hosts: names.map((h) => labels[h]),
|
|
5112
|
+
project: root,
|
|
5113
|
+
node: preflight.node.version,
|
|
5114
|
+
os: preflight.os
|
|
5115
|
+
});
|
|
5116
|
+
const choice = flags2.has("customize") ? "Customize" : await answers?.choose(["Recommended", "Customize"]);
|
|
5117
|
+
if (choice === "Cancel") return 130;
|
|
5118
|
+
if (choice !== "Customize") {
|
|
5119
|
+
replaceScreen(recommendedLines, completedStep(1, "Recommended setup selected"));
|
|
5120
|
+
break;
|
|
5121
|
+
}
|
|
5122
|
+
const items = [
|
|
5123
|
+
...names.map((name2) => ({
|
|
5124
|
+
value: name2,
|
|
5125
|
+
label: labels[name2],
|
|
5126
|
+
checked: true
|
|
5127
|
+
})),
|
|
5128
|
+
{ value: "scanner", label: "Indexing of your projects", checked: scanner }
|
|
5129
|
+
];
|
|
5130
|
+
replaceScreen(recommendedLines);
|
|
5131
|
+
const customizeLines = renderCustomize(items, output);
|
|
5132
|
+
const customized = await answers?.customize(items);
|
|
5133
|
+
if (customized === "Cancel") return 130;
|
|
5134
|
+
if (customized === "Back") {
|
|
5135
|
+
replaceScreen(customizeLines);
|
|
5136
|
+
if (flags2.has("customize")) return 130;
|
|
5137
|
+
continue;
|
|
5138
|
+
}
|
|
5139
|
+
if (customized) {
|
|
5140
|
+
names = customized.selected.filter((item) => item !== "scanner");
|
|
5141
|
+
scanner = customized.selected.includes("scanner");
|
|
5142
|
+
components = scanner ? [.../* @__PURE__ */ new Set([...components, "scanner"])] : components.filter((component) => component !== "scanner");
|
|
5143
|
+
}
|
|
5144
|
+
replaceScreen(customizeLines, completedStep(1, "Custom setup selected"));
|
|
5145
|
+
break;
|
|
5125
5146
|
}
|
|
5126
5147
|
}
|
|
5127
5148
|
if (preflight.status !== "ready") {
|
|
5128
5149
|
if (!preflight.node.supported)
|
|
5129
|
-
|
|
5150
|
+
for (const line of nodeVersionHelp(
|
|
5151
|
+
preflight.node.version,
|
|
5152
|
+
deps.preflight?.platform ?? process.platform
|
|
5153
|
+
))
|
|
5154
|
+
output.error(line);
|
|
5130
5155
|
if (!preflight.network.reachable)
|
|
5131
5156
|
output.error(
|
|
5132
5157
|
`Discovery ${preflight.network.discoveryUrl}: ${preflight.network.detail ?? "unavailable"}`
|
|
@@ -5135,11 +5160,11 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5135
5160
|
}
|
|
5136
5161
|
if (!automatic && !flags2.has("apply")) {
|
|
5137
5162
|
renderJourney("account", output);
|
|
5138
|
-
renderJourney("cli_approval", output);
|
|
5139
5163
|
}
|
|
5140
5164
|
for (; ; ) {
|
|
5141
5165
|
try {
|
|
5142
5166
|
await authorize();
|
|
5167
|
+
if (!automatic) output.line(completedLine("Signed in"));
|
|
5143
5168
|
break;
|
|
5144
5169
|
} catch (error) {
|
|
5145
5170
|
if (automatic || await choose("Sign-in did not finish.", ["Retry", "Skip"]) !== "Retry")
|
|
@@ -5194,24 +5219,24 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5194
5219
|
(host) => components.filter((c) => c !== "scanner").sort((a, b) => a === b ? 0 : a === "hooks" ? -1 : 1).map((component) => ({
|
|
5195
5220
|
host,
|
|
5196
5221
|
component,
|
|
5197
|
-
scope,
|
|
5222
|
+
scope: "user",
|
|
5198
5223
|
home,
|
|
5199
5224
|
projectRoot: root
|
|
5200
5225
|
}))
|
|
5201
5226
|
);
|
|
5202
|
-
if (!
|
|
5203
|
-
renderJourney("host_approvals", output, {
|
|
5204
|
-
hosts: names.map((h) => labels[h])
|
|
5205
|
-
});
|
|
5206
|
-
if (await answers?.choose(["Connect them", "Cancel"]) !== "Connect them") return 130;
|
|
5207
|
-
}
|
|
5227
|
+
if (!automatic) output.line(completedStep(3, "Configure editors"));
|
|
5208
5228
|
const afterHosts = async (journal, results, refreshHosts) => {
|
|
5229
|
+
if (!automatic)
|
|
5230
|
+
output.line(
|
|
5231
|
+
completedLine(`${names.length} ${names.length === 1 ? "editor" : "editors"} configured`)
|
|
5232
|
+
);
|
|
5209
5233
|
journal.data.components = components;
|
|
5210
5234
|
journal.data.roots = roots;
|
|
5211
5235
|
const projectConditions = [];
|
|
5212
5236
|
const projectReadiness = [];
|
|
5213
5237
|
const finish = async (scannerPlan) => {
|
|
5214
5238
|
prepared = scannerPlan;
|
|
5239
|
+
let limitMessage;
|
|
5215
5240
|
if (scannerPlan) {
|
|
5216
5241
|
if (!executor) {
|
|
5217
5242
|
const runtime = await createRealProjectRuntime({
|
|
@@ -5221,65 +5246,66 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5221
5246
|
executor = runtime.executor;
|
|
5222
5247
|
projectTransport ??= runtime.transport;
|
|
5223
5248
|
}
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5249
|
+
const connectedRoots = [];
|
|
5250
|
+
for (const [rootIndex, selectedRoot] of scannerPlan.roots.entries()) {
|
|
5251
|
+
const repo = await classifyRepository(selectedRoot);
|
|
5252
|
+
const options = {
|
|
5253
|
+
cwd: repo.path,
|
|
5254
|
+
allowCreate: true,
|
|
5255
|
+
allowNestedInherit: false,
|
|
5256
|
+
...repo.nonGitSelected ? { nonGitSelected: true } : {}
|
|
5257
|
+
};
|
|
5258
|
+
const target = await journal.plan(join3(repo.path, ".mnemonik.json"), null, {
|
|
5259
|
+
kind: "project"
|
|
5260
|
+
});
|
|
5261
|
+
await journal.event("project_stage_intent", repo.path);
|
|
5262
|
+
const staged = await executor.stage(options);
|
|
5263
|
+
if (staged.status !== "staged") {
|
|
5264
|
+
limitMessage = projectLimitMessage(staged, scannerPlan.roots.slice(rootIndex))?.join(
|
|
5265
|
+
"\n"
|
|
5266
|
+
);
|
|
5267
|
+
await journal.restore(target);
|
|
5268
|
+
if (limitMessage) break;
|
|
5269
|
+
const condition = {
|
|
5270
|
+
kind: "project_identity_choice_pending",
|
|
5271
|
+
reason: `project_setup_required: ${repo.path}`,
|
|
5272
|
+
action: `mnemonik project init "${repo.path}"`
|
|
5236
5273
|
};
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
const condition = {
|
|
5244
|
-
kind: "project_identity_choice_pending",
|
|
5245
|
-
reason: `project_setup_required: ${repo.path}`,
|
|
5246
|
-
action: `mnemonik project init "${repo.path}"`
|
|
5247
|
-
};
|
|
5248
|
-
projectConditions.push(condition);
|
|
5249
|
-
projectReadiness.push(
|
|
5250
|
-
...serializeReadiness({
|
|
5251
|
-
installation: { conditions: [] },
|
|
5252
|
-
projects: [{ identityFile: target.path, summary: { conditions: [condition] } }]
|
|
5253
|
-
}).projects ?? []
|
|
5254
|
-
);
|
|
5255
|
-
await journal.restore(target);
|
|
5256
|
-
continue;
|
|
5257
|
-
}
|
|
5258
|
-
if (!journal.data.projects.some((p) => p.root === repo.path))
|
|
5259
|
-
journal.data.projects.push({
|
|
5260
|
-
root: repo.path,
|
|
5261
|
-
nonGitSelected: repo.nonGitSelected
|
|
5262
|
-
});
|
|
5263
|
-
const record = JSON.parse(
|
|
5264
|
-
await readFile(recordPath(repo.path, deps.projectStateDir ?? stateDir), "utf8")
|
|
5274
|
+
projectConditions.push(condition);
|
|
5275
|
+
projectReadiness.push(
|
|
5276
|
+
...serializeReadiness({
|
|
5277
|
+
installation: { conditions: [] },
|
|
5278
|
+
projects: [{ identityFile: target.path, summary: { conditions: [condition] } }]
|
|
5279
|
+
}).projects ?? []
|
|
5265
5280
|
);
|
|
5266
|
-
|
|
5267
|
-
await journal.stage(target);
|
|
5281
|
+
continue;
|
|
5268
5282
|
}
|
|
5283
|
+
connectedRoots.push(repo.path);
|
|
5284
|
+
if (!journal.data.projects.some((p) => p.root === repo.path))
|
|
5285
|
+
journal.data.projects.push({
|
|
5286
|
+
root: repo.path,
|
|
5287
|
+
nonGitSelected: repo.nonGitSelected
|
|
5288
|
+
});
|
|
5289
|
+
const record = JSON.parse(
|
|
5290
|
+
await readFile(recordPath(repo.path, deps.projectStateDir ?? stateDir), "utf8")
|
|
5291
|
+
);
|
|
5292
|
+
if (record.staged) await journal.propose(target, Buffer.from(record.staged.content));
|
|
5293
|
+
await journal.stage(target);
|
|
5269
5294
|
}
|
|
5295
|
+
scannerPlan.roots.splice(0, scannerPlan.roots.length, ...connectedRoots);
|
|
5296
|
+
roots = scannerPlan.roots;
|
|
5297
|
+
journal.data.roots = roots;
|
|
5270
5298
|
}
|
|
5271
5299
|
if (!automatic && !flags2.has("apply")) {
|
|
5272
5300
|
for (; ; ) {
|
|
5273
|
-
renderJourney("apply", output, {
|
|
5274
|
-
|
|
5275
|
-
files: [
|
|
5276
|
-
...new Set(
|
|
5277
|
-
journal.data.targets.filter((t) => t.status !== "restored").map((t) => t.path)
|
|
5278
|
-
),
|
|
5279
|
-
...scannerPlan?.files ?? []
|
|
5280
|
-
]
|
|
5301
|
+
const applyLines = renderJourney("apply", output, {
|
|
5302
|
+
files: []
|
|
5281
5303
|
});
|
|
5282
5304
|
const choice = await answers?.choose(["Install and upload", "Back", "Cancel"]);
|
|
5305
|
+
replaceScreen(
|
|
5306
|
+
applyLines,
|
|
5307
|
+
choice === "Install and upload" ? completedStep(5, "Finish") : void 0
|
|
5308
|
+
);
|
|
5283
5309
|
if (choice === "Back") {
|
|
5284
5310
|
restart = true;
|
|
5285
5311
|
throw new Error("install_back");
|
|
@@ -5310,15 +5336,19 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5310
5336
|
let scannerDocument;
|
|
5311
5337
|
if (scannerPlan) {
|
|
5312
5338
|
try {
|
|
5313
|
-
scannerDocument = await scannerPlan.apply(journal);
|
|
5314
|
-
if (!
|
|
5339
|
+
scannerDocument = await scannerPlan.apply(journal, scannerPlan.roots);
|
|
5340
|
+
if (!json) {
|
|
5341
|
+
if (scannerPlan.roots.length)
|
|
5342
|
+
output.line(connectedProjectsMessage(scannerPlan.roots));
|
|
5343
|
+
if (limitMessage) for (const line of limitMessage.split("\n")) output.line(line);
|
|
5344
|
+
}
|
|
5315
5345
|
} catch (error) {
|
|
5316
5346
|
if (!(error instanceof ScannerServiceLimited)) throw error;
|
|
5317
5347
|
await scannerPlan.rollback(journal);
|
|
5318
5348
|
journal.data.reports.push(
|
|
5319
|
-
`
|
|
5349
|
+
`Background indexing was skipped (${error.reason}). Run mnemonik install to try again.`
|
|
5320
5350
|
);
|
|
5321
|
-
if (!automatic &&
|
|
5351
|
+
if (!automatic && preflight.os === "Windows")
|
|
5322
5352
|
renderJourney("windows", output, { reason: error.message });
|
|
5323
5353
|
}
|
|
5324
5354
|
}
|
|
@@ -5331,8 +5361,8 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5331
5361
|
...hostReadinessConditions(results, false),
|
|
5332
5362
|
{
|
|
5333
5363
|
kind: "scanner_omitted",
|
|
5334
|
-
reason: "
|
|
5335
|
-
action: "mnemonik
|
|
5364
|
+
reason: "Background indexing was omitted.",
|
|
5365
|
+
action: "mnemonik install"
|
|
5336
5366
|
}
|
|
5337
5367
|
]
|
|
5338
5368
|
}
|
|
@@ -5340,13 +5370,12 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5340
5370
|
);
|
|
5341
5371
|
return;
|
|
5342
5372
|
}
|
|
5343
|
-
if (!automatic) output.line(" Checking your installation, up to 2 minutes.");
|
|
5344
5373
|
const conditions = [...hostReadinessConditions(results, true), ...projectConditions];
|
|
5345
5374
|
if (!scannerDocument)
|
|
5346
5375
|
conditions.push({
|
|
5347
5376
|
kind: "scanner_omitted",
|
|
5348
|
-
reason: "
|
|
5349
|
-
action: "mnemonik
|
|
5377
|
+
reason: "Background indexing was skipped.",
|
|
5378
|
+
action: "mnemonik install"
|
|
5350
5379
|
});
|
|
5351
5380
|
const check = async () => collectStatusDocument({
|
|
5352
5381
|
preflight: {
|
|
@@ -5361,7 +5390,6 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5361
5390
|
getCliBearer: managed.getCliBearer,
|
|
5362
5391
|
transport: projectTransport,
|
|
5363
5392
|
configuredHosts: names,
|
|
5364
|
-
grants: managed.grants,
|
|
5365
5393
|
projectHookConditions: await hookStatusConditions(
|
|
5366
5394
|
managed,
|
|
5367
5395
|
components.includes("hooks") ? names.filter(
|
|
@@ -5386,7 +5414,6 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5386
5414
|
actions: [...document.installation.actions, "mnemonik doctor"]
|
|
5387
5415
|
}
|
|
5388
5416
|
};
|
|
5389
|
-
if (!automatic && document.installation.state === "READY") output.line(" \u2713 Checks passed");
|
|
5390
5417
|
document = devReadiness({
|
|
5391
5418
|
...document,
|
|
5392
5419
|
...scannerDocument?.scanner ? { scanner: scannerDocument.scanner } : {},
|
|
@@ -5408,19 +5435,23 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5408
5435
|
input: deps.input ?? process.stdin,
|
|
5409
5436
|
output,
|
|
5410
5437
|
nonInteractive: automatic,
|
|
5411
|
-
roots,
|
|
5438
|
+
...roots.length ? { roots } : {},
|
|
5439
|
+
home,
|
|
5412
5440
|
noBrowser: flags2.has("no-browser"),
|
|
5441
|
+
approvalAnnounced: true,
|
|
5413
5442
|
exclusions: String(flags2.get("exclusions") ?? "").split(",").filter(Boolean),
|
|
5414
5443
|
...deps.scannerService,
|
|
5415
5444
|
...deps.scannerEnable,
|
|
5445
|
+
projectExecutor: executor,
|
|
5446
|
+
projectStateDir: deps.projectStateDir ?? stateDir,
|
|
5416
5447
|
journal,
|
|
5417
5448
|
waiting: (phase) => {
|
|
5418
5449
|
if (!automatic)
|
|
5419
5450
|
output.line(
|
|
5420
|
-
phase === "service" ? " Waiting for
|
|
5451
|
+
phase === "service" ? " Waiting for background indexing to start, up to 2 minutes." : " Waiting for indexing to begin, up to 1 minute."
|
|
5421
5452
|
);
|
|
5422
5453
|
},
|
|
5423
|
-
timeout: async () => await choose("
|
|
5454
|
+
timeout: async () => await choose("Background indexing did not start.", ["Retry", "Skip"]) === "Retry" ? "retry" : "skip"
|
|
5424
5455
|
},
|
|
5425
5456
|
finish
|
|
5426
5457
|
);
|
|
@@ -5461,8 +5492,8 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5461
5492
|
...projectConditions,
|
|
5462
5493
|
{
|
|
5463
5494
|
kind: "scanner_not_verified",
|
|
5464
|
-
reason: `
|
|
5465
|
-
action: "mnemonik
|
|
5495
|
+
reason: `Background indexing could not be started: ${reason}`,
|
|
5496
|
+
action: "mnemonik install"
|
|
5466
5497
|
}
|
|
5467
5498
|
]
|
|
5468
5499
|
},
|
|
@@ -5479,16 +5510,14 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5479
5510
|
{
|
|
5480
5511
|
...managed,
|
|
5481
5512
|
noBrowser: flags2.has("no-browser"),
|
|
5482
|
-
approveHost: managed.approveHost ?? (async () => true),
|
|
5483
5513
|
apply: true,
|
|
5484
5514
|
afterHosts,
|
|
5485
5515
|
rollbackInstall,
|
|
5486
5516
|
installPlan: { components, roots },
|
|
5487
5517
|
recovery: async () => "resume",
|
|
5488
|
-
instruction: automatic ? void 0 : (text) => output.line(text)
|
|
5489
|
-
timeout: managed.timeout ?? (automatic ? void 0 : async (host) => await choose(`${host} has not connected yet.`, ["Retry", "Skip"]) === "Retry" ? "retry" : "skip")
|
|
5518
|
+
instruction: automatic ? void 0 : (text) => output.line(text)
|
|
5490
5519
|
},
|
|
5491
|
-
|
|
5520
|
+
false
|
|
5492
5521
|
);
|
|
5493
5522
|
if (restart && result.journal.phase === "rolled_back") {
|
|
5494
5523
|
answers?.close();
|
|
@@ -5526,6 +5555,7 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5526
5555
|
actions: [...final.installation.actions, launcherError.launcher.action]
|
|
5527
5556
|
};
|
|
5528
5557
|
final = await reportFinal({ ...final, ...launcher ? { launcher } : {} });
|
|
5558
|
+
await log({ preflight, journal: result.journal, targets: result.results, readiness: final });
|
|
5529
5559
|
if (json)
|
|
5530
5560
|
output.json({
|
|
5531
5561
|
...final,
|
|
@@ -5536,14 +5566,8 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5536
5566
|
phase: result.journal.phase
|
|
5537
5567
|
});
|
|
5538
5568
|
else {
|
|
5539
|
-
renderStatusSummaries(final, output);
|
|
5540
|
-
for (const target of result.results)
|
|
5541
|
-
output.line(
|
|
5542
|
-
`${target.target}: ${target.status} (${target.reason}${target.detail ? `: ${target.detail}` : ""})`
|
|
5543
|
-
);
|
|
5544
5569
|
if (result.journal.state === "FAILED") {
|
|
5545
|
-
output.line(` Installation failed.
|
|
5546
|
-
for (const line of result.reports) output.line(` ${line}`);
|
|
5570
|
+
output.line(` Installation failed. Details: ${logPath}`);
|
|
5547
5571
|
} else if (final.installation.state === "READY")
|
|
5548
5572
|
renderJourney("done", output, {
|
|
5549
5573
|
total: final.indexing?.total,
|
|
@@ -5552,20 +5576,20 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5552
5576
|
else
|
|
5553
5577
|
renderJourney("skipped", output, {
|
|
5554
5578
|
remaining: remainingReadinessCount(final.installation),
|
|
5555
|
-
skipped: [...
|
|
5579
|
+
skipped: [...new Set(final.installation.actions)].join("\n") || "mnemonik status"
|
|
5556
5580
|
});
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
else {
|
|
5562
|
-
if (launcher && !launcher.onPath) output.line(` ${launcherPathAction(launcherOptions)}`);
|
|
5563
|
-
output.line(" In this terminal: npx -y @mnemonik/cli@latest status");
|
|
5564
|
-
}
|
|
5581
|
+
if (launcherError || launcher && !launcher.onPath)
|
|
5582
|
+
output.line(
|
|
5583
|
+
` ${launcher ? launcherPathAction(launcherOptions) : "Run npx -y @mnemonik/cli@latest status"}`
|
|
5584
|
+
);
|
|
5565
5585
|
}
|
|
5566
5586
|
return result.journal.state === "FAILED" ? 1 : result.journal.phase === "rolled_back" ? 130 : final.installation.state === "READY" ? 0 : 3;
|
|
5567
5587
|
} catch (error) {
|
|
5568
5588
|
const reason = error instanceof Error ? error.message : "install_failed";
|
|
5589
|
+
if (reason === "install_cancelled") {
|
|
5590
|
+
output.line(" Installation cancelled.");
|
|
5591
|
+
return 130;
|
|
5592
|
+
}
|
|
5569
5593
|
await reportFinal(
|
|
5570
5594
|
serializeReadiness({
|
|
5571
5595
|
installation: {
|
|
@@ -5581,7 +5605,10 @@ async function joinedInstall(flags2, deps, output, authorize, management) {
|
|
|
5581
5605
|
reason,
|
|
5582
5606
|
...error instanceof LauncherError ? { launcher: error.launcher } : {}
|
|
5583
5607
|
});
|
|
5584
|
-
else
|
|
5608
|
+
else {
|
|
5609
|
+
await log({ error: reason }).catch(() => void 0);
|
|
5610
|
+
output.error(`Installation stopped. Details: ${logPath}`);
|
|
5611
|
+
}
|
|
5585
5612
|
return 3;
|
|
5586
5613
|
} finally {
|
|
5587
5614
|
answers?.close();
|