@ai-dossier/cli 0.9.1 → 0.11.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/README.md +345 -0
- package/dist/cache-resolver.d.ts.map +1 -1
- package/dist/cache-resolver.js +4 -16
- package/dist/cache-resolver.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +2 -14
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +113 -28
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +4 -3
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/runstate.d.ts +12 -0
- package/dist/commands/runstate.d.ts.map +1 -0
- package/dist/commands/runstate.js +819 -0
- package/dist/commands/runstate.js.map +1 -0
- package/dist/commands/traces.d.ts.map +1 -1
- package/dist/commands/traces.js +6 -7
- package/dist/commands/traces.js.map +1 -1
- package/dist/duration.d.ts +29 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/duration.js +63 -0
- package/dist/duration.js.map +1 -0
- package/dist/helpers.d.ts +8 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +17 -0
- package/dist/helpers.js.map +1 -1
- package/dist/issue-selection.d.ts +22 -0
- package/dist/issue-selection.d.ts.map +1 -0
- package/dist/issue-selection.js +88 -0
- package/dist/issue-selection.js.map +1 -0
- package/dist/runstate-stats.d.ts +157 -0
- package/dist/runstate-stats.d.ts.map +1 -0
- package/dist/runstate-stats.js +359 -0
- package/dist/runstate-stats.js.map +1 -0
- package/dist/runstate.d.ts +177 -0
- package/dist/runstate.d.ts.map +1 -0
- package/dist/runstate.js +438 -0
- package/dist/runstate.js.map +1 -0
- package/dist/table.d.ts +26 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +49 -0
- package/dist/table.js.map +1 -0
- package/dist/verify-dossier.d.ts.map +1 -1
- package/dist/verify-dossier.js +43 -22
- package/dist/verify-dossier.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runstate protocol (`runstate:v1`) — the milestone comments issue-workflow dossiers
|
|
3
|
+
* append to a GitHub issue after every phase.
|
|
4
|
+
*
|
|
5
|
+
* This module is the executable copy of the "Runstate Milestones" table in
|
|
6
|
+
* `imboard-ai/git/full-cycle-issue@3.8.0`. Dossiers used to ask agents to reproduce a
|
|
7
|
+
* markdown heredoc by hand; smaller models skipped it or pasted `$(date …)` literally.
|
|
8
|
+
* Everything here is pure and dependency-free so it can be unit tested without touching
|
|
9
|
+
* `gh`, the network, or the filesystem.
|
|
10
|
+
*/
|
|
11
|
+
/** Marker that opens every runstate comment. Readers filter on this exact prefix. */
|
|
12
|
+
export declare const RUNSTATE_MARKER = "<!-- runstate:v1 -->";
|
|
13
|
+
/** Workflow phases, in execution order. */
|
|
14
|
+
export declare const PHASES: readonly ["gate", "setup", "plan", "implement", "review", "ship", "report"];
|
|
15
|
+
export type Phase = (typeof PHASES)[number];
|
|
16
|
+
/** Milestone statuses. */
|
|
17
|
+
export declare const STATUSES: readonly ["done", "partial", "blocked", "awaiting-merge"];
|
|
18
|
+
export type Status = (typeof STATUSES)[number];
|
|
19
|
+
/**
|
|
20
|
+
* Keys whose values are paths and must therefore be absolute — the dossier rule is
|
|
21
|
+
* "paths are absolute", and a relative worktree path makes a resume unresolvable from
|
|
22
|
+
* a different working directory.
|
|
23
|
+
*/
|
|
24
|
+
export declare const PATH_KEYS: readonly ["worktree", "planning"];
|
|
25
|
+
/**
|
|
26
|
+
* Per-phase specification, transcribed from full-cycle-issue@3.8.0.
|
|
27
|
+
*
|
|
28
|
+
* `statuses` is the closed set a phase may report. `required` maps each status to the
|
|
29
|
+
* keys that must accompany it. `status=blocked` additionally requires `reason` for every
|
|
30
|
+
* phase (see {@link BLOCKED_REQUIRED}) — the dossier rule is "If a phase aborts, post
|
|
31
|
+
* `status=blocked` with `reason=<short-slug>` before stopping".
|
|
32
|
+
*/
|
|
33
|
+
export interface PhaseSpec {
|
|
34
|
+
statuses: readonly Status[];
|
|
35
|
+
required: Partial<Record<Status, readonly string[]>>;
|
|
36
|
+
}
|
|
37
|
+
/** Keys required whenever a phase reports `status=blocked`. */
|
|
38
|
+
export declare const BLOCKED_REQUIRED: readonly ["reason"];
|
|
39
|
+
/**
|
|
40
|
+
* Caps that keep a milestone postable. GitHub rejects an issue comment over 65536
|
|
41
|
+
* characters with an opaque 422, and `execFileSync` hits E2BIG well before that on some
|
|
42
|
+
* platforms — both surface as "gh failed" with no hint that size was the cause. Checking
|
|
43
|
+
* here turns those into a named key and a number.
|
|
44
|
+
*/
|
|
45
|
+
export declare const MAX_VALUE_LENGTH = 4000;
|
|
46
|
+
export declare const MAX_BODY_LENGTH = 60000;
|
|
47
|
+
export declare const PHASE_SPECS: Record<Phase, PhaseSpec>;
|
|
48
|
+
/** Consecutive `blocked` milestones on one phase that mean the run is looping. */
|
|
49
|
+
export declare const RESUME_LOOP_CAP = 3;
|
|
50
|
+
/** Every value `next=` may legally carry: a phase to re-enter, or `done`. */
|
|
51
|
+
export declare const NEXT_VALUES: readonly string[];
|
|
52
|
+
/** GitHub issue numbers are positive integers; anything else is a caller mistake. */
|
|
53
|
+
export declare function isIssueNumber(value: string): boolean;
|
|
54
|
+
/** True when `key` may carry spaces in its value. */
|
|
55
|
+
export declare function isAcKey(key: string): boolean;
|
|
56
|
+
export declare function isPhase(value: string): value is Phase;
|
|
57
|
+
export declare function isStatus(value: string): value is Status;
|
|
58
|
+
/**
|
|
59
|
+
* The phase that follows `phase`, for the milestone's `next=` line.
|
|
60
|
+
*
|
|
61
|
+
* - `blocked` ends the run, so `next=done`.
|
|
62
|
+
* - the two non-terminal statuses keep the run inside the same phase: ship's
|
|
63
|
+
* `awaiting-merge` is the FIRST of ship's two milestones (CI wait, then teardown),
|
|
64
|
+
* and a `partial` review still has agents left to run — which is exactly how
|
|
65
|
+
* gate-issue's resume table reads them back.
|
|
66
|
+
* - otherwise the linear order gate → setup → plan → implement → review → ship →
|
|
67
|
+
* report → done.
|
|
68
|
+
*/
|
|
69
|
+
export declare function defaultNext(phase: Phase, status: Status): Phase | 'done';
|
|
70
|
+
/** The keys `phase` must carry when reporting `status`. */
|
|
71
|
+
export declare function requiredKeys(phase: Phase, status: Status): readonly string[];
|
|
72
|
+
export interface MilestoneInput {
|
|
73
|
+
phase: string;
|
|
74
|
+
status: string;
|
|
75
|
+
run: string;
|
|
76
|
+
/** Phase-specific `key=value` pairs, in the order they should be emitted. */
|
|
77
|
+
keys?: Array<[string, string]>;
|
|
78
|
+
/** Override the computed `next=` value. */
|
|
79
|
+
next?: string;
|
|
80
|
+
/** Override the timestamp (tests); defaults to now. */
|
|
81
|
+
at?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate a milestone against the protocol.
|
|
85
|
+
*
|
|
86
|
+
* @returns one actionable line per problem; an empty array means valid.
|
|
87
|
+
*/
|
|
88
|
+
export declare function validateMilestone(input: MilestoneInput): string[];
|
|
89
|
+
/** Current time as `YYYY-MM-DDTHH:MM:SSZ` (the dossier template's `date -u` format). */
|
|
90
|
+
export declare function nowStamp(date?: Date): string;
|
|
91
|
+
/**
|
|
92
|
+
* Build the milestone comment body. Does not validate — call
|
|
93
|
+
* {@link validateMilestone} first.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildMilestone(input: MilestoneInput): string;
|
|
96
|
+
/**
|
|
97
|
+
* Split one `key=value` token at its FIRST `=`, so a value may itself contain `=`.
|
|
98
|
+
* Returns null when nothing precedes the separator.
|
|
99
|
+
*
|
|
100
|
+
* The single definition of the pair grammar: {@link parseMilestone} reads it back off an
|
|
101
|
+
* issue comment and the `--kv` flag parser reads it off argv, and the two must agree.
|
|
102
|
+
*/
|
|
103
|
+
export declare function splitPair(token: string): [string, string] | null;
|
|
104
|
+
export interface ParsedMilestone {
|
|
105
|
+
phase: string;
|
|
106
|
+
status: string;
|
|
107
|
+
run: string;
|
|
108
|
+
at: string;
|
|
109
|
+
next: string;
|
|
110
|
+
/** Every `key=value` line, including the ones from the header line. */
|
|
111
|
+
keys: Record<string, string>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Parse a runstate comment body. Returns `null` when `body` is not a runstate comment.
|
|
115
|
+
*
|
|
116
|
+
* Tolerant by design: a milestone posted by an older dossier (or a hand-written one)
|
|
117
|
+
* should still be readable by `runstate last` even if it would not pass validation.
|
|
118
|
+
*/
|
|
119
|
+
export declare function parseMilestone(body: string): ParsedMilestone | null;
|
|
120
|
+
/** Extract every runstate milestone from a list of comment bodies, oldest first. */
|
|
121
|
+
export declare function parseMilestones(bodies: string[]): ParsedMilestone[];
|
|
122
|
+
/** Mint a fresh run id: `r-<issue>-<4 hex>`. */
|
|
123
|
+
export declare function mintRunId(issue: number | string): string;
|
|
124
|
+
/**
|
|
125
|
+
* The world-facing checks the resume table needs. Injected so {@link computeResume}
|
|
126
|
+
* stays pure and testable — the command layer supplies the `git`/`gh`/`fs` versions.
|
|
127
|
+
*/
|
|
128
|
+
export interface ResumeProbe {
|
|
129
|
+
/** `git ls-remote --exit-code origin <branch>` succeeds. */
|
|
130
|
+
branchOnRemote(branch: string): boolean;
|
|
131
|
+
/** The worktree directory exists. */
|
|
132
|
+
dirExists(path: string): boolean;
|
|
133
|
+
/** The planning file exists. */
|
|
134
|
+
fileExists(path: string): boolean;
|
|
135
|
+
/** `git -C <worktree> rev-parse --short HEAD`, or null if it fails. */
|
|
136
|
+
headOf(worktree: string): string | null;
|
|
137
|
+
/** `gh pr view <pr> --json state,mergedAt,mergeable`, or null if it fails. */
|
|
138
|
+
prState(pr: string): {
|
|
139
|
+
state: string;
|
|
140
|
+
mergedAt: string | null;
|
|
141
|
+
mergeable: string;
|
|
142
|
+
} | null;
|
|
143
|
+
/** The issue's state is CLOSED. */
|
|
144
|
+
issueClosed(): boolean;
|
|
145
|
+
}
|
|
146
|
+
export interface ResumeResult {
|
|
147
|
+
/** Phase to resume from: a phase name, `ship-wait`, `ship-teardown`, `done`, or `none`. */
|
|
148
|
+
resume_from: string;
|
|
149
|
+
/** The run id to reuse, or null on a fresh run. */
|
|
150
|
+
run_id: string | null;
|
|
151
|
+
/** Checks that passed, for the gate milestone's `verified=` key. */
|
|
152
|
+
verified: string[];
|
|
153
|
+
/**
|
|
154
|
+
* Merged `key=value` state for the run: every milestone's keys, later milestones
|
|
155
|
+
* winning. Merged rather than last-only because a resume at `plan` still needs
|
|
156
|
+
* `branch`/`worktree` from the `setup` milestone.
|
|
157
|
+
*/
|
|
158
|
+
resume_context: Record<string, string>;
|
|
159
|
+
/** The last milestone, or null on a fresh run. */
|
|
160
|
+
last: ParsedMilestone | null;
|
|
161
|
+
/** Set when the run must hard-block instead of resuming (currently `resume-loop`). */
|
|
162
|
+
hard_block?: string;
|
|
163
|
+
/** Human-readable note, e.g. "already complete". */
|
|
164
|
+
note?: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* True when the last {@link RESUME_LOOP_CAP} milestones are all `blocked` on the same
|
|
168
|
+
* phase — the run is retrying the same wall and needs a human, not another resume.
|
|
169
|
+
*/
|
|
170
|
+
export declare function hitLoopCap(milestones: ParsedMilestone[]): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Resolve where a run should resume from, implementing the resume verification table in
|
|
173
|
+
* `imboard-ai/git/gate-issue`. Never trusts the milestone alone — every claim is checked
|
|
174
|
+
* against reality through `probe`, and {@link PHASE_RESUMERS} holds the per-phase rules.
|
|
175
|
+
*/
|
|
176
|
+
export declare function computeResume(milestones: ParsedMilestone[], probe: ResumeProbe): ResumeResult;
|
|
177
|
+
//# sourceMappingURL=runstate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runstate.d.ts","sourceRoot":"","sources":["../src/runstate.ts"],"names":[],"mappings":"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"}
|
package/dist/runstate.js
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Runstate protocol (`runstate:v1`) — the milestone comments issue-workflow dossiers
|
|
4
|
+
* append to a GitHub issue after every phase.
|
|
5
|
+
*
|
|
6
|
+
* This module is the executable copy of the "Runstate Milestones" table in
|
|
7
|
+
* `imboard-ai/git/full-cycle-issue@3.8.0`. Dossiers used to ask agents to reproduce a
|
|
8
|
+
* markdown heredoc by hand; smaller models skipped it or pasted `$(date …)` literally.
|
|
9
|
+
* Everything here is pure and dependency-free so it can be unit tested without touching
|
|
10
|
+
* `gh`, the network, or the filesystem.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.NEXT_VALUES = exports.RESUME_LOOP_CAP = exports.PHASE_SPECS = exports.MAX_BODY_LENGTH = exports.MAX_VALUE_LENGTH = exports.BLOCKED_REQUIRED = exports.PATH_KEYS = exports.STATUSES = exports.PHASES = exports.RUNSTATE_MARKER = void 0;
|
|
14
|
+
exports.isIssueNumber = isIssueNumber;
|
|
15
|
+
exports.isAcKey = isAcKey;
|
|
16
|
+
exports.isPhase = isPhase;
|
|
17
|
+
exports.isStatus = isStatus;
|
|
18
|
+
exports.defaultNext = defaultNext;
|
|
19
|
+
exports.requiredKeys = requiredKeys;
|
|
20
|
+
exports.validateMilestone = validateMilestone;
|
|
21
|
+
exports.nowStamp = nowStamp;
|
|
22
|
+
exports.buildMilestone = buildMilestone;
|
|
23
|
+
exports.splitPair = splitPair;
|
|
24
|
+
exports.parseMilestone = parseMilestone;
|
|
25
|
+
exports.parseMilestones = parseMilestones;
|
|
26
|
+
exports.mintRunId = mintRunId;
|
|
27
|
+
exports.hitLoopCap = hitLoopCap;
|
|
28
|
+
exports.computeResume = computeResume;
|
|
29
|
+
const node_crypto_1 = require("node:crypto");
|
|
30
|
+
/** Marker that opens every runstate comment. Readers filter on this exact prefix. */
|
|
31
|
+
exports.RUNSTATE_MARKER = '<!-- runstate:v1 -->';
|
|
32
|
+
/** Workflow phases, in execution order. */
|
|
33
|
+
exports.PHASES = ['gate', 'setup', 'plan', 'implement', 'review', 'ship', 'report'];
|
|
34
|
+
/** Milestone statuses. */
|
|
35
|
+
exports.STATUSES = ['done', 'partial', 'blocked', 'awaiting-merge'];
|
|
36
|
+
/**
|
|
37
|
+
* Keys whose values are paths and must therefore be absolute — the dossier rule is
|
|
38
|
+
* "paths are absolute", and a relative worktree path makes a resume unresolvable from
|
|
39
|
+
* a different working directory.
|
|
40
|
+
*/
|
|
41
|
+
exports.PATH_KEYS = ['worktree', 'planning'];
|
|
42
|
+
/** Keys required whenever a phase reports `status=blocked`. */
|
|
43
|
+
exports.BLOCKED_REQUIRED = ['reason'];
|
|
44
|
+
/**
|
|
45
|
+
* Caps that keep a milestone postable. GitHub rejects an issue comment over 65536
|
|
46
|
+
* characters with an opaque 422, and `execFileSync` hits E2BIG well before that on some
|
|
47
|
+
* platforms — both surface as "gh failed" with no hint that size was the cause. Checking
|
|
48
|
+
* here turns those into a named key and a number.
|
|
49
|
+
*/
|
|
50
|
+
exports.MAX_VALUE_LENGTH = 4000;
|
|
51
|
+
exports.MAX_BODY_LENGTH = 60000;
|
|
52
|
+
/**
|
|
53
|
+
* `review` reports the same keys whether it finished or still has agents pending, so the
|
|
54
|
+
* list lives once — a key added to one status must never drift from the other.
|
|
55
|
+
*/
|
|
56
|
+
const REVIEW_KEYS = ['head', 'fixed', 'escalated', 'agents_done', 'agents_pending'];
|
|
57
|
+
exports.PHASE_SPECS = {
|
|
58
|
+
gate: {
|
|
59
|
+
statuses: ['done', 'blocked'],
|
|
60
|
+
required: { done: ['base_branch', 'warnings'] },
|
|
61
|
+
},
|
|
62
|
+
setup: {
|
|
63
|
+
statuses: ['done', 'blocked'],
|
|
64
|
+
required: { done: ['branch', 'worktree', 'pool_claimed', 'base_branch'] },
|
|
65
|
+
},
|
|
66
|
+
plan: {
|
|
67
|
+
statuses: ['done', 'blocked'],
|
|
68
|
+
required: { done: ['planning', 'head', 'open_questions', 'visual_review'] },
|
|
69
|
+
},
|
|
70
|
+
implement: {
|
|
71
|
+
statuses: ['done', 'blocked'],
|
|
72
|
+
required: { done: ['head', 'files', 'tests_added', 'tests_run', 'ci_parity'] },
|
|
73
|
+
},
|
|
74
|
+
review: {
|
|
75
|
+
statuses: ['done', 'partial', 'blocked'],
|
|
76
|
+
required: { done: REVIEW_KEYS, partial: REVIEW_KEYS },
|
|
77
|
+
},
|
|
78
|
+
ship: {
|
|
79
|
+
statuses: ['awaiting-merge', 'done', 'blocked'],
|
|
80
|
+
required: {
|
|
81
|
+
'awaiting-merge': ['pr', 'head', 'ci_fix_attempts'],
|
|
82
|
+
done: ['pr', 'merge_commit', 'ci_fix_attempts', 'cleanup'],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
report: {
|
|
86
|
+
statuses: ['done'],
|
|
87
|
+
required: { done: ['pr', 'traps_added'] },
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* `r-<issue>-<hex>`, minted once per run by the gate phase. Accepts four or more hex
|
|
92
|
+
* chars so a longer id from another minter still reads back as valid.
|
|
93
|
+
*/
|
|
94
|
+
const RUN_ID_RE = /^r-\d+-[0-9a-f]{4,}$/;
|
|
95
|
+
/** Random bytes in a minted run id; 2 bytes renders as the 4 hex chars in `r-440-ab56`. */
|
|
96
|
+
const RUN_ID_RANDOM_BYTES = 2;
|
|
97
|
+
/** Characters in the abbreviated SHA `git rev-parse --short HEAD` prints. */
|
|
98
|
+
const SHORT_SHA_LENGTH = 7;
|
|
99
|
+
/** Consecutive `blocked` milestones on one phase that mean the run is looping. */
|
|
100
|
+
exports.RESUME_LOOP_CAP = 3;
|
|
101
|
+
/** Suffix `implement` milestones add to `head=` when the worktree had uncommitted changes. */
|
|
102
|
+
const DIRTY_HEAD_SUFFIX_RE = /-dirty$/;
|
|
103
|
+
/** Every value `next=` may legally carry: a phase to re-enter, or `done`. */
|
|
104
|
+
exports.NEXT_VALUES = [...exports.PHASES, 'done'];
|
|
105
|
+
/** GitHub issue numbers are positive integers; anything else is a caller mistake. */
|
|
106
|
+
function isIssueNumber(value) {
|
|
107
|
+
return /^[1-9]\d*$/.test(value);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Keys exempt from the no-spaces rule: acceptance-criterion lines are prose by nature.
|
|
111
|
+
* Matches `ac`, `ac1`, `ac_results`, `ac2_note`, …
|
|
112
|
+
*/
|
|
113
|
+
const AC_KEY_RE = /^ac(\d+)?(_[a-z0-9_]+)?$/;
|
|
114
|
+
/** True when `key` may carry spaces in its value. */
|
|
115
|
+
function isAcKey(key) {
|
|
116
|
+
return AC_KEY_RE.test(key);
|
|
117
|
+
}
|
|
118
|
+
function isPhase(value) {
|
|
119
|
+
return exports.PHASES.includes(value);
|
|
120
|
+
}
|
|
121
|
+
function isStatus(value) {
|
|
122
|
+
return exports.STATUSES.includes(value);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The phase that follows `phase`, for the milestone's `next=` line.
|
|
126
|
+
*
|
|
127
|
+
* - `blocked` ends the run, so `next=done`.
|
|
128
|
+
* - the two non-terminal statuses keep the run inside the same phase: ship's
|
|
129
|
+
* `awaiting-merge` is the FIRST of ship's two milestones (CI wait, then teardown),
|
|
130
|
+
* and a `partial` review still has agents left to run — which is exactly how
|
|
131
|
+
* gate-issue's resume table reads them back.
|
|
132
|
+
* - otherwise the linear order gate → setup → plan → implement → review → ship →
|
|
133
|
+
* report → done.
|
|
134
|
+
*/
|
|
135
|
+
function defaultNext(phase, status) {
|
|
136
|
+
if (status === 'blocked')
|
|
137
|
+
return 'done';
|
|
138
|
+
if (status === 'awaiting-merge' || status === 'partial')
|
|
139
|
+
return phase;
|
|
140
|
+
const idx = exports.PHASES.indexOf(phase);
|
|
141
|
+
return idx === exports.PHASES.length - 1 ? 'done' : exports.PHASES[idx + 1];
|
|
142
|
+
}
|
|
143
|
+
/** The keys `phase` must carry when reporting `status`. */
|
|
144
|
+
function requiredKeys(phase, status) {
|
|
145
|
+
const spec = exports.PHASE_SPECS[phase];
|
|
146
|
+
const base = spec.required[status] ?? [];
|
|
147
|
+
return status === 'blocked' ? [...base, ...exports.BLOCKED_REQUIRED] : base;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The single most important thing wrong with one `key=value` pair, or null when it is
|
|
151
|
+
* well-formed. Checked in the order an author would want to hear about them.
|
|
152
|
+
*/
|
|
153
|
+
function firstKeyProblem(key, value) {
|
|
154
|
+
if (!/^[a-z][a-z0-9_]*$/.test(key)) {
|
|
155
|
+
return `Invalid key '${key}' — use lower_snake_case, e.g. base_branch`;
|
|
156
|
+
}
|
|
157
|
+
if (value === '') {
|
|
158
|
+
return `Key '${key}' has an empty value — omit the key or give it a value`;
|
|
159
|
+
}
|
|
160
|
+
if (value.includes('$')) {
|
|
161
|
+
return `Key '${key}' contains '$' — values must be literal; shell expansions like $(date …) end up pasted verbatim`;
|
|
162
|
+
}
|
|
163
|
+
// Checked before the ac* whitespace exemption: one milestone line is one key, so a
|
|
164
|
+
// newline in ANY value silently splits into extra `key=` lines that readers would
|
|
165
|
+
// parse as real state. Not exempt for ac* keys.
|
|
166
|
+
if (/[\r\n]/.test(value)) {
|
|
167
|
+
return `Key '${key}' contains a newline — every value must be a single line, or it splits into extra key= lines in the posted comment; collapse it (use ' / ' or ',') and retry`;
|
|
168
|
+
}
|
|
169
|
+
if (value.length > exports.MAX_VALUE_LENGTH) {
|
|
170
|
+
return `Key '${key}' is ${value.length} characters — the maximum is ${exports.MAX_VALUE_LENGTH}; summarise it (e.g. a count, or a path to the full text) instead of inlining it`;
|
|
171
|
+
}
|
|
172
|
+
if (/\s/.test(value) && !isAcKey(key)) {
|
|
173
|
+
return `Key '${key}' contains whitespace — values must not contain spaces (use '-' or ','); only ac* keys are exempt`;
|
|
174
|
+
}
|
|
175
|
+
if (exports.PATH_KEYS.includes(key) && !value.startsWith('/')) {
|
|
176
|
+
return `Key '${key}' must be an absolute path, got '${value}'`;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Validate a milestone against the protocol.
|
|
182
|
+
*
|
|
183
|
+
* @returns one actionable line per problem; an empty array means valid.
|
|
184
|
+
*/
|
|
185
|
+
function validateMilestone(input) {
|
|
186
|
+
const errors = [];
|
|
187
|
+
const { phase, status, run } = input;
|
|
188
|
+
const keys = input.keys ?? [];
|
|
189
|
+
if (!isPhase(phase)) {
|
|
190
|
+
errors.push(`Unknown phase '${phase}' — expected one of: ${exports.PHASES.join(', ')}`);
|
|
191
|
+
}
|
|
192
|
+
if (!isStatus(status)) {
|
|
193
|
+
errors.push(`Unknown status '${status}' — expected one of: ${exports.STATUSES.join(', ')}`);
|
|
194
|
+
}
|
|
195
|
+
else if (isPhase(phase)) {
|
|
196
|
+
const allowed = exports.PHASE_SPECS[phase].statuses;
|
|
197
|
+
if (!allowed.includes(status)) {
|
|
198
|
+
errors.push(`Status '${status}' is not valid for phase '${phase}' — expected one of: ${allowed.join(', ')}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!RUN_ID_RE.test(run)) {
|
|
202
|
+
errors.push(`Invalid run id '${run}' — expected r-<issue>-<hex>, e.g. r-440-ab56 (mint one with: ai-dossier runstate mint --issue <n>)`);
|
|
203
|
+
}
|
|
204
|
+
// An unchecked --next lands verbatim in the comment: a typo sends the next resume to a
|
|
205
|
+
// phase that does not exist, and whitespace/newlines corrupt the line outright.
|
|
206
|
+
if (input.next !== undefined && !exports.NEXT_VALUES.includes(input.next)) {
|
|
207
|
+
errors.push(`Invalid --next '${input.next}' — expected one of: ${exports.NEXT_VALUES.join(', ')} (omit --next to use the default for this phase and status)`);
|
|
208
|
+
}
|
|
209
|
+
// One line per offending key — an agent fixes the first problem with a value and
|
|
210
|
+
// re-runs, so listing every way the same value is wrong is noise, not help.
|
|
211
|
+
const seen = new Map();
|
|
212
|
+
for (const [key, value] of keys) {
|
|
213
|
+
if (seen.has(key)) {
|
|
214
|
+
errors.push(`Duplicate key '${key}' — each key may appear at most once`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
seen.set(key, value);
|
|
218
|
+
const problem = firstKeyProblem(key, value);
|
|
219
|
+
if (problem)
|
|
220
|
+
errors.push(problem);
|
|
221
|
+
}
|
|
222
|
+
if (isPhase(phase) && isStatus(status) && exports.PHASE_SPECS[phase].statuses.includes(status)) {
|
|
223
|
+
const missing = requiredKeys(phase, status).filter((k) => !seen.has(k));
|
|
224
|
+
if (missing.length > 0) {
|
|
225
|
+
errors.push(`Phase '${phase}' with status '${status}' requires ${missing.map((k) => `${k}=`).join(' ')} — add with --kv ${missing.map((k) => `${k}=<value>`).join(' --kv ')}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return errors;
|
|
229
|
+
}
|
|
230
|
+
/** Current time as `YYYY-MM-DDTHH:MM:SSZ` (the dossier template's `date -u` format). */
|
|
231
|
+
function nowStamp(date = new Date()) {
|
|
232
|
+
return `${date.toISOString().slice(0, 19)}Z`;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Build the milestone comment body. Does not validate — call
|
|
236
|
+
* {@link validateMilestone} first.
|
|
237
|
+
*/
|
|
238
|
+
function buildMilestone(input) {
|
|
239
|
+
const at = input.at ?? nowStamp();
|
|
240
|
+
const next = input.next ??
|
|
241
|
+
(isPhase(input.phase) && isStatus(input.status)
|
|
242
|
+
? defaultNext(input.phase, input.status)
|
|
243
|
+
: 'done');
|
|
244
|
+
const lines = [
|
|
245
|
+
exports.RUNSTATE_MARKER,
|
|
246
|
+
`phase=${input.phase} status=${input.status} run=${input.run} at=${at}`,
|
|
247
|
+
...(input.keys ?? []).map(([k, v]) => `${k}=${v}`),
|
|
248
|
+
`next=${next}`,
|
|
249
|
+
];
|
|
250
|
+
return `${lines.join('\n')}\n`;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Split one `key=value` token at its FIRST `=`, so a value may itself contain `=`.
|
|
254
|
+
* Returns null when nothing precedes the separator.
|
|
255
|
+
*
|
|
256
|
+
* The single definition of the pair grammar: {@link parseMilestone} reads it back off an
|
|
257
|
+
* issue comment and the `--kv` flag parser reads it off argv, and the two must agree.
|
|
258
|
+
*/
|
|
259
|
+
function splitPair(token) {
|
|
260
|
+
const eq = token.indexOf('=');
|
|
261
|
+
if (eq <= 0)
|
|
262
|
+
return null;
|
|
263
|
+
return [token.slice(0, eq), token.slice(eq + 1)];
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Parse a runstate comment body. Returns `null` when `body` is not a runstate comment.
|
|
267
|
+
*
|
|
268
|
+
* Tolerant by design: a milestone posted by an older dossier (or a hand-written one)
|
|
269
|
+
* should still be readable by `runstate last` even if it would not pass validation.
|
|
270
|
+
*/
|
|
271
|
+
function parseMilestone(body) {
|
|
272
|
+
if (!body.startsWith(exports.RUNSTATE_MARKER))
|
|
273
|
+
return null;
|
|
274
|
+
const keys = {};
|
|
275
|
+
const lines = body.split('\n').slice(1);
|
|
276
|
+
for (const raw of lines) {
|
|
277
|
+
const line = raw.trim();
|
|
278
|
+
if (line === '' || line.startsWith('<!--'))
|
|
279
|
+
continue;
|
|
280
|
+
// The header line packs several pairs; later lines carry exactly one each, and
|
|
281
|
+
// their values may contain spaces (ac* keys), so only the header is split on space.
|
|
282
|
+
const isHeader = line.startsWith('phase=');
|
|
283
|
+
const pairs = isHeader ? line.split(/\s+/) : [line];
|
|
284
|
+
for (const pair of pairs) {
|
|
285
|
+
const kv = splitPair(pair);
|
|
286
|
+
if (!kv)
|
|
287
|
+
continue;
|
|
288
|
+
const [key, value] = kv;
|
|
289
|
+
if (!(key in keys))
|
|
290
|
+
keys[key] = value;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
phase: keys.phase ?? '',
|
|
295
|
+
status: keys.status ?? '',
|
|
296
|
+
run: keys.run ?? '',
|
|
297
|
+
at: keys.at ?? '',
|
|
298
|
+
next: keys.next ?? '',
|
|
299
|
+
keys,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/** Extract every runstate milestone from a list of comment bodies, oldest first. */
|
|
303
|
+
function parseMilestones(bodies) {
|
|
304
|
+
const out = [];
|
|
305
|
+
for (const body of bodies) {
|
|
306
|
+
const parsed = parseMilestone(body);
|
|
307
|
+
if (parsed)
|
|
308
|
+
out.push(parsed);
|
|
309
|
+
}
|
|
310
|
+
return out;
|
|
311
|
+
}
|
|
312
|
+
/** Mint a fresh run id: `r-<issue>-<4 hex>`. */
|
|
313
|
+
function mintRunId(issue) {
|
|
314
|
+
return `r-${issue}-${(0, node_crypto_1.randomBytes)(RUN_ID_RANDOM_BYTES).toString('hex')}`;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* True when the last {@link RESUME_LOOP_CAP} milestones are all `blocked` on the same
|
|
318
|
+
* phase — the run is retrying the same wall and needs a human, not another resume.
|
|
319
|
+
*/
|
|
320
|
+
function hitLoopCap(milestones) {
|
|
321
|
+
if (milestones.length < exports.RESUME_LOOP_CAP)
|
|
322
|
+
return false;
|
|
323
|
+
const streak = milestones.slice(-exports.RESUME_LOOP_CAP);
|
|
324
|
+
return (streak.every((m) => m.status === 'blocked') &&
|
|
325
|
+
streak.every((m) => m.phase === streak[0].phase) &&
|
|
326
|
+
streak[0].phase !== '');
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Where each phase's run re-enters, given that its own milestone is the latest one.
|
|
330
|
+
*
|
|
331
|
+
* Every phase downstream of `setup` re-checks the setup claims first: a branch deleted on
|
|
332
|
+
* the remote or a reaped worktree invalidates everything recorded after it, so the run
|
|
333
|
+
* has to rebuild the workspace before it can trust its own later milestones.
|
|
334
|
+
*/
|
|
335
|
+
const PHASE_RESUMERS = {
|
|
336
|
+
gate: () => ({ resume_from: 'setup' }),
|
|
337
|
+
setup: (scan) => ({ resume_from: scan.setupOk() ? 'plan' : 'setup' }),
|
|
338
|
+
plan: (scan) => {
|
|
339
|
+
if (!scan.setupOk())
|
|
340
|
+
return { resume_from: 'setup' };
|
|
341
|
+
const planning = scan.context.planning;
|
|
342
|
+
if (!planning || !scan.probe.fileExists(planning))
|
|
343
|
+
return { resume_from: 'plan' };
|
|
344
|
+
scan.pass('planning');
|
|
345
|
+
return { resume_from: 'implement' };
|
|
346
|
+
},
|
|
347
|
+
implement: (scan) => {
|
|
348
|
+
if (!scan.setupOk())
|
|
349
|
+
return { resume_from: 'setup' };
|
|
350
|
+
const head = scan.probe.headOf(scan.context.worktree);
|
|
351
|
+
const claimed = (scan.last.keys.head ?? '').replace(DIRTY_HEAD_SUFFIX_RE, '');
|
|
352
|
+
// The milestone may record a longer or shorter abbreviation than `--short` prints,
|
|
353
|
+
// so compare on the short-SHA prefix rather than for equality.
|
|
354
|
+
if (!head || !claimed || !head.startsWith(claimed.slice(0, SHORT_SHA_LENGTH))) {
|
|
355
|
+
return { resume_from: 'implement' };
|
|
356
|
+
}
|
|
357
|
+
scan.pass('head');
|
|
358
|
+
return { resume_from: 'review' };
|
|
359
|
+
},
|
|
360
|
+
review: (scan) => {
|
|
361
|
+
if (!scan.setupOk())
|
|
362
|
+
return { resume_from: 'setup' };
|
|
363
|
+
// A `partial` review still has agents left to run.
|
|
364
|
+
return { resume_from: scan.last.status === 'partial' ? 'review' : 'ship' };
|
|
365
|
+
},
|
|
366
|
+
ship: (scan) => {
|
|
367
|
+
if (scan.last.status === 'done')
|
|
368
|
+
return { resume_from: 'report' };
|
|
369
|
+
// awaiting-merge: the PR itself decides where to re-enter ship.
|
|
370
|
+
const pr = scan.last.keys.pr;
|
|
371
|
+
const state = pr ? scan.probe.prState(pr) : null;
|
|
372
|
+
if (!state)
|
|
373
|
+
return { resume_from: 'ship' };
|
|
374
|
+
scan.pass('pr');
|
|
375
|
+
if (state.mergedAt)
|
|
376
|
+
return { resume_from: 'ship-teardown' };
|
|
377
|
+
if (state.state === 'OPEN' && state.mergeable === 'MERGEABLE') {
|
|
378
|
+
return { resume_from: 'ship-wait' };
|
|
379
|
+
}
|
|
380
|
+
return { resume_from: 'ship' };
|
|
381
|
+
},
|
|
382
|
+
report: (scan) => {
|
|
383
|
+
if (!scan.probe.issueClosed())
|
|
384
|
+
return { resume_from: 'report' };
|
|
385
|
+
scan.pass('issue-closed');
|
|
386
|
+
return { resume_from: 'done', note: 'already complete' };
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Resolve where a run should resume from, implementing the resume verification table in
|
|
391
|
+
* `imboard-ai/git/gate-issue`. Never trusts the milestone alone — every claim is checked
|
|
392
|
+
* against reality through `probe`, and {@link PHASE_RESUMERS} holds the per-phase rules.
|
|
393
|
+
*/
|
|
394
|
+
function computeResume(milestones, probe) {
|
|
395
|
+
if (milestones.length === 0) {
|
|
396
|
+
return { resume_from: 'none', run_id: null, verified: [], resume_context: {}, last: null };
|
|
397
|
+
}
|
|
398
|
+
const context = {};
|
|
399
|
+
for (const m of milestones)
|
|
400
|
+
Object.assign(context, m.keys);
|
|
401
|
+
const last = milestones[milestones.length - 1];
|
|
402
|
+
const verified = [];
|
|
403
|
+
const base = { run_id: last.run || null, verified, resume_context: context, last };
|
|
404
|
+
if (hitLoopCap(milestones)) {
|
|
405
|
+
return { ...base, resume_from: last.phase, hard_block: 'resume-loop' };
|
|
406
|
+
}
|
|
407
|
+
// Any blocked milestone resumes at that same phase.
|
|
408
|
+
if (last.status === 'blocked') {
|
|
409
|
+
return { ...base, resume_from: last.phase || 'none' };
|
|
410
|
+
}
|
|
411
|
+
// A phase this version does not know — a hand-written comment, or one written by a
|
|
412
|
+
// newer dossier — is not resumable, so the caller starts over.
|
|
413
|
+
if (!isPhase(last.phase)) {
|
|
414
|
+
return { ...base, resume_from: 'none' };
|
|
415
|
+
}
|
|
416
|
+
const pass = (check) => {
|
|
417
|
+
if (!verified.includes(check))
|
|
418
|
+
verified.push(check);
|
|
419
|
+
};
|
|
420
|
+
const setupOk = () => {
|
|
421
|
+
const { branch, worktree } = context;
|
|
422
|
+
if (!branch || !worktree)
|
|
423
|
+
return false;
|
|
424
|
+
let ok = true;
|
|
425
|
+
if (probe.branchOnRemote(branch))
|
|
426
|
+
pass('branch');
|
|
427
|
+
else
|
|
428
|
+
ok = false;
|
|
429
|
+
if (probe.dirExists(worktree))
|
|
430
|
+
pass('worktree');
|
|
431
|
+
else
|
|
432
|
+
ok = false;
|
|
433
|
+
return ok;
|
|
434
|
+
};
|
|
435
|
+
const { resume_from, note } = PHASE_RESUMERS[last.phase]({ last, context, probe, pass, setupOk });
|
|
436
|
+
return { ...base, resume_from, ...(note ? { note } : {}) };
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=runstate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runstate.js","sourceRoot":"","sources":["../src/runstate.ts"],"names":[],"mappings":"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"}
|