codex

package
v0.10.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package codex implements the Agent interface for OpenAI's Codex CLI.

Index

Constants

View Source
const (
	HookNameSessionStart     = "session-start"
	HookNameSessionEnd       = "session-end"
	HookNameUserPromptSubmit = "user-prompt-submit"
	HookNameStop             = "stop"
	HookNamePreToolUse       = "pre-tool-use"
	HookNamePostToolUse      = "post-tool-use"
	HookNameSubagentStart    = "subagent-start"
	HookNameSubagentStop     = "subagent-stop"
)

Codex hook names — these become subcommands under `entire hooks codex`

View Source
const HooksFileName = "hooks.json"

HooksFileName is the hooks config file used by Codex.

View Source
const SessionEndTimeoutSec = 3

SessionEndTimeoutSec is the timeout Entire configures for Codex's SessionEnd hook. Codex clamps SessionEnd handlers to SESSION_END_MAX_TIMEOUT_SEC = 3 (codex-rs/hooks/src/events/session_end.rs) and prints a "clamping SessionEnd hook timeout" warning on every startup when a config asks for more, so requesting exactly the ceiling gets the longest run available without nagging the user. Every other Codex hook keeps the standard 30s that addHook applies.

Variables

This section is empty.

Functions

func HookTrustGaps added in v0.6.2

func HookTrustGaps(ctx context.Context) []string

HookTrustGaps returns the snake_case event labels declared in the hooks.json Codex discovers that don't have a matching approval entry in the user's Codex config.toml. Matching parses the full `<hooks.json>:<event>:<group>:<handler>` key, accepts any valid indexes, and compares canonicalized hook paths.

This is the structural form of the trust check: we don't recompute Codex's hook hash, we only look at key presence. That misses the "command changed but key is still there" case (status = Modified), but Codex's own startup warning catches those — our purpose here is to surface fresh additions like "you trusted three hooks last month but a new PostToolUse arrived" inside our SessionStart welcome.

Returns nil when:

  • .codex/hooks.json doesn't exist (entire isn't installed in this repo)
  • The authoritative hook location can't be resolved
  • The checkout has no local .codex project layer
  • The user's config.toml can't be read
  • Every declared event already has a state entry

func MissingEntireHooks added in v0.6.2

func MissingEntireHooks(repoRoot string) []string

MissingEntireHooks reports the managed Codex events that are not present in a repository-local hooks file. It is kept as a compatibility helper for callers that only need the drift list; diagnostics use HookConfigInspection.

func NewCodexAgent

func NewCodexAgent() agent.Agent

NewCodexAgent creates a new Codex agent instance.

func NewReviewer added in v0.6.1

func NewReviewer() *reviewtypes.ReviewerTemplate

NewReviewer returns the AgentReviewer for codex.

Argv shape: codex exec --skip-git-repo-check --json -. Prompt is piped via stdin (the trailing "-" tells codex to read from stdin). Stdout is newline-delimited JSON envelopes (one event per line); no chrome filter needed — each line is parsed directly into an Event.

func NewSpawner added in v0.7.0

func NewSpawner() spawn.Spawner

NewSpawner returns a Spawner for codex's non-interactive review/investigate mode.

func SanitizePortableTranscript added in v0.5.4

func SanitizePortableTranscript(data []byte) []byte

SanitizePortableTranscript strips encrypted history fragments that cannot be replayed when Entire reconstructs a Codex rollout outside its original session context.

func WorktreeProjectLayerExists added in v0.10.3

func WorktreeProjectLayerExists(ctx context.Context) bool

WorktreeProjectLayerExists reports whether the current checkout has a valid local .codex project directory.

Types

type CodexAgent

type CodexAgent struct {
	CommandRunner agent.TextCommandRunner
}

CodexAgent implements the Agent interface for OpenAI's Codex CLI.

func (*CodexAgent) AreHooksInstalled

func (c *CodexAgent) AreHooksInstalled(ctx context.Context) (bool, error)

AreHooksInstalled reports whether Codex is wired up to Entire in this repo.

It requires only the core events, not everything InstallHooks writes today. The two questions are different: this one decides whether Codex is listed as an installed agent (`entire status`, the review and investigate pickers), and answering it with the full set would drop Codex out of all of them the moment a release adds an event — every existing install predates the addition. Drift against today's set is part of hook-config inspection, which `entire doctor` reports with the fix (`entire enable`).

A missing config file is an answer, not a failure: that file is where the state lives, so its absence means no hooks. Anything that stops us reading the answer — an unreadable file, malformed config — is returned as an error, since "we could not tell" and "there are none" are different things to a caller deciding whether hooks can be left alone.

func (*CodexAgent) CalculateTokenUsage

func (c *CodexAgent) CalculateTokenUsage(transcriptData []byte, fromOffset int) (*agent.TokenUsage, error)

CalculateTokenUsage computes token usage from the transcript starting at the given line offset. Codex reports cumulative total_token_usage, so we compute the delta between the last token_count at/before the offset and the last token_count after the offset.

func (*CodexAgent) CheckHookConfig added in v0.10.3

func (c *CodexAgent) CheckHookConfig(ctx context.Context) agent.HookConfigState

CheckHookConfig reports whether the current checkout's Codex hook configuration is absent, current, or needs installation.

func (*CodexAgent) ChunkTranscript

func (c *CodexAgent) ChunkTranscript(_ context.Context, content []byte, maxSize int) ([][]byte, error)

ChunkTranscript splits a JSONL transcript at line boundaries.

func (*CodexAgent) Description

func (c *CodexAgent) Description() string

Description returns a human-readable description.

func (*CodexAgent) DetectPresence

func (c *CodexAgent) DetectPresence(ctx context.Context) (bool, error)

DetectPresence checks if Codex is configured in the repository.

func (*CodexAgent) DiscoverReviewSkills added in v0.6.1

func (c *CodexAgent) DiscoverReviewSkills(ctx context.Context) ([]agent.DiscoveredSkill, error)

DiscoverReviewSkills walks codex's on-disk skill layout looking for review-adjacent skills. Returns (nil, nil) when HOME is unreadable or the directories are missing — discovery is best-effort.

Codex exposes skills as <root>/<name>/SKILL.md (same frontmatter shape as Claude). Three roots contribute, mirroring codex's own injected skills catalog:

  • ~/.codex/skills/<name>/ → user skills ($name)
  • ~/.codex/plugins/cache/<m>/<p>/<v>/skills/<name>/ → plugin skills ($p:name)
  • ~/.codex/superpowers/skills/<name>/ → superpowers ($superpowers:name)

Skills are emitted in codex's dollar invocation form ($name / $plugin:name) — the literal token a user types to invoke the skill in the codex CLI — so the review prompt names skills exactly the way codex's skill system expects, loading the real SKILL.md rather than relying on a loose description match.

func (*CodexAgent) ExtractModifiedFilesFromOffset

func (c *CodexAgent) ExtractModifiedFilesFromOffset(path string, startOffset int) (files []string, currentPosition int, err error)

ExtractModifiedFilesFromOffset extracts files modified since a given line offset.

func (*CodexAgent) ExtractPrompts

func (c *CodexAgent) ExtractPrompts(sessionRef string, fromOffset int) ([]string, error)

ExtractPrompts returns user prompts from the transcript starting at the given offset.

func (*CodexAgent) FormatResumeCommand

func (c *CodexAgent) FormatResumeCommand(sessionID string) string

FormatResumeCommand returns the command to resume a Codex session.

func (*CodexAgent) GenerateText added in v0.5.6

func (c *CodexAgent) GenerateText(ctx context.Context, prompt string, model string) (string, error)

GenerateText sends a prompt to the Codex CLI and returns the raw text response.

func (*CodexAgent) GetSessionDir

func (c *CodexAgent) GetSessionDir(_ string) (string, error)

GetSessionDir returns the directory where Codex stores session transcripts. Codex stores transcripts under CODEX_HOME/sessions/YYYY/MM/DD/.

func (*CodexAgent) GetSessionID

func (c *CodexAgent) GetSessionID(input *agent.HookInput) string

GetSessionID extracts the session ID from hook input.

func (*CodexAgent) GetTranscriptPosition

func (c *CodexAgent) GetTranscriptPosition(path string) (int, error)

GetTranscriptPosition returns the current line count of a Codex rollout transcript.

func (*CodexAgent) HookNames

func (c *CodexAgent) HookNames() []string

HookNames returns the hook verbs Codex supports.

func (*CodexAgent) InjectionEvent added in v0.7.7

func (c *CodexAgent) InjectionEvent() agent.EventType

InjectionEvent reports that Codex injects model context at TurnStart (its user-prompt-submit hook). Codex hosts Claude-compatible hooks, so it consumes the same hookSpecificOutput.additionalContext shape.

func (*CodexAgent) InstallHooks

func (c *CodexAgent) InstallHooks(ctx context.Context, force bool) (int, error)

InstallHooks installs Codex hooks in .codex/hooks.json.

func (*CodexAgent) IsPreview

func (c *CodexAgent) IsPreview() bool

IsPreview returns true because this is a new integration.

func (*CodexAgent) LaunchCmd added in v0.6.1

func (c *CodexAgent) LaunchCmd(ctx context.Context, initialPrompt string) (*exec.Cmd, error)

LaunchCmd builds an exec.Cmd for `codex "<initialPrompt>"`. Stdio is wired to the caller's TTY so the agent runs foreground and the user interacts normally. The call site is expected to Run() and wait. Hooks inherit the parent environment.

func (*CodexAgent) Name

func (c *CodexAgent) Name() types.AgentName

Name returns the agent registry key.

func (*CodexAgent) OwnsEffectiveHookDiagnostics added in v0.10.3

func (c *CodexAgent) OwnsEffectiveHookDiagnostics()

OwnsEffectiveHookDiagnostics keeps Codex's discovered-file state out of the generic current-worktree freshness report.

func (*CodexAgent) ParseHookEvent

func (c *CodexAgent) ParseHookEvent(_ context.Context, hookName string, stdin io.Reader) (*agent.Event, error)

ParseHookEvent translates a Codex hook into a normalized lifecycle Event. Returns nil if the hook has no lifecycle significance.

func (*CodexAgent) ProtectedDirs

func (c *CodexAgent) ProtectedDirs() []string

ProtectedDirs returns directories that Codex uses for config/state.

func (*CodexAgent) ReadSession

func (c *CodexAgent) ReadSession(input *agent.HookInput) (*agent.AgentSession, error)

ReadSession reads a session from Codex's storage (JSONL rollout file).

func (*CodexAgent) ReadTranscript

func (c *CodexAgent) ReadTranscript(sessionRef string) ([]byte, error)

ReadTranscript reads the raw JSONL transcript bytes for a session.

func (*CodexAgent) ReassembleTranscript

func (c *CodexAgent) ReassembleTranscript(chunks [][]byte) ([]byte, error)

ReassembleTranscript concatenates JSONL chunks with newlines.

func (*CodexAgent) RenderContextInjection added in v0.7.7

func (c *CodexAgent) RenderContextInjection(inj agent.ContextInjection) ([]byte, error)

RenderContextInjection renders the Claude-style additionalContext payload Codex injects into the model context at user-prompt-submit.

func (*CodexAgent) ResolveRestoredSessionFile added in v0.5.4

func (c *CodexAgent) ResolveRestoredSessionFile(sessionDir, agentSessionID string, transcript []byte) (string, error)

ResolveRestoredSessionFile returns the canonical Codex rollout path for a restored session so `codex resume <id>` can rediscover it.

func (*CodexAgent) ResolveSessionFile

func (c *CodexAgent) ResolveSessionFile(sessionDir, agentSessionID string) string

ResolveSessionFile returns the path to a Codex session transcript file. Codex provides the transcript path directly in hook payloads as an absolute path. When only a session ID is available, callers recover it from the sessions/YYYY/MM/DD/rollout-...-<session-id>.jsonl layout.

func (*CodexAgent) SanitizeTranscriptForStorage added in v0.10.0

func (c *CodexAgent) SanitizeTranscriptForStorage(data []byte) []byte

SanitizeTranscriptForStorage implements agent.TranscriptSanitizer. Codex rollouts embed encrypted reasoning payloads and compaction blobs that are bound to the originating session, so Entire strips them from its stored copy while leaving Codex's own rollout file untouched.

func (*CodexAgent) SessionEndBudget added in v0.10.1

func (c *CodexAgent) SessionEndBudget() time.Duration

SessionEndBudget implements agent.SessionEndBudgeter. Codex runs SessionEnd inside its shutdown sequence under a hard cap; see the interface docs.

func (*CodexAgent) Type

func (c *CodexAgent) Type() types.AgentType

Type returns the agent type identifier.

func (*CodexAgent) UninstallHooks

func (c *CodexAgent) UninstallHooks(ctx context.Context) error

UninstallHooks removes Entire hooks from Codex hooks.json.

func (*CodexAgent) WriteHookResponse

func (c *CodexAgent) WriteHookResponse(message string) error

WriteHookResponse outputs a JSON hook response to stdout. Codex reads the systemMessage field and displays it to the user.

func (*CodexAgent) WriteSession

func (c *CodexAgent) WriteSession(_ context.Context, session *agent.AgentSession) error

WriteSession writes a session to Codex's storage (JSONL rollout file).

type DiscoveredHooksPath added in v0.10.3

type DiscoveredHooksPath struct {
	// contains filtered or unexported fields
}

DiscoveredHooksPath identifies the read-only project hooks file Codex is expected to load. It is intentionally distinct from WorktreeHooksPath.

func (DiscoveredHooksPath) Path added in v0.10.3

func (p DiscoveredHooksPath) Path() string

Path returns the discovered hooks file's absolute path.

type HookConfigInspection added in v0.10.3

type HookConfigInspection struct {
	State         HookFileState
	Missing       []string
	Declared      []string
	Current       bool
	CoreInstalled bool
	Err           error
}

HookConfigInspection is the single parsed view used by Codex presence, freshness, missing-hook, and doctor reporting.

func InspectHookConfig added in v0.10.3

func InspectHookConfig(ctx context.Context) HookConfigInspection

InspectHookConfig resolves and parses the hooks file Codex discovers.

type HookDiagnostics added in v0.10.3

type HookDiagnostics struct {
	Discovery       HookDiscovery
	WorktreeHooks   WorktreeHooksPath
	Worktree        HookConfigInspection
	Discovered      HookConfigInspection
	Trust           HookTrustInspection
	WorktreePathErr error
}

HookDiagnostics keeps current-checkout ownership separate from the read-only file Codex discovers.

func InspectHookDiagnostics added in v0.10.3

func InspectHookDiagnostics(ctx context.Context) HookDiagnostics

InspectHookDiagnostics collects the local and effective Codex hook state without creating, rewriting, or removing either file.

func InspectHookDiagnosticsLightweight added in v0.10.3

func InspectHookDiagnosticsLightweight(ctx context.Context) HookDiagnostics

InspectHookDiagnosticsLightweight collects only the checks safe to run from Codex's SessionStart hook. It avoids freshness probes and platform-specific command checks, which can delay the agent startup path.

func (HookDiagnostics) PathsDiffer added in v0.10.3

func (d HookDiagnostics) PathsDiffer() bool

PathsDiffer reports whether current-checkout mutation and Codex discovery refer to different hook files.

type HookDiscovery added in v0.10.3

type HookDiscovery struct {
	State           HookDiscoveryState
	DiscoveredHooks DiscoveredHooksPath
	Diagnostic      error
	// contains filtered or unexported fields
}

HookDiscovery describes the hooks file Codex is expected to discover. It is diagnostic-only and carries no write target, migration path, or lock path.

func ResolveHookDiscovery added in v0.10.3

func ResolveHookDiscovery(ctx context.Context) HookDiscovery

ResolveHookDiscovery performs read-only discovery of the hook file Codex is expected to load for the current checkout.

func (HookDiscovery) ProjectLayerExists added in v0.10.3

func (d HookDiscovery) ProjectLayerExists() bool

ProjectLayerExists reports whether the current checkout has a valid local .codex directory Codex can use to construct its project config layer.

type HookDiscoveryState added in v0.10.3

type HookDiscoveryState uint8

HookDiscoveryState distinguishes a resolved Codex hook source from a layout whose behavior Entire cannot safely infer.

const (
	HookDiscoveryUnresolved HookDiscoveryState = iota
	HookDiscoveryResolved
)

type HookEntry

type HookEntry struct {
	Type    string `json:"type"`
	Command string `json:"command"`
	Timeout int    `json:"timeout,omitempty"`
}

HookEntry represents a single hook command in the config.

type HookEventSpec added in v0.10.3

type HookEventSpec struct {
	Event       string
	Label       string
	Verb        string
	Timeout     int
	Managed     bool
	Core        bool
	JSONWarning bool
}

HookEventSpec is the shared Codex event metadata used by installation, trust inspection, and the Codex integration tests.

func HookEventSpecs added in v0.10.3

func HookEventSpecs() []HookEventSpec

HookEventSpecs returns a copy so callers cannot mutate the canonical table.

type HookEvents

type HookEvents struct {
	SessionStart     []MatcherGroup `json:"SessionStart,omitempty"`
	SessionEnd       []MatcherGroup `json:"SessionEnd,omitempty"`
	UserPromptSubmit []MatcherGroup `json:"UserPromptSubmit,omitempty"`
	Stop             []MatcherGroup `json:"Stop,omitempty"`
	PreToolUse       []MatcherGroup `json:"PreToolUse,omitempty"`
	PostToolUse      []MatcherGroup `json:"PostToolUse,omitempty"`
	SubagentStart    []MatcherGroup `json:"SubagentStart,omitempty"`
	SubagentStop     []MatcherGroup `json:"SubagentStop,omitempty"`
}

HookEvents contains the hook configurations by event type.

type HookFileState added in v0.10.3

type HookFileState uint8

HookFileState distinguishes Entire's installation from unrelated user configuration, malformed JSON, and a file that cannot be inspected.

const (
	HookFileAbsent HookFileState = iota
	HookFileUserOnly
	HookFileEntire
	HookFileMalformed
	HookFileUnavailable
)

type HookTrustInspection added in v0.10.3

type HookTrustInspection struct {
	Declared []string
	Gaps     []string
	Known    bool
}

HookTrustInspection is a structural view of Codex's local approval records. It never computes or copies trusted hashes.

func InspectHookTrust added in v0.10.3

func InspectHookTrust(ctx context.Context) HookTrustInspection

InspectHookTrust reports declared events and whether the user's Codex config contains approval records for them. Known is false when config.toml cannot be read, so callers do not mistake an unavailable trust check for active hooks.

type HooksFile

type HooksFile struct {
	Hooks HookEvents `json:"hooks"`
}

HooksFile represents the .codex/hooks.json structure.

type MatcherGroup

type MatcherGroup struct {
	Matcher *string     `json:"matcher"`
	Hooks   []HookEntry `json:"hooks"`
}

MatcherGroup groups hooks under an optional matcher pattern.

type UnresolvedHookDiscoveryError added in v0.10.3

type UnresolvedHookDiscoveryError struct {
	Reason string
}

UnresolvedHookDiscoveryError explains why Entire will not guess which hook file Codex loads for a Git layout.

func (*UnresolvedHookDiscoveryError) Error added in v0.10.3

type WorktreeHooksPath added in v0.10.3

type WorktreeHooksPath struct {
	// contains filtered or unexported fields
}

WorktreeHooksPath identifies the hooks file owned by the current checkout. It is intentionally distinct from DiscoveredHooksPath.

func ResolveWorktreeHooksPath added in v0.10.3

func ResolveWorktreeHooksPath(ctx context.Context) (WorktreeHooksPath, error)

ResolveWorktreeHooksPath resolves the hooks file owned by the current checkout, independently of the file Codex discovers.

func (WorktreeHooksPath) Path added in v0.10.3

func (p WorktreeHooksPath) Path() string

Path returns the current checkout's hooks file path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL