harness-test

command module
v0.0.0-...-26bf2cd Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2026 License: MIT Imports: 9 Imported by: 0

README

harness-test

Conformance test suite for coding agent CLIs. Tests 15 agents across 4 control modes, 4 API formats, and 7 hook formats.

Verifies: prompt/response, tool calls, hook lifecycle, streaming, model selection, context injection.

Built for belt.sh — connect your agent to skills, knowledge, and tools.

Build Nightly

claude codex copilot droid gemini goose grok hermes kilo kimi kiro omp opencode pi qwen

Compatibility matrix

Agent Version Headless Interactive ACP SDK Hook Format API
Claude Code 2.1.x ✅¹ JSONNested Anthropic
Codex 1.x ✅² JSONNested Responses
Copilot 1.0.x JSONCopilot OpenAI
Droid 0.208.x JSONNested OpenAI
Gemini CLI 0.57.x JSONNested Gemini
Goose 1.48.x JSONNested OpenAI
Grok 1.0.x JSONNested Responses
Hermes 0.19.x YAML OpenAI
Kilo 7.5.x TSPlugin Responses
Kimi Code 1.49.x TOML OpenAI
Kiro JSONNested OpenAI
Oh My Pi 18.x ✅⁴ TSExtension OpenAI
OpenCode 1.18.x TSPlugin Responses
Pi 0.x ✅³ TSExtension OpenAI
Qwen Code 0.22.x JSONNested OpenAI

15/15 headless · 12/15 ACP · 4/15 SDK · 31 mode-tests in CI

¹ claude -p --output-format stream-json — claude's own streaming protocol, not ACP. ² codex exec --experimental-json — JSONL event stream over stdout. ³ pi --mode json — structured JSONL output (provider URL not overridable). ⁴ omp --mode json — Oh My Pi is a Pi fork (bun runtime) with native ACP, plugins, and multi-model roles.

Control modes
Mode Transport What it tests
Headless CLI args + stdout agent -p "prompt" — fast, deterministic
Interactive PTY terminal Full TUI flow: onboarding, typing, /compact, exit
ACP JSON-RPC over stdio Agent Client Protocol — programmatic session control
SDK Agent-specific stdio Claude's --output-format stream-json protocol
ACP protocol support

The ACP driver implements ACP v1 with a handler registry:

Method Direction Handler
initialize client → agent Capability exchange
session/new client → agent Create session (cwd + mcpServers)
session/prompt client → agent Send prompt (fire-and-forget)
session/update agent → client Stream content chunks
session/request_permission agent → client Auto-approve
fs/write_text_file agent → client Write files to disk
fs/read_text_file agent → client Read files from disk
elicitation/create agent → client Auto-confirm
session/close client → agent End session

Use cases

Plugin/hooks testing

You have a product (like belt, an MCP server, or a custom hook system) and need to verify it works inside multiple agents.

docker compose run test --harness all
docker compose run test --harness claude,codex,grok
ACP conformance testing

You're building an editor or app that controls agents via ACP (like Zed, T3 Code).

harness-test --harness copilot,grok,opencode --mode acp
Agent development

You're building a new agent CLI and want to verify your hook/API implementation.

// Add to harness/registry.go
"myagent": {
    Name: "myagent", Binary: "myagent",
    APIFormat: OpenAI,
    HookFormat: JSONNested,
    Events: Events{PromptSubmit: "UserPromptSubmit", Stop: "Stop"},
    HeadlessCmd: []string{"myagent", "-p"},
    HooksInHeadless: true,
    ACPCmd: []string{"myagent", "--acp"},
    HooksInACP: true,
},

Quick start

go build -o harness-test .

# Docker (recommended)
cd tests && docker compose run test --harness claude

# List harnesses
harness-test --list

# Detect installed agents
harness-test --detect
CI
jobs:
  harness:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        harness: [claude, codex, copilot, grok]
    steps:
      - uses: actions/checkout@v4
      - run: |
          docker build -f tests/Dockerfile -t harness-test .
          docker run --rm harness-test --harness ${{ matrix.harness }} --mode headless
Mock server
harness-test --server
# Speaks all 4 API formats on one port:
# POST /v1/chat/completions   (OpenAI)
# POST /v1/responses          (Responses)
# POST /v1/messages           (Anthropic)
# POST /v1beta/...            (Gemini)

What it verifies

Check What it tests
Prompt/response Agent sends a request, mock server responds, agent produces output
Hook events Lifecycle hooks fire (SessionStart, PromptSubmit, PreToolUse, PostToolUse, Stop, PreCompact)
API requests Mock server received requests in the correct format
Streaming Agent uses SSE streaming
Model selection Correct model name in API requests
Tool calls Agent makes tool calls and sends results back
Version Agent binary version is detected and reported

Hook formats

Format Agents Config
JSONNested claude, codex, grok, droid, goose, qwen, gemini settings.json / hooks.json
JSONCopilot copilot hooks.json (v1, bash field)
TOML kimi config.toml
YAML hermes config.yaml
TSExtension pi .ts with pi.on(event, ...)
TSPlugin opencode, kilo .ts exporting plugin object

Architecture

harness-test
├── main.go           CLI entry point
├── harness/
│   ├── harness.go    Harness type definitions
│   ├── registry.go   13 agent configs (pure data)
│   ├── detect.go     5-probe detection
│   └── install.go    Hook config generation
├── runner/
│   ├── runner.go     Test orchestrator (install → config → hooks → run → verify)
│   ├── driver.go     Driver interface
│   ├── acp.go        ACP driver (JSON-RPC, handler registry)
│   ├── protocol.go   JSON-RPC + ACP message types
│   ├── pty.go        PTY driver (terminal sessions)
│   └── checks.go     Verification checks
└── server/
    ├── server.go     Mock LLM server
    ├── chat.go       OpenAI Chat Completions
    ├── responses.go  OpenAI Responses
    ├── anthropic.go  Anthropic Messages
    ├── gemini.go     Gemini generateContent
    └── types.go      Shared types

Each harness is a pure data struct — no per-harness code. Adding a new agent means adding one entry to the registry.

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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