@codeledger/cli 0.6.8 → 0.6.9

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.
Files changed (83) hide show
  1. package/dist/commands/activate.d.ts.map +1 -1
  2. package/dist/commands/activate.js +16 -1
  3. package/dist/commands/activate.js.map +1 -1
  4. package/dist/commands/commit-msg.d.ts +58 -0
  5. package/dist/commands/commit-msg.d.ts.map +1 -0
  6. package/dist/commands/commit-msg.js +461 -0
  7. package/dist/commands/commit-msg.js.map +1 -0
  8. package/dist/commands/init.d.ts.map +1 -1
  9. package/dist/commands/init.js +14 -0
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/intent.d.ts +3 -1
  12. package/dist/commands/intent.d.ts.map +1 -1
  13. package/dist/commands/intent.js +68 -2
  14. package/dist/commands/intent.js.map +1 -1
  15. package/dist/commands/pr-summary.d.ts +59 -0
  16. package/dist/commands/pr-summary.d.ts.map +1 -0
  17. package/dist/commands/pr-summary.js +524 -0
  18. package/dist/commands/pr-summary.js.map +1 -0
  19. package/dist/commands/session-cleanup.js +1 -0
  20. package/dist/commands/session-cleanup.js.map +1 -1
  21. package/dist/commands/session-summary.d.ts.map +1 -1
  22. package/dist/commands/session-summary.js +135 -3
  23. package/dist/commands/session-summary.js.map +1 -1
  24. package/dist/commands/setup-ci.d.ts.map +1 -1
  25. package/dist/commands/setup-ci.js +12 -0
  26. package/dist/commands/setup-ci.js.map +1 -1
  27. package/dist/commands/verify.d.ts.map +1 -1
  28. package/dist/commands/verify.js +35 -3
  29. package/dist/commands/verify.js.map +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +45 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/intent/extractor.d.ts +15 -0
  34. package/dist/intent/extractor.d.ts.map +1 -0
  35. package/dist/intent/extractor.js +149 -0
  36. package/dist/intent/extractor.js.map +1 -0
  37. package/dist/intent/fetcher.d.ts +33 -0
  38. package/dist/intent/fetcher.d.ts.map +1 -0
  39. package/dist/intent/fetcher.js +364 -0
  40. package/dist/intent/fetcher.js.map +1 -0
  41. package/dist/intent/loader.d.ts +26 -0
  42. package/dist/intent/loader.d.ts.map +1 -0
  43. package/dist/intent/loader.js +80 -0
  44. package/dist/intent/loader.js.map +1 -0
  45. package/dist/intent/types.d.ts +33 -0
  46. package/dist/intent/types.d.ts.map +1 -0
  47. package/dist/intent/types.js +9 -0
  48. package/dist/intent/types.js.map +1 -0
  49. package/dist/project-config.d.ts +38 -0
  50. package/dist/project-config.d.ts.map +1 -0
  51. package/dist/project-config.js +206 -0
  52. package/dist/project-config.js.map +1 -0
  53. package/dist/review-intelligence/detectors/architecture-graph.d.ts +18 -0
  54. package/dist/review-intelligence/detectors/architecture-graph.d.ts.map +1 -0
  55. package/dist/review-intelligence/detectors/architecture-graph.js +73 -0
  56. package/dist/review-intelligence/detectors/architecture-graph.js.map +1 -0
  57. package/dist/review-intelligence/detectors/pack-rules.d.ts +16 -0
  58. package/dist/review-intelligence/detectors/pack-rules.d.ts.map +1 -0
  59. package/dist/review-intelligence/detectors/pack-rules.js +107 -0
  60. package/dist/review-intelligence/detectors/pack-rules.js.map +1 -0
  61. package/dist/review-intelligence/fixes/index.d.ts +18 -0
  62. package/dist/review-intelligence/fixes/index.d.ts.map +1 -1
  63. package/dist/review-intelligence/fixes/index.js +198 -9
  64. package/dist/review-intelligence/fixes/index.js.map +1 -1
  65. package/dist/review-intelligence/index.d.ts +4 -1
  66. package/dist/review-intelligence/index.d.ts.map +1 -1
  67. package/dist/review-intelligence/index.js +20 -3
  68. package/dist/review-intelligence/index.js.map +1 -1
  69. package/dist/review-intelligence/invariants.d.ts +15 -0
  70. package/dist/review-intelligence/invariants.d.ts.map +1 -1
  71. package/dist/review-intelligence/invariants.js +36 -5
  72. package/dist/review-intelligence/invariants.js.map +1 -1
  73. package/dist/review-intelligence/types.d.ts +16 -12
  74. package/dist/review-intelligence/types.d.ts.map +1 -1
  75. package/dist/review-intelligence/types.js +9 -1
  76. package/dist/review-intelligence/types.js.map +1 -1
  77. package/dist/templates/claude-md.d.ts.map +1 -1
  78. package/dist/templates/claude-md.js +23 -128
  79. package/dist/templates/claude-md.js.map +1 -1
  80. package/dist/templates/hooks.d.ts.map +1 -1
  81. package/dist/templates/hooks.js +39 -0
  82. package/dist/templates/hooks.js.map +1 -1
  83. package/package.json +9 -9
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Project-level configuration loader for .codeledger.yml
3
+ *
4
+ * Reads optional project config from repo root (.codeledger.yml) that controls
5
+ * commit-msg, pr-summary, and PR review bot defaults. This is separate from
6
+ * the core .codeledger/config.json which handles scoring, selection, and harness.
7
+ *
8
+ * Uses a minimal YAML parser (no dependency) — supports only the flat/nested
9
+ * key-value structure documented in sample.codeledger.yml.
10
+ */
11
+ import { existsSync, readFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ const DEFAULT_CONFIG = {
14
+ pr: {
15
+ base_branch: 'main',
16
+ comment_enabled: true,
17
+ sections: [
18
+ 'summary', 'why', 'business_impact', 'key_changes',
19
+ 'subsystems_touched', 'risk_signals', 'verify_findings',
20
+ 'reviewer_focus', 'testing', 'stats',
21
+ ],
22
+ },
23
+ verify: {
24
+ mode: 'warn',
25
+ severity_threshold: 'P1',
26
+ review_intelligence: {
27
+ enabled: true,
28
+ invariants: {
29
+ runtime_validation: true,
30
+ outbound_io: true,
31
+ platform_helpers: true,
32
+ build_runtime: true,
33
+ test_integrity: true,
34
+ },
35
+ },
36
+ },
37
+ commit_msg: {
38
+ signature: false,
39
+ format: 'full',
40
+ },
41
+ intent: {
42
+ tracker_prefix: '',
43
+ },
44
+ };
45
+ // ── Minimal YAML parser ──────────────────────────────────────────────────────
46
+ // Handles the subset of YAML used in .codeledger.yml: scalars, simple lists,
47
+ // and nested objects (2-space indent). No anchors, aliases, flow style, or
48
+ // multi-line strings.
49
+ function parseSimpleYaml(text) {
50
+ const result = {};
51
+ const lines = text.split('\n');
52
+ const stack = [
53
+ { indent: -1, obj: result },
54
+ ];
55
+ for (const rawLine of lines) {
56
+ // Skip comments and blank lines
57
+ const commentIdx = rawLine.indexOf('#');
58
+ const line = commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine;
59
+ if (line.trim() === '')
60
+ continue;
61
+ const indent = line.length - line.trimStart().length;
62
+ const trimmed = line.trim();
63
+ // List item: "- value"
64
+ if (trimmed.startsWith('- ')) {
65
+ const value = parseScalar(trimmed.slice(2).trim());
66
+ // Find the parent at this indent level — pop entries at deeper or equal indent
67
+ while (stack.length > 1 && (stack[stack.length - 1]?.indent ?? -1) >= indent) {
68
+ stack.pop();
69
+ }
70
+ let parent = stack[stack.length - 1]?.obj ?? result;
71
+ // If we landed on an empty object created by "key:" syntax, go one level
72
+ // up and convert the key from an empty object to an array.
73
+ if (Object.keys(parent).length === 0 && stack.length > 1) {
74
+ stack.pop();
75
+ const grandparent = stack[stack.length - 1]?.obj ?? result;
76
+ const gpKeys = Object.keys(grandparent);
77
+ const gpLastKey = gpKeys[gpKeys.length - 1];
78
+ if (gpLastKey !== undefined) {
79
+ grandparent[gpLastKey] = [value];
80
+ }
81
+ continue;
82
+ }
83
+ // Find the last key in the parent to attach the list item
84
+ const keys = Object.keys(parent);
85
+ const lastKey = keys[keys.length - 1];
86
+ if (lastKey !== undefined) {
87
+ if (!Array.isArray(parent[lastKey])) {
88
+ parent[lastKey] = [];
89
+ }
90
+ parent[lastKey].push(value);
91
+ }
92
+ continue;
93
+ }
94
+ // Key-value pair: "key: value" or "key:" (nested object)
95
+ const colonIdx = trimmed.indexOf(':');
96
+ if (colonIdx < 0)
97
+ continue;
98
+ const key = trimmed.slice(0, colonIdx).trim();
99
+ const rawValue = trimmed.slice(colonIdx + 1).trim();
100
+ // Pop stack to find the right parent
101
+ while (stack.length > 1 && (stack[stack.length - 1]?.indent ?? -1) >= indent) {
102
+ stack.pop();
103
+ }
104
+ const parent = stack[stack.length - 1]?.obj ?? result;
105
+ if (rawValue === '') {
106
+ // Nested object — key with no value
107
+ const nested = {};
108
+ parent[key] = nested;
109
+ stack.push({ indent, obj: nested });
110
+ }
111
+ else {
112
+ parent[key] = parseScalar(rawValue);
113
+ }
114
+ }
115
+ return result;
116
+ }
117
+ function parseScalar(value) {
118
+ if (value === 'true')
119
+ return true;
120
+ if (value === 'false')
121
+ return false;
122
+ if (value === 'null' || value === '~')
123
+ return '';
124
+ // Quoted strings
125
+ if ((value.startsWith('"') && value.endsWith('"')) ||
126
+ (value.startsWith("'") && value.endsWith("'"))) {
127
+ return value.slice(1, -1);
128
+ }
129
+ // Numbers
130
+ const num = Number(value);
131
+ if (!isNaN(num) && value !== '')
132
+ return num;
133
+ return value;
134
+ }
135
+ // ── Loader ───────────────────────────────────────────────────────────────────
136
+ /**
137
+ * Load project config from .codeledger.yml in the given directory.
138
+ * Returns defaults if the file doesn't exist or fails to parse.
139
+ */
140
+ export function loadProjectConfig(cwd) {
141
+ const filePath = join(cwd, '.codeledger.yml');
142
+ if (!existsSync(filePath)) {
143
+ return { ...DEFAULT_CONFIG };
144
+ }
145
+ try {
146
+ const raw = readFileSync(filePath, 'utf-8');
147
+ const parsed = parseSimpleYaml(raw);
148
+ return mergeConfig(DEFAULT_CONFIG, parsed);
149
+ }
150
+ catch {
151
+ // Non-fatal — fall back to defaults
152
+ return { ...DEFAULT_CONFIG };
153
+ }
154
+ }
155
+ function mergeConfig(defaults, overrides) {
156
+ const result = structuredClone(defaults);
157
+ // pr section
158
+ const pr = overrides['pr'];
159
+ if (pr) {
160
+ if (typeof pr['base_branch'] === 'string')
161
+ result.pr.base_branch = pr['base_branch'];
162
+ if (typeof pr['comment_enabled'] === 'boolean')
163
+ result.pr.comment_enabled = pr['comment_enabled'];
164
+ if (Array.isArray(pr['sections']))
165
+ result.pr.sections = pr['sections'];
166
+ }
167
+ // verify section
168
+ const verify = overrides['verify'];
169
+ if (verify) {
170
+ if (typeof verify['mode'] === 'string' && ['observe', 'warn', 'block'].includes(verify['mode'])) {
171
+ result.verify.mode = verify['mode'];
172
+ }
173
+ if (typeof verify['severity_threshold'] === 'string') {
174
+ result.verify.severity_threshold = verify['severity_threshold'];
175
+ }
176
+ const ri = verify['review_intelligence'];
177
+ if (ri) {
178
+ if (typeof ri['enabled'] === 'boolean')
179
+ result.verify.review_intelligence.enabled = ri['enabled'];
180
+ const invariants = ri['invariants'];
181
+ if (invariants) {
182
+ for (const [k, v] of Object.entries(invariants)) {
183
+ if (typeof v === 'boolean')
184
+ result.verify.review_intelligence.invariants[k] = v;
185
+ }
186
+ }
187
+ }
188
+ }
189
+ // commit_msg section
190
+ const commitMsg = overrides['commit_msg'];
191
+ if (commitMsg) {
192
+ if (typeof commitMsg['signature'] === 'boolean')
193
+ result.commit_msg.signature = commitMsg['signature'];
194
+ if (typeof commitMsg['format'] === 'string' && ['full', 'minimal'].includes(commitMsg['format'])) {
195
+ result.commit_msg.format = commitMsg['format'];
196
+ }
197
+ }
198
+ // intent section
199
+ const intent = overrides['intent'];
200
+ if (intent) {
201
+ if (typeof intent['tracker_prefix'] === 'string')
202
+ result.intent.tracker_prefix = intent['tracker_prefix'];
203
+ }
204
+ return result;
205
+ }
206
+ //# sourceMappingURL=project-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../src/project-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { InvariantDetector } from '../types.js';
2
+ /**
3
+ * INVARIANT — architecture_graph
4
+ *
5
+ * Runs the architecture graph analysis and converts structural violations
6
+ * (circular dependencies, service boundary violations) into ReviewFindings
7
+ * so they appear in `codeledger verify` and CI gate output.
8
+ *
9
+ * This detector is graph-level (not per-file), so it ignores the files list
10
+ * and analyzes the whole repo structure. It caches the graph result per
11
+ * analysis run.
12
+ *
13
+ * Severity:
14
+ * - Circular dependencies: P1
15
+ * - Service boundary violations: P1 or P2 (from graph analysis)
16
+ */
17
+ export declare const architectureGraphDetector: InvariantDetector;
18
+ //# sourceMappingURL=architecture-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture-graph.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/architecture-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,aAAa,CAAC;AAMrB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,EAAE,iBA4DvC,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { buildArchitectureGraph, } from '../../architecture-graph/index.js';
2
+ /**
3
+ * INVARIANT — architecture_graph
4
+ *
5
+ * Runs the architecture graph analysis and converts structural violations
6
+ * (circular dependencies, service boundary violations) into ReviewFindings
7
+ * so they appear in `codeledger verify` and CI gate output.
8
+ *
9
+ * This detector is graph-level (not per-file), so it ignores the files list
10
+ * and analyzes the whole repo structure. It caches the graph result per
11
+ * analysis run.
12
+ *
13
+ * Severity:
14
+ * - Circular dependencies: P1
15
+ * - Service boundary violations: P1 or P2 (from graph analysis)
16
+ */
17
+ export const architectureGraphDetector = {
18
+ name: 'architecture_graph',
19
+ analyze(ctx) {
20
+ const findings = [];
21
+ let graph;
22
+ try {
23
+ graph = buildArchitectureGraph(ctx.cwd);
24
+ }
25
+ catch {
26
+ // Graph build can fail in repos without package structure — skip silently
27
+ return findings;
28
+ }
29
+ // Convert circular dependencies to findings
30
+ for (const cycle of graph.cycles) {
31
+ if (cycle.length < 2)
32
+ continue;
33
+ const cycleStr = cycle.join(' → ');
34
+ findings.push({
35
+ rule_id: 'RI-AG-001',
36
+ title: 'Circular dependency detected',
37
+ severity: 'P1',
38
+ category: 'architecture_graph',
39
+ file: cycle[0],
40
+ line: 0,
41
+ trigger: cycleStr,
42
+ missing_companions: [
43
+ 'Break the cycle by extracting shared types/interfaces into a common package',
44
+ ],
45
+ why_it_matters: `Circular dependency: ${cycleStr}. ` +
46
+ 'Circular package dependencies cause unpredictable initialization order, ' +
47
+ 'make tree-shaking impossible, and often indicate a layering violation.',
48
+ confidence: 'high',
49
+ fixable: false,
50
+ });
51
+ }
52
+ // Convert boundary violations to findings
53
+ for (const violation of graph.boundaryViolations) {
54
+ findings.push({
55
+ rule_id: 'RI-AG-002',
56
+ title: 'Service boundary violation',
57
+ severity: violation.severity,
58
+ category: 'architecture_graph',
59
+ file: violation.sourceService,
60
+ line: 0,
61
+ trigger: `${violation.sourceService} imports ${violation.importPath}`,
62
+ missing_companions: [
63
+ 'Use the public API/events of the target service instead of direct imports',
64
+ ],
65
+ why_it_matters: violation.description,
66
+ confidence: 'high',
67
+ fixable: false,
68
+ });
69
+ }
70
+ return findings;
71
+ },
72
+ };
73
+ //# sourceMappingURL=architecture-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture-graph.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/architecture-graph.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,sBAAsB,GAEvB,MAAM,mCAAmC,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,IAAI,EAAE,oBAAoB;IAE1B,OAAO,CAAC,GAAoB;QAC1B,MAAM,QAAQ,GAAoB,EAAE,CAAC;QAErC,IAAI,KAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,4CAA4C;QAC5C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC;gBACZ,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,8BAA8B;gBACrC,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,oBAAoB;gBAC9B,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE;gBACf,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,QAAQ;gBACjB,kBAAkB,EAAE;oBAClB,6EAA6E;iBAC9E;gBACD,cAAc,EACZ,wBAAwB,QAAQ,IAAI;oBACpC,0EAA0E;oBAC1E,wEAAwE;gBAC1E,UAAU,EAAE,MAAM;gBAClB,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;QACL,CAAC;QAED,0CAA0C;QAC1C,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC;gBACZ,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,4BAA4B;gBACnC,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,oBAAoB;gBAC9B,IAAI,EAAE,SAAS,CAAC,aAAa;gBAC7B,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,GAAG,SAAS,CAAC,aAAa,YAAY,SAAS,CAAC,UAAU,EAAE;gBACrE,kBAAkB,EAAE;oBAClB,2EAA2E;iBAC5E;gBACD,cAAc,EAAE,SAAS,CAAC,WAAW;gBACrC,UAAU,EAAE,MAAM;gBAClB,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { InvariantDetector } from '../types.js';
2
+ import type { PackRule } from '../packs/index.js';
3
+ /**
4
+ * INVARIANT — pack_rules (dynamic)
5
+ *
6
+ * Enforces enabled invariant pack rules. Each PackRule has:
7
+ * - trigger_pattern: regex that matches raw callsites
8
+ * - helper: the sanctioned wrapper/helper name that should be used
9
+ * - kind: required_wrapper | required_helper | forbidden_pattern | required_pattern
10
+ *
11
+ * This detector is parameterized at construction time with the active pack
12
+ * rules. It is NOT registered as a static built-in — instead it is created
13
+ * on-the-fly by the engine when enabled packs have rules.
14
+ */
15
+ export declare function createPackRulesDetector(rules: PackRule[]): InvariantDetector;
16
+ //# sourceMappingURL=pack-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-rules.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/pack-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CA6B5E"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * INVARIANT — pack_rules (dynamic)
3
+ *
4
+ * Enforces enabled invariant pack rules. Each PackRule has:
5
+ * - trigger_pattern: regex that matches raw callsites
6
+ * - helper: the sanctioned wrapper/helper name that should be used
7
+ * - kind: required_wrapper | required_helper | forbidden_pattern | required_pattern
8
+ *
9
+ * This detector is parameterized at construction time with the active pack
10
+ * rules. It is NOT registered as a static built-in — instead it is created
11
+ * on-the-fly by the engine when enabled packs have rules.
12
+ */
13
+ export function createPackRulesDetector(rules) {
14
+ return {
15
+ name: 'pack_rules',
16
+ analyze(ctx) {
17
+ const findings = [];
18
+ if (rules.length === 0)
19
+ return findings;
20
+ for (const filePath of ctx.files) {
21
+ const content = ctx.fileContents.get(filePath);
22
+ if (!content)
23
+ continue;
24
+ if (!isAnalyzableFile(filePath))
25
+ continue;
26
+ const lines = content.split('\n');
27
+ for (const rule of rules) {
28
+ if (rule.kind === 'forbidden_pattern') {
29
+ analyzeForbiddenPattern(rule, filePath, lines, findings);
30
+ }
31
+ else if (rule.kind === 'required_wrapper' || rule.kind === 'required_helper') {
32
+ analyzeRequiredWrapper(rule, filePath, content, lines, findings);
33
+ }
34
+ // required_pattern rules are structural — handled by built-in detectors
35
+ }
36
+ }
37
+ return findings;
38
+ },
39
+ };
40
+ }
41
+ function analyzeForbiddenPattern(rule, filePath, lines, findings) {
42
+ if (!rule.trigger_pattern)
43
+ return;
44
+ const triggerRe = new RegExp(rule.trigger_pattern, 'g');
45
+ for (let i = 0; i < lines.length; i++) {
46
+ const line = lines[i];
47
+ const trimmed = line.trim();
48
+ if (trimmed.startsWith('//') || trimmed.startsWith('*'))
49
+ continue;
50
+ triggerRe.lastIndex = 0;
51
+ if (triggerRe.test(trimmed)) {
52
+ findings.push({
53
+ rule_id: rule.rule_id,
54
+ title: rule.description,
55
+ severity: rule.severity,
56
+ category: 'pack_rules',
57
+ file: filePath,
58
+ line: i + 1,
59
+ trigger: trimmed.slice(0, 80),
60
+ missing_companions: ['Remove or replace the forbidden pattern'],
61
+ why_it_matters: rule.description,
62
+ confidence: 'high',
63
+ fixable: false,
64
+ });
65
+ }
66
+ }
67
+ }
68
+ function analyzeRequiredWrapper(rule, filePath, content, lines, findings) {
69
+ if (!rule.trigger_pattern || !rule.helper)
70
+ return;
71
+ // Check if the file uses the sanctioned helper
72
+ const helperUsed = content.includes(rule.helper);
73
+ if (helperUsed)
74
+ return; // File already uses the helper
75
+ const triggerRe = new RegExp(rule.trigger_pattern, 'g');
76
+ for (let i = 0; i < lines.length; i++) {
77
+ const line = lines[i];
78
+ const trimmed = line.trim();
79
+ if (trimmed.startsWith('//') || trimmed.startsWith('*'))
80
+ continue;
81
+ if (trimmed.startsWith('import '))
82
+ continue;
83
+ triggerRe.lastIndex = 0;
84
+ if (triggerRe.test(trimmed)) {
85
+ findings.push({
86
+ rule_id: rule.rule_id,
87
+ title: rule.description,
88
+ severity: rule.severity,
89
+ category: 'pack_rules',
90
+ file: filePath,
91
+ line: i + 1,
92
+ trigger: trimmed.slice(0, 80),
93
+ missing_companions: [`Use ${rule.helper} instead`],
94
+ why_it_matters: `Repository convention: ${rule.description}. ` +
95
+ `The sanctioned helper \`${rule.helper}\` should be used instead of raw calls.`,
96
+ confidence: 'high',
97
+ fixable: true,
98
+ });
99
+ // Only report first violation per file per rule to avoid noise
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ function isAnalyzableFile(filePath) {
105
+ return /\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
106
+ }
107
+ //# sourceMappingURL=pack-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-rules.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/pack-rules.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,18 @@ export interface FixResult {
12
12
  }
13
13
  /** A fixer function */
14
14
  export type Fixer = (finding: ReviewFinding, content: string) => FixResult | undefined;
15
+ /**
16
+ * Register a fixer for a rule ID. Replaces any existing fixer for that rule.
17
+ */
18
+ export declare function registerFixer(ruleId: string, fixer: Fixer): void;
19
+ /**
20
+ * Remove a registered fixer by rule ID. No-op if not found.
21
+ */
22
+ export declare function unregisterFixer(ruleId: string): void;
23
+ /**
24
+ * Register a fallback fixer that applies to findings matching a predicate.
25
+ */
26
+ export declare function registerFallbackFixer(matches: (f: ReviewFinding) => boolean, fixer: Fixer): void;
15
27
  /**
16
28
  * Check if a finding has an auto-fix available.
17
29
  */
@@ -33,4 +45,10 @@ export declare function applyAllFixes(findings: ReviewFinding[], content: string
33
45
  * Get all fixable rule IDs.
34
46
  */
35
47
  export declare function getFixableRuleIds(): string[];
48
+ /**
49
+ * Stamp `fixable: true` on findings that have a registered fixer
50
+ * (exact match OR fallback). Called by the engine after detectors run,
51
+ * before returning results.
52
+ */
53
+ export declare function annotateFixable(findings: ReviewFinding[]): void;
36
54
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/fixes/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,qCAAqC;AACrC,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,uBAAuB;AACvB,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;AAUvF;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAIvF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,MAAM,GACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,CAiB9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/fixes/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,qCAAqC;AACrC,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,uBAAuB;AACvB,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;AA2BvF;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAEhE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,OAAO,EACtC,KAAK,EAAE,KAAK,GACX,IAAI,CAEN;AAaD;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAIvF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,MAAM,GACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,CAiB9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAM/D"}