Documentation
¶
Overview ¶
Package agent defines the provider-agnostic contract codexmon uses to drive and monitor an AI coding CLI — codex, Claude Code, or the Cursor agent.
Each concrete agent lives in a subpackage (internal/agent/codex, .../claude, .../cursor) that registers a Provider via Register from an init function. The supervisor and CLI then work only against the shared types here, so adding a new agent never touches the monitor: it just implements Provider and registers itself.
The central idea is normalization. Every agent emits a different event stream — codex's JSONL item/turn events, Claude Code's stream-json system/assistant/ result events, Cursor's tool_call lifecycle — but codexmon only cares about a handful of liveness facts: what phase the run is in, which units of work are in flight (so the watchdog can time them), the final answer, and token usage. A Provider's ParseLine collapses its native stream into the common Event here.
Index ¶
- Constants
- Variables
- func Caller() string
- func FallbackChain(caller string) []string
- func FirstNonEmpty(vals ...string) string
- func IsLimitFailure(texts ...string) bool
- func Names() []string
- func Register(p Provider)
- func ResolveBin(p Provider, override string) (string, error)
- func ReviewPrompt(spec ReviewSpec) string
- func Shorten(s string, limit int) string
- func UsageSummary(u *Usage) string
- type ActiveItem
- type Analysis
- type DoctorReport
- type Event
- type ItemKind
- type Phase
- type Provider
- type ReviewScope
- type ReviewSpec
- type RunFunc
- type Usage
Constants ¶
const DefaultName = "codex"
DefaultName is the agent codexmon uses when none is selected via --agent or CODEXMON_AGENT. It is codex, so every command that worked before this tool learned other agents keeps working unchanged.
Variables ¶
var ErrTimeout = errors.New("timed out")
ErrTimeout is returned by a RunFunc when the probed command exceeded its deadline — the very hang codexmon exists to surface — so a Provider can report it distinctly from an ordinary command failure.
Functions ¶
func Caller ¶ added in v0.6.0
func Caller() string
Caller reports which coding agent invoked codexmon, inferred from the environment, or "" when unknown (a human shell, CI, an unrecognized agent). It exists so codexmon can avoid falling back to the very agent that is calling it. Today only Claude Code is detected: it exports CLAUDECODE=1 into the environment of every process it launches, so a codexmon run spawned from Claude Code sees it.
func FallbackChain ¶ added in v0.6.0
FallbackChain is FallbackOrder with the calling agent removed: codexmon must not fall back to the agent that invoked it, which is presumably the one already rate-limited or busy. With a Claude Code caller, for instance, the chain collapses from codex→claude→cursor to codex→cursor (Cursor becomes the second and last fallback). An unknown caller leaves the full chain intact.
func FirstNonEmpty ¶
FirstNonEmpty returns the first argument that is not empty after trimming, or "" if all are empty.
func IsLimitFailure ¶ added in v0.6.0
IsLimitFailure reports whether any of the given texts (typically a failed run's error message and final output) indicates the agent stopped because it ran out of a usage, rate, or quota limit — the cue codexmon uses to fall back to the next agent rather than surfacing the failure.
func Register ¶
func Register(p Provider)
Register adds a provider to the global registry. Providers call this from an init function; registering two providers under the same name panics, since that can only be a programming error.
func ResolveBin ¶
ResolveBin locates a provider's executable. An explicit override (e.g. --agent-bin) wins; then the provider's BinEnv environment variable; then the first of its BinCandidates found on PATH.
func ReviewPrompt ¶
func ReviewPrompt(spec ReviewSpec) string
ReviewPrompt builds a provider-neutral code-review instruction for agents that have no purpose-built reviewer (Claude Code, Cursor). It tells the agent which diff to look at and to stay strictly read-only.
func Shorten ¶
Shorten collapses runs of whitespace in s and truncates it to limit bytes, appending an ellipsis when it had to cut. Providers use it to keep one-line status summaries tidy.
func UsageSummary ¶
UsageSummary renders token usage as " (N in / M out tokens)", or "" when nil, for appending to a completion summary.
Types ¶
type ActiveItem ¶
type ActiveItem struct {
ID string
Kind ItemKind
Label string // short human label, used in stuck-tool kill reasons
}
ActiveItem is a unit of work an agent reported starting. The watchdog tracks it by ID until a matching completion arrives, timing it per its Kind.
type Analysis ¶
Analysis is the outcome of inspecting the args destined for one agent: the (possibly flag-augmented) args to actually run, whether codexmon will monitor the run as a JSON event stream, and a short human title.
type DoctorReport ¶
type DoctorReport struct {
Agent string `json:"agent"`
Ready bool `json:"ready"`
Bin string `json:"bin"`
Version string `json:"version,omitempty"`
HealthName string `json:"health_name,omitempty"` // probe used, e.g. "codex doctor"
HealthOK bool `json:"health_ok"`
Detail json.RawMessage `json:"detail,omitempty"` // structured probe output, if any
DetailText string `json:"detail_text,omitempty"` // textual probe output, if any
Problems []string `json:"problems,omitempty"`
}
DoctorReport is the normalized result of a Provider's readiness check.
type Event ¶
type Event struct {
Phase Phase
Summary string
Started []ActiveItem // units of work that began on this line
Finished []string // IDs of units that completed or failed on this line
Result string // final/most-recent answer text carried by this line
ThreadID string // session/thread id, when this line establishes one
Usage *Usage // token usage, when this line reports it
Failure bool // a hard error / failed-turn line
FailMsg string // failure detail (used when Failure is true)
}
Event is the normalized interpretation of one line of an agent's output stream. A Provider's ParseLine fills only the fields a given line implies; the monitor merges them into the live status. Two conventions keep parsers simple: Phase == "" means "keep the previous phase", and Summary == "" means "log nothing for this line" (the line still counts as activity).
type ItemKind ¶
type ItemKind int
ItemKind buckets an in-flight unit of work so the watchdog can apply the right liveness rule: a shell command may legitimately run for minutes (wall-clock only), an MCP/tool call should be quick (its own stuck-timeout), and anything else is generic activity governed by the idle ceiling.
type Phase ¶
type Phase string
Phase is a coarse, human-meaningful stage label derived from an agent's event stream. It is what `codexmon status` shows so a watcher can tell *what* the agent is doing — regardless of which agent it is.
const ( PhaseStarting Phase = "starting" PhaseThinking Phase = "thinking" PhaseRunning Phase = "running" PhaseVerifying Phase = "verifying" PhaseEditing Phase = "editing" PhaseInvestigate Phase = "investigating" PhaseSearching Phase = "searching" PhaseReviewing Phase = "reviewing" PhaseWriting Phase = "writing" PhaseFinalizing Phase = "finalizing" PhaseCompleted Phase = "completed" PhaseFailed Phase = "failed" )
type Provider ¶
type Provider interface {
// Name is the canonical id used by --agent and CODEXMON_AGENT.
Name() string
// BinEnv is the environment variable that overrides the binary path
// (e.g. CODEXMON_CODEX). It is also used in "not found" diagnostics.
BinEnv() string
// BinCandidates lists the executables to look up on PATH, in preference
// order (Cursor ships both "cursor-agent" and "agent", for instance).
BinCandidates() []string
// Analyze inspects the args headed for the agent, optionally injects the
// flags codexmon needs to monitor a JSON event stream and capture the final
// answer, and reports whether the run will be JSON-monitored.
Analyze(args []string, resultFile string, allowJSON bool) Analysis
// ReviewArgs builds the agent-native args for a code review from a
// high-level ReviewSpec. The result is then fed through Analyze.
ReviewArgs(spec ReviewSpec) ([]string, error)
// ParseLine normalizes one line of the agent's stdout stream into an Event.
// ok is false for blank or non-event lines.
ParseLine(line string) (Event, bool)
// Doctor reports whether the agent is installed and usable, using run for
// bounded version/health probes.
Doctor(bin string, run RunFunc) DoctorReport
}
Provider adapts one AI coding CLI to codexmon's monitor.
type ReviewScope ¶
type ReviewScope string
ReviewScope selects which changes `codexmon review` asks the agent to review.
const ( ScopeUncommitted ReviewScope = "uncommitted" // the working tree (default) ScopeBase ReviewScope = "base" // current branch vs a base ref )
type ReviewSpec ¶
type ReviewSpec struct {
Scope ReviewScope
Base string // base ref when Scope == ScopeBase
}
ReviewSpec is the high-level, agent-independent description of a review that the `codexmon review` command turns into native args via Provider.ReviewArgs.
type RunFunc ¶
RunFunc runs a short, bounded command and returns its combined output. On a deadline it returns ErrTimeout. Providers use it for version/health probes in Doctor; the CLI supplies an implementation that kills the whole process group on timeout so a wedged agent can never hang `codexmon doctor`.
type Usage ¶
type Usage struct {
InputTokens int `json:"input_tokens"`
CachedInputTokens int `json:"cached_input_tokens"`
CacheCreationTokens int `json:"cache_creation_tokens,omitempty"`
OutputTokens int `json:"output_tokens"`
ReasoningOutputTokens int `json:"reasoning_output_tokens"`
}
Usage is normalized token accounting. Agents leave fields they do not report at zero (Cursor, for instance, reports no token usage at all).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package all registers every built-in agent provider as an import side effect.
|
Package all registers every built-in agent provider as an import side effect. |
|
Package claude adapts Anthropic's Claude Code CLI (`claude`) to codexmon's agent contract.
|
Package claude adapts Anthropic's Claude Code CLI (`claude`) to codexmon's agent contract. |
|
Package codex adapts the OpenAI Codex CLI (`codex`) to codexmon's agent contract: it locates the binary, injects the `exec --json` / `--output-last-message` flags that make a run observable, and parses codex's JSONL event stream into the normalized agent.Event the monitor consumes.
|
Package codex adapts the OpenAI Codex CLI (`codex`) to codexmon's agent contract: it locates the binary, injects the `exec --json` / `--output-last-message` flags that make a run observable, and parses codex's JSONL event stream into the normalized agent.Event the monitor consumes. |
|
Package cursor adapts the Cursor agent CLI (`cursor-agent`, also installed as `agent`) to codexmon's agent contract.
|
Package cursor adapts the Cursor agent CLI (`cursor-agent`, also installed as `agent`) to codexmon's agent contract. |