pi-harness-runtime 1.1.451 → 1.1.452
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/AGENTS.md +53 -0
- package/CHANGELOG.md +24 -0
- package/index.ts +172 -21
- package/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/dist/continuation-status.d.ts +31 -0
- package/packages/jev-judge/dist/continuation-status.d.ts.map +1 -0
- package/packages/jev-judge/dist/continuation-status.js +40 -0
- package/packages/jev-judge/dist/continuation-status.js.map +1 -0
- package/packages/jev-judge/dist/delegation-harness.d.ts +74 -1
- package/packages/jev-judge/dist/delegation-harness.d.ts.map +1 -1
- package/packages/jev-judge/dist/delegation-harness.js +183 -18
- package/packages/jev-judge/dist/delegation-harness.js.map +1 -1
- package/packages/jev-judge/dist/delegation-scope.d.ts +88 -0
- package/packages/jev-judge/dist/delegation-scope.d.ts.map +1 -0
- package/packages/jev-judge/dist/delegation-scope.js +218 -0
- package/packages/jev-judge/dist/delegation-scope.js.map +1 -0
- package/packages/jev-judge/package.json +1 -1
- package/packages/jev-judge/src/continuation-status.ts +41 -0
- package/packages/jev-judge/src/delegation-harness.ts +254 -45
- package/packages/jev-judge/src/delegation-scope.ts +264 -0
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/tooling-preference/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/two-phase-review/dist/classify.d.ts +22 -1
- package/packages/two-phase-review/dist/classify.d.ts.map +1 -1
- package/packages/two-phase-review/dist/classify.js +37 -1
- package/packages/two-phase-review/dist/classify.js.map +1 -1
- package/packages/two-phase-review/dist/index.d.ts +4 -2
- package/packages/two-phase-review/dist/index.d.ts.map +1 -1
- package/packages/two-phase-review/dist/index.js +3 -2
- package/packages/two-phase-review/dist/index.js.map +1 -1
- package/packages/two-phase-review/dist/rules.d.ts +8 -3
- package/packages/two-phase-review/dist/rules.d.ts.map +1 -1
- package/packages/two-phase-review/dist/rules.js +36 -5
- package/packages/two-phase-review/dist/rules.js.map +1 -1
- package/packages/two-phase-review/dist/runtime.d.ts +9 -0
- package/packages/two-phase-review/dist/runtime.d.ts.map +1 -1
- package/packages/two-phase-review/dist/runtime.js +68 -17
- package/packages/two-phase-review/dist/runtime.js.map +1 -1
- package/packages/two-phase-review/dist/state.d.ts +15 -0
- package/packages/two-phase-review/dist/state.d.ts.map +1 -1
- package/packages/two-phase-review/dist/state.js +37 -2
- package/packages/two-phase-review/dist/state.js.map +1 -1
- package/packages/two-phase-review/dist/types.d.ts +2 -2
- package/packages/two-phase-review/dist/types.d.ts.map +1 -1
- package/packages/two-phase-review/dist/validation.d.ts +50 -0
- package/packages/two-phase-review/dist/validation.d.ts.map +1 -0
- package/packages/two-phase-review/dist/validation.js +54 -0
- package/packages/two-phase-review/dist/validation.js.map +1 -0
- package/packages/two-phase-review/package.json +1 -1
- package/packages/two-phase-review/src/classify.ts +38 -1
- package/packages/two-phase-review/src/index.ts +16 -0
- package/packages/two-phase-review/src/rules.ts +48 -4
- package/packages/two-phase-review/src/runtime.ts +88 -17
- package/packages/two-phase-review/src/state.ts +38 -2
- package/packages/two-phase-review/src/types.ts +2 -1
- package/packages/two-phase-review/src/validation.ts +86 -0
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The measured scope of a task.
|
|
3
|
+
*
|
|
4
|
+
* A delegation decision is only worth something when it is based on the
|
|
5
|
+
* work that really has to be done. The numbers of a request are not a
|
|
6
|
+
* measurement: "refactor everything" says nothing about how many files
|
|
7
|
+
* are affected. This module measures the scope in the workspace:
|
|
8
|
+
*
|
|
9
|
+
* - The files of the workspace that the request actually names.
|
|
10
|
+
* - The files the session has already changed.
|
|
11
|
+
* - The groups those files form (one group per package or directory).
|
|
12
|
+
* - The tracked files that reference the measured groups.
|
|
13
|
+
*
|
|
14
|
+
* Every number in the result is a count of something real. When nothing
|
|
15
|
+
* can be measured the result is empty, and the caller has to say so
|
|
16
|
+
* instead of inventing a scope.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { execFileSync } from "node:child_process";
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
|
|
22
|
+
/** One group of files that can be worked on together. */
|
|
23
|
+
export interface ScopeWorkGroup {
|
|
24
|
+
/** The name of the group: the package or the directory of the files. */
|
|
25
|
+
id: string;
|
|
26
|
+
/** The files of the group. */
|
|
27
|
+
files: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The measured scope of a task. */
|
|
31
|
+
export interface ScopeMeasurement {
|
|
32
|
+
/** The files the measurement found. */
|
|
33
|
+
files: string[];
|
|
34
|
+
/** The groups the files form. */
|
|
35
|
+
groups: ScopeWorkGroup[];
|
|
36
|
+
/** The number of tracked files of the workspace. */
|
|
37
|
+
workspaceFiles: number;
|
|
38
|
+
/** The number of tracked files that reference the measured groups. */
|
|
39
|
+
callSites: number;
|
|
40
|
+
/** The histogram of the file extensions. */
|
|
41
|
+
fileTypes: Record<string, number>;
|
|
42
|
+
/** A stable fingerprint of the measurement. */
|
|
43
|
+
fingerprint: string;
|
|
44
|
+
/** The hints of the request that matched a file of the workspace. */
|
|
45
|
+
matchedHints: string[];
|
|
46
|
+
/** How the files were found: the request named them, or the session changed them. */
|
|
47
|
+
source: "request" | "working-tree" | "none";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The options of {@link measureScope}. */
|
|
51
|
+
export interface MeasureScopeOptions {
|
|
52
|
+
/** The root of the workspace. */
|
|
53
|
+
workspacePath: string;
|
|
54
|
+
/** The path fragments of the request, for example a package name. */
|
|
55
|
+
hints?: string[];
|
|
56
|
+
/** The files the session has changed in the workspace. */
|
|
57
|
+
changedFiles?: string[];
|
|
58
|
+
/** The upper bound of the files of one measurement. */
|
|
59
|
+
limit?: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The default upper bound of the files of one measurement. */
|
|
63
|
+
const DEFAULT_LIMIT = 400;
|
|
64
|
+
|
|
65
|
+
/** The maximum number of groups that are searched for references. */
|
|
66
|
+
const MAX_REFERENCE_GROUPS = 10;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Run a git command in the workspace and return its output.
|
|
70
|
+
*
|
|
71
|
+
* A command that fails is not a measurement: the caller gets an empty
|
|
72
|
+
* result instead of a guess.
|
|
73
|
+
*/
|
|
74
|
+
function git(workspacePath: string, args: string[]): string {
|
|
75
|
+
try {
|
|
76
|
+
return execFileSync("git", args, {
|
|
77
|
+
cwd: workspacePath,
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
80
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
81
|
+
});
|
|
82
|
+
} catch {
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The tracked files of the workspace.
|
|
89
|
+
*/
|
|
90
|
+
function trackedFiles(workspacePath: string): string[] {
|
|
91
|
+
const out = git(workspacePath, ["ls-files", "-z"]);
|
|
92
|
+
if (!out) return [];
|
|
93
|
+
return out.split("\0").filter(Boolean);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The files the working tree has changed.
|
|
98
|
+
*/
|
|
99
|
+
export function changedFiles(workspacePath: string): string[] {
|
|
100
|
+
const out = git(workspacePath, ["status", "--porcelain", "-z"]);
|
|
101
|
+
if (!out) return [];
|
|
102
|
+
const files: string[] = [];
|
|
103
|
+
for (const entry of out.split("\0")) {
|
|
104
|
+
if (!entry) continue;
|
|
105
|
+
// The porcelain format is "XY path"; a rename carries two paths.
|
|
106
|
+
const path = entry.slice(3).trim();
|
|
107
|
+
if (!path) continue;
|
|
108
|
+
if (path.includes(" -> ")) {
|
|
109
|
+
const parts = path.split(" -> ");
|
|
110
|
+
files.push(parts[0].trim(), parts[1].trim());
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
files.push(path);
|
|
114
|
+
}
|
|
115
|
+
return files.filter(Boolean);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The group a file belongs to: its package, or its top directory.
|
|
120
|
+
*/
|
|
121
|
+
export function moduleOf(file: string): string {
|
|
122
|
+
const parts = file.split("/");
|
|
123
|
+
if (parts[0] === "packages" && parts.length > 1) return `packages/${parts[1]}`;
|
|
124
|
+
return parts[0];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The extension of a file, without the dot.
|
|
129
|
+
*/
|
|
130
|
+
export function extensionOf(file: string): string {
|
|
131
|
+
const name = file.split("/").pop() ?? file;
|
|
132
|
+
const dot = name.lastIndexOf(".");
|
|
133
|
+
if (dot <= 0) return "";
|
|
134
|
+
return name.slice(dot + 1).toLowerCase();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Compare two paths.
|
|
139
|
+
*/
|
|
140
|
+
function comparePaths(a: string, b: string): number {
|
|
141
|
+
if (a === b) return 0;
|
|
142
|
+
return a < b ? -1 : 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Group the measured files.
|
|
147
|
+
*/
|
|
148
|
+
export function groupFiles(files: string[]): ScopeWorkGroup[] {
|
|
149
|
+
const groups = new Map<string, string[]>();
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const id = moduleOf(file);
|
|
152
|
+
const list = groups.get(id) ?? [];
|
|
153
|
+
list.push(file);
|
|
154
|
+
groups.set(id, list);
|
|
155
|
+
}
|
|
156
|
+
return [...groups.entries()]
|
|
157
|
+
.map(([id, groupFiles]) => ({ id, files: groupFiles.sort(comparePaths) }))
|
|
158
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The number of tracked files that reference the groups.
|
|
163
|
+
*
|
|
164
|
+
* The count is a real count of the files that mention the path of the
|
|
165
|
+
* group, so it is a lower bound of the coupling, not a guess.
|
|
166
|
+
*/
|
|
167
|
+
function countCallSites(workspacePath: string, groups: ScopeWorkGroup[]): number {
|
|
168
|
+
let count = 0;
|
|
169
|
+
for (const group of groups.slice(0, MAX_REFERENCE_GROUPS)) {
|
|
170
|
+
const out = git(workspacePath, ["grep", "-l", "-F", "--", group.id]);
|
|
171
|
+
if (!out) continue;
|
|
172
|
+
const files = out.split("\n").filter(Boolean);
|
|
173
|
+
// The files of the group mention their own path: they are not
|
|
174
|
+
// references to the group.
|
|
175
|
+
count += files.filter((file) => moduleOf(file) !== group.id).length;
|
|
176
|
+
}
|
|
177
|
+
return count;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* A stable fingerprint of a set of files.
|
|
182
|
+
*/
|
|
183
|
+
export function fingerprintOf(files: string[]): string {
|
|
184
|
+
const hash = createHash("sha256");
|
|
185
|
+
hash.update([...files].sort(comparePaths).join("\n"));
|
|
186
|
+
return hash.digest("hex").slice(0, 16);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The path fragments of a request.
|
|
191
|
+
*
|
|
192
|
+
* A hint is a place in the repository that the request names: a path with
|
|
193
|
+
* a separator, or a file name with a known extension. The measurement
|
|
194
|
+
* checks every hint against the tracked files, so a hint that names
|
|
195
|
+
* nothing is simply not used.
|
|
196
|
+
*/
|
|
197
|
+
export function scopeHintsFromText(text: string): string[] {
|
|
198
|
+
const hints = new Set<string>();
|
|
199
|
+
for (const match of text.match(/[\w.-]+(?:\/[\w.-]+)+/g) ?? []) {
|
|
200
|
+
hints.add(match.replace(/^\.\//, ""));
|
|
201
|
+
}
|
|
202
|
+
for (const match of text.match(/[\w-]+\.(?:ts|tsx|mts|cts|js|mjs|cjs|json|md|py|sh|yaml|yml)\b/g) ?? []) {
|
|
203
|
+
hints.add(match);
|
|
204
|
+
}
|
|
205
|
+
return [...hints].slice(0, 8);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Measure the scope of a task in the workspace.
|
|
210
|
+
*/
|
|
211
|
+
export function measureScope(options: MeasureScopeOptions): ScopeMeasurement {
|
|
212
|
+
const workspacePath = options.workspacePath;
|
|
213
|
+
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
214
|
+
const tracked = trackedFiles(workspacePath);
|
|
215
|
+
const hints = (options.hints ?? []).map((hint) => hint.trim()).filter(Boolean);
|
|
216
|
+
|
|
217
|
+
// The files the request names: a real match against the tracked paths.
|
|
218
|
+
const matchedHints: string[] = [];
|
|
219
|
+
const named = new Set<string>();
|
|
220
|
+
for (const hint of hints) {
|
|
221
|
+
const needle = hint.toLowerCase();
|
|
222
|
+
let matched = false;
|
|
223
|
+
for (const file of tracked) {
|
|
224
|
+
if (!file.toLowerCase().includes(needle)) continue;
|
|
225
|
+
matched = true;
|
|
226
|
+
if (named.size < limit) named.add(file);
|
|
227
|
+
}
|
|
228
|
+
if (matched) matchedHints.push(hint);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// The files the session has changed: the scope that is already real.
|
|
232
|
+
const changed = (options.changedFiles ?? changedFiles(workspacePath)).filter((file) =>
|
|
233
|
+
tracked.includes(file),
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
let files: string[] = [];
|
|
237
|
+
let source: ScopeMeasurement["source"] = "none";
|
|
238
|
+
if (named.size > 0) {
|
|
239
|
+
files = [...named];
|
|
240
|
+
source = "request";
|
|
241
|
+
} else if (changed.length > 0) {
|
|
242
|
+
files = changed.slice(0, limit);
|
|
243
|
+
source = "working-tree";
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const groups = groupFiles(files);
|
|
247
|
+
const fileTypes: Record<string, number> = {};
|
|
248
|
+
for (const file of files) {
|
|
249
|
+
const extension = extensionOf(file);
|
|
250
|
+
if (!extension) continue;
|
|
251
|
+
fileTypes[extension] = (fileTypes[extension] ?? 0) + 1;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
files: files.sort(comparePaths),
|
|
256
|
+
groups,
|
|
257
|
+
workspaceFiles: tracked.length,
|
|
258
|
+
callSites: countCallSites(workspacePath, groups),
|
|
259
|
+
fileTypes,
|
|
260
|
+
fingerprint: fingerprintOf(files),
|
|
261
|
+
matchedHints,
|
|
262
|
+
source,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
@@ -12,6 +12,8 @@ export declare const IMPLEMENT_PREFIX = "[IMPLEMENT]";
|
|
|
12
12
|
export declare const REVIEW_PREFIX = "[REVIEW]";
|
|
13
13
|
/** Prefix of a todo item that fixes a confirmed review finding. */
|
|
14
14
|
export declare const REVIEW_FIX_PREFIX = "[REVIEW-FIX]";
|
|
15
|
+
/** Prefix of a todo item that is the validation of the task. */
|
|
16
|
+
export declare const TEST_PREFIX = "[TEST]";
|
|
15
17
|
/** The part of a todo item the workflow needs. */
|
|
16
18
|
export interface TodoLike {
|
|
17
19
|
id?: number;
|
|
@@ -35,14 +37,32 @@ export declare function openTodos(todos: TodoLike[]): TodoLike[];
|
|
|
35
37
|
* The open todo items that are still implementation work.
|
|
36
38
|
*
|
|
37
39
|
* A queued review item is not implementation work: it must never block the
|
|
38
|
-
* implementation.
|
|
40
|
+
* implementation. A test item is not implementation work either: it is the
|
|
41
|
+
* validation of the finished work, and it belongs to the phase that follows
|
|
42
|
+
* the review. An unclassified item counts as implementation work, because
|
|
39
43
|
* a task that is tracked without a prefix is still work that has to finish.
|
|
40
44
|
*/
|
|
41
45
|
export declare function implementationTodos(todos: TodoLike[]): TodoLike[];
|
|
46
|
+
/**
|
|
47
|
+
* The finished todo items that were implementation work.
|
|
48
|
+
*
|
|
49
|
+
* They are the evidence that the implementation of the task actually ran.
|
|
50
|
+
* A session without any finished implementation work has no proof that the
|
|
51
|
+
* implementation is over, so the workflow waits instead of starting the
|
|
52
|
+
* review of a task that is still running.
|
|
53
|
+
*/
|
|
54
|
+
export declare function completedImplementationTodos(todos: TodoLike[]): TodoLike[];
|
|
42
55
|
/** The open todo items that represent the queued review. */
|
|
43
56
|
export declare function reviewTodos(todos: TodoLike[]): TodoLike[];
|
|
44
57
|
/** The open todo items that fix a confirmed review finding. */
|
|
45
58
|
export declare function reviewFixTodos(todos: TodoLike[]): TodoLike[];
|
|
59
|
+
/**
|
|
60
|
+
* The open todo items that are the validation of the task.
|
|
61
|
+
*
|
|
62
|
+
* A test item carries the validation plan of the task: the tiers it declares
|
|
63
|
+
* and the final tier that has to pass before the task is complete.
|
|
64
|
+
*/
|
|
65
|
+
export declare function testTodos(todos: TodoLike[]): TodoLike[];
|
|
46
66
|
/** Does the task still have implementation work? */
|
|
47
67
|
export declare function hasOpenImplementationWork(todos: TodoLike[]): boolean;
|
|
48
68
|
/** How many todo items of each kind are open. */
|
|
@@ -50,6 +70,7 @@ export declare function summarizeTodos(todos: TodoLike[]): {
|
|
|
50
70
|
implementation: number;
|
|
51
71
|
review: number;
|
|
52
72
|
reviewFix: number;
|
|
73
|
+
test: number;
|
|
53
74
|
};
|
|
54
75
|
/** Prefix a title with the kind of its todo item. */
|
|
55
76
|
export declare function buildTodoSubject(kind: TodoKind, text: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAC9C,uDAAuD;AACvD,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAC9C,uDAAuD;AACvD,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,gEAAgE;AAChE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAkBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAiBxE;AAED,mCAAmC;AACnC,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAElD;AAED,4BAA4B;AAC5B,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAKjE;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAM1E;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEzD;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEvD;AAED,oDAAoD;AACpD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAEpE;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACb,CAOA;AAUD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrE"}
|
|
@@ -11,6 +11,8 @@ export const IMPLEMENT_PREFIX = "[IMPLEMENT]";
|
|
|
11
11
|
export const REVIEW_PREFIX = "[REVIEW]";
|
|
12
12
|
/** Prefix of a todo item that fixes a confirmed review finding. */
|
|
13
13
|
export const REVIEW_FIX_PREFIX = "[REVIEW-FIX]";
|
|
14
|
+
/** Prefix of a todo item that is the validation of the task. */
|
|
15
|
+
export const TEST_PREFIX = "[TEST]";
|
|
14
16
|
const KIND_BY_NAME = {
|
|
15
17
|
implement: "implement",
|
|
16
18
|
implementation: "implement",
|
|
@@ -21,6 +23,9 @@ const KIND_BY_NAME = {
|
|
|
21
23
|
review_fix: "review_fix",
|
|
22
24
|
"review-fix": "review_fix",
|
|
23
25
|
reviewfix: "review_fix",
|
|
26
|
+
test: "test",
|
|
27
|
+
validation: "test",
|
|
28
|
+
validation_test: "test",
|
|
24
29
|
other: "other",
|
|
25
30
|
};
|
|
26
31
|
/**
|
|
@@ -44,6 +49,8 @@ export function classifyTodo(todo) {
|
|
|
44
49
|
const subject = (todo.subject ?? "").trim().toUpperCase();
|
|
45
50
|
if (subject.startsWith(REVIEW_FIX_PREFIX))
|
|
46
51
|
return "review_fix";
|
|
52
|
+
if (subject.startsWith(TEST_PREFIX))
|
|
53
|
+
return "test";
|
|
47
54
|
if (subject.startsWith(IMPLEMENT_PREFIX))
|
|
48
55
|
return "implement";
|
|
49
56
|
if (subject.startsWith(REVIEW_PREFIX))
|
|
@@ -62,7 +69,9 @@ export function openTodos(todos) {
|
|
|
62
69
|
* The open todo items that are still implementation work.
|
|
63
70
|
*
|
|
64
71
|
* A queued review item is not implementation work: it must never block the
|
|
65
|
-
* implementation.
|
|
72
|
+
* implementation. A test item is not implementation work either: it is the
|
|
73
|
+
* validation of the finished work, and it belongs to the phase that follows
|
|
74
|
+
* the review. An unclassified item counts as implementation work, because
|
|
66
75
|
* a task that is tracked without a prefix is still work that has to finish.
|
|
67
76
|
*/
|
|
68
77
|
export function implementationTodos(todos) {
|
|
@@ -71,6 +80,22 @@ export function implementationTodos(todos) {
|
|
|
71
80
|
return kind === "implement" || kind === "other";
|
|
72
81
|
});
|
|
73
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* The finished todo items that were implementation work.
|
|
85
|
+
*
|
|
86
|
+
* They are the evidence that the implementation of the task actually ran.
|
|
87
|
+
* A session without any finished implementation work has no proof that the
|
|
88
|
+
* implementation is over, so the workflow waits instead of starting the
|
|
89
|
+
* review of a task that is still running.
|
|
90
|
+
*/
|
|
91
|
+
export function completedImplementationTodos(todos) {
|
|
92
|
+
return todos.filter((todo) => {
|
|
93
|
+
if (todo.status !== "completed")
|
|
94
|
+
return false;
|
|
95
|
+
const kind = classifyTodo(todo);
|
|
96
|
+
return kind === "implement" || kind === "other";
|
|
97
|
+
});
|
|
98
|
+
}
|
|
74
99
|
/** The open todo items that represent the queued review. */
|
|
75
100
|
export function reviewTodos(todos) {
|
|
76
101
|
return openTodos(todos).filter((todo) => classifyTodo(todo) === "review");
|
|
@@ -79,6 +104,15 @@ export function reviewTodos(todos) {
|
|
|
79
104
|
export function reviewFixTodos(todos) {
|
|
80
105
|
return openTodos(todos).filter((todo) => classifyTodo(todo) === "review_fix");
|
|
81
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* The open todo items that are the validation of the task.
|
|
109
|
+
*
|
|
110
|
+
* A test item carries the validation plan of the task: the tiers it declares
|
|
111
|
+
* and the final tier that has to pass before the task is complete.
|
|
112
|
+
*/
|
|
113
|
+
export function testTodos(todos) {
|
|
114
|
+
return openTodos(todos).filter((todo) => classifyTodo(todo) === "test");
|
|
115
|
+
}
|
|
82
116
|
/** Does the task still have implementation work? */
|
|
83
117
|
export function hasOpenImplementationWork(todos) {
|
|
84
118
|
return implementationTodos(todos).length > 0;
|
|
@@ -89,12 +123,14 @@ export function summarizeTodos(todos) {
|
|
|
89
123
|
implementation: implementationTodos(todos).length,
|
|
90
124
|
review: reviewTodos(todos).length,
|
|
91
125
|
reviewFix: reviewFixTodos(todos).length,
|
|
126
|
+
test: testTodos(todos).length,
|
|
92
127
|
};
|
|
93
128
|
}
|
|
94
129
|
const PREFIX_BY_KIND = {
|
|
95
130
|
implement: IMPLEMENT_PREFIX,
|
|
96
131
|
review: REVIEW_PREFIX,
|
|
97
132
|
review_fix: REVIEW_FIX_PREFIX,
|
|
133
|
+
test: TEST_PREFIX,
|
|
98
134
|
other: "",
|
|
99
135
|
};
|
|
100
136
|
/** Prefix a title with the kind of its todo item. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAC9C,uDAAuD;AACvD,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AACxC,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
* recorded and deferred, never executed between two implementation todos.
|
|
7
7
|
*/
|
|
8
8
|
export type { TwoPhasePhase, TodoKind, ReviewSignal, ReviewChunk, ReviewFinding, TwoPhaseState, } from "./types.js";
|
|
9
|
-
export { IMPLEMENT_PREFIX, REVIEW_PREFIX, REVIEW_FIX_PREFIX, classifyTodo, isOpenTodo, openTodos, implementationTodos, reviewTodos, reviewFixTodos, hasOpenImplementationWork, summarizeTodos, buildTodoSubject, } from "./classify.js";
|
|
9
|
+
export { IMPLEMENT_PREFIX, REVIEW_PREFIX, REVIEW_FIX_PREFIX, TEST_PREFIX, classifyTodo, isOpenTodo, openTodos, implementationTodos, completedImplementationTodos, reviewTodos, reviewFixTodos, testTodos, hasOpenImplementationWork, summarizeTodos, buildTodoSubject, } from "./classify.js";
|
|
10
10
|
export type { TodoLike } from "./classify.js";
|
|
11
11
|
export { DEFAULT_REVIEW_TOOL_PATTERNS, DEFAULT_REVIEW_COMMAND_PATTERNS, parseExtraPatterns, isComprehensiveReviewTool, isReviewCommand, dispatchAgentName, detectReviewInvocation, explicitReviewRequest, extractFiles, signalKey, mergeSignals, summarizeSignals, } from "./signals.js";
|
|
12
12
|
export type { ReviewInvocation, SignalSummary } from "./signals.js";
|
|
13
13
|
export { EXCLUDED_SCOPE_PREFIXES, DEFAULT_CHUNK_SIZE, isReviewablePath, isGitRepository, currentRevision, revisionExists, moduleKey, countModules, parseNumstat, collectScope, chunkScope, shouldChunkScope, } from "./scope.js";
|
|
14
14
|
export type { ScopeMetrics, ScopeResult } from "./scope.js";
|
|
15
|
-
export { TWO_PHASE_STATE_DIR, createState, safeFileName, normalizeState, TwoPhaseStateStore, moveToPhase, recordSignal, transitionToReviewPending, startReview, markChunkDone, recordFinding, transitionToReviewFixes, allChunksDone, markComplete, hasQueuedReview, } from "./state.js";
|
|
15
|
+
export { TWO_PHASE_STATE_DIR, createState, safeFileName, normalizeState, TwoPhaseStateStore, moveToPhase, recordSignal, transitionToReviewPending, startReview, markChunkDone, recordFinding, transitionToReviewFixes, transitionToTestPending, allChunksDone, markComplete, completeWithoutReview, hasQueuedReview, } from "./state.js";
|
|
16
16
|
export { TWO_PHASE_CONTRACT, buildPhaseView, buildPhaseInstruction, buildReviewTodoSubject, buildReviewTodoDescription, buildChunkTodoSubject, buildChunkTodoDescription, isChunkTodo, syncChunkStatus, formatPhaseStatus, buildDeferralReason, } from "./rules.js";
|
|
17
17
|
export type { PhaseView } from "./rules.js";
|
|
18
|
+
export { emptyValidationGateState, validationGateSatisfied, describeValidationGate, } from "./validation.js";
|
|
19
|
+
export type { GateTodo, ValidationGateState, ValidationGateReader, } from "./validation.js";
|
|
18
20
|
export { HARNESS_MESSAGE_MARKER, initTwoPhaseReview, } from "./runtime.js";
|
|
19
21
|
export type { TwoPhaseExtensionApi, TwoPhaseExtensionContext, TwoPhaseRuntime, TwoPhaseRuntimeOptions, TodoReadResult, TodoReader, } from "./runtime.js";
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,yBAAyB,EACzB,cAAc,EACd,gBAAgB,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EACN,4BAA4B,EAC5B,+BAA+B,EAC/B,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,gBAAgB,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,eAAe,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACN,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,UAAU,GACV,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,4BAA4B,EAC5B,WAAW,EACX,cAAc,EACd,SAAS,EACT,yBAAyB,EACzB,cAAc,EACd,gBAAgB,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EACN,4BAA4B,EAC5B,+BAA+B,EAC/B,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,gBAAgB,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,eAAe,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACN,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACX,QAAQ,EACR,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,UAAU,GACV,MAAM,cAAc,CAAC"}
|