Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a3e8440
feat: add iterative agent loop with verifiers, worktree, and commit
moshloop Jun 29, 2026
875a15d
feat: add captain serve command with web UI and chat interface
moshloop Jun 29, 2026
0e3ec09
refactor: consolidate domain types into pkg/api and add session browsing
moshloop Jun 29, 2026
2f57ce0
refactor: restructure ai.Request and ai.Config to use nested types
moshloop Jun 29, 2026
89b338e
refactor: restructure ai.Request and ai.Config with nested field groups
moshloop Jun 29, 2026
ee9ce0d
refactor: restructure ai.Request to use nested api types
moshloop Jun 29, 2026
a3c67e3
feat(prompt): support spec-native frontmatter in .prompt files
moshloop Jun 29, 2026
5a93ec4
feat(cmux): add interactive claude/codex TUI provider with session ta…
moshloop Jun 29, 2026
257d416
refactor: Refactor cost tracking to break out reasoning and cache tok…
moshloop Jun 29, 2026
1477665
feat: add multi-session filtering and .prompt file support to AI comm…
moshloop Jun 29, 2026
0b50c63
refactor(cli): refactor request model field access patterns
moshloop Jun 30, 2026
437709c
chore(deps): bump flanksource/commons to v1.53.1
moshloop Jun 30, 2026
526166f
fix(serve): embed dist placeholder so the binary builds without a pre…
moshloop Jun 30, 2026
54ab144
refactor: refactor prompt handling to use file-based routing instead …
moshloop Jun 30, 2026
b22c191
feat scope: cli,claude,tools: add plan command to query session exit-…
moshloop Jun 30, 2026
cb58b74
test: expand non-API backend test coverage and improve determinism
moshloop Jun 30, 2026
dac4b0d
refactor(api): move AI runtime contract into pkg/api
moshloop Jun 30, 2026
72e558b
build(deps): pin clicky/aichat to pkg/api-based pseudo-version
moshloop Jun 30, 2026
b66cb3a
style: gofmt HistoryEntry struct tag alignment
moshloop Jun 30, 2026
b03a728
feat(ai): add model catalog system with pricing and caching
moshloop Jun 30, 2026
5179460
fix(provider): buffer runCLI output to avoid Wait/pipe-read race
moshloop Jun 30, 2026
764a29c
fix(ai): resolve model-catalog test ordering and context-window lookup
moshloop Jun 30, 2026
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
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ specs/
*.png
go.work
go.work.sum
pkg/cli/webapp/node_modules/
pkg/cli/webapp/*.tsbuildinfo
# goreleaser output at repo root.
/dist/
# Keep pkg/cli/webapp/dist tracked so the webapp is embedded by //go:embed in
# serve.go (it cannot be built in CI due to the local clicky-ui link: dependency).
# These negations override a global `dist/` ignore; re-include the directory
# before its contents.
!pkg/cli/webapp/dist/
!pkg/cli/webapp/dist/**
.grite/
pkg/cli/webapp/dist/
158 changes: 143 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ It provides tools to:

- inspect Claude Code project/session history
- summarize tool usage, paths, binaries, and API cost
- list files changed by a session
- install Claude Code hooks
- enforce a session-specific **Definition of Done** gate
- test and use AI providers from the command line
- run iterative AI agents with verifiers, worktrees, and commits
- generate/build/run containerized Claude Code sandboxes
- inspect and clean stored Claude project session data
- expose captain commands as an MCP server
- run a web UI for launching and chatting with AI agents
- configure default backend, model, and AI safety toggles

## What it does

Expand Down Expand Up @@ -57,11 +62,23 @@ Captain supports a per-session Definition of Done workflow:

This lets Claude continue iterating until required checks pass.

### 4. AI provider utilities
### 4. Session changes

`captain changes` lists the files written or edited during a Claude Code or Codex session:

- defaults to the most recent session in the current directory
- `--session-id` targets a specific session by exact or prefix match
- `--all` searches across all projects
- `--claude` / `--codex` filter by session source
- `--agents` (default: true) includes files edited by nested sub-agents
- `--plans` / `--ignored` control whether plan files and git-ignored files are shown

### 5. AI provider utilities

Captain includes provider-agnostic AI utilities under `captain ai`:

- `ai prompt` — send a prompt to a selected backend/model
- `ai agent` — run an iterative agent loop with optional verifiers, a throwaway git worktree, commit, and LLM judge
- `ai models` — list model information
- `ai test` — verify provider connectivity
- `ai fixture` — run a YAML benchmark fixture across multiple Claude configurations and capture a markdown evidence report
Expand All @@ -71,9 +88,24 @@ Supported backends are inferred from code and dependencies, including:
- Anthropic
- Gemini / Google
- OpenAI-compatible paths via the internal provider layer
- CLI/provider abstractions for local tool-backed backends
- CLI/provider abstractions for local tool-backed backends (claude, codex, gemini)

### 6. Adapter status and configuration

- `whoami` — lists every AI adapter (API providers and CLI agents), how each is authenticated, whether its binary is installed, and the models it exposes
- `configure` — interactive wizard to set default backend, model, reasoning effort, budget, timeout, and feature toggles (caching, MCP, hooks, skills, user/project settings, memory) saved to `~/.captain.yaml`

### 7. Web UI and MCP server

- `serve` — starts an HTTP API and embedded web UI for launching AI agents and opening follow-up chat sessions; supports `--dev` to proxy to the Vite dev server
- `mcp` — exposes captain commands (history, info, cost, changes, dod, etc.) as MCP tools so Claude Code can invoke them directly

### 5. Container sandbox builder
### 8. Utility commands

- `cmux screenshot` — captures a screenshot of the active browser surface in cmux and copies the path to the clipboard
- `port kill <port>` — finds and kills the process listening on a TCP port

### 9. Container sandbox builder

Captain can discover Claude-related local configuration and package it into a container sandbox.

Expand Down Expand Up @@ -103,12 +135,19 @@ The container workflow is designed to package things like:
captain/
├── cmd/captain/ # CLI entrypoint
├── pkg/ai/ # AI abstraction, provider config, models
├── pkg/ai/agent/ # Iterative agent loop, plugins (verify, worktree, judge)
├── pkg/ai/fixture/ # YAML fixture runner for Claude configuration benchmarks
├── pkg/api/ # HTTP API types and handlers (used by serve)
├── pkg/bash/ # Bash scanning, classification, rules
├── pkg/captainconfig/ # ~/.captain.yaml config load/save
├── pkg/claude/ # Claude history, sessions, parsing, formatting
├── pkg/cli/ # Cobra/clicky command implementations
├── pkg/cli/webapp/ # Embedded React web UI (served by captain serve)
├── pkg/cmux/ # Terminal multiplexer integration (screenshot)
├── pkg/collections/ # Generic collection utilities
├── pkg/container/ # Sandbox discovery, generation, build/run logic
├── pkg/dod/ # Definition of Done persistence and execution
├── pkg/git/ # Git worktree helpers
├── pkg/sandbox/ # Token/preset/sandbox helpers
├── Dockerfile # Container image for captain/Claude tooling
├── entrypoint.sh # gosu-based user switching entrypoint
Expand All @@ -124,12 +163,19 @@ Top-level commands exposed by `cmd/captain/main.go`:
captain history
captain info
captain cost
captain changes
captain sandbox
captain ai
captain whoami
captain configure
captain serve
captain dod
captain hook
captain projects
captain container
captain mcp
captain cmux
captain port
```

### History
Expand All @@ -140,6 +186,8 @@ captain history --summary
captain history --all
captain history --tool Bash --since now-7d
captain history --category git --compact
captain history --session-id 019e0365-dc2a-7ad0-a5a8-78936481a928
captain history 019e0365-dc2a-7ad0-a5a8-78936481a928
```

Useful flags include:
Expand All @@ -149,6 +197,7 @@ Useful flags include:
- `--dir`
- `--category`
- `--approved`
- `--session-id`
- `--limit`
- `--since`
- `--all`
Expand All @@ -173,6 +222,7 @@ captain cost --group-by project
captain cost --group-by model
captain cost --group-by tool
captain cost --group-by category
captain cost --session-id 019e0365-dc2a-7ad0-a5a8-78936481a928
captain cost --all --since now-30d
```

Expand All @@ -187,6 +237,18 @@ Supported groupings from the code:
- `tool`
- `category`

### Changes

```bash
captain changes
captain changes --session-id <session-id>
captain changes --all --since now-7d
captain changes --claude
captain changes --agents=false
```

Lists the files written or edited during a Claude Code or Codex session. Defaults to the most recent session in the current directory.

### Hook installation

Install the bash safety hook:
Expand Down Expand Up @@ -216,6 +278,8 @@ captain dod clear --session-id <session-id>

```bash
captain ai prompt --model claude-sonnet-4 --prompt "Summarize this diff"
captain ai agent --prompt "Fix the failing tests" --verify "go test ./..."
captain ai agent --prompt "Refactor this module" --worktree --commit --judge "all tests pass"
captain ai test --model gemini-2.0-flash
captain ai models
captain ai fixture --file examples/ai-fixtures/mission-control-investigate.yaml
Expand All @@ -230,6 +294,20 @@ Relevant provider flags include:
- `--budget`
- `--debug`

#### AI agent

`captain ai agent` runs an iterative AI agent loop with optional quality gates:

- `--prompt` / `-p` — task prompt (required; can be piped from stdin)
- `--system` / `-s` — system prompt override
- `--verify` — shell command run after each turn; non-zero exit triggers a re-run (repeatable)
- `--max-iterations` — max verify-and-rerun iterations (default: 1)
- `--scope` — verifier scope: `changed` (only changed files) or `all` (default)
- `--worktree` — run in a throwaway git branch/worktree
- `--branch` — worktree branch name (default: `captain/agent-<timestamp>`)
- `--commit` — commit changes on the worktree branch (requires `--worktree`)
- `--judge` — LLM rubric; fails a turn when the judge rejects the result

#### Fixture benchmarks

`captain ai fixture` runs the same prompt against multiple Claude
Expand Down Expand Up @@ -366,6 +444,52 @@ Important generate/build flags:
- `--base`
- `--mode copy|mount`

### Whoami

```bash
captain whoami
captain whoami --backend anthropic
captain whoami --models=false
```

Lists every AI adapter (API providers and CLI agents: `anthropic`, `openai`, `gemini`, `claude-cli`, `claude-agent`, `codex-cli`, `gemini-cli`), their authentication method, binary availability, and a live model listing.

### Configure

```bash
captain configure
```

Interactive wizard that writes `~/.captain.yaml` with defaults for backend, model, reasoning effort, budget, timeout, and feature toggles (caching, MCP, hooks, skills, user/project settings, memory). These defaults apply to `captain ai prompt`, `captain ai agent`, `captain ai test`, and other AI commands.

### Serve

```bash
captain serve
captain serve --port 8080
captain serve --dev
```

Starts an HTTP API and embedded web UI. The UI launches `captain ai agent` operations and opens follow-up chat windows that resume the returned session. `--dev` starts the Vite dev server from `pkg/cli/webapp` and proxies `/api` back to the Go process.

### MCP server

```bash
captain mcp
```

Exposes captain commands as MCP tools. Auto-exposes all commands except `sandbox`, `projects`, `container`, `hook`, `ai`, `dod set/clear/run`.

### Utility commands

```bash
# Screenshot active browser surface in cmux
captain cmux screenshot

# Kill the process on a TCP port
captain port kill 3000
```

## Build and development

This repo uses `task` as the main task runner.
Expand Down Expand Up @@ -431,42 +555,46 @@ Primary stack:
- **Go 1.25.8**
- **Cobra** for CLI wiring
- **clicky** for formatting/output/flag binding
- **charmbracelet/huh** for the interactive `configure` TUI
- **sandbox-runtime** for sandbox preset handling
- AI SDKs for Anthropic, OpenAI, and Gemini/Google
- shell parsing via `mvdan.cc/sh/v3`

## Current state

This README reflects the current code layout.

At the time of generation, `go test ./...` in this checkout does **not** fully pass. Observed issues included:

- a build failure around `pkg/claude/tools`
- failing container tests
- AI integration tests requiring valid external provider credits/config

So treat this repository as **active/in-progress** rather than guaranteed green in the current local state.

## Quick start

```bash
cd captain
make build
.bin/captain info
.bin/captain history --summary
.bin/captain changes
.bin/captain container list
```

Configure defaults:

```bash
.bin/captain configure
.bin/captain whoami
```

If you want to use hooks:

```bash
.bin/captain hook bash-check install --user
.bin/captain hook dod install --user
```

Start the web UI:

```bash
.bin/captain serve
```

## Notes

- Captain is tightly focused on **Claude Code workflows**.
- It is both an analysis tool and an execution/control tool.
- The container/sandbox functionality is a major part of the project, not a side feature.
- Many commands assume the presence of Claude local state under the user’s Claude config/projects directories.
- Configuration is persisted to `~/.captain.yaml` via `captain configure`.
16 changes: 16 additions & 0 deletions cmd/captain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ func main() {
changesCmd.Short = "List files modified by a session"
changesCmd.Long = "List the files written or edited during a Claude Code or Codex session. Pass --session-id to target a specific session; otherwise the most recent session in the current directory is used."

planCmd := clicky.AddNamedCommand("plan", rootCmd, cli.PlanOptions{}, cli.RunPlan)
planCmd.Short = "Show the exit-plan-mode plan for a session"
planCmd.Long = "Determine the plan file path and content for a Claude Code or Codex session. Pass a session ID (exact or prefix) to target a specific session; otherwise the most recent session with a plan in the current directory is used. Claude plans resolve to a ~/.claude/plans/<slug>.md file; Codex plans are inline update_plan checklists. Use --path to print only the plan file path."

sessionsCmd := &cobra.Command{Use: "sessions", Short: "Browse Claude and Codex sessions"}
rootCmd.AddCommand(sessionsCmd)
clicky.AddNamedCommand("list", sessionsCmd, cli.SessionListOptions{}, cli.RunSessionList).Short = "List discovered sessions"
clicky.AddNamedCommand("get", sessionsCmd, cli.SessionGetOptions{}, cli.RunSessionGet).Short = "Show a session transcript"

sandboxCmd := &cobra.Command{
Use: "sandbox",
Short: "Sandbox configuration tools",
Expand All @@ -92,14 +101,21 @@ func main() {
}
rootCmd.AddCommand(aiCmd)
clicky.AddNamedCommand("prompt", aiCmd, cli.AIPromptOptions{}, cli.RunAIPrompt)
clicky.AddNamedCommand("agent", aiCmd, cli.AIAgentOptions{}, cli.RunAIAgent).Short = "Run an iterative agent with verifiers, worktree, and commit"
clicky.AddNamedCommand("models", aiCmd, cli.AIModelsOptions{}, cli.RunAIModels)
clicky.AddNamedCommand("test", aiCmd, cli.AITestOptions{}, cli.RunAITest)
clicky.AddNamedCommand("fixture", aiCmd, cli.AIFixtureOptions{}, cli.RunAIFixture).Short = "Run a YAML fixture across multiple Claude configurations"

whoamiCmd := clicky.AddNamedCommand("whoami", rootCmd, cli.WhoamiOptions{}, cli.RunWhoami)
whoamiCmd.Short = "List agent adapters, auth methods, and available models"
whoamiCmd.Long = "Show every AI agent adapter (API providers and CLI agents), how each is authenticated (API-key env var or CLI login), whether its CLI binary is installed, and the models each provider exposes via a live API call. Pass --models=false to skip the network probes, or --backend to inspect a single adapter."

configureCmd := clicky.AddNamedCommand("configure", rootCmd, cli.ConfigureOptions{}, cli.RunConfigure)
configureCmd.Short = "Interactive wizard to set default model, backend, budget, and safety toggles"
configureCmd.Long = "Run an interactive form to configure ~/.captain.yaml. These defaults are applied to `captain ai prompt`, `captain ai test`, and other AI commands when corresponding flags are not passed."

rootCmd.AddCommand(cli.NewServeCommand(version))

dodCmd := &cobra.Command{
Use: "dod",
Short: "Definition of Done checks",
Expand Down
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ require (
github.com/charmbracelet/huh v1.0.0
github.com/firebase/genkit/go v1.8.0
github.com/flanksource/clicky v1.21.33
github.com/flanksource/commons v1.51.3
github.com/flanksource/clicky/aichat v1.21.34-0.20260630075958-cd55f2f4fce3
github.com/flanksource/commons v1.53.1
github.com/flanksource/sandbox-runtime v1.0.2
github.com/google/dotprompt/go v0.0.0-20260502013637-5cd4a8405ca3
github.com/google/uuid v1.6.0
github.com/invopop/jsonschema v0.13.0
github.com/mattn/go-sqlite3 v1.14.38
github.com/onsi/ginkgo/v2 v2.28.0
github.com/onsi/gomega v1.39.1
Expand Down Expand Up @@ -103,7 +106,6 @@ require (
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
github.com/googleapis/gax-go/v2 v2.18.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
Expand All @@ -112,7 +114,6 @@ require (
github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf // indirect
github.com/hairyhenderson/yaml v0.0.0-20220618171115-2d35fca545ce // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/jsonschema v0.13.0 // indirect
github.com/itchyny/gojq v0.12.19 // indirect
github.com/itchyny/timefmt-go v0.1.8 // indirect
github.com/jeremywohl/flatten v1.0.1 // indirect
Expand All @@ -125,6 +126,7 @@ require (
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
github.com/mailru/easyjson v0.9.1 // indirect
github.com/mark3labs/mcp-go v0.29.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
Expand Down Expand Up @@ -165,6 +167,7 @@ require (
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.7 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
Expand Down
Loading
Loading