The production harness for Claude Code. Turn Claude Code into a managed fleet — with smart profiles that shift mid-session, guardrails, context intelligence, and real-time broadcast messaging across every active session.
Full documentation: the-cloud-clockwork.github.io/agentihooks
graph LR
A["Identity<br/>Who your agents are"] --> E["AgentiHooks"]
B["Guardrails<br/>What keeps them safe"] --> E
C["Context Intelligence<br/>What keeps them sharp"] --> E
D["Fleet Command<br/>Talk to your entire fleet"] --> E
One command transforms your agent's entire personality, permissions, and toolset.
agentihooks init --profile coding,anton # chain profiles
agentihooks settings-profile admin # swap permissions without touching persona
agentihooks init --local --profile infra # per-repo identity- Profile chaining — comma-separated profiles merge left-to-right (rules accumulate, settings deep-merge, CLAUDE.md concatenates)
- Two-axis model — persona (rules/CLAUDE.md) and settings (permissions/MCP) are independent layers
- Bundle system — external repos of profiles, auto-discovered via
agentihooks bundle link - Built-in profiles:
default(auto mode),coding(acceptEdits),admin(bypassPermissions) - Live rule refresh —
agentihooks refresh-rulespushes rule updates into every running Claude session without restart. One-shot per session, session-snapshotted so new sessions don't re-consume.
9+ guardrails active by default. Your fleet operates within boundaries you set.
| Guardrail | What it does |
|---|---|
| Secrets — two-tier | Hard-block on Write/Edit/Bash-to-file containing secrets; inline Bash args scan + log + note only (operator-managed transcript) |
| Branch + PR guard | Default-deny branch creation and gh pr create; unlocked per-turn (branch) or per-session (PR) by operator signal phrases |
| Prod lockdown | Default-deny gh pr merge main, release.yml, :latest/:prod/:stable image tags; session-scoped unlock via release/hotfix signals |
| Controls toggle (bypass mode) | Operator phrase disable controls flips a session-wide bypass that lifts branch/PR/release-merge/hotfix/non-main-force-push gates at once; subagents inherit; HARD FLOOR (push-to-main, commit-on-main, secrets-in-files) stays enforced; restored by enable controls or SessionEnd |
| Retry breaker | Soft directive at N=5 (launch error-researcher agents) → hard block at N=10 on repeated identical failures |
| Dependency banner | Visible banner on every pip/npm/cargo/uv/poetry/apt/brew install — supply chain audit surface |
| Version guard | Blocks AI from editing version fields in manifests |
| CLAUDE.md sanity | Prevents bloat past configurable line limit |
| MCP surface area | Warns when too many tools are loaded |
| Bash output filter | Truncates verbose output to save tokens |
| File read dedup | Blocks redundant re-reads of unchanged files |
LLMs lose focus on early instructions as conversations grow. AgentiHooks defeats attention decay.
- Context refresh — re-injects rules every 20 turns and CLAUDE.md every 40 turns
- Priority frontmatter — critical rules load first within the 8000-char budget
- Token compression — 4 levels (off/light/standard/aggressive) with safety-preserving protection mask
- Tool memory — past errors injected so agents don't repeat mistakes
- Brain adapter — pluggable source that pumps knowledge (hot arcs, operational memory) into agents via broadcast channels
- Context audit — tracks what's being injected and how much budget is used
# In ~/.agentihooks/.env
CONTEXT_REFRESH_COMPRESSION=standard # default
CONTEXT_COMPRESSION_SCOPE=all # compress all injectionsFull docs: Context Intelligence
No other tool does this. Send messages to every active Claude Code session simultaneously — like a PA system for your AI workforce. Now with channels for targeted delivery — subscribe agents to topics, and only the right sessions hear the right messages.
# Manual — full control
agentihooks broadcast "Deploy freeze until 3am" -s alert -t 8h
agentihooks broadcast "STOP ALL WRITES" -s critical -t 15m
# AI-assisted — describe intent in plain English
agentihooks broadcast emit "production incident, all agents stop deploying"
agentihooks broadcast emit "clear all broadcasts"| Severity | Delivery | Default TTL | Use case |
|---|---|---|---|
info |
Once per session | 4 hours | Reminders, FYI notices |
alert |
Every user turn | 1 hour | Deploy freezes, degraded services |
critical |
Every turn + every tool call | 30 min | Incidents, immediate stops |
emit is sandboxed: Claude Haiku can only run agentihooks broadcast commands — all other tools are disallowed.
Requirement: uv must be installed.
git clone https://github.com/The-Cloud-Clockwork/agentihooks
cd agentihooks
# 1. Create the dedicated venv and install everything
uv venv ~/.agentihooks/.venv
uv pip install --python ~/.agentihooks/.venv/bin/python -e ".[all]"
# 2. Install hooks + settings + MCP into ~/.claude
agentihooks initagentihooks init wires hooks into ~/.claude/settings.json, symlinks skills/agents/commands/rules, merges MCP servers into ~/.claude.json, installs the CLI globally, and starts the sync daemon. Re-run any time — it is idempotent.
agentihooks sessions shows every running Claude Code session at a glance — session names from /rename, accurate lifetimes, and reopen by index for crash recovery.
Claude Code
|
|-- Hook Events (stdin JSON) --> python -m hooks --> hook_manager.py
| SessionStart, PreToolUse, |
| PostToolUse, Stop, ... |-- context refresh + compression
| (10 events total) |-- guardrails pipeline
| |-- broadcast delivery
| |-- transcript logging
|
|-- statusLine (native setting) --> python -m hooks.statusline
| pipes JSON on every turn --> 2-3 line status bar
|
+-- MCP Tools --> python -m hooks.mcp --> category modules
aws, email, messaging, --> hooks/integrations/*
database, compute, ...
# Install / configure
agentihooks init # global install with default profile
agentihooks init --profile coding,anton # chain profiles
agentihooks init --local --profile infra # per-repo config
agentihooks settings-profile admin # quick-switch settings layer
# Fleet messaging
agentihooks broadcast "msg" # send info broadcast
agentihooks broadcast "msg" -s critical # critical severity
agentihooks broadcast emit "natural lang" # AI-assisted
agentihooks broadcast --list # active broadcasts
agentihooks broadcast --clear # clear all
# Launch claude with profile flags
agentihooks claude # reads profile.yml -> CLI flags
agenti # alias (after source ~/.bashrc)
# Bundle management
agentihooks bundle link ~/dev/my-tools # link a bundle
agentihooks bundle pull # update linked bundle
# Link an external profile dir into the chain
agentihooks link-profile link ~/dev/brain-profile # auto-appends to chain + re-installs
agentihooks link-profile link ~/dev/brain --name br # disambiguate name on collision
agentihooks link-profile list # show all linked external profiles
agentihooks link-profile unlink brain-profile # remove from chain + sweep symlinks
# Runtime overlays (mid-session profile shifting)
agentihooks overlay list # available overlays for current base
agentihooks overlay add patch-mode # activate overlay
agentihooks overlay remove patch-mode # deactivate overlay
agentihooks overlay clear # remove all overlays
# Broadcast channels (targeted messaging)
agentihooks channel publish brain "msg" # publish to a channel
agentihooks channel list # active channels + message counts
agentihooks channel subscribe brain # subscribe CWD project
agentihooks channel unsubscribe brain # unsubscribe CWD project
# Brain adapter (knowledge injection)
agentihooks brain status # source type, entries, refresh state
agentihooks brain refresh # force re-read + republish
# Live rule refresh (push rule updates into running sessions)
agentihooks refresh-rules --dry-run # preview payload + target session IDs
agentihooks refresh-rules # one-shot push to all alive sessions
agentihooks refresh-rules --clear # cancel a pending marker
# Session registry (crash recovery + session picker)
agentihooks sessions # list recent sessions with NAME + AGE columns
agentihooks sessions reopen <IDX> # reopen by index from the list
agentihooks sessions backfill # seed registry from JSONL transcripts
# Diagnostics
agentihooks status # full system health
agentihooks lint-claude [path] # CLAUDE.md token cost analysis
agentihooks mcp report # MCP surface area
# Daemon
agentihooks daemon start|stop|status|logs # sync daemon
# Memory mirror (cross-machine auto-memory sync — opt-in, role-based, by-project layout)
# Roles (v4): off / consumer / offline / contributor / authority.
# Set MEMORY_MIRROR_ROLE in ~/.agentihooks/.env. One authority per fleet.
agentihooks memory-sync install # build gitfoam + seed main + init mirror + start daemon (skips gitfoam for consumer)
agentihooks memory-sync status # role, mode, config, binary path, PID
agentihooks memory-sync sync-now # one manual tick (snapshot + fetch main + merge)
agentihooks memory-sync propose [--auto-merge] # PR from gitfoam/<host>/main → main
agentihooks memory-sync sweep-branches # prune merged + idle branches (default 15d)
agentihooks memory-sync migrate-layout [--confirm] # one-off: rewrite main to v3 by-project/ layout
agentihooks memory-sync start|stop # gitfoam daemon lifecycle
agentihooks memory-sync uninstall [--purge] # stop daemon (+ optional mirror rm)
# Utilities
agentihooks ignore [path] # create .claudeignore
agentihooks --list-profiles # available profiles
agentihooks --query # active profile name
agentihooks uninstall [--yes] # remove everything- Links bundle (if
--bundleprovided) - Merges settings:
settings.base.json-> profile overrides -> settings-profile overlay -> OTEL config - Symlinks skills, agents, commands, and rules (3-layer merge, additive across chain)
- Writes
CLAUDE.mdto~/.claude/CLAUDE.md - Installs MCP servers (hooks-utils + bundle + profile)
- Applies hierarchy-aware MCP blacklist to all registered projects
- Prunes orphaned MCP servers
- Installs CLI globally via
uv tool - Restarts sync daemon
- Writes bashrc block (
agentienvshell function +agentialias)
Profiles mirror the Claude Code project structure:
profiles/<name>/
|-- CLAUDE.md # system prompt (-> ~/.claude/CLAUDE.md)
|-- profile.yml # agentihooks metadata + claude flags
+-- .claude/
|-- settings.overrides.json # merged into ~/.claude/settings.json
|-- .mcp.json # profile MCP servers
|-- skills/ # -> ~/.claude/skills/
|-- agents/ # -> ~/.claude/agents/
|-- commands/ # -> ~/.claude/commands/
+-- rules/ # -> ~/.claude/rules/
Built-in profiles: default (auto), coding (acceptEdits), admin (bypassPermissions). Bundle profiles are discovered automatically.
3-layer merge: agentihooks built-in -> bundle global .claude/ -> profile-specific .claude/. Applies to skills, agents, commands, rules, and MCP servers.
Profile chaining: agentihooks init --profile coding,anton applies each profile sequentially — hooks append, CLAUDE.md concatenates, rules/skills accumulate additively.
Runtime overlays — profiles that shift mid-session:
Your agent is running on anton. A service breaks. Instead of restarting:
agent calls → overlay_add("patch-mode")
Next turn, the agent has patch-mode rules layered on top — surgical mode, investigation-first, operator-gated commits. It fixes the service, operator validates, then:
agent calls → overlay_remove("patch-mode")
Back to anton. Full autonomy. Image rebuild in parallel. Zero session restart, zero context loss. The base profile's allowedOverlays field controls which overlays agents can activate — no escalation to profiles they weren't designed for.
This is a smart profile system — agents don't just have identities, they shift between complementary modes like a musician moving between tension and release. Full docs: Runtime Overlays
Settings profiles (two-axis model): Control settings independently from persona:
agentihooks init --profile anton --settings-profile admin
agentihooks settings-profile admin # quick-switch
agentihooks settings-profile --clear # revert10 lifecycle events, all handled by python -m hooks:
| Event | Key behavior |
|---|---|
SessionStart |
Register session, inject context, brain injection, deliver broadcasts, MCP warnings |
PreToolUse |
Secrets scan, branch/version guard, retry breaker, critical broadcasts |
PostToolUse |
Bash output filtering, file dedup, tool error recording |
UserPromptSubmit |
Secrets scan, overlay injection, brain refresh, context refresh, channel-filtered broadcast delivery |
Stop |
Transcript scan, auto-memory, cost metrics |
SessionEnd |
Deregister session, clear caches, log summary |
SubagentStop |
Subagent transcript logging |
Notification |
Log notifications |
PreCompact |
Log before compaction |
PermissionRequest |
Log permission requests |
All configuration in .env files in ~/.agentihooks/. Key variables:
| Variable | Default | Description |
|---|---|---|
CONTEXT_REFRESH_COMPRESSION |
standard |
Token compression level |
CONTEXT_COMPRESSION_SCOPE |
refresh |
Scope: refresh or all |
CONTEXT_REFRESH_INTERVAL |
20 |
Re-inject rules every N turns |
BROADCAST_ENABLED |
true |
Fleet messaging master switch |
BROADCAST_CRITICAL_ON_PRETOOL |
false |
Re-inject critical broadcasts on every PreToolUse (default off — alerts still land on UserPromptSubmit) |
BROADCAST_PRETOOL_MIN_SEVERITY |
critical |
Minimum severity for PreToolUse re-injection. alert widens it. |
BROADCAST_MAX_BYTES_PRETOOL |
0 |
PreToolUse banner byte cap. 0 = no cap. Set >0 to opt in to truncation under Claude Code's 10K hook output limit. |
BROADCAST_MAX_BYTES_PROMPT |
0 |
UserPromptSubmit banner byte cap. Same semantics. |
CI_MANIFESTO_MAX_BYTES |
0 |
CI manifesto inject byte cap. 0 = full doctrine ships through. Set >0 (e.g. 7500) to truncate with a "Read full file at <path>" footer. |
TOKEN_CONTROL_ENABLED |
true |
Token control layer master switch |
BASH_FILTER_ENABLED |
true |
Truncate verbose bash output |
FILE_READ_CACHE_ENABLED |
true |
Block redundant file re-reads |
OVERLAY_INJECTION_ENABLED |
true |
Mid-session overlay profile injection |
BRAIN_ENABLED |
false |
Brain adapter master switch |
BRAIN_URL |
"" |
Remote brain HTTP endpoint (kb-router). When set, hooks fetch /feed, /signal, post /marker instead of reading the filesystem. |
BRAIN_HTTP_TOKEN |
"" |
Bearer token for BRAIN_URL. Falls back to KB_ROUTER_TOKEN. |
BRAIN_SOURCE_PATH |
~/.agentihooks/brain |
Filesystem fallback when BRAIN_URL unset. |
BRAIN_CHANNEL |
brain |
Broadcast channel for brain content |
BRAIN_REFRESH_INTERVAL |
30 |
Re-read brain source every N turns |
AMYGDALA_ENABLED |
false |
Active-signal injection (uses BRAIN_URL /signal). |
BRAIN_WRITER_ENABLED |
false |
POST /marker on Stop / SubagentStop. |
Complete table: Configuration Reference
Claude Code injects hook stdout (and any hookSpecificOutput.additionalContext)
into the model's context up to a documented 10,000-character hard cap.
Beyond the cap, the harness silently writes the body to a temp file and the
model receives a filepath instead of the content. If your SessionStart or
UserPromptSubmit injection accumulates above 10K, it is silently lost.
AgentiHooks does not enforce a default cap — full content ships through so agents have the most context possible. To audit what each event actually emits and whether anything is over the limit, run:
agentihooks doctor --debug-hookIf you stack many injections (CI manifesto + brain feed + amygdala + custom
overlays + tool memory), use the *_MAX_BYTES knobs above to cap the
biggest contributors and leave headroom for the rest.
To wire a Claude Code session into a brain stack you already deployed
(e.g. via agentibrain-kernel's docker compose or helm charts), drop the
following four lines into ~/.agentihooks/.env:
BRAIN_URL=http://<your-kb-router-host>:<port>
BRAIN_HTTP_TOKEN=<KB_ROUTER_TOKEN from your bootstrap>
BRAIN_ENABLED=true
AMYGDALA_ENABLED=true
# optional — write back markers from this session
BRAIN_WRITER_ENABLED=trueRestart your Claude Code session. The hook stack will fetch hot arcs + active signals on every prompt and inject them as broadcast banners. No profile install required — works alongside any profile (or none).
agentihooks init --local # per-repo config for current directory
agentihooks init --local --profile coding # override profile for this projectReads .agentihooks.json from repo root and generates .claude/settings.local.json (per-project permissions, MCP whitelist, env). The prompt rendered from the profile chain lives only in the global ~/.claude/CLAUDE.md — per-project .claude/CLAUDE.local.md is no longer generated, and any pre-existing copy is removed on init.
Claude Code's auto-memory at ~/.claude/projects/<project>/memory/ is machine-local.
This feature mirrors only the memory/ subtrees across every machine in your
fleet via a private GitHub repo. Transcripts, session JSONLs, and ctx_refresh
snapshots are excluded by a unit-tested rsync filter.
How it works
machine A machine B
───────── ─────────
~/.claude/projects/*/memory/ ~/.claude/projects/*/memory/
│ rsync (memory-only) ▲ merge (.conflict sibling on divergence)
▼ │
~/.agentihooks/memory-mirror/ ~/.agentihooks/memory-mirror/
│ gitfoam force-push 500ms │ git fetch origin main every 60s
▼ │
origin/gitfoam/A/main origin/main ← merged by operator via PR
│ ▲
└── gh pr create --base main ───────┘
(agentihooks memory-sync propose)
Every machine still writes to its own gitfoam/<hostname>/main branch via
gitfoam (Rust daemon, 500ms
force-push, built-in secrets scanning). Consumers read origin/main only.
Promotion from a machine branch to main is a PR — agentihooks memory-sync propose opens it via gh pr create and optionally auto-merges when clean.
This gives you a review gate against bad or malicious memory without taking
away each agent's ability to accumulate its own learnings.
Identity-keyed layout (v3). The mirror stores memory under by-project/<key>/memory/
where <key> is the repo or agent name — not the absolute path. An identity
resolver reverse-walks each ~/.claude/projects/<encoded>/ dir to find the
package or agent boundary (agent.yml > pyproject.toml/Cargo.toml/package.json/go.mod
.git) and uses its basename as the key. So:
- Laptop
/home/iamroot/dev/tcc-ecosystem/agenticore→ keyagenticore - Fleet pod
/app/agenticore→ keyagenticore(same key, memory pools!) - Agent
.../agentihub/agents/finops/package→ keyfinops(skips pastpackage/) - Hyphenated repos like
tcc-toolbeltstay intact (the resolver reads the real FS, not the encoded name) - Unresolvable paths fall back to
_unmapped/<encoded>/so nothing is lost.
Enable (three commands)
cat >> ~/.agentihooks/.env <<'EOF'
MEMORY_MIRROR_MODE=write
MEMORY_MIRROR_REMOTE=git@github.com:YOU/claude-memory.git
EOF
agentihooks memory-sync install # seeds origin/main on first runPromote a machine's learnings to main
agentihooks memory-sync propose # open a PR; review + merge on GitHub
agentihooks memory-sync propose --auto-merge # arm gh pr merge --auto --squashVerify
agentihooks memory-sync status
# mode: write
# remote: git@github.com:YOU/claude-memory.git
# mirror: /home/you/.agentihooks/memory-mirror
# prefix: gitfoam
# interval: 60s
# sweep idle: 15d
# gitfoam: /home/you/.cargo/bin/gitfoam
# daemon: running (PID 12345)Conflict handling
When local state and origin/main diverge on the same file, the merge step
writes the incoming version to <name>.conflict-<host>-<epoch><ext> next to
the target — the local file is never overwritten. Resolve via /memory,
delete the conflict file when done.
Modes
off(default) — dormantwrite— full participant (push + pull main)write-local-only— air-gapped contributor (push only, never pulls)
Housekeeping
agentihooks memory-sync sweep-branches deletes remote branches already merged
into main and idle longer than MEMORY_MIRROR_SWEEP_IDLE_DAYS (default 15).
Unmerged branches are never touched. Cron-safe.
Opt-in, opt-out, purge
Nothing happens unless MEMORY_MIRROR_MODE != off and MEMORY_MIRROR_REMOTE
is set. Rollback with agentihooks memory-sync uninstall --purge.
Full guide: docs/getting-started/memory-mirror.md
Everything user-specific lives in ~/.agentihooks/. To move to a new machine:
uv venv ~/.agentihooks/.venv
uv pip install --python ~/.agentihooks/.venv/bin/python -e ".[all]"
agentihooks init| Project | Description |
|---|---|
| agenticore | Claude Code runner and orchestrator |
| agentibridge | MCP server for session persistence and remote control |
See LICENSE for details.
