Skip to content

SocialGouv/claw-code-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

157 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

claw-code-go

claw-code-go

An agentic coding runtime in Go β€” multi-provider, MCP-native, plugin-extensible.

⚠️ Experimental. The code compiles and passes go vet, but most ported features have not been manually validated. Use at your own risk. Contributions and testing are very welcome.


✨ What is this?

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.


πŸš€ Features

🌐 Multi-provider LLM client

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/completions and /v1/responses for 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_effort translation in internal/apikit.
  • Typed api.APIError (StatusCode, Retryable) so callers drive retry classification via errors.As.

πŸ› οΈ Built-in tools

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 by xdotool + ImageMagick on Linux/X11. Returns typed ErrComputerUseUnavailable when display/binaries are missing.
  • πŸ—£οΈ Interaction β€” AskUser with pluggable Asker interface (StdinAsker, ProgrammaticAsker, TUIAsker) and structured options; RemoteTrigger HTTP 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.

πŸ” Permissions engine β€” 7 modes + pluggable classifier

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.

πŸͺ Lifecycle hooks β€” 11 events, in-process or shell

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.

πŸ”Œ MCP β€” three transports + OAuth

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 ErrReauthRequired for headless contexts (where opening a browser is impossible). Bearer header injection via TransportConfig.AuthFunc.
  • Public faΓ§ade: pkg/api/mcp/oauth re-exports Broker, NewBroker, Token, Storage, ErrReauthRequired.

πŸ“¦ Plugin system + remote marketplace

Local plugin manager in plugin/ with install / uninstall / list / dispatch, plus a remote marketplace with end-to-end verification:

  • πŸ—ΊοΈ Two-tier layout β€” <base>/index.json advertises plugins; <base>/<name>/manifest.json describes 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-marketplace escape, 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.

🧱 Sandbox β€” Linux namespace isolation

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.

πŸ’Ύ Session continuity

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/PostCompact hooks, summary compression, and recent-N-turns preservation.

⚑ Prompt caching

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.

πŸ“‘ Telemetry β€” OTLP/HTTP + OTLP/gRPC

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 via otlploggrpc (CLAWD_OTLP_GRPC_ENDPOINT, CLAWD_OTLP_GRPC_INSECURE, CLAWD_OTLP_GRPC_HEADERS).
  • 🏷️ Standard resource attributes: service.name=claw-code-go (override with CLAWD_SERVICE_NAME), service.version via CLAWD_SERVICE_VERSION.
  • ⚠️ The legacy ITERION_* env vars are deprecated β€” use CLAWD_*.

πŸ–₯️ TUI

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.

🧠 LSP integration

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.

πŸ€– Multi-agent orchestration

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.

🧰 CLI

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.


πŸ”§ Quick start

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).


πŸ“š Reference

Providers

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

Running live provider tests

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.

Lifecycle hooks example

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.


πŸ—οΈ How this was built

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:

Run stats

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)

How the workflow operates

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.


Status

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.

Credits

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors