@autopilot-harness/core 0.1.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/LICENSE +21 -0
- package/README.md +8 -0
- package/dist/autopilot-ignore.d.ts +23 -0
- package/dist/autopilot-ignore.d.ts.map +1 -0
- package/dist/autopilot-ignore.js +271 -0
- package/dist/autopilot-ignore.js.map +1 -0
- package/dist/checklist-md.d.ts +62 -0
- package/dist/checklist-md.d.ts.map +1 -0
- package/dist/checklist-md.js +217 -0
- package/dist/checklist-md.js.map +1 -0
- package/dist/code-edit-detector.d.ts +10 -0
- package/dist/code-edit-detector.d.ts.map +1 -0
- package/dist/code-edit-detector.js +44 -0
- package/dist/code-edit-detector.js.map +1 -0
- package/dist/i18n-render.d.ts +3 -0
- package/dist/i18n-render.d.ts.map +1 -0
- package/dist/i18n-render.js +8 -0
- package/dist/i18n-render.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/list-tracks.d.ts +29 -0
- package/dist/list-tracks.d.ts.map +1 -0
- package/dist/list-tracks.js +232 -0
- package/dist/list-tracks.js.map +1 -0
- package/dist/migrate.d.ts +19 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +101 -0
- package/dist/migrate.js.map +1 -0
- package/dist/phase-actions.d.ts +35 -0
- package/dist/phase-actions.d.ts.map +1 -0
- package/dist/phase-actions.js +480 -0
- package/dist/phase-actions.js.map +1 -0
- package/dist/project-config.d.ts +29 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +301 -0
- package/dist/project-config.js.map +1 -0
- package/dist/project-path.d.ts +26 -0
- package/dist/project-path.d.ts.map +1 -0
- package/dist/project-path.js +104 -0
- package/dist/project-path.js.map +1 -0
- package/dist/review-engine.d.ts +263 -0
- package/dist/review-engine.d.ts.map +1 -0
- package/dist/review-engine.js +2273 -0
- package/dist/review-engine.js.map +1 -0
- package/dist/review-i18n.d.ts +29 -0
- package/dist/review-i18n.d.ts.map +1 -0
- package/dist/review-i18n.js +54 -0
- package/dist/review-i18n.js.map +1 -0
- package/dist/review-lenses.d.ts +13 -0
- package/dist/review-lenses.d.ts.map +1 -0
- package/dist/review-lenses.js +43 -0
- package/dist/review-lenses.js.map +1 -0
- package/dist/review-runtime.d.ts +12 -0
- package/dist/review-runtime.d.ts.map +1 -0
- package/dist/review-runtime.js +37 -0
- package/dist/review-runtime.js.map +1 -0
- package/dist/review-scope.d.ts +9 -0
- package/dist/review-scope.d.ts.map +1 -0
- package/dist/review-scope.js +92 -0
- package/dist/review-scope.js.map +1 -0
- package/dist/sqlite.d.ts +15 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +38 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/state-store.d.ts +277 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +1091 -0
- package/dist/state-store.js.map +1 -0
- package/dist/track-slug.d.ts +4 -0
- package/dist/track-slug.d.ts.map +1 -0
- package/dist/track-slug.js +18 -0
- package/dist/track-slug.js.map +1 -0
- package/dist/transcript-followup.d.ts +59 -0
- package/dist/transcript-followup.d.ts.map +1 -0
- package/dist/transcript-followup.js +310 -0
- package/dist/transcript-followup.js.map +1 -0
- package/dist/trigger-parser.d.ts +54 -0
- package/dist/trigger-parser.d.ts.map +1 -0
- package/dist/trigger-parser.js +250 -0
- package/dist/trigger-parser.js.map +1 -0
- package/dist/verify-report.d.ts +52 -0
- package/dist/verify-report.d.ts.map +1 -0
- package/dist/verify-report.js +195 -0
- package/dist/verify-report.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { canEnterExecuting, isRunnableTrack, listTracks, } from "./list-tracks.js";
|
|
4
|
+
import { isLexicallyInsideProject, isRealpathInsideProject, normalizeInProjectPlansDir, normalizeProjectRoot, } from "./project-path.js";
|
|
5
|
+
import { firstUnchecked, parseChecklist } from "./checklist-md.js";
|
|
6
|
+
import { isSafeTrackSlug } from "./track-slug.js";
|
|
7
|
+
export { isSafeTrackSlug } from "./track-slug.js";
|
|
8
|
+
function nowIso() {
|
|
9
|
+
return new Date().toISOString();
|
|
10
|
+
}
|
|
11
|
+
function checklistPathFor(projectRoot, slug, plansDir) {
|
|
12
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
13
|
+
// Unusable root → relative path that fails later containment (no cwd-abs escape).
|
|
14
|
+
if (!root)
|
|
15
|
+
return path.join(plansDir, slug, "checklist.md");
|
|
16
|
+
return path.join(root, plansDir, slug, "checklist.md");
|
|
17
|
+
}
|
|
18
|
+
/** Same checklist binding despite relative vs absolute spelling under projectRoot. */
|
|
19
|
+
function sameChecklistBinding(stored, rebuilt, projectRoot) {
|
|
20
|
+
if (stored === rebuilt)
|
|
21
|
+
return true;
|
|
22
|
+
if (!stored || !rebuilt || stored.includes("\0") || rebuilt.includes("\0")) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
26
|
+
if (!root)
|
|
27
|
+
return false;
|
|
28
|
+
try {
|
|
29
|
+
const absStored = path.isAbsolute(stored)
|
|
30
|
+
? path.resolve(stored)
|
|
31
|
+
: path.resolve(root, stored);
|
|
32
|
+
const absRebuilt = path.isAbsolute(rebuilt)
|
|
33
|
+
? path.resolve(rebuilt)
|
|
34
|
+
: path.resolve(root, rebuilt);
|
|
35
|
+
return absStored === absRebuilt;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Prefer a stored checklist_path only when it is still allowed in-project.
|
|
43
|
+
* Otherwise rebuild from plansDir/slug — blocks poisoned absolute/escaped session paths.
|
|
44
|
+
* Never accept stored===rebuilt by string equality alone (plans dir may be a symlink escape).
|
|
45
|
+
*/
|
|
46
|
+
function trustedChecklistPath(projectRoot, plansDir, slug, storedPath, boundTrackId) {
|
|
47
|
+
const rebuilt = checklistPathFor(projectRoot, slug, plansDir);
|
|
48
|
+
if (storedPath && boundTrackId === slug) {
|
|
49
|
+
if (isChecklistPathAllowed(projectRoot, storedPath)) {
|
|
50
|
+
return storedPath;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return rebuilt;
|
|
54
|
+
}
|
|
55
|
+
/** Existing path → realpath inside; missing → lexical inside projectRoot. */
|
|
56
|
+
function isChecklistPathAllowed(projectRoot, checklistPath) {
|
|
57
|
+
if (!checklistPath || checklistPath.includes("\0"))
|
|
58
|
+
return false;
|
|
59
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
60
|
+
if (!root)
|
|
61
|
+
return false;
|
|
62
|
+
try {
|
|
63
|
+
fs.lstatSync(path.isAbsolute(checklistPath)
|
|
64
|
+
? checklistPath
|
|
65
|
+
: path.resolve(root, checklistPath));
|
|
66
|
+
return isRealpathInsideProject(root, checklistPath);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return isLexicallyInsideProject(root, checklistPath);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function ensureSession(store, conversationId, projectRoot) {
|
|
73
|
+
const existing = store.getSession(conversationId);
|
|
74
|
+
if (existing)
|
|
75
|
+
return existing;
|
|
76
|
+
return store.upsertSession({
|
|
77
|
+
conversation_id: conversationId,
|
|
78
|
+
project_root: projectRoot,
|
|
79
|
+
code_root: projectRoot,
|
|
80
|
+
platform: "cursor",
|
|
81
|
+
phase: "idle",
|
|
82
|
+
armed: 0,
|
|
83
|
+
paused: 0,
|
|
84
|
+
track_id: "_pending",
|
|
85
|
+
checklist_path: "",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function upsertTrack(store, slug, checklistPath, plansDir, projectRoot) {
|
|
89
|
+
const ts = nowIso();
|
|
90
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
91
|
+
if (!root)
|
|
92
|
+
return;
|
|
93
|
+
const planPath = path.join(root, plansDir, slug, "plan.md");
|
|
94
|
+
const briefPath = path.join(root, plansDir, slug, "brief.md");
|
|
95
|
+
store.db
|
|
96
|
+
.prepare(`INSERT INTO tracks (track_id, slug, checklist_path, plan_path, brief_path, updated_at)
|
|
97
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
98
|
+
ON CONFLICT(track_id) DO UPDATE SET
|
|
99
|
+
slug = excluded.slug,
|
|
100
|
+
checklist_path = excluded.checklist_path,
|
|
101
|
+
plan_path = excluded.plan_path,
|
|
102
|
+
brief_path = excluded.brief_path,
|
|
103
|
+
updated_at = excluded.updated_at`)
|
|
104
|
+
.run(slug, slug, checklistPath, fs.existsSync(planPath) ? planPath : null, fs.existsSync(briefPath) ? briefPath : null, ts);
|
|
105
|
+
}
|
|
106
|
+
function candidatePayload(tracks) {
|
|
107
|
+
return JSON.stringify(tracks.map((t) => ({
|
|
108
|
+
slug: t.slug,
|
|
109
|
+
title: t.title,
|
|
110
|
+
phase: t.phase,
|
|
111
|
+
progress: `${t.checklistDone}/${t.checklistTotal}`,
|
|
112
|
+
})));
|
|
113
|
+
}
|
|
114
|
+
function resolveRunSlug(store, session, projectRoot, plansDir, requestedSlug) {
|
|
115
|
+
const runnable = listTracks(projectRoot, store, "runnable", plansDir).filter((t) => isSafeTrackSlug(t.slug));
|
|
116
|
+
if (requestedSlug) {
|
|
117
|
+
if (!isSafeTrackSlug(requestedSlug)) {
|
|
118
|
+
return {
|
|
119
|
+
kind: "none",
|
|
120
|
+
userMessage: `Invalid track slug "${requestedSlug}".`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const hit = runnable.find((t) => t.slug === requestedSlug);
|
|
124
|
+
if (!hit) {
|
|
125
|
+
const all = listTracks(projectRoot, store, "all", plansDir);
|
|
126
|
+
if (!all.some((t) => t.slug === requestedSlug)) {
|
|
127
|
+
return {
|
|
128
|
+
kind: "none",
|
|
129
|
+
userMessage: `Track "${requestedSlug}" not found or has no unchecked checklist items.`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
kind: "none",
|
|
134
|
+
userMessage: `Track "${requestedSlug}" is not runnable (paused or no unchecked items).`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return { kind: "slug", slug: requestedSlug };
|
|
138
|
+
}
|
|
139
|
+
// Prefer this conversation's bound track if runnable
|
|
140
|
+
if (session.track_id && session.track_id !== "_pending") {
|
|
141
|
+
const bound = runnable.find((t) => t.slug === session.track_id);
|
|
142
|
+
if (bound) {
|
|
143
|
+
return { kind: "slug", slug: bound.slug };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (runnable.length === 0) {
|
|
147
|
+
return {
|
|
148
|
+
kind: "none",
|
|
149
|
+
userMessage: "No runnable plan. Use /autopilot-on to plan, then finalize a checklist with unchecked items.",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (runnable.length === 1) {
|
|
153
|
+
return { kind: "slug", slug: runnable[0].slug };
|
|
154
|
+
}
|
|
155
|
+
return { kind: "pick", candidates: runnable };
|
|
156
|
+
}
|
|
157
|
+
function requireProjectRoot(store, projectRoot) {
|
|
158
|
+
// Store is authoritative — caller arg must not redirect plans/checklist FS roots.
|
|
159
|
+
return (normalizeProjectRoot(store.projectRoot) ??
|
|
160
|
+
normalizeProjectRoot(projectRoot));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* plansDir must stay a relative in-project directory (no absolute, no ..).
|
|
164
|
+
* Otherwise path.join(root, plansDir, …) can escape before checklist containment.
|
|
165
|
+
*/
|
|
166
|
+
function requirePlansDir(projectRoot, plansDir) {
|
|
167
|
+
return normalizeInProjectPlansDir(projectRoot, plansDir);
|
|
168
|
+
}
|
|
169
|
+
/** Enter executing for a concrete track (RUN gate). */
|
|
170
|
+
export function applyRun(store, conversationId, projectRoot, opts) {
|
|
171
|
+
const root = requireProjectRoot(store, projectRoot);
|
|
172
|
+
if (!root) {
|
|
173
|
+
return { ok: false, userMessage: "Invalid project root." };
|
|
174
|
+
}
|
|
175
|
+
projectRoot = root;
|
|
176
|
+
const plansDir = requirePlansDir(projectRoot, opts?.config?.plansDir);
|
|
177
|
+
if (!plansDir) {
|
|
178
|
+
return { ok: false, userMessage: "Invalid plans directory." };
|
|
179
|
+
}
|
|
180
|
+
const concurrencyMode = opts?.config?.concurrencyMode ?? "one_executor";
|
|
181
|
+
const session = ensureSession(store, conversationId, projectRoot);
|
|
182
|
+
const resolved = resolveRunSlug(store, session, projectRoot, plansDir, opts?.slug);
|
|
183
|
+
if (resolved.kind === "none") {
|
|
184
|
+
return { ok: false, userMessage: resolved.userMessage };
|
|
185
|
+
}
|
|
186
|
+
if (resolved.kind === "pick") {
|
|
187
|
+
store.upsertSession({
|
|
188
|
+
conversation_id: conversationId,
|
|
189
|
+
project_root: session.project_root,
|
|
190
|
+
code_root: session.code_root,
|
|
191
|
+
pending_action: "run",
|
|
192
|
+
track_candidates_json: candidatePayload(resolved.candidates),
|
|
193
|
+
armed: 0,
|
|
194
|
+
// phase unchanged — do not write executing
|
|
195
|
+
});
|
|
196
|
+
const lines = resolved.candidates
|
|
197
|
+
.map((t, i) => ` ${i + 1}. ${t.slug} — ${t.title} (${t.checklistTotal - t.checklistDone}/${t.checklistTotal} left)`)
|
|
198
|
+
.join("\n");
|
|
199
|
+
return {
|
|
200
|
+
ok: false,
|
|
201
|
+
needPick: true,
|
|
202
|
+
candidates: resolved.candidates,
|
|
203
|
+
userMessage: `Select a plan to execute:\n\n${lines}\n\nReply with a number or /autopilot-run <slug>.`,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const slug = resolved.slug;
|
|
207
|
+
if (!isSafeTrackSlug(slug)) {
|
|
208
|
+
return {
|
|
209
|
+
ok: false,
|
|
210
|
+
userMessage: `Invalid track slug "${slug}".`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const checklistPath = checklistPathFor(projectRoot, slug, plansDir);
|
|
214
|
+
const gate = canEnterExecuting({
|
|
215
|
+
slug,
|
|
216
|
+
checklistPath,
|
|
217
|
+
paused: session.paused === 1,
|
|
218
|
+
projectRoot,
|
|
219
|
+
});
|
|
220
|
+
if (!gate.ok) {
|
|
221
|
+
return {
|
|
222
|
+
ok: false,
|
|
223
|
+
userMessage: `Cannot start executing: ${gate.reason}.`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
// Atomically re-check one_executor and write track+session+chain so concurrent
|
|
227
|
+
// RUNs cannot both pass the gate, and a mid-write crash does not leave a
|
|
228
|
+
// half-armed executing session without a matching track/chain update.
|
|
229
|
+
try {
|
|
230
|
+
return store.exclusiveWrite(() => {
|
|
231
|
+
if (concurrencyMode === "one_executor") {
|
|
232
|
+
const other = store.findExecutingSession(conversationId);
|
|
233
|
+
if (other) {
|
|
234
|
+
return {
|
|
235
|
+
commit: false,
|
|
236
|
+
value: {
|
|
237
|
+
ok: false,
|
|
238
|
+
userMessage: `Another session is already executing (${other.track_id}). Send Autopilot OFF there or wait, then retry.`,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Re-read inside the lock: idempotent re-RUN on the *same* armed track
|
|
244
|
+
// (same checklist binding) preserves review chain (F-E8). Switching tracks,
|
|
245
|
+
// plansDir/checklist path, or freshly entering must reset — otherwise
|
|
246
|
+
// confirm_left/pending from track A (or an old checklist) leak onto B.
|
|
247
|
+
const fresh = store.getSession(conversationId);
|
|
248
|
+
const alreadyExecutingSameTrack = fresh?.phase === "executing" &&
|
|
249
|
+
fresh.armed === 1 &&
|
|
250
|
+
fresh.paused === 0 &&
|
|
251
|
+
fresh.track_id === slug &&
|
|
252
|
+
sameChecklistBinding(fresh.checklist_path, checklistPath, projectRoot);
|
|
253
|
+
upsertTrack(store, slug, checklistPath, plansDir, projectRoot);
|
|
254
|
+
const updated = store.upsertSession({
|
|
255
|
+
conversation_id: conversationId,
|
|
256
|
+
project_root: projectRoot,
|
|
257
|
+
code_root: projectRoot,
|
|
258
|
+
track_id: slug,
|
|
259
|
+
checklist_path: checklistPath,
|
|
260
|
+
phase: "executing",
|
|
261
|
+
armed: 1,
|
|
262
|
+
paused: 0,
|
|
263
|
+
paused_reason: null,
|
|
264
|
+
pending_action: null,
|
|
265
|
+
track_candidates_json: null,
|
|
266
|
+
error_count: 0,
|
|
267
|
+
idle_stop_count: 0,
|
|
268
|
+
});
|
|
269
|
+
if (!alreadyExecutingSameTrack) {
|
|
270
|
+
// Fresh enter or track switch: drop stale pending / chain from prior work.
|
|
271
|
+
// Seed sticky reviewing_item_id from firstUnchecked so a premature `[x]`
|
|
272
|
+
// before the first product edit cannot retarget via firstUnchecked.
|
|
273
|
+
let reviewingItemId = null;
|
|
274
|
+
try {
|
|
275
|
+
const cl = parseChecklist(checklistPath, { projectRoot });
|
|
276
|
+
reviewingItemId = firstUnchecked(cl)?.id ?? null;
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
/* checklist unreadable — leave sticky null; first edit may still arm */
|
|
280
|
+
}
|
|
281
|
+
store.updateReviewChain(conversationId, {
|
|
282
|
+
fix_round: 0,
|
|
283
|
+
confirm_left: null,
|
|
284
|
+
chain_pending: 0,
|
|
285
|
+
code_edited: 0,
|
|
286
|
+
item_confirm_complete: 0,
|
|
287
|
+
reviewing_item_id: reviewingItemId,
|
|
288
|
+
pending_followup: null,
|
|
289
|
+
pending_followup_at: null,
|
|
290
|
+
pending_redeliver_at: null,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
store.ensureReviewChain(conversationId);
|
|
295
|
+
}
|
|
296
|
+
return { commit: true, value: { ok: true, session: updated } };
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
301
|
+
if (/busy|locked|SQLITE_BUSY|SQLITE_LOCKED/i.test(msg)) {
|
|
302
|
+
return {
|
|
303
|
+
ok: false,
|
|
304
|
+
userMessage: "State database is busy; retry Autopilot RUN in a moment.",
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
throw err;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** REPLAN: back to planning; reset review chain; keep track + checklist file. */
|
|
311
|
+
export function applyReplan(store, conversationId, projectRoot, opts) {
|
|
312
|
+
const root = requireProjectRoot(store, projectRoot);
|
|
313
|
+
if (!root) {
|
|
314
|
+
return { ok: false, userMessage: "Invalid project root." };
|
|
315
|
+
}
|
|
316
|
+
projectRoot = root;
|
|
317
|
+
const plansDir = requirePlansDir(projectRoot, opts?.config?.plansDir);
|
|
318
|
+
if (!plansDir) {
|
|
319
|
+
return { ok: false, userMessage: "Invalid plans directory." };
|
|
320
|
+
}
|
|
321
|
+
const session = ensureSession(store, conversationId, projectRoot);
|
|
322
|
+
let slug = opts?.slug ?? session.track_id;
|
|
323
|
+
if (slug && slug !== "_pending" && !isSafeTrackSlug(slug)) {
|
|
324
|
+
return {
|
|
325
|
+
ok: false,
|
|
326
|
+
userMessage: `Invalid track slug "${slug}".`,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
if (!slug || slug === "_pending") {
|
|
330
|
+
const all = listTracks(projectRoot, store, "all", plansDir).filter((t) => isSafeTrackSlug(t.slug));
|
|
331
|
+
if (all.length === 1) {
|
|
332
|
+
slug = all[0].slug;
|
|
333
|
+
}
|
|
334
|
+
else if (all.length > 1) {
|
|
335
|
+
store.upsertSession({
|
|
336
|
+
conversation_id: conversationId,
|
|
337
|
+
project_root: session.project_root,
|
|
338
|
+
code_root: session.code_root,
|
|
339
|
+
pending_action: "replan",
|
|
340
|
+
track_candidates_json: candidatePayload(all),
|
|
341
|
+
armed: 0,
|
|
342
|
+
});
|
|
343
|
+
const lines = all
|
|
344
|
+
.map((t, i) => ` ${i + 1}. ${t.slug} — ${t.title}`)
|
|
345
|
+
.join("\n");
|
|
346
|
+
return {
|
|
347
|
+
ok: false,
|
|
348
|
+
needPick: true,
|
|
349
|
+
candidates: all,
|
|
350
|
+
userMessage: `Select a plan to replan:\n\n${lines}\n\nReply with a number or /autopilot-replan <slug>.`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
return {
|
|
355
|
+
ok: false,
|
|
356
|
+
userMessage: "No plan to replan. Use /autopilot-on first.",
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const checklistPath = trustedChecklistPath(projectRoot, plansDir, slug, session.checklist_path, session.track_id);
|
|
361
|
+
const updated = store.upsertSession({
|
|
362
|
+
conversation_id: conversationId,
|
|
363
|
+
project_root: projectRoot,
|
|
364
|
+
code_root: projectRoot,
|
|
365
|
+
track_id: slug,
|
|
366
|
+
checklist_path: checklistPath,
|
|
367
|
+
phase: "planning",
|
|
368
|
+
armed: 0,
|
|
369
|
+
paused: 0,
|
|
370
|
+
paused_reason: null,
|
|
371
|
+
pending_action: null,
|
|
372
|
+
track_candidates_json: null,
|
|
373
|
+
});
|
|
374
|
+
store.updateReviewChain(conversationId, {
|
|
375
|
+
fix_round: 0,
|
|
376
|
+
confirm_left: null,
|
|
377
|
+
chain_pending: 0,
|
|
378
|
+
code_edited: 0,
|
|
379
|
+
item_confirm_complete: 0,
|
|
380
|
+
reviewing_item_id: null,
|
|
381
|
+
pending_followup: null,
|
|
382
|
+
pending_followup_at: null,
|
|
383
|
+
pending_redeliver_at: null,
|
|
384
|
+
});
|
|
385
|
+
return { ok: true, session: updated };
|
|
386
|
+
}
|
|
387
|
+
/** Resolve pending track pick (digit or slug) then apply run/replan. */
|
|
388
|
+
export function applyTrackPick(store, conversationId, projectRoot, pick, opts) {
|
|
389
|
+
const root = requireProjectRoot(store, projectRoot);
|
|
390
|
+
if (!root) {
|
|
391
|
+
return { ok: false, userMessage: "Invalid project root." };
|
|
392
|
+
}
|
|
393
|
+
projectRoot = root;
|
|
394
|
+
const session = store.getSession(conversationId);
|
|
395
|
+
if (!session?.pending_action) {
|
|
396
|
+
return {
|
|
397
|
+
ok: false,
|
|
398
|
+
userMessage: "No pending track selection.",
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
const pending = session.pending_action;
|
|
402
|
+
if (pending !== "run" && pending !== "replan") {
|
|
403
|
+
return {
|
|
404
|
+
ok: false,
|
|
405
|
+
userMessage: `Unknown pending action "${pending}".`,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
if (!session.track_candidates_json) {
|
|
409
|
+
return { ok: false, userMessage: "Invalid track candidates JSON." };
|
|
410
|
+
}
|
|
411
|
+
let candidates = [];
|
|
412
|
+
try {
|
|
413
|
+
const parsed = JSON.parse(session.track_candidates_json);
|
|
414
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
415
|
+
return { ok: false, userMessage: "Invalid track candidates JSON." };
|
|
416
|
+
}
|
|
417
|
+
const hasValidSlug = parsed.some((c) => !!c &&
|
|
418
|
+
typeof c === "object" &&
|
|
419
|
+
!Array.isArray(c) &&
|
|
420
|
+
typeof c.slug === "string" &&
|
|
421
|
+
isSafeTrackSlug(c.slug));
|
|
422
|
+
if (!hasValidSlug) {
|
|
423
|
+
return { ok: false, userMessage: "Invalid track candidates JSON." };
|
|
424
|
+
}
|
|
425
|
+
candidates = parsed;
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
return { ok: false, userMessage: "Invalid track candidates JSON." };
|
|
429
|
+
}
|
|
430
|
+
let slug;
|
|
431
|
+
if (/^\d+$/.test(pick)) {
|
|
432
|
+
const idx = Number.parseInt(pick, 10) - 1;
|
|
433
|
+
const entry = candidates[idx];
|
|
434
|
+
slug =
|
|
435
|
+
entry &&
|
|
436
|
+
typeof entry === "object" &&
|
|
437
|
+
!Array.isArray(entry) &&
|
|
438
|
+
typeof entry.slug === "string"
|
|
439
|
+
? entry.slug
|
|
440
|
+
: undefined;
|
|
441
|
+
if (!slug || !isSafeTrackSlug(slug)) {
|
|
442
|
+
return {
|
|
443
|
+
ok: false,
|
|
444
|
+
userMessage: `Invalid selection "${pick}". Choose 1–${candidates.length}.`,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
if (!isSafeTrackSlug(pick)) {
|
|
450
|
+
return {
|
|
451
|
+
ok: false,
|
|
452
|
+
userMessage: `Invalid track slug "${pick}".`,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
slug = pick;
|
|
456
|
+
if (!candidates.some((c) => !!c &&
|
|
457
|
+
typeof c === "object" &&
|
|
458
|
+
!Array.isArray(c) &&
|
|
459
|
+
c.slug === slug)) {
|
|
460
|
+
return {
|
|
461
|
+
ok: false,
|
|
462
|
+
userMessage: `Unknown slug "${pick}".`,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// Keep pending on nested failure so the user can retry the same pick.
|
|
467
|
+
// Success paths (applyRun / applyReplan) clear pending themselves.
|
|
468
|
+
if (pending === "replan") {
|
|
469
|
+
return applyReplan(store, conversationId, projectRoot, {
|
|
470
|
+
slug,
|
|
471
|
+
config: opts?.config,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return applyRun(store, conversationId, projectRoot, {
|
|
475
|
+
slug,
|
|
476
|
+
config: opts?.config,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
export { isRunnableTrack };
|
|
480
|
+
//# sourceMappingURL=phase-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-actions.js","sourceRoot":"","sources":["../src/phase-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { VerifyCommandConfig } from "./verify-report.js";
|
|
2
|
+
/** When the fix→confirm review chain may run on completed stops. */
|
|
3
|
+
export type ReviewScope = "executing_only" | "project";
|
|
4
|
+
export interface ProjectReviewConfig {
|
|
5
|
+
confirmRounds: number;
|
|
6
|
+
/** `executing_only` = after RUN; `project` = any product-code edit in this repo. */
|
|
7
|
+
reviewScope: ReviewScope;
|
|
8
|
+
verifyEnabled: boolean;
|
|
9
|
+
verifyCommands: VerifyCommandConfig[];
|
|
10
|
+
maxIdleStops: number;
|
|
11
|
+
/**
|
|
12
|
+
* Consecutive turn errors/aborts before `repeated_errors` pause.
|
|
13
|
+
* `0` = never pause on errors (unlimited recoveries).
|
|
14
|
+
*/
|
|
15
|
+
maxErrorsBeforePause: number;
|
|
16
|
+
locale: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_PROJECT_REVIEW_CONFIG: ProjectReviewConfig;
|
|
19
|
+
/**
|
|
20
|
+
* Load review runtime settings from `.autopilot/config.yml`.
|
|
21
|
+
* Missing / unreadable / corrupt → safe defaults (hook fail-open).
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadProjectReviewConfig(projectRoot: string): ProjectReviewConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Kẹp biên + làm sạch — mọi preloaded/config đều phải qua đây
|
|
26
|
+
* (không cho bypass confirm_rounds / idle / commands).
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizeProjectReviewConfig(raw: unknown): ProjectReviewConfig;
|
|
29
|
+
//# sourceMappingURL=project-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../src/project-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,oEAAoE;AACpE,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,6BAA6B,EAAE,mBAS3C,CAAC;AAqMF;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,GAClB,mBAAmB,CA6ErB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,GAAG,mBAAmB,CAmC9E"}
|