@mnemonik/cli 7.140.2 → 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.
Files changed (58) hide show
  1. package/dist/auth/credentials.js +1 -1
  2. package/dist/auth/index.js +1 -1
  3. package/dist/auth/installSession.js +1 -1
  4. package/dist/auth/status.js +1 -1
  5. package/dist/authorizationWords.js +1 -1
  6. package/dist/diagnostics.js +1 -1
  7. package/dist/digests.json +56 -56
  8. package/dist/humanReason.d.ts +7 -0
  9. package/dist/humanReason.d.ts.map +1 -1
  10. package/dist/humanReason.js +12 -1
  11. package/dist/humanReason.js.map +1 -1
  12. package/dist/identity/migrate.js +1 -1
  13. package/dist/install/hosts.js +1 -1
  14. package/dist/install/journal.js +1 -1
  15. package/dist/install/journey.js +1 -1
  16. package/dist/install/ownership.js +1 -1
  17. package/dist/install/transaction.js +1 -1
  18. package/dist/install/ui.js +1 -1
  19. package/dist/installSession.js +1 -1
  20. package/dist/installation.js +1 -1
  21. package/dist/launcher.js +1 -1
  22. package/dist/preflight.js +1 -1
  23. package/dist/project/eligibility.js +1 -1
  24. package/dist/project/records.js +1 -1
  25. package/dist/project.d.ts +1 -0
  26. package/dist/project.d.ts.map +1 -1
  27. package/dist/project.js +3 -1
  28. package/dist/project.js.map +1 -1
  29. package/dist/router.d.ts +0 -1
  30. package/dist/router.d.ts.map +1 -1
  31. package/dist/router.js +14 -7
  32. package/dist/router.js.map +1 -1
  33. package/dist/runtime/bootstrap.d.ts +22 -1
  34. package/dist/runtime/bootstrap.d.ts.map +1 -1
  35. package/dist/runtime/bootstrap.js +61 -8
  36. package/dist/runtime/bootstrap.js.map +1 -1
  37. package/dist/runtime/releaseSource.js +1 -1
  38. package/dist/runtime/selfUpdate.js +1 -1
  39. package/dist/runtime/signers.js +8 -9
  40. package/dist/runtime/store.d.ts +1 -1
  41. package/dist/runtime/store.d.ts.map +1 -1
  42. package/dist/runtime/store.js +26 -5
  43. package/dist/runtime/store.js.map +1 -1
  44. package/dist/runtime/updateCheck.js +1 -1
  45. package/dist/sbom.json +21 -21
  46. package/dist/scanner/control.js +1 -1
  47. package/dist/scanner/data.js +1 -1
  48. package/dist/scanner/discover.js +1 -1
  49. package/dist/scanner/enable.d.ts.map +1 -1
  50. package/dist/scanner/enable.js +395 -49
  51. package/dist/scanner/enable.js.map +1 -1
  52. package/dist/scanner/picker.js +1 -1
  53. package/dist/scanner/service.js +1 -1
  54. package/dist/scanner/update.js +1 -1
  55. package/dist/scanner-release.json +18 -18
  56. package/dist/status.js +1 -1
  57. package/dist/vendor/local-setup.js +1 -1
  58. package/package.json +31 -31
@@ -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 basename2 = shortcut ? basenameOf(path) : path;
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 ? basename2 : path
738
+ shortcut && rule._basenameOnly ? basename3 : path
739
739
  )) {
740
740
  ignored = !negative;
741
741
  unignored = negative;
@@ -900,9 +900,98 @@ var init_protectedPaths = __esm({
900
900
  });
901
901
 
902
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;
903
983
  var init_projectIdentityFile = __esm({
904
984
  "packages/shared/dist/projectIdentityFile.js"() {
905
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"]);
906
995
  }
907
996
  });
908
997
 
@@ -914,7 +1003,7 @@ var init_hookTimeouts = __esm({
914
1003
  });
915
1004
 
916
1005
  // packages/shared/dist/runtimeSigners.js
917
- import { basename, dirname as dirname2, join as join2, resolve, sep, win32 } from "node:path";
1006
+ import { basename, dirname as dirname2, join as join3, resolve, sep, win32 } from "node:path";
918
1007
  import { execFile, execFileSync } from "node:child_process";
919
1008
  function windowsCommand(file) {
920
1009
  const root = process.env.SystemRoot;
@@ -1004,10 +1093,252 @@ var init_repositoryFingerprint = __esm({
1004
1093
  });
1005
1094
 
1006
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;
1007
1327
  var init_repositoryRoot = __esm({
1008
1328
  "packages/shared/dist/repositoryRoot.js"() {
1009
1329
  "use strict";
1010
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
+ ];
1011
1342
  }
1012
1343
  });
1013
1344
 
@@ -1595,8 +1926,8 @@ var require_graceful_fs = __commonJS({
1595
1926
  fs4.createReadStream = createReadStream;
1596
1927
  fs4.createWriteStream = createWriteStream;
1597
1928
  var fs$readFile = fs4.readFile;
1598
- fs4.readFile = readFile3;
1599
- function readFile3(path, options, cb) {
1929
+ fs4.readFile = readFile5;
1930
+ function readFile5(path, options, cb) {
1600
1931
  if (typeof options === "function")
1601
1932
  cb = options, options = null;
1602
1933
  return go$readFile(path, options, cb);
@@ -2602,12 +2933,12 @@ var require_adapter = __commonJS({
2602
2933
  return newFs;
2603
2934
  }
2604
2935
  function toPromise(method) {
2605
- return (...args2) => new Promise((resolve2, reject) => {
2936
+ return (...args2) => new Promise((resolve3, reject) => {
2606
2937
  args2.push((err2, result) => {
2607
2938
  if (err2) {
2608
2939
  reject(err2);
2609
2940
  } else {
2610
- resolve2(result);
2941
+ resolve3(result);
2611
2942
  }
2612
2943
  });
2613
2944
  method(...args2);
@@ -2682,12 +3013,12 @@ var require_proper_lockfile = __commonJS({
2682
3013
 
2683
3014
  // packages/cli/src/scanner/enable.ts
2684
3015
  import { revokeInstallComponent } from "../install/transaction.js";
2685
- import { mkdir as mkdir2, readFile as readFile2, realpath } from "node:fs/promises";
2686
- import { join as join5 } from "node:path";
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";
2687
3018
  import { isDeepStrictEqual } from "node:util";
2688
3019
 
2689
3020
  // packages/shared/dist/instructions.js
2690
- var INSTRUCTIONS_CONTENT = `Mnemonik provides persistent project memory: decisions, rationale, tasks, and policies across sessions. If no block begins "PROJECT_CONTEXT schemaVersion=", session_bootstrap({ cwd }) loads project context when cwd is the real absolute path of the project root; a placeholder or relative path fails. 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.
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.
2691
3022
 
2692
3023
  What I learn about you belongs in Companion; what I learn about this project belongs here.
2693
3024
 
@@ -4357,13 +4688,13 @@ async function Module2(moduleArg = {}) {
4357
4688
  }
4358
4689
  readAsync = /* @__PURE__ */ __name(async (url) => {
4359
4690
  if (isFileURI(url)) {
4360
- return new Promise((resolve2, reject) => {
4691
+ return new Promise((resolve3, reject) => {
4361
4692
  var xhr = new XMLHttpRequest();
4362
4693
  xhr.open("GET", url, true);
4363
4694
  xhr.responseType = "arraybuffer";
4364
4695
  xhr.onload = () => {
4365
4696
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
4366
- resolve2(xhr.response);
4697
+ resolve3(xhr.response);
4367
4698
  return;
4368
4699
  }
4369
4700
  reject(xhr.status);
@@ -4559,9 +4890,9 @@ async function Module2(moduleArg = {}) {
4559
4890
  __name(receiveInstantiationResult, "receiveInstantiationResult");
4560
4891
  var info22 = getWasmImports();
4561
4892
  if (Module["instantiateWasm"]) {
4562
- return new Promise((resolve2, reject) => {
4893
+ return new Promise((resolve3, reject) => {
4563
4894
  Module["instantiateWasm"](info22, (mod, inst) => {
4564
- resolve2(receiveInstance(mod, inst));
4895
+ resolve3(receiveInstance(mod, inst));
4565
4896
  });
4566
4897
  });
4567
4898
  }
@@ -5894,8 +6225,8 @@ async function Module2(moduleArg = {}) {
5894
6225
  if (runtimeInitialized) {
5895
6226
  moduleRtn = Module;
5896
6227
  } else {
5897
- moduleRtn = new Promise((resolve2, reject) => {
5898
- readyPromiseResolve = resolve2;
6228
+ moduleRtn = new Promise((resolve3, reject) => {
6229
+ readyPromiseResolve = resolve3;
5899
6230
  readyPromiseReject = reject;
5900
6231
  });
5901
6232
  }
@@ -6772,9 +7103,9 @@ var Query = class {
6772
7103
  };
6773
7104
 
6774
7105
  // packages/shared/dist/ast/grammars.js
6775
- import { dirname, extname, join } from "node:path";
7106
+ import { dirname, extname, join as join2 } from "node:path";
6776
7107
  import { fileURLToPath } from "node:url";
6777
- var WASM_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm");
7108
+ var WASM_DIR = join2(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm");
6778
7109
 
6779
7110
  // packages/shared/dist/ast/astChunker.js
6780
7111
  var MAX_AST_PARSE_BYTES = 2 * 1024 * 1024;
@@ -7074,9 +7405,9 @@ init_hookRuntime();
7074
7405
  import { createHash, randomUUID } from "node:crypto";
7075
7406
  import { execFile as nodeExecFile } from "node:child_process";
7076
7407
  import fs2 from "node:fs";
7077
- import { open, rename, readFile, mkdir, lstat, chmod, writeFile, unlink, rmdir } from "node:fs/promises";
7078
- import { homedir } from "node:os";
7079
- import { dirname as dirname3, join as join3, win32 as win322, posix } from "node:path";
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";
7080
7411
  import { setTimeout as delay } from "node:timers/promises";
7081
7412
  var lockfileKey = /* @__PURE__ */ Symbol.for("mnemonik.proper-lockfile");
7082
7413
  function sharedLockfile() {
@@ -7084,7 +7415,7 @@ function sharedLockfile() {
7084
7415
  return shared[lockfileKey] ??= Promise.resolve().then(() => __toESM(require_proper_lockfile(), 1)).then((module2) => module2.default);
7085
7416
  }
7086
7417
  var codeIs = (error, code) => error.code === code;
7087
- function stateDirectory(platform = process.platform, env = process.env, home = homedir()) {
7418
+ function stateDirectory(platform = process.platform, env = process.env, home = homedir2()) {
7088
7419
  if (env.MNEMONIK_STATE_DIR)
7089
7420
  return env.MNEMONIK_STATE_DIR;
7090
7421
  if (platform === "win32")
@@ -7095,9 +7426,9 @@ function stateDirectory(platform = process.platform, env = process.env, home = h
7095
7426
  }
7096
7427
  async function readBytes(path) {
7097
7428
  try {
7098
- if (!(await lstat(path)).isFile())
7429
+ if (!(await lstat3(path)).isFile())
7099
7430
  throw new Error("setup_requires_regular_file");
7100
- return await readFile(path);
7431
+ return await readFile3(path);
7101
7432
  } catch (error) {
7102
7433
  if (codeIs(error, "ENOENT"))
7103
7434
  return null;
@@ -7118,9 +7449,9 @@ var windowsCurrentAccount = windowsCurrentAccountSync;
7118
7449
  async function windowsCurrentUserAcl(path, directory = false, options = {}, created = false) {
7119
7450
  const username = options.username ?? `*${windowsCurrentAccount().sid}`;
7120
7451
  const grant = `${username}:${directory ? "(OI)(CI)F" : "F"}`;
7121
- const execFile2 = options.execFile ?? nodeExecFile;
7122
- await new Promise((resolve2, reject) => {
7123
- execFile2("icacls.exe", [
7452
+ const execFile3 = options.execFile ?? nodeExecFile;
7453
+ await new Promise((resolve3, reject) => {
7454
+ execFile3("icacls.exe", [
7124
7455
  path,
7125
7456
  "/inheritance:r",
7126
7457
  "/grant:r",
@@ -7130,7 +7461,7 @@ async function windowsCurrentUserAcl(path, directory = false, options = {}, crea
7130
7461
  if (error)
7131
7462
  reject(error);
7132
7463
  else
7133
- resolve2();
7464
+ resolve3();
7134
7465
  });
7135
7466
  });
7136
7467
  }
@@ -7159,14 +7490,14 @@ async function atomicWrite(path, bytes, fault, assertOwned) {
7159
7490
  }
7160
7491
  await assertOwned?.();
7161
7492
  await rename(temp, path);
7162
- await syncDirectory(dirname3(path));
7493
+ await syncDirectory(dirname4(path));
7163
7494
  return permissionStatus;
7164
7495
  }
7165
7496
  async function withLock(path, waitMs, work) {
7166
7497
  const lockfile = await sharedLockfile();
7167
- await mkdir(dirname3(path), { recursive: true, mode: 448 });
7498
+ await mkdir(dirname4(path), { recursive: true, mode: 448 });
7168
7499
  const generation = randomUUID();
7169
- const owner = join3(`${path}.lock`, "owner");
7500
+ const owner = join5(`${path}.lock`, "owner");
7170
7501
  let compromised = false;
7171
7502
  let acquired = false;
7172
7503
  const assertOwned = async () => {
@@ -7181,14 +7512,14 @@ async function withLock(path, waitMs, work) {
7181
7512
  void mkdir(dir).then(() => writeFile(owner, generation, { mode: 384, flag: "wx" })).then(() => callback(), callback);
7182
7513
  },
7183
7514
  rmdir: (dir, callback) => {
7184
- void unlink(join3(dir, "owner")).catch((error) => {
7515
+ void unlink(join5(dir, "owner")).catch((error) => {
7185
7516
  if (!codeIs(error, "ENOENT"))
7186
7517
  throw error;
7187
7518
  }).then(() => rmdir(dir)).then(() => callback(), callback);
7188
7519
  },
7189
7520
  rmdirSync: (dir) => {
7190
7521
  try {
7191
- fs2.unlinkSync(join3(dir, "owner"));
7522
+ fs2.unlinkSync(join5(dir, "owner"));
7192
7523
  } catch (error) {
7193
7524
  if (!codeIs(error, "ENOENT"))
7194
7525
  throw error;
@@ -7234,15 +7565,15 @@ async function withLock(path, waitMs, work) {
7234
7565
  import { spawn as nodeSpawn } from "node:child_process";
7235
7566
  import { realpathSync } from "node:fs";
7236
7567
  import { stat as nodeStat, utimes } from "node:fs/promises";
7237
- import { homedir as homedir2 } from "node:os";
7238
- import { join as join4 } from "node:path";
7568
+ import { homedir as homedir3 } from "node:os";
7569
+ import { join as join6 } from "node:path";
7239
7570
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7240
7571
  var DAY_MS = 864e5;
7241
- var statePath = (stateDir) => join4(stateDir, "automatic-update.json");
7572
+ var statePath = (stateDir) => join6(stateDir, "automatic-update.json");
7242
7573
  function cliLauncherPath(options = {}) {
7243
7574
  const platform = options.platform ?? process.platform;
7244
- const home = options.home ?? homedir2();
7245
- return platform === "win32" ? join4(options.env?.LOCALAPPDATA || join4(home, "AppData", "Local"), "Mnemonik", "bin", "mnemonik.cmd") : join4(home, ".local", "bin", "mnemonik");
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");
7246
7577
  }
7247
7578
  async function readState(path) {
7248
7579
  const bytes = await readBytes(path);
@@ -7350,6 +7681,7 @@ import {
7350
7681
  connectedProjectsMessage,
7351
7682
  createRealProjectRuntime,
7352
7683
  ensureProjectRoot,
7684
+ insideProjectLine,
7353
7685
  projectFolderFor,
7354
7686
  projectLimitMessage
7355
7687
  } from "../project.js";
@@ -7358,10 +7690,10 @@ var scannerStateBytes = (state) => Buffer.from(`${JSON.stringify(state, null, 2)
7358
7690
  `);
7359
7691
  var SCANNER_APPROVAL_WAIT = "Waiting for approval in your browser, up to 10 minutes.";
7360
7692
  async function updateScannerRoots(options) {
7361
- await mkdir2(join5(options.stateDir, "scanner"), { recursive: true, mode: 448 });
7362
- return withLock(join5(options.stateDir, "scanner/enable"), 5e3, async () => {
7363
- const path = join5(options.stateDir, "scanner/state.json");
7364
- const state = JSON.parse(await readFile2(path, "utf8"));
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"));
7365
7697
  const response = await (options.fetch ?? fetch)(
7366
7698
  `${apiOrigin()}/api/v1/scanner-consent/current`,
7367
7699
  {
@@ -7452,13 +7784,13 @@ async function enableScanner(options) {
7452
7784
  });
7453
7785
  }
7454
7786
  async function prepareScanner(options, work) {
7455
- await mkdir2(join5(options.stateDir, "scanner"), { recursive: true, mode: 448 });
7456
- return withLock(join5(options.stateDir, "scanner/enable"), 5e3, async () => {
7457
- const path = join5(options.stateDir, "scanner/state.json");
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");
7458
7790
  if (await resumeAbandonedPause(options))
7459
7791
  if (options.nonInteractive) options.output.error(ABANDONED_PAUSE_RESUMED);
7460
7792
  else options.output.line(ABANDONED_PAUSE_RESUMED);
7461
- const saved = JSON.parse(await readFile2(path, "utf8").catch(() => "null"));
7793
+ const saved = JSON.parse(await readFile4(path, "utf8").catch(() => "null"));
7462
7794
  const credentials = options.credentials ?? createCliCredentials({ stateDir: options.stateDir });
7463
7795
  const authorize = options.authorize ?? (async (selection, installation) => {
7464
7796
  const auth = createCliAuth({
@@ -7537,8 +7869,22 @@ async function prepareScanner(options, work) {
7537
7869
  if ("status" in picked) throw new Error("consent_declined");
7538
7870
  if (!picked.roots.length && !picked.candidates?.length)
7539
7871
  throw new Error("scan_roots_required");
7540
- picked.roots = await Promise.all(picked.roots.map((root) => realpath(root)));
7541
- picked.exclusions = await Promise.all(picked.exclusions.map((root) => realpath(root)));
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)));
7542
7888
  for (const root of picked.roots) {
7543
7889
  const decision = await evaluateRoot(
7544
7890
  { kind: "absent", root, repository: await repositoryAt(root), nested: [] },
@@ -7794,7 +8140,7 @@ async function restoreScannerInstall(journal, options) {
7794
8140
  if (!before?.installed) await service.restore("scanner", record.before);
7795
8141
  }
7796
8142
  if (record?.started)
7797
- await observeScannerState(journal, join5(options.stateDir, "scanner/state.json"));
8143
+ await observeScannerState(journal, join7(options.stateDir, "scanner/state.json"));
7798
8144
  for (const target of [...journal.data.targets].reverse().filter((t) => t.group?.startsWith("scanner:")))
7799
8145
  await journal.restore(target);
7800
8146
  if (record?.started && before?.installed) await service.restore("scanner", record.before);