External Agent Plugin Protocol

August 14, 2026 · View on GitHub

Overview

The Entire CLI supports external agent plugins — standalone binaries that implement the Agent interface via a subcommand-based protocol over stdin/stdout. This allows third-party agents to integrate with the CLI without modifying the main repository.

Discovery

The CLI discovers external agents by scanning $PATH for executables matching the pattern entire-agent-<name>. For example, entire-agent-cursor would register as the "cursor" agent.

  • Binaries whose <name> conflicts with an already-registered built-in agent are skipped.
  • Discovery runs once during CLI initialization (before building the hooks command tree).
  • The binary must be executable and respond to the info subcommand.

Environment

Every subcommand invocation sets:

VariableDescription
ENTIRE_REPO_ROOTAbsolute path to the git repository root
ENTIRE_PROTOCOL_VERSIONProtocol version (1)

The working directory is set to the repository root.

Communication Model

  • Subcommand-based: Each Agent interface method maps to a CLI subcommand.
  • JSON over stdin/stdout: Structured data uses JSON. Transcripts use raw bytes.
  • Stateless: Each invocation is independent — no persistent connection.
  • Exit codes: 0 = success, non-zero = error. Error messages go to stderr.

Subcommands

Always Required

info

Returns agent metadata and declared capabilities.

Arguments: None

Output (stdout): JSON

{
  "protocol_version": 1,
  "name": "cursor",
  "type": "Cursor",
  "description": "Cursor - AI-powered code editor",
  "is_preview": true,
  "protected_dirs": [".cursor"],
  "hook_names": ["session-start", "session-end", "stop"],
  "capabilities": {
    "hooks": true,
    "transcript_analyzer": true,
    "transcript_preparer": false,
    "token_calculator": false,
    "text_generator": false,
    "hook_response_writer": false,
    "subagent_aware_extractor": false
  }
}

The capabilities object determines which optional subcommands the CLI will call. If a capability is false or missing, the CLI will never invoke the corresponding subcommands.

detect

Checks whether the agent is present/usable in the current environment.

Arguments: None

Output (stdout): JSON

{"present": true}

get-session-id

Extracts the session ID from a hook input event.

Input (stdin): JSON — the HookInput object

Output (stdout): JSON

{"session_id": "abc123"}

get-session-dir --repo-path <path>

Returns the directory where agent sessions are stored.

Arguments:

  • --repo-path — Absolute path to the repository

Output (stdout): JSON

{"session_dir": "/path/to/sessions"}

resolve-session-file --session-dir <dir> --session-id <id>

Resolves the session file path from a session directory and ID.

Arguments:

  • --session-dir — Session directory path
  • --session-id — Session identifier

Output (stdout): JSON

{"session_file": "/path/to/session/file.jsonl"}

read-session

Reads session data from a hook input event.

Input (stdin): JSON — the HookInput object

Output (stdout): JSON — AgentSession object

{
  "session_id": "abc123",
  "agent_name": "cursor",
  "repo_path": "/path/to/repo",
  "session_ref": "/path/to/file.jsonl",
  "start_time": "2026-01-13T12:00:00Z",
  "native_data": null,
  "modified_files": ["src/main.go"],
  "new_files": [],
  "deleted_files": []
}

write-session

Writes/updates session data.

Input (stdin): JSON — the AgentSession object

Output: Exit 0 on success.

read-transcript --session-ref <path>

Reads a transcript file and returns its raw bytes.

Arguments:

  • --session-ref — Path to the transcript file

Output (stdout): Raw transcript bytes.

chunk-transcript --max-size <n>

Splits a transcript into chunks for storage.

Input (stdin): Raw transcript bytes.

Arguments:

  • --max-size — Maximum chunk size in bytes

Output (stdout): JSON

{"chunks": ["<base64-encoded-chunk>", "..."]}

reassemble-transcript

Reassembles transcript chunks back into a full transcript.

Input (stdin): JSON

{"chunks": ["<base64-encoded-chunk>", "..."]}

Output (stdout): Raw transcript bytes.

format-resume-command --session-id <id>

Returns the command a user can run to resume a session.

Arguments:

  • --session-id — Session identifier

Output (stdout): JSON

{"command": "cursor --resume abc123"}

Capability: hooks

These subcommands are required when capabilities.hooks is true.

parse-hook --hook <name>

Parses a raw agent hook payload into a structured event.

Arguments:

  • --hook — Hook name (e.g., "stop", "session-start")

Input (stdin): Raw agent hook payload bytes.

Output (stdout): JSON — the parsed Event object, or null if the payload is not relevant.

install-hooks [--force]

Installs agent hooks for Entire integration.

Arguments:

  • --force — Overwrite existing hooks (optional)

--local-dev was removed: it asked the agent to point hooks at a build inside the working tree, which meant installed hooks ran whatever the checked-out branch contained. The CLI never sends it. Agents that still accept the flag should treat it as a no-op; hook commands must name the entire binary.

Output (stdout): JSON

{"hooks_installed": 3}

uninstall-hooks

Removes installed agent hooks.

Arguments: None

Output: Exit 0 on success.

are-hooks-installed

Checks whether hooks are currently installed.

Arguments: None

Output (stdout): JSON

{"installed": true}

Capability: transcript_analyzer

Required when capabilities.transcript_analyzer is true.

get-transcript-position --path <path>

Returns the current byte position/size of a transcript file.

Arguments:

  • --path — Path to the transcript file

Output (stdout): JSON

{"position": 12345}

extract-modified-files --path <path> --offset <n>

Extracts the list of files modified by the agent from a transcript.

Arguments:

  • --path — Path to the transcript file
  • --offset — Byte offset to start reading from

Output (stdout): JSON

{"files": ["path/to/file1.go", "path/to/file2.go"], "current_position": 12345}

The current_position field returns the transcript position after extraction, allowing the caller to resume from that point on subsequent calls.

extract-prompts --session-ref <path> --offset <n>

Extracts user prompts from a transcript.

Arguments:

  • --session-ref — Path to the transcript file
  • --offset — Byte offset to start reading from

Output (stdout): JSON

{"prompts": ["first prompt text", "second prompt text"]}

extract-summary --session-ref <path>

Extracts an AI-generated summary from a transcript.

Arguments:

  • --session-ref — Path to the transcript file

Output (stdout): JSON

{"summary": "Summary text here", "has_summary": true}

Capability: transcript_preparer

Required when capabilities.transcript_preparer is true.

prepare-transcript --session-ref <path>

Prepares/processes a transcript file (e.g., converting from raw format).

Arguments:

  • --session-ref — Path to the transcript file

Output: Exit 0 on success.

Capability: token_calculator

Required when capabilities.token_calculator is true.

calculate-tokens --offset <n>

Calculates token usage from a transcript.

Input (stdin): Raw transcript bytes.

Arguments:

  • --offset — Byte offset to start calculating from

Output (stdout): JSON

{
  "input_tokens": 1500,
  "cache_creation_tokens": 0,
  "cache_read_tokens": 200,
  "output_tokens": 500,
  "api_call_count": 3,
  "subagent_tokens": null
}

Only input_tokens and output_tokens are required. The optional fields (cache_creation_tokens, cache_read_tokens, api_call_count) default to 0 if omitted. subagent_tokens is an optional nested object with the same structure, for agents that spawn subagents.

Capability: text_generator

Required when capabilities.text_generator is true.

External agents that declare capabilities.text_generator: true can be used as summary providers for entire explain --generate and checkpoint auto-summarize. Configure them with:

entire configure --summarize-provider <agent-name> [--summarize-model <model>]

The provider name is derived from the executable name entire-agent-<agent-name>. The CLI passes Entire's summary prompt on stdin to generate-text --model <model> and expects {"text":"..."} on stdout.

generate-text --model <model>

Generates text using the agent's underlying LLM.

Input (stdin): Prompt text.

Arguments:

  • --model — Model to use for generation

Output (stdout): JSON

{"text": "Generated response text"}

Capability: hook_response_writer

Required when capabilities.hook_response_writer is true.

write-hook-response --message <message>

Writes a message in the agent's native hook response format.

Arguments:

  • --message — Message to write

Output (stdout): Agent-native format bytes (e.g., JSONL for Claude Code).

Capability: subagent_aware_extractor

Required when capabilities.subagent_aware_extractor is true.

extract-all-modified-files --offset <n> --subagents-dir <dir>

Extracts modified files from both the main transcript and any subagent transcripts.

Input (stdin): Raw main transcript bytes.

Arguments:

  • --offset — Byte offset for the main transcript
  • --subagents-dir — Directory containing subagent transcripts

Output (stdout): JSON

{"files": ["file1.go", "file2.go"]}

calculate-total-tokens --offset <n> --subagents-dir <dir>

Calculates total token usage across main transcript and subagent transcripts.

Input (stdin): Raw main transcript bytes.

Arguments:

  • --offset — Byte offset for the main transcript
  • --subagents-dir — Directory containing subagent transcripts

Output (stdout): JSON

{
  "input_tokens": 5000,
  "cache_creation_tokens": 0,
  "cache_read_tokens": 1000,
  "output_tokens": 2000,
  "api_call_count": 8,
  "subagent_tokens": {
    "input_tokens": 2000,
    "output_tokens": 800
  }
}

Same token usage format as calculate-tokens. The subagent_tokens field aggregates usage from all subagents.

Shared Object Definitions

HookInput Object

The HookInput object is passed via stdin to get-session-id and read-session.

{
  "hook_type": "stop",
  "session_id": "abc123",
  "session_ref": "/path/to/transcript.jsonl",
  "timestamp": "2026-01-13T12:00:00Z",
  "user_prompt": "Fix the login bug",
  "tool_name": "Write",
  "tool_use_id": "toolu_abc123",
  "tool_input": {"path": "/src/main.go"},
  "raw_data": {"custom_field": "value"}
}
FieldTypeDescription
hook_typestringHook type: session_start, session_end, user_prompt_submit, stop, pre_tool_use, post_tool_use
session_idstringAgent session identifier
session_refstringAgent-specific session reference (typically a file path)
timestampstringRFC 3339 timestamp
user_promptstringUser's prompt text (from user_prompt_submit hooks). Optional.
tool_namestringTool name (from pre_tool_use/post_tool_use hooks). Optional.
tool_use_idstringTool invocation ID. Optional.
tool_inputobjectRaw tool input JSON. Optional.
raw_dataobjectAgent-specific data for extension. Optional.

AgentSession Object

Used as input to write-session and output from read-session.

{
  "session_id": "abc123",
  "agent_name": "cursor",
  "repo_path": "/path/to/repo",
  "session_ref": "/path/to/transcript.jsonl",
  "start_time": "2026-01-13T12:00:00Z",
  "native_data": null,
  "modified_files": ["src/main.go"],
  "new_files": ["src/new_file.go"],
  "deleted_files": []
}
FieldTypeDescription
session_idstringAgent session identifier
agent_namestringAgent registry name
repo_pathstringAbsolute path to the repository
session_refstringPath/reference to session in agent's storage
start_timestringRFC 3339 timestamp of session start
native_databytes/nullSession content in agent's native format (opaque to CLI)
modified_filesstring[]Files modified during the session
new_filesstring[]Files created during the session
deleted_filesstring[]Files deleted during the session

Event Object

Returned by parse-hook. Represents a normalized lifecycle event.

{
  "type": 3,
  "session_id": "abc123",
  "session_ref": "/path/to/transcript.jsonl",
  "prompt": "Fix the login bug",
  "model": "claude-sonnet-4-20250514",
  "timestamp": "2026-01-13T12:00:00Z"
}
FieldTypeDescription
typeintRequired. Event type (see table below)
session_idstringRequired. Agent session identifier
previous_session_idstringNon-empty when this event represents a session continuation/handoff. Optional.
session_refstringAgent-specific transcript reference. Optional.
promptstringUser's prompt text (on TurnStart events). Optional.
modelstringLLM model identifier. Optional.
timestampstringRFC 3339 timestamp. Optional.
tool_use_idstringTool invocation ID (for SubagentStart/SubagentEnd). Optional.
subagent_idstringSubagent instance ID (for SubagentEnd). Optional.
tool_inputobjectRaw tool input JSON (for subagent type/description extraction). Optional.
subagent_typestringKind of subagent (for SubagentStart/SubagentEnd). Optional.
task_descriptionstringSubagent task description. Optional.
response_messagestringMessage to display to the user via the agent. Optional.
metadataobjectAgent-specific state preserved across events. Optional.

Event types:

ValueNameDescription
1SessionStartAgent session has begun
2TurnStartUser submitted a prompt, agent is about to work
3TurnEndAgent finished responding to a prompt
4CompactionAgent is compressing its context window (triggers save + offset reset)
5SessionEndSession has been terminated
6SubagentStartA subagent (task) has been spawned
7SubagentEndA subagent (task) has completed

Error Handling

  • Exit code 0 indicates success.
  • Any non-zero exit code indicates an error.
  • Error messages should be written to stderr.
  • The CLI captures stderr and wraps it in a Go error.
  • If the binary is not found in PATH, the agent is simply not registered.
  • If info fails or returns invalid JSON, the binary is skipped during discovery.

Versioning

The protocol version is declared in the info response (protocol_version field) and set via ENTIRE_PROTOCOL_VERSION environment variable. The CLI checks that the binary's protocol version matches its expected version before registering the agent.

Future protocol versions may add new subcommands or capabilities. Existing subcommands will maintain backwards compatibility within a major version.