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.
- Add cmd/entire/cli/agent/pi/reviewer.go: NewReviewer() (ReviewerTemplate)
- a parser mapping pi's JSON event stream to review Events, with tests.
- Wire pi into launchableReviewerFor.
- Remove the
entire review attachsubcommand and its plumbing (Deps.AttachCmd, newReviewAttachCmd). Its only unique behavior — consuming a pending-review marker — is folded intoentire attach --review, which already covers manual tagging. Tests migrated to theattach --reviewsurface; stale doc comments updated.
Sessions
86a03348156eView transcript
?\List me all the potential command combinations for review.Pi·Opus 4.8·3 steps
Changes
11
cmd/entire/cli
agent/pi
Areviewer.go+180
Areviewer_test.go+206
Mattach.go+31/-4
Mattach_test.go+7/-7
integration_test
Mreview_test.go+1/-1
review
Dattach_test.go-47
Mcmd.go+2/-11
Mmarker_fallback.go+5/-7
Mreview_bridge.go+4/-6
Mreview_helpers.go+6/-80
Mroot.go+1/-1
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...