mason-context 0.17.3 → 0.18.0
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/CHANGELOG.md +21 -0
- package/dist/mason-audit.js +304 -222
- package/dist/mason-audit.js.map +1 -1
- package/dist/mason-auto.js +339 -253
- package/dist/mason-auto.js.map +1 -1
- package/dist/mason-drift.js +54 -22
- package/dist/mason-drift.js.map +1 -1
- package/dist/mason-hook.js +55 -22
- package/dist/mason-hook.js.map +1 -1
- package/dist/mason-mcp.js +831 -603
- package/dist/mason-mcp.js.map +1 -1
- package/dist/mason-review.js +63 -30
- package/dist/mason-review.js.map +1 -1
- package/dist/mason.js +372 -286
- package/dist/mason.js.map +1 -1
- package/package.json +1 -1
package/dist/mason-review.js
CHANGED
|
@@ -5,28 +5,59 @@ import path12 from "path";
|
|
|
5
5
|
import { stripVTControlCharacters } from "util";
|
|
6
6
|
|
|
7
7
|
// src/review/review.ts
|
|
8
|
-
import
|
|
8
|
+
import fs6 from "fs/promises";
|
|
9
9
|
import path11 from "path";
|
|
10
|
-
import { execFile as
|
|
11
|
-
import { promisify as
|
|
10
|
+
import { execFile as execFile3 } from "child_process";
|
|
11
|
+
import { promisify as promisify3 } from "util";
|
|
12
|
+
|
|
13
|
+
// src/utils/git-read.ts
|
|
14
|
+
import { execFile } from "child_process";
|
|
15
|
+
import { promisify } from "util";
|
|
16
|
+
|
|
17
|
+
// src/utils/profile.ts
|
|
18
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
19
|
+
var profiles = new AsyncLocalStorage();
|
|
20
|
+
async function profilePhase(label, run) {
|
|
21
|
+
const phases = profiles.getStore();
|
|
22
|
+
if (!phases) return run();
|
|
23
|
+
const start = performance.now();
|
|
24
|
+
try {
|
|
25
|
+
return await run();
|
|
26
|
+
} finally {
|
|
27
|
+
const timing = phases[label] ??= { calls: 0, totalMs: 0 };
|
|
28
|
+
timing.calls++;
|
|
29
|
+
timing.totalMs += performance.now() - start;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/utils/git-read.ts
|
|
34
|
+
var execute = promisify(execFile);
|
|
35
|
+
var commands = /* @__PURE__ */ new Set(["rev-parse", "symbolic-ref", "for-each-ref", "ls-files", "check-ignore", "status", "log", "diff", "ls-tree", "show", "merge-base"]);
|
|
36
|
+
function execGit(args, options) {
|
|
37
|
+
const command = args.find((arg) => !arg.startsWith("-")) ?? "other";
|
|
38
|
+
return profilePhase("git." + (commands.has(command) ? command : "other"), async () => {
|
|
39
|
+
const { input, ...processOptions } = options;
|
|
40
|
+
const operation = execute("git", args, processOptions);
|
|
41
|
+
if (input !== void 0) {
|
|
42
|
+
operation.child.stdin.on("error", () => {
|
|
43
|
+
});
|
|
44
|
+
operation.child.stdin.end(input);
|
|
45
|
+
}
|
|
46
|
+
return operation;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
12
49
|
|
|
13
50
|
// src/drift/drift.ts
|
|
14
|
-
import
|
|
51
|
+
import fs4 from "fs/promises";
|
|
15
52
|
import path6 from "path";
|
|
16
|
-
import { execFile as execFile3 } from "child_process";
|
|
17
|
-
import { promisify as promisify3 } from "util";
|
|
18
53
|
|
|
19
54
|
// src/snapshot/snapshot.ts
|
|
20
55
|
import path5 from "path";
|
|
21
|
-
import { execFile as execFile2 } from "child_process";
|
|
22
|
-
import { promisify as promisify2 } from "util";
|
|
23
56
|
|
|
24
57
|
// src/utils/files.ts
|
|
25
58
|
import fs from "fs/promises";
|
|
26
59
|
import { constants } from "fs";
|
|
27
60
|
import path2 from "path";
|
|
28
|
-
import { execFile } from "child_process";
|
|
29
|
-
import { promisify } from "util";
|
|
30
61
|
import fg from "fast-glob";
|
|
31
62
|
|
|
32
63
|
// src/utils/paths.ts
|
|
@@ -52,7 +83,6 @@ function matchingPaths(anchors, files) {
|
|
|
52
83
|
}
|
|
53
84
|
|
|
54
85
|
// src/utils/files.ts
|
|
55
|
-
var exec = promisify(execFile);
|
|
56
86
|
var SOURCE_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "cts", "mjs", "cjs", "vue", "svelte", "kt", "kts", "java", "py", "go", "rs", "swift", "rb", "cs", "cpp", "c", "h", "hpp", "dart", "php"];
|
|
57
87
|
var SOURCE_GLOB = `**/*.{${SOURCE_EXTENSIONS.join(",")}}`;
|
|
58
88
|
var SOURCE_IGNORE = [
|
|
@@ -131,12 +161,12 @@ async function createFileAccess(rootDir) {
|
|
|
131
161
|
const ignore = [...SOURCE_IGNORE, ...config.ignore ?? []];
|
|
132
162
|
let gitFiles = null;
|
|
133
163
|
try {
|
|
134
|
-
const { stdout } = await
|
|
164
|
+
const { stdout } = await execGit(["ls-files", "-z", "--cached", "--others", "--exclude-standard"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });
|
|
135
165
|
gitFiles = new Set(stdout.split("\0").filter(Boolean));
|
|
136
166
|
} catch {
|
|
137
167
|
let inGit = false;
|
|
138
168
|
try {
|
|
139
|
-
await
|
|
169
|
+
await execGit(["rev-parse", "--git-dir"], { cwd: root });
|
|
140
170
|
inGit = true;
|
|
141
171
|
} catch {
|
|
142
172
|
}
|
|
@@ -226,6 +256,10 @@ async function readStoreJson(root, relative) {
|
|
|
226
256
|
// src/snapshot/snapshot.ts
|
|
227
257
|
import { z } from "zod";
|
|
228
258
|
|
|
259
|
+
// src/utils/store-lock.ts
|
|
260
|
+
import fs3 from "fs/promises";
|
|
261
|
+
import os from "os";
|
|
262
|
+
|
|
229
263
|
// src/test-map.ts
|
|
230
264
|
import path4 from "path";
|
|
231
265
|
async function buildTestMap(dir) {
|
|
@@ -297,12 +331,12 @@ function commonSegments(pathA, pathB) {
|
|
|
297
331
|
}
|
|
298
332
|
|
|
299
333
|
// src/snapshot/snapshot.ts
|
|
300
|
-
var exec2 = promisify2(execFile2);
|
|
301
334
|
var repoPath = z.string().refine((value) => normalizeRepoPath(value) !== null, "Expected a relative repository path");
|
|
302
335
|
var verificationFields = {
|
|
303
336
|
refreshedHash: z.string().optional(),
|
|
304
337
|
verifiedAt: z.string().optional(),
|
|
305
338
|
verifiedHash: z.string().optional(),
|
|
339
|
+
verificationToken: z.string().optional(),
|
|
306
340
|
verificationFailed: z.boolean().optional(),
|
|
307
341
|
verificationNote: z.string().optional()
|
|
308
342
|
};
|
|
@@ -324,7 +358,7 @@ var snapshotSchema = z.object({
|
|
|
324
358
|
}).passthrough();
|
|
325
359
|
async function getCurrentGitHash(rootDir) {
|
|
326
360
|
try {
|
|
327
|
-
const { stdout } = await
|
|
361
|
+
const { stdout } = await execGit(["rev-parse", "HEAD"], {
|
|
328
362
|
cwd: rootDir
|
|
329
363
|
});
|
|
330
364
|
return stdout.trim();
|
|
@@ -334,7 +368,6 @@ async function getCurrentGitHash(rootDir) {
|
|
|
334
368
|
}
|
|
335
369
|
|
|
336
370
|
// src/drift/drift.ts
|
|
337
|
-
var exec3 = promisify3(execFile3);
|
|
338
371
|
function parseChanges(output) {
|
|
339
372
|
const fields = output.split("\0");
|
|
340
373
|
const changes = [];
|
|
@@ -355,7 +388,7 @@ function touchedPaths(changes) {
|
|
|
355
388
|
async function getChangesWithStatus(resolvedRoot, fromHash, toHash = "HEAD") {
|
|
356
389
|
if (!fromHash || fromHash === "unknown" || fromHash.startsWith("-") || !toHash || toHash === "unknown" || toHash.startsWith("-")) return null;
|
|
357
390
|
try {
|
|
358
|
-
const { stdout } = await
|
|
391
|
+
const { stdout } = await execGit(["diff", "--name-status", "-z", "-M", fromHash, toHash, "--"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
359
392
|
return parseChanges(stdout);
|
|
360
393
|
} catch {
|
|
361
394
|
return null;
|
|
@@ -364,8 +397,8 @@ async function getChangesWithStatus(resolvedRoot, fromHash, toHash = "HEAD") {
|
|
|
364
397
|
async function getWorkingTree(resolvedRoot) {
|
|
365
398
|
try {
|
|
366
399
|
const [diff, untracked] = await Promise.all([
|
|
367
|
-
|
|
368
|
-
|
|
400
|
+
execGit(["diff", "--name-status", "-z", "-M", "HEAD", "--"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),
|
|
401
|
+
execGit(["ls-files", "-z", "--others", "--exclude-standard"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 })
|
|
369
402
|
]);
|
|
370
403
|
const untrackedFiles = untracked.stdout.split("\0").filter((f) => f && !f.startsWith(".mason/"));
|
|
371
404
|
return { available: true, changedFiles: [.../* @__PURE__ */ new Set([...touchedPaths(parseChanges(diff.stdout)), ...untrackedFiles])].sort(), untrackedFiles };
|
|
@@ -539,7 +572,7 @@ function decisionKnowledge(record, freshness = "unknown", proposalFreshness = "u
|
|
|
539
572
|
}
|
|
540
573
|
|
|
541
574
|
// src/decisions/decisions.ts
|
|
542
|
-
import
|
|
575
|
+
import fs5 from "fs/promises";
|
|
543
576
|
import path8 from "path";
|
|
544
577
|
import { createHash } from "crypto";
|
|
545
578
|
import { z as z3 } from "zod";
|
|
@@ -565,7 +598,7 @@ async function loadDecisionStore(rootDir) {
|
|
|
565
598
|
const diagnostics = [];
|
|
566
599
|
let entries;
|
|
567
600
|
try {
|
|
568
|
-
entries = await
|
|
601
|
+
entries = await fs5.readdir(await storePath(rootDir, ".mason/decisions"));
|
|
569
602
|
} catch (error) {
|
|
570
603
|
if (error.code !== "ENOENT") diagnostics.push({ path: ".mason/decisions", message: String(error) });
|
|
571
604
|
return { records, diagnostics };
|
|
@@ -617,9 +650,9 @@ async function computeDecisionDrift(rootDir, decisions) {
|
|
|
617
650
|
}
|
|
618
651
|
|
|
619
652
|
// src/review/cochange.ts
|
|
620
|
-
import { execFile as
|
|
621
|
-
import { promisify as
|
|
622
|
-
var
|
|
653
|
+
import { execFile as execFile2 } from "child_process";
|
|
654
|
+
import { promisify as promisify2 } from "util";
|
|
655
|
+
var exec = promisify2(execFile2);
|
|
623
656
|
var HISTORY_COMMITS = 1500;
|
|
624
657
|
var MIN_FILE_COMMITS = 5;
|
|
625
658
|
var MIN_SHARED_COMMITS = 4;
|
|
@@ -627,9 +660,9 @@ var MIN_COCHANGE_RATE = 0.6;
|
|
|
627
660
|
var MAX_COMMIT_FILES = 30;
|
|
628
661
|
async function buildMatrix(resolvedRoot) {
|
|
629
662
|
try {
|
|
630
|
-
const { stdout: shallow } = await
|
|
663
|
+
const { stdout: shallow } = await exec("git", ["rev-parse", "--is-shallow-repository"], { cwd: resolvedRoot });
|
|
631
664
|
if (shallow.trim() === "true") return null;
|
|
632
|
-
const { stdout } = await
|
|
665
|
+
const { stdout } = await exec(
|
|
633
666
|
"git",
|
|
634
667
|
["log", `-n${HISTORY_COMMITS}`, "--format=%x01", "--name-only", "-M"],
|
|
635
668
|
{ cwd: resolvedRoot, maxBuffer: 100 * 1024 * 1024 }
|
|
@@ -1129,11 +1162,11 @@ async function collectReviewEvidence(root, manifests, changedFiles, decisions, d
|
|
|
1129
1162
|
}
|
|
1130
1163
|
|
|
1131
1164
|
// src/review/review.ts
|
|
1132
|
-
var
|
|
1165
|
+
var exec2 = promisify3(execFile3);
|
|
1133
1166
|
var MAX_ANALYZED_FILES = 50;
|
|
1134
1167
|
async function resolveMergeBase(resolvedRoot, base, head) {
|
|
1135
1168
|
try {
|
|
1136
|
-
const { stdout } = await
|
|
1169
|
+
const { stdout } = await exec2("git", ["merge-base", base, head], {
|
|
1137
1170
|
cwd: resolvedRoot
|
|
1138
1171
|
});
|
|
1139
1172
|
return stdout.trim() || null;
|
|
@@ -1144,7 +1177,7 @@ async function resolveMergeBase(resolvedRoot, base, head) {
|
|
|
1144
1177
|
async function defaultBase(resolvedRoot) {
|
|
1145
1178
|
for (const ref of ["origin/HEAD", "origin/main", "origin/master", "main"]) {
|
|
1146
1179
|
try {
|
|
1147
|
-
await
|
|
1180
|
+
await exec2("git", ["rev-parse", "--verify", "--quiet", ref], {
|
|
1148
1181
|
cwd: resolvedRoot
|
|
1149
1182
|
});
|
|
1150
1183
|
return ref;
|
|
@@ -1207,7 +1240,7 @@ async function computeReview(rootDir, base, options = {}) {
|
|
|
1207
1240
|
analyzed,
|
|
1208
1241
|
async (relPath) => {
|
|
1209
1242
|
try {
|
|
1210
|
-
await
|
|
1243
|
+
await fs6.access(path11.join(resolvedRoot, relPath));
|
|
1211
1244
|
return true;
|
|
1212
1245
|
} catch {
|
|
1213
1246
|
return false;
|