mirror of
https://github.com/kunchenguid/no-mistakes.git
synced 2026-09-19 07:53:54 +08:00
fix(pipeline): generate MP4 demos and gate review fixes (#91)
* fix(mp4): generate demo.mp4 and require approval for review findings * no-mistakes(document): update README demo output docs
This commit is contained in:
@@ -62,11 +62,17 @@ demo: build
|
||||
[0:v]split[orig][zoom_src];\
|
||||
[zoom_src]crop=963:570:0:0,scale=1100:650:flags=lanczos[zoomed];\
|
||||
[orig]scale=1100:650:flags=lanczos[base];\
|
||||
[base][zoomed]overlay=0:0:enable='lt(t,4.3)',setpts=1.9*PTS,\
|
||||
[base][zoomed]overlay=0:0:enable='lt(t,4.04)',setpts=1.9*PTS,\
|
||||
split[s0][s1];\
|
||||
[s0]palettegen=max_colors=128[p];\
|
||||
[s1][p]paletteuse=dither=sierra2_4a\
|
||||
" -r 10 -y demo.gif
|
||||
ffmpeg -i demo_raw.gif -filter_complex "\
|
||||
[0:v]split[orig][zoom_src];\
|
||||
[zoom_src]crop=963:570:0:0,scale=1100:650:flags=lanczos[zoomed];\
|
||||
[orig]scale=1100:650:flags=lanczos[base];\
|
||||
[base][zoomed]overlay=0:0:enable='lt(t,4.04)',setpts=1.9*PTS\
|
||||
" -c:v libx264 -pix_fmt yuv420p -movflags +faststart -r 30 -y demo.mp4
|
||||
rm -f demo_raw.gif
|
||||
|
||||
clean:
|
||||
|
||||
@@ -268,7 +268,7 @@ auto_fix:
|
||||
```sh
|
||||
make build # Build bin/no-mistakes with version info
|
||||
make dist # Cross-compile release archives into dist/
|
||||
make demo # Regenerate demo.gif from demo.tape
|
||||
make demo # Regenerate demo.gif and demo.mp4 from demo.tape
|
||||
make install # Install the built binary into GOPATH/bin
|
||||
make test # Run go test -race ./...
|
||||
make lint # Run go vet ./...
|
||||
@@ -280,4 +280,4 @@ make clean # Remove bin/
|
||||
|
||||
Docs development uses the Astro project under `docs/`. `make docs` installs docs dependencies with `npm ci` and builds the site.
|
||||
|
||||
To regenerate `demo.gif`, run `make demo`. This target requires both `vhs` and `ffmpeg` to be installed locally.
|
||||
To regenerate `demo.gif` and `demo.mp4`, run `make demo`. This target requires both `vhs` and `ffmpeg` to be installed locally.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 595 KiB After Width: | Height: | Size: 676 KiB |
@@ -37,7 +37,16 @@ Sleep 2s
|
||||
Type "no-mistakes"
|
||||
Sleep 3s
|
||||
Enter
|
||||
Sleep 30s
|
||||
|
||||
# Wait for the review step to stream its log and surface the approval screen.
|
||||
Sleep 9s
|
||||
|
||||
# Linger on the approval screen so the human-in-the-loop moment is clear.
|
||||
Sleep 2.5s
|
||||
|
||||
# Press `f` to fix the reported findings, then watch the rest of the pipeline.
|
||||
Type "f"
|
||||
Sleep 29s
|
||||
|
||||
# Let the completed state linger
|
||||
Sleep 2s
|
||||
|
||||
@@ -43,16 +43,17 @@ func DemoSteps() []pipeline.Step {
|
||||
log: "Fetching origin...\nChecking default branch...\nRebasing onto origin/main...\nAlready up to date.",
|
||||
},
|
||||
&demoStep{
|
||||
name: types.StepReview,
|
||||
delay: 5 * time.Second,
|
||||
fixDelay: 4 * time.Second,
|
||||
displayDur: 45 * time.Second,
|
||||
log: "Reviewing diff against main...\nAnalyzing changed files...\nChecking for bugs, security issues, and design problems...",
|
||||
fixLog: "Fixing review findings...\nApplied fix: added nil check in handler\nApplied fix: removed unused import",
|
||||
name: types.StepReview,
|
||||
delay: 5 * time.Second,
|
||||
fixDelay: 4 * time.Second,
|
||||
displayDur: 45 * time.Second,
|
||||
log: "Reviewing diff against main...\nAnalyzing changed files...\nChecking for bugs, security issues, and design problems...",
|
||||
fixLog: "Fixing review findings...\nApplied fix: added nil check in handler\nApplied fix: removed unused import",
|
||||
needsApproval: true,
|
||||
findings: demoFindings{
|
||||
Items: []types.Finding{
|
||||
{ID: "review-1", Severity: "error", File: "internal/handler.go", Line: 42, Description: "Nil pointer dereference: req.Body used without nil check", Action: types.ActionAutoFix},
|
||||
{ID: "review-2", Severity: "warning", File: "internal/handler.go", Line: 5, Description: "Unused import \"fmt\"", Action: types.ActionAutoFix},
|
||||
{ID: "review-1", Severity: "error", File: "internal/handler.go", Line: 42, Description: "Nil pointer dereference: req.Body used without nil check", Action: types.ActionAskUser},
|
||||
{ID: "review-2", Severity: "warning", File: "internal/handler.go", Line: 5, Description: "Unused import \"fmt\"", Action: types.ActionAskUser},
|
||||
},
|
||||
Summary: "2 findings: 1 error, 1 warning",
|
||||
RiskLevel: "medium",
|
||||
@@ -113,15 +114,16 @@ type demoFindings struct {
|
||||
}
|
||||
|
||||
type demoStep struct {
|
||||
name types.StepName
|
||||
delay time.Duration
|
||||
fixDelay time.Duration
|
||||
displayDur time.Duration // duration shown in TUI (overrides wall clock)
|
||||
log string
|
||||
fixLog string
|
||||
findings demoFindings
|
||||
prURL string
|
||||
fixed bool
|
||||
name types.StepName
|
||||
delay time.Duration
|
||||
fixDelay time.Duration
|
||||
displayDur time.Duration // duration shown in TUI (overrides wall clock)
|
||||
log string
|
||||
fixLog string
|
||||
findings demoFindings
|
||||
needsApproval bool
|
||||
prURL string
|
||||
fixed bool
|
||||
}
|
||||
|
||||
func (s *demoStep) Name() types.StepName { return s.name }
|
||||
@@ -152,7 +154,11 @@ func (s *demoStep) Execute(sctx *pipeline.StepContext) (*pipeline.StepOutcome, e
|
||||
return nil, err
|
||||
}
|
||||
outcome.Findings = string(raw)
|
||||
outcome.AutoFixable = true
|
||||
if s.needsApproval {
|
||||
outcome.NeedsApproval = true
|
||||
} else {
|
||||
outcome.AutoFixable = true
|
||||
}
|
||||
}
|
||||
|
||||
return outcome, nil
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestDemoStepExecuteReturnsContextCancellation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDemoStepReviewAutoFix(t *testing.T) {
|
||||
func TestDemoStepReviewRequiresApproval(t *testing.T) {
|
||||
withoutDemoSleep(t)
|
||||
|
||||
steps := DemoSteps()
|
||||
@@ -159,7 +159,7 @@ func TestDemoStepReviewAutoFix(t *testing.T) {
|
||||
LogFile: func(string) {},
|
||||
}
|
||||
|
||||
// First execution should return findings.
|
||||
// First execution should return findings that require human approval.
|
||||
outcome, err := review.Execute(sctx)
|
||||
if err != nil {
|
||||
t.Fatalf("first Execute() error: %v", err)
|
||||
@@ -167,8 +167,20 @@ func TestDemoStepReviewAutoFix(t *testing.T) {
|
||||
if outcome.Findings == "" {
|
||||
t.Fatal("expected findings on first execution")
|
||||
}
|
||||
if !outcome.AutoFixable {
|
||||
t.Fatal("expected AutoFixable=true")
|
||||
if !outcome.NeedsApproval {
|
||||
t.Fatal("expected NeedsApproval=true so the demo pauses on the approval screen")
|
||||
}
|
||||
if outcome.AutoFixable {
|
||||
t.Fatal("expected AutoFixable=false so auto-fix does not bypass the approval screen")
|
||||
}
|
||||
parsed, err := types.ParseFindingsJSON(outcome.Findings)
|
||||
if err != nil {
|
||||
t.Fatalf("parse findings: %v", err)
|
||||
}
|
||||
for _, f := range parsed.Items {
|
||||
if f.Action != types.ActionAskUser {
|
||||
t.Errorf("finding %q: Action=%q, want %q", f.ID, f.Action, types.ActionAskUser)
|
||||
}
|
||||
}
|
||||
|
||||
// Fix execution should return clean.
|
||||
|
||||
Reference in New Issue
Block a user