@optave/codegraph 2.5.1 → 2.6.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/README.md +119 -49
- package/package.json +8 -7
- package/src/audit.js +423 -0
- package/src/batch.js +90 -0
- package/src/boundaries.js +346 -0
- package/src/builder.js +66 -2
- package/src/check.js +432 -0
- package/src/cli.js +361 -6
- package/src/cochange.js +5 -2
- package/src/communities.js +7 -1
- package/src/complexity.js +116 -9
- package/src/config.js +10 -0
- package/src/embedder.js +350 -38
- package/src/flow.js +4 -4
- package/src/index.js +28 -1
- package/src/manifesto.js +69 -1
- package/src/mcp.js +347 -19
- package/src/owners.js +359 -0
- package/src/paginate.js +35 -0
- package/src/queries.js +233 -19
- package/src/snapshot.js +149 -0
- package/src/structure.js +5 -2
- package/src/triage.js +273 -0
package/src/index.js
CHANGED
|
@@ -5,10 +5,18 @@
|
|
|
5
5
|
* import { buildGraph, queryNameData, findCycles, exportDOT } from 'codegraph';
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
// Audit (composite report)
|
|
9
|
+
export { audit, auditData } from './audit.js';
|
|
10
|
+
// Batch querying
|
|
11
|
+
export { BATCH_COMMANDS, batch, batchData } from './batch.js';
|
|
12
|
+
// Architecture boundary rules
|
|
13
|
+
export { evaluateBoundaries, PRESETS, validateBoundaryConfig } from './boundaries.js';
|
|
8
14
|
// Branch comparison
|
|
9
15
|
export { branchCompareData, branchCompareMermaid } from './branch-compare.js';
|
|
10
16
|
// Graph building
|
|
11
17
|
export { buildGraph, collectFiles, loadPathAliases, resolveImportPath } from './builder.js';
|
|
18
|
+
// Check (CI validation predicates)
|
|
19
|
+
export { check, checkData } from './check.js';
|
|
12
20
|
// Co-change analysis
|
|
13
21
|
export {
|
|
14
22
|
analyzeCoChanges,
|
|
@@ -30,6 +38,7 @@ export {
|
|
|
30
38
|
computeLOCMetrics,
|
|
31
39
|
computeMaintainabilityIndex,
|
|
32
40
|
HALSTEAD_RULES,
|
|
41
|
+
iterComplexity,
|
|
33
42
|
} from './complexity.js';
|
|
34
43
|
// Configuration
|
|
35
44
|
export { loadConfig } from './config.js';
|
|
@@ -55,6 +64,8 @@ export {
|
|
|
55
64
|
EMBEDDING_STRATEGIES,
|
|
56
65
|
embed,
|
|
57
66
|
estimateTokens,
|
|
67
|
+
ftsSearchData,
|
|
68
|
+
hybridSearchData,
|
|
58
69
|
MODELS,
|
|
59
70
|
multiSearchData,
|
|
60
71
|
search,
|
|
@@ -70,8 +81,10 @@ export { setVerbose } from './logger.js';
|
|
|
70
81
|
export { manifesto, manifestoData, RULE_DEFS } from './manifesto.js';
|
|
71
82
|
// Native engine
|
|
72
83
|
export { isNativeAvailable } from './native.js';
|
|
84
|
+
// Ownership (CODEOWNERS)
|
|
85
|
+
export { matchOwners, owners, ownersData, ownersForFiles, parseCodeowners } from './owners.js';
|
|
73
86
|
// Pagination utilities
|
|
74
|
-
export { MCP_DEFAULTS, MCP_MAX_LIMIT, paginate, paginateResult } from './paginate.js';
|
|
87
|
+
export { MCP_DEFAULTS, MCP_MAX_LIMIT, paginate, paginateResult, printNdjson } from './paginate.js';
|
|
75
88
|
|
|
76
89
|
// Unified parser API
|
|
77
90
|
export { getActiveEngine, parseFileAuto, parseFilesAuto } from './parser.js';
|
|
@@ -88,6 +101,9 @@ export {
|
|
|
88
101
|
fnDepsData,
|
|
89
102
|
fnImpactData,
|
|
90
103
|
impactAnalysisData,
|
|
104
|
+
iterListFunctions,
|
|
105
|
+
iterRoles,
|
|
106
|
+
iterWhere,
|
|
91
107
|
kindIcon,
|
|
92
108
|
moduleMapData,
|
|
93
109
|
pathData,
|
|
@@ -108,6 +124,15 @@ export {
|
|
|
108
124
|
saveRegistry,
|
|
109
125
|
unregisterRepo,
|
|
110
126
|
} from './registry.js';
|
|
127
|
+
// Snapshot management
|
|
128
|
+
export {
|
|
129
|
+
snapshotDelete,
|
|
130
|
+
snapshotList,
|
|
131
|
+
snapshotRestore,
|
|
132
|
+
snapshotSave,
|
|
133
|
+
snapshotsDir,
|
|
134
|
+
validateSnapshotName,
|
|
135
|
+
} from './snapshot.js';
|
|
111
136
|
// Structure analysis
|
|
112
137
|
export {
|
|
113
138
|
buildStructure,
|
|
@@ -120,5 +145,7 @@ export {
|
|
|
120
145
|
moduleBoundariesData,
|
|
121
146
|
structureData,
|
|
122
147
|
} from './structure.js';
|
|
148
|
+
// Triage — composite risk audit
|
|
149
|
+
export { triage, triageData } from './triage.js';
|
|
123
150
|
// Watch mode
|
|
124
151
|
export { watchProject } from './watcher.js';
|
package/src/manifesto.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { evaluateBoundaries } from './boundaries.js';
|
|
1
2
|
import { loadConfig } from './config.js';
|
|
2
3
|
import { findCycles } from './cycles.js';
|
|
3
4
|
import { openReadonlyOrFail } from './db.js';
|
|
4
5
|
import { debug } from './logger.js';
|
|
6
|
+
import { paginateResult, printNdjson } from './paginate.js';
|
|
5
7
|
|
|
6
8
|
// ─── Rule Definitions ─────────────────────────────────────────────────
|
|
7
9
|
|
|
@@ -54,6 +56,12 @@ export const RULE_DEFS = [
|
|
|
54
56
|
{ name: 'fanIn', level: 'file', metric: 'fan_in', defaults: { warn: null, fail: null } },
|
|
55
57
|
{ name: 'fanOut', level: 'file', metric: 'fan_out', defaults: { warn: null, fail: null } },
|
|
56
58
|
{ name: 'noCycles', level: 'graph', metric: 'noCycles', defaults: { warn: null, fail: null } },
|
|
59
|
+
{
|
|
60
|
+
name: 'boundaries',
|
|
61
|
+
level: 'graph',
|
|
62
|
+
metric: 'boundaries',
|
|
63
|
+
defaults: { warn: null, fail: null },
|
|
64
|
+
},
|
|
57
65
|
];
|
|
58
66
|
|
|
59
67
|
// ─── Helpers ──────────────────────────────────────────────────────────
|
|
@@ -318,6 +326,59 @@ function evaluateGraphRules(db, rules, opts, violations, ruleResults) {
|
|
|
318
326
|
});
|
|
319
327
|
}
|
|
320
328
|
|
|
329
|
+
function evaluateBoundaryRules(db, rules, config, opts, violations, ruleResults) {
|
|
330
|
+
const thresholds = rules.boundaries;
|
|
331
|
+
const boundaryConfig = config.manifesto?.boundaries;
|
|
332
|
+
|
|
333
|
+
// Auto-enable at warn level when boundary config exists but threshold not set
|
|
334
|
+
const effectiveThresholds = { ...thresholds };
|
|
335
|
+
if (boundaryConfig && !isEnabled(thresholds)) {
|
|
336
|
+
effectiveThresholds.warn = true;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (!isEnabled(effectiveThresholds) || !boundaryConfig) {
|
|
340
|
+
ruleResults.push({
|
|
341
|
+
name: 'boundaries',
|
|
342
|
+
level: 'graph',
|
|
343
|
+
status: 'pass',
|
|
344
|
+
thresholds: effectiveThresholds,
|
|
345
|
+
violationCount: 0,
|
|
346
|
+
});
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const result = evaluateBoundaries(db, boundaryConfig, { noTests: opts.noTests || false });
|
|
351
|
+
const hasBoundaryViolations = result.violationCount > 0;
|
|
352
|
+
|
|
353
|
+
if (!hasBoundaryViolations) {
|
|
354
|
+
ruleResults.push({
|
|
355
|
+
name: 'boundaries',
|
|
356
|
+
level: 'graph',
|
|
357
|
+
status: 'pass',
|
|
358
|
+
thresholds: effectiveThresholds,
|
|
359
|
+
violationCount: 0,
|
|
360
|
+
});
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const level = effectiveThresholds.fail != null ? 'fail' : 'warn';
|
|
365
|
+
|
|
366
|
+
for (const v of result.violations) {
|
|
367
|
+
violations.push({
|
|
368
|
+
...v,
|
|
369
|
+
level,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
ruleResults.push({
|
|
374
|
+
name: 'boundaries',
|
|
375
|
+
level: 'graph',
|
|
376
|
+
status: level,
|
|
377
|
+
thresholds: effectiveThresholds,
|
|
378
|
+
violationCount: result.violationCount,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
321
382
|
// ─── Public API ───────────────────────────────────────────────────────
|
|
322
383
|
|
|
323
384
|
/**
|
|
@@ -343,6 +404,7 @@ export function manifestoData(customDbPath, opts = {}) {
|
|
|
343
404
|
evaluateFunctionRules(db, rules, opts, violations, ruleResults);
|
|
344
405
|
evaluateFileRules(db, rules, opts, violations, ruleResults);
|
|
345
406
|
evaluateGraphRules(db, rules, opts, violations, ruleResults);
|
|
407
|
+
evaluateBoundaryRules(db, rules, config, opts, violations, ruleResults);
|
|
346
408
|
|
|
347
409
|
const failViolations = violations.filter((v) => v.level === 'fail');
|
|
348
410
|
|
|
@@ -354,12 +416,13 @@ export function manifestoData(customDbPath, opts = {}) {
|
|
|
354
416
|
violationCount: violations.length,
|
|
355
417
|
};
|
|
356
418
|
|
|
357
|
-
|
|
419
|
+
const base = {
|
|
358
420
|
rules: ruleResults,
|
|
359
421
|
violations,
|
|
360
422
|
summary,
|
|
361
423
|
passed: failViolations.length === 0,
|
|
362
424
|
};
|
|
425
|
+
return paginateResult(base, 'violations', { limit: opts.limit, offset: opts.offset });
|
|
363
426
|
} finally {
|
|
364
427
|
db.close();
|
|
365
428
|
}
|
|
@@ -371,6 +434,11 @@ export function manifestoData(customDbPath, opts = {}) {
|
|
|
371
434
|
export function manifesto(customDbPath, opts = {}) {
|
|
372
435
|
const data = manifestoData(customDbPath, opts);
|
|
373
436
|
|
|
437
|
+
if (opts.ndjson) {
|
|
438
|
+
printNdjson(data, 'violations');
|
|
439
|
+
if (!data.passed) process.exit(1);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
374
442
|
if (opts.json) {
|
|
375
443
|
console.log(JSON.stringify(data, null, 2));
|
|
376
444
|
if (!data.passed) process.exit(1);
|