@mnemonik/cli 7.140.1 → 7.140.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/credentials.js +41 -8
- package/dist/auth/index.js +41 -8
- package/dist/auth/installSession.js +1 -1
- package/dist/auth/status.js +1 -1
- package/dist/authorizationWords.js +1 -1
- package/dist/diagnostics.js +41 -8
- package/dist/digests.json +71 -67
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +50 -4
- package/dist/help.js.map +1 -1
- package/dist/hooksLog.d.ts +61 -0
- package/dist/hooksLog.d.ts.map +1 -0
- package/dist/hooksLog.js +350 -0
- package/dist/hooksLog.js.map +1 -0
- package/dist/humanReason.d.ts +7 -0
- package/dist/humanReason.d.ts.map +1 -1
- package/dist/humanReason.js +12 -4
- package/dist/humanReason.js.map +1 -1
- package/dist/identity/migrate.js +102 -69
- package/dist/install/hosts.js +1 -1
- package/dist/install/journal.js +41 -8
- package/dist/install/journey.d.ts.map +1 -1
- package/dist/install/journey.js +41 -11
- package/dist/install/journey.js.map +1 -1
- package/dist/install/ownership.js +41 -8
- package/dist/install/transaction.d.ts.map +1 -1
- package/dist/install/transaction.js +42 -10
- package/dist/install/transaction.js.map +1 -1
- package/dist/install/ui.js +41 -8
- package/dist/installSession.js +1 -1
- package/dist/installation.js +41 -8
- package/dist/launcher.js +41 -8
- package/dist/preflight.js +201 -164
- package/dist/project/eligibility.js +41 -8
- package/dist/project/records.js +41 -8
- package/dist/project.d.ts +35 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +294 -231
- package/dist/project.js.map +1 -1
- package/dist/router.d.ts +7 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +340 -182
- package/dist/router.js.map +1 -1
- package/dist/runtime/bootstrap.d.ts +22 -1
- package/dist/runtime/bootstrap.d.ts.map +1 -1
- package/dist/runtime/bootstrap.js +61 -8
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/releaseSource.js +41 -8
- package/dist/runtime/selfUpdate.js +41 -8
- package/dist/runtime/signers.js +789 -183
- package/dist/runtime/store.d.ts +1 -1
- package/dist/runtime/store.d.ts.map +1 -1
- package/dist/runtime/store.js +54 -5
- package/dist/runtime/store.js.map +1 -1
- package/dist/runtime/updateCheck.js +41 -8
- package/dist/sbom.json +21 -21
- package/dist/scanner/control.js +41 -8
- package/dist/scanner/data.js +1 -1
- package/dist/scanner/discover.d.ts.map +1 -1
- package/dist/scanner/discover.js +211 -171
- package/dist/scanner/discover.js.map +1 -1
- package/dist/scanner/enable.d.ts.map +1 -1
- package/dist/scanner/enable.js +440 -57
- package/dist/scanner/enable.js.map +1 -1
- package/dist/scanner/picker.d.ts.map +1 -1
- package/dist/scanner/picker.js +12 -4
- package/dist/scanner/picker.js.map +1 -1
- package/dist/scanner/service.js +41 -8
- package/dist/scanner/update.js +41 -8
- package/dist/scanner-release.json +24 -24
- package/dist/status.js +41 -8
- package/dist/vendor/local-setup.js +44 -11
- package/package.json +31 -31
package/dist/scanner/enable.js
CHANGED
|
@@ -729,13 +729,13 @@ var require_ignore = __commonJS({
|
|
|
729
729
|
const rules = this._rules;
|
|
730
730
|
const { length } = rules;
|
|
731
731
|
const shortcut = this._basenameCount * 2 >= length;
|
|
732
|
-
const
|
|
732
|
+
const basename3 = shortcut ? basenameOf(path) : path;
|
|
733
733
|
for (let index = 0; index < length; index++) {
|
|
734
734
|
const rule = rules[index];
|
|
735
735
|
const { negative } = rule;
|
|
736
736
|
const skip = unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored;
|
|
737
737
|
if (!skip && rule[mode].test(
|
|
738
|
-
shortcut && rule._basenameOnly ?
|
|
738
|
+
shortcut && rule._basenameOnly ? basename3 : path
|
|
739
739
|
)) {
|
|
740
740
|
ignored = !negative;
|
|
741
741
|
unignored = negative;
|
|
@@ -885,6 +885,116 @@ var require_ignore = __commonJS({
|
|
|
885
885
|
}
|
|
886
886
|
});
|
|
887
887
|
|
|
888
|
+
// packages/shared/dist/secretPatterns.js
|
|
889
|
+
var init_secretPatterns = __esm({
|
|
890
|
+
"packages/shared/dist/secretPatterns.js"() {
|
|
891
|
+
"use strict";
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
// packages/shared/dist/protectedPaths.js
|
|
896
|
+
var init_protectedPaths = __esm({
|
|
897
|
+
"packages/shared/dist/protectedPaths.js"() {
|
|
898
|
+
"use strict";
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
// packages/shared/dist/projectIdentityFile.js
|
|
903
|
+
import { lstat, readFile } from "node:fs/promises";
|
|
904
|
+
import { join } from "node:path";
|
|
905
|
+
function parseIdentityFile(text) {
|
|
906
|
+
let value;
|
|
907
|
+
try {
|
|
908
|
+
value = JSON.parse(text);
|
|
909
|
+
} catch (error) {
|
|
910
|
+
return { kind: "malformed", detail: `unparseable JSON: ${error.message}` };
|
|
911
|
+
}
|
|
912
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
913
|
+
return { kind: "malformed", detail: "identity file must contain a JSON object" };
|
|
914
|
+
}
|
|
915
|
+
const record = value;
|
|
916
|
+
if (record.schemaVersion !== 1) {
|
|
917
|
+
return { kind: "unknown_version", version: record.schemaVersion };
|
|
918
|
+
}
|
|
919
|
+
const unknownKey = Object.keys(record).find((key) => !IDENTITY_KEYS.has(key));
|
|
920
|
+
if (unknownKey)
|
|
921
|
+
return { kind: "malformed", detail: `unknown key "${unknownKey}"` };
|
|
922
|
+
if (!isCanonicalUuid(record.projectId)) {
|
|
923
|
+
return { kind: "malformed", detail: '"projectId" must be a canonical RFC 4122 UUID string' };
|
|
924
|
+
}
|
|
925
|
+
if ("projectName" in record && typeof record.projectName !== "string") {
|
|
926
|
+
return { kind: "malformed", detail: '"projectName" must be a string when present' };
|
|
927
|
+
}
|
|
928
|
+
if ("repositoryFingerprint" in record && (!record.repositoryFingerprint || typeof record.repositoryFingerprint !== "object" || Array.isArray(record.repositoryFingerprint))) {
|
|
929
|
+
return { kind: "malformed", detail: '"repositoryFingerprint" must be an object when present' };
|
|
930
|
+
}
|
|
931
|
+
const fingerprint = record.repositoryFingerprint;
|
|
932
|
+
const unknownFingerprintKey = fingerprint ? Object.keys(fingerprint).find((key) => !FINGERPRINT_KEYS.has(key)) : void 0;
|
|
933
|
+
if (unknownFingerprintKey) {
|
|
934
|
+
return {
|
|
935
|
+
kind: "malformed",
|
|
936
|
+
detail: `unknown repositoryFingerprint key "${unknownFingerprintKey}"`
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
if (fingerprint && (fingerprint.algorithmVersion !== 1 || typeof fingerprint.hash !== "string")) {
|
|
940
|
+
return {
|
|
941
|
+
kind: "malformed",
|
|
942
|
+
detail: '"repositoryFingerprint" must contain algorithmVersion 1 and a string hash'
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
const repositoryFingerprint = fingerprint ? { algorithmVersion: 1, hash: fingerprint.hash } : void 0;
|
|
946
|
+
return {
|
|
947
|
+
kind: "ok",
|
|
948
|
+
identity: {
|
|
949
|
+
schemaVersion: 1,
|
|
950
|
+
projectId: record.projectId,
|
|
951
|
+
...record.projectName === void 0 ? {} : { projectName: record.projectName },
|
|
952
|
+
...repositoryFingerprint ? { repositoryFingerprint } : {}
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
function isConfigurationOnly(text) {
|
|
957
|
+
try {
|
|
958
|
+
const value = JSON.parse(text);
|
|
959
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && !("projectId" in value) && (!("schemaVersion" in value) || value.schemaVersion === 1);
|
|
960
|
+
} catch {
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
async function readIdentityFile(dir, options = {}) {
|
|
965
|
+
const path = join(dir, ".mnemonik.json");
|
|
966
|
+
try {
|
|
967
|
+
const stat = await lstat(path);
|
|
968
|
+
if (stat.isSymbolicLink())
|
|
969
|
+
return { kind: "malformed", detail: "symlink" };
|
|
970
|
+
if (!stat.isFile())
|
|
971
|
+
return { kind: "malformed", detail: "identity path is not a regular file" };
|
|
972
|
+
const text = await readFile(path, "utf8");
|
|
973
|
+
if ((options.selectedRoot || options.configurationOnlyAbsent) && isConfigurationOnly(text))
|
|
974
|
+
return { kind: "absent" };
|
|
975
|
+
return parseIdentityFile(text);
|
|
976
|
+
} catch (error) {
|
|
977
|
+
if (error.code === "ENOENT")
|
|
978
|
+
return { kind: "absent" };
|
|
979
|
+
return { kind: "malformed", detail: `cannot read identity file: ${error.message}` };
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
var CANONICAL_UUID, isCanonicalUuid, IDENTITY_KEYS, FINGERPRINT_KEYS;
|
|
983
|
+
var init_projectIdentityFile = __esm({
|
|
984
|
+
"packages/shared/dist/projectIdentityFile.js"() {
|
|
985
|
+
"use strict";
|
|
986
|
+
CANONICAL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
987
|
+
isCanonicalUuid = (value) => typeof value === "string" && CANONICAL_UUID.test(value);
|
|
988
|
+
IDENTITY_KEYS = /* @__PURE__ */ new Set([
|
|
989
|
+
"schemaVersion",
|
|
990
|
+
"projectId",
|
|
991
|
+
"projectName",
|
|
992
|
+
"repositoryFingerprint"
|
|
993
|
+
]);
|
|
994
|
+
FINGERPRINT_KEYS = /* @__PURE__ */ new Set(["algorithmVersion", "hash"]);
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
|
|
888
998
|
// packages/shared/dist/hookTimeouts.js
|
|
889
999
|
var init_hookTimeouts = __esm({
|
|
890
1000
|
"packages/shared/dist/hookTimeouts.js"() {
|
|
@@ -893,7 +1003,7 @@ var init_hookTimeouts = __esm({
|
|
|
893
1003
|
});
|
|
894
1004
|
|
|
895
1005
|
// packages/shared/dist/runtimeSigners.js
|
|
896
|
-
import { basename, dirname as dirname2, join as
|
|
1006
|
+
import { basename, dirname as dirname2, join as join3, resolve, sep, win32 } from "node:path";
|
|
897
1007
|
import { execFile, execFileSync } from "node:child_process";
|
|
898
1008
|
function windowsCommand(file) {
|
|
899
1009
|
const root = process.env.SystemRoot;
|
|
@@ -982,18 +1092,265 @@ var init_repositoryFingerprint = __esm({
|
|
|
982
1092
|
}
|
|
983
1093
|
});
|
|
984
1094
|
|
|
985
|
-
// packages/shared/dist/projectIdentityFile.js
|
|
986
|
-
var init_projectIdentityFile = __esm({
|
|
987
|
-
"packages/shared/dist/projectIdentityFile.js"() {
|
|
988
|
-
"use strict";
|
|
989
|
-
}
|
|
990
|
-
});
|
|
991
|
-
|
|
992
1095
|
// packages/shared/dist/repositoryRoot.js
|
|
1096
|
+
import { lstat as lstat2, readFile as readFile2, realpath } from "node:fs/promises";
|
|
1097
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
1098
|
+
import { homedir } from "node:os";
|
|
1099
|
+
import { dirname as dirname3, join as join4, resolve as resolve2 } from "node:path";
|
|
1100
|
+
function gitEnvironment() {
|
|
1101
|
+
const env = {};
|
|
1102
|
+
for (const key of GIT_ENV_KEYS) {
|
|
1103
|
+
if (process.env[key] !== void 0)
|
|
1104
|
+
env[key] = process.env[key];
|
|
1105
|
+
}
|
|
1106
|
+
env.LC_ALL = "C";
|
|
1107
|
+
return env;
|
|
1108
|
+
}
|
|
1109
|
+
function runGit(cwd, args2) {
|
|
1110
|
+
return new Promise((resolvePromise, reject) => {
|
|
1111
|
+
execFile2("git", args2, { cwd, timeout: GIT_TIMEOUT_MS, encoding: "utf8", env: gitEnvironment() }, (error, stdout, stderr) => {
|
|
1112
|
+
if (error)
|
|
1113
|
+
reject(Object.assign(error, { stdout, stderr }));
|
|
1114
|
+
else
|
|
1115
|
+
resolvePromise({ stdout, stderr });
|
|
1116
|
+
});
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
async function boundaryAt(path) {
|
|
1120
|
+
try {
|
|
1121
|
+
const stat = await lstat2(join4(path, ".git"));
|
|
1122
|
+
if (stat.isDirectory())
|
|
1123
|
+
return { path, kind: "directory" };
|
|
1124
|
+
if (stat.isFile())
|
|
1125
|
+
return { path, kind: "file" };
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
const code = error.code;
|
|
1128
|
+
if (code !== "ENOENT" && code !== "ENOTDIR")
|
|
1129
|
+
throw error;
|
|
1130
|
+
}
|
|
1131
|
+
return void 0;
|
|
1132
|
+
}
|
|
1133
|
+
async function confirmedBoundaryAt(path) {
|
|
1134
|
+
const boundary = await boundaryAt(path);
|
|
1135
|
+
if (!boundary)
|
|
1136
|
+
return void 0;
|
|
1137
|
+
try {
|
|
1138
|
+
const { stdout } = await runGit(path, ["rev-parse", "--git-dir"]);
|
|
1139
|
+
return stdout.trim() ? boundary : void 0;
|
|
1140
|
+
} catch {
|
|
1141
|
+
return void 0;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
async function boundariesBetween(cwd, root) {
|
|
1145
|
+
const boundaries = [];
|
|
1146
|
+
let directory = cwd;
|
|
1147
|
+
while (!samePath(directory, root)) {
|
|
1148
|
+
const boundary = await confirmedBoundaryAt(directory);
|
|
1149
|
+
if (boundary)
|
|
1150
|
+
boundaries.push(boundary);
|
|
1151
|
+
const parent = dirname3(directory);
|
|
1152
|
+
if (parent === directory)
|
|
1153
|
+
break;
|
|
1154
|
+
directory = parent;
|
|
1155
|
+
}
|
|
1156
|
+
return boundaries;
|
|
1157
|
+
}
|
|
1158
|
+
async function containingRepository(root) {
|
|
1159
|
+
let directory = dirname3(root);
|
|
1160
|
+
while (true) {
|
|
1161
|
+
const boundary = await confirmedBoundaryAt(directory);
|
|
1162
|
+
if (boundary)
|
|
1163
|
+
return boundary;
|
|
1164
|
+
const parent = dirname3(directory);
|
|
1165
|
+
if (parent === directory)
|
|
1166
|
+
return void 0;
|
|
1167
|
+
directory = parent;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
async function canonicalPath(path) {
|
|
1171
|
+
const absolute = resolve2(path);
|
|
1172
|
+
return realpath(absolute).catch(() => absolute);
|
|
1173
|
+
}
|
|
1174
|
+
function samePath(left, right) {
|
|
1175
|
+
return process.platform === "win32" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
1176
|
+
}
|
|
1177
|
+
async function resolveRepositoryRoot(cwd) {
|
|
1178
|
+
const absoluteCwd = await canonicalPath(cwd);
|
|
1179
|
+
try {
|
|
1180
|
+
const { stdout } = await runGit(absoluteCwd, [
|
|
1181
|
+
"rev-parse",
|
|
1182
|
+
"--show-toplevel",
|
|
1183
|
+
"--git-dir",
|
|
1184
|
+
"--git-common-dir"
|
|
1185
|
+
]);
|
|
1186
|
+
const [rootLine, gitDirLine, commonLine, ...extra] = stdout.trim().split(/\r?\n/);
|
|
1187
|
+
if (!rootLine || !gitDirLine || !commonLine || extra.length) {
|
|
1188
|
+
return { kind: "git_unavailable", detail: "git rev-parse returned an unexpected response" };
|
|
1189
|
+
}
|
|
1190
|
+
const fromGit = (line) => canonicalPath(resolve2(absoluteCwd, line));
|
|
1191
|
+
const root = await fromGit(rootLine);
|
|
1192
|
+
const gitDir = await fromGit(gitDirLine);
|
|
1193
|
+
const commonDir = await fromGit(commonLine);
|
|
1194
|
+
const isLinkedWorktree = !samePath(gitDir, commonDir);
|
|
1195
|
+
const nested = await boundariesBetween(absoluteCwd, root);
|
|
1196
|
+
if (!isLinkedWorktree && await containingRepository(root)) {
|
|
1197
|
+
const boundary = await boundaryAt(root);
|
|
1198
|
+
if (boundary)
|
|
1199
|
+
nested.push(boundary);
|
|
1200
|
+
}
|
|
1201
|
+
return {
|
|
1202
|
+
kind: "git",
|
|
1203
|
+
root,
|
|
1204
|
+
commonDir,
|
|
1205
|
+
isLinkedWorktree,
|
|
1206
|
+
nested
|
|
1207
|
+
};
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
const failure = error;
|
|
1210
|
+
if (failure.code === 128 && /not a git repository/i.test(failure.stderr ?? failure.message)) {
|
|
1211
|
+
return { kind: "plain", root: absoluteCwd };
|
|
1212
|
+
}
|
|
1213
|
+
return { kind: "git_unavailable", detail: failure.message };
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
async function linkedWorktreeCommonDir(dir) {
|
|
1217
|
+
try {
|
|
1218
|
+
if (!(await lstat2(join4(dir, ".git"))).isFile())
|
|
1219
|
+
return void 0;
|
|
1220
|
+
const pointer = /^gitdir:\s*(.+?)\s*$/im.exec(await readFile2(join4(dir, ".git"), "utf8"))?.[1];
|
|
1221
|
+
if (!pointer)
|
|
1222
|
+
return void 0;
|
|
1223
|
+
const gitDir = resolve2(dir, pointer);
|
|
1224
|
+
const common = (await readFile2(join4(gitDir, "commondir"), "utf8")).trim();
|
|
1225
|
+
return common ? await canonicalPath(resolve2(gitDir, common)) : void 0;
|
|
1226
|
+
} catch {
|
|
1227
|
+
return void 0;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
async function mainCheckout(worktreeTop, commonDir) {
|
|
1231
|
+
try {
|
|
1232
|
+
const { stdout } = await runGit(worktreeTop, ["worktree", "list", "--porcelain"]);
|
|
1233
|
+
const first = stdout.split(/\r?\n\r?\n/)[0] ?? "";
|
|
1234
|
+
const path = /^worktree (.+)$/m.exec(first)?.[1];
|
|
1235
|
+
if (path) {
|
|
1236
|
+
const main = await canonicalPath(resolve2(worktreeTop, path));
|
|
1237
|
+
return /^bare$/m.test(first) ? dirname3(main) : main;
|
|
1238
|
+
}
|
|
1239
|
+
} catch {
|
|
1240
|
+
}
|
|
1241
|
+
return dirname3(commonDir);
|
|
1242
|
+
}
|
|
1243
|
+
async function readPlainIdentity(start2) {
|
|
1244
|
+
const home = await canonicalPath(homedir());
|
|
1245
|
+
let directory = start2;
|
|
1246
|
+
while (true) {
|
|
1247
|
+
const result = await readIdentityFile(directory, { configurationOnlyAbsent: true });
|
|
1248
|
+
if (result.kind !== "absent")
|
|
1249
|
+
return { root: directory, result };
|
|
1250
|
+
if (samePath(directory, home))
|
|
1251
|
+
break;
|
|
1252
|
+
const parent = dirname3(directory);
|
|
1253
|
+
if (parent === directory)
|
|
1254
|
+
break;
|
|
1255
|
+
directory = parent;
|
|
1256
|
+
}
|
|
1257
|
+
return { root: start2, result: { kind: "absent" } };
|
|
1258
|
+
}
|
|
1259
|
+
async function nearestIdentity(start2) {
|
|
1260
|
+
const home = await canonicalPath(homedir());
|
|
1261
|
+
let directory = start2;
|
|
1262
|
+
while (true) {
|
|
1263
|
+
const commonDir = await linkedWorktreeCommonDir(directory);
|
|
1264
|
+
if (commonDir)
|
|
1265
|
+
return { worktreeTop: directory, commonDir };
|
|
1266
|
+
const result = await readIdentityFile(directory, { configurationOnlyAbsent: true });
|
|
1267
|
+
if (result.kind !== "absent")
|
|
1268
|
+
return { root: directory, result };
|
|
1269
|
+
if (samePath(directory, home))
|
|
1270
|
+
return void 0;
|
|
1271
|
+
const parent = dirname3(directory);
|
|
1272
|
+
if (parent === directory)
|
|
1273
|
+
return void 0;
|
|
1274
|
+
directory = parent;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
async function resolveNearestProjectIdentity(cwd) {
|
|
1278
|
+
const start2 = await canonicalPath(cwd);
|
|
1279
|
+
const resolved = await resolveRepositoryRoot(start2);
|
|
1280
|
+
const repository = resolved.kind === "git_unavailable" ? { kind: "plain", root: start2 } : resolved;
|
|
1281
|
+
const nested = repository.kind === "git" ? repository.nested : [];
|
|
1282
|
+
let found = await nearestIdentity(start2);
|
|
1283
|
+
if (found && "worktreeTop" in found) {
|
|
1284
|
+
found = await readPlainIdentity(await mainCheckout(found.worktreeTop, found.commonDir));
|
|
1285
|
+
}
|
|
1286
|
+
if (found) {
|
|
1287
|
+
return shapedIdentity(found, await projectFolderRepository(found.root, repository), nested);
|
|
1288
|
+
}
|
|
1289
|
+
return { ...withBase(repository, repository.root, nested), kind: "absent" };
|
|
1290
|
+
}
|
|
1291
|
+
async function resolveNamedProjectIdentity(cwd, options) {
|
|
1292
|
+
const start2 = await canonicalPath(cwd);
|
|
1293
|
+
const resolved = await resolveRepositoryRoot(start2);
|
|
1294
|
+
const repository = resolved.kind === "git_unavailable" ? { kind: "plain", root: start2 } : resolved;
|
|
1295
|
+
const commonDir = await linkedWorktreeCommonDir(start2);
|
|
1296
|
+
const root = commonDir ? await mainCheckout(start2, commonDir) : start2;
|
|
1297
|
+
return shapedIdentity({ root, result: await readIdentityFile(root, options) }, await projectFolderRepository(root, repository), repository.kind === "git" ? repository.nested : []);
|
|
1298
|
+
}
|
|
1299
|
+
function shapedIdentity(found, repository, nested) {
|
|
1300
|
+
const base = withBase(repository, found.root, nested);
|
|
1301
|
+
if (found.result.kind === "ok")
|
|
1302
|
+
return { ...base, ...found.result };
|
|
1303
|
+
if (found.result.kind === "unknown_version")
|
|
1304
|
+
return { ...base, ...found.result, path: found.root };
|
|
1305
|
+
if (found.result.kind === "malformed")
|
|
1306
|
+
return { ...base, ...found.result, path: found.root };
|
|
1307
|
+
return { ...base, kind: "absent" };
|
|
1308
|
+
}
|
|
1309
|
+
async function projectFolderRepository(projectRoot, known) {
|
|
1310
|
+
if (known.kind === "git" && samePath(known.root, projectRoot))
|
|
1311
|
+
return known;
|
|
1312
|
+
const repository = await resolveRepositoryRoot(projectRoot);
|
|
1313
|
+
if (repository.kind === "git" && samePath(repository.root, projectRoot))
|
|
1314
|
+
return repository;
|
|
1315
|
+
return { kind: "plain", root: projectRoot };
|
|
1316
|
+
}
|
|
1317
|
+
function withBase(repository, root, nested) {
|
|
1318
|
+
return { root, repository, nested };
|
|
1319
|
+
}
|
|
1320
|
+
async function resolveProjectIdentity(cwd, options = {}) {
|
|
1321
|
+
if (options.selectedRoot || options.namedRoot) {
|
|
1322
|
+
return resolveNamedProjectIdentity(cwd, { selectedRoot: options.selectedRoot });
|
|
1323
|
+
}
|
|
1324
|
+
return resolveNearestProjectIdentity(cwd);
|
|
1325
|
+
}
|
|
1326
|
+
var GIT_TIMEOUT_MS, GIT_ENV_KEYS;
|
|
993
1327
|
var init_repositoryRoot = __esm({
|
|
994
1328
|
"packages/shared/dist/repositoryRoot.js"() {
|
|
995
1329
|
"use strict";
|
|
996
1330
|
init_projectIdentityFile();
|
|
1331
|
+
GIT_TIMEOUT_MS = 2e3;
|
|
1332
|
+
GIT_ENV_KEYS = [
|
|
1333
|
+
"PATH",
|
|
1334
|
+
"HOME",
|
|
1335
|
+
"LANG",
|
|
1336
|
+
"LC_ALL",
|
|
1337
|
+
"SYSTEMROOT",
|
|
1338
|
+
"TEMP",
|
|
1339
|
+
"TMP",
|
|
1340
|
+
"USERPROFILE"
|
|
1341
|
+
];
|
|
1342
|
+
}
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1345
|
+
// packages/shared/dist/hookTrace.js
|
|
1346
|
+
var HOOK_TRACE_MAX_BYTES;
|
|
1347
|
+
var init_hookTrace = __esm({
|
|
1348
|
+
"packages/shared/dist/hookTrace.js"() {
|
|
1349
|
+
"use strict";
|
|
1350
|
+
init_protectedPaths();
|
|
1351
|
+
init_runtimeSigners();
|
|
1352
|
+
init_secretPatterns();
|
|
1353
|
+
HOOK_TRACE_MAX_BYTES = 2 * 1024 * 1024;
|
|
997
1354
|
}
|
|
998
1355
|
});
|
|
999
1356
|
|
|
@@ -1068,10 +1425,12 @@ var init_hookRuntime = __esm({
|
|
|
1068
1425
|
init_runtimeSigners();
|
|
1069
1426
|
init_hookTimeouts();
|
|
1070
1427
|
init_repositoryRoot();
|
|
1428
|
+
init_hookTrace();
|
|
1071
1429
|
init_runtimeReader();
|
|
1072
1430
|
init_runtimeSigners();
|
|
1073
1431
|
init_projectSetupHandoff();
|
|
1074
1432
|
init_hookConversation();
|
|
1433
|
+
init_hookTrace();
|
|
1075
1434
|
}
|
|
1076
1435
|
});
|
|
1077
1436
|
|
|
@@ -1567,8 +1926,8 @@ var require_graceful_fs = __commonJS({
|
|
|
1567
1926
|
fs4.createReadStream = createReadStream;
|
|
1568
1927
|
fs4.createWriteStream = createWriteStream;
|
|
1569
1928
|
var fs$readFile = fs4.readFile;
|
|
1570
|
-
fs4.readFile =
|
|
1571
|
-
function
|
|
1929
|
+
fs4.readFile = readFile5;
|
|
1930
|
+
function readFile5(path, options, cb) {
|
|
1572
1931
|
if (typeof options === "function")
|
|
1573
1932
|
cb = options, options = null;
|
|
1574
1933
|
return go$readFile(path, options, cb);
|
|
@@ -2574,12 +2933,12 @@ var require_adapter = __commonJS({
|
|
|
2574
2933
|
return newFs;
|
|
2575
2934
|
}
|
|
2576
2935
|
function toPromise(method) {
|
|
2577
|
-
return (...args2) => new Promise((
|
|
2936
|
+
return (...args2) => new Promise((resolve3, reject) => {
|
|
2578
2937
|
args2.push((err2, result) => {
|
|
2579
2938
|
if (err2) {
|
|
2580
2939
|
reject(err2);
|
|
2581
2940
|
} else {
|
|
2582
|
-
|
|
2941
|
+
resolve3(result);
|
|
2583
2942
|
}
|
|
2584
2943
|
});
|
|
2585
2944
|
method(...args2);
|
|
@@ -2654,12 +3013,12 @@ var require_proper_lockfile = __commonJS({
|
|
|
2654
3013
|
|
|
2655
3014
|
// packages/cli/src/scanner/enable.ts
|
|
2656
3015
|
import { revokeInstallComponent } from "../install/transaction.js";
|
|
2657
|
-
import { mkdir as mkdir2, readFile as
|
|
2658
|
-
import { join as
|
|
3016
|
+
import { mkdir as mkdir2, readFile as readFile4, realpath as realpath2 } from "node:fs/promises";
|
|
3017
|
+
import { basename as basename2, join as join7 } from "node:path";
|
|
2659
3018
|
import { isDeepStrictEqual } from "node:util";
|
|
2660
3019
|
|
|
2661
3020
|
// packages/shared/dist/instructions.js
|
|
2662
|
-
var INSTRUCTIONS_CONTENT = `Mnemonik provides persistent project memory: decisions, rationale, tasks, and policies across sessions. If no block begins "PROJECT_CONTEXT schemaVersion=", session_bootstrap({
|
|
3021
|
+
var INSTRUCTIONS_CONTENT = `Mnemonik provides persistent project memory: decisions, rationale, tasks, and policies across sessions. If no block begins "PROJECT_CONTEXT schemaVersion=", session_bootstrap({}) loads project context; installed hooks supply the project. With that block, context is loaded and no session_bootstrap call is needed. Code and docs show current artifacts, git shows changes, and memory carries the why; memory_search recalls rationale or intent, then Grep or Read verifies current source.
|
|
2663
3022
|
|
|
2664
3023
|
What I learn about you belongs in Companion; what I learn about this project belongs here.
|
|
2665
3024
|
|
|
@@ -2696,6 +3055,9 @@ var MCP_INSTRUCTIONS = getMcpInstructions();
|
|
|
2696
3055
|
|
|
2697
3056
|
// packages/shared/dist/codeScanner.js
|
|
2698
3057
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
3058
|
+
init_secretPatterns();
|
|
3059
|
+
init_protectedPaths();
|
|
3060
|
+
init_projectIdentityFile();
|
|
2699
3061
|
|
|
2700
3062
|
// node_modules/web-tree-sitter/web-tree-sitter.js
|
|
2701
3063
|
var __defProp2 = Object.defineProperty;
|
|
@@ -4326,13 +4688,13 @@ async function Module2(moduleArg = {}) {
|
|
|
4326
4688
|
}
|
|
4327
4689
|
readAsync = /* @__PURE__ */ __name(async (url) => {
|
|
4328
4690
|
if (isFileURI(url)) {
|
|
4329
|
-
return new Promise((
|
|
4691
|
+
return new Promise((resolve3, reject) => {
|
|
4330
4692
|
var xhr = new XMLHttpRequest();
|
|
4331
4693
|
xhr.open("GET", url, true);
|
|
4332
4694
|
xhr.responseType = "arraybuffer";
|
|
4333
4695
|
xhr.onload = () => {
|
|
4334
4696
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
4335
|
-
|
|
4697
|
+
resolve3(xhr.response);
|
|
4336
4698
|
return;
|
|
4337
4699
|
}
|
|
4338
4700
|
reject(xhr.status);
|
|
@@ -4528,9 +4890,9 @@ async function Module2(moduleArg = {}) {
|
|
|
4528
4890
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
4529
4891
|
var info22 = getWasmImports();
|
|
4530
4892
|
if (Module["instantiateWasm"]) {
|
|
4531
|
-
return new Promise((
|
|
4893
|
+
return new Promise((resolve3, reject) => {
|
|
4532
4894
|
Module["instantiateWasm"](info22, (mod, inst) => {
|
|
4533
|
-
|
|
4895
|
+
resolve3(receiveInstance(mod, inst));
|
|
4534
4896
|
});
|
|
4535
4897
|
});
|
|
4536
4898
|
}
|
|
@@ -5863,8 +6225,8 @@ async function Module2(moduleArg = {}) {
|
|
|
5863
6225
|
if (runtimeInitialized) {
|
|
5864
6226
|
moduleRtn = Module;
|
|
5865
6227
|
} else {
|
|
5866
|
-
moduleRtn = new Promise((
|
|
5867
|
-
readyPromiseResolve =
|
|
6228
|
+
moduleRtn = new Promise((resolve3, reject) => {
|
|
6229
|
+
readyPromiseResolve = resolve3;
|
|
5868
6230
|
readyPromiseReject = reject;
|
|
5869
6231
|
});
|
|
5870
6232
|
}
|
|
@@ -6741,9 +7103,9 @@ var Query = class {
|
|
|
6741
7103
|
};
|
|
6742
7104
|
|
|
6743
7105
|
// packages/shared/dist/ast/grammars.js
|
|
6744
|
-
import { dirname, extname, join } from "node:path";
|
|
7106
|
+
import { dirname, extname, join as join2 } from "node:path";
|
|
6745
7107
|
import { fileURLToPath } from "node:url";
|
|
6746
|
-
var WASM_DIR =
|
|
7108
|
+
var WASM_DIR = join2(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm");
|
|
6747
7109
|
|
|
6748
7110
|
// packages/shared/dist/ast/astChunker.js
|
|
6749
7111
|
var MAX_AST_PARSE_BYTES = 2 * 1024 * 1024;
|
|
@@ -6921,6 +7283,7 @@ var BUILT_IN_IGNORE_DIR_SET = new Set(BUILT_IN_IGNORE_DIRS);
|
|
|
6921
7283
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
6922
7284
|
|
|
6923
7285
|
// packages/shared/dist/index.js
|
|
7286
|
+
init_secretPatterns();
|
|
6924
7287
|
init_hookTimeouts();
|
|
6925
7288
|
|
|
6926
7289
|
// packages/shared/dist/jitDeliveryAck.js
|
|
@@ -6936,6 +7299,7 @@ init_settingsIo();
|
|
|
6936
7299
|
init_repositoryFingerprint();
|
|
6937
7300
|
init_projectIdentityFile();
|
|
6938
7301
|
init_repositoryRoot();
|
|
7302
|
+
init_protectedPaths();
|
|
6939
7303
|
|
|
6940
7304
|
// packages/shared/dist/readiness.js
|
|
6941
7305
|
var READINESS_SCHEMA_VERSION = 1;
|
|
@@ -7041,9 +7405,9 @@ init_hookRuntime();
|
|
|
7041
7405
|
import { createHash, randomUUID } from "node:crypto";
|
|
7042
7406
|
import { execFile as nodeExecFile } from "node:child_process";
|
|
7043
7407
|
import fs2 from "node:fs";
|
|
7044
|
-
import { open, rename, readFile, mkdir, lstat, chmod, writeFile, unlink, rmdir } from "node:fs/promises";
|
|
7045
|
-
import { homedir } from "node:os";
|
|
7046
|
-
import { dirname as
|
|
7408
|
+
import { open, rename, readFile as readFile3, mkdir, lstat as lstat3, chmod, writeFile, unlink, rmdir } from "node:fs/promises";
|
|
7409
|
+
import { homedir as homedir2 } from "node:os";
|
|
7410
|
+
import { dirname as dirname4, join as join5, win32 as win322, posix } from "node:path";
|
|
7047
7411
|
import { setTimeout as delay } from "node:timers/promises";
|
|
7048
7412
|
var lockfileKey = /* @__PURE__ */ Symbol.for("mnemonik.proper-lockfile");
|
|
7049
7413
|
function sharedLockfile() {
|
|
@@ -7051,7 +7415,7 @@ function sharedLockfile() {
|
|
|
7051
7415
|
return shared[lockfileKey] ??= Promise.resolve().then(() => __toESM(require_proper_lockfile(), 1)).then((module2) => module2.default);
|
|
7052
7416
|
}
|
|
7053
7417
|
var codeIs = (error, code) => error.code === code;
|
|
7054
|
-
function stateDirectory(platform = process.platform, env = process.env, home =
|
|
7418
|
+
function stateDirectory(platform = process.platform, env = process.env, home = homedir2()) {
|
|
7055
7419
|
if (env.MNEMONIK_STATE_DIR)
|
|
7056
7420
|
return env.MNEMONIK_STATE_DIR;
|
|
7057
7421
|
if (platform === "win32")
|
|
@@ -7062,9 +7426,9 @@ function stateDirectory(platform = process.platform, env = process.env, home = h
|
|
|
7062
7426
|
}
|
|
7063
7427
|
async function readBytes(path) {
|
|
7064
7428
|
try {
|
|
7065
|
-
if (!(await
|
|
7429
|
+
if (!(await lstat3(path)).isFile())
|
|
7066
7430
|
throw new Error("setup_requires_regular_file");
|
|
7067
|
-
return await
|
|
7431
|
+
return await readFile3(path);
|
|
7068
7432
|
} catch (error) {
|
|
7069
7433
|
if (codeIs(error, "ENOENT"))
|
|
7070
7434
|
return null;
|
|
@@ -7085,9 +7449,9 @@ var windowsCurrentAccount = windowsCurrentAccountSync;
|
|
|
7085
7449
|
async function windowsCurrentUserAcl(path, directory = false, options = {}, created = false) {
|
|
7086
7450
|
const username = options.username ?? `*${windowsCurrentAccount().sid}`;
|
|
7087
7451
|
const grant = `${username}:${directory ? "(OI)(CI)F" : "F"}`;
|
|
7088
|
-
const
|
|
7089
|
-
await new Promise((
|
|
7090
|
-
|
|
7452
|
+
const execFile3 = options.execFile ?? nodeExecFile;
|
|
7453
|
+
await new Promise((resolve3, reject) => {
|
|
7454
|
+
execFile3("icacls.exe", [
|
|
7091
7455
|
path,
|
|
7092
7456
|
"/inheritance:r",
|
|
7093
7457
|
"/grant:r",
|
|
@@ -7097,7 +7461,7 @@ async function windowsCurrentUserAcl(path, directory = false, options = {}, crea
|
|
|
7097
7461
|
if (error)
|
|
7098
7462
|
reject(error);
|
|
7099
7463
|
else
|
|
7100
|
-
|
|
7464
|
+
resolve3();
|
|
7101
7465
|
});
|
|
7102
7466
|
});
|
|
7103
7467
|
}
|
|
@@ -7126,14 +7490,14 @@ async function atomicWrite(path, bytes, fault, assertOwned) {
|
|
|
7126
7490
|
}
|
|
7127
7491
|
await assertOwned?.();
|
|
7128
7492
|
await rename(temp, path);
|
|
7129
|
-
await syncDirectory(
|
|
7493
|
+
await syncDirectory(dirname4(path));
|
|
7130
7494
|
return permissionStatus;
|
|
7131
7495
|
}
|
|
7132
7496
|
async function withLock(path, waitMs, work) {
|
|
7133
7497
|
const lockfile = await sharedLockfile();
|
|
7134
|
-
await mkdir(
|
|
7498
|
+
await mkdir(dirname4(path), { recursive: true, mode: 448 });
|
|
7135
7499
|
const generation = randomUUID();
|
|
7136
|
-
const owner =
|
|
7500
|
+
const owner = join5(`${path}.lock`, "owner");
|
|
7137
7501
|
let compromised = false;
|
|
7138
7502
|
let acquired = false;
|
|
7139
7503
|
const assertOwned = async () => {
|
|
@@ -7148,14 +7512,14 @@ async function withLock(path, waitMs, work) {
|
|
|
7148
7512
|
void mkdir(dir).then(() => writeFile(owner, generation, { mode: 384, flag: "wx" })).then(() => callback(), callback);
|
|
7149
7513
|
},
|
|
7150
7514
|
rmdir: (dir, callback) => {
|
|
7151
|
-
void unlink(
|
|
7515
|
+
void unlink(join5(dir, "owner")).catch((error) => {
|
|
7152
7516
|
if (!codeIs(error, "ENOENT"))
|
|
7153
7517
|
throw error;
|
|
7154
7518
|
}).then(() => rmdir(dir)).then(() => callback(), callback);
|
|
7155
7519
|
},
|
|
7156
7520
|
rmdirSync: (dir) => {
|
|
7157
7521
|
try {
|
|
7158
|
-
fs2.unlinkSync(
|
|
7522
|
+
fs2.unlinkSync(join5(dir, "owner"));
|
|
7159
7523
|
} catch (error) {
|
|
7160
7524
|
if (!codeIs(error, "ENOENT"))
|
|
7161
7525
|
throw error;
|
|
@@ -7201,15 +7565,15 @@ async function withLock(path, waitMs, work) {
|
|
|
7201
7565
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
7202
7566
|
import { realpathSync } from "node:fs";
|
|
7203
7567
|
import { stat as nodeStat, utimes } from "node:fs/promises";
|
|
7204
|
-
import { homedir as
|
|
7205
|
-
import { join as
|
|
7568
|
+
import { homedir as homedir3 } from "node:os";
|
|
7569
|
+
import { join as join6 } from "node:path";
|
|
7206
7570
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7207
7571
|
var DAY_MS = 864e5;
|
|
7208
|
-
var statePath = (stateDir) =>
|
|
7572
|
+
var statePath = (stateDir) => join6(stateDir, "automatic-update.json");
|
|
7209
7573
|
function cliLauncherPath(options = {}) {
|
|
7210
7574
|
const platform = options.platform ?? process.platform;
|
|
7211
|
-
const home = options.home ??
|
|
7212
|
-
return platform === "win32" ?
|
|
7575
|
+
const home = options.home ?? homedir3();
|
|
7576
|
+
return platform === "win32" ? join6(options.env?.LOCALAPPDATA || join6(home, "AppData", "Local"), "Mnemonik", "bin", "mnemonik.cmd") : join6(home, ".local", "bin", "mnemonik");
|
|
7213
7577
|
}
|
|
7214
7578
|
async function readState(path) {
|
|
7215
7579
|
const bytes = await readBytes(path);
|
|
@@ -7317,6 +7681,8 @@ import {
|
|
|
7317
7681
|
connectedProjectsMessage,
|
|
7318
7682
|
createRealProjectRuntime,
|
|
7319
7683
|
ensureProjectRoot,
|
|
7684
|
+
insideProjectLine,
|
|
7685
|
+
projectFolderFor,
|
|
7320
7686
|
projectLimitMessage
|
|
7321
7687
|
} from "../project.js";
|
|
7322
7688
|
import { consentDraft, runScannerBoundaryPicker } from "./picker.js";
|
|
@@ -7324,10 +7690,10 @@ var scannerStateBytes = (state) => Buffer.from(`${JSON.stringify(state, null, 2)
|
|
|
7324
7690
|
`);
|
|
7325
7691
|
var SCANNER_APPROVAL_WAIT = "Waiting for approval in your browser, up to 10 minutes.";
|
|
7326
7692
|
async function updateScannerRoots(options) {
|
|
7327
|
-
await mkdir2(
|
|
7328
|
-
return withLock(
|
|
7329
|
-
const path =
|
|
7330
|
-
const state = JSON.parse(await
|
|
7693
|
+
await mkdir2(join7(options.stateDir, "scanner"), { recursive: true, mode: 448 });
|
|
7694
|
+
return withLock(join7(options.stateDir, "scanner/enable"), 5e3, async () => {
|
|
7695
|
+
const path = join7(options.stateDir, "scanner/state.json");
|
|
7696
|
+
const state = JSON.parse(await readFile4(path, "utf8"));
|
|
7331
7697
|
const response = await (options.fetch ?? fetch)(
|
|
7332
7698
|
`${apiOrigin()}/api/v1/scanner-consent/current`,
|
|
7333
7699
|
{
|
|
@@ -7392,7 +7758,10 @@ async function enableScanner(options) {
|
|
|
7392
7758
|
const executor = await prepared.projectExecutor();
|
|
7393
7759
|
const connected = [];
|
|
7394
7760
|
let limit;
|
|
7395
|
-
|
|
7761
|
+
const projectFolders = /* @__PURE__ */ new Set();
|
|
7762
|
+
for (const folder of prepared.roots)
|
|
7763
|
+
projectFolders.add(await projectFolderFor(folder, executor));
|
|
7764
|
+
for (const root of projectFolders) {
|
|
7396
7765
|
const result = await ensureProjectRoot(root, executor);
|
|
7397
7766
|
if (result.status === "done") connected.push(root);
|
|
7398
7767
|
else {
|
|
@@ -7415,13 +7784,13 @@ async function enableScanner(options) {
|
|
|
7415
7784
|
});
|
|
7416
7785
|
}
|
|
7417
7786
|
async function prepareScanner(options, work) {
|
|
7418
|
-
await mkdir2(
|
|
7419
|
-
return withLock(
|
|
7420
|
-
const path =
|
|
7787
|
+
await mkdir2(join7(options.stateDir, "scanner"), { recursive: true, mode: 448 });
|
|
7788
|
+
return withLock(join7(options.stateDir, "scanner/enable"), 5e3, async () => {
|
|
7789
|
+
const path = join7(options.stateDir, "scanner/state.json");
|
|
7421
7790
|
if (await resumeAbandonedPause(options))
|
|
7422
7791
|
if (options.nonInteractive) options.output.error(ABANDONED_PAUSE_RESUMED);
|
|
7423
7792
|
else options.output.line(ABANDONED_PAUSE_RESUMED);
|
|
7424
|
-
const saved = JSON.parse(await
|
|
7793
|
+
const saved = JSON.parse(await readFile4(path, "utf8").catch(() => "null"));
|
|
7425
7794
|
const credentials = options.credentials ?? createCliCredentials({ stateDir: options.stateDir });
|
|
7426
7795
|
const authorize = options.authorize ?? (async (selection, installation) => {
|
|
7427
7796
|
const auth = createCliAuth({
|
|
@@ -7500,8 +7869,22 @@ async function prepareScanner(options, work) {
|
|
|
7500
7869
|
if ("status" in picked) throw new Error("consent_declined");
|
|
7501
7870
|
if (!picked.roots.length && !picked.candidates?.length)
|
|
7502
7871
|
throw new Error("scan_roots_required");
|
|
7503
|
-
picked.roots = await Promise.all(picked.roots.map((root) =>
|
|
7504
|
-
|
|
7872
|
+
picked.roots = await Promise.all(picked.roots.map((root) => realpath2(root)));
|
|
7873
|
+
if (options.roots) {
|
|
7874
|
+
const resolver = options.projectExecutor ?? { resolveProjectIdentity };
|
|
7875
|
+
const folders = [];
|
|
7876
|
+
for (const named of picked.roots) {
|
|
7877
|
+
const folder = await projectFolderFor(named, resolver);
|
|
7878
|
+
if (folder !== named) {
|
|
7879
|
+
const line = insideProjectLine(basename2(named), folder);
|
|
7880
|
+
if (options.nonInteractive) options.output.error(line);
|
|
7881
|
+
else options.output.line(line);
|
|
7882
|
+
}
|
|
7883
|
+
if (!folders.includes(folder)) folders.push(folder);
|
|
7884
|
+
}
|
|
7885
|
+
picked.roots = folders;
|
|
7886
|
+
}
|
|
7887
|
+
picked.exclusions = await Promise.all(picked.exclusions.map((root) => realpath2(root)));
|
|
7505
7888
|
for (const root of picked.roots) {
|
|
7506
7889
|
const decision = await evaluateRoot(
|
|
7507
7890
|
{ kind: "absent", root, repository: await repositoryAt(root), nested: [] },
|
|
@@ -7757,7 +8140,7 @@ async function restoreScannerInstall(journal, options) {
|
|
|
7757
8140
|
if (!before?.installed) await service.restore("scanner", record.before);
|
|
7758
8141
|
}
|
|
7759
8142
|
if (record?.started)
|
|
7760
|
-
await observeScannerState(journal,
|
|
8143
|
+
await observeScannerState(journal, join7(options.stateDir, "scanner/state.json"));
|
|
7761
8144
|
for (const target of [...journal.data.targets].reverse().filter((t) => t.group?.startsWith("scanner:")))
|
|
7762
8145
|
await journal.restore(target);
|
|
7763
8146
|
if (record?.started && before?.installed) await service.restore("scanner", record.before);
|