A local daemon that proxies, guards, and observes coding-agent hooks β once, for every agent.
agentd sits between your AI coding agents (Claude Code, Cursor, Codex, Gemini CLI, OpenCode, Kimi Code) and your hook logic. Agents invoke a thin CLI entrypoint; a user-level daemon applies policies, dispatches sync and async pipelines, and returns provider-correct responses. Built on agenthooks for wire compatibility.
Status: v0.0.5 (trajectory stats, session stats). Roadmap history: PROGRESS.md.
- User guide (English) β default (why agentd)
- Π ΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ (ΡΡΡΡΠΊΠΈΠΉ) (Π·Π°ΡΠ΅ΠΌ Π½ΡΠΆΠ΅Π½)
- Keeping docs current: docs/en/maintaining.md
Contributor design and conventions: DESIGN.md, AGENTS.md, CONVENTIONS.md. How to contribute: CONTRIBUTING.md.
Structured verbatim excerpts from primary sources β used when designing provider support, hooks, and conventions. Each tree has its own index and SOURCES.md.
| Tree | Focus |
|---|---|
| research/best-practice | Go best practices (Go β₯ 1.26.7) |
| research/claude-code | Claude Code docs β agent loop, hooks, MCP, settings, skills, plugins, cloud, enterprise |
| research/codex | Codex / ChatGPT Learn docs β sandbox, hooks, MCP, cloud, enterprise |
| research/cursor | Cursor docs β agent loop, hooks, MCP, settings, enterprise |
| research/gemini | Gemini CLI docs (snapshot 2026-08-29) β agent loop, hooks, MCP, settings, skills, extensions, Managed Agents API, Antigravity migration delta |
Stub dirs for other agents (opencode, kimi-code) live under research/ and will fill in the same shape.
Coding-agent hooks are powerful but painful to operationalize:
- Duplicated glue β each provider speaks a slightly different JSON dialect, timeout unit, and failure mode.
- Heavy cold starts β spawning full hook logic on every tool call adds latency.
- Mixed concerns β blocking guards, audit webhooks, and metrics want different lifecycles but share one process.
agentd centralizes hook logic in a long-lived daemon while keeping the agent-facing contract compatible with agenthooks. You configure declarative guards and dispatch routes; the daemon hot-reloads config without re-reading disk on every event.
- Universal hook proxy β one CLI surface (
agentd hook run) for all supported agents - Sync + async + hybrid dispatch β blocking decisions for the agent, fire-and-forget observability in parallel or after sync
- Declarative guards β secrets, shell, MCP, path policies via YAML
- Approvals & temporary blocks β Ask once / approve with TTL; runtime overlay persisted across restarts
- Efficient config reload β in-memory snapshots, fsnotify with debounce; zero config I/O on the hot path
- Cross-platform IPC β gRPC over Unix domain sockets (Linux/macOS) or named pipes (Windows)
- Provider-faithful I/O β stdout/stderr discipline and exit codes handled per agenthooks codecs
- Ops Status β queue depth and async overflow drop counter on
daemon status
| Agent | Hook install target | Entry command | Guide |
|---|---|---|---|
| Claude Code | .claude/settings.json, plugins |
agentd hook run --provider=claude-code |
docs |
| Cursor | .cursor/hooks.json |
agentd hook run --provider=cursor |
docs |
| OpenAI Codex | hooks.json / config.toml |
agentd hook run --provider=codex |
docs |
| Gemini CLI | .gemini/settings.json |
agentd hook run --provider=gemini |
docs |
| OpenCode | .opencode/plugin shim |
agentd hook serve --provider=opencode |
docs |
| Kimi Code | user ~/.kimi-code/config.toml only |
agentd hook run --provider=kimi-code |
docs |
Provider quirks (Ask support, empty stdout, timeouts, install scope): docs/en/providers.md.
Agent (Claude/Cursor/β¦) agentd CLI agentd daemon
β (hook edge) (gRPC + dispatch)
β spawn per event β β
βββββ hook run βββββββββββΊβ decode ββ Invoke βββββββΊβ sync pipeline βββΊ decision
β β async pipeline βββΊ queue β sinks
ββββ encode stdout ββββββββ
βββ JSON + exit code ββββββ
- Hook CLI β decode/encode only; no business logic
- Daemon β routing, guards, forward targets (HTTP, exec, gRPC, logs)
- Config β layered YAML with atomic in-memory snapshots
Details: DESIGN.md
- Go 1.26+ (to build from source)
- A supported coding agent (see table above)
- Linux, macOS, or Windows
go install github.com/macrox-pro/agentd@latestPre-built binaries for linux/darwin/windows are published on GitHub Releases (goreleaser).
Details: docs/en/installation.md.
1. Start the daemon (one instance per user). If ~/.agentd.yaml is missing, start creates a minimal bootstrap automatically:
agentd daemon start
agentd daemon status2. Customize user config (optional β edit ~/.agentd.yaml after start, or create it yourself first):
version: 1
policy:
fail: fail_closed
# offline defaults to fail_open β agents keep working if the daemon is down
guards:
secrets:
enabled: true
action: ask3. Install hooks for your agent (example: Claude Code, project scope):
cd your-repo
agentd install --provider=claude-code --scope=project4. Verify β trigger a tool call in your agent; check daemon status:
agentd daemon status --jsonFor OpenCode, use agentd hook serve --provider=opencode in generated plugin config (see DESIGN.md Β§1).
Full walkthrough: docs/en/getting-started.md.
Configuration merges four layers: defaults β ~/.agentd.yaml β .agentd.yaml (project) β runtime overlay (daemon-written). State (log, runtime overlay, sessions) lives under the state directory, not ~/.agentd/.
Minimal dispatch example (sync guard + async audit):
dispatch:
- name: gate-and-audit
match: { kind: [tool.pre] }
mode: parallel
sync:
- target: builtin
guards: [secrets]
async:
- target: log
level: infoFull schema: docs/en/configuration.md Β· layer/runtime overlay: DESIGN.md Β§7
| Command | Purpose |
|---|---|
agentd daemon start |
Start the user-level daemon |
agentd daemon enable |
Register login autostart (see Operations) |
agentd daemon disable |
Remove login autostart |
agentd daemon stop |
Graceful shutdown |
agentd daemon status |
Health, config generation, queue depth, async drops |
agentd hook run |
Agent entrypoint β blocking hooks |
agentd hook notify |
Codex notify path (async) |
agentd hook serve |
OpenCode NDJSON bridge |
agentd install |
Write agent hook configs (via agenthooks) |
agentd config validate |
Validate YAML offline (CI-friendly) |
agentd config enable FEATURE |
Curated toggles (trajectory, guards) β user/project YAML |
agentd config disable FEATURE |
Turn off a curated toggle |
agentd config get FEATURE |
Effective on/off + winning layer (no runtime) |
agentd config show |
Inspect merged config |
agentd config patch |
Patch runtime overlay (persisted) |
agentd config record-decision |
Record approval after Ask |
agentd dispatch routes |
Show compiled dispatch routes |
agentd session subscribe |
Live trajectory stream (daemon required) |
Trajectory (opt-in): every supported agentβs hooks are traceable on one stream; transcript/thinking depth varies by provider β not βeverything the model sees everywhere.β
| Provider | L2 import |
|---|---|
| claude-code, codex | supported |
| cursor | partial (--path) |
| gemini, opencode, kimi-code | none |
Details: docs/en/trajectory.md Β· DESIGN Β§14.3
Rationale for each command: docs/en/cli.md Β· DESIGN Β§6 (architecture notes)
git clone https://github.com/macrox-pro/agentd.git
cd agentd
make generate # protobuf (requires buf)
make test # go test -race
make lint # golangci-lint + buf lint
go test -tags=integration ./... # optional daemonβhook integrationSee CONTRIBUTING.md and AGENTS.md.
Issues and pull requests are welcome. Please read CONTRIBUTING.md (and AGENTS.md before submitting code).
MIT β see LICENSE.
Hook wire formats and provider compatibility powered by speakeasy-api/agenthooks.
