mason-context 0.3.2 → 0.3.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/bin/mason-mcp.js +12 -11
- package/dist/bin/mason-mcp.js.map +1 -1
- package/dist/bin/mason.js +42 -18
- package/dist/bin/mason.js.map +1 -1
- package/dist/src/cli.js +42 -18
- package/dist/src/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/mason.js
CHANGED
|
@@ -405,13 +405,12 @@ function spawnWithStdin(command, args, input) {
|
|
|
405
405
|
});
|
|
406
406
|
}
|
|
407
407
|
async function callClaudeCLI(system, userMessage) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
${userMessage}`;
|
|
411
|
-
return spawnWithStdin("claude", ["-p"], prompt);
|
|
408
|
+
return spawnWithStdin("claude", ["-p", "--system-prompt", system], userMessage);
|
|
412
409
|
}
|
|
413
410
|
async function callGeminiCLI(system, userMessage) {
|
|
414
|
-
const prompt =
|
|
411
|
+
const prompt = `<system>
|
|
412
|
+
${system}
|
|
413
|
+
</system>
|
|
415
414
|
|
|
416
415
|
${userMessage}`;
|
|
417
416
|
return spawnWithStdin("gemini", ["-p", ""], prompt);
|
|
@@ -1094,6 +1093,7 @@ import fs4 from "fs/promises";
|
|
|
1094
1093
|
import path4 from "path";
|
|
1095
1094
|
import { execFile as execFile6 } from "child_process";
|
|
1096
1095
|
import { promisify as promisify6 } from "util";
|
|
1096
|
+
import fg4 from "fast-glob";
|
|
1097
1097
|
function snapshotDir(rootDir) {
|
|
1098
1098
|
return path4.join(rootDir, ".mason");
|
|
1099
1099
|
}
|
|
@@ -1157,7 +1157,31 @@ function parseSnapshotResponse(raw) {
|
|
|
1157
1157
|
}
|
|
1158
1158
|
async function createSnapshot(rootDir, config) {
|
|
1159
1159
|
const resolvedRoot = path4.resolve(rootDir);
|
|
1160
|
-
const
|
|
1160
|
+
const allFiles = await fg4(
|
|
1161
|
+
"**/*.{ts,tsx,js,jsx,kt,kts,java,py,go,rs,swift,rb,cs,cpp,c,dart}",
|
|
1162
|
+
{
|
|
1163
|
+
cwd: resolvedRoot,
|
|
1164
|
+
ignore: [
|
|
1165
|
+
"**/node_modules/**",
|
|
1166
|
+
"**/dist/**",
|
|
1167
|
+
"**/build/**",
|
|
1168
|
+
"**/.gradle/**",
|
|
1169
|
+
"**/target/**",
|
|
1170
|
+
"**/.git/**",
|
|
1171
|
+
"**/vendor/**",
|
|
1172
|
+
"**/__pycache__/**",
|
|
1173
|
+
"**/venv/**",
|
|
1174
|
+
"**/.venv/**",
|
|
1175
|
+
"**/*.min.*",
|
|
1176
|
+
"**/*.map",
|
|
1177
|
+
"**/generated/**",
|
|
1178
|
+
"**/R.java",
|
|
1179
|
+
"**/BuildConfig.java"
|
|
1180
|
+
]
|
|
1181
|
+
}
|
|
1182
|
+
);
|
|
1183
|
+
const sampleCount = Math.min(80, Math.max(20, Math.round(allFiles.length * 0.15)));
|
|
1184
|
+
const sampled = await sampleFiles(resolvedRoot, sampleCount);
|
|
1161
1185
|
const filesWithContent = [];
|
|
1162
1186
|
for (const sample of sampled) {
|
|
1163
1187
|
const full = await readFullFile(resolvedRoot, sample.path);
|
|
@@ -1324,7 +1348,7 @@ import fs5 from "fs/promises";
|
|
|
1324
1348
|
import path5 from "path";
|
|
1325
1349
|
import { execFile as execFile7 } from "child_process";
|
|
1326
1350
|
import { promisify as promisify7 } from "util";
|
|
1327
|
-
import
|
|
1351
|
+
import fg5 from "fast-glob";
|
|
1328
1352
|
async function analyzeImpact(rootDir, targetFiles) {
|
|
1329
1353
|
const resolvedRoot = path5.resolve(rootDir);
|
|
1330
1354
|
const resolvedTargets = await resolveTargetFiles(resolvedRoot, targetFiles);
|
|
@@ -1347,7 +1371,7 @@ async function resolveTargetFiles(rootDir, targets) {
|
|
|
1347
1371
|
resolved.push(target);
|
|
1348
1372
|
continue;
|
|
1349
1373
|
}
|
|
1350
|
-
const matches = await
|
|
1374
|
+
const matches = await fg5(`**/${target}`, {
|
|
1351
1375
|
cwd: rootDir,
|
|
1352
1376
|
ignore: IGNORE2
|
|
1353
1377
|
});
|
|
@@ -1355,7 +1379,7 @@ async function resolveTargetFiles(rootDir, targets) {
|
|
|
1355
1379
|
resolved.push(matches[0]);
|
|
1356
1380
|
} else {
|
|
1357
1381
|
const noExt = target.replace(/\.[^.]+$/, "");
|
|
1358
|
-
const extMatches = await
|
|
1382
|
+
const extMatches = await fg5(`**/${noExt}.*`, {
|
|
1359
1383
|
cwd: rootDir,
|
|
1360
1384
|
ignore: IGNORE2
|
|
1361
1385
|
});
|
|
@@ -1412,7 +1436,7 @@ async function getReferences(rootDir, targetFiles) {
|
|
|
1412
1436
|
const basename = path5.basename(target).replace(/\.[^.]+$/, "");
|
|
1413
1437
|
searchNames.add(basename);
|
|
1414
1438
|
}
|
|
1415
|
-
const allSourceFiles = await
|
|
1439
|
+
const allSourceFiles = await fg5(`**/${SOURCE_EXTENSIONS2}`, {
|
|
1416
1440
|
cwd: rootDir,
|
|
1417
1441
|
ignore: IGNORE2
|
|
1418
1442
|
});
|
|
@@ -1461,7 +1485,7 @@ async function getRelatedTests(rootDir, targetFiles) {
|
|
|
1461
1485
|
"**/*Test.swift",
|
|
1462
1486
|
"**/*_test.rs"
|
|
1463
1487
|
];
|
|
1464
|
-
const testFiles = await
|
|
1488
|
+
const testFiles = await fg5(testPatterns, { cwd: rootDir, ignore: IGNORE2 });
|
|
1465
1489
|
const results = [];
|
|
1466
1490
|
for (const target of targetFiles) {
|
|
1467
1491
|
const targetBaseName = path5.basename(target).replace(/\.[^.]+$/, "");
|
|
@@ -1508,7 +1532,7 @@ import fs6 from "fs/promises";
|
|
|
1508
1532
|
import path6 from "path";
|
|
1509
1533
|
import { execFile as execFile8 } from "child_process";
|
|
1510
1534
|
import { promisify as promisify8 } from "util";
|
|
1511
|
-
import
|
|
1535
|
+
import fg6 from "fast-glob";
|
|
1512
1536
|
async function buildContext(dir) {
|
|
1513
1537
|
return {
|
|
1514
1538
|
rootDir: dir,
|
|
@@ -1588,7 +1612,7 @@ async function detectProjectSnapshot(rootDir) {
|
|
|
1588
1612
|
];
|
|
1589
1613
|
const testInfo = {};
|
|
1590
1614
|
for (const pattern of testDirs) {
|
|
1591
|
-
const files = await
|
|
1615
|
+
const files = await fg6(`${pattern}/**/*`, {
|
|
1592
1616
|
cwd: rootDir,
|
|
1593
1617
|
ignore: IGNORE3,
|
|
1594
1618
|
onlyFiles: true
|
|
@@ -1608,12 +1632,12 @@ async function detectProjectSnapshot(rootDir) {
|
|
|
1608
1632
|
{ pattern: "**/*_test.rs", label: "*_test.rs" }
|
|
1609
1633
|
];
|
|
1610
1634
|
for (const { pattern, label } of testFilePatterns) {
|
|
1611
|
-
const files = await
|
|
1635
|
+
const files = await fg6(pattern, { cwd: rootDir, ignore: IGNORE3 });
|
|
1612
1636
|
if (files.length > 0) {
|
|
1613
1637
|
testInfo[label] = files.length;
|
|
1614
1638
|
}
|
|
1615
1639
|
}
|
|
1616
|
-
const sourceFiles = await
|
|
1640
|
+
const sourceFiles = await fg6("**/*.{ts,tsx,js,jsx,kt,kts,java,py,go,rs,swift,rb,cs,cpp,c,dart}", {
|
|
1617
1641
|
cwd: rootDir,
|
|
1618
1642
|
ignore: IGNORE3
|
|
1619
1643
|
});
|
|
@@ -1646,7 +1670,7 @@ async function getCodeSamples(dir, count = 15) {
|
|
|
1646
1670
|
}
|
|
1647
1671
|
async function getProjectStructure(dir) {
|
|
1648
1672
|
const rootDir = path6.resolve(dir);
|
|
1649
|
-
const allFiles = await
|
|
1673
|
+
const allFiles = await fg6("**/*", {
|
|
1650
1674
|
cwd: rootDir,
|
|
1651
1675
|
ignore: IGNORE3,
|
|
1652
1676
|
onlyFiles: true
|
|
@@ -1829,7 +1853,7 @@ function createMcpServer() {
|
|
|
1829
1853
|
const server = new McpServer(
|
|
1830
1854
|
{
|
|
1831
1855
|
name: "mason",
|
|
1832
|
-
version: "0.3.
|
|
1856
|
+
version: "0.3.3"
|
|
1833
1857
|
},
|
|
1834
1858
|
{
|
|
1835
1859
|
instructions: "Mason is a context engineering tool. Always call get_snapshot before using Explore agents, Glob, or Grep to understand the codebase. The snapshot is a concept map that maps features and flows to their implementing files \u2014 it eliminates the need to search. This applies to ANY question about architecture, features, flows, how things work, cross-feature interactions, or bug investigation. Workflow: 1) Call get_snapshot first. 2) If no snapshot, call full_analysis and then save_snapshot to create one. 3) If the snapshot is stale, tell the user and offer to update it. 4) Use your native file reading tool to read files the snapshot points to. 5) Before modifying a file, call get_impact to check what else might be affected. 6) After making significant changes (new features, refactors, architecture changes), call save_snapshot to update the concept map."
|
|
@@ -2014,7 +2038,7 @@ function createCLI() {
|
|
|
2014
2038
|
const program2 = new Command();
|
|
2015
2039
|
program2.name("mason").description(
|
|
2016
2040
|
"Context engineering CLI & MCP server \u2014 generates intelligent CLAUDE.md files"
|
|
2017
|
-
).version("0.3.
|
|
2041
|
+
).version("0.3.3");
|
|
2018
2042
|
program2.command("setup").description("Register Mason as an MCP server with Claude Code").option("--scope <scope>", "Config scope: user or project", "user").action(async (opts) => {
|
|
2019
2043
|
const { execFile: execFile9 } = await import("child_process");
|
|
2020
2044
|
const { promisify: promisify9 } = await import("util");
|