@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.
- package/dist/auth/credentials.js +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/installSession.js +1 -1
- package/dist/auth/status.js +1 -1
- package/dist/authorizationWords.js +1 -1
- package/dist/diagnostics.js +1 -1
- package/dist/digests.json +56 -56
- package/dist/humanReason.d.ts +7 -0
- package/dist/humanReason.d.ts.map +1 -1
- package/dist/humanReason.js +12 -1
- package/dist/humanReason.js.map +1 -1
- package/dist/identity/migrate.js +1 -1
- package/dist/install/hosts.js +1 -1
- package/dist/install/journal.js +1 -1
- package/dist/install/journey.js +1 -1
- package/dist/install/ownership.js +1 -1
- package/dist/install/transaction.js +1 -1
- package/dist/install/ui.js +1 -1
- package/dist/installSession.js +1 -1
- package/dist/installation.js +1 -1
- package/dist/launcher.js +1 -1
- package/dist/preflight.js +1 -1
- package/dist/project/eligibility.js +1 -1
- package/dist/project/records.js +1 -1
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +3 -1
- package/dist/project.js.map +1 -1
- package/dist/router.d.ts +0 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +14 -7
- 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 +1 -1
- package/dist/runtime/selfUpdate.js +1 -1
- package/dist/runtime/signers.js +8 -9
- package/dist/runtime/store.d.ts +1 -1
- package/dist/runtime/store.d.ts.map +1 -1
- package/dist/runtime/store.js +26 -5
- package/dist/runtime/store.js.map +1 -1
- package/dist/runtime/updateCheck.js +1 -1
- package/dist/sbom.json +21 -21
- package/dist/scanner/control.js +1 -1
- package/dist/scanner/data.js +1 -1
- package/dist/scanner/discover.js +1 -1
- package/dist/scanner/enable.d.ts.map +1 -1
- package/dist/scanner/enable.js +395 -49
- package/dist/scanner/enable.js.map +1 -1
- package/dist/scanner/picker.js +1 -1
- package/dist/scanner/service.js +1 -1
- package/dist/scanner/update.js +1 -1
- package/dist/scanner-release.json +18 -18
- package/dist/status.js +1 -1
- package/dist/vendor/local-setup.js +1 -1
- 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;
|
|
@@ -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
|
|
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 =
|
|
1599
|
-
function
|
|
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((
|
|
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
|
-
|
|
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
|
|
2686
|
-
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";
|
|
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({
|
|
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((
|
|
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
|
-
|
|
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((
|
|
4893
|
+
return new Promise((resolve3, reject) => {
|
|
4563
4894
|
Module["instantiateWasm"](info22, (mod, inst) => {
|
|
4564
|
-
|
|
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((
|
|
5898
|
-
readyPromiseResolve =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
7429
|
+
if (!(await lstat3(path)).isFile())
|
|
7099
7430
|
throw new Error("setup_requires_regular_file");
|
|
7100
|
-
return await
|
|
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
|
|
7122
|
-
await new Promise((
|
|
7123
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
7498
|
+
await mkdir(dirname4(path), { recursive: true, mode: 448 });
|
|
7168
7499
|
const generation = randomUUID();
|
|
7169
|
-
const 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(
|
|
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(
|
|
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
|
|
7238
|
-
import { join as
|
|
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) =>
|
|
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 ??
|
|
7245
|
-
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");
|
|
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(
|
|
7362
|
-
return withLock(
|
|
7363
|
-
const path =
|
|
7364
|
-
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"));
|
|
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(
|
|
7456
|
-
return withLock(
|
|
7457
|
-
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");
|
|
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
|
|
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) =>
|
|
7541
|
-
|
|
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,
|
|
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);
|