sequant 2.1.2 → 2.3.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 (146) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +73 -0
  4. package/dist/bin/cli.js +95 -9
  5. package/dist/src/commands/doctor.d.ts +25 -0
  6. package/dist/src/commands/doctor.js +36 -1
  7. package/dist/src/commands/init.d.ts +1 -0
  8. package/dist/src/commands/init.js +118 -0
  9. package/dist/src/commands/locks.d.ts +67 -0
  10. package/dist/src/commands/locks.js +290 -0
  11. package/dist/src/commands/merge.js +11 -0
  12. package/dist/src/commands/prompt.d.ts +39 -0
  13. package/dist/src/commands/prompt.js +179 -0
  14. package/dist/src/commands/run-display.d.ts +26 -0
  15. package/dist/src/commands/run-display.js +150 -0
  16. package/dist/src/commands/run-progress.d.ts +32 -0
  17. package/dist/src/commands/run-progress.js +76 -0
  18. package/dist/src/commands/run.js +83 -73
  19. package/dist/src/commands/stats.d.ts +2 -0
  20. package/dist/src/commands/stats.js +94 -8
  21. package/dist/src/commands/status.js +27 -1
  22. package/dist/src/commands/watch.d.ts +16 -0
  23. package/dist/src/commands/watch.js +147 -0
  24. package/dist/src/lib/ac-linter.d.ts +1 -1
  25. package/dist/src/lib/ac-linter.js +81 -0
  26. package/dist/src/lib/assess-collision-detect.d.ts +91 -0
  27. package/dist/src/lib/assess-collision-detect.js +217 -0
  28. package/dist/src/lib/assess-comment-parser.d.ts +59 -1
  29. package/dist/src/lib/assess-comment-parser.js +124 -2
  30. package/dist/src/lib/cli-ui/format.d.ts +19 -0
  31. package/dist/src/lib/cli-ui/format.js +34 -0
  32. package/dist/src/lib/cli-ui/run-renderer-types.d.ts +181 -0
  33. package/dist/src/lib/cli-ui/run-renderer-types.js +7 -0
  34. package/dist/src/lib/cli-ui/run-renderer.d.ts +239 -0
  35. package/dist/src/lib/cli-ui/run-renderer.js +1173 -0
  36. package/dist/src/lib/heuristics/behavior-rule-detector.d.ts +94 -0
  37. package/dist/src/lib/heuristics/behavior-rule-detector.js +467 -0
  38. package/dist/src/lib/locks/index.d.ts +7 -0
  39. package/dist/src/lib/locks/index.js +5 -0
  40. package/dist/src/lib/locks/lock-manager.d.ts +168 -0
  41. package/dist/src/lib/locks/lock-manager.js +433 -0
  42. package/dist/src/lib/locks/types.d.ts +59 -0
  43. package/dist/src/lib/locks/types.js +31 -0
  44. package/dist/src/lib/qa/markdown-only-ci.d.ts +46 -0
  45. package/dist/src/lib/qa/markdown-only-ci.js +74 -0
  46. package/dist/src/lib/relay/activation.d.ts +60 -0
  47. package/dist/src/lib/relay/activation.js +122 -0
  48. package/dist/src/lib/relay/archive.d.ts +34 -0
  49. package/dist/src/lib/relay/archive.js +106 -0
  50. package/dist/src/lib/relay/frame.d.ts +20 -0
  51. package/dist/src/lib/relay/frame.js +76 -0
  52. package/dist/src/lib/relay/index.d.ts +13 -0
  53. package/dist/src/lib/relay/index.js +13 -0
  54. package/dist/src/lib/relay/paths.d.ts +43 -0
  55. package/dist/src/lib/relay/paths.js +59 -0
  56. package/dist/src/lib/relay/pid.d.ts +34 -0
  57. package/dist/src/lib/relay/pid.js +72 -0
  58. package/dist/src/lib/relay/reader.d.ts +35 -0
  59. package/dist/src/lib/relay/reader.js +115 -0
  60. package/dist/src/lib/relay/types.d.ts +68 -0
  61. package/dist/src/lib/relay/types.js +76 -0
  62. package/dist/src/lib/relay/writer.d.ts +48 -0
  63. package/dist/src/lib/relay/writer.js +113 -0
  64. package/dist/src/lib/settings.d.ts +31 -1
  65. package/dist/src/lib/settings.js +18 -3
  66. package/dist/src/lib/skill-version.d.ts +19 -0
  67. package/dist/src/lib/skill-version.js +68 -0
  68. package/dist/src/lib/templates.d.ts +1 -0
  69. package/dist/src/lib/templates.js +1 -1
  70. package/dist/src/lib/version-check.d.ts +60 -5
  71. package/dist/src/lib/version-check.js +97 -9
  72. package/dist/src/lib/workflow/batch-executor.d.ts +20 -1
  73. package/dist/src/lib/workflow/batch-executor.js +249 -176
  74. package/dist/src/lib/workflow/config-resolver.js +4 -0
  75. package/dist/src/lib/workflow/heartbeat.d.ts +71 -0
  76. package/dist/src/lib/workflow/heartbeat.js +194 -0
  77. package/dist/src/lib/workflow/phase-executor.d.ts +88 -3
  78. package/dist/src/lib/workflow/phase-executor.js +276 -52
  79. package/dist/src/lib/workflow/phase-mapper.d.ts +3 -2
  80. package/dist/src/lib/workflow/phase-mapper.js +17 -20
  81. package/dist/src/lib/workflow/platforms/github.d.ts +1 -1
  82. package/dist/src/lib/workflow/platforms/github.js +20 -3
  83. package/dist/src/lib/workflow/pr-status.d.ts +18 -2
  84. package/dist/src/lib/workflow/pr-status.js +41 -9
  85. package/dist/src/lib/workflow/qa-stagnation.d.ts +117 -0
  86. package/dist/src/lib/workflow/qa-stagnation.js +179 -0
  87. package/dist/src/lib/workflow/run-orchestrator.d.ts +76 -0
  88. package/dist/src/lib/workflow/run-orchestrator.js +382 -29
  89. package/dist/src/lib/workflow/run-reflect.js +1 -1
  90. package/dist/src/lib/workflow/run-state.d.ts +71 -0
  91. package/dist/src/lib/workflow/run-state.js +14 -0
  92. package/dist/src/lib/workflow/state-cleanup.d.ts +13 -5
  93. package/dist/src/lib/workflow/state-cleanup.js +17 -5
  94. package/dist/src/lib/workflow/state-manager.d.ts +12 -1
  95. package/dist/src/lib/workflow/state-manager.js +37 -0
  96. package/dist/src/lib/workflow/state-schema.d.ts +62 -0
  97. package/dist/src/lib/workflow/state-schema.js +35 -1
  98. package/dist/src/lib/workflow/types.d.ts +74 -1
  99. package/dist/src/lib/workflow/worktree-manager.d.ts +12 -4
  100. package/dist/src/lib/workflow/worktree-manager.js +76 -17
  101. package/dist/src/mcp/tools/run.d.ts +44 -0
  102. package/dist/src/mcp/tools/run.js +104 -13
  103. package/dist/src/ui/tui/App.d.ts +14 -0
  104. package/dist/src/ui/tui/App.js +41 -0
  105. package/dist/src/ui/tui/ElapsedTimer.d.ts +10 -0
  106. package/dist/src/ui/tui/ElapsedTimer.js +31 -0
  107. package/dist/src/ui/tui/Header.d.ts +6 -0
  108. package/dist/src/ui/tui/Header.js +15 -0
  109. package/dist/src/ui/tui/IssueBox.d.ts +16 -0
  110. package/dist/src/ui/tui/IssueBox.js +68 -0
  111. package/dist/src/ui/tui/Spinner.d.ts +9 -0
  112. package/dist/src/ui/tui/Spinner.js +18 -0
  113. package/dist/src/ui/tui/index.d.ts +15 -0
  114. package/dist/src/ui/tui/index.js +29 -0
  115. package/dist/src/ui/tui/theme.d.ts +29 -0
  116. package/dist/src/ui/tui/theme.js +52 -0
  117. package/dist/src/ui/tui/truncate.d.ts +11 -0
  118. package/dist/src/ui/tui/truncate.js +31 -0
  119. package/package.json +10 -3
  120. package/templates/agents/sequant-explorer.md +1 -0
  121. package/templates/agents/sequant-qa-checker.md +2 -1
  122. package/templates/agents/sequant-testgen.md +1 -0
  123. package/templates/hooks/post-tool.sh +11 -0
  124. package/templates/hooks/pre-tool.sh +18 -9
  125. package/templates/hooks/relay-check.sh +107 -0
  126. package/templates/relay/frame.txt +11 -0
  127. package/templates/scripts/cleanup-worktree.sh +25 -3
  128. package/templates/scripts/new-feature.sh +6 -0
  129. package/templates/skills/_shared/references/behavior-rule-detection.md +205 -0
  130. package/templates/skills/_shared/references/subagent-types.md +21 -8
  131. package/templates/skills/assess/SKILL.md +261 -94
  132. package/templates/skills/assess/references/predicted-collision-detection.md +109 -0
  133. package/templates/skills/docs/SKILL.md +141 -22
  134. package/templates/skills/exec/SKILL.md +10 -49
  135. package/templates/skills/fullsolve/SKILL.md +80 -32
  136. package/templates/skills/loop/SKILL.md +28 -0
  137. package/templates/skills/merger/SKILL.md +621 -0
  138. package/templates/skills/qa/SKILL.md +746 -8
  139. package/templates/skills/qa/scripts/quality-checks.sh +47 -1
  140. package/templates/skills/setup/SKILL.md +6 -0
  141. package/templates/skills/spec/SKILL.md +217 -964
  142. package/templates/skills/spec/references/parallel-groups.md +7 -0
  143. package/templates/skills/spec/references/quality-checklist.md +75 -0
  144. package/templates/skills/spec/references/recommended-workflow.md +4 -2
  145. package/templates/skills/test/SKILL.md +0 -27
  146. package/templates/skills/testgen/SKILL.md +24 -44
@@ -0,0 +1,239 @@
1
+ /**
2
+ * RunRenderer — single coordinator for all `sequant run` stdout output.
3
+ *
4
+ * Replaces the dual-output regression where `PhaseSpinner` (legacy, #244) and
5
+ * the parallel-mode `▸/✔` lines (#458) both wrote to stdout for single-issue
6
+ * runs and produced overwritten / missing-duration lines.
7
+ *
8
+ * Three modes implement the same `RunRenderer` interface:
9
+ * - TTYRenderer: live grid (top, redrawn ~1Hz) + events log (below)
10
+ * - NonTTYRenderer: append-only `[HH:MM:SS]` events + 60s heartbeat
11
+ * - OrchestratorRenderer: no-op when SEQUANT_ORCHESTRATOR is set so MCP's
12
+ * `emitProgressLine` JSON is the only stdout
13
+ *
14
+ * See issue #618.
15
+ */
16
+ import type { IssueRegistration, IssueState, ProgressEvent, RenderOptions, RendererMode, RunRenderer, SummaryRenderInput } from "./run-renderer-types.js";
17
+ /**
18
+ * #624 Item 4: normalized failure signature for dedup decisions.
19
+ *
20
+ * Strips ANSI escape sequences, lowercases, trims whitespace, and truncates to
21
+ * the first 80 visible chars. The plan deliberately chose a length-bounded
22
+ * prefix over a crypto hash so debugging can match signatures by eye.
23
+ */
24
+ export declare function failureSignature(error: string | undefined): string;
25
+ /**
26
+ * #624 Item 3 / Derived AC-D2: shared suffix builder used by all three retry
27
+ * sites (NonTTY events log, TTY events log, TTY status header). Centralizes
28
+ * the `(attempt N/M)` / `loop N/M` literals so they cannot drift between paths.
29
+ *
30
+ * `kind` selects the surface:
31
+ * - "events" → events-log line: leading space + parentheses
32
+ * - "header" → status cell: leading space, no parentheses
33
+ *
34
+ * Returns the empty string when the attempt counter does not apply
35
+ * (no iteration, iteration === 1, or non-positive).
36
+ */
37
+ export declare function formatRetrySuffix(iteration: number | undefined, maxIterations: number, kind: "events" | "header"): string;
38
+ declare abstract class BaseRenderer implements RunRenderer {
39
+ protected readonly issues: Map<number, IssueState>;
40
+ protected readonly stdoutWrite: (s: string) => void;
41
+ protected readonly stderrWrite: (s: string) => void;
42
+ protected readonly now: () => number;
43
+ protected readonly wallClock: () => Date;
44
+ protected readonly noColor: boolean;
45
+ protected readonly runStartedAt: number;
46
+ protected paused: boolean;
47
+ protected disposed: boolean;
48
+ constructor(options: RenderOptions);
49
+ registerIssue(reg: IssueRegistration): void;
50
+ onEvent(event: ProgressEvent): void;
51
+ setPullRequest(issue: number, prNumber: number, prUrl: string): void;
52
+ pause(): void;
53
+ resume(): void;
54
+ abstract renderSummary(input: SummaryRenderInput): void;
55
+ dispose(): void;
56
+ protected applyEvent(state: IssueState, event: ProgressEvent): void;
57
+ /** Mark an issue done after PR is recorded — derived from phase completion. */
58
+ protected maybeMarkIssueDone(state: IssueState): void;
59
+ protected afterEvent(_event: ProgressEvent, state: IssueState): void;
60
+ protected afterStateChange(): void;
61
+ protected onPause(): void;
62
+ protected onResume(): void;
63
+ protected onDispose(): void;
64
+ }
65
+ /**
66
+ * No-op renderer used when `SEQUANT_ORCHESTRATOR` is set.
67
+ *
68
+ * The orchestrator (e.g. MCP server) consumes `emitProgressLine` JSON from
69
+ * batch-executor directly. Rendering anything else from the CLI would be
70
+ * double-emission. We still track state so `renderSummary` could be useful
71
+ * if explicitly invoked, but neither stdout nor stderr is touched.
72
+ */
73
+ export declare class OrchestratorRenderer extends BaseRenderer {
74
+ renderSummary(): void;
75
+ }
76
+ export declare class NonTTYRenderer extends BaseRenderer {
77
+ private heartbeatTimer;
78
+ private readonly heartbeatMs;
79
+ private readonly columnsOverride?;
80
+ private readonly maxLoopIterations;
81
+ private lastEventAt;
82
+ constructor(options: RenderOptions);
83
+ private getColumns;
84
+ private startHeartbeat;
85
+ /** Test hook: drive a heartbeat without waiting on real timers. */
86
+ tickHeartbeatNow(): void;
87
+ private tickHeartbeat;
88
+ protected afterEvent(event: ProgressEvent, state: IssueState): void;
89
+ private emitEventLine;
90
+ /** Append a single `\n`-terminated line with `[HH:MM:SS]` prefix. */
91
+ private emitLine;
92
+ setPullRequest(issue: number, prNumber: number, prUrl: string): void;
93
+ renderSummary(input: SummaryRenderInput): void;
94
+ protected onDispose(): void;
95
+ }
96
+ /**
97
+ * #624 Derived AC-D1: test-only observability for the log-update stub. Tests
98
+ * can read `replacementCount` and `lastFrame` to verify the frame is *replaced*
99
+ * on each redraw rather than appended — the foundational guarantee that Items
100
+ * 1 and 2 rely on.
101
+ *
102
+ * `clearCalls` / `doneCalls` (added in the hardening pass) let AC-2.2 verify
103
+ * the renderer actually invokes `logUpdate.clear()` + `logUpdate.done()` during
104
+ * `renderSummary` teardown — not just that the stub's local `lastFrame` was
105
+ * reset.
106
+ */
107
+ export interface TTYTestStub {
108
+ /** Number of times the live frame was replaced (not the initial write). */
109
+ readonly replacementCount: number;
110
+ /** The most recent live frame text passed to log-update. */
111
+ readonly lastFrame: string;
112
+ /** Number of times `logUpdate.clear()` was invoked. */
113
+ readonly clearCalls: number;
114
+ /** Number of times `logUpdate.done()` was invoked. */
115
+ readonly doneCalls: number;
116
+ }
117
+ export declare class TTYRenderer extends BaseRenderer {
118
+ private readonly liveTickMs;
119
+ private liveTimer;
120
+ private spinnerFrame;
121
+ private readonly columnsOverride?;
122
+ private readonly rowsOverride?;
123
+ private readonly noSignalListeners;
124
+ private readonly stallThresholdMs;
125
+ private readonly multiIssueRowCap;
126
+ private readonly maxLoopIterations;
127
+ private readonly logUpdateImpl;
128
+ private readonly logUpdateClear;
129
+ private readonly logUpdateDone;
130
+ private resizeListener;
131
+ private banner;
132
+ private readonly _testStub;
133
+ constructor(options: RenderOptions);
134
+ /**
135
+ * #624 Derived AC-D1: expose the test-only log-update stub. Returns `null`
136
+ * when not in test mode (production renders go through real `log-update`).
137
+ */
138
+ getTestStub(): TTYTestStub | null;
139
+ private startLiveTimer;
140
+ private installSignalListeners;
141
+ /** Test hook: drive a tick without waiting on real timers. */
142
+ tickNow(): void;
143
+ private tick;
144
+ protected afterEvent(event: ProgressEvent, state: IssueState): void;
145
+ protected afterStateChange(): void;
146
+ /** Set a banner that renders above the live grid (e.g. worktree-loss). */
147
+ setBanner(text: string | null): void;
148
+ private appendEventLine;
149
+ setPullRequest(issue: number, prNumber: number, prUrl: string): void;
150
+ renderSummary(input: SummaryRenderInput): void;
151
+ protected onPause(): void;
152
+ protected onResume(): void;
153
+ protected onDispose(): void;
154
+ private getColumns;
155
+ /**
156
+ * #624 Item 1: terminal row count, with a safe default for piped / detached
157
+ * stdout where `process.stdout.rows` is undefined.
158
+ */
159
+ private getRows;
160
+ /**
161
+ * #624 Item 1: hard ceiling on live-zone height. The cap is
162
+ * `max(8, rows - 5)`, dropping to `max(8, rows - 7)` when a banner is active
163
+ * so the banner + a few separator rows still fit. The floor of 8 prevents
164
+ * the live zone from collapsing on tiny terminals.
165
+ */
166
+ private getMaxLiveRows;
167
+ private redraw;
168
+ /** Public for tests — render the live zone to a string without emitting. */
169
+ renderLiveFrame(columns?: number): string;
170
+ /**
171
+ * #624 Item 1 (AC-1.1): hard ceiling on rendered frame height. The interior
172
+ * `applyRowCap` already collapses excess issues into the rollup row, but the
173
+ * frame can still drift over the cap if many issues have multi-line status
174
+ * cells (sub-status + phase sequence). This is the belt-and-braces clamp
175
+ * that guarantees `log-update` never sees a frame taller than the terminal.
176
+ *
177
+ * Always engages — when `rows` isn't explicitly provided, `getRows()` returns
178
+ * `DEFAULT_TERMINAL_ROWS` (100) so the cap is generous but never disengaged.
179
+ */
180
+ private clampFrameHeight;
181
+ private renderNarrowFrame;
182
+ private renderSingleIssueFrame;
183
+ private renderMultiIssueFrame;
184
+ /**
185
+ * AC-28 + #624 Item 1: enforce the per-frame issue row cap, derived from
186
+ * the smaller of `multiIssueRowCap` (static config) and a dynamic ceiling
187
+ * computed from terminal height. The dynamic ceiling reserves ~3 lines per
188
+ * issue (status header + sub-status + separator) and a fixed overhead for
189
+ * the frame header, blank lines, grid borders, and the rollup line.
190
+ *
191
+ * If the cap is not exceeded, returns all issues unchanged. Otherwise: keep
192
+ * all non-done rows, then fill remaining slots with the most recently
193
+ * completed done rows; older done rows roll up into a single summary entry.
194
+ */
195
+ private applyRowCap;
196
+ /**
197
+ * #624 Item 1 (AC-1.1): smaller of the configured static cap and the
198
+ * dynamic terminal-height-derived cap. Each issue row takes roughly 3 grid
199
+ * lines (header, sub-status, separator); the fixed overhead covers the
200
+ * frame title, blank lines, grid borders, and the rollup row.
201
+ *
202
+ * Always engages — when `rows` isn't explicitly provided, `getRows()` returns
203
+ * `DEFAULT_TERMINAL_ROWS` (100) which produces a dynamic cap of ~30, well
204
+ * above the static `multiIssueRowCap` default of 10, so the static cap stays
205
+ * in charge for normal-height terminals.
206
+ */
207
+ private effectiveRowCap;
208
+ private statusHeader;
209
+ private statusSubLines;
210
+ private statusCellLines;
211
+ private runHeader;
212
+ private rollupLine;
213
+ private drawKeyValueTable;
214
+ private drawIssueGrid;
215
+ }
216
+ export interface CreateRendererOptions extends RenderOptions {
217
+ /** Force a specific mode (otherwise auto-detected from env + TTY). */
218
+ mode?: RendererMode;
219
+ }
220
+ /**
221
+ * Create a `RunRenderer` matching the current execution context.
222
+ *
223
+ * Detection order:
224
+ * 1. Explicit `mode` override.
225
+ * 2. `SEQUANT_ORCHESTRATOR` env var → orchestrator (no-op).
226
+ * 3. `process.stdout.isTTY` (or `options.isTTY`) → TTY renderer.
227
+ * 4. Otherwise → non-TTY renderer.
228
+ */
229
+ export declare function createRunRenderer(options?: CreateRendererOptions): RunRenderer;
230
+ /**
231
+ * Public summary helper — used by the legacy displaySummary path so callers
232
+ * that bypass the renderer still get the new grid layout.
233
+ */
234
+ export declare function renderRunSummary(input: SummaryRenderInput, options?: {
235
+ stdoutWrite?: (s: string) => void;
236
+ noColor?: boolean;
237
+ columns?: number;
238
+ }): void;
239
+ export {};