musubix2 0.5.26 → 0.5.28
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/.claude/.musubix-managed +1 -1
- package/dist/assets/skills-manifest.json +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +194 -70
- package/dist/cli.js.map +1 -1
- package/dist/index.js +194 -70
- package/package.json +1 -1
package/.claude/.musubix-managed
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generator":"musubix2","version":"0.5.
|
|
1
|
+
{"generator":"musubix2","version":"0.5.28","timestamp":"2026-07-09T21:16:10.785Z"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -15909,8 +15909,8 @@ var COMMAND_HELP = {
|
|
|
15909
15909
|
description: "\u30AA\u30F3\u30C8\u30ED\u30B8\u30FC\u7BA1\u7406"
|
|
15910
15910
|
},
|
|
15911
15911
|
cg: {
|
|
15912
|
-
usage: "musubix cg <index|search|stats|deps|impact|candidates|cycles|export|diff|languages> [args]",
|
|
15913
|
-
description: "\u30B3\u30FC\u30C9\u30B0\u30E9\u30D5\u5206\u6790 (impact
|
|
15912
|
+
usage: "musubix cg <index|search|stats|deps|impact|candidates|cycles|gate|export|diff|languages> [args]",
|
|
15913
|
+
description: "\u30B3\u30FC\u30C9\u30B0\u30E9\u30D5\u5206\u6790 (impact \u5F71\u97FF\u3001candidates \u5019\u88DC\u3001cycles \u5FAA\u74B0\u3001gate CI\u54C1\u8CEA\u30B2\u30FC\u30C8\u3001export\u3001diff)"
|
|
15914
15914
|
},
|
|
15915
15915
|
security: {
|
|
15916
15916
|
usage: "musubix security <path> [--fail-on critical|high|medium|low|info] [--exclude-tests]",
|
|
@@ -16652,6 +16652,72 @@ function resolveFileEdges(nodes, edges) {
|
|
|
16652
16652
|
}
|
|
16653
16653
|
return fileEdges;
|
|
16654
16654
|
}
|
|
16655
|
+
function findDependencyCycles(nodes, edges) {
|
|
16656
|
+
const { defFiles, filesByBasename } = buildResolutionMaps(nodes);
|
|
16657
|
+
const adj = /* @__PURE__ */ new Map();
|
|
16658
|
+
for (const e of edges) {
|
|
16659
|
+
for (const to of resolveImportToFiles(e.to, defFiles, filesByBasename)) {
|
|
16660
|
+
if (to === e.from)
|
|
16661
|
+
continue;
|
|
16662
|
+
const set = adj.get(e.from) ?? /* @__PURE__ */ new Set();
|
|
16663
|
+
set.add(to);
|
|
16664
|
+
adj.set(e.from, set);
|
|
16665
|
+
}
|
|
16666
|
+
}
|
|
16667
|
+
const index = /* @__PURE__ */ new Map();
|
|
16668
|
+
const low = /* @__PURE__ */ new Map();
|
|
16669
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
16670
|
+
const stack = [];
|
|
16671
|
+
const sccs = [];
|
|
16672
|
+
let idx = 0;
|
|
16673
|
+
const allNodes = /* @__PURE__ */ new Set([...adj.keys()]);
|
|
16674
|
+
for (const set of adj.values())
|
|
16675
|
+
for (const t of set)
|
|
16676
|
+
allNodes.add(t);
|
|
16677
|
+
for (const start of allNodes) {
|
|
16678
|
+
if (index.has(start))
|
|
16679
|
+
continue;
|
|
16680
|
+
const work = [];
|
|
16681
|
+
const pushNode = (v) => {
|
|
16682
|
+
index.set(v, idx);
|
|
16683
|
+
low.set(v, idx);
|
|
16684
|
+
idx++;
|
|
16685
|
+
stack.push(v);
|
|
16686
|
+
onStack.add(v);
|
|
16687
|
+
work.push({ v, it: (adj.get(v) ?? /* @__PURE__ */ new Set()).values() });
|
|
16688
|
+
};
|
|
16689
|
+
pushNode(start);
|
|
16690
|
+
while (work.length > 0) {
|
|
16691
|
+
const frame = work[work.length - 1];
|
|
16692
|
+
const next = frame.it.next();
|
|
16693
|
+
if (!next.done) {
|
|
16694
|
+
const w = next.value;
|
|
16695
|
+
if (!index.has(w)) {
|
|
16696
|
+
pushNode(w);
|
|
16697
|
+
} else if (onStack.has(w)) {
|
|
16698
|
+
low.set(frame.v, Math.min(low.get(frame.v), index.get(w)));
|
|
16699
|
+
}
|
|
16700
|
+
} else {
|
|
16701
|
+
if (low.get(frame.v) === index.get(frame.v)) {
|
|
16702
|
+
const comp = [];
|
|
16703
|
+
let w;
|
|
16704
|
+
do {
|
|
16705
|
+
w = stack.pop();
|
|
16706
|
+
onStack.delete(w);
|
|
16707
|
+
comp.push(w);
|
|
16708
|
+
} while (w !== frame.v);
|
|
16709
|
+
if (comp.length > 1)
|
|
16710
|
+
sccs.push(comp);
|
|
16711
|
+
}
|
|
16712
|
+
work.pop();
|
|
16713
|
+
const parent = work[work.length - 1];
|
|
16714
|
+
if (parent)
|
|
16715
|
+
low.set(parent.v, Math.min(low.get(parent.v), low.get(frame.v)));
|
|
16716
|
+
}
|
|
16717
|
+
}
|
|
16718
|
+
}
|
|
16719
|
+
return sccs.sort((a, b) => b.length - a.length);
|
|
16720
|
+
}
|
|
16655
16721
|
function loadGraphFromPath(path) {
|
|
16656
16722
|
try {
|
|
16657
16723
|
if (!existsSync11(path))
|
|
@@ -16667,11 +16733,12 @@ var CG_SUBCOMMAND_HELP = {
|
|
|
16667
16733
|
search: "musubix cg search <query>\n Find indexed symbols whose name contains <query> (case-insensitive).",
|
|
16668
16734
|
stats: "musubix cg stats\n Summary of the indexed graph: node/edge counts, kind breakdowns, file\n count, and the most-called functions.",
|
|
16669
16735
|
deps: "musubix cg deps [path-fragment]\n List outgoing dependencies (\u2192 #include targets and function calls) per\n file. Call edges are annotated `name() [call]`.",
|
|
16670
|
-
impact: "musubix cg impact <path-fragment> [--direct] [--depth N]\n Reverse reachability: which files are affected if the target changes.\n Splits direct (depth-1) from indirect dependents.\n --direct show only immediate (depth-1) dependents\n --depth N limit transitive expansion to N hops",
|
|
16671
|
-
candidates: "musubix cg candidates [N]\n Rank files by suitability for an isolated rewrite (e.g. to Rust):\n score = (functions + dependents) / (1 + external deps). Test files are\n excluded. N limits the number of rows (default 15).",
|
|
16672
|
-
cycles: "musubix cg cycles [path-fragment] [N]\n Detect circular file dependencies (strongly-connected components of the\n file-level graph with >1 member). N limits the number of cycles shown\n (default 20); a path-fragment restricts to cycles touching those files.",
|
|
16736
|
+
impact: "musubix cg impact <path-fragment> [--direct] [--depth N] [--json]\n Reverse reachability: which files are affected if the target changes.\n Splits direct (depth-1) from indirect dependents.\n --direct show only immediate (depth-1) dependents\n --depth N limit transitive expansion to N hops\n --json machine-readable output (for CI/automation)",
|
|
16737
|
+
candidates: "musubix cg candidates [N] [--json]\n Rank files by suitability for an isolated rewrite (e.g. to Rust):\n score = (functions + dependents) / (1 + external deps). Test files are\n excluded. N limits the number of rows (default 15). --json for automation.",
|
|
16738
|
+
cycles: "musubix cg cycles [path-fragment] [N] [--json]\n Detect circular file dependencies (strongly-connected components of the\n file-level graph with >1 member). N limits the number of cycles shown\n (default 20); a path-fragment restricts to cycles touching those files.\n --json for machine-readable output.",
|
|
16673
16739
|
export: "musubix cg export [path-fragment] [--format dot|json] [--out <file>]\n Export the file-level dependency graph (symbol edges resolved to\n file \u2192 file). Default format dot (Graphviz), or json. Writes to <file>\n with --out, else stdout. A path-fragment limits it to a subgraph.",
|
|
16674
|
-
|
|
16740
|
+
gate: "musubix cg gate [--max-cycles N] [--forbid A:B[,C:D]] [--json]\n CI quality gate: check architectural rules against the current graph and\n exit non-zero on any violation.\n --max-cycles N fail if dependency cycles exceed N\n --forbid A:B fail if any file matching 'A' depends on one matching 'B'\n (comma-separate multiple rules); --json for automation",
|
|
16741
|
+
diff: "musubix cg diff <baseline.json> [current.json] [--json]\n Compare two persisted graphs (.musubix/codegraph.json format) and report\n files and file-level dependency edges added/removed. current defaults to\n the working graph .musubix/codegraph.json. Useful for change-impact review.\n --json for machine-readable output.",
|
|
16675
16742
|
languages: "musubix cg languages\n List the source languages the parser supports."
|
|
16676
16743
|
};
|
|
16677
16744
|
function cgSubcommandHelp(sub) {
|
|
@@ -16898,6 +16965,19 @@ async function handleCodegraph(sub, args) {
|
|
|
16898
16965
|
cands.push({ file, fns, deps, users, score });
|
|
16899
16966
|
}
|
|
16900
16967
|
cands.sort((a, b) => b.score - a.score);
|
|
16968
|
+
if (args.includes("--json")) {
|
|
16969
|
+
console.log(JSON.stringify({
|
|
16970
|
+
total: cands.length,
|
|
16971
|
+
candidates: cands.slice(0, limit).map((c) => ({
|
|
16972
|
+
file: c.file,
|
|
16973
|
+
functions: c.fns,
|
|
16974
|
+
externalDeps: c.deps,
|
|
16975
|
+
dependents: c.users,
|
|
16976
|
+
score: Number(c.score.toFixed(3))
|
|
16977
|
+
}))
|
|
16978
|
+
}, null, 2));
|
|
16979
|
+
return ExitCode.SUCCESS;
|
|
16980
|
+
}
|
|
16901
16981
|
console.log(`Rewrite candidates (top ${Math.min(limit, cands.length)} of ${cands.length}, by self-containment \xD7 usage):`);
|
|
16902
16982
|
console.log(` ${"score".padStart(7)} ${"fns".padStart(4)} ${"deps".padStart(4)} ${"users".padStart(5)} file`);
|
|
16903
16983
|
for (const c of cands.slice(0, limit)) {
|
|
@@ -17001,6 +17081,18 @@ async function handleCodegraph(sub, args) {
|
|
|
17001
17081
|
}
|
|
17002
17082
|
}
|
|
17003
17083
|
const indirect = [...affected].filter((f) => !direct.has(f));
|
|
17084
|
+
if (args.includes("--json")) {
|
|
17085
|
+
console.log(JSON.stringify({
|
|
17086
|
+
filter,
|
|
17087
|
+
depth: Number.isFinite(maxDepth) ? maxDepth : null,
|
|
17088
|
+
seeds,
|
|
17089
|
+
direct: [...direct].sort(),
|
|
17090
|
+
indirect: directOnly ? void 0 : indirect.sort(),
|
|
17091
|
+
total: affected.size,
|
|
17092
|
+
counts: { direct: direct.size, indirect: indirect.length }
|
|
17093
|
+
}, null, 2));
|
|
17094
|
+
return ExitCode.SUCCESS;
|
|
17095
|
+
}
|
|
17004
17096
|
console.log(`Impact of ${seeds.length} file(s) matching '${filter}':`);
|
|
17005
17097
|
for (const s of seeds)
|
|
17006
17098
|
console.log(` \u29BF ${s}`);
|
|
@@ -17043,72 +17135,16 @@ async function handleCodegraph(sub, args) {
|
|
|
17043
17135
|
console.log("No indexed graph. Run `musubix cg index <path>` first.");
|
|
17044
17136
|
return ExitCode.SUCCESS;
|
|
17045
17137
|
}
|
|
17046
|
-
|
|
17047
|
-
const adj = /* @__PURE__ */ new Map();
|
|
17048
|
-
for (const e of edges) {
|
|
17049
|
-
for (const to of resolveImportToFiles(e.to, defFiles, filesByBasename)) {
|
|
17050
|
-
if (to === e.from)
|
|
17051
|
-
continue;
|
|
17052
|
-
const set = adj.get(e.from) ?? /* @__PURE__ */ new Set();
|
|
17053
|
-
set.add(to);
|
|
17054
|
-
adj.set(e.from, set);
|
|
17055
|
-
}
|
|
17056
|
-
}
|
|
17057
|
-
const index = /* @__PURE__ */ new Map();
|
|
17058
|
-
const low = /* @__PURE__ */ new Map();
|
|
17059
|
-
const onStack = /* @__PURE__ */ new Set();
|
|
17060
|
-
const stack = [];
|
|
17061
|
-
const sccs = [];
|
|
17062
|
-
let idx = 0;
|
|
17063
|
-
const allNodes = /* @__PURE__ */ new Set([...adj.keys()]);
|
|
17064
|
-
for (const set of adj.values())
|
|
17065
|
-
for (const t of set)
|
|
17066
|
-
allNodes.add(t);
|
|
17067
|
-
for (const start of allNodes) {
|
|
17068
|
-
if (index.has(start))
|
|
17069
|
-
continue;
|
|
17070
|
-
const work = [];
|
|
17071
|
-
const pushNode = (v) => {
|
|
17072
|
-
index.set(v, idx);
|
|
17073
|
-
low.set(v, idx);
|
|
17074
|
-
idx++;
|
|
17075
|
-
stack.push(v);
|
|
17076
|
-
onStack.add(v);
|
|
17077
|
-
work.push({ v, it: (adj.get(v) ?? /* @__PURE__ */ new Set()).values() });
|
|
17078
|
-
};
|
|
17079
|
-
pushNode(start);
|
|
17080
|
-
while (work.length > 0) {
|
|
17081
|
-
const frame = work[work.length - 1];
|
|
17082
|
-
const next = frame.it.next();
|
|
17083
|
-
if (!next.done) {
|
|
17084
|
-
const w = next.value;
|
|
17085
|
-
if (!index.has(w)) {
|
|
17086
|
-
pushNode(w);
|
|
17087
|
-
} else if (onStack.has(w)) {
|
|
17088
|
-
low.set(frame.v, Math.min(low.get(frame.v), index.get(w)));
|
|
17089
|
-
}
|
|
17090
|
-
} else {
|
|
17091
|
-
if (low.get(frame.v) === index.get(frame.v)) {
|
|
17092
|
-
const comp = [];
|
|
17093
|
-
let w;
|
|
17094
|
-
do {
|
|
17095
|
-
w = stack.pop();
|
|
17096
|
-
onStack.delete(w);
|
|
17097
|
-
comp.push(w);
|
|
17098
|
-
} while (w !== frame.v);
|
|
17099
|
-
if (comp.length > 1)
|
|
17100
|
-
sccs.push(comp);
|
|
17101
|
-
}
|
|
17102
|
-
work.pop();
|
|
17103
|
-
const parent = work[work.length - 1];
|
|
17104
|
-
if (parent)
|
|
17105
|
-
low.set(parent.v, Math.min(low.get(parent.v), low.get(frame.v)));
|
|
17106
|
-
}
|
|
17107
|
-
}
|
|
17108
|
-
}
|
|
17109
|
-
let cycles = sccs.sort((a, b) => b.length - a.length);
|
|
17138
|
+
let cycles = findDependencyCycles(nodes, edges);
|
|
17110
17139
|
if (filter)
|
|
17111
17140
|
cycles = cycles.filter((c) => c.some((f) => f.includes(filter)));
|
|
17141
|
+
if (args.includes("--json")) {
|
|
17142
|
+
console.log(JSON.stringify({
|
|
17143
|
+
count: cycles.length,
|
|
17144
|
+
cycles: cycles.slice(0, limit).map((c) => [...c].sort())
|
|
17145
|
+
}, null, 2));
|
|
17146
|
+
return ExitCode.SUCCESS;
|
|
17147
|
+
}
|
|
17112
17148
|
if (cycles.length === 0) {
|
|
17113
17149
|
console.log(`No circular file dependencies found${filter ? ` matching '${filter}'` : ""}. \u2705`);
|
|
17114
17150
|
return ExitCode.SUCCESS;
|
|
@@ -17127,6 +17163,71 @@ async function handleCodegraph(sub, args) {
|
|
|
17127
17163
|
});
|
|
17128
17164
|
return ExitCode.SUCCESS;
|
|
17129
17165
|
}
|
|
17166
|
+
case "gate": {
|
|
17167
|
+
const asJson = args.includes("--json");
|
|
17168
|
+
let maxCycles = null;
|
|
17169
|
+
const forbidRules = [];
|
|
17170
|
+
for (let i = 0; i < args.length; i++) {
|
|
17171
|
+
const a = args[i];
|
|
17172
|
+
if (a === "--max-cycles") {
|
|
17173
|
+
const v = Number(args[++i]);
|
|
17174
|
+
if (Number.isFinite(v) && v >= 0)
|
|
17175
|
+
maxCycles = Math.floor(v);
|
|
17176
|
+
} else if (a === "--forbid") {
|
|
17177
|
+
for (const spec of (args[++i] ?? "").split(",")) {
|
|
17178
|
+
const [from, to] = spec.split(":");
|
|
17179
|
+
if (from && to)
|
|
17180
|
+
forbidRules.push({ from: from.trim(), to: to.trim() });
|
|
17181
|
+
}
|
|
17182
|
+
}
|
|
17183
|
+
}
|
|
17184
|
+
if (maxCycles === null && forbidRules.length === 0) {
|
|
17185
|
+
console.error("\u274C Usage: musubix cg gate [--max-cycles N] [--forbid A:B[,C:D]] [--json]");
|
|
17186
|
+
return ExitCode.VALIDATION_ERROR;
|
|
17187
|
+
}
|
|
17188
|
+
const { nodes, edges } = loadCodeGraphData();
|
|
17189
|
+
if (nodes.length === 0) {
|
|
17190
|
+
console.log("No indexed graph. Run `musubix cg index <path>` first.");
|
|
17191
|
+
return ExitCode.SUCCESS;
|
|
17192
|
+
}
|
|
17193
|
+
const checks = [];
|
|
17194
|
+
if (maxCycles !== null) {
|
|
17195
|
+
const cycles = findDependencyCycles(nodes, edges);
|
|
17196
|
+
checks.push({
|
|
17197
|
+
rule: `cycles \u2264 ${maxCycles}`,
|
|
17198
|
+
pass: cycles.length <= maxCycles,
|
|
17199
|
+
detail: `${cycles.length} dependency cycle(s)`,
|
|
17200
|
+
offenders: cycles.slice(0, 5).map((c) => `[${c.length}] ${[...c].sort()[0]}, \u2026`)
|
|
17201
|
+
});
|
|
17202
|
+
}
|
|
17203
|
+
if (forbidRules.length > 0) {
|
|
17204
|
+
const rels = [...resolveFileEdges(nodes, edges).values()];
|
|
17205
|
+
for (const rule of forbidRules) {
|
|
17206
|
+
const hits = rels.filter((e) => e.from.includes(rule.from) && e.to.includes(rule.to));
|
|
17207
|
+
checks.push({
|
|
17208
|
+
rule: `forbid ${rule.from} \u2192 ${rule.to}`,
|
|
17209
|
+
pass: hits.length === 0,
|
|
17210
|
+
detail: `${hits.length} forbidden edge(s)`,
|
|
17211
|
+
offenders: hits.slice(0, 10).map((e) => `${e.from} \u2192 ${e.to}`)
|
|
17212
|
+
});
|
|
17213
|
+
}
|
|
17214
|
+
}
|
|
17215
|
+
const failed = checks.filter((c) => !c.pass);
|
|
17216
|
+
if (asJson) {
|
|
17217
|
+
console.log(JSON.stringify({ passed: failed.length === 0, checks }, null, 2));
|
|
17218
|
+
} else {
|
|
17219
|
+
for (const c of checks) {
|
|
17220
|
+
console.log(` ${c.pass ? "\u2705" : "\u274C"} ${c.rule} \u2014 ${c.detail}`);
|
|
17221
|
+
if (!c.pass)
|
|
17222
|
+
for (const o of c.offenders ?? [])
|
|
17223
|
+
console.log(` ${o}`);
|
|
17224
|
+
}
|
|
17225
|
+
console.log(failed.length === 0 ? `
|
|
17226
|
+
\u2705 Gate passed (${checks.length} check(s)).` : `
|
|
17227
|
+
\u274C Gate failed: ${failed.length}/${checks.length} check(s) violated.`);
|
|
17228
|
+
}
|
|
17229
|
+
return failed.length === 0 ? ExitCode.SUCCESS : ExitCode.GENERAL_ERROR;
|
|
17230
|
+
}
|
|
17130
17231
|
case "diff": {
|
|
17131
17232
|
const positional = args.filter((a) => !a.startsWith("--"));
|
|
17132
17233
|
const baselinePath = positional[0];
|
|
@@ -17158,6 +17259,23 @@ async function handleCodegraph(sub, args) {
|
|
|
17158
17259
|
const fmt = (r) => `${r.from} \u2192 ${r.to}${r.kind === "calls" ? " [call]" : ""}`;
|
|
17159
17260
|
const edgesAdded = [...curEdges.entries()].filter(([k]) => !baseEdges.has(k)).map(([, v]) => v);
|
|
17160
17261
|
const edgesRemoved = [...baseEdges.entries()].filter(([k]) => !curEdges.has(k)).map(([, v]) => v);
|
|
17262
|
+
if (args.includes("--json")) {
|
|
17263
|
+
console.log(JSON.stringify({
|
|
17264
|
+
baseline: baselinePath,
|
|
17265
|
+
current: currentPath ?? CODEGRAPH_STATE_FILE,
|
|
17266
|
+
filesAdded,
|
|
17267
|
+
filesRemoved,
|
|
17268
|
+
edgesAdded,
|
|
17269
|
+
edgesRemoved,
|
|
17270
|
+
counts: {
|
|
17271
|
+
filesAdded: filesAdded.length,
|
|
17272
|
+
filesRemoved: filesRemoved.length,
|
|
17273
|
+
edgesAdded: edgesAdded.length,
|
|
17274
|
+
edgesRemoved: edgesRemoved.length
|
|
17275
|
+
}
|
|
17276
|
+
}, null, 2));
|
|
17277
|
+
return ExitCode.SUCCESS;
|
|
17278
|
+
}
|
|
17161
17279
|
const CAP = 25;
|
|
17162
17280
|
const list = (label, items) => {
|
|
17163
17281
|
if (items.length === 0)
|
|
@@ -18580,6 +18698,12 @@ function getDefaultCommands() {
|
|
|
18580
18698
|
positionalArgs.push("--format", String(args["format"]));
|
|
18581
18699
|
if (args["out"] !== void 0)
|
|
18582
18700
|
positionalArgs.push("--out", String(args["out"]));
|
|
18701
|
+
if (args["json"] === true)
|
|
18702
|
+
positionalArgs.push("--json");
|
|
18703
|
+
if (args["max-cycles"] !== void 0)
|
|
18704
|
+
positionalArgs.push("--max-cycles", String(args["max-cycles"]));
|
|
18705
|
+
if (args["forbid"] !== void 0)
|
|
18706
|
+
positionalArgs.push("--forbid", String(args["forbid"]));
|
|
18583
18707
|
return await handleCodegraph(sub, positionalArgs);
|
|
18584
18708
|
}
|
|
18585
18709
|
},
|