An agentic coding runtime in Go β multi-provider, MCP-native, plugin-extensible.
β οΈ Experimental. The code compiles and passesgo vet, but most ported features have not been manually validated. Use at your own risk. Contributions and testing are very welcome.
claw-code-go is a Go-native runtime for Claude Codeβstyle agentic coding sessions: a streaming model loop, a permissions engine, a tool registry, MCP integration, plugins, sandboxing, and persistence β all callable from Go and runnable as a single CLI binary.
It is a fork of daolmedo/claw-code-go (the original Go port) augmented with features ingested from ultraworkers/claw-code (a Rust port that emerged after the source leak): hooks, plugins, MCP lifecycle + OAuth, sandbox, classifier-driven permissions, multi-provider routing, prompt caching, OTLP telemetry, and more.
The Rust β Go porting was driven end-to-end by Iterion, a workflow engine for multi-agent LLM pipelines. See How this was built below for the run stats.
Five providers are wired through a unified <provider>/<model-id> addressing scheme (e.g. openai/gpt-5.4-mini, anthropic/claude-sonnet-4-6, bedrock/anthropic.claude-sonnet-4-6):
- Anthropic & OpenAI β validated end-to-end (OpenAI routes through both
/v1/chat/completionsand/v1/responsesfor reasoning + tools). - AWS Bedrock, Google Vertex AI, Azure AI Foundry β real implementations on top of the official SDKs, with live smoke tests under build tag
live. - Capability-aware routing, fallback chains, and per-provider
reasoning_efforttranslation ininternal/apikit. - Typed
api.APIError(StatusCode,Retryable) so callers drive retry classification viaerrors.As.
A rich tool surface re-exported from pkg/api/tools β pair of XxxTool() api.Tool (schema) + ExecuteXxx(ctx, input) (runtime):
- π File I/O β
ReadFile,WriteFile,FileEdit,Glob,Grep,ReadImage,NotebookEdit, PDF extraction. - π» Execution β
Bash(with workspace validation),WebFetch(size cap, header filtering). - π±οΈ Computer use β full Anthropic action surface (
screenshot,*_click,type,key,mouse_move,cursor_position,left_click_drag) backed byxdotool+ ImageMagick on Linux/X11. Returns typedErrComputerUseUnavailablewhen display/binaries are missing. - π£οΈ Interaction β
AskUserwith pluggableAskerinterface (StdinAsker,ProgrammaticAsker,TUIAsker) and structured options;RemoteTriggerHTTP wrapper with timeout, body cap, header allow/deny lists, CRLF guard. - π€ Multi-agent β
Worker*,Team*,Task*,Cron*tools (create / get / list / update / stop) for spawning isolated agents, scheduling, and parallel orchestration. - π MCP & LSP β
ListMcpResources,ReadMcpResource,McpAuth, plus first-class LSP queries. - π§ Workflow β
TodoWrite,Sleep,StructuredOutput,REPL,Skill(slash command dispatch),ToolSearch(discover tools by description), plan-mode toggles.
| Mode | Behavior |
|---|---|
ModeAllow |
Permits all operations without prompting. |
ModePrompt |
Consults the ruleset; asks the prompter when no rule matches. |
ModeReadOnly |
Allows read-only operations only; denies writes/exec. |
ModeWorkspaceWrite |
Allows writes within the workspace directory; denies outside. |
ModeDangerFullAccess |
Allows arbitrary command execution and system access. |
ModeDontAsk |
Strict allow-list β never prompts; denies anything not explicitly listed. |
ModeAuto |
Delegates to a Classifier (default safe-list permits read-only ops, prompts on writes). |
Pluggable classifiers in internal/permissions/:
RuleClassifierβ rule-based safe-list.LLMClassifierβ small-model (Haiku-backed) classifier with TTL+FIFO decision cache (1024 entries, 1h TTL by default) and fail-safe-to-Ask invariant on transport errors. Untrusted args are wrapped in<tool_invocation>tags so payloads cannot hijack the decision.
Programmatic Runner with sequential dispatch and "first non-Continue wins" semantics:
| Tool events | Session events | Plugin events |
|---|---|---|
PreToolUse |
UserPromptSubmit |
PrePluginInstall |
PostToolUse |
PreCompact |
PostPluginInstall |
PostToolUseFailure |
PostCompact |
PrePluginUninstall |
Stop |
PostPluginUninstall |
Subprocess shell-script hooks (hooks/runner.go) cover the same lifecycle for ops who prefer scripts β Unix and Windows exec adapters, exec.CommandContext so cancelling the conversation kills any in-flight hook script.
Full Model Context Protocol support in internal/mcp/:
- π‘ Transports β stdio, SSE, WebSocket. RPC protocol layer is shared.
- π OAuth Authorization Code + PKCE broker with atomic disk-backed token storage. RFC 6749 / 7636 compliant: loopback callback for browser flows, automatic refresh near expiry, typed
ErrReauthRequiredfor headless contexts (where opening a browser is impossible). Bearer header injection viaTransportConfig.AuthFunc. - Public faΓ§ade:
pkg/api/mcp/oauthre-exportsBroker,NewBroker,Token,Storage,ErrReauthRequired.
Local plugin manager in plugin/ with install / uninstall / list / dispatch, plus a remote marketplace with end-to-end verification:
- πΊοΈ Two-tier layout β
<base>/index.jsonadvertises plugins;<base>/<name>/manifest.jsondescribes each. - π SHA-256 + cosign signature verification, delegated to a single path so the slash command and the public API agree.
- π‘οΈ HTTPS-only by default, opt-in
--insecure-marketplaceescape, 1 MiB metadata size cap. - πͺ Lifecycle hooks fire around every install/uninstall (
Pre*can block,Post*always fires with error info on failure). - π§° CLI:
claw-code-go plugin install --marketplace <url> [--require-signed] <name>. Env vars:CLAW_MARKETPLACE_URL,CLAW_PLUGIN_PUBLIC_KEY,CLAW_REQUIRE_SIGNED.
internal/runtime/sandbox/ provides per-session isolation with graceful fallback on non-Linux hosts or inside containers:
- Filesystem modes β
Off,WorkspaceOnly,AllowList. - Namespaces β PID, UTS, IPC, network restrictions on Linux.
- Auto-detection β recognizes
/.dockerenv,/run/.containerenv, and cgroup state to skip nesting. - Status reporting via the runtime so callers can observe whether isolation is active.
internal/runtime/ persists every turn as JSONL events (legacy single-JSON sessions auto-loaded via LoadSessionAuto):
- π Fork / inherit sessions to preserve KV cache across related phases (this is what made the Iterion port converge fast).
- β―οΈ Resume any session by ID,
latest, or path. - π Timeline subcommand renders chronological event view (
pretty|json|md). - π§Ή Compaction with
Pre/PostCompacthooks, summary compression, and recent-N-turns preservation.
Anthropic-native cache_control breakpoint manager with session-scoped fingerprints, cache-break detection (unexpected drops in cache_read_input_tokens), and persistent stats (hits / misses / writes / unexpected breaks). Cache-aware retry logic in internal/apikit/retry.go.
Two exporters built on the official OpenTelemetry SDKs:
- π¨
internal/apikit/telemetry/otlpβ OTLP/HTTP-JSON (CLAWD_OTLP_HTTP_ENDPOINT). - π¨
internal/apikit/telemetry/otlpgrpcβ OTLP/gRPC viaotlploggrpc(CLAWD_OTLP_GRPC_ENDPOINT,CLAWD_OTLP_GRPC_INSECURE,CLAWD_OTLP_GRPC_HEADERS). - π·οΈ Standard resource attributes:
service.name=claw-code-go(override withCLAWD_SERVICE_NAME),service.versionviaCLAWD_SERVICE_VERSION. β οΈ The legacyITERION_*env vars are deprecated β useCLAWD_*.
internal/tui/ ships a Bubble Tea-backed interface: markdown rendering, syntax-highlighted code blocks, themes, REPL history, logo. The same renderer powers the timeline subcommand.
A first-class LSP tool (internal/lsp/ + pkg/api/lsp) lets the model query language servers for diagnostics, hover, and definitions during a coding session.
Beyond single-agent loops, runtime primitives in internal/runtime/ support multi-agent fleets:
- π· Workers β observable state machine (
SpawningβTrustRequiredβReadyForPromptβRunningβFinished/Failed) with failure classification (TrustGate, PromptDelivery, Protocol, Provider). - π₯ Teams β sub-agent registry and coordination primitives.
- ποΈ Tasks β background task lifecycle (
create/get/list/update/output/stop). - β° Cron β scheduled recurring tasks.
- π¦ Lanes / Policies / Recovery β declarative rule engine for branch-locked workflows, freshness analysis, and 7 named failure-recovery scenarios.
claw-code-go [--prompt | --repl | --session ID] ...
claw-code-go timeline --session <id> [--format pretty|json|md] [--limit n]
claw-code-go plugin install --marketplace <url> [--require-signed] <name>
claw-code-go dump-manifests [--json]
claw-code-go bootstrap-plan
claw-code-go print-system-prompt [--cwd ...] [--date ...]
claw-code-go resume-session <file> [commands...]
Main-mode flags include --model, --permission-mode, --allowed-tools, --reasoning-effort, --output-format, --session-dir, --work-dir, and --dangerously-skip-permissions.
import (
"context"
"github.com/SocialGouv/claw-code-go/pkg/api"
"github.com/SocialGouv/claw-code-go/pkg/api/tools"
)
defs := []api.Tool{
tools.ReadFileTool(),
tools.WriteFileTool(),
tools.GlobTool(),
tools.GrepTool(),
tools.FileEditTool(),
tools.WebFetchTool(),
tools.BashTool(),
tools.ReadImageTool(),
tools.ComputerUseTool(),
}
// Dispatch a tool call from the model:
out, err := tools.ExecuteReadFile(ctx, map[string]any{"path": "README.md"})ExecuteBash additionally takes a workspace string for command validation (pass "" to skip). The wrapper pins permissions to ModeAllow; gate invocations upstream (e.g. via an Iterion workflow's allowed_tools list).
| Provider | Status | Path |
|---|---|---|
| Anthropic | π’ validated end-to-end | pkg/api/providers/anthropic |
| OpenAI | π’ validated end-to-end (/v1/chat/completions + /v1/responses) |
pkg/api/providers/openai |
| Bedrock | π‘ available, untested in production (built on aws-sdk-go-v2) |
pkg/api/providers/bedrock |
| Vertex AI | π‘ available, untested in production (Google ADC + canonical MapModelID) |
pkg/api/providers/vertex |
| Azure Foundry | π‘ available, untested in production (OpenAI-wire compatible) | pkg/api/providers/foundry |
Each cloud provider ships a smoke test gated by the live Go build tag. The tests skip cleanly when the relevant credentials are not set, so the default go test ./... is unaffected.
# AWS Bedrock β uses the standard AWS SDK credentials chain.
AWS_REGION=us-east-1 \
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... \
BEDROCK_MODEL=anthropic.claude-3-5-sonnet-20241022-v2:0 \
go test -tags live -run TestLiveStreamSmokeBedrock -v ./internal/api/providers/bedrock/...
# Google Vertex AI β uses Application Default Credentials.
GOOGLE_CLOUD_PROJECT=my-project \
GOOGLE_CLOUD_REGION=us-east5 \
GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json \
VERTEX_MODEL=claude-sonnet-4-20250514 \
go test -tags live -run TestLiveStreamSmokeVertex -v ./internal/api/providers/vertex/...
# Azure AI Foundry β api-key auth, or DefaultAzureCredential when key is unset.
AZURE_OPENAI_ENDPOINT=https://my-resource.openai.azure.com \
AZURE_OPENAI_API_KEY=... \
FOUNDRY_MODEL=my-deployment \
go test -tags live -run TestLiveStreamSmokeFoundry -v ./internal/api/providers/foundry/...Each test asserts only that the stream produced at least one text delta and a message_stop event β enough to confirm authentication, request shape, and SSE decoding work end-to-end.
runner := hooks.NewRunner()
runner.Register(hooks.PreToolUse, func(ctx context.Context, hctx hooks.Context) (hooks.Decision, error) {
if hctx.ToolName == "bash" {
return hooks.Decision{Action: hooks.ActionBlock, Reason: "no shell"}, nil
}
return hooks.Decision{Action: hooks.ActionContinue}, nil
})
decision, _ := runner.Fire(ctx, hooks.Context{Event: hooks.PreToolUse, ToolName: "bash"})The runner is wired into internal/runtime/conversation.go; nil runners are a documented no-op.
The Rust-to-Go feature porting was orchestrated by Iterion β a workflow engine for complex multi-agent LLM pipelines, using Claude Code, Codex, and other backends. This repo is the real-world example that drove Iterion's development:
- π rust_to_go_port.iter β the Iterion workflow definition (DSL).
- π rust_to_go_port.md β design decisions, lessons learned, empirical data.
| Metric | Value |
|---|---|
| Refinement runs | 4 (workflow iterated alongside the engine) |
| Outer loop iterations | 25+ batches across all runs |
| Commits added | 48 (47 by Iterion, 1 by Claude Code) |
| Go code generated | 37,995 lines across 173 files + 96 test files |
| New Go packages | 30+ (hooks, plugin, apikit, worker, lane, policy, recovery, sandbox, lsp, task, team, β¦) |
| Feature parity | 100% (37/37 features) |
| Final run | 100% parity in 41 min, single batch, zero fix loops, zero interventions |
| Longest autonomous stretch | 2h25m without human intervention |
| Dual-judge verdicts | 30+ across all runs (Claude + Codex) |
The workflow breaks the porting into dependency-ordered batches. Each batch goes through: plan β implement β simplify β commit β test β parity scan β dual-judge review β fix loop. Session continuity (fork/inherit) preserves KV cache across related phases. A human gate pauses for high-risk batches and auto-approves routine ones. See the full writeup for details on convergence strategies, stagnation detection, and model allocation.
Experimental. The code compiles and passes go vet, but most of it has not been manually tested. The latest commit (Anthropic prompt caching with cache_control breakpoints) was done directly with Claude Code outside the Iterion workflow.
Contributions, testing, and feedback are welcome.
For the running list of changes, see CHANGELOG.md. For the parity matrix versus upstream Claude Code, see docs/parity.md.
- daolmedo/claw-code-go β the original Go port of Claude Code (upstream).
- ultraworkers/claw-code β the Rust port of Claude Code (feature source).
- Iterion β the workflow orchestration engine that performed the porting.
MIT
