@delegance/claude-autopilot 5.2.2 → 6.2.2

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 (130) hide show
  1. package/CHANGELOG.md +1027 -1
  2. package/README.md +104 -17
  3. package/dist/src/adapters/council/claude.js +2 -1
  4. package/dist/src/adapters/council/openai.js +14 -7
  5. package/dist/src/adapters/deploy/_http.d.ts +43 -0
  6. package/dist/src/adapters/deploy/_http.js +99 -0
  7. package/dist/src/adapters/deploy/fly.d.ts +206 -0
  8. package/dist/src/adapters/deploy/fly.js +696 -0
  9. package/dist/src/adapters/deploy/generic.d.ts +39 -0
  10. package/dist/src/adapters/deploy/generic.js +98 -0
  11. package/dist/src/adapters/deploy/index.d.ts +15 -0
  12. package/dist/src/adapters/deploy/index.js +78 -0
  13. package/dist/src/adapters/deploy/render.d.ts +181 -0
  14. package/dist/src/adapters/deploy/render.js +550 -0
  15. package/dist/src/adapters/deploy/types.d.ts +221 -0
  16. package/dist/src/adapters/deploy/types.js +15 -0
  17. package/dist/src/adapters/deploy/vercel.d.ts +143 -0
  18. package/dist/src/adapters/deploy/vercel.js +426 -0
  19. package/dist/src/adapters/pricing.d.ts +36 -0
  20. package/dist/src/adapters/pricing.js +40 -0
  21. package/dist/src/adapters/review-engine/claude.js +2 -1
  22. package/dist/src/adapters/review-engine/codex.js +12 -8
  23. package/dist/src/adapters/review-engine/gemini.js +2 -1
  24. package/dist/src/adapters/review-engine/openai-compatible.js +2 -1
  25. package/dist/src/adapters/sdk-loader.d.ts +15 -0
  26. package/dist/src/adapters/sdk-loader.js +77 -0
  27. package/dist/src/cli/autopilot.d.ts +71 -0
  28. package/dist/src/cli/autopilot.js +735 -0
  29. package/dist/src/cli/brainstorm.d.ts +23 -0
  30. package/dist/src/cli/brainstorm.js +131 -0
  31. package/dist/src/cli/costs.d.ts +15 -1
  32. package/dist/src/cli/costs.js +99 -10
  33. package/dist/src/cli/deploy.d.ts +71 -0
  34. package/dist/src/cli/deploy.js +539 -0
  35. package/dist/src/cli/fix.d.ts +18 -0
  36. package/dist/src/cli/fix.js +105 -11
  37. package/dist/src/cli/help-text.d.ts +52 -0
  38. package/dist/src/cli/help-text.js +400 -0
  39. package/dist/src/cli/implement.d.ts +91 -0
  40. package/dist/src/cli/implement.js +196 -0
  41. package/dist/src/cli/index.js +784 -222
  42. package/dist/src/cli/json-envelope.d.ts +187 -0
  43. package/dist/src/cli/json-envelope.js +270 -0
  44. package/dist/src/cli/json-mode.d.ts +33 -0
  45. package/dist/src/cli/json-mode.js +201 -0
  46. package/dist/src/cli/migrate.d.ts +111 -0
  47. package/dist/src/cli/migrate.js +305 -0
  48. package/dist/src/cli/plan.d.ts +81 -0
  49. package/dist/src/cli/plan.js +149 -0
  50. package/dist/src/cli/pr.d.ts +106 -0
  51. package/dist/src/cli/pr.js +191 -19
  52. package/dist/src/cli/preflight.js +102 -1
  53. package/dist/src/cli/review.d.ts +27 -0
  54. package/dist/src/cli/review.js +126 -0
  55. package/dist/src/cli/runs-watch-renderer.d.ts +45 -0
  56. package/dist/src/cli/runs-watch-renderer.js +275 -0
  57. package/dist/src/cli/runs-watch.d.ts +41 -0
  58. package/dist/src/cli/runs-watch.js +395 -0
  59. package/dist/src/cli/runs.d.ts +122 -0
  60. package/dist/src/cli/runs.js +902 -0
  61. package/dist/src/cli/scan.d.ts +93 -0
  62. package/dist/src/cli/scan.js +166 -40
  63. package/dist/src/cli/spec.d.ts +66 -0
  64. package/dist/src/cli/spec.js +132 -0
  65. package/dist/src/cli/validate.d.ts +29 -0
  66. package/dist/src/cli/validate.js +131 -0
  67. package/dist/src/core/config/schema.d.ts +43 -0
  68. package/dist/src/core/config/schema.js +25 -0
  69. package/dist/src/core/config/types.d.ts +17 -0
  70. package/dist/src/core/council/runner.d.ts +10 -1
  71. package/dist/src/core/council/runner.js +25 -3
  72. package/dist/src/core/council/types.d.ts +7 -0
  73. package/dist/src/core/errors.d.ts +1 -1
  74. package/dist/src/core/errors.js +12 -0
  75. package/dist/src/core/logging/redaction.d.ts +13 -0
  76. package/dist/src/core/logging/redaction.js +20 -0
  77. package/dist/src/core/migrate/detector-rules.js +6 -0
  78. package/dist/src/core/migrate/schema-validator.js +22 -1
  79. package/dist/src/core/phases/static-rules.d.ts +5 -1
  80. package/dist/src/core/phases/static-rules.js +2 -5
  81. package/dist/src/core/run-state/budget.d.ts +88 -0
  82. package/dist/src/core/run-state/budget.js +141 -0
  83. package/dist/src/core/run-state/cli-internal.d.ts +21 -0
  84. package/dist/src/core/run-state/cli-internal.js +174 -0
  85. package/dist/src/core/run-state/events.d.ts +59 -0
  86. package/dist/src/core/run-state/events.js +504 -0
  87. package/dist/src/core/run-state/lock.d.ts +61 -0
  88. package/dist/src/core/run-state/lock.js +206 -0
  89. package/dist/src/core/run-state/phase-context.d.ts +60 -0
  90. package/dist/src/core/run-state/phase-context.js +108 -0
  91. package/dist/src/core/run-state/phase-registry.d.ts +137 -0
  92. package/dist/src/core/run-state/phase-registry.js +162 -0
  93. package/dist/src/core/run-state/phase-runner.d.ts +80 -0
  94. package/dist/src/core/run-state/phase-runner.js +447 -0
  95. package/dist/src/core/run-state/provider-readback.d.ts +130 -0
  96. package/dist/src/core/run-state/provider-readback.js +426 -0
  97. package/dist/src/core/run-state/replay-decision.d.ts +69 -0
  98. package/dist/src/core/run-state/replay-decision.js +144 -0
  99. package/dist/src/core/run-state/resolve-engine.d.ts +100 -0
  100. package/dist/src/core/run-state/resolve-engine.js +190 -0
  101. package/dist/src/core/run-state/resume-preflight.d.ts +66 -0
  102. package/dist/src/core/run-state/resume-preflight.js +116 -0
  103. package/dist/src/core/run-state/run-phase-with-lifecycle.d.ts +73 -0
  104. package/dist/src/core/run-state/run-phase-with-lifecycle.js +186 -0
  105. package/dist/src/core/run-state/runs.d.ts +57 -0
  106. package/dist/src/core/run-state/runs.js +288 -0
  107. package/dist/src/core/run-state/snapshot.d.ts +14 -0
  108. package/dist/src/core/run-state/snapshot.js +114 -0
  109. package/dist/src/core/run-state/state.d.ts +40 -0
  110. package/dist/src/core/run-state/state.js +164 -0
  111. package/dist/src/core/run-state/types.d.ts +278 -0
  112. package/dist/src/core/run-state/types.js +13 -0
  113. package/dist/src/core/run-state/ulid.d.ts +11 -0
  114. package/dist/src/core/run-state/ulid.js +95 -0
  115. package/dist/src/core/schema-alignment/extractor/index.d.ts +1 -1
  116. package/dist/src/core/schema-alignment/extractor/index.js +2 -2
  117. package/dist/src/core/schema-alignment/extractor/prisma.d.ts +13 -1
  118. package/dist/src/core/schema-alignment/extractor/prisma.js +65 -10
  119. package/dist/src/core/schema-alignment/git-history.d.ts +19 -0
  120. package/dist/src/core/schema-alignment/git-history.js +53 -0
  121. package/dist/src/core/static-rules/rules/brand-tokens.js +2 -2
  122. package/dist/src/core/static-rules/rules/schema-alignment.js +14 -4
  123. package/package.json +9 -5
  124. package/scripts/autoregress.ts +3 -2
  125. package/skills/claude-autopilot.md +1 -1
  126. package/skills/make-interfaces-feel-better/SKILL.md +104 -0
  127. package/skills/migrate/SKILL.md +193 -47
  128. package/skills/simplify-ui/SKILL.md +103 -0
  129. package/skills/ui/SKILL.md +117 -0
  130. package/skills/ui-ux-pro-max/SKILL.md +90 -0
@@ -0,0 +1,141 @@
1
+ // src/core/run-state/budget.ts
2
+ //
3
+ // v6 Phase 4 — budget enforcement policy.
4
+ //
5
+ // Pure data + a pure decision function. No IO, no globals, no side effects.
6
+ // `checkPhaseBudget` is the authoritative answer to "may this phase run?"
7
+ // — `runPhase` consumes the result, emits a `budget.check` event with the
8
+ // full payload, and throws `budget_exceeded` on hard-fail.
9
+ //
10
+ // Two-layer policy per spec (Codex CRITICAL #3 fold-in — estimates can fail
11
+ // open, the runtime guard MUST run independently):
12
+ //
13
+ // - Layer 1 (advisory) — only fires when the phase declares
14
+ // `estimateCost`. Compares `actualSoFar + estimate.high` against
15
+ // `perRunUSD`. Pause-and-prompt (interactive) or hard-fail (CI mode)
16
+ // if it would exceed.
17
+ // - Layer 2 (mandatory) — ALWAYS runs. Compares `actualSoFar +
18
+ // conservativePhaseReserveUSD` against `perRunUSD`. Phases without
19
+ // estimates therefore still trigger budget gates. Default reserve is
20
+ // $5 (overridable in config).
21
+ // - `perPhaseUSD` gate — if set AND the larger of the per-phase estimate
22
+ // or reserve would push this phase's cost over the per-phase cap,
23
+ // applies the same pause/hard-fail rule.
24
+ //
25
+ // Spec: docs/specs/v6-run-state-engine.md "Budget enforcement".
26
+ /** Default Layer 2 reserve when none is configured. Conservative — phases
27
+ * without an `estimateCost` are assumed to consume at least this much,
28
+ * which keeps the cap from "failing open" the moment a phase forgets to
29
+ * declare its cost shape. */
30
+ export const DEFAULT_CONSERVATIVE_PHASE_RESERVE_USD = 5;
31
+ /** Policy decision for a single about-to-run phase. Pure — no IO. The
32
+ * caller (`runPhase`) is responsible for emitting the `budget.check`
33
+ * event with this payload and acting on the decision. */
34
+ export function checkPhaseBudget(opts) {
35
+ const { budget, phaseName, phaseIdx, estimatedCost, actualSoFarUSD, nonInteractive, } = opts;
36
+ // v6.2.0 — `'phase'` (default for back-compat) vs `'run'` (orchestrator).
37
+ // The math is intentionally identical between the two; `actualSoFarUSD`
38
+ // is already the cross-phase sum produced by `sumRunCost` in
39
+ // phase-runner.ts. The flag exists so the `budget.check` event tells
40
+ // observers which scope generated the decision and so future policy
41
+ // tweaks (e.g. divergent perPhase reserves under run scope) have a
42
+ // place to land without an event-shape break.
43
+ const scope = budget.scope ?? 'phase';
44
+ const reserveFloor = typeof budget.conservativePhaseReserveUSD === 'number'
45
+ ? budget.conservativePhaseReserveUSD
46
+ : DEFAULT_CONSERVATIVE_PHASE_RESERVE_USD;
47
+ // The reserve actually deducted is the larger of "what the phase says
48
+ // it will cost (high end)" and "the conservative floor we always apply".
49
+ // This is the core of Codex CRITICAL #3 — even if estimateCost is
50
+ // present and tiny, the floor still applies, and even if estimateCost
51
+ // is absent, the floor still applies.
52
+ const estimatedHigh = estimatedCost?.highUSD ?? null;
53
+ const reserveApplied = Math.max(estimatedHigh ?? 0, reserveFloor);
54
+ const projected = actualSoFarUSD + reserveApplied;
55
+ const capRemaining = budget.perRunUSD - projected;
56
+ // Layer 1 — ADVISORY using the explicit estimate. Runs FIRST so a precise
57
+ // estimate produces a precise reason ("estimate would exceed cap") instead
58
+ // of falling through to Layer 2's conservative-floor wording. Only fires
59
+ // when an estimate is present AND would push us past perRunUSD on its own.
60
+ // (Bugbot LOW on PR #89 caught the prior ordering, where Layer 2 always
61
+ // ran first and Layer 1 was provably unreachable since `reserveApplied =
62
+ // max(estimatedHigh, floor) >= estimatedHigh`.)
63
+ if (estimatedHigh !== null && actualSoFarUSD + estimatedHigh > budget.perRunUSD) {
64
+ const decision = nonInteractive ? 'hard-fail' : 'pause';
65
+ return {
66
+ decision,
67
+ phase: phaseName,
68
+ phaseIdx,
69
+ estimatedHigh,
70
+ actualSoFar: actualSoFarUSD,
71
+ reserveApplied,
72
+ capRemaining: budget.perRunUSD - (actualSoFarUSD + estimatedHigh),
73
+ reason: `advisory estimate would exceed run cap — actual ` +
74
+ `$${fmtUSD(actualSoFarUSD)} + estimate.high ` +
75
+ `$${fmtUSD(estimatedHigh)} > perRunUSD $${fmtUSD(budget.perRunUSD)}`,
76
+ scope,
77
+ };
78
+ }
79
+ // Layer 2 — MANDATORY floor against perRunUSD. Catches the case where the
80
+ // estimate is missing (Layer 1 didn't fire) OR present-but-tiny (estimate
81
+ // alone fits, but the conservative reserve floor pushes over). This is the
82
+ // safety net that prevents phases without `estimateCost` from sneaking
83
+ // past the cap.
84
+ if (projected > budget.perRunUSD) {
85
+ const decision = nonInteractive ? 'hard-fail' : 'pause';
86
+ return {
87
+ decision,
88
+ phase: phaseName,
89
+ phaseIdx,
90
+ estimatedHigh,
91
+ actualSoFar: actualSoFarUSD,
92
+ reserveApplied,
93
+ capRemaining,
94
+ reason: `run cap exceeded — actual $${fmtUSD(actualSoFarUSD)} + reserve ` +
95
+ `$${fmtUSD(reserveApplied)} = $${fmtUSD(projected)} > perRunUSD ` +
96
+ `$${fmtUSD(budget.perRunUSD)}`,
97
+ scope,
98
+ };
99
+ }
100
+ // perPhaseUSD gate — independent of the run cap. Applies the same
101
+ // reserve logic but compares against the per-phase cap.
102
+ if (typeof budget.perPhaseUSD === 'number' && reserveApplied > budget.perPhaseUSD) {
103
+ const decision = nonInteractive ? 'hard-fail' : 'pause';
104
+ return {
105
+ decision,
106
+ phase: phaseName,
107
+ phaseIdx,
108
+ estimatedHigh,
109
+ actualSoFar: actualSoFarUSD,
110
+ reserveApplied,
111
+ capRemaining,
112
+ reason: `per-phase cap exceeded — reserve $${fmtUSD(reserveApplied)} > ` +
113
+ `perPhaseUSD $${fmtUSD(budget.perPhaseUSD)}`,
114
+ scope,
115
+ };
116
+ }
117
+ return {
118
+ decision: 'proceed',
119
+ phase: phaseName,
120
+ phaseIdx,
121
+ estimatedHigh,
122
+ actualSoFar: actualSoFarUSD,
123
+ reserveApplied,
124
+ capRemaining,
125
+ reason: estimatedHigh !== null
126
+ ? `within budget — projected $${fmtUSD(projected)} of $${fmtUSD(budget.perRunUSD)}`
127
+ : `within budget (no estimate, applied $${fmtUSD(reserveApplied)} ` +
128
+ `reserve floor) — projected $${fmtUSD(projected)} of ` +
129
+ `$${fmtUSD(budget.perRunUSD)}`,
130
+ scope,
131
+ };
132
+ }
133
+ /** Format a USD amount with 2 decimal places for human-readable reasons.
134
+ * Kept local — the run-state module doesn't have a shared formatter and
135
+ * budget reasons are the only consumer. */
136
+ function fmtUSD(n) {
137
+ // toFixed(2) returns "0.00" for 0; we keep the trailing zeros so the
138
+ // reason strings line up visually in CLI output.
139
+ return n.toFixed(2);
140
+ }
141
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1,21 @@
1
+ /** Result of a single internal-CLI invocation. The dispatcher in
2
+ * src/cli/index.ts converts this to an exit code + console output. Pure
3
+ * data so we can unit-test the dispatch shape without spawning a child. */
4
+ export interface RunInternalCliResult {
5
+ /** Process exit code. */
6
+ exit: number;
7
+ /** Lines to print on stdout (text mode only). */
8
+ stdout: string[];
9
+ /** Lines to print on stderr (text mode only). */
10
+ stderr: string[];
11
+ }
12
+ export interface RunInternalCliOptions {
13
+ /** argv after `claude-autopilot internal`. e.g. ['log-phase-event',
14
+ * '--run-id', '01HZK', '--event', '{...}']. */
15
+ args: string[];
16
+ /** Working directory containing `.guardrail-cache/runs/`. Defaults to
17
+ * process.cwd(). */
18
+ cwd?: string;
19
+ }
20
+ export declare function runInternalCli(opts: RunInternalCliOptions): Promise<RunInternalCliResult>;
21
+ //# sourceMappingURL=cli-internal.d.ts.map
@@ -0,0 +1,174 @@
1
+ // src/core/run-state/cli-internal.ts
2
+ //
3
+ // Hidden CLI verb: `claude-autopilot internal log-phase-event`.
4
+ //
5
+ // Markdown-driven skills (brainstorm, plan, implement) can't directly import
6
+ // the run-state module — they spawn `claude-autopilot` as a subprocess. This
7
+ // helper gives them a one-shot way to append a typed event into a known run
8
+ // without rewriting the skills as TypeScript modules.
9
+ //
10
+ // Surface:
11
+ //
12
+ // claude-autopilot internal log-phase-event \
13
+ // --run-id 01HZK7... \
14
+ // --event '<json>' \
15
+ // [--cwd /path/to/repo]
16
+ //
17
+ // `<json>` is the RunEventInput shape (no seq/ts/runId/schema_version/
18
+ // writerId — the appender fills those in). Examples:
19
+ //
20
+ // --event '{"event":"phase.cost","phase":"plan","phaseIdx":1,
21
+ // "provider":"anthropic","inputTokens":1200,
22
+ // "outputTokens":3400,"costUSD":0.07}'
23
+ //
24
+ // The verb is HIDDEN — not in HELP_GROUPS, not in HELP_VERBS, not in the
25
+ // welcome text. It is documented only via `claude-autopilot internal --help`
26
+ // for diagnostics.
27
+ //
28
+ // Spec: docs/specs/v6-run-state-engine.md "Phase contract" — the markdown
29
+ // skills shell out to write events.
30
+ import * as path from 'node:path';
31
+ import { GuardrailError } from "../errors.js";
32
+ import { appendEvent } from "./events.js";
33
+ import { makeWriterId } from "./lock.js";
34
+ import { runDirFor } from "./runs.js";
35
+ const HELP_TEXT = `
36
+ Usage: claude-autopilot internal <verb> [options]
37
+
38
+ Internal / diagnostic verbs. NOT for end-user use — these are called by
39
+ markdown-driven skills (brainstorm, plan, implement) that can't import the
40
+ run-state TS module directly. Surface stability is best-effort; do NOT
41
+ script against this in user-facing code.
42
+
43
+ Verbs:
44
+ log-phase-event Append a typed event to a run's events.ndjson
45
+
46
+ Options (log-phase-event):
47
+ --run-id <id> Required. ULID of the run to append to.
48
+ --event <json> Required. RunEventInput JSON (no seq/ts/runId — those
49
+ are filled in by the appender).
50
+ --cwd <path> Optional. Repo root containing .guardrail-cache/runs/.
51
+ Defaults to the current working directory.
52
+
53
+ Examples:
54
+
55
+ claude-autopilot internal log-phase-event \\
56
+ --run-id 01HZK7XXXXXXXXXXXXXXXXXXXX \\
57
+ --event '{"event":"phase.cost","phase":"plan","phaseIdx":1,
58
+ "provider":"anthropic","inputTokens":1200,
59
+ "outputTokens":3400,"costUSD":0.07}'
60
+ `;
61
+ /** Parse argv pairs of the form `--name <value>`. Multi-value not supported
62
+ * here — there is exactly one value per flag. Returns undefined when the
63
+ * flag is missing, throws when the flag is present but its value is missing
64
+ * or starts with another `--`. */
65
+ function readFlag(args, name) {
66
+ const idx = args.indexOf(`--${name}`);
67
+ if (idx < 0)
68
+ return undefined;
69
+ const val = args[idx + 1];
70
+ if (val === undefined || val.startsWith('--')) {
71
+ throw new GuardrailError(`--${name} requires a value`, { code: 'user_input', provider: 'cli', details: { flag: name } });
72
+ }
73
+ return val;
74
+ }
75
+ export async function runInternalCli(opts) {
76
+ const args = opts.args;
77
+ const verb = args[0];
78
+ if (!verb || verb === '--help' || verb === '-h' || verb === 'help') {
79
+ return { exit: 0, stdout: [HELP_TEXT.trimStart()], stderr: [] };
80
+ }
81
+ if (verb !== 'log-phase-event') {
82
+ return {
83
+ exit: 1,
84
+ stdout: [],
85
+ stderr: [
86
+ `[claude-autopilot] internal: unknown verb "${verb}"`,
87
+ HELP_TEXT.trimStart(),
88
+ ],
89
+ };
90
+ }
91
+ // log-phase-event
92
+ let runId;
93
+ let eventJson;
94
+ let cwdOverride;
95
+ try {
96
+ runId = readFlag(args, 'run-id');
97
+ eventJson = readFlag(args, 'event');
98
+ cwdOverride = readFlag(args, 'cwd');
99
+ }
100
+ catch (err) {
101
+ return {
102
+ exit: 1,
103
+ stdout: [],
104
+ stderr: [`[claude-autopilot] internal: ${err.message}`],
105
+ };
106
+ }
107
+ if (!runId) {
108
+ return {
109
+ exit: 1,
110
+ stdout: [],
111
+ stderr: [`[claude-autopilot] internal: --run-id is required`],
112
+ };
113
+ }
114
+ if (!eventJson) {
115
+ return {
116
+ exit: 1,
117
+ stdout: [],
118
+ stderr: [`[claude-autopilot] internal: --event is required`],
119
+ };
120
+ }
121
+ let parsed;
122
+ try {
123
+ parsed = JSON.parse(eventJson);
124
+ }
125
+ catch (err) {
126
+ return {
127
+ exit: 1,
128
+ stdout: [],
129
+ stderr: [
130
+ `[claude-autopilot] internal: --event is not valid JSON: ${err.message}`,
131
+ ],
132
+ };
133
+ }
134
+ if (!parsed || typeof parsed !== 'object' || typeof parsed.event !== 'string') {
135
+ return {
136
+ exit: 1,
137
+ stdout: [],
138
+ stderr: [
139
+ `[claude-autopilot] internal: --event must be an object with an "event" string field`,
140
+ ],
141
+ };
142
+ }
143
+ const cwd = cwdOverride ? path.resolve(cwdOverride) : (opts.cwd ?? process.cwd());
144
+ const runDir = runDirFor(cwd, runId);
145
+ // Best-effort writerId. The internal verb does NOT take the run's lock —
146
+ // the markdown skill that calls it is operating "out-of-band" of any
147
+ // currently-held lock by design (skills can't hold a lock across multiple
148
+ // bash invocations). Stamping the writerId of the calling process keeps
149
+ // the event auditable even though it sidesteps the single-writer
150
+ // invariant. Phase 6 may add a `--writer-id <id>` flag for stricter
151
+ // attribution; Phase 2 keeps the surface minimal.
152
+ const writerId = makeWriterId();
153
+ let appended;
154
+ try {
155
+ appended = appendEvent(runDir, parsed, { writerId, runId });
156
+ }
157
+ catch (err) {
158
+ return {
159
+ exit: 1,
160
+ stdout: [],
161
+ stderr: [
162
+ `[claude-autopilot] internal: appendEvent failed: ${err.message}`,
163
+ ],
164
+ };
165
+ }
166
+ return {
167
+ exit: 0,
168
+ stdout: [
169
+ `[claude-autopilot] internal: appended seq=${appended.seq} event=${appended.event} runId=${runId}`,
170
+ ],
171
+ stderr: [],
172
+ };
173
+ }
174
+ //# sourceMappingURL=cli-internal.js.map
@@ -0,0 +1,59 @@
1
+ import { type RunEvent, type RunEventInput, type RunIndexEntry, type RunState, type WriterId } from './types.ts';
2
+ export declare function eventsPath(runDir: string): string;
3
+ export interface ReadEventsOptions {
4
+ /** Skip events with seq < this value. */
5
+ fromSeq?: number;
6
+ /** Return only the last N events. Applied after `fromSeq` filter. */
7
+ tail?: number;
8
+ }
9
+ export interface ReadEventsResult {
10
+ events: RunEvent[];
11
+ /** True if the last line of the file was a partial JSON write and was
12
+ * ignored. The next append should emit a `run.recovery` event. */
13
+ truncatedTail: boolean;
14
+ /** Highest seq observed in the file (after dropping a truncated tail). */
15
+ maxSeq: number;
16
+ }
17
+ /** Stream all events from disk. Detects partial-JSON tail and signals
18
+ * recovery via `truncatedTail`. Does NOT throw on individual line parse
19
+ * errors that are NOT the last line — those produce a `partial_write`
20
+ * GuardrailError because mid-log corruption is unrecoverable here. */
21
+ export declare function readEvents(runDir: string, opts?: ReadEventsOptions): ReadEventsResult;
22
+ /** Read just the highest seq from disk. Prefers the sidecar; falls back to
23
+ * rescanning the events file. */
24
+ export declare function readMaxSeq(runDir: string): number;
25
+ export interface AppendEventOptions {
26
+ /** Override the runId stamped onto the event. Required for runs whose
27
+ * ID isn't derivable from the runDir (almost never; we accept it for
28
+ * test fixtures). */
29
+ runId?: string;
30
+ writerId: WriterId;
31
+ }
32
+ /** Append a single event to events.ndjson. Strict ordering:
33
+ * 1. open(O_APPEND), write line, fsync(fd), close.
34
+ * 2. Update sidecar with new seq (best-effort).
35
+ *
36
+ * Returns the fully-formed RunEvent that landed on disk (with seq, ts,
37
+ * schema_version, etc. filled in).
38
+ *
39
+ * This is the ONLY supported way to append. Bypassing it with raw fs writes
40
+ * will desync the seq sidecar and may break recovery. */
41
+ export declare function appendEvent(runDir: string, input: RunEventInput, opts: AppendEventOptions): RunEvent;
42
+ /** Replay events.ndjson into a fresh RunState snapshot. The events file is
43
+ * the source of truth — this is always callable; if the file is missing or
44
+ * empty, the result is a minimal "pending" state with no phases.
45
+ *
46
+ * Throws GuardrailError(corrupted_state) if the log has internal
47
+ * contradictions that prevent a coherent snapshot (e.g. seq gaps,
48
+ * phase.success without a prior phase.start), OR if the persisted
49
+ * `schema_version` falls outside this binary's supported window
50
+ * (`RUN_STATE_MIN_SUPPORTED_SCHEMA_VERSION..RUN_STATE_MAX_SUPPORTED_SCHEMA_VERSION`).
51
+ * Per v6.2.2 spec — the prior shape would fail with a cryptic
52
+ * `cannot read property 'phases' of undefined` instead of an actionable
53
+ * "this run dir is from a newer/older version" message. */
54
+ export declare function replayState(runDir: string): RunState;
55
+ export declare function foldEvents(runDir: string, events: RunEvent[]): RunState;
56
+ /** Fold an in-memory state into a list-row used by `runs list`. Lives here
57
+ * because it's a pure projection over RunState — no IO, no side effects. */
58
+ export declare function stateToIndexEntry(state: RunState, recovered?: boolean): RunIndexEntry;
59
+ //# sourceMappingURL=events.d.ts.map