sequant 2.9.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +20 -5
- package/dist/bin/cli.js +143 -18
- package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
- package/dist/marketplace/external_plugins/sequant/.mcp.json +1 -1
- package/dist/marketplace/external_plugins/sequant/README.md +56 -2
- package/dist/marketplace/external_plugins/sequant/hooks/parallel-marker.sh +50 -0
- package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +20 -7
- package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +75 -10
- package/dist/marketplace/external_plugins/sequant/skills/_shared/references/trust-model.md +18 -0
- package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +215 -390
- package/dist/marketplace/external_plugins/sequant/skills/assess/references/predicted-collision-detection.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/docs/SKILL.md +4 -4
- package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +26 -6
- package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +3 -1
- package/dist/marketplace/external_plugins/sequant/skills/loop/SKILL.md +38 -2
- package/dist/marketplace/external_plugins/sequant/skills/merger/SKILL.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +337 -57
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/anti-pattern-detection.md +6 -6
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/call-site-review.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/code-review-checklist.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/fixtures/injection-issue-body.md +36 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/quality-gates.md +21 -7
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/testing-requirements.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +11 -11
- package/dist/marketplace/external_plugins/sequant/skills/release/SKILL.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +5 -5
- package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +2 -0
- package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +1 -1
- package/dist/src/commands/assess-render.d.ts +23 -0
- package/dist/src/commands/assess-render.js +60 -0
- package/dist/src/commands/doctor.js +8 -13
- package/dist/src/commands/init.js +13 -1
- package/dist/src/commands/locks.d.ts +20 -1
- package/dist/src/commands/locks.js +208 -4
- package/dist/src/commands/logs.js +14 -5
- package/dist/src/commands/merge.js +154 -2
- package/dist/src/commands/ready-tui-adapter.js +6 -1
- package/dist/src/commands/ready.d.ts +31 -3
- package/dist/src/commands/ready.js +53 -13
- package/dist/src/commands/resume.d.ts +113 -0
- package/dist/src/commands/resume.js +193 -0
- package/dist/src/commands/run-display.js +38 -4
- package/dist/src/commands/run-flags.d.ts +42 -1
- package/dist/src/commands/run-flags.js +53 -1
- package/dist/src/commands/run-progress.js +26 -1
- package/dist/src/commands/run.js +11 -10
- package/dist/src/commands/state.js +7 -0
- package/dist/src/commands/status.d.ts +9 -0
- package/dist/src/commands/status.js +24 -1
- package/dist/src/commands/sync.js +90 -19
- package/dist/src/commands/update.js +28 -5
- package/dist/src/commands/worktree.d.ts +31 -0
- package/dist/src/commands/worktree.js +95 -0
- package/dist/src/lib/ac-parser.d.ts +14 -0
- package/dist/src/lib/ac-parser.js +99 -5
- package/dist/src/lib/assess/index.d.ts +10 -0
- package/dist/src/lib/assess/index.js +9 -0
- package/dist/src/lib/assess/renderer.d.ts +64 -0
- package/dist/src/lib/assess/renderer.js +481 -0
- package/dist/src/lib/assess/types.d.ts +224 -0
- package/dist/src/lib/assess/types.js +241 -0
- package/dist/src/lib/ci/outputs.d.ts +15 -2
- package/dist/src/lib/ci/outputs.js +17 -5
- package/dist/src/lib/cli-flags.d.ts +56 -0
- package/dist/src/lib/cli-flags.js +89 -0
- package/dist/src/lib/cli-ui/run-renderer-types.d.ts +23 -7
- package/dist/src/lib/cli-ui/run-renderer.d.ts +10 -0
- package/dist/src/lib/cli-ui/run-renderer.js +69 -1
- package/dist/src/lib/errors.d.ts +78 -6
- package/dist/src/lib/errors.js +133 -15
- package/dist/src/lib/locks/checkout-lock.d.ts +193 -0
- package/dist/src/lib/locks/checkout-lock.js +389 -0
- package/dist/src/lib/locks/index.d.ts +7 -4
- package/dist/src/lib/locks/index.js +5 -3
- package/dist/src/lib/locks/lock-manager.d.ts +101 -3
- package/dist/src/lib/locks/lock-manager.js +277 -8
- package/dist/src/lib/locks/types.d.ts +106 -3
- package/dist/src/lib/locks/types.js +44 -0
- package/dist/src/lib/mcp-config.d.ts +45 -0
- package/dist/src/lib/mcp-config.js +77 -1
- package/dist/src/lib/merge-check/combined-branch-test.d.ts +21 -2
- package/dist/src/lib/merge-check/combined-branch-test.js +233 -110
- package/dist/src/lib/merge-check/command-result.d.ts +36 -0
- package/dist/src/lib/merge-check/command-result.js +56 -0
- package/dist/src/lib/merge-check/index.d.ts +4 -0
- package/dist/src/lib/merge-check/index.js +1 -1
- package/dist/src/lib/merge-check/report.js +5 -1
- package/dist/src/lib/merge-check/types.d.ts +9 -0
- package/dist/src/lib/merge-check/watch.d.ts +121 -0
- package/dist/src/lib/merge-check/watch.js +215 -0
- package/dist/src/lib/qa/infra-blocked-ci.d.ts +90 -0
- package/dist/src/lib/qa/infra-blocked-ci.js +80 -0
- package/dist/src/lib/settings.d.ts +87 -0
- package/dist/src/lib/settings.js +106 -8
- package/dist/src/lib/shutdown.d.ts +42 -2
- package/dist/src/lib/shutdown.js +75 -5
- package/dist/src/lib/skills-check.d.ts +26 -0
- package/dist/src/lib/skills-check.js +31 -0
- package/dist/src/lib/stacks.d.ts +110 -1
- package/dist/src/lib/stacks.js +244 -5
- package/dist/src/lib/templates.d.ts +74 -0
- package/dist/src/lib/templates.js +171 -16
- package/dist/src/lib/test-tautology-detector.d.ts +10 -2
- package/dist/src/lib/test-tautology-detector.js +213 -12
- package/dist/src/lib/version-check.d.ts +31 -0
- package/dist/src/lib/version-check.js +45 -2
- package/dist/src/lib/workflow/batch-executor.d.ts +125 -6
- package/dist/src/lib/workflow/batch-executor.js +552 -60
- package/dist/src/lib/workflow/chain-resume.d.ts +13 -11
- package/dist/src/lib/workflow/chain-resume.js +24 -20
- package/dist/src/lib/workflow/completed-status.d.ts +52 -0
- package/dist/src/lib/workflow/completed-status.js +57 -0
- package/dist/src/lib/workflow/config-resolver.d.ts +51 -0
- package/dist/src/lib/workflow/config-resolver.js +143 -2
- package/dist/src/lib/workflow/drivers/agent-driver.d.ts +22 -0
- package/dist/src/lib/workflow/drivers/aider.d.ts +2 -0
- package/dist/src/lib/workflow/drivers/aider.js +2 -0
- package/dist/src/lib/workflow/drivers/claude-code.d.ts +14 -0
- package/dist/src/lib/workflow/drivers/claude-code.js +25 -2
- package/dist/src/lib/workflow/effort-escalation.d.ts +73 -0
- package/dist/src/lib/workflow/effort-escalation.js +82 -0
- package/dist/src/lib/workflow/error-classifier.d.ts +4 -1
- package/dist/src/lib/workflow/error-classifier.js +4 -0
- package/dist/src/lib/workflow/git-diff-utils.d.ts +35 -3
- package/dist/src/lib/workflow/git-diff-utils.js +77 -4
- package/dist/src/lib/workflow/heartbeat.d.ts +38 -0
- package/dist/src/lib/workflow/heartbeat.js +90 -0
- package/dist/src/lib/workflow/log-writer.d.ts +54 -2
- package/dist/src/lib/workflow/log-writer.js +95 -6
- package/dist/src/lib/workflow/metrics-schema.d.ts +52 -9
- package/dist/src/lib/workflow/metrics-schema.js +33 -0
- package/dist/src/lib/workflow/metrics-writer.d.ts +11 -0
- package/dist/src/lib/workflow/phase-detection.d.ts +12 -0
- package/dist/src/lib/workflow/phase-detection.js +5 -1
- package/dist/src/lib/workflow/phase-executor.d.ts +203 -14
- package/dist/src/lib/workflow/phase-executor.js +467 -52
- package/dist/src/lib/workflow/phase-registry.js +2 -1
- package/dist/src/lib/workflow/platforms/github.d.ts +64 -0
- package/dist/src/lib/workflow/platforms/github.js +152 -0
- package/dist/src/lib/workflow/qa-cache.d.ts +6 -1
- package/dist/src/lib/workflow/qa-cache.js +22 -9
- package/dist/src/lib/workflow/ready-gate.d.ts +45 -4
- package/dist/src/lib/workflow/ready-gate.js +49 -12
- package/dist/src/lib/workflow/run-log-schema.d.ts +69 -0
- package/dist/src/lib/workflow/run-log-schema.js +78 -2
- package/dist/src/lib/workflow/run-orchestrator.d.ts +19 -0
- package/dist/src/lib/workflow/run-orchestrator.js +168 -20
- package/dist/src/lib/workflow/skills-preflight.d.ts +89 -0
- package/dist/src/lib/workflow/skills-preflight.js +112 -0
- package/dist/src/lib/workflow/spec-recommendation.d.ts +71 -0
- package/dist/src/lib/workflow/spec-recommendation.js +142 -0
- package/dist/src/lib/workflow/state-cleanup.js +9 -2
- package/dist/src/lib/workflow/state-manager.d.ts +33 -0
- package/dist/src/lib/workflow/state-manager.js +83 -0
- package/dist/src/lib/workflow/state-schema.d.ts +26 -0
- package/dist/src/lib/workflow/state-schema.js +47 -0
- package/dist/src/lib/workflow/types.d.ts +190 -4
- package/dist/src/lib/workflow/types.js +1 -0
- package/dist/src/lib/workflow/worktree-manager.d.ts +36 -3
- package/dist/src/lib/workflow/worktree-manager.js +111 -24
- package/dist/src/lib/workflow/worktree-resolver.d.ts +73 -0
- package/dist/src/lib/workflow/worktree-resolver.js +126 -0
- package/dist/src/mcp/tools/run.d.ts +9 -1
- package/dist/src/mcp/tools/run.js +20 -1
- package/dist/src/mcp/tools/status.js +6 -0
- package/dist/src/ui/tui/ElapsedTimer.d.ts +12 -3
- package/dist/src/ui/tui/ElapsedTimer.js +12 -10
- package/dist/src/ui/tui/IssueBox.js +10 -2
- package/dist/src/ui/tui/row-cap.js +2 -1
- package/dist/src/ui/tui/theme.d.ts +7 -0
- package/dist/src/ui/tui/theme.js +9 -0
- package/package.json +10 -8
- package/templates/hooks/parallel-marker.sh +50 -0
- package/templates/hooks/post-tool.sh +20 -7
- package/templates/hooks/pre-tool.sh +303 -10
- package/templates/scripts/cleanup-worktree.sh +217 -33
- package/templates/scripts/new-feature.sh +289 -35
- package/templates/skills/_shared/references/subagent-types.md +7 -18
- package/templates/skills/_shared/references/trust-model.md +18 -0
- package/templates/skills/assess/SKILL.md +220 -391
- package/templates/skills/assess/references/predicted-collision-detection.md +1 -1
- package/templates/skills/docs/SKILL.md +4 -4
- package/templates/skills/exec/SKILL.md +87 -13
- package/templates/skills/fullsolve/SKILL.md +130 -22
- package/templates/skills/loop/SKILL.md +94 -13
- package/templates/skills/merger/SKILL.md +100 -12
- package/templates/skills/qa/SKILL.md +396 -63
- package/templates/skills/qa/references/anti-pattern-detection.md +6 -6
- package/templates/skills/qa/references/call-site-review.md +2 -2
- package/templates/skills/qa/references/code-review-checklist.md +2 -2
- package/templates/skills/qa/references/fixtures/injection-issue-body.md +36 -0
- package/templates/skills/qa/references/quality-gates.md +21 -7
- package/templates/skills/qa/references/testing-requirements.md +1 -1
- package/templates/skills/qa/scripts/quality-checks.sh +11 -11
- package/templates/skills/release/SKILL.md +80 -1
- package/templates/skills/setup/SKILL.md +5 -5
- package/templates/skills/spec/SKILL.md +33 -15
- package/templates/skills/spec/references/recommended-workflow.md +14 -1
- package/templates/skills/test/SKILL.md +1 -1
- package/templates/skills/testgen/SKILL.md +23 -6
- package/dist/src/lib/phase-spinner.d.ts +0 -146
- package/dist/src/lib/phase-spinner.js +0 -255
- package/dist/src/lib/workflow/pr-operations.d.ts +0 -86
- package/dist/src/lib/workflow/pr-operations.js +0 -326
- package/dist/src/lib/workflow/run-summary.d.ts +0 -36
- package/dist/src/lib/workflow/run-summary.js +0 -142
- package/templates/agents/sequant-explorer.md +0 -24
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase Spinner - Animated spinner with elapsed time for phase execution
|
|
3
|
-
*
|
|
4
|
-
* Wraps the cli-ui spinner with:
|
|
5
|
-
* - Elapsed time tracking (updates every 5 seconds)
|
|
6
|
-
* - Phase progress indicator (e.g., "spec (1/3)")
|
|
7
|
-
* - Integration with ShutdownManager for graceful cleanup
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* const spinner = new PhaseSpinner({
|
|
12
|
-
* phase: 'exec',
|
|
13
|
-
* phaseIndex: 2,
|
|
14
|
-
* totalPhases: 3,
|
|
15
|
-
* shutdownManager,
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* spinner.start();
|
|
19
|
-
* // ... phase execution
|
|
20
|
-
* spinner.succeed(); // Shows "✓ exec (2/3) (45s)"
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
import type { ShutdownManager } from "./shutdown.js";
|
|
24
|
-
/**
|
|
25
|
-
* Options for creating a PhaseSpinner
|
|
26
|
-
*/
|
|
27
|
-
export interface PhaseSpinnerOptions {
|
|
28
|
-
/** Phase name (e.g., "spec", "exec", "qa") */
|
|
29
|
-
phase: string;
|
|
30
|
-
/** Current phase index (1-based) */
|
|
31
|
-
phaseIndex: number;
|
|
32
|
-
/** Total number of phases */
|
|
33
|
-
totalPhases: number;
|
|
34
|
-
/** Optional ShutdownManager for graceful cleanup */
|
|
35
|
-
shutdownManager?: ShutdownManager;
|
|
36
|
-
/** Optional prefix for indentation (default: " ") */
|
|
37
|
-
prefix?: string;
|
|
38
|
-
/** Optional quality loop iteration (shows "iteration N" if > 1) */
|
|
39
|
-
iteration?: number;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Format elapsed time in human-readable format
|
|
43
|
-
*
|
|
44
|
-
* @param seconds - Elapsed time in seconds
|
|
45
|
-
* @returns Formatted string (e.g., "45s", "2m 15s", "1h 5m")
|
|
46
|
-
*/
|
|
47
|
-
export declare function formatElapsedTime(seconds: number): string;
|
|
48
|
-
/**
|
|
49
|
-
* PhaseSpinner - Animated spinner with elapsed time and phase progress
|
|
50
|
-
*
|
|
51
|
-
* Features:
|
|
52
|
-
* - Animated spinner (or text fallback) via cli-ui
|
|
53
|
-
* - Elapsed time tracking with automatic updates
|
|
54
|
-
* - Phase progress indicator (e.g., "exec (2/3)")
|
|
55
|
-
* - ShutdownManager integration for graceful Ctrl+C cleanup
|
|
56
|
-
* - Pause/resume for verbose streaming output
|
|
57
|
-
*/
|
|
58
|
-
export declare class PhaseSpinner {
|
|
59
|
-
private spinner;
|
|
60
|
-
private startTime;
|
|
61
|
-
private intervalId;
|
|
62
|
-
private disposed;
|
|
63
|
-
private paused;
|
|
64
|
-
private readonly phase;
|
|
65
|
-
private readonly phaseIndex;
|
|
66
|
-
private readonly totalPhases;
|
|
67
|
-
private readonly shutdownManager?;
|
|
68
|
-
private readonly prefix;
|
|
69
|
-
private readonly iteration?;
|
|
70
|
-
private readonly cleanupName;
|
|
71
|
-
constructor(options: PhaseSpinnerOptions);
|
|
72
|
-
/**
|
|
73
|
-
* Format the spinner text with phase, progress, and elapsed time
|
|
74
|
-
*/
|
|
75
|
-
private formatText;
|
|
76
|
-
/**
|
|
77
|
-
* Update the spinner text with current elapsed time
|
|
78
|
-
*/
|
|
79
|
-
private updateElapsedTime;
|
|
80
|
-
/**
|
|
81
|
-
* Start the spinner
|
|
82
|
-
*
|
|
83
|
-
* Begins the animation and elapsed time tracking.
|
|
84
|
-
*/
|
|
85
|
-
start(): PhaseSpinner;
|
|
86
|
-
/**
|
|
87
|
-
* Mark the phase as succeeded
|
|
88
|
-
*
|
|
89
|
-
* Stops the spinner and shows a checkmark with total duration.
|
|
90
|
-
*/
|
|
91
|
-
succeed(customText?: string): PhaseSpinner;
|
|
92
|
-
/**
|
|
93
|
-
* Mark the phase as failed
|
|
94
|
-
*
|
|
95
|
-
* Stops the spinner and shows an error indicator with message.
|
|
96
|
-
*/
|
|
97
|
-
fail(error?: string): PhaseSpinner;
|
|
98
|
-
/**
|
|
99
|
-
* Stop the spinner without success/fail indication
|
|
100
|
-
*
|
|
101
|
-
* Use this for cleanup or when the phase is interrupted.
|
|
102
|
-
*/
|
|
103
|
-
stop(): PhaseSpinner;
|
|
104
|
-
/**
|
|
105
|
-
* Pause the spinner (for verbose streaming output)
|
|
106
|
-
*
|
|
107
|
-
* Temporarily stops the animation without disposing.
|
|
108
|
-
* Call resume() to continue.
|
|
109
|
-
*/
|
|
110
|
-
pause(): PhaseSpinner;
|
|
111
|
-
/**
|
|
112
|
-
* Resume the spinner after pause
|
|
113
|
-
*
|
|
114
|
-
* Restarts the animation with updated elapsed time.
|
|
115
|
-
*/
|
|
116
|
-
resume(): PhaseSpinner;
|
|
117
|
-
/**
|
|
118
|
-
* Check if the spinner is currently active
|
|
119
|
-
*/
|
|
120
|
-
get isSpinning(): boolean;
|
|
121
|
-
/**
|
|
122
|
-
* Get the total elapsed time in seconds
|
|
123
|
-
*/
|
|
124
|
-
get elapsedSeconds(): number;
|
|
125
|
-
/**
|
|
126
|
-
* Dispose of the spinner and clean up resources
|
|
127
|
-
*
|
|
128
|
-
* Called automatically by succeed(), fail(), or stop().
|
|
129
|
-
* Safe to call multiple times.
|
|
130
|
-
*/
|
|
131
|
-
dispose(): void;
|
|
132
|
-
/**
|
|
133
|
-
* Clear the elapsed time update interval
|
|
134
|
-
*/
|
|
135
|
-
private clearInterval;
|
|
136
|
-
/**
|
|
137
|
-
* Unregister from ShutdownManager
|
|
138
|
-
*/
|
|
139
|
-
private unregisterCleanup;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Create a PhaseSpinner with the given options
|
|
143
|
-
*
|
|
144
|
-
* Convenience function matching the pattern of cli-ui.spinner().
|
|
145
|
-
*/
|
|
146
|
-
export declare function phaseSpinner(options: PhaseSpinnerOptions): PhaseSpinner;
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase Spinner - Animated spinner with elapsed time for phase execution
|
|
3
|
-
*
|
|
4
|
-
* Wraps the cli-ui spinner with:
|
|
5
|
-
* - Elapsed time tracking (updates every 5 seconds)
|
|
6
|
-
* - Phase progress indicator (e.g., "spec (1/3)")
|
|
7
|
-
* - Integration with ShutdownManager for graceful cleanup
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* const spinner = new PhaseSpinner({
|
|
12
|
-
* phase: 'exec',
|
|
13
|
-
* phaseIndex: 2,
|
|
14
|
-
* totalPhases: 3,
|
|
15
|
-
* shutdownManager,
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* spinner.start();
|
|
19
|
-
* // ... phase execution
|
|
20
|
-
* spinner.succeed(); // Shows "✓ exec (2/3) (45s)"
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
import { spinner as createSpinner } from "./cli-ui.js";
|
|
24
|
-
/**
|
|
25
|
-
* Elapsed time update interval in milliseconds
|
|
26
|
-
*/
|
|
27
|
-
const ELAPSED_UPDATE_INTERVAL_MS = 5000;
|
|
28
|
-
/**
|
|
29
|
-
* Format elapsed time in human-readable format
|
|
30
|
-
*
|
|
31
|
-
* @param seconds - Elapsed time in seconds
|
|
32
|
-
* @returns Formatted string (e.g., "45s", "2m 15s", "1h 5m")
|
|
33
|
-
*/
|
|
34
|
-
export function formatElapsedTime(seconds) {
|
|
35
|
-
if (seconds < 60) {
|
|
36
|
-
return `${Math.floor(seconds)}s`;
|
|
37
|
-
}
|
|
38
|
-
if (seconds < 3600) {
|
|
39
|
-
const minutes = Math.floor(seconds / 60);
|
|
40
|
-
const remainingSeconds = Math.floor(seconds % 60);
|
|
41
|
-
return remainingSeconds > 0
|
|
42
|
-
? `${minutes}m ${remainingSeconds}s`
|
|
43
|
-
: `${minutes}m`;
|
|
44
|
-
}
|
|
45
|
-
const hours = Math.floor(seconds / 3600);
|
|
46
|
-
const remainingMinutes = Math.floor((seconds % 3600) / 60);
|
|
47
|
-
return remainingMinutes > 0 ? `${hours}h ${remainingMinutes}m` : `${hours}h`;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* PhaseSpinner - Animated spinner with elapsed time and phase progress
|
|
51
|
-
*
|
|
52
|
-
* Features:
|
|
53
|
-
* - Animated spinner (or text fallback) via cli-ui
|
|
54
|
-
* - Elapsed time tracking with automatic updates
|
|
55
|
-
* - Phase progress indicator (e.g., "exec (2/3)")
|
|
56
|
-
* - ShutdownManager integration for graceful Ctrl+C cleanup
|
|
57
|
-
* - Pause/resume for verbose streaming output
|
|
58
|
-
*/
|
|
59
|
-
export class PhaseSpinner {
|
|
60
|
-
spinner;
|
|
61
|
-
startTime = 0;
|
|
62
|
-
intervalId = null;
|
|
63
|
-
disposed = false;
|
|
64
|
-
paused = false;
|
|
65
|
-
phase;
|
|
66
|
-
phaseIndex;
|
|
67
|
-
totalPhases;
|
|
68
|
-
shutdownManager;
|
|
69
|
-
prefix;
|
|
70
|
-
iteration;
|
|
71
|
-
cleanupName;
|
|
72
|
-
constructor(options) {
|
|
73
|
-
this.phase = options.phase;
|
|
74
|
-
this.phaseIndex = options.phaseIndex;
|
|
75
|
-
this.totalPhases = options.totalPhases;
|
|
76
|
-
this.shutdownManager = options.shutdownManager;
|
|
77
|
-
this.prefix = options.prefix ?? " ";
|
|
78
|
-
this.iteration = options.iteration;
|
|
79
|
-
this.cleanupName = `phase-spinner-${options.phase}`;
|
|
80
|
-
// Create the underlying spinner with initial text
|
|
81
|
-
this.spinner = createSpinner(this.formatText(0));
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Format the spinner text with phase, progress, and elapsed time
|
|
85
|
-
*/
|
|
86
|
-
formatText(elapsedSeconds) {
|
|
87
|
-
const progress = `(${this.phaseIndex}/${this.totalPhases})`;
|
|
88
|
-
const elapsed = elapsedSeconds > 0 ? ` ${formatElapsedTime(elapsedSeconds)}` : "";
|
|
89
|
-
const iterationSuffix = this.iteration && this.iteration > 1
|
|
90
|
-
? ` [iteration ${this.iteration}]`
|
|
91
|
-
: "";
|
|
92
|
-
return `${this.prefix}${this.phase} ${progress}...${elapsed}${iterationSuffix}`;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Update the spinner text with current elapsed time
|
|
96
|
-
*/
|
|
97
|
-
updateElapsedTime() {
|
|
98
|
-
if (this.disposed || this.paused)
|
|
99
|
-
return;
|
|
100
|
-
const elapsedSeconds = (Date.now() - this.startTime) / 1000;
|
|
101
|
-
this.spinner.text = this.formatText(elapsedSeconds);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Start the spinner
|
|
105
|
-
*
|
|
106
|
-
* Begins the animation and elapsed time tracking.
|
|
107
|
-
*/
|
|
108
|
-
start() {
|
|
109
|
-
if (this.disposed)
|
|
110
|
-
return this;
|
|
111
|
-
this.startTime = Date.now();
|
|
112
|
-
this.spinner.start(this.formatText(0));
|
|
113
|
-
// Start elapsed time update interval
|
|
114
|
-
this.intervalId = setInterval(() => {
|
|
115
|
-
this.updateElapsedTime();
|
|
116
|
-
}, ELAPSED_UPDATE_INTERVAL_MS);
|
|
117
|
-
// Register with ShutdownManager for graceful cleanup
|
|
118
|
-
if (this.shutdownManager) {
|
|
119
|
-
this.shutdownManager.registerCleanup(this.cleanupName, async () => {
|
|
120
|
-
this.stop();
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
return this;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Mark the phase as succeeded
|
|
127
|
-
*
|
|
128
|
-
* Stops the spinner and shows a checkmark with total duration.
|
|
129
|
-
*/
|
|
130
|
-
succeed(customText) {
|
|
131
|
-
if (this.disposed)
|
|
132
|
-
return this;
|
|
133
|
-
this.clearInterval();
|
|
134
|
-
this.unregisterCleanup();
|
|
135
|
-
const elapsedSeconds = (Date.now() - this.startTime) / 1000;
|
|
136
|
-
const duration = formatElapsedTime(elapsedSeconds);
|
|
137
|
-
const progress = `(${this.phaseIndex}/${this.totalPhases})`;
|
|
138
|
-
const text = customText ?? `${this.prefix}${this.phase} ${progress} (${duration})`;
|
|
139
|
-
this.spinner.succeed(text);
|
|
140
|
-
this.disposed = true;
|
|
141
|
-
return this;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Mark the phase as failed
|
|
145
|
-
*
|
|
146
|
-
* Stops the spinner and shows an error indicator with message.
|
|
147
|
-
*/
|
|
148
|
-
fail(error) {
|
|
149
|
-
if (this.disposed)
|
|
150
|
-
return this;
|
|
151
|
-
this.clearInterval();
|
|
152
|
-
this.unregisterCleanup();
|
|
153
|
-
const elapsedSeconds = (Date.now() - this.startTime) / 1000;
|
|
154
|
-
const duration = formatElapsedTime(elapsedSeconds);
|
|
155
|
-
const progress = `(${this.phaseIndex}/${this.totalPhases})`;
|
|
156
|
-
const errorSuffix = error ? `: ${error}` : "";
|
|
157
|
-
const text = `${this.prefix}${this.phase} ${progress} (${duration})${errorSuffix}`;
|
|
158
|
-
this.spinner.fail(text);
|
|
159
|
-
this.disposed = true;
|
|
160
|
-
return this;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Stop the spinner without success/fail indication
|
|
164
|
-
*
|
|
165
|
-
* Use this for cleanup or when the phase is interrupted.
|
|
166
|
-
*/
|
|
167
|
-
stop() {
|
|
168
|
-
if (this.disposed)
|
|
169
|
-
return this;
|
|
170
|
-
this.clearInterval();
|
|
171
|
-
this.unregisterCleanup();
|
|
172
|
-
this.spinner.stop();
|
|
173
|
-
this.disposed = true;
|
|
174
|
-
return this;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Pause the spinner (for verbose streaming output)
|
|
178
|
-
*
|
|
179
|
-
* Temporarily stops the animation without disposing.
|
|
180
|
-
* Call resume() to continue.
|
|
181
|
-
*/
|
|
182
|
-
pause() {
|
|
183
|
-
if (this.disposed || this.paused)
|
|
184
|
-
return this;
|
|
185
|
-
this.paused = true;
|
|
186
|
-
this.spinner.stop();
|
|
187
|
-
return this;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Resume the spinner after pause
|
|
191
|
-
*
|
|
192
|
-
* Restarts the animation with updated elapsed time.
|
|
193
|
-
*/
|
|
194
|
-
resume() {
|
|
195
|
-
if (this.disposed || !this.paused)
|
|
196
|
-
return this;
|
|
197
|
-
this.paused = false;
|
|
198
|
-
const elapsedSeconds = (Date.now() - this.startTime) / 1000;
|
|
199
|
-
this.spinner.start(this.formatText(elapsedSeconds));
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Check if the spinner is currently active
|
|
204
|
-
*/
|
|
205
|
-
get isSpinning() {
|
|
206
|
-
return this.spinner.isSpinning && !this.disposed && !this.paused;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Get the total elapsed time in seconds
|
|
210
|
-
*/
|
|
211
|
-
get elapsedSeconds() {
|
|
212
|
-
if (this.startTime === 0)
|
|
213
|
-
return 0;
|
|
214
|
-
return (Date.now() - this.startTime) / 1000;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Dispose of the spinner and clean up resources
|
|
218
|
-
*
|
|
219
|
-
* Called automatically by succeed(), fail(), or stop().
|
|
220
|
-
* Safe to call multiple times.
|
|
221
|
-
*/
|
|
222
|
-
dispose() {
|
|
223
|
-
if (this.disposed)
|
|
224
|
-
return;
|
|
225
|
-
this.clearInterval();
|
|
226
|
-
this.unregisterCleanup();
|
|
227
|
-
this.spinner.stop();
|
|
228
|
-
this.disposed = true;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Clear the elapsed time update interval
|
|
232
|
-
*/
|
|
233
|
-
clearInterval() {
|
|
234
|
-
if (this.intervalId !== null) {
|
|
235
|
-
clearInterval(this.intervalId);
|
|
236
|
-
this.intervalId = null;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Unregister from ShutdownManager
|
|
241
|
-
*/
|
|
242
|
-
unregisterCleanup() {
|
|
243
|
-
if (this.shutdownManager) {
|
|
244
|
-
this.shutdownManager.unregisterCleanup(this.cleanupName);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Create a PhaseSpinner with the given options
|
|
250
|
-
*
|
|
251
|
-
* Convenience function matching the pattern of cli-ui.spinner().
|
|
252
|
-
*/
|
|
253
|
-
export function phaseSpinner(options) {
|
|
254
|
-
return new PhaseSpinner(options);
|
|
255
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PR Operations Module
|
|
3
|
-
*
|
|
4
|
-
* Handles pre-PR and PR creation operations:
|
|
5
|
-
* - Checkpoint commits for chain recovery
|
|
6
|
-
* - Lockfile change detection and dependency reinstall
|
|
7
|
-
* - Pre-PR rebase onto origin/main
|
|
8
|
-
* - PR creation with existing-PR detection
|
|
9
|
-
*
|
|
10
|
-
* @module pr-operations
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Result of a pre-PR rebase operation
|
|
14
|
-
*/
|
|
15
|
-
export interface RebaseResult {
|
|
16
|
-
/** Whether the rebase was performed */
|
|
17
|
-
performed: boolean;
|
|
18
|
-
/** Whether the rebase succeeded */
|
|
19
|
-
success: boolean;
|
|
20
|
-
/** Whether dependencies were reinstalled */
|
|
21
|
-
reinstalled: boolean;
|
|
22
|
-
/** Error message if rebase failed */
|
|
23
|
-
error?: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Result of PR creation
|
|
27
|
-
*/
|
|
28
|
-
export interface PRCreationResult {
|
|
29
|
-
/** Whether PR creation was attempted */
|
|
30
|
-
attempted: boolean;
|
|
31
|
-
/** Whether PR was created successfully (or already existed) */
|
|
32
|
-
success: boolean;
|
|
33
|
-
/** PR number */
|
|
34
|
-
prNumber?: number;
|
|
35
|
-
/** PR URL */
|
|
36
|
-
prUrl?: string;
|
|
37
|
-
/** Error message if failed */
|
|
38
|
-
error?: string;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Create a checkpoint commit in the worktree after QA passes
|
|
42
|
-
* This allows recovery in case later issues in the chain fail
|
|
43
|
-
* @internal Exported for testing
|
|
44
|
-
*/
|
|
45
|
-
export declare function createCheckpointCommit(worktreePath: string, issueNumber: number, verbose: boolean): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Check if any lockfile changed during a rebase and re-run install if needed.
|
|
48
|
-
* This prevents dependency drift when the lockfile was updated on main.
|
|
49
|
-
* @param worktreePath Path to the worktree
|
|
50
|
-
* @param packageManager Package manager to use for install
|
|
51
|
-
* @param verbose Whether to show verbose output
|
|
52
|
-
* @param preRebaseRef Git ref pointing to pre-rebase HEAD (defaults to ORIG_HEAD,
|
|
53
|
-
* which git sets automatically after rebase). Using ORIG_HEAD captures all
|
|
54
|
-
* lockfile changes across multi-commit rebases, unlike HEAD~1 which only
|
|
55
|
-
* checks the last commit.
|
|
56
|
-
* @returns true if reinstall was performed, false otherwise
|
|
57
|
-
* @internal Exported for testing
|
|
58
|
-
*/
|
|
59
|
-
export declare function reinstallIfLockfileChanged(worktreePath: string, packageManager: string | undefined, verbose: boolean, preRebaseRef?: string): boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Rebase the worktree branch onto origin/main before PR creation.
|
|
62
|
-
* This ensures the branch is up-to-date and prevents lockfile drift.
|
|
63
|
-
*
|
|
64
|
-
* @param worktreePath Path to the worktree
|
|
65
|
-
* @param issueNumber Issue number (for logging)
|
|
66
|
-
* @param packageManager Package manager to use if reinstall needed
|
|
67
|
-
* @param verbose Whether to show verbose output
|
|
68
|
-
* @returns RebaseResult indicating success/failure and whether reinstall was performed
|
|
69
|
-
* @internal Exported for testing
|
|
70
|
-
*/
|
|
71
|
-
export declare function rebaseBeforePR(worktreePath: string, issueNumber: number, packageManager: string | undefined, verbose: boolean): RebaseResult;
|
|
72
|
-
/**
|
|
73
|
-
* Push branch and create a PR after successful QA.
|
|
74
|
-
*
|
|
75
|
-
* Handles both fresh PR creation and detection of existing PRs.
|
|
76
|
-
* Failures are warnings — they don't fail the run.
|
|
77
|
-
*
|
|
78
|
-
* @param worktreePath Path to the worktree
|
|
79
|
-
* @param issueNumber Issue number
|
|
80
|
-
* @param issueTitle Issue title (for PR title)
|
|
81
|
-
* @param branch Branch name
|
|
82
|
-
* @param verbose Whether to show verbose output
|
|
83
|
-
* @returns PRCreationResult with PR info or error
|
|
84
|
-
* @internal Exported for testing
|
|
85
|
-
*/
|
|
86
|
-
export declare function createPR(worktreePath: string, issueNumber: number, issueTitle: string, branch: string, verbose: boolean, labels?: string[]): PRCreationResult;
|