@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,23 @@
1
+ export interface BrainstormCommandOptions {
2
+ cwd?: string;
3
+ configPath?: string;
4
+ /**
5
+ * v6.0.3 — engine knob inputs. Same shape and precedence as scan / costs /
6
+ * fix (CLI > env > config > built-in default off in v6.0.x). The CLI
7
+ * dispatcher wires `cliEngine` from `--engine` / `--no-engine`;
8
+ * `envEngine` from `process.env.CLAUDE_AUTOPILOT_ENGINE`. An absent CLI
9
+ * flag + absent env value falls through to the loaded config and then to
10
+ * the built-in default.
11
+ */
12
+ cliEngine?: boolean;
13
+ envEngine?: string;
14
+ /**
15
+ * Test-only seam — when true, the phase body returns its result without
16
+ * printing the advisory banner. Lets engine-smoke tests assert the
17
+ * `state.json` + `events.ndjson` lifecycle without polluting stdout.
18
+ * Production callers (the CLI dispatcher) MUST NOT pass this.
19
+ */
20
+ __silent?: boolean;
21
+ }
22
+ export declare function runBrainstorm(options?: BrainstormCommandOptions): Promise<number>;
23
+ //# sourceMappingURL=brainstorm.d.ts.map
@@ -0,0 +1,131 @@
1
+ // src/cli/brainstorm.ts
2
+ //
3
+ // v6.0.3 — wrap the `brainstorm` pipeline phase through `runPhase`.
4
+ //
5
+ // `brainstorm` is the entry point of the autopilot pipeline. It is implemented
6
+ // primarily as a Claude Code skill (`/brainstorm` → `superpowers:brainstorming`),
7
+ // not as a standalone CLI subcommand. The CLI verb that ships in this binary is
8
+ // an advisory shim: it points the user at the Claude Code skill and the next
9
+ // pipeline verbs. There is no LLM call in the CLI verb body, and no provider
10
+ // side effects. The pure-LLM design dialogue happens in Claude Code; the spec
11
+ // markdown produced there lands at `docs/superpowers/specs/<slug>.md` (a local
12
+ // file write, not a platform-side-effect-free remote write — the recipe treats
13
+ // local file writes as acceptable inside the phase body, identical precedent to
14
+ // `fix.ts` editing local source files).
15
+ //
16
+ // Idempotency / side effects (deviation note vs. spec table):
17
+ // - The spec table at docs/specs/v6-run-state-engine.md says
18
+ // `idempotent: no` for `brainstorm` because re-running produces NEW LLM
19
+ // content each invocation. The recipe table at
20
+ // docs/v6/wrapping-pipeline-phases.md previously echoed that. v6.0.3
21
+ // declares `idempotent: true` to match the engine's actual semantics
22
+ // ("safe to retry without reconciliation"): the CLI verb itself is a
23
+ // printed advisory message that is byte-for-byte identical on every
24
+ // invocation, has no externalRefs to reconcile, and no provider state
25
+ // to roll back. The engine's idempotency check is "safe to replay,"
26
+ // not "produces byte-identical output." See the recipe section 2:
27
+ // `idempotent: true → phase output depends only on its input + project
28
+ // state, and re-running gives the same answer.` That holds here.
29
+ // - `hasSideEffects: false` — the CLI verb prints to stdout. No provider
30
+ // calls, no git push, no PR creation, no remote API write. Identical
31
+ // to costs.
32
+ import * as path from 'node:path';
33
+ import * as fs from 'node:fs';
34
+ import { loadConfig } from "../core/config/loader.js";
35
+ import { runPhaseWithLifecycle } from "../core/run-state/run-phase-with-lifecycle.js";
36
+ const C = {
37
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
38
+ cyan: '\x1b[36m', red: '\x1b[31m',
39
+ };
40
+ const fmt = (c, t) => `${C[c]}${t}${C.reset}`;
41
+ export async function runBrainstorm(options = {}) {
42
+ const cwd = options.cwd ?? process.cwd();
43
+ const configPath = options.configPath ?? path.join(cwd, 'guardrail.config.yaml');
44
+ let config = { configVersion: 1 };
45
+ if (fs.existsSync(configPath)) {
46
+ const loaded = await loadConfig(configPath);
47
+ if (loaded)
48
+ config = loaded;
49
+ }
50
+ const brainstormInput = { cwd, silent: options.__silent === true };
51
+ // The wrapped phase body. Pure: reads no files, makes no provider calls.
52
+ // Engine-off callers invoke `executeBrainstormPhase()` directly;
53
+ // engine-on callers route through `runPhase()`.
54
+ const phase = {
55
+ name: 'brainstorm',
56
+ // Pure-LLM design dialogue happens in the Claude Code skill, not here.
57
+ // The CLI verb is an advisory print with no externalRefs to reconcile
58
+ // and no provider state to roll back. Safe to retry. (Deviation from
59
+ // the spec table noted at the top of the file.)
60
+ idempotent: true,
61
+ // No provider calls, no git push, no PR creation. Identical to costs.
62
+ hasSideEffects: false,
63
+ run: async (input) => executeBrainstormPhase(input),
64
+ };
65
+ // v6.0.6 — lifecycle wiring lives in `runPhaseWithLifecycle`. The helper
66
+ // owns the engine-on/engine-off branch and the failure banner.
67
+ let output;
68
+ try {
69
+ const result = await runPhaseWithLifecycle({
70
+ cwd,
71
+ phase,
72
+ input: brainstormInput,
73
+ config,
74
+ cliEngine: options.cliEngine,
75
+ envEngine: options.envEngine,
76
+ runEngineOff: () => executeBrainstormPhase(brainstormInput),
77
+ });
78
+ output = result.output;
79
+ }
80
+ catch {
81
+ // Helper already printed the failure banner + emitted run.complete
82
+ // failed + refreshed state.json + released the lock.
83
+ return 1;
84
+ }
85
+ return renderBrainstormOutput(output, brainstormInput);
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // Phase body — produce the advisory payload. Pure: no provider calls. By
89
+ // default does NOT print to stdout (the renderer handles that) so the engine
90
+ // path's idempotency isn't coupled to console output. Returns a
91
+ // JSON-serializable BrainstormOutput so the engine can persist it as
92
+ // `result` on the phase snapshot.
93
+ // ---------------------------------------------------------------------------
94
+ async function executeBrainstormPhase(_input) {
95
+ return {
96
+ kind: 'advisory',
97
+ nextActions: [
98
+ 'Invoke /brainstorm from Claude Code for interactive spec writing',
99
+ 'Then /autopilot to run the full pipeline from an approved spec',
100
+ ],
101
+ };
102
+ }
103
+ // ---------------------------------------------------------------------------
104
+ // Render — translate BrainstormOutput back to the legacy stdout advisory +
105
+ // exit code. Lives outside the wrapped phase because it's pure presentation;
106
+ // doing the rendering inside the phase would couple the engine path's
107
+ // idempotency to console output.
108
+ // ---------------------------------------------------------------------------
109
+ function renderBrainstormOutput(_output, input) {
110
+ if (input.silent)
111
+ return 0;
112
+ console.log(`
113
+ ${fmt('bold', '[brainstorm]')} The pipeline entry point is a Claude Code skill, not a CLI subcommand.
114
+
115
+ Invoke it from Claude Code:
116
+
117
+ ${fmt('cyan', '/brainstorm')} Interactive spec writing
118
+ ${fmt('cyan', '/autopilot')} Full pipeline from an approved spec
119
+ ${fmt('cyan', '/migrate')} Database migration phase (stack-dependent)
120
+
121
+ From the terminal, the CLI subset exposes only the individual review-phase subcommands:
122
+
123
+ ${fmt('cyan', 'claude-autopilot run --base main')} Just the review phase
124
+ ${fmt('cyan', 'claude-autopilot doctor')} Check prerequisites (incl. superpowers plugin)
125
+ ${fmt('cyan', 'claude-autopilot migrate-v4')} Codemod for v4 → v5 repo migration (not a pipeline phase)
126
+
127
+ Full pipeline docs: https://github.com/axledbetter/claude-autopilot#the-pipeline-phase-by-phase
128
+ `);
129
+ return 0;
130
+ }
131
+ //# sourceMappingURL=brainstorm.js.map
@@ -1,2 +1,16 @@
1
- export declare function runCosts(cwd?: string): Promise<number>;
1
+ export interface CostsCommandOptions {
2
+ cwd?: string;
3
+ configPath?: string;
4
+ /**
5
+ * v6.0.2 — engine knob inputs. Same shape and precedence as scan
6
+ * (CLI > env > config > built-in default off in v6.0.x). The CLI dispatcher
7
+ * wires `cliEngine` from `--engine` / `--no-engine`; `envEngine` from
8
+ * `process.env.CLAUDE_AUTOPILOT_ENGINE`. An absent CLI flag + absent env
9
+ * value falls through to the loaded config and then to the built-in
10
+ * default.
11
+ */
12
+ cliEngine?: boolean;
13
+ envEngine?: string;
14
+ }
15
+ export declare function runCosts(cwdOrOptions?: string | CostsCommandOptions): Promise<number>;
2
16
  //# sourceMappingURL=costs.d.ts.map
@@ -1,7 +1,11 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs';
1
3
  import { readCostLog } from "../core/persist/cost-log.js";
4
+ import { loadConfig } from "../core/config/loader.js";
5
+ import { runPhaseWithLifecycle } from "../core/run-state/run-phase-with-lifecycle.js";
2
6
  const C = {
3
7
  reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
4
- green: '\x1b[32m', yellow: '\x1b[33m', cyan: '\x1b[36m',
8
+ green: '\x1b[32m', yellow: '\x1b[33m', cyan: '\x1b[36m', red: '\x1b[31m',
5
9
  };
6
10
  const fmt = (c, t) => `${C[c]}${t}${C.reset}`;
7
11
  function formatDate(iso) {
@@ -19,13 +23,69 @@ function fmtUSD(n) {
19
23
  function fmtTokens(n) {
20
24
  return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
21
25
  }
22
- export async function runCosts(cwd = process.cwd()) {
23
- const log = readCostLog(cwd);
24
- if (log.length === 0) {
25
- console.log(fmt('yellow', `[costs] No run history found in ${cwd} run \`guardrail run\` first.`));
26
- console.log(fmt('dim', ` (Costs are scoped per-project. \`cd\` to the project before checking.)`));
27
- return 0;
26
+ export async function runCosts(cwdOrOptions = {}) {
27
+ // Back-compat early callers (tests, MCP) pass a bare `cwd: string`. The
28
+ // tests/costs.test.ts harness drives this shape directly. Promote both
29
+ // forms into a single options struct so the rest of the function can treat
30
+ // it uniformly.
31
+ const options = typeof cwdOrOptions === 'string'
32
+ ? { cwd: cwdOrOptions }
33
+ : cwdOrOptions;
34
+ const cwd = options.cwd ?? process.cwd();
35
+ const configPath = options.configPath ?? path.join(cwd, 'guardrail.config.yaml');
36
+ let config = { configVersion: 1 };
37
+ if (fs.existsSync(configPath)) {
38
+ const loaded = await loadConfig(configPath);
39
+ if (loaded)
40
+ config = loaded;
41
+ }
42
+ const costsInput = { cwd };
43
+ // The wrapped phase body — pure read of the cost ledger + summary build.
44
+ // Extracted into a RunPhase so the engine-on path and the engine-off path
45
+ // share the exact same logic. Engine-off callers invoke this directly via
46
+ // `executeCostsPhase()`; engine-on callers route through `runPhase()`.
47
+ const phase = {
48
+ name: 'costs',
49
+ // Cost summary is a pure read of `.guardrail-cache/costs.jsonl` — re-running
50
+ // produces identical output for identical ledger contents. Always safe to
51
+ // retry.
52
+ idempotent: true,
53
+ // No provider calls, no git push, no PR comment, no file writes (the
54
+ // ledger is read-only on this path; the writer is `appendCostLog` called
55
+ // by other verbs). Replays are safe.
56
+ hasSideEffects: false,
57
+ run: async (input) => executeCostsPhase(input),
58
+ };
59
+ // v6.0.6 — lifecycle wiring lives in `runPhaseWithLifecycle`. The helper
60
+ // owns the engine-on/engine-off branch and the failure banner; the caller
61
+ // just supplies the phase, the input, and the engine-off escape hatch.
62
+ let output;
63
+ try {
64
+ const result = await runPhaseWithLifecycle({
65
+ cwd,
66
+ phase,
67
+ input: costsInput,
68
+ config,
69
+ cliEngine: options.cliEngine,
70
+ envEngine: options.envEngine,
71
+ runEngineOff: () => executeCostsPhase(costsInput),
72
+ });
73
+ output = result.output;
74
+ }
75
+ catch {
76
+ // Helper already printed the failure banner + emitted run.complete
77
+ // failed + refreshed state.json + released the lock.
78
+ return 1;
28
79
  }
80
+ return renderCostsOutput(output, costsInput);
81
+ }
82
+ // ---------------------------------------------------------------------------
83
+ // Phase body — read the cost ledger and assemble the summary. Pure: no
84
+ // console output, no exit codes. Returns a JSON-serializable CostsOutput so
85
+ // the engine can persist it as `result` on the phase snapshot.
86
+ // ---------------------------------------------------------------------------
87
+ async function executeCostsPhase(input) {
88
+ const log = readCostLog(input.cwd);
29
89
  // 7-day window
30
90
  const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
31
91
  const recent = log.filter(e => new Date(e.timestamp).getTime() >= sevenDaysAgo);
@@ -34,12 +94,41 @@ export async function runCosts(cwd = process.cwd()) {
34
94
  const totalInput = log.reduce((s, e) => s + e.inputTokens, 0);
35
95
  const totalOutput = log.reduce((s, e) => s + e.outputTokens, 0);
36
96
  const recentCost = recent.reduce((s, e) => s + e.costUSD, 0);
97
+ return {
98
+ entryCount: log.length,
99
+ totals: {
100
+ runs: log.length,
101
+ inputTokens: totalInput,
102
+ outputTokens: totalOutput,
103
+ costUSD: totalCost,
104
+ },
105
+ recent: {
106
+ runs: recent.length,
107
+ costUSD: recentCost,
108
+ },
109
+ last10,
110
+ };
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // Render — translate CostsOutput back to the legacy stdout summary + exit
114
+ // code. Lives outside the wrapped phase because it's pure presentation;
115
+ // doing the rendering inside the phase would couple the engine path's
116
+ // idempotency to console output.
117
+ // ---------------------------------------------------------------------------
118
+ function renderCostsOutput(output, input) {
119
+ const { cwd } = input;
120
+ const { entryCount, totals, recent, last10 } = output;
121
+ if (entryCount === 0) {
122
+ console.log(fmt('yellow', `[costs] No run history found in ${cwd} — run \`guardrail run\` first.`));
123
+ console.log(fmt('dim', ` (Costs are scoped per-project. \`cd\` to the project before checking.)`));
124
+ return 0;
125
+ }
37
126
  console.log(`\n${fmt('bold', '[costs]')} ${fmt('dim', cwd)}\n`);
38
127
  // Summary row
39
128
  console.log(fmt('bold', 'Summary'));
40
- console.log(` All-time runs: ${log.length}`);
41
- console.log(` All-time cost: ${fmtUSD(totalCost)} (${fmtTokens(totalInput)} in / ${fmtTokens(totalOutput)} out)`);
42
- console.log(` Last 7 days: ${fmtUSD(recentCost)} (${recent.length} run${recent.length !== 1 ? 's' : ''})`);
129
+ console.log(` All-time runs: ${totals.runs}`);
130
+ console.log(` All-time cost: ${fmtUSD(totals.costUSD)} (${fmtTokens(totals.inputTokens)} in / ${fmtTokens(totals.outputTokens)} out)`);
131
+ console.log(` Last 7 days: ${fmtUSD(recent.costUSD)} (${recent.runs} run${recent.runs !== 1 ? 's' : ''})`);
43
132
  console.log(fmt('dim', ` (per-project — scoped to ${cwd}/.guardrail-cache/costs.jsonl)`));
44
133
  console.log('');
45
134
  // Last 10 runs table
@@ -0,0 +1,71 @@
1
+ import type { DeployAdapter, DeployConfig } from '../adapters/deploy/types.ts';
2
+ export interface RunDeployOptions {
3
+ configPath?: string;
4
+ /** When set, overrides `deploy.adapter` from config. */
5
+ adapterOverride?: 'vercel' | 'fly' | 'render' | 'generic';
6
+ ref?: string;
7
+ commitSha?: string;
8
+ cwd?: string;
9
+ /** Phase 2 — when true, subscribe to streamLogs() and pipe to stderr. */
10
+ watch?: boolean;
11
+ /**
12
+ * Test seam — allows injecting a fake DeployAdapter without going through
13
+ * the real factory (which requires VERCEL_TOKEN etc.). Production callers
14
+ * MUST NOT set this.
15
+ */
16
+ adapterFactory?: (config: DeployConfig) => DeployAdapter;
17
+ /**
18
+ * Test seam — injected `fetch` implementation for the post-deploy health
19
+ * check. Defaults to `globalThis.fetch`.
20
+ */
21
+ fetchImpl?: typeof fetch;
22
+ /**
23
+ * Test seam — injected sleep function used between health-check retries.
24
+ * Defaults to `setTimeout`-based sleep. Pass `async () => {}` from tests.
25
+ */
26
+ sleepImpl?: (ms: number) => Promise<void>;
27
+ /** GitHub PR number — when set, post upserting deploy summary comment. */
28
+ pr?: number;
29
+ /**
30
+ * Test seam — injected `gh` CLI runner. Receives argv plus an optional
31
+ * stdin `body` (passed via `gh ... --body-file -`). Returns stdout.
32
+ * Defaults to `core/shell.runSafe`.
33
+ */
34
+ ghImpl?: (args: string[], opts?: {
35
+ body?: string;
36
+ cwd?: string;
37
+ }) => string;
38
+ }
39
+ export declare function runDeploy(opts: RunDeployOptions): Promise<number>;
40
+ export interface RunDeployRollbackOptions {
41
+ configPath?: string;
42
+ adapterOverride?: 'vercel' | 'fly' | 'render' | 'generic';
43
+ /** Specific deploy ID to roll back to. When omitted, the previous prod deploy is used. */
44
+ to?: string;
45
+ cwd?: string;
46
+ /** Test seam — same contract as `RunDeployOptions.adapterFactory`. */
47
+ adapterFactory?: (config: DeployConfig) => DeployAdapter;
48
+ }
49
+ export interface RunDeployStatusOptions {
50
+ configPath?: string;
51
+ adapterOverride?: 'vercel' | 'fly' | 'render' | 'generic';
52
+ cwd?: string;
53
+ adapterFactory?: (config: DeployConfig) => DeployAdapter;
54
+ }
55
+ /**
56
+ * Handle `claude-autopilot deploy rollback [--to <id>]`.
57
+ *
58
+ * Returns process exit code (0 on success, 1 on failure). Failure modes:
59
+ * - Adapter doesn't implement rollback (e.g. generic adapter).
60
+ * - No previous prod deploy exists when `--to` is omitted.
61
+ * - Auth / network / API error (surfaced via formatErr).
62
+ */
63
+ export declare function runDeployRollback(opts: RunDeployRollbackOptions): Promise<number>;
64
+ /**
65
+ * Handle `claude-autopilot deploy status`. Lists the current production
66
+ * deploy plus the last 5 builds (newest-first), pulling from the adapter's
67
+ * `listDeployments` capability. Adapters that don't expose this method
68
+ * (e.g. the generic shell adapter) get a clear error and exit 1.
69
+ */
70
+ export declare function runDeployStatus(opts: RunDeployStatusOptions): Promise<number>;
71
+ //# sourceMappingURL=deploy.d.ts.map