@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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -0
  3. package/dist/autopilot-ignore.d.ts +23 -0
  4. package/dist/autopilot-ignore.d.ts.map +1 -0
  5. package/dist/autopilot-ignore.js +271 -0
  6. package/dist/autopilot-ignore.js.map +1 -0
  7. package/dist/checklist-md.d.ts +62 -0
  8. package/dist/checklist-md.d.ts.map +1 -0
  9. package/dist/checklist-md.js +217 -0
  10. package/dist/checklist-md.js.map +1 -0
  11. package/dist/code-edit-detector.d.ts +10 -0
  12. package/dist/code-edit-detector.d.ts.map +1 -0
  13. package/dist/code-edit-detector.js +44 -0
  14. package/dist/code-edit-detector.js.map +1 -0
  15. package/dist/i18n-render.d.ts +3 -0
  16. package/dist/i18n-render.d.ts.map +1 -0
  17. package/dist/i18n-render.js +8 -0
  18. package/dist/i18n-render.js.map +1 -0
  19. package/dist/index.d.ts +20 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +20 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/list-tracks.d.ts +29 -0
  24. package/dist/list-tracks.d.ts.map +1 -0
  25. package/dist/list-tracks.js +232 -0
  26. package/dist/list-tracks.js.map +1 -0
  27. package/dist/migrate.d.ts +19 -0
  28. package/dist/migrate.d.ts.map +1 -0
  29. package/dist/migrate.js +101 -0
  30. package/dist/migrate.js.map +1 -0
  31. package/dist/phase-actions.d.ts +35 -0
  32. package/dist/phase-actions.d.ts.map +1 -0
  33. package/dist/phase-actions.js +480 -0
  34. package/dist/phase-actions.js.map +1 -0
  35. package/dist/project-config.d.ts +29 -0
  36. package/dist/project-config.d.ts.map +1 -0
  37. package/dist/project-config.js +301 -0
  38. package/dist/project-config.js.map +1 -0
  39. package/dist/project-path.d.ts +26 -0
  40. package/dist/project-path.d.ts.map +1 -0
  41. package/dist/project-path.js +104 -0
  42. package/dist/project-path.js.map +1 -0
  43. package/dist/review-engine.d.ts +263 -0
  44. package/dist/review-engine.d.ts.map +1 -0
  45. package/dist/review-engine.js +2273 -0
  46. package/dist/review-engine.js.map +1 -0
  47. package/dist/review-i18n.d.ts +29 -0
  48. package/dist/review-i18n.d.ts.map +1 -0
  49. package/dist/review-i18n.js +54 -0
  50. package/dist/review-i18n.js.map +1 -0
  51. package/dist/review-lenses.d.ts +13 -0
  52. package/dist/review-lenses.d.ts.map +1 -0
  53. package/dist/review-lenses.js +43 -0
  54. package/dist/review-lenses.js.map +1 -0
  55. package/dist/review-runtime.d.ts +12 -0
  56. package/dist/review-runtime.d.ts.map +1 -0
  57. package/dist/review-runtime.js +37 -0
  58. package/dist/review-runtime.js.map +1 -0
  59. package/dist/review-scope.d.ts +9 -0
  60. package/dist/review-scope.d.ts.map +1 -0
  61. package/dist/review-scope.js +92 -0
  62. package/dist/review-scope.js.map +1 -0
  63. package/dist/sqlite.d.ts +15 -0
  64. package/dist/sqlite.d.ts.map +1 -0
  65. package/dist/sqlite.js +38 -0
  66. package/dist/sqlite.js.map +1 -0
  67. package/dist/state-store.d.ts +277 -0
  68. package/dist/state-store.d.ts.map +1 -0
  69. package/dist/state-store.js +1091 -0
  70. package/dist/state-store.js.map +1 -0
  71. package/dist/track-slug.d.ts +4 -0
  72. package/dist/track-slug.d.ts.map +1 -0
  73. package/dist/track-slug.js +18 -0
  74. package/dist/track-slug.js.map +1 -0
  75. package/dist/transcript-followup.d.ts +59 -0
  76. package/dist/transcript-followup.d.ts.map +1 -0
  77. package/dist/transcript-followup.js +310 -0
  78. package/dist/transcript-followup.js.map +1 -0
  79. package/dist/trigger-parser.d.ts +54 -0
  80. package/dist/trigger-parser.d.ts.map +1 -0
  81. package/dist/trigger-parser.js +250 -0
  82. package/dist/trigger-parser.js.map +1 -0
  83. package/dist/verify-report.d.ts +52 -0
  84. package/dist/verify-report.d.ts.map +1 -0
  85. package/dist/verify-report.js +195 -0
  86. package/dist/verify-report.js.map +1 -0
  87. package/package.json +41 -0
@@ -0,0 +1,250 @@
1
+ import { isSafeTrackSlug } from "./track-slug.js";
2
+ export const DEFAULT_TRIGGERS = {
3
+ match: "line_start",
4
+ on: ["Autopilot ON", "Enable autopilot", "开启自动驾驶"],
5
+ run: ["Autopilot RUN", "Start execution", "开始执行"],
6
+ off: ["Autopilot OFF", "Disable autopilot", "关闭自动驾驶"],
7
+ resume: ["Autopilot RESUME", "继续执行"],
8
+ replan: ["Autopilot REPLAN", "修改方案"],
9
+ resume_review: ["Resume review", "继续自审"],
10
+ };
11
+ const SLASH_MAP = {
12
+ "autopilot-on": "on",
13
+ "autopilot-run": "run",
14
+ "autopilot-off": "off",
15
+ "autopilot-resume": "resume",
16
+ "autopilot-replan": "replan",
17
+ };
18
+ /** Prefixes that count as harness followups (E8: do not clear chain_pending). */
19
+ export const HARNESS_FOLLOWUP_PREFIXES = [
20
+ "Review fix round",
21
+ "Review confirm",
22
+ "Advance checklist",
23
+ "All checklist items done",
24
+ "Stuck:",
25
+ "Recover:",
26
+ "Review complete",
27
+ "Verify failed",
28
+ "自审修复",
29
+ "自审确认",
30
+ "自审完成",
31
+ "推进下一项",
32
+ "全部完成",
33
+ "校验失败",
34
+ // Match zh recover/stuck templates (fullwidth colon) — bare「恢复」is too broad.
35
+ "恢复:",
36
+ "卡住:",
37
+ // Halfwidth colon variants (same as isRecoverOrStuckFollowupMessage).
38
+ "恢复:",
39
+ "卡住:",
40
+ ];
41
+ function stripUserQuery(prompt) {
42
+ const m = prompt.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/i);
43
+ return (m?.[1] ?? prompt).trim();
44
+ }
45
+ /**
46
+ * Prompt body after stripping `<user_query>` and leading markup lines
47
+ * (`<timestamp>…</timestamp>`, etc.). Keeps the remainder of a multiline tip.
48
+ */
49
+ export function substantivePromptBody(text) {
50
+ const body = stripUserQuery(text || "");
51
+ const lines = body.split(/\r?\n/);
52
+ let i = 0;
53
+ while (i < lines.length) {
54
+ const trimmed = lines[i].trim();
55
+ if (!trimmed) {
56
+ i++;
57
+ continue;
58
+ }
59
+ // Cursor may prepend <timestamp>...</timestamp>.
60
+ if (trimmed.startsWith("<") && trimmed.includes(">")) {
61
+ i++;
62
+ continue;
63
+ }
64
+ break;
65
+ }
66
+ return lines.slice(i).join("\n").trim();
67
+ }
68
+ /** First non-empty line of {@link substantivePromptBody}. */
69
+ export function firstSubstantiveLine(text) {
70
+ const body = substantivePromptBody(text);
71
+ if (!body)
72
+ return "";
73
+ return body.split(/\r?\n/)[0]?.trim() ?? "";
74
+ }
75
+ export function isHarnessFollowupMessage(text) {
76
+ // Cursor may wrap the prompt in <user_query> and/or a leading <timestamp> line.
77
+ const line = firstSubstantiveLine(text);
78
+ if (!line)
79
+ return false;
80
+ return HARNESS_FOLLOWUP_PREFIXES.some((p) => line.startsWith(p));
81
+ }
82
+ /**
83
+ * Recover automation prompts (not stuck). Used for error-recover coalesce/CAS.
84
+ * Must tolerate <user_query> / <timestamp> wrappers like isHarnessFollowupMessage.
85
+ */
86
+ export function isRecoverFollowupMessage(text) {
87
+ const line = firstSubstantiveLine(text);
88
+ if (!line)
89
+ return false;
90
+ return (line.startsWith("Recover:") ||
91
+ line.startsWith("恢复:") ||
92
+ line.startsWith("恢复:"));
93
+ }
94
+ /**
95
+ * Recover / stuck automation prompts. Safe to drop on user Stop or ordinary chat
96
+ * (unlike fix/confirm pending, which must survive for lens redelivery).
97
+ */
98
+ export function isRecoverOrStuckFollowupMessage(text) {
99
+ const line = firstSubstantiveLine(text);
100
+ if (!line)
101
+ return false;
102
+ return (isRecoverFollowupMessage(line) ||
103
+ line.startsWith("Stuck:") ||
104
+ line.startsWith("卡住:") ||
105
+ line.startsWith("卡住:"));
106
+ }
107
+ /** Cursor / host phrases that mean the user clicked Stop (not a model crash). */
108
+ export const USER_ABORT_MARKERS = [
109
+ "user aborted",
110
+ "interrupted manually",
111
+ "aborted/interrupted",
112
+ ];
113
+ export function isUserAbortText(text) {
114
+ const low = (text || "").toLowerCase();
115
+ if (!low.trim())
116
+ return false;
117
+ return USER_ABORT_MARKERS.some((m) => low.includes(m));
118
+ }
119
+ function firstLine(text) {
120
+ return text.trim().split(/\r?\n/)[0]?.trim() ?? "";
121
+ }
122
+ function matchTextTrigger(line, phrases) {
123
+ for (const phrase of phrases) {
124
+ if (line === phrase || line.startsWith(phrase + " ") || line.startsWith(phrase + "·") || line.startsWith(phrase + " ·")) {
125
+ let rest = line.slice(phrase.length).trim();
126
+ rest = rest.replace(/^[·•]\s*/, "").trim();
127
+ return { matched: phrase, rest };
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ function parseSlugAndBrief(rest) {
133
+ if (!rest)
134
+ return {};
135
+ // token optional then · slug or free text
136
+ const parts = rest.split(/\s*·\s*/);
137
+ if (parts.length >= 2) {
138
+ const maybeSlug = parts[1].trim();
139
+ if (isSafeTrackSlug(maybeSlug)) {
140
+ return { slug: maybeSlug, initialBrief: parts.slice(2).join(" · ").trim() || undefined };
141
+ }
142
+ }
143
+ if (isSafeTrackSlug(rest)) {
144
+ return { slug: rest };
145
+ }
146
+ return { initialBrief: rest };
147
+ }
148
+ export function parseTrigger(options) {
149
+ const { conversationId, projectRoot, triggers = DEFAULT_TRIGGERS, pendingAction, } = options;
150
+ const text = stripUserQuery(options.prompt);
151
+ const line = firstLine(text);
152
+ // Slash: /autopilot-on … or bare skill name
153
+ const slash = line.match(/^\/?(autopilot-(?:on|run|off|resume|replan))(?:\s+(.*))?$/i);
154
+ if (slash) {
155
+ const command = slash[1].toLowerCase();
156
+ const kind = SLASH_MAP[command];
157
+ if (!kind)
158
+ return null;
159
+ const rest = (slash[2] ?? "").trim();
160
+ const event = {
161
+ kind,
162
+ source: "slash",
163
+ command,
164
+ conversationId,
165
+ projectRoot,
166
+ };
167
+ if (kind === "on") {
168
+ const { slug, initialBrief } = parseSlugAndBrief(rest);
169
+ if (slug)
170
+ event.slug = slug;
171
+ if (initialBrief || (!slug && rest))
172
+ event.initialBrief = initialBrief ?? rest;
173
+ }
174
+ else if (kind === "run" || kind === "replan" || kind === "resume") {
175
+ const { slug, initialBrief } = parseSlugAndBrief(rest);
176
+ if (slug)
177
+ event.slug = slug;
178
+ else if (rest && kind !== "resume") {
179
+ event.slug = rest.split(/\s+/)[0];
180
+ }
181
+ else if (rest && kind === "resume") {
182
+ // Single token → pass through (applyResume rejects unsafe). Multi-word
183
+ // free text → no slug (bare resume). Do not silently drop illegal slugs.
184
+ const token = rest.split(/\s+/)[0];
185
+ if (token === rest)
186
+ event.slug = token;
187
+ }
188
+ if (initialBrief && kind !== "resume")
189
+ event.initialBrief = initialBrief;
190
+ }
191
+ return event;
192
+ }
193
+ const cfg = { ...DEFAULT_TRIGGERS, ...triggers };
194
+ const kinds = [
195
+ { kind: "on", phrases: cfg.on },
196
+ { kind: "run", phrases: cfg.run },
197
+ { kind: "off", phrases: cfg.off },
198
+ { kind: "resume", phrases: cfg.resume },
199
+ { kind: "replan", phrases: cfg.replan },
200
+ { kind: "resume_review", phrases: cfg.resume_review },
201
+ ];
202
+ for (const { kind, phrases } of kinds) {
203
+ const hit = matchTextTrigger(line, phrases);
204
+ if (!hit)
205
+ continue;
206
+ const event = {
207
+ kind,
208
+ source: "text",
209
+ conversationId,
210
+ projectRoot,
211
+ };
212
+ if (kind === "on") {
213
+ const { slug, initialBrief } = parseSlugAndBrief(hit.rest);
214
+ if (slug)
215
+ event.slug = slug;
216
+ if (initialBrief || (!slug && hit.rest))
217
+ event.initialBrief = initialBrief ?? hit.rest;
218
+ }
219
+ else if (kind === "run" || kind === "replan" || kind === "resume") {
220
+ const { slug } = parseSlugAndBrief(hit.rest);
221
+ if (slug)
222
+ event.slug = slug;
223
+ else if (hit.rest && kind !== "resume") {
224
+ event.slug = hit.rest.split(/\s+/)[0];
225
+ }
226
+ else if (hit.rest && kind === "resume") {
227
+ // Single token → pass through (applyResume rejects unsafe). Multi-word
228
+ // free text → no slug (bare resume).
229
+ const token = hit.rest.split(/\s+/)[0];
230
+ if (token === hit.rest)
231
+ event.slug = token;
232
+ }
233
+ }
234
+ return event;
235
+ }
236
+ // track_pick when pending
237
+ if (pendingAction === "run" || pendingAction === "replan") {
238
+ if (/^\d+$/.test(line) || isSafeTrackSlug(line)) {
239
+ return {
240
+ kind: "track_pick",
241
+ source: "text",
242
+ trackPick: line,
243
+ conversationId,
244
+ projectRoot,
245
+ };
246
+ }
247
+ }
248
+ return null;
249
+ }
250
+ //# sourceMappingURL=trigger-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-parser.js","sourceRoot":"","sources":["../src/trigger-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { ChecklistItem } from "./checklist-md.js";
2
+ export interface VerifyCommandConfig {
3
+ id: string;
4
+ run?: string;
5
+ required?: boolean;
6
+ }
7
+ export interface VerifyCommandResult {
8
+ id: string;
9
+ exitCode?: number;
10
+ required?: boolean;
11
+ stdoutTail?: string;
12
+ stderrTail?: string;
13
+ durationMs?: number;
14
+ }
15
+ export interface VerifyLastReport {
16
+ itemId: string;
17
+ checklistPath: string;
18
+ ranAt: string;
19
+ commands: VerifyCommandResult[];
20
+ }
21
+ export type VerifyOutcome = "pass" | "fail" | "skip";
22
+ export interface VerifyEvaluation {
23
+ outcome: VerifyOutcome;
24
+ reason?: string;
25
+ }
26
+ /** Cap hostile/symlink-replaced verify-last.json so stop-hook cannot OOM. */
27
+ export declare const MAX_VERIFY_REPORT_BYTES = 1048576;
28
+ export declare function readVerifyReport(reportPath: string, opts?: {
29
+ projectRoot?: string;
30
+ }): VerifyLastReport | null;
31
+ export declare function evaluateVerifyReport(options: {
32
+ enabled: boolean;
33
+ commands: VerifyCommandConfig[];
34
+ reportPath: string;
35
+ currentItem: ChecklistItem | null;
36
+ checklistPath: string;
37
+ /** When set, refuse report files whose realpath escapes the project. */
38
+ projectRoot?: string;
39
+ }): VerifyEvaluation;
40
+ /**
41
+ * Soft completion evidence for no-code checklist E0 continue when verify is
42
+ * skipped (disabled / no required commands). Requires a readable in-project
43
+ * report whose itemId matches the current checklist item. Optional `ok: false`
44
+ * blocks; missing `ok` is allowed.
45
+ */
46
+ export declare function hasNoCodeCompletionEvidence(options: {
47
+ reportPath: string;
48
+ currentItemId: string;
49
+ projectRoot?: string;
50
+ }): boolean;
51
+ export declare function defaultVerifyReportPath(projectRoot: string): string;
52
+ //# sourceMappingURL=verify-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-report.d.ts","sourceRoot":"","sources":["../src/verify-report.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,UAAY,CAAC;AAEjD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,gBAAgB,GAAG,IAAI,CAgDzB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,aAAa,GAAG,IAAI,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,gBAAgB,CAqGnB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CA4CV;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAInE"}
@@ -0,0 +1,195 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { isRealpathInsideProject, normalizeProjectRoot, } from "./project-path.js";
4
+ /** Cap hostile/symlink-replaced verify-last.json so stop-hook cannot OOM. */
5
+ export const MAX_VERIFY_REPORT_BYTES = 1_048_576;
6
+ export function readVerifyReport(reportPath, opts) {
7
+ // Untrusted project path: refuse empty/NUL/symlinks; size-cap before parse.
8
+ if (!reportPath || reportPath.includes("\0"))
9
+ return null;
10
+ // Provided root must normalize; blank/padded/NUL → refuse (fail closed).
11
+ let root;
12
+ if (opts?.projectRoot !== undefined && opts?.projectRoot !== null) {
13
+ const n = normalizeProjectRoot(opts.projectRoot);
14
+ if (!n)
15
+ return null;
16
+ root = n;
17
+ }
18
+ try {
19
+ const nofollow = typeof fs.constants.O_NOFOLLOW === "number" ? fs.constants.O_NOFOLLOW : 0;
20
+ if (nofollow === 0) {
21
+ const lst = fs.lstatSync(reportPath);
22
+ if (lst.isSymbolicLink() || !lst.isFile())
23
+ return null;
24
+ }
25
+ const fd = fs.openSync(reportPath, fs.constants.O_RDONLY | nofollow);
26
+ try {
27
+ const st = fs.fstatSync(fd);
28
+ if (!st.isFile() || st.size > MAX_VERIFY_REPORT_BYTES)
29
+ return null;
30
+ // Bind fd to the path's current identity. Always — not only when O_NOFOLLOW
31
+ // is missing. Otherwise an attacker can: (1) pass pre-open realpath check,
32
+ // (2) swap an intermediate dir so open() follows to an outside file,
33
+ // (3) swap back so post-open realpath looks in-project, then we would
34
+ // read the outside inode via the already-open fd.
35
+ const lst = fs.lstatSync(reportPath);
36
+ if (lst.isSymbolicLink() || !lst.isFile())
37
+ return null;
38
+ if (lst.ino !== st.ino || lst.dev !== st.dev)
39
+ return null;
40
+ // Re-check containment after open (O_NOFOLLOW only covers the final component).
41
+ if (root && !isRealpathInsideProject(root, reportPath)) {
42
+ return null;
43
+ }
44
+ const buf = Buffer.alloc(st.size);
45
+ const n = fs.readSync(fd, buf, 0, st.size, 0);
46
+ const raw = buf.subarray(0, n).toString("utf8");
47
+ if (Buffer.byteLength(raw, "utf8") > MAX_VERIFY_REPORT_BYTES)
48
+ return null;
49
+ const parsed = JSON.parse(raw);
50
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
51
+ return null;
52
+ }
53
+ return parsed;
54
+ }
55
+ finally {
56
+ fs.closeSync(fd);
57
+ }
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ export function evaluateVerifyReport(options) {
64
+ const { enabled, commands, reportPath, currentItem, checklistPath, projectRoot, } = options;
65
+ if (!enabled) {
66
+ return { outcome: "skip", reason: "verify disabled" };
67
+ }
68
+ const commandList = Array.isArray(commands) ? commands : [];
69
+ const requiredCommands = commandList.filter((c) => c.required === true);
70
+ if (requiredCommands.length === 0) {
71
+ return { outcome: "skip", reason: "no required commands" };
72
+ }
73
+ // If caller supplied a projectRoot, it must normalize (trim blank/NUL).
74
+ // Fail closed: do not skip containment; never path.resolve on padded absolute
75
+ // roots (Node treats " /abs " as cwd-relative).
76
+ let root;
77
+ if (projectRoot !== undefined && projectRoot !== null) {
78
+ const n = typeof projectRoot === "string"
79
+ ? normalizeProjectRoot(projectRoot)
80
+ : null;
81
+ if (!n) {
82
+ return { outcome: "fail", reason: "missing verify report" };
83
+ }
84
+ root = n;
85
+ }
86
+ // Resolve relative report paths against normalized projectRoot (not cwd).
87
+ // Refuse NUL in reportPath before resolve — Node will otherwise embed \0 in the path.
88
+ const resolvedReportPath = root &&
89
+ typeof reportPath === "string" &&
90
+ reportPath &&
91
+ !reportPath.includes("\0")
92
+ ? path.resolve(root, reportPath)
93
+ : reportPath;
94
+ // Existing report must stay in-project (intermediate dir symlink / poisoned path).
95
+ // Missing path: fall through — readVerifyReport returns null → missing report.
96
+ if (root) {
97
+ try {
98
+ fs.lstatSync(resolvedReportPath);
99
+ if (!isRealpathInsideProject(root, resolvedReportPath)) {
100
+ return { outcome: "fail", reason: "missing verify report" };
101
+ }
102
+ }
103
+ catch {
104
+ /* missing / unreadable — handled below */
105
+ }
106
+ }
107
+ const report = readVerifyReport(resolvedReportPath, {
108
+ projectRoot: root,
109
+ });
110
+ if (!report || typeof report !== "object") {
111
+ return { outcome: "fail", reason: "missing verify report" };
112
+ }
113
+ if (!currentItem) {
114
+ return { outcome: "fail", reason: "no current checklist item" };
115
+ }
116
+ if (typeof report.itemId !== "string" || report.itemId !== currentItem.id) {
117
+ return { outcome: "fail", reason: "itemId mismatch" };
118
+ }
119
+ if (typeof report.checklistPath !== "string" ||
120
+ report.checklistPath !== checklistPath) {
121
+ return { outcome: "fail", reason: "checklistPath mismatch" };
122
+ }
123
+ if (!Array.isArray(report.commands)) {
124
+ return { outcome: "fail", reason: "invalid commands array" };
125
+ }
126
+ for (const cmd of requiredCommands) {
127
+ const result = report.commands.find((r) => !!r && typeof r === "object" && !Array.isArray(r) && r.id === cmd.id);
128
+ if (!result) {
129
+ return { outcome: "fail", reason: `missing result for ${cmd.id}` };
130
+ }
131
+ if (typeof result.exitCode !== "number" || !Number.isFinite(result.exitCode)) {
132
+ return { outcome: "fail", reason: `missing exitCode for ${cmd.id}` };
133
+ }
134
+ if (result.exitCode !== 0) {
135
+ return { outcome: "fail", reason: `${cmd.id} exit ${result.exitCode}` };
136
+ }
137
+ }
138
+ return { outcome: "pass" };
139
+ }
140
+ /**
141
+ * Soft completion evidence for no-code checklist E0 continue when verify is
142
+ * skipped (disabled / no required commands). Requires a readable in-project
143
+ * report whose itemId matches the current checklist item. Optional `ok: false`
144
+ * blocks; missing `ok` is allowed.
145
+ */
146
+ export function hasNoCodeCompletionEvidence(options) {
147
+ const { reportPath, currentItemId, projectRoot } = options;
148
+ if (!currentItemId || typeof currentItemId !== "string")
149
+ return false;
150
+ let root;
151
+ if (projectRoot !== undefined && projectRoot !== null) {
152
+ const n = typeof projectRoot === "string"
153
+ ? normalizeProjectRoot(projectRoot)
154
+ : null;
155
+ if (!n)
156
+ return false;
157
+ root = n;
158
+ }
159
+ const resolvedReportPath = root &&
160
+ typeof reportPath === "string" &&
161
+ reportPath &&
162
+ !reportPath.includes("\0")
163
+ ? path.resolve(root, reportPath)
164
+ : reportPath;
165
+ if (root) {
166
+ try {
167
+ fs.lstatSync(resolvedReportPath);
168
+ if (!isRealpathInsideProject(root, resolvedReportPath)) {
169
+ return false;
170
+ }
171
+ }
172
+ catch {
173
+ return false;
174
+ }
175
+ }
176
+ const report = readVerifyReport(resolvedReportPath, {
177
+ projectRoot: root,
178
+ });
179
+ if (!report || typeof report !== "object")
180
+ return false;
181
+ if (typeof report.itemId !== "string" || report.itemId !== currentItemId) {
182
+ return false;
183
+ }
184
+ const ok = report.ok;
185
+ // Only a boolean false rejects; other types / missing ok are allowed.
186
+ if (ok === false)
187
+ return false;
188
+ return true;
189
+ }
190
+ export function defaultVerifyReportPath(projectRoot) {
191
+ // Prefer normalized root so padded absolutes do not become cwd-relative joins.
192
+ const root = normalizeProjectRoot(projectRoot) ?? "";
193
+ return path.join(root, ".autopilot", "verify-last.json");
194
+ }
195
+ //# sourceMappingURL=verify-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-report.js","sourceRoot":"","sources":["../src/verify-report.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@autopilot-harness/core",
3
+ "version": "0.1.0",
4
+ "description": "Autopilot harness core: state store, review engine, checklist",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mt2007/autopilot-harness.git",
9
+ "directory": "packages/core"
10
+ },
11
+ "homepage": "https://github.com/mt2007/autopilot-harness#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/mt2007/autopilot-harness/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "dependencies": {},
28
+ "devDependencies": {
29
+ "typescript": "^5.8.2"
30
+ },
31
+ "engines": {
32
+ "node": ">=22"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.json",
39
+ "typecheck": "tsc -p tsconfig.json --noEmit"
40
+ }
41
+ }