@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/router.js
CHANGED
|
@@ -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,102 +1092,8 @@ var init_repositoryFingerprint = __esm({
|
|
|
982
1092
|
}
|
|
983
1093
|
});
|
|
984
1094
|
|
|
985
|
-
// packages/shared/dist/projectIdentityFile.js
|
|
986
|
-
import { lstat, readFile } from "node:fs/promises";
|
|
987
|
-
import { join as join3 } from "node:path";
|
|
988
|
-
function parseIdentityFile(text) {
|
|
989
|
-
let value;
|
|
990
|
-
try {
|
|
991
|
-
value = JSON.parse(text);
|
|
992
|
-
} catch (error) {
|
|
993
|
-
return { kind: "malformed", detail: `unparseable JSON: ${error.message}` };
|
|
994
|
-
}
|
|
995
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
996
|
-
return { kind: "malformed", detail: "identity file must contain a JSON object" };
|
|
997
|
-
}
|
|
998
|
-
const record = value;
|
|
999
|
-
if (record.schemaVersion !== 1) {
|
|
1000
|
-
return { kind: "unknown_version", version: record.schemaVersion };
|
|
1001
|
-
}
|
|
1002
|
-
const unknownKey = Object.keys(record).find((key) => !IDENTITY_KEYS.has(key));
|
|
1003
|
-
if (unknownKey)
|
|
1004
|
-
return { kind: "malformed", detail: `unknown key "${unknownKey}"` };
|
|
1005
|
-
if (!isCanonicalUuid(record.projectId)) {
|
|
1006
|
-
return { kind: "malformed", detail: '"projectId" must be a canonical RFC 4122 UUID string' };
|
|
1007
|
-
}
|
|
1008
|
-
if ("projectName" in record && typeof record.projectName !== "string") {
|
|
1009
|
-
return { kind: "malformed", detail: '"projectName" must be a string when present' };
|
|
1010
|
-
}
|
|
1011
|
-
if ("repositoryFingerprint" in record && (!record.repositoryFingerprint || typeof record.repositoryFingerprint !== "object" || Array.isArray(record.repositoryFingerprint))) {
|
|
1012
|
-
return { kind: "malformed", detail: '"repositoryFingerprint" must be an object when present' };
|
|
1013
|
-
}
|
|
1014
|
-
const fingerprint = record.repositoryFingerprint;
|
|
1015
|
-
const unknownFingerprintKey = fingerprint ? Object.keys(fingerprint).find((key) => !FINGERPRINT_KEYS.has(key)) : void 0;
|
|
1016
|
-
if (unknownFingerprintKey) {
|
|
1017
|
-
return {
|
|
1018
|
-
kind: "malformed",
|
|
1019
|
-
detail: `unknown repositoryFingerprint key "${unknownFingerprintKey}"`
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
if (fingerprint && (fingerprint.algorithmVersion !== 1 || typeof fingerprint.hash !== "string")) {
|
|
1023
|
-
return {
|
|
1024
|
-
kind: "malformed",
|
|
1025
|
-
detail: '"repositoryFingerprint" must contain algorithmVersion 1 and a string hash'
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
const repositoryFingerprint = fingerprint ? { algorithmVersion: 1, hash: fingerprint.hash } : void 0;
|
|
1029
|
-
return {
|
|
1030
|
-
kind: "ok",
|
|
1031
|
-
identity: {
|
|
1032
|
-
schemaVersion: 1,
|
|
1033
|
-
projectId: record.projectId,
|
|
1034
|
-
...record.projectName === void 0 ? {} : { projectName: record.projectName },
|
|
1035
|
-
...repositoryFingerprint ? { repositoryFingerprint } : {}
|
|
1036
|
-
}
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
async function readIdentityFile(dir, options = {}) {
|
|
1040
|
-
const path = join3(dir, ".mnemonik.json");
|
|
1041
|
-
try {
|
|
1042
|
-
const stat = await lstat(path);
|
|
1043
|
-
if (stat.isSymbolicLink())
|
|
1044
|
-
return { kind: "malformed", detail: "symlink" };
|
|
1045
|
-
if (!stat.isFile())
|
|
1046
|
-
return { kind: "malformed", detail: "identity path is not a regular file" };
|
|
1047
|
-
const text = await readFile(path, "utf8");
|
|
1048
|
-
if (options.selectedRoot) {
|
|
1049
|
-
try {
|
|
1050
|
-
const value = JSON.parse(text);
|
|
1051
|
-
if (value && typeof value === "object" && !Array.isArray(value) && !("projectId" in value) && (!("schemaVersion" in value) || value.schemaVersion === 1))
|
|
1052
|
-
return { kind: "absent" };
|
|
1053
|
-
} catch {
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
return parseIdentityFile(text);
|
|
1057
|
-
} catch (error) {
|
|
1058
|
-
if (error.code === "ENOENT")
|
|
1059
|
-
return { kind: "absent" };
|
|
1060
|
-
return { kind: "malformed", detail: `cannot read identity file: ${error.message}` };
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
var CANONICAL_UUID, isCanonicalUuid, IDENTITY_KEYS, FINGERPRINT_KEYS;
|
|
1064
|
-
var init_projectIdentityFile = __esm({
|
|
1065
|
-
"packages/shared/dist/projectIdentityFile.js"() {
|
|
1066
|
-
"use strict";
|
|
1067
|
-
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}$/;
|
|
1068
|
-
isCanonicalUuid = (value) => typeof value === "string" && CANONICAL_UUID.test(value);
|
|
1069
|
-
IDENTITY_KEYS = /* @__PURE__ */ new Set([
|
|
1070
|
-
"schemaVersion",
|
|
1071
|
-
"projectId",
|
|
1072
|
-
"projectName",
|
|
1073
|
-
"repositoryFingerprint"
|
|
1074
|
-
]);
|
|
1075
|
-
FINGERPRINT_KEYS = /* @__PURE__ */ new Set(["algorithmVersion", "hash"]);
|
|
1076
|
-
}
|
|
1077
|
-
});
|
|
1078
|
-
|
|
1079
1095
|
// packages/shared/dist/repositoryRoot.js
|
|
1080
|
-
import { lstat as lstat2, readFile as readFile2 } from "node:fs/promises";
|
|
1096
|
+
import { lstat as lstat2, readFile as readFile2, realpath } from "node:fs/promises";
|
|
1081
1097
|
import { execFile as execFile2 } from "node:child_process";
|
|
1082
1098
|
import { homedir } from "node:os";
|
|
1083
1099
|
import { dirname as dirname3, join as join4, resolve as resolve2 } from "node:path";
|
|
@@ -1128,7 +1144,7 @@ async function confirmedBoundaryAt(path) {
|
|
|
1128
1144
|
async function boundariesBetween(cwd, root) {
|
|
1129
1145
|
const boundaries = [];
|
|
1130
1146
|
let directory = cwd;
|
|
1131
|
-
while (directory
|
|
1147
|
+
while (!samePath(directory, root)) {
|
|
1132
1148
|
const boundary = await confirmedBoundaryAt(directory);
|
|
1133
1149
|
if (boundary)
|
|
1134
1150
|
boundaries.push(boundary);
|
|
@@ -1151,37 +1167,31 @@ async function containingRepository(root) {
|
|
|
1151
1167
|
directory = parent;
|
|
1152
1168
|
}
|
|
1153
1169
|
}
|
|
1154
|
-
async function
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
const gitDir = resolve2(boundary.path, pointer);
|
|
1161
|
-
try {
|
|
1162
|
-
const commonDir = resolve2(gitDir, (await readFile2(join4(gitDir, "commondir"), "utf8")).trim());
|
|
1163
|
-
return dirname3(commonDir);
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
if (error.code === "ENOENT")
|
|
1166
|
-
return boundary.path;
|
|
1167
|
-
throw error;
|
|
1168
|
-
}
|
|
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;
|
|
1169
1176
|
}
|
|
1170
1177
|
async function resolveRepositoryRoot(cwd) {
|
|
1171
|
-
const absoluteCwd =
|
|
1178
|
+
const absoluteCwd = await canonicalPath(cwd);
|
|
1172
1179
|
try {
|
|
1173
1180
|
const { stdout } = await runGit(absoluteCwd, [
|
|
1174
1181
|
"rev-parse",
|
|
1175
1182
|
"--show-toplevel",
|
|
1183
|
+
"--git-dir",
|
|
1176
1184
|
"--git-common-dir"
|
|
1177
1185
|
]);
|
|
1178
|
-
const [rootLine, commonLine, ...extra] = stdout.trim().split(/\r?\n/);
|
|
1179
|
-
if (!rootLine || !commonLine || extra.length) {
|
|
1186
|
+
const [rootLine, gitDirLine, commonLine, ...extra] = stdout.trim().split(/\r?\n/);
|
|
1187
|
+
if (!rootLine || !gitDirLine || !commonLine || extra.length) {
|
|
1180
1188
|
return { kind: "git_unavailable", detail: "git rev-parse returned an unexpected response" };
|
|
1181
1189
|
}
|
|
1182
|
-
const
|
|
1183
|
-
const
|
|
1184
|
-
const
|
|
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);
|
|
1185
1195
|
const nested = await boundariesBetween(absoluteCwd, root);
|
|
1186
1196
|
if (!isLinkedWorktree && await containingRepository(root)) {
|
|
1187
1197
|
const boundary = await boundaryAt(root);
|
|
@@ -1203,14 +1213,41 @@ async function resolveRepositoryRoot(cwd) {
|
|
|
1203
1213
|
return { kind: "git_unavailable", detail: failure.message };
|
|
1204
1214
|
}
|
|
1205
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
|
+
}
|
|
1206
1243
|
async function readPlainIdentity(start2) {
|
|
1207
|
-
const home =
|
|
1244
|
+
const home = await canonicalPath(homedir());
|
|
1208
1245
|
let directory = start2;
|
|
1209
1246
|
while (true) {
|
|
1210
|
-
const result = await readIdentityFile(directory);
|
|
1247
|
+
const result = await readIdentityFile(directory, { configurationOnlyAbsent: true });
|
|
1211
1248
|
if (result.kind !== "absent")
|
|
1212
1249
|
return { root: directory, result };
|
|
1213
|
-
if (directory
|
|
1250
|
+
if (samePath(directory, home))
|
|
1214
1251
|
break;
|
|
1215
1252
|
const parent = dirname3(directory);
|
|
1216
1253
|
if (parent === directory)
|
|
@@ -1219,58 +1256,72 @@ async function readPlainIdentity(start2) {
|
|
|
1219
1256
|
}
|
|
1220
1257
|
return { root: start2, result: { kind: "absent" } };
|
|
1221
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
|
+
}
|
|
1222
1317
|
function withBase(repository, root, nested) {
|
|
1223
1318
|
return { root, repository, nested };
|
|
1224
1319
|
}
|
|
1225
1320
|
async function resolveProjectIdentity(cwd, options = {}) {
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
if (repository.kind === "plain") {
|
|
1229
|
-
const { root, result } = options.selectedRoot ? { root: repository.root, result: await readIdentityFile(repository.root, options) } : await readPlainIdentity(repository.root);
|
|
1230
|
-
const base2 = withBase(repository, root, []);
|
|
1231
|
-
if (result.kind === "ok")
|
|
1232
|
-
return { ...base2, ...result };
|
|
1233
|
-
if (result.kind === "unknown_version")
|
|
1234
|
-
return { ...base2, ...result, path: root };
|
|
1235
|
-
if (result.kind === "malformed")
|
|
1236
|
-
return { ...base2, ...result, path: root };
|
|
1237
|
-
return { ...base2, kind: "absent" };
|
|
1238
|
-
}
|
|
1239
|
-
const ownRoot = repository.isLinkedWorktree ? dirname3(repository.commonDir) : repository.root;
|
|
1240
|
-
const outer = repository.isLinkedWorktree ? void 0 : await containingRepository(repository.root);
|
|
1241
|
-
const own = await readIdentityFile(ownRoot, options);
|
|
1242
|
-
if (!outer || options.selectedRoot || own.kind === "ok") {
|
|
1243
|
-
const base2 = withBase(repository, ownRoot, repository.nested);
|
|
1244
|
-
if (own.kind === "ok")
|
|
1245
|
-
return { ...base2, ...own };
|
|
1246
|
-
if (own.kind === "unknown_version")
|
|
1247
|
-
return { ...base2, ...own, path: ownRoot };
|
|
1248
|
-
if (own.kind === "malformed")
|
|
1249
|
-
return { ...base2, ...own, path: ownRoot };
|
|
1250
|
-
return { ...base2, kind: "absent" };
|
|
1251
|
-
}
|
|
1252
|
-
const nested = repository.nested;
|
|
1253
|
-
const parentRoot = await canonicalBoundaryRoot(outer);
|
|
1254
|
-
const parent = await readIdentityFile(parentRoot);
|
|
1255
|
-
const base = withBase(repository, parentRoot, nested);
|
|
1256
|
-
if (own.kind === "unknown_version")
|
|
1257
|
-
return { ...base, ...own, path: ownRoot };
|
|
1258
|
-
if (own.kind === "malformed")
|
|
1259
|
-
return { ...base, ...own, path: ownRoot };
|
|
1260
|
-
if (parent.kind === "unknown_version")
|
|
1261
|
-
return { ...base, ...parent, path: parentRoot };
|
|
1262
|
-
if (parent.kind === "malformed")
|
|
1263
|
-
return { ...base, ...parent, path: parentRoot };
|
|
1264
|
-
if (!options.allowNestedInherit) {
|
|
1265
|
-
return {
|
|
1266
|
-
...base,
|
|
1267
|
-
kind: "nested",
|
|
1268
|
-
...parent.kind === "ok" ? { parentIdentity: parent.identity } : {}
|
|
1269
|
-
};
|
|
1321
|
+
if (options.selectedRoot || options.namedRoot) {
|
|
1322
|
+
return resolveNamedProjectIdentity(cwd, { selectedRoot: options.selectedRoot });
|
|
1270
1323
|
}
|
|
1271
|
-
|
|
1272
|
-
return { ...base, kind: "ok", identity: parent.identity };
|
|
1273
|
-
return { ...base, kind: "absent" };
|
|
1324
|
+
return resolveNearestProjectIdentity(cwd);
|
|
1274
1325
|
}
|
|
1275
1326
|
var GIT_TIMEOUT_MS, GIT_ENV_KEYS;
|
|
1276
1327
|
var init_repositoryRoot = __esm({
|
|
@@ -1291,6 +1342,23 @@ var init_repositoryRoot = __esm({
|
|
|
1291
1342
|
}
|
|
1292
1343
|
});
|
|
1293
1344
|
|
|
1345
|
+
// packages/shared/dist/hookTrace.js
|
|
1346
|
+
function hookTraceEnabled(env = process.env) {
|
|
1347
|
+
const value = env[HOOK_TRACE_ENV]?.trim().toLowerCase();
|
|
1348
|
+
return !value || !["off", "0", "false", "no", "disabled"].includes(value);
|
|
1349
|
+
}
|
|
1350
|
+
var HOOK_TRACE_MAX_BYTES, HOOK_TRACE_ENV;
|
|
1351
|
+
var init_hookTrace = __esm({
|
|
1352
|
+
"packages/shared/dist/hookTrace.js"() {
|
|
1353
|
+
"use strict";
|
|
1354
|
+
init_protectedPaths();
|
|
1355
|
+
init_runtimeSigners();
|
|
1356
|
+
init_secretPatterns();
|
|
1357
|
+
HOOK_TRACE_MAX_BYTES = 2 * 1024 * 1024;
|
|
1358
|
+
HOOK_TRACE_ENV = "MNEMONIK_HOOK_TRACE";
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1294
1362
|
// packages/shared/dist/runtimeReader.js
|
|
1295
1363
|
var RuntimeError;
|
|
1296
1364
|
var init_runtimeReader = __esm({
|
|
@@ -1362,10 +1430,12 @@ var init_hookRuntime = __esm({
|
|
|
1362
1430
|
init_runtimeSigners();
|
|
1363
1431
|
init_hookTimeouts();
|
|
1364
1432
|
init_repositoryRoot();
|
|
1433
|
+
init_hookTrace();
|
|
1365
1434
|
init_runtimeReader();
|
|
1366
1435
|
init_runtimeSigners();
|
|
1367
1436
|
init_projectSetupHandoff();
|
|
1368
1437
|
init_hookConversation();
|
|
1438
|
+
init_hookTrace();
|
|
1369
1439
|
}
|
|
1370
1440
|
});
|
|
1371
1441
|
|
|
@@ -2953,6 +3023,7 @@ import {
|
|
|
2953
3023
|
humanIdentityState,
|
|
2954
3024
|
INTERRUPTED_INSTALL,
|
|
2955
3025
|
INTERRUPTED_INSTALL_MESSAGE,
|
|
3026
|
+
REGISTRY_FAILURE,
|
|
2956
3027
|
approvalMessage,
|
|
2957
3028
|
knownReason,
|
|
2958
3029
|
SCANNER_APPROVAL_ACTION,
|
|
@@ -2985,7 +3056,7 @@ import {
|
|
|
2985
3056
|
} from "./scanner/service.js";
|
|
2986
3057
|
|
|
2987
3058
|
// packages/shared/dist/instructions.js
|
|
2988
|
-
var INSTRUCTIONS_CONTENT = `Mnemonik provides persistent project memory: decisions, rationale, tasks, and policies across sessions. If no block begins "PROJECT_CONTEXT schemaVersion=", session_bootstrap({
|
|
3059
|
+
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.
|
|
2989
3060
|
|
|
2990
3061
|
What I learn about you belongs in Companion; what I learn about this project belongs here.
|
|
2991
3062
|
|
|
@@ -3022,6 +3093,9 @@ var MCP_INSTRUCTIONS = getMcpInstructions();
|
|
|
3022
3093
|
|
|
3023
3094
|
// packages/shared/dist/codeScanner.js
|
|
3024
3095
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
3096
|
+
init_secretPatterns();
|
|
3097
|
+
init_protectedPaths();
|
|
3098
|
+
init_projectIdentityFile();
|
|
3025
3099
|
|
|
3026
3100
|
// node_modules/web-tree-sitter/web-tree-sitter.js
|
|
3027
3101
|
var __defProp2 = Object.defineProperty;
|
|
@@ -7067,9 +7141,9 @@ var Query = class {
|
|
|
7067
7141
|
};
|
|
7068
7142
|
|
|
7069
7143
|
// packages/shared/dist/ast/grammars.js
|
|
7070
|
-
import { dirname, extname, join } from "node:path";
|
|
7144
|
+
import { dirname, extname, join as join2 } from "node:path";
|
|
7071
7145
|
import { fileURLToPath } from "node:url";
|
|
7072
|
-
var WASM_DIR =
|
|
7146
|
+
var WASM_DIR = join2(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm");
|
|
7073
7147
|
|
|
7074
7148
|
// packages/shared/dist/ast/astChunker.js
|
|
7075
7149
|
var MAX_AST_PARSE_BYTES = 2 * 1024 * 1024;
|
|
@@ -7247,6 +7321,7 @@ var BUILT_IN_IGNORE_DIR_SET = new Set(BUILT_IN_IGNORE_DIRS);
|
|
|
7247
7321
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
7248
7322
|
|
|
7249
7323
|
// packages/shared/dist/index.js
|
|
7324
|
+
init_secretPatterns();
|
|
7250
7325
|
init_hookTimeouts();
|
|
7251
7326
|
|
|
7252
7327
|
// packages/shared/dist/jitDeliveryAck.js
|
|
@@ -7262,6 +7337,7 @@ init_settingsIo();
|
|
|
7262
7337
|
init_repositoryFingerprint();
|
|
7263
7338
|
init_projectIdentityFile();
|
|
7264
7339
|
init_repositoryRoot();
|
|
7340
|
+
init_protectedPaths();
|
|
7265
7341
|
|
|
7266
7342
|
// packages/shared/dist/readiness.js
|
|
7267
7343
|
var READINESS_SCHEMA_VERSION = 1;
|
|
@@ -7689,6 +7765,7 @@ public class MnemonikCredential {
|
|
|
7689
7765
|
}`.replace(/\n\s*/gu, " ");
|
|
7690
7766
|
|
|
7691
7767
|
// packages/cli/src/router.ts
|
|
7768
|
+
init_hookRuntime();
|
|
7692
7769
|
import {
|
|
7693
7770
|
runHosts,
|
|
7694
7771
|
hostSource,
|
|
@@ -7697,9 +7774,15 @@ import {
|
|
|
7697
7774
|
selectOwned
|
|
7698
7775
|
} from "./install/hosts.js";
|
|
7699
7776
|
import { hostOrder, launchHostLabels } from "./install/adapters.js";
|
|
7777
|
+
import {
|
|
7778
|
+
hookActivityLines,
|
|
7779
|
+
hooksLog,
|
|
7780
|
+
invocationLine,
|
|
7781
|
+
tracedHosts
|
|
7782
|
+
} from "./hooksLog.js";
|
|
7700
7783
|
import { readInstallVersions } from "./install/ownership.js";
|
|
7701
7784
|
import { ensureLauncher, removeLauncher, LauncherError } from "./launcher.js";
|
|
7702
|
-
import { readFile as readFile4, realpath } from "node:fs/promises";
|
|
7785
|
+
import { readFile as readFile4, realpath as realpath2 } from "node:fs/promises";
|
|
7703
7786
|
import { createInterface } from "node:readline";
|
|
7704
7787
|
import {
|
|
7705
7788
|
RuntimeStore,
|
|
@@ -7718,6 +7801,8 @@ import {
|
|
|
7718
7801
|
createRealProjectRuntime,
|
|
7719
7802
|
ensureProjectRoot,
|
|
7720
7803
|
ensureProjectForAgent,
|
|
7804
|
+
insideProjectLine,
|
|
7805
|
+
projectFolderFor,
|
|
7721
7806
|
folderRefusalMessage,
|
|
7722
7807
|
projectLimitMessage,
|
|
7723
7808
|
runProjectCommand
|
|
@@ -7928,10 +8013,13 @@ function scannerConsentRequired(output, json, agent) {
|
|
|
7928
8013
|
else for (const line of approvalLines("scanner_consent_required", agent)) output.line(line);
|
|
7929
8014
|
return 3;
|
|
7930
8015
|
}
|
|
8016
|
+
var hostTargetFailed = (target) => target.status !== "READY" && target.reason !== "codex_trust_pending";
|
|
7931
8017
|
function hostUpdateFailed(result) {
|
|
7932
|
-
return result.results.some(
|
|
7933
|
-
|
|
7934
|
-
|
|
8018
|
+
return result.results.some(hostTargetFailed);
|
|
8019
|
+
}
|
|
8020
|
+
function registryFailure(hostError, results) {
|
|
8021
|
+
const reasons = hostError !== void 0 ? [hostError] : results.filter(hostTargetFailed).map((target) => target.reason);
|
|
8022
|
+
return reasons.length > 0 && reasons.every((reason) => REGISTRY_FAILURE.test(reason)) ? reasons[0] : void 0;
|
|
7935
8023
|
}
|
|
7936
8024
|
var updateFailureMessage = "Mnemonik could not update. It will try again automatically tomorrow.";
|
|
7937
8025
|
var booleans = /* @__PURE__ */ new Set([
|
|
@@ -7955,7 +8043,8 @@ var booleans = /* @__PURE__ */ new Set([
|
|
|
7955
8043
|
"automatic",
|
|
7956
8044
|
"cancel",
|
|
7957
8045
|
"retry",
|
|
7958
|
-
"skip"
|
|
8046
|
+
"skip",
|
|
8047
|
+
"follow"
|
|
7959
8048
|
]);
|
|
7960
8049
|
var values = /* @__PURE__ */ new Set([
|
|
7961
8050
|
"components",
|
|
@@ -7967,7 +8056,8 @@ var values = /* @__PURE__ */ new Set([
|
|
|
7967
8056
|
"rollback",
|
|
7968
8057
|
"out",
|
|
7969
8058
|
"project",
|
|
7970
|
-
"exclusions"
|
|
8059
|
+
"exclusions",
|
|
8060
|
+
"last"
|
|
7971
8061
|
]);
|
|
7972
8062
|
var help = helpScreen([]) ?? "";
|
|
7973
8063
|
function parse(args2) {
|
|
@@ -8411,7 +8501,11 @@ async function runHostCommand(command, parsed, deps, output, scannerSelected = f
|
|
|
8411
8501
|
output.error(INTERRUPTED_INSTALL_MESSAGE.sentence);
|
|
8412
8502
|
output.error(INTERRUPTED_INSTALL_MESSAGE.nextStep);
|
|
8413
8503
|
} else if (hostError === "lock_held") output.error(humanReason(hostError));
|
|
8414
|
-
else
|
|
8504
|
+
else {
|
|
8505
|
+
const registry = registryFailure(hostError, result.results);
|
|
8506
|
+
if (registry) for (const line of humanReport(registry).split("\n")) output.error(line);
|
|
8507
|
+
else output.error("Run mnemonik repair, then start a new session in each coding tool.");
|
|
8508
|
+
}
|
|
8415
8509
|
}
|
|
8416
8510
|
if (scanner?.status === "FAILED") {
|
|
8417
8511
|
output.error(scannerRecovery?.message ?? "The scanner could not update.");
|
|
@@ -8614,7 +8708,7 @@ async function enableCommand(parsed, deps, output) {
|
|
|
8614
8708
|
if (!present && !roots)
|
|
8615
8709
|
return actionRequired2(output, json, "Supply --scan-roots with approved roots", "--scan-roots");
|
|
8616
8710
|
for (const folder of [...roots ?? [], ...exclusions ?? []]) {
|
|
8617
|
-
const failure = await
|
|
8711
|
+
const failure = await realpath2(folder).then(
|
|
8618
8712
|
() => void 0,
|
|
8619
8713
|
(error) => folderFailure(error.code, folder)
|
|
8620
8714
|
);
|
|
@@ -8808,6 +8902,12 @@ async function doctorCommand(parsed, deps, output) {
|
|
|
8808
8902
|
else {
|
|
8809
8903
|
renderPreflight(result, output);
|
|
8810
8904
|
renderStatusSummaries(document, output, { diagnostics: true });
|
|
8905
|
+
for (const line of await hookActivityLines(
|
|
8906
|
+
deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home),
|
|
8907
|
+
deps.hooksLog?.now?.() ?? Date.now(),
|
|
8908
|
+
deps.hooksLog?.alive
|
|
8909
|
+
).catch(() => []))
|
|
8910
|
+
output.line(line);
|
|
8811
8911
|
if (document.installation.reasons.some(
|
|
8812
8912
|
(reason) => reason === "scanner_failing" || reason === "scanner_signed_out"
|
|
8813
8913
|
))
|
|
@@ -8894,7 +8994,7 @@ async function deleteProjectCommand(parsed, rest, deps, output) {
|
|
|
8894
8994
|
const json = parsed.flags.has("json");
|
|
8895
8995
|
const cwd = deps.cwd ?? process.cwd();
|
|
8896
8996
|
const resolve3 = deps.projectResolver?.resolveProjectIdentity ?? resolveProjectIdentity;
|
|
8897
|
-
const here = await resolve3(cwd
|
|
8997
|
+
const here = await resolve3(cwd);
|
|
8898
8998
|
const hereId = here.kind === "ok" ? here.identity.projectId : void 0;
|
|
8899
8999
|
const root = "root" in here ? here.root : cwd;
|
|
8900
9000
|
const target = rest[0] ?? hereId;
|
|
@@ -9064,8 +9164,13 @@ async function runCli(args2, deps = {}) {
|
|
|
9064
9164
|
if ((action === "add" || action === "remove") && !personPresent(parsed, deps) && !parsed.flags.has("apply"))
|
|
9065
9165
|
return actionRequired2(output, parsed.flags.has("json"), "Rerun with --apply", "--apply");
|
|
9066
9166
|
const pathArgument = actionArguments[0] ?? "";
|
|
9067
|
-
const
|
|
9167
|
+
const named = action === "add" ? await realpath2(pathArgument) : saved.config.roots.find((root) => root === pathArgument) ?? pathArgument;
|
|
9168
|
+
const requested = action === "add" ? await projectFolderFor(named, deps.projectExecutor ?? { resolveProjectIdentity }) : named;
|
|
9068
9169
|
const name2 = requested.split(/[\\/]/u).filter(Boolean).at(-1) ?? requested;
|
|
9170
|
+
if (requested !== named && !parsed.flags.has("json"))
|
|
9171
|
+
output.line(
|
|
9172
|
+
insideProjectLine(named.split(/[\\/]/u).filter(Boolean).at(-1) ?? named, requested)
|
|
9173
|
+
);
|
|
9069
9174
|
if (action === "add" && saved.config.roots.includes(requested)) {
|
|
9070
9175
|
if (parsed.flags.has("json")) output.json(saved.config.roots);
|
|
9071
9176
|
else output.line(alreadyConnectedFolderLine(name2));
|
|
@@ -9088,7 +9193,7 @@ async function runCli(args2, deps = {}) {
|
|
|
9088
9193
|
getCliBearer: async () => bearer,
|
|
9089
9194
|
fetch: deps.grantFetch
|
|
9090
9195
|
})).executor;
|
|
9091
|
-
const resolution = await executor.resolveProjectIdentity(requested);
|
|
9196
|
+
const resolution = await executor.resolveProjectIdentity(requested, { namedRoot: true });
|
|
9092
9197
|
const decision = await evaluateRoot(resolution, { cwd: requested, home: deps.home });
|
|
9093
9198
|
if (!decision.allowed) {
|
|
9094
9199
|
if (parsed.flags.has("json")) return actionRequired2(output, true, decision.reason);
|
|
@@ -9392,6 +9497,59 @@ Preview: ${preview.path}
|
|
|
9392
9497
|
return 1;
|
|
9393
9498
|
}
|
|
9394
9499
|
}
|
|
9500
|
+
if (command === "hooks") {
|
|
9501
|
+
const invalid = allowed(parsed, ["host", "last", "follow"]);
|
|
9502
|
+
if (invalid) return flagError(output, parsed, invalid);
|
|
9503
|
+
if (subcommand !== "log") return usageError(["hooks"]);
|
|
9504
|
+
if (rest.length) return argumentError(["hooks", "log"], ["hooks", "log"], rest, 0);
|
|
9505
|
+
const host = parsed.flags.get("host");
|
|
9506
|
+
if (host !== void 0 && !tracedHosts.includes(host))
|
|
9507
|
+
return usageFailure(
|
|
9508
|
+
output,
|
|
9509
|
+
parsed,
|
|
9510
|
+
{ reason: "invalid_value", path: ["hooks", "log"], detail: String(host) },
|
|
9511
|
+
`Unknown coding tool: ${String(host)}. Use claude-code, codex, cursor or copilot.`
|
|
9512
|
+
);
|
|
9513
|
+
const lastFlag = parsed.flags.get("last");
|
|
9514
|
+
const last = lastFlag === void 0 ? 20 : Number(lastFlag);
|
|
9515
|
+
if (!Number.isInteger(last) || last < 1 || last > 1e4)
|
|
9516
|
+
return usageFailure(
|
|
9517
|
+
output,
|
|
9518
|
+
parsed,
|
|
9519
|
+
{ reason: "invalid_value", path: ["hooks", "log"], detail: String(lastFlag) },
|
|
9520
|
+
"--last takes a whole number from 1 to 10000."
|
|
9521
|
+
);
|
|
9522
|
+
const json = parsed.flags.has("json");
|
|
9523
|
+
const follow = parsed.flags.has("follow");
|
|
9524
|
+
const stop2 = new AbortController();
|
|
9525
|
+
const interrupt = () => stop2.abort();
|
|
9526
|
+
if (follow && !deps.hooksLog?.signal) process.once("SIGINT", interrupt);
|
|
9527
|
+
try {
|
|
9528
|
+
const shown = await hooksLog({
|
|
9529
|
+
stateDir: deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home),
|
|
9530
|
+
hosts: host ? [host] : void 0,
|
|
9531
|
+
alive: deps.hooksLog?.alive,
|
|
9532
|
+
now: deps.hooksLog?.now,
|
|
9533
|
+
last,
|
|
9534
|
+
follow: follow && {
|
|
9535
|
+
signal: deps.hooksLog?.signal ?? stop2.signal,
|
|
9536
|
+
pollMs: deps.hooksLog?.pollMs
|
|
9537
|
+
},
|
|
9538
|
+
print: (invocation) => {
|
|
9539
|
+
if (json && follow) output.json(invocation);
|
|
9540
|
+
else if (!json) output.line(invocationLine(invocation));
|
|
9541
|
+
}
|
|
9542
|
+
});
|
|
9543
|
+
if (json && !follow) output.json({ invocations: shown });
|
|
9544
|
+
else if (!json && !shown.length && !follow)
|
|
9545
|
+
output.line(
|
|
9546
|
+
hookTraceEnabled(process.env) ? "No hook runs were found in this machine's Mnemonik state folder." : "No hook runs were found in this machine's Mnemonik state folder. MNEMONIK_HOOK_TRACE=off is set here, so hooks started from this environment record nothing."
|
|
9547
|
+
);
|
|
9548
|
+
} finally {
|
|
9549
|
+
process.removeListener("SIGINT", interrupt);
|
|
9550
|
+
}
|
|
9551
|
+
return 0;
|
|
9552
|
+
}
|
|
9395
9553
|
if (command === "status") {
|
|
9396
9554
|
const invalid = allowed(parsed, []);
|
|
9397
9555
|
if (invalid || subcommand)
|