@nathapp/nax 0.50.3 → 0.51.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 (352) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/nax.js +393 -197
  3. package/package.json +1 -3
  4. package/bin/nax.ts +0 -1195
  5. package/src/acceptance/fix-generator.ts +0 -322
  6. package/src/acceptance/generator.ts +0 -415
  7. package/src/acceptance/index.ts +0 -42
  8. package/src/acceptance/refinement.ts +0 -224
  9. package/src/acceptance/templates/cli.ts +0 -47
  10. package/src/acceptance/templates/component.ts +0 -78
  11. package/src/acceptance/templates/e2e.ts +0 -43
  12. package/src/acceptance/templates/index.ts +0 -21
  13. package/src/acceptance/templates/snapshot.ts +0 -50
  14. package/src/acceptance/templates/unit.ts +0 -48
  15. package/src/acceptance/types.ts +0 -138
  16. package/src/agents/acp/adapter.ts +0 -888
  17. package/src/agents/acp/cost.ts +0 -9
  18. package/src/agents/acp/index.ts +0 -7
  19. package/src/agents/acp/interaction-bridge.ts +0 -126
  20. package/src/agents/acp/parser.ts +0 -119
  21. package/src/agents/acp/spawn-client.ts +0 -373
  22. package/src/agents/acp/types.ts +0 -22
  23. package/src/agents/aider/adapter.ts +0 -135
  24. package/src/agents/claude/adapter.ts +0 -258
  25. package/src/agents/claude/complete.ts +0 -80
  26. package/src/agents/claude/cost.ts +0 -16
  27. package/src/agents/claude/execution.ts +0 -215
  28. package/src/agents/claude/index.ts +0 -3
  29. package/src/agents/claude/interactive.ts +0 -77
  30. package/src/agents/claude/plan.ts +0 -179
  31. package/src/agents/codex/adapter.ts +0 -153
  32. package/src/agents/cost/calculate.ts +0 -154
  33. package/src/agents/cost/index.ts +0 -10
  34. package/src/agents/cost/parse.ts +0 -97
  35. package/src/agents/cost/pricing.ts +0 -59
  36. package/src/agents/cost/types.ts +0 -45
  37. package/src/agents/gemini/adapter.ts +0 -177
  38. package/src/agents/index.ts +0 -18
  39. package/src/agents/opencode/adapter.ts +0 -106
  40. package/src/agents/registry.ts +0 -136
  41. package/src/agents/shared/decompose.ts +0 -154
  42. package/src/agents/shared/model-resolution.ts +0 -43
  43. package/src/agents/shared/types-extended.ts +0 -164
  44. package/src/agents/shared/validation.ts +0 -69
  45. package/src/agents/shared/version-detection.ts +0 -109
  46. package/src/agents/types.ts +0 -205
  47. package/src/analyze/classifier.ts +0 -282
  48. package/src/analyze/index.ts +0 -16
  49. package/src/analyze/scanner.ts +0 -171
  50. package/src/analyze/types.ts +0 -51
  51. package/src/cli/accept.ts +0 -108
  52. package/src/cli/agents.ts +0 -87
  53. package/src/cli/analyze-parser.ts +0 -291
  54. package/src/cli/analyze.ts +0 -352
  55. package/src/cli/config-descriptions.ts +0 -219
  56. package/src/cli/config-diff.ts +0 -103
  57. package/src/cli/config-display.ts +0 -285
  58. package/src/cli/config-get.ts +0 -55
  59. package/src/cli/config.ts +0 -14
  60. package/src/cli/constitution.ts +0 -17
  61. package/src/cli/diagnose-analysis.ts +0 -159
  62. package/src/cli/diagnose-formatter.ts +0 -87
  63. package/src/cli/diagnose.ts +0 -203
  64. package/src/cli/generate.ts +0 -250
  65. package/src/cli/index.ts +0 -42
  66. package/src/cli/init-context.ts +0 -405
  67. package/src/cli/init-detect.ts +0 -303
  68. package/src/cli/init.ts +0 -296
  69. package/src/cli/interact.ts +0 -295
  70. package/src/cli/plan.ts +0 -509
  71. package/src/cli/plugins.ts +0 -122
  72. package/src/cli/prompts-export.ts +0 -58
  73. package/src/cli/prompts-init.ts +0 -200
  74. package/src/cli/prompts-main.ts +0 -183
  75. package/src/cli/prompts-shared.ts +0 -70
  76. package/src/cli/prompts-tdd.ts +0 -88
  77. package/src/cli/prompts.ts +0 -17
  78. package/src/cli/runs.ts +0 -174
  79. package/src/cli/status-cost.ts +0 -151
  80. package/src/cli/status-features.ts +0 -405
  81. package/src/cli/status.ts +0 -13
  82. package/src/commands/common.ts +0 -171
  83. package/src/commands/diagnose.ts +0 -17
  84. package/src/commands/index.ts +0 -9
  85. package/src/commands/logs-formatter.ts +0 -201
  86. package/src/commands/logs-reader.ts +0 -171
  87. package/src/commands/logs.ts +0 -103
  88. package/src/commands/precheck.ts +0 -86
  89. package/src/commands/runs.ts +0 -220
  90. package/src/commands/unlock.ts +0 -96
  91. package/src/config/defaults.ts +0 -218
  92. package/src/config/index.ts +0 -22
  93. package/src/config/loader.ts +0 -143
  94. package/src/config/merge.ts +0 -106
  95. package/src/config/merger.ts +0 -147
  96. package/src/config/path-security.ts +0 -121
  97. package/src/config/paths.ts +0 -27
  98. package/src/config/permissions.ts +0 -63
  99. package/src/config/runtime-types.ts +0 -522
  100. package/src/config/schema-types.ts +0 -53
  101. package/src/config/schema.ts +0 -60
  102. package/src/config/schemas.ts +0 -426
  103. package/src/config/test-strategy.ts +0 -71
  104. package/src/config/types.ts +0 -57
  105. package/src/config/validate.ts +0 -103
  106. package/src/constitution/generator.ts +0 -158
  107. package/src/constitution/generators/aider.ts +0 -41
  108. package/src/constitution/generators/claude.ts +0 -35
  109. package/src/constitution/generators/cursor.ts +0 -36
  110. package/src/constitution/generators/opencode.ts +0 -38
  111. package/src/constitution/generators/types.ts +0 -33
  112. package/src/constitution/generators/windsurf.ts +0 -36
  113. package/src/constitution/index.ts +0 -11
  114. package/src/constitution/loader.ts +0 -121
  115. package/src/constitution/types.ts +0 -31
  116. package/src/context/auto-detect.ts +0 -228
  117. package/src/context/builder.ts +0 -299
  118. package/src/context/elements.ts +0 -122
  119. package/src/context/formatter.ts +0 -107
  120. package/src/context/generator.ts +0 -343
  121. package/src/context/generators/aider.ts +0 -34
  122. package/src/context/generators/claude.ts +0 -28
  123. package/src/context/generators/codex.ts +0 -28
  124. package/src/context/generators/cursor.ts +0 -28
  125. package/src/context/generators/gemini.ts +0 -28
  126. package/src/context/generators/opencode.ts +0 -30
  127. package/src/context/generators/windsurf.ts +0 -28
  128. package/src/context/greenfield.ts +0 -114
  129. package/src/context/index.ts +0 -34
  130. package/src/context/injector.ts +0 -279
  131. package/src/context/parent-context.ts +0 -39
  132. package/src/context/test-scanner.ts +0 -370
  133. package/src/context/types.ts +0 -98
  134. package/src/decompose/apply.ts +0 -50
  135. package/src/decompose/builder.ts +0 -181
  136. package/src/decompose/index.ts +0 -8
  137. package/src/decompose/sections/codebase.ts +0 -26
  138. package/src/decompose/sections/constraints.ts +0 -32
  139. package/src/decompose/sections/index.ts +0 -4
  140. package/src/decompose/sections/sibling-stories.ts +0 -25
  141. package/src/decompose/sections/target-story.ts +0 -31
  142. package/src/decompose/types.ts +0 -55
  143. package/src/decompose/validators/complexity.ts +0 -45
  144. package/src/decompose/validators/coverage.ts +0 -134
  145. package/src/decompose/validators/dependency.ts +0 -91
  146. package/src/decompose/validators/index.ts +0 -35
  147. package/src/decompose/validators/overlap.ts +0 -128
  148. package/src/errors.ts +0 -67
  149. package/src/execution/batching.ts +0 -157
  150. package/src/execution/crash-heartbeat.ts +0 -77
  151. package/src/execution/crash-recovery.ts +0 -79
  152. package/src/execution/crash-signals.ts +0 -165
  153. package/src/execution/crash-writer.ts +0 -154
  154. package/src/execution/deferred-review.ts +0 -105
  155. package/src/execution/dry-run.ts +0 -81
  156. package/src/execution/escalation/escalation.ts +0 -46
  157. package/src/execution/escalation/index.ts +0 -13
  158. package/src/execution/escalation/tier-escalation.ts +0 -346
  159. package/src/execution/escalation/tier-outcome.ts +0 -143
  160. package/src/execution/executor-types.ts +0 -73
  161. package/src/execution/helpers.ts +0 -38
  162. package/src/execution/index.ts +0 -27
  163. package/src/execution/iteration-runner.ts +0 -160
  164. package/src/execution/lifecycle/acceptance-loop.ts +0 -309
  165. package/src/execution/lifecycle/headless-formatter.ts +0 -83
  166. package/src/execution/lifecycle/index.ts +0 -11
  167. package/src/execution/lifecycle/parallel-lifecycle.ts +0 -101
  168. package/src/execution/lifecycle/precheck-runner.ts +0 -140
  169. package/src/execution/lifecycle/run-cleanup.ts +0 -81
  170. package/src/execution/lifecycle/run-completion.ts +0 -247
  171. package/src/execution/lifecycle/run-initialization.ts +0 -187
  172. package/src/execution/lifecycle/run-regression.ts +0 -305
  173. package/src/execution/lifecycle/run-setup.ts +0 -240
  174. package/src/execution/lifecycle/story-size-prompts.ts +0 -123
  175. package/src/execution/lock.ts +0 -129
  176. package/src/execution/parallel-coordinator.ts +0 -281
  177. package/src/execution/parallel-executor-rectification-pass.ts +0 -117
  178. package/src/execution/parallel-executor-rectify.ts +0 -136
  179. package/src/execution/parallel-executor.ts +0 -330
  180. package/src/execution/parallel-worker.ts +0 -149
  181. package/src/execution/parallel.ts +0 -13
  182. package/src/execution/pid-registry.ts +0 -275
  183. package/src/execution/pipeline-result-handler.ts +0 -221
  184. package/src/execution/progress.ts +0 -27
  185. package/src/execution/queue-handler.ts +0 -109
  186. package/src/execution/runner-completion.ts +0 -171
  187. package/src/execution/runner-execution.ts +0 -243
  188. package/src/execution/runner-setup.ts +0 -86
  189. package/src/execution/runner.ts +0 -265
  190. package/src/execution/sequential-executor.ts +0 -219
  191. package/src/execution/status-file.ts +0 -264
  192. package/src/execution/status-writer.ts +0 -181
  193. package/src/execution/story-context.ts +0 -266
  194. package/src/execution/story-selector.ts +0 -76
  195. package/src/execution/test-output-parser.ts +0 -14
  196. package/src/execution/timeout-handler.ts +0 -100
  197. package/src/hooks/index.ts +0 -2
  198. package/src/hooks/runner.ts +0 -280
  199. package/src/hooks/types.ts +0 -79
  200. package/src/interaction/chain.ts +0 -170
  201. package/src/interaction/index.ts +0 -61
  202. package/src/interaction/init.ts +0 -84
  203. package/src/interaction/plugins/auto.ts +0 -243
  204. package/src/interaction/plugins/cli.ts +0 -300
  205. package/src/interaction/plugins/telegram.ts +0 -384
  206. package/src/interaction/plugins/webhook.ts +0 -286
  207. package/src/interaction/state.ts +0 -171
  208. package/src/interaction/triggers.ts +0 -250
  209. package/src/interaction/types.ts +0 -170
  210. package/src/logger/formatters.ts +0 -84
  211. package/src/logger/index.ts +0 -16
  212. package/src/logger/logger.ts +0 -296
  213. package/src/logger/types.ts +0 -48
  214. package/src/logging/formatter.ts +0 -355
  215. package/src/logging/index.ts +0 -22
  216. package/src/logging/types.ts +0 -93
  217. package/src/metrics/aggregator.ts +0 -191
  218. package/src/metrics/index.ts +0 -14
  219. package/src/metrics/tracker.ts +0 -200
  220. package/src/metrics/types.ts +0 -115
  221. package/src/optimizer/index.ts +0 -63
  222. package/src/optimizer/noop.optimizer.ts +0 -24
  223. package/src/optimizer/rule-based.optimizer.ts +0 -248
  224. package/src/optimizer/types.ts +0 -53
  225. package/src/pipeline/event-bus.ts +0 -297
  226. package/src/pipeline/events.ts +0 -130
  227. package/src/pipeline/index.ts +0 -19
  228. package/src/pipeline/runner.ts +0 -149
  229. package/src/pipeline/stages/acceptance-setup.ts +0 -144
  230. package/src/pipeline/stages/acceptance.ts +0 -215
  231. package/src/pipeline/stages/autofix.ts +0 -262
  232. package/src/pipeline/stages/completion.ts +0 -110
  233. package/src/pipeline/stages/constitution.ts +0 -63
  234. package/src/pipeline/stages/context.ts +0 -122
  235. package/src/pipeline/stages/execution.ts +0 -359
  236. package/src/pipeline/stages/index.ts +0 -86
  237. package/src/pipeline/stages/optimizer.ts +0 -74
  238. package/src/pipeline/stages/prompt.ts +0 -79
  239. package/src/pipeline/stages/queue-check.ts +0 -103
  240. package/src/pipeline/stages/rectify.ts +0 -101
  241. package/src/pipeline/stages/regression.ts +0 -99
  242. package/src/pipeline/stages/review.ts +0 -94
  243. package/src/pipeline/stages/routing.ts +0 -276
  244. package/src/pipeline/stages/verify.ts +0 -286
  245. package/src/pipeline/subscribers/events-writer.ts +0 -135
  246. package/src/pipeline/subscribers/hooks.ts +0 -179
  247. package/src/pipeline/subscribers/interaction.ts +0 -103
  248. package/src/pipeline/subscribers/registry.ts +0 -73
  249. package/src/pipeline/subscribers/reporters.ts +0 -174
  250. package/src/pipeline/types.ts +0 -220
  251. package/src/plugins/extensions.ts +0 -225
  252. package/src/plugins/index.ts +0 -33
  253. package/src/plugins/loader.ts +0 -352
  254. package/src/plugins/plugin-logger.ts +0 -41
  255. package/src/plugins/registry.ts +0 -168
  256. package/src/plugins/types.ts +0 -206
  257. package/src/plugins/validator.ts +0 -352
  258. package/src/prd/index.ts +0 -220
  259. package/src/prd/schema.ts +0 -268
  260. package/src/prd/types.ts +0 -273
  261. package/src/prd/validate.ts +0 -41
  262. package/src/precheck/checks-agents.ts +0 -63
  263. package/src/precheck/checks-blockers.ts +0 -23
  264. package/src/precheck/checks-cli.ts +0 -68
  265. package/src/precheck/checks-config.ts +0 -102
  266. package/src/precheck/checks-git.ts +0 -117
  267. package/src/precheck/checks-system.ts +0 -101
  268. package/src/precheck/checks-warnings.ts +0 -221
  269. package/src/precheck/checks.ts +0 -36
  270. package/src/precheck/index.ts +0 -374
  271. package/src/precheck/story-size-gate.ts +0 -144
  272. package/src/precheck/types.ts +0 -31
  273. package/src/prompts/builder.ts +0 -166
  274. package/src/prompts/index.ts +0 -2
  275. package/src/prompts/loader.ts +0 -43
  276. package/src/prompts/sections/conventions.ts +0 -19
  277. package/src/prompts/sections/hermetic.ts +0 -41
  278. package/src/prompts/sections/index.ts +0 -12
  279. package/src/prompts/sections/isolation.ts +0 -70
  280. package/src/prompts/sections/role-task.ts +0 -182
  281. package/src/prompts/sections/story.ts +0 -55
  282. package/src/prompts/sections/verdict.ts +0 -70
  283. package/src/prompts/types.ts +0 -21
  284. package/src/queue/index.ts +0 -2
  285. package/src/queue/manager.ts +0 -254
  286. package/src/queue/types.ts +0 -54
  287. package/src/review/index.ts +0 -8
  288. package/src/review/orchestrator.ts +0 -154
  289. package/src/review/runner.ts +0 -303
  290. package/src/review/types.ts +0 -70
  291. package/src/routing/batch-route.ts +0 -35
  292. package/src/routing/builder.ts +0 -81
  293. package/src/routing/chain.ts +0 -75
  294. package/src/routing/content-hash.ts +0 -25
  295. package/src/routing/index.ts +0 -20
  296. package/src/routing/loader.ts +0 -62
  297. package/src/routing/router.ts +0 -305
  298. package/src/routing/strategies/adaptive.ts +0 -215
  299. package/src/routing/strategies/index.ts +0 -8
  300. package/src/routing/strategies/keyword.ts +0 -180
  301. package/src/routing/strategies/llm-prompts.ts +0 -224
  302. package/src/routing/strategies/llm.ts +0 -320
  303. package/src/routing/strategies/manual.ts +0 -50
  304. package/src/routing/strategy.ts +0 -102
  305. package/src/tdd/cleanup.ts +0 -120
  306. package/src/tdd/index.ts +0 -22
  307. package/src/tdd/isolation.ts +0 -117
  308. package/src/tdd/orchestrator.ts +0 -406
  309. package/src/tdd/prompts.ts +0 -40
  310. package/src/tdd/rectification-gate.ts +0 -274
  311. package/src/tdd/session-runner.ts +0 -263
  312. package/src/tdd/types.ts +0 -84
  313. package/src/tdd/verdict-reader.ts +0 -266
  314. package/src/tdd/verdict.ts +0 -152
  315. package/src/tui/App.tsx +0 -265
  316. package/src/tui/components/AgentPanel.tsx +0 -75
  317. package/src/tui/components/CostOverlay.tsx +0 -118
  318. package/src/tui/components/HelpOverlay.tsx +0 -107
  319. package/src/tui/components/StatusBar.tsx +0 -63
  320. package/src/tui/components/StoriesPanel.tsx +0 -177
  321. package/src/tui/hooks/useKeyboard.ts +0 -142
  322. package/src/tui/hooks/useLayout.ts +0 -137
  323. package/src/tui/hooks/usePipelineEvents.ts +0 -183
  324. package/src/tui/hooks/usePty.ts +0 -189
  325. package/src/tui/index.tsx +0 -38
  326. package/src/tui/types.ts +0 -76
  327. package/src/utils/errors.ts +0 -12
  328. package/src/utils/git.ts +0 -245
  329. package/src/utils/json-file.ts +0 -72
  330. package/src/utils/log-test-output.ts +0 -25
  331. package/src/utils/path-security.ts +0 -73
  332. package/src/utils/queue-writer.ts +0 -54
  333. package/src/verification/crash-detector.ts +0 -34
  334. package/src/verification/executor.ts +0 -250
  335. package/src/verification/index.ts +0 -12
  336. package/src/verification/orchestrator-types.ts +0 -154
  337. package/src/verification/orchestrator.ts +0 -76
  338. package/src/verification/parser.ts +0 -220
  339. package/src/verification/rectification-loop.ts +0 -172
  340. package/src/verification/rectification.ts +0 -108
  341. package/src/verification/runners.ts +0 -129
  342. package/src/verification/smart-runner.ts +0 -307
  343. package/src/verification/strategies/acceptance.ts +0 -136
  344. package/src/verification/strategies/regression.ts +0 -90
  345. package/src/verification/strategies/scoped.ts +0 -154
  346. package/src/verification/types.ts +0 -117
  347. package/src/version.ts +0 -40
  348. package/src/worktree/dispatcher.ts +0 -6
  349. package/src/worktree/index.ts +0 -2
  350. package/src/worktree/manager.ts +0 -193
  351. package/src/worktree/merge.ts +0 -302
  352. package/src/worktree/types.ts +0 -4
@@ -1,75 +0,0 @@
1
- /**
2
- * AgentPanel — displays PTY output from agent session.
3
- *
4
- * Renders a scrollable text buffer showing live agent output.
5
- * When focused, displays a border highlight.
6
- */
7
-
8
- import { Box, Text } from "ink";
9
- import Spinner from "ink-spinner";
10
-
11
- /**
12
- * Props for AgentPanel component.
13
- */
14
- export interface AgentPanelProps {
15
- /** Whether the panel is focused (receives keyboard input) */
16
- focused?: boolean;
17
- /** PTY output lines (buffered) */
18
- outputLines?: string[];
19
- }
20
-
21
- /**
22
- * Maximum number of output lines to buffer.
23
- *
24
- * Prevents memory bloat from long-running agent sessions.
25
- * Last 500 lines typically contain all relevant info for debugging.
26
- */
27
- const MAX_OUTPUT_LINES = 500;
28
-
29
- /**
30
- * AgentPanel component.
31
- *
32
- * Displays PTY output from the agent session in a scrollable text buffer.
33
- * Shows a border highlight when focused to indicate keyboard input routing.
34
- *
35
- * @example
36
- * ```tsx
37
- * const [outputLines, setOutputLines] = useState<string[]>([]);
38
- *
39
- * <AgentPanel
40
- * focused={agentFocused}
41
- * outputLines={outputLines}
42
- * onData={(data) => setOutputLines(prev => [...prev, data])}
43
- * />
44
- * ```
45
- */
46
- export function AgentPanel({ focused = false, outputLines = [] }: AgentPanelProps) {
47
- const borderColor = focused ? "cyan" : "gray";
48
-
49
- // Buffer output lines (last N lines only)
50
- const bufferedLines = outputLines.length > MAX_OUTPUT_LINES ? outputLines.slice(-MAX_OUTPUT_LINES) : outputLines;
51
-
52
- const hasOutput = bufferedLines.length > 0;
53
-
54
- return (
55
- <Box flexDirection="column" flexGrow={1} borderStyle="single" borderColor={borderColor}>
56
- {/* Header */}
57
- <Box paddingX={1} borderStyle="single" borderBottom borderColor={borderColor}>
58
- <Text bold color={focused ? "cyan" : undefined}>
59
- Agent {focused && <Text dimColor>(focused)</Text>}
60
- </Text>
61
- </Box>
62
-
63
- {/* Output buffer */}
64
- <Box flexDirection="column" paddingX={1} paddingY={1}>
65
- {hasOutput ? (
66
- bufferedLines.map((line, i) => <Text key={`line-${i}-${line.slice(0, 20)}`}>{line}</Text>)
67
- ) : (
68
- <Text dimColor>
69
- <Spinner type="dots" /> Waiting for agent...
70
- </Text>
71
- )}
72
- </Box>
73
- </Box>
74
- );
75
- }
@@ -1,118 +0,0 @@
1
- /**
2
- * CostOverlay — modal-style overlay showing cost breakdown per story.
3
- *
4
- * Shown when c is pressed, dismissed with Esc.
5
- */
6
-
7
- import { Box, Text } from "ink";
8
- import type { StoryDisplayState } from "../types";
9
-
10
- /**
11
- * Props for CostOverlay component.
12
- */
13
- export interface CostOverlayProps {
14
- /** Whether the overlay is visible */
15
- visible?: boolean;
16
- /** All stories with cost data */
17
- stories?: StoryDisplayState[];
18
- /** Total accumulated cost */
19
- totalCost?: number;
20
- }
21
-
22
- /**
23
- * Format cost as USD with 4 decimal places.
24
- */
25
- function formatCost(cost: number): string {
26
- return `$${cost.toFixed(4)}`;
27
- }
28
-
29
- /**
30
- * CostOverlay component.
31
- *
32
- * Displays a modal-style overlay with cost breakdown per story.
33
- * Shows story ID, status, and cost incurred.
34
- *
35
- * @example
36
- * ```tsx
37
- * const [showCost, setShowCost] = useState(false);
38
- *
39
- * <CostOverlay
40
- * visible={showCost}
41
- * stories={state.stories}
42
- * totalCost={state.totalCost}
43
- * />
44
- * ```
45
- */
46
- export function CostOverlay({ visible = false, stories = [], totalCost = 0 }: CostOverlayProps) {
47
- if (!visible) {
48
- return null;
49
- }
50
-
51
- // Only show stories that have been executed (cost > 0 or status !== pending)
52
- const executedStories = stories.filter((s) => (s.cost && s.cost > 0) || s.status !== "pending");
53
-
54
- return (
55
- <Box flexDirection="column" borderStyle="double" borderColor="cyan" paddingX={2} paddingY={1} minWidth={60}>
56
- <Box paddingBottom={1}>
57
- <Text bold color="cyan">
58
- Cost Breakdown
59
- </Text>
60
- </Box>
61
-
62
- {/* Header row */}
63
- <Box paddingBottom={1} borderBottom borderColor="gray">
64
- <Box width={12}>
65
- <Text bold>Story ID</Text>
66
- </Box>
67
- <Box width={12}>
68
- <Text bold>Status</Text>
69
- </Box>
70
- <Box width={12}>
71
- <Text bold>Cost</Text>
72
- </Box>
73
- </Box>
74
-
75
- {/* Story rows */}
76
- <Box flexDirection="column" paddingY={1}>
77
- {executedStories.length > 0 ? (
78
- executedStories.map((story) => (
79
- <Box key={story.story.id}>
80
- <Box width={12}>
81
- <Text>{story.story.id}</Text>
82
- </Box>
83
- <Box width={12}>
84
- <Text color={story.status === "passed" ? "green" : story.status === "failed" ? "red" : undefined}>
85
- {story.status}
86
- </Text>
87
- </Box>
88
- <Box width={12}>
89
- <Text>{formatCost(story.cost || 0)}</Text>
90
- </Box>
91
- </Box>
92
- ))
93
- ) : (
94
- <Text dimColor>No stories executed yet</Text>
95
- )}
96
- </Box>
97
-
98
- {/* Total row */}
99
- <Box paddingTop={1} borderTop borderColor="gray">
100
- <Box width={24}>
101
- <Text bold>Total Cost:</Text>
102
- </Box>
103
- <Box width={12}>
104
- <Text bold color="cyan">
105
- {formatCost(totalCost)}
106
- </Text>
107
- </Box>
108
- </Box>
109
-
110
- {/* Footer */}
111
- <Box justifyContent="center" paddingTop={1} borderTop borderColor="gray">
112
- <Text dimColor>
113
- Press <Text color="yellow">Esc</Text> to close
114
- </Text>
115
- </Box>
116
- </Box>
117
- );
118
- }
@@ -1,107 +0,0 @@
1
- /**
2
- * HelpOverlay — modal-style overlay listing all keybindings.
3
- *
4
- * Shown when ? is pressed, dismissed with Esc.
5
- */
6
-
7
- import { Box, Text } from "ink";
8
-
9
- /**
10
- * Props for HelpOverlay component.
11
- */
12
- export interface HelpOverlayProps {
13
- /** Whether the overlay is visible */
14
- visible?: boolean;
15
- }
16
-
17
- /**
18
- * HelpOverlay component.
19
- *
20
- * Displays a modal-style overlay with keybinding reference.
21
- * Centered on screen with a border.
22
- *
23
- * @example
24
- * ```tsx
25
- * const [showHelp, setShowHelp] = useState(false);
26
- *
27
- * <HelpOverlay visible={showHelp} />
28
- *
29
- * // Close with Esc or by toggling state
30
- * ```
31
- */
32
- export function HelpOverlay({ visible = false }: HelpOverlayProps) {
33
- if (!visible) {
34
- return null;
35
- }
36
-
37
- return (
38
- <Box flexDirection="column" borderStyle="double" borderColor="cyan" paddingX={2} paddingY={1}>
39
- <Box paddingBottom={1}>
40
- <Text bold color="cyan">
41
- Keyboard Shortcuts
42
- </Text>
43
- </Box>
44
-
45
- {/* Stories panel shortcuts */}
46
- <Box flexDirection="column" paddingBottom={1}>
47
- <Text dimColor>Stories Panel (default):</Text>
48
- <Text>
49
- {" "}
50
- <Text color="yellow">p</Text> — Pause after current story
51
- </Text>
52
- <Text>
53
- {" "}
54
- <Text color="yellow">a</Text> — Abort run
55
- </Text>
56
- <Text>
57
- {" "}
58
- <Text color="yellow">s</Text> — Skip current story
59
- </Text>
60
- <Text>
61
- {" "}
62
- <Text color="yellow">Tab</Text> — Toggle focus to Agent panel
63
- </Text>
64
- <Text>
65
- {" "}
66
- <Text color="yellow">q</Text> — Quit TUI
67
- </Text>
68
- <Text>
69
- {" "}
70
- <Text color="yellow">?</Text> — Show this help
71
- </Text>
72
- <Text>
73
- {" "}
74
- <Text color="yellow">c</Text> — Show cost breakdown
75
- </Text>
76
- <Text>
77
- {" "}
78
- <Text color="yellow">r</Text> — Retry last failed story
79
- </Text>
80
- <Text>
81
- {" "}
82
- <Text color="yellow">Esc</Text> — Close overlay
83
- </Text>
84
- </Box>
85
-
86
- {/* Agent panel shortcuts */}
87
- <Box flexDirection="column" paddingBottom={1}>
88
- <Text dimColor>Agent Panel (when focused):</Text>
89
- <Text>
90
- {" "}
91
- <Text color="yellow">Ctrl+]</Text> — Escape back to Stories panel
92
- </Text>
93
- <Text>
94
- {" "}
95
- <Text dimColor>All other keys</Text> — Forwarded to agent PTY
96
- </Text>
97
- </Box>
98
-
99
- {/* Footer */}
100
- <Box justifyContent="center" paddingTop={1} borderTop borderColor="gray">
101
- <Text dimColor>
102
- Press <Text color="yellow">Esc</Text> to close
103
- </Text>
104
- </Box>
105
- </Box>
106
- );
107
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * StatusBar — displays current story and pipeline stage information.
3
- */
4
-
5
- import { Box, Text } from "ink";
6
- import type { UserStory } from "../../prd/types";
7
-
8
- /**
9
- * Props for StatusBar component.
10
- */
11
- export interface StatusBarProps {
12
- /** Current story being executed */
13
- currentStory?: UserStory;
14
- /** Current pipeline stage */
15
- currentStage?: string;
16
- /** Model tier for current story */
17
- modelTier?: string;
18
- /** Test strategy for current story */
19
- testStrategy?: string;
20
- }
21
-
22
- /**
23
- * StatusBar component.
24
- *
25
- * Displays a single line showing the current story ID, stage, model tier, and test strategy.
26
- *
27
- * @example
28
- * ```tsx
29
- * <StatusBar
30
- * currentStory={story}
31
- * currentStage="execution"
32
- * modelTier="balanced"
33
- * testStrategy="single-session"
34
- * />
35
- * ```
36
- */
37
- export function StatusBar({ currentStory, currentStage, modelTier, testStrategy }: StatusBarProps) {
38
- if (!currentStory) {
39
- return (
40
- <Box paddingX={1} borderStyle="single" borderColor="gray">
41
- <Text dimColor>Idle</Text>
42
- </Box>
43
- );
44
- }
45
-
46
- const storyInfo = `Story ${currentStory.id}`;
47
- const stageInfo = currentStage ? ` · ${currentStage}` : "";
48
- const tierInfo = modelTier ? ` · ${modelTier}` : "";
49
- const strategyInfo = testStrategy ? ` · ${testStrategy}` : "";
50
-
51
- return (
52
- <Box paddingX={1} borderStyle="single" borderColor="gray">
53
- <Text>
54
- <Text bold>{storyInfo}</Text>
55
- <Text dimColor>
56
- {stageInfo}
57
- {tierInfo}
58
- {strategyInfo}
59
- </Text>
60
- </Text>
61
- </Box>
62
- );
63
- }
@@ -1,177 +0,0 @@
1
- /**
2
- * StoriesPanel — displays story list with status icons, cost, and elapsed time.
3
- *
4
- * Supports scrolling for >15 stories and compact mode for single-column layout.
5
- */
6
-
7
- import { Box, Text } from "ink";
8
- import { useEffect, useState } from "react";
9
- import { COMPACT_MAX_VISIBLE_STORIES, MAX_VISIBLE_STORIES } from "../hooks/useLayout";
10
- import type { StoryDisplayState } from "../types";
11
-
12
- /**
13
- * Props for StoriesPanel component.
14
- */
15
- export interface StoriesPanelProps {
16
- /** Stories to display */
17
- stories: StoryDisplayState[];
18
- /** Total cost accumulated */
19
- totalCost: number;
20
- /** Elapsed time in milliseconds */
21
- elapsedMs: number;
22
- /** Panel width (columns) */
23
- width?: number;
24
- /** Compact mode (fewer details, for single-column layout) */
25
- compact?: boolean;
26
- /** Maximum height in rows (for single-column mode) */
27
- maxHeight?: number;
28
- }
29
-
30
- /**
31
- * Get status icon for a story.
32
- */
33
- function getStatusIcon(status: StoryDisplayState["status"]): string {
34
- switch (status) {
35
- case "pending":
36
- return "⬚";
37
- case "running":
38
- return "🔄";
39
- case "passed":
40
- return "✅";
41
- case "failed":
42
- return "❌";
43
- case "skipped":
44
- return "⏭️";
45
- case "retrying":
46
- return "🔁";
47
- case "paused":
48
- return "⏸️";
49
- }
50
- }
51
-
52
- /**
53
- * Format elapsed time as mm:ss.
54
- */
55
- function formatElapsedTime(ms: number): string {
56
- const totalSeconds = Math.floor(ms / 1000);
57
- const minutes = Math.floor(totalSeconds / 60);
58
- const seconds = totalSeconds % 60;
59
- return `${minutes}m ${seconds}s`;
60
- }
61
-
62
- /**
63
- * StoriesPanel component.
64
- *
65
- * Displays all stories with status icons, routing info, cost total, and elapsed time.
66
- * Supports scrolling for >15 stories (or >8 in compact mode) and shows scroll indicators.
67
- *
68
- * @example
69
- * ```tsx
70
- * <StoriesPanel
71
- * stories={storyStates}
72
- * totalCost={0.42}
73
- * elapsedMs={263000}
74
- * width={30}
75
- * compact={false}
76
- * />
77
- * ```
78
- */
79
- export function StoriesPanel({ stories, totalCost, elapsedMs, width, compact = false, maxHeight }: StoriesPanelProps) {
80
- // Determine max visible stories based on mode
81
- const maxVisible = compact ? COMPACT_MAX_VISIBLE_STORIES : MAX_VISIBLE_STORIES;
82
- const needsScrolling = stories.length > maxVisible;
83
-
84
- // Scroll position (0-indexed offset)
85
- const [scrollOffset, setScrollOffset] = useState(0);
86
-
87
- // Auto-scroll to keep the current running story in view
88
- useEffect(() => {
89
- const runningIndex = stories.findIndex((s) => s.status === "running");
90
- if (runningIndex !== -1 && needsScrolling) {
91
- // If running story is outside the visible window, scroll to it
92
- if (runningIndex < scrollOffset) {
93
- setScrollOffset(runningIndex);
94
- } else if (runningIndex >= scrollOffset + maxVisible) {
95
- setScrollOffset(runningIndex - maxVisible + 1);
96
- }
97
- }
98
- }, [stories, scrollOffset, maxVisible, needsScrolling]);
99
-
100
- // Get visible stories (either all or a scrolled window)
101
- const visibleStories = needsScrolling ? stories.slice(scrollOffset, scrollOffset + maxVisible) : stories;
102
-
103
- const canScrollUp = scrollOffset > 0;
104
- const canScrollDown = scrollOffset + maxVisible < stories.length;
105
-
106
- return (
107
- <Box flexDirection="column" width={width} height={maxHeight} borderStyle="single" borderColor="gray">
108
- {/* Header */}
109
- <Box paddingX={1} borderStyle="single" borderBottom borderColor="gray">
110
- <Text bold>Stories</Text>
111
- {needsScrolling && <Text dimColor> ({stories.length} total)</Text>}
112
- </Box>
113
-
114
- {/* Scroll indicator (top) */}
115
- {needsScrolling && canScrollUp && (
116
- <Box paddingX={1}>
117
- <Text dimColor>▲ {scrollOffset} more above</Text>
118
- </Box>
119
- )}
120
-
121
- {/* Story list */}
122
- <Box flexDirection="column" paddingX={1} paddingY={1} flexGrow={1}>
123
- {visibleStories.map((s) => {
124
- const icon = getStatusIcon(s.status);
125
-
126
- if (compact) {
127
- // Compact mode: just icon and ID
128
- return (
129
- <Box key={s.story.id}>
130
- <Text>
131
- {icon} {s.story.id}
132
- </Text>
133
- </Box>
134
- );
135
- }
136
-
137
- // Normal mode: icon, ID, and routing info
138
- const routing = s.routing ? ` ${s.routing.complexity.slice(0, 3)} ${s.routing.modelTier}` : "";
139
- return (
140
- <Box key={s.story.id}>
141
- <Text>
142
- {icon} {s.story.id}
143
- <Text dimColor>{routing}</Text>
144
- </Text>
145
- </Box>
146
- );
147
- })}
148
- </Box>
149
-
150
- {/* Scroll indicator (bottom) */}
151
- {needsScrolling && canScrollDown && (
152
- <Box paddingX={1}>
153
- <Text dimColor>▼ {stories.length - scrollOffset - maxVisible} more below</Text>
154
- </Box>
155
- )}
156
-
157
- {/* Footer — Cost and time */}
158
- <Box flexDirection="column" paddingX={1} paddingY={1} borderStyle="single" borderTop borderColor="gray">
159
- {!compact && (
160
- <>
161
- <Text>
162
- Cost: <Text color="green">${totalCost.toFixed(4)}</Text>
163
- </Text>
164
- <Text>
165
- Time: <Text color="cyan">{formatElapsedTime(elapsedMs)}</Text>
166
- </Text>
167
- </>
168
- )}
169
- {compact && (
170
- <Text>
171
- ${totalCost.toFixed(2)} · {formatElapsedTime(elapsedMs)}
172
- </Text>
173
- )}
174
- </Box>
175
- </Box>
176
- );
177
- }
@@ -1,142 +0,0 @@
1
- /**
2
- * useKeyboard hook — handle keyboard shortcuts for TUI controls.
3
- *
4
- * Listens for keyboard input when agent panel is NOT focused and dispatches
5
- * actions like PAUSE/ABORT/SKIP to the queue file.
6
- *
7
- * When agent panel IS focused, only Ctrl+] escapes back to TUI controls.
8
- */
9
-
10
- import { useInput } from "ink";
11
- import type { UserStory } from "../../prd/types";
12
- import { PanelFocus } from "../types";
13
-
14
- /**
15
- * Keyboard action types.
16
- */
17
- export type KeyboardAction =
18
- | { type: "PAUSE" }
19
- | { type: "ABORT" }
20
- | { type: "SKIP"; storyId: string }
21
- | { type: "TOGGLE_FOCUS" }
22
- | { type: "ESCAPE_AGENT" }
23
- | { type: "QUIT" }
24
- | { type: "SHOW_HELP" }
25
- | { type: "SHOW_COST" }
26
- | { type: "RETRY" }
27
- | { type: "CLOSE_OVERLAY" };
28
-
29
- /**
30
- * Props for useKeyboard hook.
31
- */
32
- export interface UseKeyboardProps {
33
- /** Current panel focus state */
34
- focus: PanelFocus;
35
- /** Current story being executed (for SKIP command) */
36
- currentStory?: UserStory;
37
- /** Callback when an action is triggered */
38
- onAction: (action: KeyboardAction) => void;
39
- /** Disable keyboard handling (e.g., during confirmation dialogs) */
40
- disabled?: boolean;
41
- }
42
-
43
- /**
44
- * Hook for handling keyboard shortcuts.
45
- *
46
- * Keybindings (when Stories panel is focused):
47
- * - p: PAUSE after current story
48
- * - a: ABORT run
49
- * - s: SKIP current story
50
- * - Tab: Toggle focus between Stories and Agent panels
51
- * - q: Quit TUI
52
- * - ?: Show help overlay
53
- * - c: Show cost breakdown overlay
54
- * - r: Retry last failed story
55
- * - Esc: Close overlay
56
- *
57
- * When Agent panel is focused:
58
- * - Ctrl+]: Escape back to TUI controls
59
- * - All other keys: Forwarded to PTY (handled elsewhere)
60
- *
61
- * @example
62
- * ```tsx
63
- * const [focus, setFocus] = useState(PanelFocus.Stories);
64
- * const [showHelp, setShowHelp] = useState(false);
65
- *
66
- * useKeyboard({
67
- * focus,
68
- * currentStory: state.currentStory,
69
- * onAction: (action) => {
70
- * if (action.type === "TOGGLE_FOCUS") {
71
- * setFocus(prev => prev === PanelFocus.Stories ? PanelFocus.Agent : PanelFocus.Stories);
72
- * } else if (action.type === "SHOW_HELP") {
73
- * setShowHelp(true);
74
- * } else if (action.type === "PAUSE") {
75
- * writeQueueCommand({ type: "PAUSE" });
76
- * }
77
- * }
78
- * });
79
- * ```
80
- */
81
- export function useKeyboard({ focus, currentStory, onAction, disabled = false }: UseKeyboardProps): void {
82
- useInput((input, key) => {
83
- // If disabled, don't process any input
84
- if (disabled) {
85
- return;
86
- }
87
-
88
- // When Agent panel is focused, only Ctrl+] escapes back to TUI
89
- if (focus === PanelFocus.Agent) {
90
- // Ctrl+] is key.ctrl === true and input === ']'
91
- if (key.ctrl && input === "]") {
92
- onAction({ type: "ESCAPE_AGENT" });
93
- }
94
- // All other input is routed to PTY (handled by caller)
95
- return;
96
- }
97
-
98
- // Stories panel is focused — handle TUI shortcuts
99
- // Tab key toggles focus
100
- if (key.tab) {
101
- onAction({ type: "TOGGLE_FOCUS" });
102
- return;
103
- }
104
-
105
- // Esc closes overlays
106
- if (key.escape) {
107
- onAction({ type: "CLOSE_OVERLAY" });
108
- return;
109
- }
110
-
111
- // Character-based shortcuts
112
- switch (input.toLowerCase()) {
113
- case "p":
114
- onAction({ type: "PAUSE" });
115
- break;
116
- case "a":
117
- onAction({ type: "ABORT" });
118
- break;
119
- case "s":
120
- // Skip requires a current story
121
- if (currentStory) {
122
- onAction({ type: "SKIP", storyId: currentStory.id });
123
- }
124
- break;
125
- case "q":
126
- onAction({ type: "QUIT" });
127
- break;
128
- case "?":
129
- onAction({ type: "SHOW_HELP" });
130
- break;
131
- case "c":
132
- onAction({ type: "SHOW_COST" });
133
- break;
134
- case "r":
135
- onAction({ type: "RETRY" });
136
- break;
137
- default:
138
- // Ignore unrecognized keys
139
- break;
140
- }
141
- });
142
- }