Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Repository Overview

Entire CLI is a Go CLI tool that captures AI coding agent sessions (Claude Code, Cursor, etc.) as searchable metadata stored separately from code commits. It uses a strategy pattern for session/checkpoint management with minimal impact on commit history.
Entire CLI is a Go CLI tool that captures AI coding agent sessions (Claude Code, Cursor, Copilot CLI, Gemini CLI, OpenCode, etc.) as searchable metadata stored separately from code commits. It uses a strategy pattern for session/checkpoint management with minimal impact on commit history.

**Tech Stack**: Go (version in `mise.toml`), Cobra (CLI), charmbracelet/huh (interactive prompts), go-git/v5 (with caveats)

Expand Down
8 changes: 5 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This repo contains the CLI for Entire.
- `entire/`: Main CLI entry point
- `entire/cli`: CLI utilities and helpers
- `entire/cli/commands`: actual command implementations
- `entire/cli/agent`: agent implementations (Claude Code, Gemini CLI, OpenCode, Cursor) - see [Agent Integration Checklist](docs/architecture/agent-integration-checklist.md) and [Agent Implementation Guide](docs/architecture/agent-guide.md)
- `entire/cli/agent`: agent implementations (Claude Code, Gemini CLI, OpenCode, Cursor, Copilot CLI) - see [Agent Integration Checklist](docs/architecture/agent-integration-checklist.md) and [Agent Implementation Guide](docs/architecture/agent-guide.md)
- `entire/cli/strategy`: strategy implementation (manual-commit) - see section below
- `entire/cli/checkpoint`: checkpoint storage abstractions (temporary and committed)
- `entire/cli/session`: session state management
Expand Down Expand Up @@ -72,16 +72,18 @@ mise run test:e2e [filter] # All agents, filtered
mise run test:e2e --agent claude-code [filter] # Claude Code only
mise run test:e2e --agent gemini-cli [filter] # Gemini CLI only
mise run test:e2e --agent opencode [filter] # OpenCode only
mise run test:e2e --agent copilot-cli [filter] # Copilot CLI only
mise run test:e2e --agent cursor [filter] # Cursor only
Comment on lines +75 to +76
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --agent value for Cursor E2E runs appears incorrect here. The E2E agent registry uses cursor-cli (see e2e/agents/cursor_cli.go), so mise run test:e2e --agent cursor won’t match the current filter/registration.

Copilot uses AI. Check for mistakes.
```

E2E tests:

- Use the `//go:build e2e` build tag
- Located in `e2e/tests/`
- See [`e2e/README.md`](e2e/README.md) for full documentation (structure, debugging, adding agents)
- Test real agent interactions (Claude Code, Gemini CLI, OpenCode, Cursor, or Vogon creating files, committing, etc.)
- Test real agent interactions (Claude Code, Gemini CLI, OpenCode, Cursor, Copilot CLI, or Vogon creating files, committing, etc.)
- Validate checkpoint scenarios documented in `docs/architecture/checkpoint-scenarios.md`
- Support multiple agents via `E2E_AGENT` env var (`claude-code`, `gemini`, `opencode`, `cursor`, `vogon`)
- Support multiple agents via `E2E_AGENT` env var (`claude-code`, `gemini`, `opencode`, `cursor`, `copilot-cli`, `vogon`)
Comment on lines +84 to +86
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documented E2E_AGENT values (gemini, cursor, etc.) don’t match the actual E2E agent names used by the harness (gemini-cli, cursor-cli, plus factoryai-droid, etc.). Please update this list so contributors can correctly filter E2E runs.

Copilot uses AI. Check for mistakes.

**Environment variables:**

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ These are markdown files that define specialized behaviors for Claude Code (e.g.

### 2. Coding Agent Integrations (Go)

These are Go implementations that integrate Entire with different AI coding tools (Claude Code, Gemini CLI, OpenCode, Cursor, etc.) using the Agent abstraction layer.
These are Go implementations that integrate Entire with different AI coding tools (Claude Code, Gemini CLI, OpenCode, Cursor, Copilot CLI, etc.) using the Agent abstraction layer.

- **Location:** `cmd/entire/cli/agent/`
- **Steps:**
Expand Down Expand Up @@ -338,7 +338,7 @@ Join the Entire community:

- [README](README.md) - Setup and usage documentation
- [CLAUDE.md](CLAUDE.md) - Architecture and development reference (Claude Code)
- [AGENTS.md](AGENTS.md) - Architecture and development reference (Gemini CLI, OpenCode, Cursor)
- [AGENTS.md](AGENTS.md) - Architecture and development reference (Gemini CLI, OpenCode, Cursor, Copilot CLI)
- [Code of Conduct](CODE_OF_CONDUCT.md) - Community guidelines
- [Security Policy](SECURITY.md) - Reporting security vulnerabilities

Expand Down
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ With Entire, you can:

- Git
- macOS or Linux (Windows via WSL)
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [OpenCode](https://opencode.ai/docs/cli/), or [Cursor](https://www.cursor.com/) installed and authenticated
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [OpenCode](https://opencode.ai/docs/cli/), [Cursor](https://www.cursor.com/), or [GitHub Copilot CLI](https://docs.github.com/en/copilot) installed and authenticated

## Quick Start

Expand All @@ -56,13 +56,13 @@ entire status
entire enable
```

This installs agent and git hooks to work with your AI agent (Claude Code, Gemini CLI, OpenCode, or Cursor). You'll be prompted to select which agents to enable. To enable a specific agent non-interactively, use `entire enable --agent <name>` (e.g., `entire enable --agent cursor`).
This installs agent and git hooks to work with your AI agent (Claude Code, Gemini CLI, OpenCode, Cursor, or Copilot CLI). You'll be prompted to select which agents to enable. To enable a specific agent non-interactively, use `entire enable --agent <name>` (e.g., `entire enable --agent cursor`).

The hooks capture session data as you work. Checkpoints are created when you or the agent make a git commit. Your code commits stay clean, Entire never creates commits on your active branch. All session metadata is stored on a separate `entire/checkpoints/v1` branch.

### 2. Work with Your AI Agent

Just use Claude Code, Gemini CLI, OpenCode, or Cursor normally. Entire runs in the background, tracking your session:
Just use Claude Code, Gemini CLI, OpenCode, Cursor, or Copilot CLI normally. Entire runs in the background, tracking your session:

```
entire status # Check current session status anytime
Expand Down Expand Up @@ -171,7 +171,7 @@ Multiple AI sessions can run on the same commit. If you start a second session w

| Flag | Description |
| ---------------------- | --------------------------------------------------------------------- |
| `--agent <name>` | AI agent to install hooks for: `claude-code`, `gemini`, `opencode`, or `cursor` |
| `--agent <name>` | AI agent to install hooks for: `claude-code`, `gemini`, `opencode`, `cursor`, or `copilot-cli` |
| `--force`, `-f` | Force reinstall hooks (removes existing Entire hooks first) |
| `--local` | Write settings to `settings.local.json` instead of `settings.json` |
| `--project` | Write settings to `settings.json` even if it already exists |
Expand Down Expand Up @@ -232,7 +232,8 @@ Each agent stores its hook configuration in its own directory. When you run `ent
| Claude Code | `.claude/settings.json` | JSON hooks config |
| Gemini CLI | `.gemini/settings.json` | JSON hooks config |
| OpenCode | `.opencode/plugins/entire.ts` | TypeScript plugin |
| Cursor | `.cursor/hooks.json` | JSON hooks config |
| Cursor | `.cursor/hooks.json` | JSON hooks config |
| Copilot CLI | `.github/hooks/entire.json` | JSON hooks config |

You can enable multiple agents at the same time — each agent's hooks are independent. Entire detects which agents are active by checking for installed hooks, not by a setting in `settings.json`.

Expand Down Expand Up @@ -309,6 +310,22 @@ Rewind is not available at this time, but other commands (`doctor`, `status` etc

If you run into any issues with Cursor integration, please [open an issue](https://github.com/entireio/cli/issues).

### Copilot CLI

GitHub Copilot CLI support is currently in preview. Entire can work with [GitHub Copilot CLI](https://docs.github.com/en/copilot) as an alternative to Claude Code, or alongside it — you can have multiple agents' hooks enabled at the same time.

To enable:

```bash
entire enable --agent copilot-cli
```

Or select Copilot CLI from the interactive agent picker when running `entire enable`.

All commands (`rewind`, `resume`, `status`, `doctor`, etc.) work the same regardless of which agent is configured.

If you run into any issues with Copilot CLI integration, please [open an issue](https://github.com/entireio/cli/issues).

## Security & Privacy

**Your session transcripts are stored in your git repository** on the `entire/checkpoints/v1` branch. If your repository is public, this data is visible to anyone.
Expand Down
2 changes: 1 addition & 1 deletion cmd/entire/cli/agent/copilotcli/AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Each line has: `type`, `data`, `id` (UUID), `timestamp` (ISO 8601), `parentId`

The `assistant.message` entries have a `toolRequests` array with tool call IDs. After each tool executes, a `tool.execution_complete` event is emitted with `toolTelemetry.properties.filePaths`, where `filePaths` is a string containing a JSON array of file paths modified by that tool call. The `TranscriptAnalyzer` implementation parses this `filePaths` property to extract modified files for checkpoint metadata.

**Note:** Token usage is NOT available in the Copilot CLI JSONL format. The transcript events do not include input/output token counts or cost information, so `TokenCalculator` is not implemented.
**Token usage:** Extracted via `TokenCalculator` from `session.shutdown` events, which contain aggregate `modelMetrics` with per-model `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheWriteTokens`, and `requests.count`. Mid-session checkpoints use per-message `outputTokens` fallback from `assistant.message` events. **Timing constraint:** Copilot CLI writes `session.shutdown` AFTER all hooks (including `sessionEnd`) return — hooks are synchronous/blocking. This means in-hook token extraction can only use the per-message fallback. The authoritative aggregate is captured at condensation time (commit/push), when the framework re-reads the full transcript and `session.shutdown` is present. Condensation also backfills `state.TokenUsage` so the session JSON reflects the authoritative totals after the first commit.
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section says token usage is extracted via a TokenCalculator, but the copilotcli agent package currently does not implement agent.TokenCalculator (no CalculateTokenUsage method). Either update the docs to reflect the current behavior (no token usage support), or add the missing implementation so the documentation matches reality.

Suggested change
**Token usage:** Extracted via `TokenCalculator` from `session.shutdown` events, which contain aggregate `modelMetrics` with per-model `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheWriteTokens`, and `requests.count`. Mid-session checkpoints use per-message `outputTokens` fallback from `assistant.message` events. **Timing constraint:** Copilot CLI writes `session.shutdown` AFTER all hooks (including `sessionEnd`) return — hooks are synchronous/blocking. This means in-hook token extraction can only use the per-message fallback. The authoritative aggregate is captured at condensation time (commit/push), when the framework re-reads the full transcript and `session.shutdown` is present. Condensation also backfills `state.TokenUsage` so the session JSON reflects the authoritative totals after the first commit.
**Token usage:** Currently not supported for the Copilot CLI agent. While `session.shutdown` events include aggregate `modelMetrics` (for example, `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheWriteTokens`, and `requests.count`), the `copilotcli` integration does not yet implement `agent.TokenCalculator` / `CalculateTokenUsage`, and token usage values are not computed or stored in `state.TokenUsage`.

Copilot uses AI. Check for mistakes.

### Transcript Position

Expand Down
26 changes: 13 additions & 13 deletions docs/architecture/agent-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ var (

### Step 8: Implement Hook Installation (if `HookSupport`)

If your agent uses a JSON config file for hooks (like Claude Code's `.claude/settings.json`, Gemini's `.gemini/settings.json`, or Cursor's `.cursor/hooks.json`), implement `HookSupport`:
If your agent uses a JSON config file for hooks (like Claude Code's `.claude/settings.json`, Gemini's `.gemini/settings.json`, Cursor's `.cursor/hooks.json`, or Copilot CLI's `.github/hooks/entire.json`), implement `HookSupport`:

```go
func (a *YourAgent) InstallHooks(localDev bool, force bool) (int, error) {
Expand Down Expand Up @@ -422,15 +422,15 @@ Test `ParseHookEvent` for every hook name your agent supports. See [Testing Patt

The framework dispatcher (`DispatchLifecycleEvent` in `lifecycle.go`) handles each event type as follows:

| Event Type | Framework Actions | Claude Code Hook | Gemini CLI Hook | Cursor Hook | OpenCode Hook |
|------------|-------------------|------------------|-----------------|-----------------|---------------|
| `SessionStart` | Shows banner, checks concurrent sessions, fires state machine transition | `session-start` | `session-start` | `session-start` | `session-start` |
| `TurnStart` | Captures pre-prompt state (git status, transcript position), ensures strategy setup, initializes session | `user-prompt-submit` | `before-agent` | `before-submit-prompt` | `turn-start` |
| `TurnEnd` | Validates transcript, extracts metadata (prompts, summary, files), detects file changes via git status, saves step + checkpoint, transitions phase to IDLE | `stop` | `after-agent` | `stop` | `turn-end` |
| `Compaction` | Fires compaction transition (stays ACTIVE), resets transcript offset | *(not used)* | `pre-compress` | `pre-compact` | `compaction` |
| `SessionEnd` | Marks session as ENDED in state machine | `session-end` | `session-end` | `session-end` | `session-end` |
| `SubagentStart` | Captures pre-task state (git status snapshot) | `pre-task` (PreToolUse[Task]) | *(not used)* | `subagent-start` | *(not used)* |
| `SubagentEnd` | Extracts subagent modified files, detects changes, saves task checkpoint | `post-task` (PostToolUse[Task]) | *(not used)* | `subagent-stop` | *(not used)* |
| Event Type | Framework Actions | Claude Code Hook | Gemini CLI Hook | Cursor Hook | OpenCode Hook | Copilot CLI Hook |
|------------|-------------------|------------------|-----------------|-----------------|---------------|-----------------|
| `SessionStart` | Shows banner, checks concurrent sessions, fires state machine transition | `session-start` | `session-start` | `session-start` | `session-start` | `sessionStart` |
| `TurnStart` | Captures pre-prompt state (git status, transcript position), ensures strategy setup, initializes session | `user-prompt-submit` | `before-agent` | `before-submit-prompt` | `turn-start` | `userPromptSubmitted` |
| `TurnEnd` | Validates transcript, extracts metadata (prompts, summary, files), detects file changes via git status, saves step + checkpoint, transitions phase to IDLE | `stop` | `after-agent` | `stop` | `turn-end` | `agentStop` |
| `Compaction` | Fires compaction transition (stays ACTIVE), resets transcript offset | *(not used)* | `pre-compress` | `pre-compact` | `compaction` | *(not used)* |
| `SessionEnd` | Marks session as ENDED in state machine | `session-end` | `session-end` | `session-end` | `session-end` | `sessionEnd` |
| `SubagentStart` | Captures pre-task state (git status snapshot) | `pre-task` (PreToolUse[Task]) | *(not used)* | `subagent-start` | *(not used)* | *(not used)* |
| `SubagentEnd` | Extracts subagent modified files, detects changes, saves task checkpoint | `post-task` (PostToolUse[Task]) | *(not used)* | `subagent-stop` | *(not used)* | `subagentStop` |

### Event Field Requirements

Expand Down Expand Up @@ -591,7 +591,7 @@ agent.SortChunkFiles(files, "full.jsonl") // sorted by chunk index

### JSON Config File Pattern

Claude Code, Gemini CLI, and Cursor use a JSON settings file in their config directory. The installation pattern is:
Claude Code, Gemini CLI, Cursor, and Copilot CLI use a JSON settings file in their config directory. The installation pattern is:

1. **Read existing settings** as `map[string]json.RawMessage` to preserve unknown fields
2. **Parse only the hook types you modify** into typed slices
Expand Down Expand Up @@ -833,8 +833,8 @@ Use `//nolint:nilnil` to suppress the linter warning on intentional nil returns.

### Agent Name vs Agent Type

- `AgentName` is the **registry key** used in code (`"claude-code"`, `"gemini"`, `"cursor"`). It appears in CLI commands: `entire hooks cursor stop`.
- `AgentType` is the **display name** stored in metadata and commit trailers (`"Claude Code"`, `"Gemini CLI"`, `"Cursor"`). It's what users see.
- `AgentName` is the **registry key** used in code (`"claude-code"`, `"gemini"`, `"opencode"`, `"cursor"`, `"copilot-cli"`). It appears in CLI commands: `entire hooks cursor stop`.
- `AgentType` is the **display name** stored in metadata and commit trailers (`"Claude Code"`, `"Gemini CLI"`, `"OpenCode"`, `"Cursor"`, `"Copilot CLI"`). It's what users see.

Register constants for both in `cmd/entire/cli/agent/registry.go` when adding a new agent.

Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/agent-integration-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ See Guide: [Transcript Format Guide](agent-guide.md#transcript-format-guide), [T

- [ ] **Full transcript on every turn**: At turn-end, capture the complete session transcript, not just events since the last checkpoint
- [ ] **Resumed session handling**: When a user resumes an existing session, the transcript must include all historical messages, not just new ones since the plugin/hook loaded
- [ ] **Use agent's canonical export**: Prefer the agent's native export command (e.g., reading Claude's JSONL file, Gemini's JSON, Cursor's JSONL, OpenCode's `opencode export` JSON) over manually reconstructing from events
- [ ] **Use agent's canonical export**: Prefer the agent's native export command (e.g., reading Claude's JSONL file, Gemini's JSON, Cursor's JSONL, Copilot CLI's JSONL, OpenCode's `opencode export` JSON) over manually reconstructing from events
- [ ] **No custom formats**: Store the agent's native format directly in `NativeData` - do not convert between formats (e.g., JSON to JSONL) or create intermediate representations
- [ ] **Graceful degradation**: If the canonical source is unavailable (e.g., agent shutting down), fall back to best-effort capture with clear documentation of limitations

Expand All @@ -54,7 +54,7 @@ See Guide: [Transcript Format Guide](agent-guide.md#transcript-format-guide), [T
See Guide: [Step 3 - Core Agent Interface](agent-guide.md#step-3-implement-core-agent-interface-youragentgo)

- [ ] **`WriteSession` implementation**: Agent must implement `WriteSession(AgentSession)` to restore sessions
- [ ] **File-based agents** (Claude, Gemini, Cursor): Write `NativeData` to `SessionRef` path
- [ ] **File-based agents** (Claude, Gemini, Cursor, Copilot CLI): Write `NativeData` to `SessionRef` path
- [ ] **Database-backed agents** (OpenCode): Write `NativeData` to file, then import into native storage (the native format should be what the agent's import command expects)
- [ ] **Single format per agent**: Store only the agent's native format in `NativeData` - no separate fields for different representations of the same data

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/sessions-and-checkpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

Entire CLI creates checkpoints for AI coding sessions. The system is agent-agnostic - it works with Claude Code, Gemini CLI, OpenCode, Cursor, or any tool that triggers Entire hooks.
Entire CLI creates checkpoints for AI coding sessions. The system is agent-agnostic - it works with Claude Code, Gemini CLI, OpenCode, Cursor, Copilot CLI, or any tool that triggers Entire hooks.

## Domain Model

Expand Down
2 changes: 1 addition & 1 deletion docs/security-and-privacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Entire stores AI session transcripts and metadata in your git repository. This d

### Where data is stored

When you use Entire with an AI agent (Claude Code, Gemini CLI, OpenCode, Cursor), session transcripts, user prompts, and checkpoint metadata are committed to a dedicated branch in your git repository (`entire/checkpoints/v1`). This branch is separate from your working branches, your code commits stay clean, but it lives in the same repository.
When you use Entire with an AI agent (Claude Code, Gemini CLI, OpenCode, Cursor, Copilot CLI), session transcripts, user prompts, and checkpoint metadata are committed to a dedicated branch in your git repository (`entire/checkpoints/v1`). This branch is separate from your working branches, your code commits stay clean, but it lives in the same repository.

Entire also creates temporary local branches (e.g., `entire/<short-hash>`) as working storage during a session. These shadow branches store file snapshots and transcripts **without redaction**. They are cleaned up when session data is condensed (with redaction) into `entire/checkpoints/v1` at commit time. Shadow branches are **not** pushed by Entire — do not push them manually, as unredacted content would be visible on the remote.

Expand Down
Loading