FORG + Claude Code: Deep Integration Guide
Everything you need to know about connecting FORG to Claude Code. What data flows, how session tracking works, how to configure hooks, and how to attribute costs to individual developers and projects.
How the Integration Works
FORG integrates with Claude Code via the hooks system. Claude Code exposes 7 hook event types: PostToolUse, PreCompact,PreToolUse, SessionEnd, SessionStart,Stop, and UserPromptSubmit. FORG uses all seven.
When Claude Code fires a hook event, it invokes a shell script with the event payload as JSON on stdin. FORG's agent binary reads that payload, extracts the metadata (tokens, cost, model, latency), and emits a signal to the Rule Engine. The entire path adds <2ms to the hook execution time.
Critically: FORG reads the metadata from the event, not the payload. When a PostToolUse event fires for an LLM call, the event contains usage statistics — not the prompt or completion content. FORG never touches the conversation content.
Prerequisites
- FORG agent installed:
npm install -g forg-agent - Active FORG license (Solo plan or higher)
- Claude Code installed and authenticated
- macOS, Linux, or Windows (WSL2)
Step 1: Install and Activate
# Install the FORG agent
npm install -g forg-agent
# Verify installation
forg --version
# Activate with your license key
# (Get yours at forg.pro/dashboard/license)
forg activate lic_a1b2c3d4e5f6a7b8c9d0
# The activation process:
# 1. Verifies your license with the License Worker
# 2. Derives a session key using HKDF-SHA256
# 3. Stores the bundle in OS-native keystore
# (macOS Keychain / Linux libsecret / Windows DPAPI)
# 4. Configures Claude Code hooks automaticallyAfter activation, run forg status to verify:
$ forg status
FORG Agent v3.0.3
License: lic_a1b2c3... [active]
Plan: Solo
Adapters: claude-code [active]
Signals: 247 emitted, 0 failed
Last emit: 2s ago
Dashboard: forg.pro/dashboardStep 2: Verify Hook Installation
FORG automatically writes to your Claude Code settings file at~/.claude/settings.json. Check that the hooks are present:
$ cat ~/.claude/settings.json | jq '.hooks'
{
"PostToolUse": [
{
"matcher": "Bash|Write|Edit|Read",
"hooks": [
{
"type": "command",
"command": "forg emit --event PostToolUse"
}
]
}
],
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "forg emit --event SessionStart"
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "forg emit --event SessionEnd"
}
]
}
]
// ... all 7 event types
}All hooks are marked _forg_managed in the hook metadata. If you have a pre-existing custom ~/.claude/statusline.sh, FORG will detect it and warn you at activation — it won't overwrite it.
Step 3: Configure Dimensions
Dimensions are the metadata fields that let you slice your usage data by developer, project, team, and environment. Configure them in~/.forg/config.yaml:
# ~/.forg/config.yaml
dimensions:
user: "${USER}@yourcompany.com" # auto-detected from git config
team: "backend" # your team name
environment: "development" # development, staging, production
# Per-project overrides in .forg/project.yaml at repo root
# project: "backend-api"
# team: "backend"
# environment: "development"For teams, the recommended setup is:
- Each developer sets their
userdimension to their work email - Each repo has a
.forg/project.yamlat the root withprojectandteamset - FORG auto-detects the
environmentfrom git branch name (main/master → production, develop → staging, other → development)
# .forg/project.yaml (checked in at repo root)
project: "payment-service"
team: "payments"
# environment auto-detected from branchWhat Data Flows: A Signal Walkthrough
Let's trace exactly what happens when you run a Claude Code session.
Session start: Claude Code fires SessionStart. FORG generates a sess_ prefixed UUID and opens a session record. No API call to Claude has been made yet.
// SessionStart signal
{
"event": "SessionStart",
"session_id": "sess_01hwxyzabc123",
"ts": 1716840000000,
"adapter": "claude-code",
"dimensions": {
"user": "alice@company.com",
"project": "payment-service",
"team": "payments",
"environment": "development"
}
}After each LLM call: PostToolUse fires with usage statistics. This is where the token and cost data flows:
// PostToolUse signal (after an LLM call)
{
"event": "PostToolUse",
"session_id": "sess_01hwxyzabc123",
"ts": 1716840045000,
"adapter": "claude-code",
"model": "claude-sonnet-4-5",
"tokens": {
"input": 2847,
"output": 412,
"cache_read": 1200,
"cache_write": 0
},
"cost_usd": 0.00892,
"latency_ms": { "ttft": 312, "total": 1847 },
"dimensions": { ... }
}Session end: SessionEnd fires when you close Claude Code or explicitly end the session. FORG closes the session record and computes session-level aggregates (total tokens, total cost, duration, call count).
Session Tracking and Attribution
FORG uses session IDs to group all API calls in a single Claude Code session. This gives you session-level analytics: cost per session, tokens per session, duration, and whether sessions ended cleanly or were abandoned (idle timeout).
In the FORG dashboard, the Sessions view shows:
- All active and recent sessions across your team
- Per-session cost, tokens, and duration
- Sessions that hit budget rules (highlighted)
- Abandoned sessions (terminated by idle timeout vs. explicit end)
- Session cost by developer, project, and day
Cost Attribution
With dimensions configured correctly, you can answer:
// Example FORG Atlas queries once you have 30 days of data:
"What is our total AI spend by team this month?"
→ Backend: $340, Frontend: $180, DevOps: $95
"Which project has the highest cost per session?"
→ payment-service: $0.47/session (high context)
"Which developer has the most sessions per day?"
→ alice: 12 sessions/day (avg), bob: 8, charlie: 6
"What percentage of our spend is going to production?"
→ 3% (environment=production), 89% development, 8% CITroubleshooting Common Issues
Signals not appearing in dashboard
# Check agent status
forg status
# Tail signals in real-time
forg tail
# Check for errors
forg logs --last=50
# Force re-emit any pending signals
forg flushHooks not firing
# Verify hooks are installed
cat ~/.claude/settings.json | jq '.hooks | keys'
# Re-install hooks (won't overwrite custom hooks)
forg install-hooks --adapter=claude-code
# Test a hook manually
echo '{"event":"SessionStart"}' | forg emit --event SessionStart --stdinMultiple machines
Your license supports up to 3 machines on the Solo plan (unlimited on Team+). Run forg activate on each machine with the same license key. Session IDs are globally unique across machines.
What's Next
Once you have a week of data flowing, explore the FORG dashboard:
- Observe tab: Signal timeline, session view, cost breakdown by model/user/project
- Control tab: Create your first budget rule, test it in warn-only mode
- Optimize tab: Cost intelligence insights, FORG Atlas queries
The FORG docs have reference documentation for every config option, rule type, and API endpoint. Join our Discord if you run into anything.