mason-context 0.3.3 → 0.3.5
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/README.md +8 -0
- package/dist/bin/mason-mcp.js +27 -1
- package/dist/bin/mason-mcp.js.map +1 -1
- package/dist/bin/mason.js +28 -2
- package/dist/bin/mason.js.map +1 -1
- package/dist/src/cli.js +28 -2
- package/dist/src/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/mason.js
CHANGED
|
@@ -518,10 +518,22 @@ async function loadProjectConfig(rootDir) {
|
|
|
518
518
|
return {};
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
+
async function getTrackedFiles(rootDir) {
|
|
522
|
+
try {
|
|
523
|
+
const { stdout } = await exec5("git", ["ls-files", "--cached", "--others", "--exclude-standard"], {
|
|
524
|
+
cwd: rootDir,
|
|
525
|
+
maxBuffer: 1e7
|
|
526
|
+
});
|
|
527
|
+
return new Set(stdout.trim().split("\n").filter(Boolean));
|
|
528
|
+
} catch {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
521
532
|
async function sampleFiles(rootDir, maxFiles = 25) {
|
|
522
533
|
const selected = /* @__PURE__ */ new Map();
|
|
523
534
|
const projectConfig = await loadProjectConfig(rootDir);
|
|
524
535
|
const ignorePatterns = [...IGNORE_PATTERNS, ...projectConfig.ignore ?? []];
|
|
536
|
+
const trackedFiles = await getTrackedFiles(rootDir);
|
|
525
537
|
for (const filePath of projectConfig.alwaysInclude ?? []) {
|
|
526
538
|
if (selected.size >= maxFiles) break;
|
|
527
539
|
const resolvedPath = path2.resolve(rootDir, filePath);
|
|
@@ -700,6 +712,7 @@ async function sampleFiles(rootDir, maxFiles = 25) {
|
|
|
700
712
|
const fullPath = path2.resolve(rootDir, filePath);
|
|
701
713
|
if (!fullPath.startsWith(path2.resolve(rootDir))) continue;
|
|
702
714
|
if (isSensitiveFile(filePath)) continue;
|
|
715
|
+
if (trackedFiles && !trackedFiles.has(filePath)) continue;
|
|
703
716
|
const stat = await fs3.stat(fullPath);
|
|
704
717
|
if (stat.size > 1e5) continue;
|
|
705
718
|
const content = await fs3.readFile(fullPath, "utf-8");
|
|
@@ -1776,10 +1789,23 @@ async function fullAnalysis(dir) {
|
|
|
1776
1789
|
}
|
|
1777
1790
|
return JSON.stringify(output, null, 2);
|
|
1778
1791
|
}
|
|
1792
|
+
function sanitizePaths(rootDir, files) {
|
|
1793
|
+
return files.filter((f) => {
|
|
1794
|
+
const resolved = path6.resolve(rootDir, f);
|
|
1795
|
+
return resolved.startsWith(rootDir) && !f.startsWith("/") && !f.includes("..");
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1779
1798
|
async function saveSnapshotData(dir, features, flows) {
|
|
1780
1799
|
const rootDir = path6.resolve(dir);
|
|
1781
1800
|
const gitHash = await getCurrentGitHash(rootDir);
|
|
1782
1801
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1802
|
+
for (const feat of Object.values(features)) {
|
|
1803
|
+
feat.files = sanitizePaths(rootDir, feat.files);
|
|
1804
|
+
if (feat.tests) feat.tests = sanitizePaths(rootDir, feat.tests);
|
|
1805
|
+
}
|
|
1806
|
+
for (const flow of Object.values(flows)) {
|
|
1807
|
+
flow.chain = sanitizePaths(rootDir, flow.chain);
|
|
1808
|
+
}
|
|
1783
1809
|
const existing = await loadSnapshot(rootDir);
|
|
1784
1810
|
if (existing) {
|
|
1785
1811
|
existing.features = { ...existing.features, ...features };
|
|
@@ -1853,7 +1879,7 @@ function createMcpServer() {
|
|
|
1853
1879
|
const server = new McpServer(
|
|
1854
1880
|
{
|
|
1855
1881
|
name: "mason",
|
|
1856
|
-
version: "0.3.
|
|
1882
|
+
version: "0.3.5"
|
|
1857
1883
|
},
|
|
1858
1884
|
{
|
|
1859
1885
|
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."
|
|
@@ -2038,7 +2064,7 @@ function createCLI() {
|
|
|
2038
2064
|
const program2 = new Command();
|
|
2039
2065
|
program2.name("mason").description(
|
|
2040
2066
|
"Context engineering CLI & MCP server \u2014 generates intelligent CLAUDE.md files"
|
|
2041
|
-
).version("0.3.
|
|
2067
|
+
).version("0.3.5");
|
|
2042
2068
|
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) => {
|
|
2043
2069
|
const { execFile: execFile9 } = await import("child_process");
|
|
2044
2070
|
const { promisify: promisify9 } = await import("util");
|