@codeledger/selector 0.5.0 → 0.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/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/review-candidates.d.ts +23 -0
- package/dist/review-candidates.d.ts.map +1 -0
- package/dist/review-candidates.js +230 -0
- package/dist/review-candidates.js.map +1 -0
- package/dist/review-coverage.d.ts +33 -0
- package/dist/review-coverage.d.ts.map +1 -0
- package/dist/review-coverage.js +110 -0
- package/dist/review-coverage.js.map +1 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -36,4 +36,7 @@ export { buildKnowledgeBundle, buildKnowledgeTrace } from './knowledge-bundle.js
|
|
|
36
36
|
export type { KnowledgeBundleOptions } from './knowledge-bundle.js';
|
|
37
37
|
export { detectSelectionMode } from './mode-detect.js';
|
|
38
38
|
export type { ModeDetectionInput } from './mode-detect.js';
|
|
39
|
+
export { generateReviewCandidates, splitReviewCandidates } from './review-candidates.js';
|
|
40
|
+
export { computeReviewCoverage, meetsCoverageThreshold, getShallowReads } from './review-coverage.js';
|
|
41
|
+
export type { ReadDepthInput } from './review-coverage.js';
|
|
39
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -28,4 +28,7 @@ export { tokenizeIntent, computeKnowledgeTokenWeights, inferAnchorFolders, gener
|
|
|
28
28
|
export { extractKnowledgeExcerpt } from './knowledge-excerpt.js';
|
|
29
29
|
export { buildKnowledgeBundle, buildKnowledgeTrace } from './knowledge-bundle.js';
|
|
30
30
|
export { detectSelectionMode } from './mode-detect.js';
|
|
31
|
+
// ─── Review Coverage (Sentinel) ──────────────────────────────────────────────
|
|
32
|
+
export { generateReviewCandidates, splitReviewCandidates } from './review-candidates.js';
|
|
33
|
+
export { computeReviewCoverage, meetsCoverageThreshold, getShallowReads } from './review-coverage.js';
|
|
31
34
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAElH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE5G,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACpH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACjH,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEjH,+EAA+E;AAC/E,OAAO,EACL,IAAI,IAAI,UAAU,EAClB,OAAO,IAAI,aAAa,EACxB,YAAY,EACZ,MAAM,IAAI,YAAY,EACtB,UAAU,EACV,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAS3B,+EAA+E;AAC/E,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAElH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE5G,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACpH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACjH,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEjH,+EAA+E;AAC/E,OAAO,EACL,IAAI,IAAI,UAAU,EAClB,OAAO,IAAI,aAAa,EACxB,YAAY,EACZ,MAAM,IAAI,YAAY,EACtB,UAAU,EACV,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAS3B,+EAA+E;AAC/E,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,gFAAgF;AAChF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RepoIndex, DepGraph, ReviewCandidate } from '@codeledger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Generate review-mode candidates from a task prompt.
|
|
4
|
+
*
|
|
5
|
+
* Unlike edit-mode candidates (which predict files-to-edit), review-mode
|
|
6
|
+
* candidates identify files that MUST be read to verify a review task.
|
|
7
|
+
*
|
|
8
|
+
* Heuristics:
|
|
9
|
+
* 1. Extract file paths mentioned in the task prompt (literal path references)
|
|
10
|
+
* 2. Extract package/module names → resolve to entry points
|
|
11
|
+
* 3. For export/API review tasks: identify index.ts and re-export files
|
|
12
|
+
* 4. For feature review tasks: use keyword matching + dependency graph
|
|
13
|
+
* 5. Mark each file as MUST_READ (directly referenced) or SHOULD_READ (inferred)
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateReviewCandidates(task: string, repoIndex: RepoIndex, depGraph: DepGraph): ReviewCandidate[];
|
|
16
|
+
/**
|
|
17
|
+
* Split review candidates into must-read and should-read lists.
|
|
18
|
+
*/
|
|
19
|
+
export declare function splitReviewCandidates(candidates: ReviewCandidate[]): {
|
|
20
|
+
mustRead: string[];
|
|
21
|
+
shouldRead: string[];
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=review-candidates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-candidates.d.ts","sourceRoot":"","sources":["../src/review-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GACjB,eAAe,EAAE,CA0FnB;AAyID;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAAE,GAC5B;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAa9C"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate review-mode candidates from a task prompt.
|
|
3
|
+
*
|
|
4
|
+
* Unlike edit-mode candidates (which predict files-to-edit), review-mode
|
|
5
|
+
* candidates identify files that MUST be read to verify a review task.
|
|
6
|
+
*
|
|
7
|
+
* Heuristics:
|
|
8
|
+
* 1. Extract file paths mentioned in the task prompt (literal path references)
|
|
9
|
+
* 2. Extract package/module names → resolve to entry points
|
|
10
|
+
* 3. For export/API review tasks: identify index.ts and re-export files
|
|
11
|
+
* 4. For feature review tasks: use keyword matching + dependency graph
|
|
12
|
+
* 5. Mark each file as MUST_READ (directly referenced) or SHOULD_READ (inferred)
|
|
13
|
+
*/
|
|
14
|
+
export function generateReviewCandidates(task, repoIndex, depGraph) {
|
|
15
|
+
const candidates = new Map();
|
|
16
|
+
const repoFiles = new Set(repoIndex.files.map((f) => f.path));
|
|
17
|
+
// Stage 1: Extract explicit file path references from the task
|
|
18
|
+
const explicitPaths = extractExplicitPaths(task, repoFiles);
|
|
19
|
+
for (const path of explicitPaths) {
|
|
20
|
+
candidates.set(path, {
|
|
21
|
+
path,
|
|
22
|
+
review_reason: 'explicit_reference',
|
|
23
|
+
requirement: 'must_read',
|
|
24
|
+
relevance: 1.0,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Stage 2: Extract package/module references → resolve entry points
|
|
28
|
+
const packageEntries = resolvePackageEntries(task, repoIndex);
|
|
29
|
+
for (const path of packageEntries) {
|
|
30
|
+
if (!candidates.has(path)) {
|
|
31
|
+
candidates.set(path, {
|
|
32
|
+
path,
|
|
33
|
+
review_reason: 'package_entry',
|
|
34
|
+
requirement: 'must_read',
|
|
35
|
+
relevance: 0.9,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Stage 3: For export/API review tasks, identify export surfaces
|
|
40
|
+
if (isExportReviewTask(task)) {
|
|
41
|
+
const exportSurfaces = findExportSurfaces(repoIndex);
|
|
42
|
+
for (const path of exportSurfaces) {
|
|
43
|
+
if (!candidates.has(path)) {
|
|
44
|
+
candidates.set(path, {
|
|
45
|
+
path,
|
|
46
|
+
review_reason: 'export_surface',
|
|
47
|
+
requirement: 'must_read',
|
|
48
|
+
relevance: 0.85,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Stage 4: Keyword-inferred candidates from task text
|
|
54
|
+
const keywords = extractReviewKeywords(task);
|
|
55
|
+
if (keywords.length > 0) {
|
|
56
|
+
const keywordMatches = matchKeywordsToFiles(keywords, repoIndex);
|
|
57
|
+
for (const { path, relevance } of keywordMatches) {
|
|
58
|
+
if (!candidates.has(path)) {
|
|
59
|
+
const requirement = relevance >= 0.7 ? 'must_read' : 'should_read';
|
|
60
|
+
candidates.set(path, {
|
|
61
|
+
path,
|
|
62
|
+
review_reason: 'keyword_inferred',
|
|
63
|
+
requirement,
|
|
64
|
+
relevance,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Stage 5: Expand must-read files via dependency graph
|
|
70
|
+
const mustReadPaths = [...candidates.entries()]
|
|
71
|
+
.filter(([_, c]) => c.requirement === 'must_read')
|
|
72
|
+
.map(([p]) => p);
|
|
73
|
+
for (const seedPath of mustReadPaths) {
|
|
74
|
+
const deps = depGraph.imports[seedPath];
|
|
75
|
+
if (!deps)
|
|
76
|
+
continue;
|
|
77
|
+
for (const dep of deps) {
|
|
78
|
+
if (!repoFiles.has(dep))
|
|
79
|
+
continue;
|
|
80
|
+
if (!candidates.has(dep)) {
|
|
81
|
+
candidates.set(dep, {
|
|
82
|
+
path: dep,
|
|
83
|
+
review_reason: 'dependency_chain',
|
|
84
|
+
requirement: 'should_read',
|
|
85
|
+
relevance: 0.6,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Sort: must_read first, then by relevance descending
|
|
91
|
+
const result = [...candidates.values()].sort((a, b) => {
|
|
92
|
+
if (a.requirement !== b.requirement) {
|
|
93
|
+
return a.requirement === 'must_read' ? -1 : 1;
|
|
94
|
+
}
|
|
95
|
+
return b.relevance - a.relevance;
|
|
96
|
+
});
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract file paths explicitly mentioned in the task text.
|
|
101
|
+
* Matches patterns like `packages/types/src/index.ts` or `src/foo.js`.
|
|
102
|
+
*/
|
|
103
|
+
function extractExplicitPaths(task, repoFiles) {
|
|
104
|
+
// Match anything that looks like a relative file path
|
|
105
|
+
const pathPattern = /(?:^|\s|["'`(])([a-zA-Z0-9_./\-]+\.[a-zA-Z]{1,6})(?:$|\s|["'`),])/g;
|
|
106
|
+
const found = [];
|
|
107
|
+
let match;
|
|
108
|
+
while ((match = pathPattern.exec(task)) !== null) {
|
|
109
|
+
const candidate = match[1];
|
|
110
|
+
// Check if this path exists in the repo
|
|
111
|
+
if (repoFiles.has(candidate)) {
|
|
112
|
+
found.push(candidate);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return [...new Set(found)];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve package/module names mentioned in the task to their entry points.
|
|
119
|
+
* E.g., "packages/selector" → "packages/selector/src/index.ts"
|
|
120
|
+
*/
|
|
121
|
+
function resolvePackageEntries(task, repoIndex) {
|
|
122
|
+
const dirPattern = /(?:packages|src|lib)\/[a-zA-Z0-9_-]+/g;
|
|
123
|
+
const dirs = [];
|
|
124
|
+
let match;
|
|
125
|
+
while ((match = dirPattern.exec(task)) !== null) {
|
|
126
|
+
dirs.push(match[0]);
|
|
127
|
+
}
|
|
128
|
+
const entries = [];
|
|
129
|
+
for (const dir of dirs) {
|
|
130
|
+
// Look for index files in this directory
|
|
131
|
+
const indexCandidates = [
|
|
132
|
+
`${dir}/src/index.ts`,
|
|
133
|
+
`${dir}/src/index.js`,
|
|
134
|
+
`${dir}/index.ts`,
|
|
135
|
+
`${dir}/index.js`,
|
|
136
|
+
];
|
|
137
|
+
for (const candidate of indexCandidates) {
|
|
138
|
+
const found = repoIndex.files.find((f) => f.path === candidate);
|
|
139
|
+
if (found) {
|
|
140
|
+
entries.push(found.path);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return [...new Set(entries)];
|
|
146
|
+
}
|
|
147
|
+
/** Detect if the task is about reviewing exports, APIs, or public interfaces */
|
|
148
|
+
function isExportReviewTask(task) {
|
|
149
|
+
const lower = task.toLowerCase();
|
|
150
|
+
const exportKeywords = ['export', 'api', 'public interface', 'surface', 'contract', 're-export'];
|
|
151
|
+
return exportKeywords.some((kw) => lower.includes(kw));
|
|
152
|
+
}
|
|
153
|
+
/** Find files that are export surfaces (index.ts, barrel files) */
|
|
154
|
+
function findExportSurfaces(repoIndex) {
|
|
155
|
+
return repoIndex.files
|
|
156
|
+
.filter((f) => {
|
|
157
|
+
const name = f.path.split('/').pop() ?? '';
|
|
158
|
+
return name === 'index.ts' || name === 'index.js';
|
|
159
|
+
})
|
|
160
|
+
.map((f) => f.path);
|
|
161
|
+
}
|
|
162
|
+
/** Extract review-relevant keywords from a task prompt */
|
|
163
|
+
function extractReviewKeywords(task) {
|
|
164
|
+
const stopWords = new Set([
|
|
165
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
166
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
167
|
+
'should', 'may', 'might', 'shall', 'can', 'need', 'must', 'ought',
|
|
168
|
+
'i', 'you', 'he', 'she', 'it', 'we', 'they', 'me', 'him', 'her',
|
|
169
|
+
'us', 'them', 'my', 'your', 'his', 'its', 'our', 'their',
|
|
170
|
+
'this', 'that', 'these', 'those', 'and', 'or', 'but', 'if', 'then',
|
|
171
|
+
'of', 'in', 'on', 'at', 'to', 'for', 'with', 'from', 'by', 'as',
|
|
172
|
+
'into', 'through', 'during', 'before', 'after', 'above', 'below',
|
|
173
|
+
'not', 'no', 'nor', 'so', 'very', 'just', 'all', 'each', 'every',
|
|
174
|
+
'review', 'verify', 'check', 'audit', 'ensure', 'confirm', 'validate',
|
|
175
|
+
]);
|
|
176
|
+
const words = task.toLowerCase().replace(/[^a-z0-9_\-]/g, ' ').split(/\s+/);
|
|
177
|
+
return words
|
|
178
|
+
.filter((w) => w.length >= 3 && !stopWords.has(w))
|
|
179
|
+
.slice(0, 20);
|
|
180
|
+
}
|
|
181
|
+
/** Match keywords to repo files by path and content keyword overlap */
|
|
182
|
+
function matchKeywordsToFiles(keywords, repoIndex) {
|
|
183
|
+
const results = [];
|
|
184
|
+
const keywordSet = new Set(keywords);
|
|
185
|
+
for (const file of repoIndex.files) {
|
|
186
|
+
if (file.is_test)
|
|
187
|
+
continue;
|
|
188
|
+
let score = 0;
|
|
189
|
+
const pathLower = file.path.toLowerCase();
|
|
190
|
+
// Path-based matching
|
|
191
|
+
for (const kw of keywords) {
|
|
192
|
+
if (pathLower.includes(kw)) {
|
|
193
|
+
score += 0.3;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Content keyword matching
|
|
197
|
+
if (file.content_keywords) {
|
|
198
|
+
const contentSet = new Set(file.content_keywords);
|
|
199
|
+
for (const kw of keywordSet) {
|
|
200
|
+
if (contentSet.has(kw)) {
|
|
201
|
+
score += 0.15;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const relevance = Math.min(score, 1.0);
|
|
206
|
+
if (relevance >= 0.15) {
|
|
207
|
+
results.push({ path: file.path, relevance });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Sort by relevance descending
|
|
211
|
+
results.sort((a, b) => b.relevance - a.relevance);
|
|
212
|
+
return results.slice(0, 50);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Split review candidates into must-read and should-read lists.
|
|
216
|
+
*/
|
|
217
|
+
export function splitReviewCandidates(candidates) {
|
|
218
|
+
const mustRead = [];
|
|
219
|
+
const shouldRead = [];
|
|
220
|
+
for (const c of candidates) {
|
|
221
|
+
if (c.requirement === 'must_read') {
|
|
222
|
+
mustRead.push(c.path);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
shouldRead.push(c.path);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return { mustRead, shouldRead };
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=review-candidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-candidates.js","sourceRoot":"","sources":["../src/review-candidates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReviewCoverageReport, FileReadDepth, ISODateTime, RepoIndex } from '@codeledger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Read depth info for a file (from ReadTracker or equivalent).
|
|
4
|
+
* This is the input interface — decoupled from the instrument package.
|
|
5
|
+
*/
|
|
6
|
+
export interface ReadDepthInput {
|
|
7
|
+
path: string;
|
|
8
|
+
total_lines: number;
|
|
9
|
+
lines_read: number;
|
|
10
|
+
read_depth: number;
|
|
11
|
+
first_read_at: ISODateTime;
|
|
12
|
+
read_count: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compute review coverage by comparing the review bundle's required files
|
|
16
|
+
* against the session's actual read data.
|
|
17
|
+
*
|
|
18
|
+
* Three metrics:
|
|
19
|
+
* 1. File Coverage — did the agent open the file at all?
|
|
20
|
+
* 2. Depth-Weighted Coverage — how much of each file was actually read?
|
|
21
|
+
* 3. Temporal Alignment — did reads happen BEFORE claims, or after?
|
|
22
|
+
*/
|
|
23
|
+
export declare function computeReviewCoverage(requiredFiles: string[], readDepths: ReadDepthInput[], readPaths: Set<string>, repoIndex: RepoIndex, firstClaimTs?: ISODateTime): ReviewCoverageReport;
|
|
24
|
+
/**
|
|
25
|
+
* Evaluate whether coverage meets a threshold.
|
|
26
|
+
* Returns true if both file coverage and depth coverage meet their thresholds.
|
|
27
|
+
*/
|
|
28
|
+
export declare function meetsCoverageThreshold(report: ReviewCoverageReport, fileCoverageThreshold: number, depthCoverageThreshold: number): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Get files that were only shallowly read (below a depth threshold).
|
|
31
|
+
*/
|
|
32
|
+
export declare function getShallowReads(report: ReviewCoverageReport, shallowThreshold: number): FileReadDepth[];
|
|
33
|
+
//# sourceMappingURL=review-coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-coverage.d.ts","sourceRoot":"","sources":["../src/review-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EAAE,EACvB,UAAU,EAAE,cAAc,EAAE,EAC5B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,SAAS,EAAE,SAAS,EACpB,YAAY,CAAC,EAAE,WAAW,GACzB,oBAAoB,CA8FtB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,oBAAoB,EAC5B,qBAAqB,EAAE,MAAM,EAC7B,sBAAsB,EAAE,MAAM,GAC7B,OAAO,CAKT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,oBAAoB,EAC5B,gBAAgB,EAAE,MAAM,GACvB,aAAa,EAAE,CAIjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute review coverage by comparing the review bundle's required files
|
|
3
|
+
* against the session's actual read data.
|
|
4
|
+
*
|
|
5
|
+
* Three metrics:
|
|
6
|
+
* 1. File Coverage — did the agent open the file at all?
|
|
7
|
+
* 2. Depth-Weighted Coverage — how much of each file was actually read?
|
|
8
|
+
* 3. Temporal Alignment — did reads happen BEFORE claims, or after?
|
|
9
|
+
*/
|
|
10
|
+
export function computeReviewCoverage(requiredFiles, readDepths, readPaths, repoIndex, firstClaimTs) {
|
|
11
|
+
const requiredSet = new Set(requiredFiles);
|
|
12
|
+
const readPathSet = readPaths;
|
|
13
|
+
// Files actually read (intersection with required)
|
|
14
|
+
const filesRead = [];
|
|
15
|
+
const filesSkipped = [];
|
|
16
|
+
for (const rf of requiredFiles) {
|
|
17
|
+
if (readPathSet.has(rf)) {
|
|
18
|
+
filesRead.push(rf);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
filesSkipped.push(rf);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// File-level coverage
|
|
25
|
+
const fileCoverage = requiredFiles.length > 0
|
|
26
|
+
? filesRead.length / requiredFiles.length
|
|
27
|
+
: 1.0;
|
|
28
|
+
// Build file depth entries for required files
|
|
29
|
+
const depthMap = new Map();
|
|
30
|
+
for (const d of readDepths) {
|
|
31
|
+
depthMap.set(d.path, d);
|
|
32
|
+
}
|
|
33
|
+
// Build FileReadDepth entries for all required files (including unread ones)
|
|
34
|
+
const fileDepths = [];
|
|
35
|
+
const repoFileMap = new Map();
|
|
36
|
+
for (const f of repoIndex.files) {
|
|
37
|
+
repoFileMap.set(f.path, f.lines);
|
|
38
|
+
}
|
|
39
|
+
for (const rf of requiredFiles) {
|
|
40
|
+
const depthInfo = depthMap.get(rf);
|
|
41
|
+
if (depthInfo) {
|
|
42
|
+
fileDepths.push({
|
|
43
|
+
path: depthInfo.path,
|
|
44
|
+
total_lines: depthInfo.total_lines,
|
|
45
|
+
lines_read: depthInfo.lines_read,
|
|
46
|
+
read_depth: depthInfo.read_depth,
|
|
47
|
+
first_read_at: depthInfo.first_read_at,
|
|
48
|
+
read_count: depthInfo.read_count,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Unread file
|
|
53
|
+
const totalLines = repoFileMap.get(rf) ?? 0;
|
|
54
|
+
fileDepths.push({
|
|
55
|
+
path: rf,
|
|
56
|
+
total_lines: totalLines,
|
|
57
|
+
lines_read: 0,
|
|
58
|
+
read_depth: 0,
|
|
59
|
+
first_read_at: '',
|
|
60
|
+
read_count: 0,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Depth-weighted coverage: average read_depth across required files
|
|
65
|
+
let depthSum = 0;
|
|
66
|
+
for (const fd of fileDepths) {
|
|
67
|
+
depthSum += fd.read_depth;
|
|
68
|
+
}
|
|
69
|
+
const depthWeightedCoverage = requiredFiles.length > 0
|
|
70
|
+
? depthSum / requiredFiles.length
|
|
71
|
+
: 1.0;
|
|
72
|
+
// Post-hoc reads: files first read AFTER the first claim timestamp
|
|
73
|
+
let postHocReads = [];
|
|
74
|
+
if (firstClaimTs) {
|
|
75
|
+
for (const fd of fileDepths) {
|
|
76
|
+
if (fd.read_count > 0 &&
|
|
77
|
+
fd.first_read_at &&
|
|
78
|
+
fd.first_read_at > firstClaimTs &&
|
|
79
|
+
requiredSet.has(fd.path)) {
|
|
80
|
+
postHocReads.push(fd.path);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
postHocReads.sort();
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
required_files: requiredFiles,
|
|
87
|
+
files_read: filesRead,
|
|
88
|
+
files_skipped: filesSkipped,
|
|
89
|
+
file_coverage: fileCoverage,
|
|
90
|
+
depth_weighted_coverage: depthWeightedCoverage,
|
|
91
|
+
file_depths: fileDepths,
|
|
92
|
+
post_hoc_reads: postHocReads,
|
|
93
|
+
analyzed_at: new Date().toISOString(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Evaluate whether coverage meets a threshold.
|
|
98
|
+
* Returns true if both file coverage and depth coverage meet their thresholds.
|
|
99
|
+
*/
|
|
100
|
+
export function meetsCoverageThreshold(report, fileCoverageThreshold, depthCoverageThreshold) {
|
|
101
|
+
return (report.file_coverage >= fileCoverageThreshold &&
|
|
102
|
+
report.depth_weighted_coverage >= depthCoverageThreshold);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get files that were only shallowly read (below a depth threshold).
|
|
106
|
+
*/
|
|
107
|
+
export function getShallowReads(report, shallowThreshold) {
|
|
108
|
+
return report.file_depths.filter((fd) => fd.read_count > 0 && fd.read_depth < shallowThreshold);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=review-coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-coverage.js","sourceRoot":"","sources":["../src/review-coverage.ts"],"names":[],"mappings":"AAoBA;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,aAAuB,EACvB,UAA4B,EAC5B,SAAsB,EACtB,SAAoB,EACpB,YAA0B;IAE1B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,SAAS,CAAC;IAE9B,mDAAmD;IACnD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;QAC/B,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM;QACzC,CAAC,CAAC,GAAG,CAAC;IAER,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,6EAA6E;IAC7E,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QAChC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,WAAW,EAAE,SAAS,CAAC,WAAW;gBAClC,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,aAAa,EAAE,SAAS,CAAC,aAAa;gBACtC,UAAU,EAAE,SAAS,CAAC,UAAU;aACjC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,cAAc;YACd,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC5C,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,EAAE;gBACR,WAAW,EAAE,UAAU;gBACvB,UAAU,EAAE,CAAC;gBACb,UAAU,EAAE,CAAC;gBACb,aAAa,EAAE,EAAiB;gBAChC,UAAU,EAAE,CAAC;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC;IAC5B,CAAC;IACD,MAAM,qBAAqB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC;QACpD,CAAC,CAAC,QAAQ,GAAG,aAAa,CAAC,MAAM;QACjC,CAAC,CAAC,GAAG,CAAC;IAER,mEAAmE;IACnE,IAAI,YAAY,GAAa,EAAE,CAAC;IAChC,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IACE,EAAE,CAAC,UAAU,GAAG,CAAC;gBACjB,EAAE,CAAC,aAAa;gBAChB,EAAE,CAAC,aAAa,GAAG,YAAY;gBAC/B,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EACxB,CAAC;gBACD,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,YAAY,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,OAAO;QACL,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,SAAS;QACrB,aAAa,EAAE,YAAY;QAC3B,aAAa,EAAE,YAAY;QAC3B,uBAAuB,EAAE,qBAAqB;QAC9C,WAAW,EAAE,UAAU;QACvB,cAAc,EAAE,YAAY;QAC5B,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAiB;KACrD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAA4B,EAC5B,qBAA6B,EAC7B,sBAA8B;IAE9B,OAAO,CACL,MAAM,CAAC,aAAa,IAAI,qBAAqB;QAC7C,MAAM,CAAC,uBAAuB,IAAI,sBAAsB,CACzD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA4B,EAC5B,gBAAwB;IAExB,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAC9B,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,GAAG,gBAAgB,CAC9D,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeledger/selector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Deterministic context selection algorithm for CodeLedger",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/codeledgerECF/codeledger-blackbox.git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@codeledger/types": "0.
|
|
27
|
+
"@codeledger/types": "0.6.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"typescript": "^5.4.0"
|