Documentation
¶
Index ¶
- Constants
- func AcquireSlot(ctx context.Context, a Agent) error
- func DefaultDroidModel() string
- func Register(a Agent)
- func RegisterGate(name string, defaultMax int)
- func ReleaseSlot(a Agent)
- type Agent
- type Antigravity
- func (a *Antigravity) Binary() string
- func (a *Antigravity) Bootstrap() error
- func (a *Antigravity) CleanupRepo(repoDir string) error
- func (a *Antigravity) EntireAgent() string
- func (a *Antigravity) ExtraArtifacts(repoDir string) map[string]string
- func (a *Antigravity) IsTransientError(out Output, err error) bool
- func (a *Antigravity) Name() string
- func (a *Antigravity) PrepareRepo(repoDir string) error
- func (a *Antigravity) PromptPattern() string
- func (a *Antigravity) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (a *Antigravity) StartSession(_ context.Context, dir string) (Session, error)
- func (a *Antigravity) TimeoutMultiplier() float64
- type ArtifactCollector
- type Claude
- func (c *Claude) Binary() string
- func (c *Claude) Bootstrap() error
- func (c *Claude) EntireAgent() string
- func (c *Claude) IsTransientError(out Output, _ error) bool
- func (c *Claude) Name() string
- func (c *Claude) PromptPattern() string
- func (c *Claude) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (c *Claude) StartSession(ctx context.Context, dir string) (Session, error)
- func (c *Claude) TimeoutMultiplier() float64
- type Codex
- func (c *Codex) Binary() string
- func (c *Codex) Bootstrap() error
- func (c *Codex) EntireAgent() string
- func (c *Codex) IsTransientError(out Output, err error) bool
- func (c *Codex) Name() string
- func (c *Codex) PromptPattern() string
- func (c *Codex) ResumeSession(ctx context.Context, dir, home, sessionID string) (Session, error)
- func (c *Codex) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (c *Codex) StartSession(ctx context.Context, dir string) (Session, error)
- func (c *Codex) TimeoutMultiplier() float64
- type CodexSession
- type CopilotCLI
- func (c *CopilotCLI) Binary() string
- func (c *CopilotCLI) Bootstrap() error
- func (c *CopilotCLI) EntireAgent() string
- func (c *CopilotCLI) IsTransientError(out Output, err error) bool
- func (c *CopilotCLI) Name() string
- func (c *CopilotCLI) PromptPattern() string
- func (c *CopilotCLI) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (c *CopilotCLI) StartSession(ctx context.Context, dir string) (Session, error)
- func (c *CopilotCLI) TimeoutMultiplier() float64
- type CopilotSession
- type CursorCLI
- func (a *CursorCLI) Binary() string
- func (a *CursorCLI) Bootstrap() error
- func (a *CursorCLI) EntireAgent() string
- func (a *CursorCLI) IsTransientError(out Output, err error) bool
- func (a *CursorCLI) Name() string
- func (a *CursorCLI) PromptPattern() string
- func (a *CursorCLI) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (a *CursorCLI) StartSession(ctx context.Context, dir string) (Session, error)
- func (a *CursorCLI) TimeoutMultiplier() float64
- type Droid
- func (d *Droid) Binary() string
- func (d *Droid) Bootstrap() error
- func (d *Droid) EntireAgent() string
- func (d *Droid) IsTransientError(out Output, err error) bool
- func (d *Droid) Name() string
- func (d *Droid) PromptPattern() string
- func (d *Droid) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (d *Droid) StartSession(ctx context.Context, dir string) (Session, error)
- func (d *Droid) TimeoutMultiplier() float64
- type ExternalAgent
- type Option
- type Output
- type Pi
- func (p *Pi) Binary() string
- func (p *Pi) Bootstrap() error
- func (p *Pi) EntireAgent() string
- func (p *Pi) IsTransientError(out Output, _ error) bool
- func (p *Pi) Name() string
- func (p *Pi) PromptPattern() string
- func (p *Pi) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (p *Pi) StartSession(_ context.Context, dir string) (Session, error)
- func (p *Pi) TimeoutMultiplier() float64
- type PiSession
- type RepoCleaner
- type RepoPreparer
- type RepoSeeder
- type RogerRoger
- func (r *RogerRoger) Binary() string
- func (r *RogerRoger) Bootstrap() error
- func (r *RogerRoger) EntireAgent() string
- func (r *RogerRoger) IsExternalAgent() bool
- func (r *RogerRoger) IsTransientError(_ Output, _ error) bool
- func (r *RogerRoger) Name() string
- func (r *RogerRoger) PromptPattern() string
- func (r *RogerRoger) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (r *RogerRoger) StartSession(_ context.Context, dir string) (Session, error)
- func (r *RogerRoger) TimeoutMultiplier() float64
- type Session
- type TmuxSession
- func (s *TmuxSession) Capture() string
- func (s *TmuxSession) Close() error
- func (s *TmuxSession) IsPaneDead() bool
- func (s *TmuxSession) OnClose(fn func())
- func (s *TmuxSession) Quit(timeout time.Duration) error
- func (s *TmuxSession) Send(input string) error
- func (s *TmuxSession) SendKeys(keys ...string) error
- func (s *TmuxSession) Terminate() error
- func (s *TmuxSession) WaitFor(pattern string, timeout time.Duration) (string, error)
- type Vogon
- func (v *Vogon) Binary() string
- func (v *Vogon) Bootstrap() error
- func (v *Vogon) EntireAgent() string
- func (v *Vogon) IsTransientError(_ Output, _ error) bool
- func (v *Vogon) Name() string
- func (v *Vogon) PromptPattern() string
- func (v *Vogon) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
- func (v *Vogon) StartSession(_ context.Context, dir string) (Session, error)
- func (v *Vogon) TimeoutMultiplier() float64
- func (v *Vogon) WriteSessionTranscript(ctx context.Context, dir string, extraEnv []string, ...) (Output, error)
Constants ¶
const PromptTimeoutEnv = "E2E_TIMEOUT"
PromptTimeoutEnv is the environment variable that overrides every agent's per-prompt timeout. It is documented in e2e/README.md and docs/development/testing.md.
Variables ¶
This section is empty.
Functions ¶
func AcquireSlot ¶
AcquireSlot blocks until a test slot is available for the agent or the context is cancelled. Returns a non-nil error if the context expires before a slot opens.
func DefaultDroidModel ¶ added in v0.5.0
func DefaultDroidModel() string
DefaultDroidModel returns the default model string for Droid BYOK configuration. Format is "custom:<baseModelID>" which the Droid API expects for custom model selection.
func RegisterGate ¶
RegisterGate sets a concurrency limit for an agent's tests. Tests call AcquireSlot/ReleaseSlot to respect this limit. The limit can be overridden via E2E_CONCURRENT_TEST_LIMIT.
Types ¶
type Agent ¶
type Agent interface {
Name() string
// Binary returns the CLI binary name (e.g. "claude", "codex").
Binary() string
EntireAgent() string
PromptPattern() string
// TimeoutMultiplier returns a factor applied to per-test timeouts.
// Slower agents (e.g. Factory AI Droid) return values > 1.
TimeoutMultiplier() float64
RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
StartSession(ctx context.Context, dir string) (Session, error)
// Bootstrap performs one-time CI setup (auth config, warmup, etc.).
// Called before any tests run. Implementations should be idempotent.
Bootstrap() error
// IsTransientError returns true if the error from RunPrompt looks like
// a transient API failure (e.g. 500, rate limit, network error) that
// is worth retrying.
IsTransientError(out Output, err error) bool
}
type Antigravity ¶ added in v0.11.3
type Antigravity struct{}
Antigravity implements the Agent interface for the agy CLI (Antigravity 2.0, successor to Gemini CLI).
func (*Antigravity) Binary ¶ added in v0.11.3
func (a *Antigravity) Binary() string
func (*Antigravity) Bootstrap ¶ added in v0.11.3
func (a *Antigravity) Bootstrap() error
func (*Antigravity) CleanupRepo ¶ added in v0.11.3
func (a *Antigravity) CleanupRepo(repoDir string) error
CleanupRepo removes the isolated HOME that antigravityPrepareHome created beside the repo. It has no *testing.T of its own, so the repo's cleanup calls this; RemoveAll on the OAuth path, where no such directory exists, is a no-op.
func (*Antigravity) EntireAgent ¶ added in v0.11.3
func (a *Antigravity) EntireAgent() string
func (*Antigravity) ExtraArtifacts ¶ added in v0.11.3
func (a *Antigravity) ExtraArtifacts(repoDir string) map[string]string
ExtraArtifacts exposes agy's own state from the isolated HOME (its CLI log directory and the settings.json the harness wrote) so CI failures inside agy are diagnosable from artifacts. Nothing is captured in OAuth mode: the developer's real HOME is not a test artifact.
func (*Antigravity) IsTransientError ¶ added in v0.11.3
func (a *Antigravity) IsTransientError(out Output, err error) bool
func (*Antigravity) Name ¶ added in v0.11.3
func (a *Antigravity) Name() string
func (*Antigravity) PrepareRepo ¶ added in v0.11.3
func (a *Antigravity) PrepareRepo(repoDir string) error
PrepareRepo runs after `entire enable`. When the hook probe is enabled it adds a second, independent entry to the repo's .agents/hooks.json that appends the hook's cwd and stdin payload to antigravityHookProbeLog for PreInvocation, PreToolUse and Stop. Entire's own entry is untouched. This answers "did agy run hooks at all, from where, with what payload" when a run leaves no session state — the failure mode that is otherwise invisible.
func (*Antigravity) PromptPattern ¶ added in v0.11.3
func (a *Antigravity) PromptPattern() string
PromptPattern is a placeholder until the real interactive prompt pattern is observed against a working `agy` session. Tracked in the Deferred table.
func (*Antigravity) StartSession ¶ added in v0.11.3
func (*Antigravity) TimeoutMultiplier ¶ added in v0.11.3
func (a *Antigravity) TimeoutMultiplier() float64
type ArtifactCollector ¶ added in v0.11.3
ArtifactCollector is implemented by agents that keep state outside the test repo (an isolated HOME, the agent's own logs) worth capturing when artifacts are collected. Keys are artifact names (written under the test's artifact dir), values are source files or directories; missing sources are skipped. Optional.
type Claude ¶
type Claude struct{}
func (*Claude) EntireAgent ¶
func (*Claude) PromptPattern ¶
func (*Claude) StartSession ¶
func (*Claude) TimeoutMultiplier ¶
type Codex ¶ added in v0.5.2
type Codex struct{}
Codex implements the E2E Agent interface for OpenAI's Codex CLI.
func (*Codex) EntireAgent ¶ added in v0.5.2
func (*Codex) IsTransientError ¶ added in v0.5.2
func (*Codex) PromptPattern ¶ added in v0.5.2
func (*Codex) ResumeSession ¶ added in v0.5.4
func (*Codex) StartSession ¶ added in v0.5.2
func (*Codex) TimeoutMultiplier ¶ added in v0.5.2
type CodexSession ¶ added in v0.5.4
type CodexSession struct {
*TmuxSession
// contains filtered or unexported fields
}
func (*CodexSession) Home ¶ added in v0.5.4
func (s *CodexSession) Home() string
type CopilotCLI ¶ added in v0.5.0
type CopilotCLI struct{}
func (*CopilotCLI) Binary ¶ added in v0.5.0
func (c *CopilotCLI) Binary() string
func (*CopilotCLI) Bootstrap ¶ added in v0.5.0
func (c *CopilotCLI) Bootstrap() error
func (*CopilotCLI) EntireAgent ¶ added in v0.5.0
func (c *CopilotCLI) EntireAgent() string
func (*CopilotCLI) IsTransientError ¶ added in v0.5.0
func (c *CopilotCLI) IsTransientError(out Output, err error) bool
func (*CopilotCLI) Name ¶ added in v0.5.0
func (c *CopilotCLI) Name() string
func (*CopilotCLI) PromptPattern ¶ added in v0.5.0
func (c *CopilotCLI) PromptPattern() string
func (*CopilotCLI) StartSession ¶ added in v0.5.0
func (*CopilotCLI) TimeoutMultiplier ¶ added in v0.5.0
func (c *CopilotCLI) TimeoutMultiplier() float64
type CopilotSession ¶ added in v0.5.2
type CopilotSession struct {
*TmuxSession
}
CopilotSession wraps TmuxSession to handle Copilot CLI's dual input modes. Copilot CLI can be in "Chat" mode (Enter submits) or "Edit" mode (Ctrl+S submits). After completing a prompt, copilot may return to either mode non-deterministically. This wrapper detects Edit mode after sending Enter and falls back to Ctrl+S if needed.
func (*CopilotSession) Send ¶ added in v0.5.2
func (cs *CopilotSession) Send(input string) error
type CursorCLI ¶ added in v0.5.0
type CursorCLI struct{}
CursorCLI implements the E2E Agent interface for the Cursor Agent CLI binary. The CLI binary is called "agent" and uses Cursor's hooks system via .cursor/hooks.json. It maps to the same Entire agent as Cursor IDE ("cursor").
All E2E interactions use interactive (tmux) mode so that the full hook lifecycle fires (sessionStart, beforeSubmitPrompt, stop, sessionEnd). Headless (-p) mode skips beforeSubmitPrompt and stop hooks.
func (*CursorCLI) EntireAgent ¶ added in v0.5.0
func (*CursorCLI) IsTransientError ¶ added in v0.5.0
func (*CursorCLI) PromptPattern ¶ added in v0.5.0
PromptPattern returns a regex matching Cursor's ready-state prompt markers. Cursor has used multiple startup/completion markers across releases.
func (*CursorCLI) StartSession ¶ added in v0.5.0
func (*CursorCLI) TimeoutMultiplier ¶ added in v0.5.0
type Droid ¶ added in v0.4.9
type Droid struct{}
Droid implements the Agent interface for Factory AI Droid.
func (*Droid) EntireAgent ¶ added in v0.4.9
func (*Droid) IsTransientError ¶ added in v0.4.9
func (*Droid) PromptPattern ¶ added in v0.4.9
func (*Droid) StartSession ¶ added in v0.4.9
func (*Droid) TimeoutMultiplier ¶ added in v0.4.9
type ExternalAgent ¶ added in v0.5.1
type ExternalAgent interface {
IsExternalAgent() bool
}
ExternalAgent is an optional interface for agents discovered via the external agent protocol (entire-agent-* binaries). SetupRepo uses this to pre-configure external_agents in settings before running `entire enable`.
type Pi ¶ added in v0.6.2
type Pi struct{}
Pi implements the E2E Agent interface for the Pi coding agent.
func (*Pi) EntireAgent ¶ added in v0.6.2
func (*Pi) IsTransientError ¶ added in v0.6.2
func (*Pi) PromptPattern ¶ added in v0.6.2
func (*Pi) StartSession ¶ added in v0.6.2
func (*Pi) TimeoutMultiplier ¶ added in v0.6.2
type PiSession ¶ added in v0.6.2
type PiSession struct {
*TmuxSession
// contains filtered or unexported fields
}
PiSession exposes the per-test isolated Pi home so test fixtures can inspect or clean it up.
type RepoCleaner ¶ added in v0.11.3
RepoCleaner is implemented by agents whose PrepareRepo (or prompt runs) leave state beside the test repo — Antigravity's isolated HOME is a sibling directory of it — so that state goes with the repo when the test cleans up. Called from the repo's t.Cleanup, after artifacts are captured. Optional.
type RepoPreparer ¶ added in v0.11.3
RepoPreparer is implemented by agents that need repo-local setup after `entire enable` (e.g. extra hook entries for diagnostics). Optional.
type RepoSeeder ¶ added in v0.10.6
RepoSeeder is implemented by an agent that needs files planted in a fresh test repo before it first runs there. SetupRepo calls SeedRepo once the repo exists and `entire enable` has written the agent's own config into it.
Seeding is best-effort by contract: an agent that cannot seed should return nil and leave the repo alone, so the tests degrade to whatever the agent does for itself rather than failing on setup.
type RogerRoger ¶ added in v0.5.1
type RogerRoger struct{}
RogerRoger implements the Agent interface using a deterministic external agent binary that creates files and fires hooks without making any API calls. Unlike built-in agents (Vogon, Claude Code, etc.), roger-roger is discovered via the external agent protocol (entire-agent-roger-roger binary in $PATH).
func (*RogerRoger) Binary ¶ added in v0.5.1
func (r *RogerRoger) Binary() string
func (*RogerRoger) Bootstrap ¶ added in v0.5.1
func (r *RogerRoger) Bootstrap() error
func (*RogerRoger) EntireAgent ¶ added in v0.5.1
func (r *RogerRoger) EntireAgent() string
func (*RogerRoger) IsExternalAgent ¶ added in v0.5.1
func (r *RogerRoger) IsExternalAgent() bool
IsExternalAgent returns true — roger-roger is discovered via the external agent protocol.
func (*RogerRoger) IsTransientError ¶ added in v0.5.1
func (r *RogerRoger) IsTransientError(_ Output, _ error) bool
func (*RogerRoger) Name ¶ added in v0.5.1
func (r *RogerRoger) Name() string
func (*RogerRoger) PromptPattern ¶ added in v0.5.1
func (r *RogerRoger) PromptPattern() string
func (*RogerRoger) StartSession ¶ added in v0.5.1
func (*RogerRoger) TimeoutMultiplier ¶ added in v0.5.1
func (r *RogerRoger) TimeoutMultiplier() float64
type TmuxSession ¶
type TmuxSession struct {
// contains filtered or unexported fields
}
TmuxSession implements Session using tmux for PTY-based interactive agents.
func NewTmuxSession ¶
func NewTmuxSession(name string, dir string, unsetEnv []string, command string, args ...string) (*TmuxSession, error)
NewTmuxSession creates a new tmux session running the given command in dir. unsetEnv lists environment variable names to strip from the session.
The command is wrapped with `env` to propagate PATH from the current process. tmux sessions inherit the tmux server's environment (not the client's), so without this, binaries added to PATH by the test runner (e.g., freshly built `entire` and `vogon`) would not be found inside the session.
func (*TmuxSession) Capture ¶
func (s *TmuxSession) Capture() string
func (*TmuxSession) Close ¶
func (s *TmuxSession) Close() error
func (*TmuxSession) IsPaneDead ¶ added in v0.5.0
func (s *TmuxSession) IsPaneDead() bool
IsPaneDead returns true if the process inside the tmux pane has exited. This relies on the remain-on-exit option being set (which NewTmuxSession does).
func (*TmuxSession) OnClose ¶
func (s *TmuxSession) OnClose(fn func())
OnClose registers a function to run when the session is closed.
func (*TmuxSession) Quit ¶ added in v0.10.0
func (s *TmuxSession) Quit(timeout time.Duration) error
Quit asks the foreground program to exit the way a user would — by sending Ctrl+C — and waits for the process to actually exit. It sends Ctrl+C again each poll because some TUIs (Codex among them) treat a single Ctrl+C as "cancel the current turn" and need a second press to quit, and that gesture is version-dependent. If the process has still not exited by timeout it falls back to a hard kill: callers use Quit when they need the process gone (e.g. to release a lock it holds) and must not hang on an agent that changed its quit keybinding. Like Terminate, it does NOT run the OnClose cleanups, so a caller that needs a registered resource torn down owns that itself.
func (*TmuxSession) Send ¶
func (s *TmuxSession) Send(input string) error
func (*TmuxSession) SendKeys ¶
func (s *TmuxSession) SendKeys(keys ...string) error
SendKeys sends raw tmux key names without appending Enter.
func (*TmuxSession) Terminate ¶ added in v0.10.0
func (s *TmuxSession) Terminate() error
Terminate kills the tmux session (and the process it runs) WITHOUT running the registered OnClose cleanups. Use it when the process must die but a resource it registered for teardown — e.g. an isolated HOME that a later step in the same test still reads — has to outlive the process. Callers that bypass Close this way own the surviving resource's cleanup themselves.
type Vogon ¶ added in v0.5.0
type Vogon struct{}
Vogon implements the Agent interface using a deterministic binary that creates files and fires hooks without making any API calls. Named after the Vogons from The Hitchhiker's Guide to the Galaxy.
func (*Vogon) EntireAgent ¶ added in v0.5.0
func (*Vogon) IsTransientError ¶ added in v0.5.0
func (*Vogon) PromptPattern ¶ added in v0.5.0
func (*Vogon) StartSession ¶ added in v0.5.0
func (*Vogon) TimeoutMultiplier ¶ added in v0.5.0
func (*Vogon) WriteSessionTranscript ¶ added in v0.6.0
func (v *Vogon) WriteSessionTranscript(ctx context.Context, dir string, extraEnv []string, sessionID, userPrompt, assistantMessage string) (Output, error)
WriteSessionTranscript creates a deterministic vogon session transcript without firing hooks or mutating the repository. Attach E2E tests use this to prepare a session that `entire attach` can import.