@codeledger/cli 0.6.2 → 0.6.4
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/commands/activate.d.ts.map +1 -1
- package/dist/commands/activate.js +3 -1
- package/dist/commands/activate.js.map +1 -1
- package/dist/commands/refine.d.ts.map +1 -1
- package/dist/commands/refine.js +2 -1
- package/dist/commands/refine.js.map +1 -1
- package/dist/commands/session-summary.js +27 -10
- package/dist/commands/session-summary.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +78 -2
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/policy/schema.d.ts.map +1 -1
- package/dist/policy/schema.js +1 -0
- package/dist/policy/schema.js.map +1 -1
- package/dist/review-intelligence/companion-check.d.ts +28 -0
- package/dist/review-intelligence/companion-check.d.ts.map +1 -0
- package/dist/review-intelligence/companion-check.js +71 -0
- package/dist/review-intelligence/companion-check.js.map +1 -0
- package/dist/review-intelligence/detectors/outbound-io.d.ts +14 -0
- package/dist/review-intelligence/detectors/outbound-io.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/outbound-io.js +122 -0
- package/dist/review-intelligence/detectors/outbound-io.js.map +1 -0
- package/dist/review-intelligence/detectors/platform-helpers.d.ts +15 -0
- package/dist/review-intelligence/detectors/platform-helpers.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/platform-helpers.js +171 -0
- package/dist/review-intelligence/detectors/platform-helpers.js.map +1 -0
- package/dist/review-intelligence/detectors/runtime-validation.d.ts +10 -0
- package/dist/review-intelligence/detectors/runtime-validation.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/runtime-validation.js +109 -0
- package/dist/review-intelligence/detectors/runtime-validation.js.map +1 -0
- package/dist/review-intelligence/index.d.ts +17 -0
- package/dist/review-intelligence/index.d.ts.map +1 -0
- package/dist/review-intelligence/index.js +90 -0
- package/dist/review-intelligence/index.js.map +1 -0
- package/dist/review-intelligence/invariants.d.ts +10 -0
- package/dist/review-intelligence/invariants.d.ts.map +1 -0
- package/dist/review-intelligence/invariants.js +29 -0
- package/dist/review-intelligence/invariants.js.map +1 -0
- package/dist/review-intelligence/output.d.ts +25 -0
- package/dist/review-intelligence/output.d.ts.map +1 -0
- package/dist/review-intelligence/output.js +116 -0
- package/dist/review-intelligence/output.js.map +1 -0
- package/dist/review-intelligence/repair-guidance.d.ts +11 -0
- package/dist/review-intelligence/repair-guidance.d.ts.map +1 -0
- package/dist/review-intelligence/repair-guidance.js +91 -0
- package/dist/review-intelligence/repair-guidance.js.map +1 -0
- package/dist/review-intelligence/severity.d.ts +10 -0
- package/dist/review-intelligence/severity.d.ts.map +1 -0
- package/dist/review-intelligence/severity.js +36 -0
- package/dist/review-intelligence/severity.js.map +1 -0
- package/dist/review-intelligence/standards-discovery.d.ts +12 -0
- package/dist/review-intelligence/standards-discovery.d.ts.map +1 -0
- package/dist/review-intelligence/standards-discovery.js +221 -0
- package/dist/review-intelligence/standards-discovery.js.map +1 -0
- package/dist/review-intelligence/triggers.d.ts +15 -0
- package/dist/review-intelligence/triggers.d.ts.map +1 -0
- package/dist/review-intelligence/triggers.js +104 -0
- package/dist/review-intelligence/triggers.js.map +1 -0
- package/dist/review-intelligence/types.d.ts +137 -0
- package/dist/review-intelligence/types.d.ts.map +1 -0
- package/dist/review-intelligence/types.js +3 -0
- package/dist/review-intelligence/types.js.map +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, extname } from 'node:path';
|
|
3
|
+
/** Maximum files to scan during discovery */
|
|
4
|
+
const MAX_DISCOVERY_FILES = 200;
|
|
5
|
+
/** Minimum import/usage count to qualify as a "standard" */
|
|
6
|
+
const MIN_USAGE_COUNT = 2;
|
|
7
|
+
/**
|
|
8
|
+
* Discover repository-standard helpers, wrappers, and patterns
|
|
9
|
+
* by analyzing import frequency and repeated usage patterns.
|
|
10
|
+
*
|
|
11
|
+
* Uses lightweight heuristics:
|
|
12
|
+
* - import frequency analysis
|
|
13
|
+
* - repeated wrapper/helper name detection
|
|
14
|
+
* - callsite clustering in utility/helper directories
|
|
15
|
+
*/
|
|
16
|
+
export function discoverRepoStandards(cwd, changedFiles) {
|
|
17
|
+
const standards = [];
|
|
18
|
+
// Collect analyzable files from common helper/utility directories
|
|
19
|
+
const helperDirs = findHelperDirectories(cwd);
|
|
20
|
+
const helperFiles = collectHelperFiles(cwd, helperDirs);
|
|
21
|
+
// Also scan the changed files and their siblings
|
|
22
|
+
const relevantFiles = new Set();
|
|
23
|
+
for (const f of changedFiles) {
|
|
24
|
+
relevantFiles.add(f);
|
|
25
|
+
}
|
|
26
|
+
for (const f of helperFiles) {
|
|
27
|
+
relevantFiles.add(f);
|
|
28
|
+
}
|
|
29
|
+
// Analyze exports from helper files to identify standard patterns
|
|
30
|
+
const exportedHelpers = analyzeHelperExports(cwd, helperFiles);
|
|
31
|
+
// Count usage of these helpers across the codebase
|
|
32
|
+
const usageCounts = countHelperUsage(cwd, exportedHelpers, relevantFiles);
|
|
33
|
+
// Build standards from sufficiently-used helpers
|
|
34
|
+
for (const [helperName, info] of usageCounts.entries()) {
|
|
35
|
+
if (info.count >= MIN_USAGE_COUNT) {
|
|
36
|
+
standards.push({
|
|
37
|
+
helper_name: helperName,
|
|
38
|
+
example_paths: info.definedIn,
|
|
39
|
+
recommendation: `Use ${helperName} from ${info.definedIn[0] ?? 'shared helpers'}`,
|
|
40
|
+
usage_count: info.count,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return standards;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Find directories likely to contain shared helpers/utilities.
|
|
48
|
+
*/
|
|
49
|
+
function findHelperDirectories(cwd) {
|
|
50
|
+
const candidates = [
|
|
51
|
+
'src/utils',
|
|
52
|
+
'src/helpers',
|
|
53
|
+
'src/lib',
|
|
54
|
+
'src/shared',
|
|
55
|
+
'src/common',
|
|
56
|
+
'lib',
|
|
57
|
+
'utils',
|
|
58
|
+
'helpers',
|
|
59
|
+
'shared',
|
|
60
|
+
'common',
|
|
61
|
+
];
|
|
62
|
+
const found = [];
|
|
63
|
+
// Also check packages/*/src/{utils,helpers,lib,shared,common}
|
|
64
|
+
const packagesDir = join(cwd, 'packages');
|
|
65
|
+
if (existsSync(packagesDir)) {
|
|
66
|
+
try {
|
|
67
|
+
const pkgs = readdirSync(packagesDir);
|
|
68
|
+
for (const pkg of pkgs) {
|
|
69
|
+
const pkgDir = join('packages', pkg);
|
|
70
|
+
for (const sub of ['src/utils', 'src/helpers', 'src/lib', 'src/shared', 'src/common', 'utils', 'helpers', 'lib']) {
|
|
71
|
+
candidates.push(join(pkgDir, sub));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Skip if can't read packages dir
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const candidate of candidates) {
|
|
80
|
+
const fullPath = join(cwd, candidate);
|
|
81
|
+
if (existsSync(fullPath)) {
|
|
82
|
+
try {
|
|
83
|
+
const stat = statSync(fullPath);
|
|
84
|
+
if (stat.isDirectory()) {
|
|
85
|
+
found.push(candidate);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Skip inaccessible directories
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return found;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Collect TypeScript/JavaScript files from helper directories.
|
|
97
|
+
*/
|
|
98
|
+
function collectHelperFiles(cwd, dirs) {
|
|
99
|
+
const files = [];
|
|
100
|
+
const analyzableExts = new Set(['.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs']);
|
|
101
|
+
for (const dir of dirs) {
|
|
102
|
+
const fullDir = join(cwd, dir);
|
|
103
|
+
try {
|
|
104
|
+
const entries = readdirSync(fullDir);
|
|
105
|
+
for (const entry of entries) {
|
|
106
|
+
if (files.length >= MAX_DISCOVERY_FILES)
|
|
107
|
+
break;
|
|
108
|
+
const ext = extname(entry);
|
|
109
|
+
if (analyzableExts.has(ext) && !entry.endsWith('.test.ts') && !entry.endsWith('.spec.ts')) {
|
|
110
|
+
files.push(join(dir, entry));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Skip unreadable directories
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return files;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Analyze helper files for exported functions/classes that look like
|
|
122
|
+
* shared utilities.
|
|
123
|
+
*/
|
|
124
|
+
function analyzeHelperExports(cwd, helperFiles) {
|
|
125
|
+
const helpers = [];
|
|
126
|
+
for (const filePath of helperFiles) {
|
|
127
|
+
const fullPath = join(cwd, filePath);
|
|
128
|
+
let content;
|
|
129
|
+
try {
|
|
130
|
+
content = readFileSync(fullPath, 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// Find exported function/const/class names
|
|
136
|
+
const exportPattern = /export\s+(?:async\s+)?(?:function|const|class)\s+(\w+)/g;
|
|
137
|
+
let match;
|
|
138
|
+
while ((match = exportPattern.exec(content)) !== null) {
|
|
139
|
+
const name = match[1];
|
|
140
|
+
const category = categorizeHelper(name, content);
|
|
141
|
+
helpers.push({ name, filePath, category });
|
|
142
|
+
}
|
|
143
|
+
// Also find export { name } patterns
|
|
144
|
+
const reExportPattern = /export\s*\{([^}]+)\}/g;
|
|
145
|
+
while ((match = reExportPattern.exec(content)) !== null) {
|
|
146
|
+
const names = match[1].split(',').map((n) => n.trim().split(/\s+as\s+/)[0].trim());
|
|
147
|
+
for (const name of names) {
|
|
148
|
+
if (name && /^[a-zA-Z_]/.test(name)) {
|
|
149
|
+
const category = categorizeHelper(name, content);
|
|
150
|
+
helpers.push({ name, filePath, category });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return helpers;
|
|
156
|
+
}
|
|
157
|
+
function categorizeHelper(name, content) {
|
|
158
|
+
const lower = name.toLowerCase();
|
|
159
|
+
if (lower.includes('fetch') || lower.includes('http') || lower.includes('request') || lower.includes('api')) {
|
|
160
|
+
return 'fetch';
|
|
161
|
+
}
|
|
162
|
+
if (lower.includes('error') || lower.includes('response') || lower.includes('reply')) {
|
|
163
|
+
return 'error';
|
|
164
|
+
}
|
|
165
|
+
if (lower.includes('cache') || lower.includes('redis') || lower.includes('key')) {
|
|
166
|
+
return 'cache';
|
|
167
|
+
}
|
|
168
|
+
if (lower.includes('valid') || lower.includes('schema') || lower.includes('parse')) {
|
|
169
|
+
return 'validation';
|
|
170
|
+
}
|
|
171
|
+
if (lower.includes('rate') || lower.includes('limit') || lower.includes('throttle')) {
|
|
172
|
+
return 'rate_limit';
|
|
173
|
+
}
|
|
174
|
+
// Also check content context
|
|
175
|
+
if (/fetch|axios|http\.request/.test(content))
|
|
176
|
+
return 'fetch';
|
|
177
|
+
if (/redis|cache/.test(content))
|
|
178
|
+
return 'cache';
|
|
179
|
+
return 'general';
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Count how many files import or reference each discovered helper.
|
|
183
|
+
*/
|
|
184
|
+
function countHelperUsage(cwd, helpers, filesToScan) {
|
|
185
|
+
const usage = new Map();
|
|
186
|
+
// Initialize with helper definitions
|
|
187
|
+
for (const helper of helpers) {
|
|
188
|
+
const existing = usage.get(helper.name);
|
|
189
|
+
if (existing) {
|
|
190
|
+
if (!existing.definedIn.includes(helper.filePath)) {
|
|
191
|
+
existing.definedIn.push(helper.filePath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
usage.set(helper.name, { count: 0, definedIn: [helper.filePath] });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Count imports/usage across scanned files
|
|
199
|
+
for (const filePath of filesToScan) {
|
|
200
|
+
const fullPath = join(cwd, filePath);
|
|
201
|
+
let content;
|
|
202
|
+
try {
|
|
203
|
+
content = readFileSync(fullPath, 'utf-8');
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
for (const helper of helpers) {
|
|
209
|
+
// Skip counting usage in the file where it's defined
|
|
210
|
+
if (filePath === helper.filePath)
|
|
211
|
+
continue;
|
|
212
|
+
// Check for import or direct usage
|
|
213
|
+
if (content.includes(helper.name)) {
|
|
214
|
+
const info = usage.get(helper.name);
|
|
215
|
+
info.count++;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return usage;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=standards-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standards-discovery.js","sourceRoot":"","sources":["../../src/review-intelligence/standards-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DetectedTrigger } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scan file content for trigger patterns. Returns all detected triggers
|
|
4
|
+
* with file path, line number, and matched text.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectTriggers(filePath: string, content: string): DetectedTrigger[];
|
|
7
|
+
/**
|
|
8
|
+
* Check if triggers indicate typed route definitions (Body/Params/Querystring).
|
|
9
|
+
*/
|
|
10
|
+
export declare function isTypedRouteTrigger(trigger: DetectedTrigger): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Check if triggers indicate outbound I/O.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isOutboundIOTrigger(trigger: DetectedTrigger): boolean;
|
|
15
|
+
//# sourceMappingURL=triggers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,YAAY,CAAC;AA8D/D;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,eAAe,EAAE,CAkCnB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAMrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAMrE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const TRIGGER_PATTERNS = [
|
|
2
|
+
// Fastify route definitions
|
|
3
|
+
{
|
|
4
|
+
type: 'fastify_route',
|
|
5
|
+
pattern: /\b(?:server|app|fastify|instance)\s*\.\s*(?:get|post|put|patch|delete|head|options|all|route)\s*[<(]/,
|
|
6
|
+
},
|
|
7
|
+
// Typed route body
|
|
8
|
+
{
|
|
9
|
+
type: 'typed_route_body',
|
|
10
|
+
pattern: /[<{]\s*(?:Body|body)\s*:/,
|
|
11
|
+
},
|
|
12
|
+
// Typed route params
|
|
13
|
+
{
|
|
14
|
+
type: 'typed_route_params',
|
|
15
|
+
pattern: /[<{]\s*(?:Params|params)\s*:/,
|
|
16
|
+
},
|
|
17
|
+
// Typed route query
|
|
18
|
+
{
|
|
19
|
+
type: 'typed_route_query',
|
|
20
|
+
pattern: /[<{]\s*(?:Querystring|querystring|Query|query)\s*:/,
|
|
21
|
+
},
|
|
22
|
+
// fetch() calls
|
|
23
|
+
{
|
|
24
|
+
type: 'fetch_call',
|
|
25
|
+
pattern: /\bfetch\s*\(/,
|
|
26
|
+
},
|
|
27
|
+
// axios calls
|
|
28
|
+
{
|
|
29
|
+
type: 'axios_call',
|
|
30
|
+
pattern: /\baxios\s*(?:\.\s*(?:get|post|put|patch|delete|head|options|request))?\s*\(/,
|
|
31
|
+
},
|
|
32
|
+
// http.request / https.request
|
|
33
|
+
{
|
|
34
|
+
type: 'http_request',
|
|
35
|
+
pattern: /\b(?:https?)\s*\.\s*(?:request|get)\s*\(/,
|
|
36
|
+
},
|
|
37
|
+
// Raw error responses (reply.status(...).send / res.status(...).send / res.status(...).json)
|
|
38
|
+
{
|
|
39
|
+
type: 'raw_error_response',
|
|
40
|
+
pattern: /\b(?:reply|res|response)\s*\.\s*(?:status|code)\s*\(\s*(?:4\d{2}|5\d{2})\s*\)/,
|
|
41
|
+
},
|
|
42
|
+
// Redis/cache key construction
|
|
43
|
+
{
|
|
44
|
+
type: 'redis_cache_key',
|
|
45
|
+
pattern: /\b(?:redis|cache|client)\s*\.\s*(?:get|set|del|hget|hset|sadd|srem|zadd|zrem|expire|ttl)\s*\(\s*[`'"]/,
|
|
46
|
+
},
|
|
47
|
+
// Circuit breaker
|
|
48
|
+
{
|
|
49
|
+
type: 'circuit_breaker',
|
|
50
|
+
pattern: /\b(?:circuitBreaker|circuit_breaker|breaker)\s*\.\s*(?:fire|execute|run|call)\s*\(/,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* Scan file content for trigger patterns. Returns all detected triggers
|
|
55
|
+
* with file path, line number, and matched text.
|
|
56
|
+
*/
|
|
57
|
+
export function detectTriggers(filePath, content) {
|
|
58
|
+
const triggers = [];
|
|
59
|
+
const lines = content.split('\n');
|
|
60
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61
|
+
const line = lines[i];
|
|
62
|
+
// Skip comments and import lines
|
|
63
|
+
const trimmed = line.trim();
|
|
64
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (trimmed.startsWith('import ') || trimmed.startsWith('import{')) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
for (const tp of TRIGGER_PATTERNS) {
|
|
71
|
+
const match = tp.pattern.exec(line);
|
|
72
|
+
if (match) {
|
|
73
|
+
// Skip if it's a type import or type definition
|
|
74
|
+
if (/\btype\b/.test(line) && !line.includes('('))
|
|
75
|
+
continue;
|
|
76
|
+
triggers.push({
|
|
77
|
+
type: tp.type,
|
|
78
|
+
file: filePath,
|
|
79
|
+
line: i + 1,
|
|
80
|
+
matched_text: match[0],
|
|
81
|
+
context: trimmed.length > 120 ? trimmed.slice(0, 120) + '...' : trimmed,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return triggers;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if triggers indicate typed route definitions (Body/Params/Querystring).
|
|
90
|
+
*/
|
|
91
|
+
export function isTypedRouteTrigger(trigger) {
|
|
92
|
+
return (trigger.type === 'typed_route_body' ||
|
|
93
|
+
trigger.type === 'typed_route_params' ||
|
|
94
|
+
trigger.type === 'typed_route_query');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if triggers indicate outbound I/O.
|
|
98
|
+
*/
|
|
99
|
+
export function isOutboundIOTrigger(trigger) {
|
|
100
|
+
return (trigger.type === 'fetch_call' ||
|
|
101
|
+
trigger.type === 'axios_call' ||
|
|
102
|
+
trigger.type === 'http_request');
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.js","sourceRoot":"","sources":["../../src/review-intelligence/triggers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/** Severity levels for review intelligence findings */
|
|
2
|
+
export type ReviewSeverity = 'P0' | 'P1' | 'P2' | 'P3';
|
|
3
|
+
/** Categories of review intelligence findings */
|
|
4
|
+
export type FindingCategory = 'runtime_validation' | 'outbound_io' | 'platform_helpers';
|
|
5
|
+
/** Confidence level of a finding */
|
|
6
|
+
export type FindingConfidence = 'high' | 'medium' | 'low';
|
|
7
|
+
/** A trigger detected in source code */
|
|
8
|
+
export interface DetectedTrigger {
|
|
9
|
+
/** Type of trigger pattern found */
|
|
10
|
+
type: TriggerType;
|
|
11
|
+
/** File where trigger was found */
|
|
12
|
+
file: string;
|
|
13
|
+
/** Line number (1-based) */
|
|
14
|
+
line: number;
|
|
15
|
+
/** The matched source text */
|
|
16
|
+
matched_text: string;
|
|
17
|
+
/** Additional context about the trigger */
|
|
18
|
+
context?: string;
|
|
19
|
+
}
|
|
20
|
+
export type TriggerType = 'fastify_route' | 'typed_route_body' | 'typed_route_params' | 'typed_route_query' | 'fetch_call' | 'axios_call' | 'http_request' | 'raw_error_response' | 'redis_cache_key' | 'circuit_breaker';
|
|
21
|
+
/** A companion safeguard expected alongside a trigger */
|
|
22
|
+
export interface ExpectedCompanion {
|
|
23
|
+
/** What kind of companion is expected */
|
|
24
|
+
type: CompanionType;
|
|
25
|
+
/** Human-readable description of what is expected */
|
|
26
|
+
description: string;
|
|
27
|
+
/** Whether the companion was found */
|
|
28
|
+
found: boolean;
|
|
29
|
+
/** Where the companion was found, if present */
|
|
30
|
+
evidence?: string;
|
|
31
|
+
}
|
|
32
|
+
export type CompanionType = 'zod_validation' | 'ajv_validation' | 'fastify_schema' | 'abort_controller' | 'timeout_config' | 'sanctioned_wrapper' | 'shared_error_helper' | 'shared_cache_helper' | 'shared_middleware';
|
|
33
|
+
/** A discovered repository standard (helper, wrapper, pattern) */
|
|
34
|
+
export interface RepoStandard {
|
|
35
|
+
/** Name of the helper/wrapper/pattern */
|
|
36
|
+
helper_name: string;
|
|
37
|
+
/** File paths where this standard is defined or commonly used */
|
|
38
|
+
example_paths: string[];
|
|
39
|
+
/** Short recommendation text */
|
|
40
|
+
recommendation: string;
|
|
41
|
+
/** How many times this pattern is used in the repo */
|
|
42
|
+
usage_count: number;
|
|
43
|
+
}
|
|
44
|
+
/** A review intelligence finding */
|
|
45
|
+
export interface ReviewFinding {
|
|
46
|
+
/** Unique rule identifier */
|
|
47
|
+
rule_id: string;
|
|
48
|
+
/** Human-readable title */
|
|
49
|
+
title: string;
|
|
50
|
+
/** Severity level */
|
|
51
|
+
severity: ReviewSeverity;
|
|
52
|
+
/** Finding category */
|
|
53
|
+
category: FindingCategory;
|
|
54
|
+
/** File where the issue was found */
|
|
55
|
+
file: string;
|
|
56
|
+
/** Line number (1-based) */
|
|
57
|
+
line: number;
|
|
58
|
+
/** What triggered the finding */
|
|
59
|
+
trigger: string;
|
|
60
|
+
/** Missing companion safeguards */
|
|
61
|
+
missing_companions: string[];
|
|
62
|
+
/** Why this matters */
|
|
63
|
+
why_it_matters: string;
|
|
64
|
+
/** Repository standard that should be used, if discovered */
|
|
65
|
+
repo_standard?: RepoStandard;
|
|
66
|
+
/** Confidence level */
|
|
67
|
+
confidence: FindingConfidence;
|
|
68
|
+
}
|
|
69
|
+
/** Configuration for an individual invariant module */
|
|
70
|
+
export interface InvariantConfig {
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** Policy configuration for Review Intelligence */
|
|
74
|
+
export interface ReviewIntelligencePolicy {
|
|
75
|
+
enabled: boolean;
|
|
76
|
+
severity_threshold: ReviewSeverity;
|
|
77
|
+
invariants: {
|
|
78
|
+
runtime_validation: InvariantConfig;
|
|
79
|
+
outbound_io: InvariantConfig;
|
|
80
|
+
platform_helpers: InvariantConfig;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** Result of running the review intelligence engine */
|
|
84
|
+
export interface ReviewIntelligenceResult {
|
|
85
|
+
/** All findings, sorted by severity then file */
|
|
86
|
+
findings: ReviewFinding[];
|
|
87
|
+
/** Discovered repo standards */
|
|
88
|
+
repo_standards: RepoStandard[];
|
|
89
|
+
/** Summary counts by severity */
|
|
90
|
+
summary: {
|
|
91
|
+
p0: number;
|
|
92
|
+
p1: number;
|
|
93
|
+
p2: number;
|
|
94
|
+
p3: number;
|
|
95
|
+
total: number;
|
|
96
|
+
};
|
|
97
|
+
/** Overall status */
|
|
98
|
+
status: 'PASS' | 'WARN' | 'FAIL';
|
|
99
|
+
/** Duration in milliseconds */
|
|
100
|
+
duration_ms: number;
|
|
101
|
+
}
|
|
102
|
+
/** Options for running the review intelligence engine */
|
|
103
|
+
export interface ReviewIntelligenceOptions {
|
|
104
|
+
/** Root directory of the repository */
|
|
105
|
+
cwd: string;
|
|
106
|
+
/** Files to analyze (changed/relevant files) */
|
|
107
|
+
files: string[];
|
|
108
|
+
/** Policy configuration */
|
|
109
|
+
policy: ReviewIntelligencePolicy;
|
|
110
|
+
/** Whether to include verbose reasoning */
|
|
111
|
+
explain: boolean;
|
|
112
|
+
/** Whether to include debug details */
|
|
113
|
+
debug: boolean;
|
|
114
|
+
/** Narrow to specific invariant module */
|
|
115
|
+
invariant?: string;
|
|
116
|
+
}
|
|
117
|
+
/** Interface that detector modules implement */
|
|
118
|
+
export interface InvariantDetector {
|
|
119
|
+
/** Unique module name */
|
|
120
|
+
name: FindingCategory;
|
|
121
|
+
/** Detect triggers and check invariants for a set of files */
|
|
122
|
+
analyze(ctx: DetectorContext): ReviewFinding[];
|
|
123
|
+
}
|
|
124
|
+
/** Context passed to each detector */
|
|
125
|
+
export interface DetectorContext {
|
|
126
|
+
/** Root directory of the repository */
|
|
127
|
+
cwd: string;
|
|
128
|
+
/** Files to analyze (paths relative to cwd) */
|
|
129
|
+
files: string[];
|
|
130
|
+
/** File contents map (path → content) */
|
|
131
|
+
fileContents: Map<string, string>;
|
|
132
|
+
/** Discovered repo standards */
|
|
133
|
+
repoStandards: RepoStandard[];
|
|
134
|
+
/** Whether to include verbose reasoning */
|
|
135
|
+
explain: boolean;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/review-intelligence/types.ts"],"names":[],"mappings":"AAAA,+EAA+E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeledger/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for CodeLedger — deterministic context selection for AI coding agents",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@codeledger/types": "0.6.
|
|
31
|
-
"@codeledger/core": "0.6.
|
|
32
|
-
"@codeledger/core-engine": "0.6.
|
|
33
|
-
"@codeledger/repo": "0.6.
|
|
34
|
-
"@codeledger/instrument": "0.6.
|
|
35
|
-
"@codeledger/
|
|
36
|
-
"@codeledger/
|
|
37
|
-
"@codeledger/
|
|
30
|
+
"@codeledger/types": "0.6.4",
|
|
31
|
+
"@codeledger/core": "0.6.4",
|
|
32
|
+
"@codeledger/core-engine": "0.6.4",
|
|
33
|
+
"@codeledger/repo": "0.6.4",
|
|
34
|
+
"@codeledger/instrument": "0.6.4",
|
|
35
|
+
"@codeledger/cowork": "0.6.4",
|
|
36
|
+
"@codeledger/selector": "0.6.4",
|
|
37
|
+
"@codeledger/harness": "0.6.4"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"typescript": "^5.4.0"
|