Add Pi review-runner adapter; drop `entire review attach` · Entire

Add Pi review-runner adapter; drop entire review attach

1d8ceda→main·

dipree·1mo ago·11 files·+443 added/-164 removed

Pi can now be driven by entire review like claude-code/codex/gemini: it runs headless via pi --mode json <prompt>, inherits the ENTIRE_REVIEW_* env vars, and self-tags its session through the existing hook adoption path. No marker file or manual attach is needed.

Sessions

86a03348156eView transcript

?\List me all the potential command combinations for review.Pi·Opus 4.8·3 steps

Changes

11

package pi

import (
    "bufio"
    "context"
    "encoding/json"
    "fmt"
    "io"
    "os"
    "os/exec"

"github.com/entireio/cli/cmd/entire/cli/review"
    reviewtypes "github.com/entireio/cli/cmd/entire/cli/review/types"
)

// piReviewMaxScannerBuf is the bufio.Scanner cap for the Pi review parser.
// 64MB matches the claude-code and codex parsers so all three tolerate the
// same worst-case line length (a tool result packed into one JSON envelope).
const piReviewMaxScannerBuf = 64 * 1024 * 1024

// NewReviewer returns the AgentReviewer for the Pi coding agent.
//
// Argv shape: pi --mode json <prompt> [--model <pattern>]. The prompt is a
// positional argument; stdin is unused. Stdout is newline-delimited JSON
// event envelopes (one event per line, see Pi's docs/json.md), which the
// parser decodes into the review Event stream.
//
// Pi spawned this way is a child process of `entire review`, so it inherits
// the ENTIRE_REVIEW_* env vars set by AppendReviewEnv. Pi's lifecycle hook
// then self-tags the session as a review via the shared adoptReviewEnv path —
// no marker file and no `entire attach` are needed.
func NewReviewer() *reviewtypes.ReviewerTemplate {
    return &reviewtypes.ReviewerTemplate{
        AgentName: "pi",
        BuildCmd:  buildReviewCmd,
        Parser:    parsePiOutput,
    }
}

// buildReviewCmd builds the exec.Cmd for a Pi review run.
// Exposed at package level for test inspection of argv and env.
func buildReviewCmd(ctx context.Context, cfg reviewtypes.RunConfig) *exec.Cmd {
    prompt := review.ComposeReviewPrompt(cfg)
    args := []string{"--mode", "json", prompt}
    if cfg.Model != "" {
        args = append(args, "--model", cfg.Model)
    }
    cmd := exec.CommandContext(ctx, "pi", args...)
    cmd.Env = review.AppendReviewEnv(os.Environ(), "pi", cfg, prompt)
    return cmd
}

// piStreamEnvelope is one line of `pi --mode json` stdout. Only the fields the
// review parser consumes are declared; unknown fields and event types are
// ignored so new Pi event types don't break parsing.
type piStreamEnvelope struct {
    Type     string           `json:"type"`
    ToolName string           `json:"toolName"`
    Args     json.RawMessage  `json:"args"`
    Message  *piStreamMessage `json:"message"`
}

// additional code...