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-drift.js
CHANGED
|
@@ -3,23 +3,54 @@
|
|
|
3
3
|
// src/drift/cli.ts
|
|
4
4
|
import path10 from "path";
|
|
5
5
|
|
|
6
|
+
// src/utils/git-read.ts
|
|
7
|
+
import { execFile } from "child_process";
|
|
8
|
+
import { promisify } from "util";
|
|
9
|
+
|
|
10
|
+
// src/utils/profile.ts
|
|
11
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
12
|
+
var profiles = new AsyncLocalStorage();
|
|
13
|
+
async function profilePhase(label, run) {
|
|
14
|
+
const phases = profiles.getStore();
|
|
15
|
+
if (!phases) return run();
|
|
16
|
+
const start = performance.now();
|
|
17
|
+
try {
|
|
18
|
+
return await run();
|
|
19
|
+
} finally {
|
|
20
|
+
const timing = phases[label] ??= { calls: 0, totalMs: 0 };
|
|
21
|
+
timing.calls++;
|
|
22
|
+
timing.totalMs += performance.now() - start;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/utils/git-read.ts
|
|
27
|
+
var execute = promisify(execFile);
|
|
28
|
+
var commands = /* @__PURE__ */ new Set(["rev-parse", "symbolic-ref", "for-each-ref", "ls-files", "check-ignore", "status", "log", "diff", "ls-tree", "show", "merge-base"]);
|
|
29
|
+
function execGit(args, options) {
|
|
30
|
+
const command = args.find((arg) => !arg.startsWith("-")) ?? "other";
|
|
31
|
+
return profilePhase("git." + (commands.has(command) ? command : "other"), async () => {
|
|
32
|
+
const { input, ...processOptions } = options;
|
|
33
|
+
const operation = execute("git", args, processOptions);
|
|
34
|
+
if (input !== void 0) {
|
|
35
|
+
operation.child.stdin.on("error", () => {
|
|
36
|
+
});
|
|
37
|
+
operation.child.stdin.end(input);
|
|
38
|
+
}
|
|
39
|
+
return operation;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
6
43
|
// src/drift/drift.ts
|
|
7
|
-
import
|
|
44
|
+
import fs4 from "fs/promises";
|
|
8
45
|
import path6 from "path";
|
|
9
|
-
import { execFile as execFile3 } from "child_process";
|
|
10
|
-
import { promisify as promisify3 } from "util";
|
|
11
46
|
|
|
12
47
|
// src/snapshot/snapshot.ts
|
|
13
48
|
import path5 from "path";
|
|
14
|
-
import { execFile as execFile2 } from "child_process";
|
|
15
|
-
import { promisify as promisify2 } from "util";
|
|
16
49
|
|
|
17
50
|
// src/utils/files.ts
|
|
18
51
|
import fs from "fs/promises";
|
|
19
52
|
import { constants } from "fs";
|
|
20
53
|
import path2 from "path";
|
|
21
|
-
import { execFile } from "child_process";
|
|
22
|
-
import { promisify } from "util";
|
|
23
54
|
import fg from "fast-glob";
|
|
24
55
|
|
|
25
56
|
// src/utils/paths.ts
|
|
@@ -45,7 +76,6 @@ function matchingPaths(anchors, files) {
|
|
|
45
76
|
}
|
|
46
77
|
|
|
47
78
|
// src/utils/files.ts
|
|
48
|
-
var exec = promisify(execFile);
|
|
49
79
|
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"];
|
|
50
80
|
var SOURCE_GLOB = `**/*.{${SOURCE_EXTENSIONS.join(",")}}`;
|
|
51
81
|
var SOURCE_IGNORE = [
|
|
@@ -124,12 +154,12 @@ async function createFileAccess(rootDir) {
|
|
|
124
154
|
const ignore = [...SOURCE_IGNORE, ...config.ignore ?? []];
|
|
125
155
|
let gitFiles = null;
|
|
126
156
|
try {
|
|
127
|
-
const { stdout } = await
|
|
157
|
+
const { stdout } = await execGit(["ls-files", "-z", "--cached", "--others", "--exclude-standard"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });
|
|
128
158
|
gitFiles = new Set(stdout.split("\0").filter(Boolean));
|
|
129
159
|
} catch {
|
|
130
160
|
let inGit = false;
|
|
131
161
|
try {
|
|
132
|
-
await
|
|
162
|
+
await execGit(["rev-parse", "--git-dir"], { cwd: root });
|
|
133
163
|
inGit = true;
|
|
134
164
|
} catch {
|
|
135
165
|
}
|
|
@@ -219,16 +249,20 @@ async function readStoreJson(root, relative) {
|
|
|
219
249
|
// src/snapshot/snapshot.ts
|
|
220
250
|
import { z } from "zod";
|
|
221
251
|
|
|
252
|
+
// src/utils/store-lock.ts
|
|
253
|
+
import fs3 from "fs/promises";
|
|
254
|
+
import os from "os";
|
|
255
|
+
|
|
222
256
|
// src/test-map.ts
|
|
223
257
|
import path4 from "path";
|
|
224
258
|
|
|
225
259
|
// src/snapshot/snapshot.ts
|
|
226
|
-
var exec2 = promisify2(execFile2);
|
|
227
260
|
var repoPath = z.string().refine((value) => normalizeRepoPath(value) !== null, "Expected a relative repository path");
|
|
228
261
|
var verificationFields = {
|
|
229
262
|
refreshedHash: z.string().optional(),
|
|
230
263
|
verifiedAt: z.string().optional(),
|
|
231
264
|
verifiedHash: z.string().optional(),
|
|
265
|
+
verificationToken: z.string().optional(),
|
|
232
266
|
verificationFailed: z.boolean().optional(),
|
|
233
267
|
verificationNote: z.string().optional()
|
|
234
268
|
};
|
|
@@ -257,7 +291,7 @@ async function loadSnapshot(rootDir) {
|
|
|
257
291
|
}
|
|
258
292
|
async function getCurrentGitHash(rootDir) {
|
|
259
293
|
try {
|
|
260
|
-
const { stdout } = await
|
|
294
|
+
const { stdout } = await execGit(["rev-parse", "HEAD"], {
|
|
261
295
|
cwd: rootDir
|
|
262
296
|
});
|
|
263
297
|
return stdout.trim();
|
|
@@ -270,7 +304,6 @@ async function listSourceFiles(resolvedRoot) {
|
|
|
270
304
|
}
|
|
271
305
|
|
|
272
306
|
// src/drift/drift.ts
|
|
273
|
-
var exec3 = promisify3(execFile3);
|
|
274
307
|
var FULL_REBUILD_FRACTION = 0.4;
|
|
275
308
|
var FULL_REBUILD_MIN_CHANGED_MAPPED_FILES = 10;
|
|
276
309
|
function parseChanges(output) {
|
|
@@ -293,7 +326,7 @@ function touchedPaths(changes) {
|
|
|
293
326
|
async function getChangesWithStatus(resolvedRoot, fromHash, toHash = "HEAD") {
|
|
294
327
|
if (!fromHash || fromHash === "unknown" || fromHash.startsWith("-") || !toHash || toHash === "unknown" || toHash.startsWith("-")) return null;
|
|
295
328
|
try {
|
|
296
|
-
const { stdout } = await
|
|
329
|
+
const { stdout } = await execGit(["diff", "--name-status", "-z", "-M", fromHash, toHash, "--"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
297
330
|
return parseChanges(stdout);
|
|
298
331
|
} catch {
|
|
299
332
|
return null;
|
|
@@ -302,8 +335,8 @@ async function getChangesWithStatus(resolvedRoot, fromHash, toHash = "HEAD") {
|
|
|
302
335
|
async function getWorkingTree(resolvedRoot) {
|
|
303
336
|
try {
|
|
304
337
|
const [diff, untracked] = await Promise.all([
|
|
305
|
-
|
|
306
|
-
|
|
338
|
+
execGit(["diff", "--name-status", "-z", "-M", "HEAD", "--"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),
|
|
339
|
+
execGit(["ls-files", "-z", "--others", "--exclude-standard"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 })
|
|
307
340
|
]);
|
|
308
341
|
const untrackedFiles = untracked.stdout.split("\0").filter((f) => f && !f.startsWith(".mason/"));
|
|
309
342
|
return { available: true, changedFiles: [.../* @__PURE__ */ new Set([...touchedPaths(parseChanges(diff.stdout)), ...untrackedFiles])].sort(), untrackedFiles };
|
|
@@ -314,8 +347,7 @@ async function getWorkingTree(resolvedRoot) {
|
|
|
314
347
|
async function countCommitsBehind(resolvedRoot, fromHash) {
|
|
315
348
|
if (!fromHash || fromHash === "unknown" || fromHash.startsWith("-")) return null;
|
|
316
349
|
try {
|
|
317
|
-
const { stdout } = await
|
|
318
|
-
"git",
|
|
350
|
+
const { stdout } = await execGit(
|
|
319
351
|
["rev-list", "--count", `${fromHash}..HEAD`],
|
|
320
352
|
{ cwd: resolvedRoot }
|
|
321
353
|
);
|
|
@@ -340,7 +372,7 @@ async function findGhostFiles(resolvedRoot, mappedFiles) {
|
|
|
340
372
|
const ghosts = [];
|
|
341
373
|
for (const file of mappedFiles) {
|
|
342
374
|
try {
|
|
343
|
-
await
|
|
375
|
+
await fs4.access(path6.join(resolvedRoot, file));
|
|
344
376
|
} catch {
|
|
345
377
|
ghosts.push(file);
|
|
346
378
|
}
|
|
@@ -405,7 +437,7 @@ async function computeDrift(rootDir) {
|
|
|
405
437
|
const sourceFiles = new Set(await listSourceFiles(root));
|
|
406
438
|
let committedFiles = /* @__PURE__ */ new Set();
|
|
407
439
|
try {
|
|
408
|
-
const { stdout } = await
|
|
440
|
+
const { stdout } = await execGit(["ls-tree", "-r", "--name-only", "-z", "HEAD"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });
|
|
409
441
|
committedFiles = new Set(stdout.split("\0").filter(Boolean));
|
|
410
442
|
} catch {
|
|
411
443
|
report.historyAvailable = false;
|
|
@@ -430,7 +462,7 @@ async function computeDrift(rootDir) {
|
|
|
430
462
|
import path9 from "path";
|
|
431
463
|
|
|
432
464
|
// src/decisions/decisions.ts
|
|
433
|
-
import
|
|
465
|
+
import fs5 from "fs/promises";
|
|
434
466
|
import path8 from "path";
|
|
435
467
|
import { createHash } from "crypto";
|
|
436
468
|
import { z as z3 } from "zod";
|
|
@@ -577,7 +609,7 @@ async function loadDecisionStore(rootDir) {
|
|
|
577
609
|
const diagnostics = [];
|
|
578
610
|
let entries;
|
|
579
611
|
try {
|
|
580
|
-
entries = await
|
|
612
|
+
entries = await fs5.readdir(await storePath(rootDir, ".mason/decisions"));
|
|
581
613
|
} catch (error) {
|
|
582
614
|
if (error.code !== "ENOENT") diagnostics.push({ path: ".mason/decisions", message: String(error) });
|
|
583
615
|
return { records, diagnostics };
|