From ad5a4b4114ddc10bfdaa70ef97c827f1f9fc99f1 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 17 Aug 2026 16:39:29 +0000 Subject: [PATCH] Stream Phase 1 artifacts from container tmpfs Co-authored-by: codegirl007 --- agentbox/internal/phase1/run.go | 19 +++++++--- agentbox/internal/phase1/run_test.go | 54 ++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 agentbox/internal/phase1/run_test.go diff --git a/agentbox/internal/phase1/run.go b/agentbox/internal/phase1/run.go index 884088b..e491f44 100644 --- a/agentbox/internal/phase1/run.go +++ b/agentbox/internal/phase1/run.go @@ -294,8 +294,19 @@ func (r *runner) screenshot(ctx context.Context, containerPath, hostPath string) if _, err := r.docker(ctx, "exec", r.containerName, "scrot", "-o", containerPath); err != nil { return fmt.Errorf("capture screenshot: %w", err) } - if _, err := r.docker(ctx, "cp", r.containerName+":"+containerPath, hostPath); err != nil { - return fmt.Errorf("copy screenshot: %w", err) + if err := r.extract(ctx, containerPath, hostPath); err != nil { + return fmt.Errorf("extract screenshot: %w", err) + } + return nil +} + +func (r *runner) extract(ctx context.Context, containerPath, hostPath string) error { + data, err := r.docker(ctx, "exec", r.containerName, "cat", containerPath) + if err != nil { + return err + } + if err := os.WriteFile(hostPath, data, 0o644); err != nil { + return fmt.Errorf("write %s: %w", hostPath, err) } return nil } @@ -354,10 +365,10 @@ func (r *runner) cleanup() error { fmt.Println("Stopping environment...") stopCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, stopErr := r.docker(stopCtx, "stop", "--time=3", r.containerName) for _, name := range []string{"stdout.log", "stderr.log"} { - _, _ = r.docker(stopCtx, "cp", r.containerName+":/tmp/"+name, filepath.Join(r.runDir, name)) + _ = r.extract(stopCtx, "/tmp/"+name, filepath.Join(r.runDir, name)) } + _, stopErr := r.docker(stopCtx, "stop", "--time=3", r.containerName) _, removeErr := r.docker(stopCtx, "rm", "-f", r.containerName) if stopErr != nil { return fmt.Errorf("stop environment: %w", stopErr) diff --git a/agentbox/internal/phase1/run_test.go b/agentbox/internal/phase1/run_test.go new file mode 100644 index 0000000..fb4fe6a --- /dev/null +++ b/agentbox/internal/phase1/run_test.go @@ -0,0 +1,54 @@ +package phase1 + +import ( + "image" + "image/color" + "image/png" + "os" + "path/filepath" + "testing" +) + +func TestSquareCentroid(t *testing.T) { + path := filepath.Join(t.TempDir(), "screenshot.png") + img := image.NewRGBA(image.Rect(0, 0, 200, 100)) + green := color.RGBA{R: 0, G: 255, B: 102, A: 255} + for y := 20; y < 60; y++ { + for x := 80; x < 120; x++ { + img.Set(x, y, green) + } + } + writePNG(t, path, img) + + got, err := squareCentroid(path) + if err != nil { + t.Fatalf("squareCentroid() error = %v", err) + } + if got.X != 99.5 || got.Y != 39.5 { + t.Fatalf("squareCentroid() = (%.1f, %.1f), want (99.5, 39.5)", got.X, got.Y) + } +} + +func TestSquareCentroidRejectsMissingSquare(t *testing.T) { + path := filepath.Join(t.TempDir(), "empty.png") + writePNG(t, path, image.NewRGBA(image.Rect(0, 0, 200, 100))) + + if _, err := squareCentroid(path); err == nil { + t.Fatal("squareCentroid() error = nil, want missing-square error") + } +} + +func writePNG(t *testing.T, path string, img image.Image) { + t.Helper() + file, err := os.Create(path) + if err != nil { + t.Fatal(err) + } + if err := png.Encode(file, img); err != nil { + _ = file.Close() + t.Fatal(err) + } + if err := file.Close(); err != nil { + t.Fatal(err) + } +}