Monitor Local Coding Agents with Olakai
This skill sets up hooks-based monitoring for local coding agents and teaches you to self-diagnose and repair that monitoring. Every session in a monitored workspace reports activity to Olakai — no SDK code required.
Is this the right skill?
| You want to… | Use |
|--------------|-----|
| Monitor the coding tool itself (Claude Code / Codex / Cursor / Gemini CLI / Antigravity CLI sessions) | this skill |
| Check / fix your own monitoring ("is it working?", "no events") | this skill → Self-healing |
| Roll out monitoring to a whole team/fleet as an Olakai ADMIN | this skill → Admin bulk-provisioning |
| Instrument your own agent's source code with the @olakai/sdk / olakai-sdk | olakai-integrate |
| Build a brand-new agent project from scratch | olakai-new-project |
| Debug SDK / KPI / event issues unrelated to a coding tool | olakai-troubleshoot |
Five tools are supported, all behind the same olakai monitor command, gated by a --tool flag:
| Tool | --tool value | Minimum version |
|------|----------------|-----------------|
| Claude Code | claude-code | any current version |
| OpenAI Codex CLI | codex | 0.124.0 (stable hooks) |
| Cursor | cursor | 1.7 (hooks beta; validated against 3.x) |
| Gemini CLI | gemini-cli | 0.26.0 |
| Antigravity CLI | antigravity | recent agy w/ hooks (validated 1.0.4) |
CLI requirement: the
monitor list,monitor doctor,monitor repair, andagents mine/agents archive|rename|deletecommands documented here require olakai-cli ≥ 0.7.0. Older CLIs only haveinit/status/disable. The adminbulk-provisioncommand requires ≥ 0.13.0. Claude Code hooks move to.claude/settings.local.jsonat ≥ 0.14.0 (see Claude Code hooks live in.claude/settings.local.json). Upgrade withnpm install -g olakai-cli@latest.Since olakai-cli 0.13.0, every monitored event also reports the CLI version that produced it — no action needed, but it helps diagnose version drift across machines.
⚠️ Check your CLI version before migrating hooks. Check that
olakai --versionreports 0.14.0 or later before running any hook-migration command in this skill. On 0.13.0 and earlier,doctor --fixre-adds the hooks to.claude/settings.jsonand reports success, so a green result there does not mean the hooks are safe from agit pull. Do not treatnpm install -g olakai-cli@latestas proof you are on 0.14.0: runolakai --versionand read the number. If it is below 0.14.0, say so and stop, rather than reporting a migration that did not happen.
What you get:
- Activity tracking on the AI Coding Apps tab in Coding IQ → AI Impact — a single table with all five tools' agents, filterable by source (
All / Claude Code / Codex / Cursor / Gemini CLI / Antigravity CLI). - Session-level metrics (tokens, turns, model)
- KPI evaluation on local agent traffic (Time Saved, Value Created, Governance Compliance, ROI)
- Governance signals and policy enforcement
What is NOT included yet:
- Per-session cost tracking from the tool's own billing surface (Olakai computes its own model-based cost estimate)
Two lenses: machine vs account
There are two distinct questions, answered by two distinct commands. Keep them straight.
| Question | Lens | Command | Source of truth |
|----------|------|---------|-----------------|
| "What is monitored on THIS machine, and where?" | Machine | olakai monitor list | Local registry at ~/.olakai/registry.json |
| "What coding agents exist across my whole account?" | Account | olakai agents mine | Olakai backend (cross-machine) |
Why two lenses? The backend has no scope model. Agents are account-scoped only — there are no per-repo / per-workspace / per-host fields. So "where am I monitoring?" is a purely machine-local fact that nobody persists server-side. The CLI records it in a local registry (~/.olakai/registry.json) that monitor list reads. monitor doctor is what bridges the two lenses — it flags drift between the registry, the backend, and what is actually on disk.
# Machine lens — every workspace monitored on this box, grouped by tool,
# with scope + linked agent + a drift flag where registry/backend/disk disagree.
olakai monitor list
olakai monitor list --json
# Account lens — your coding agents across the whole Olakai account.
olakai agents mine
olakai agents mine --source claude-code # filter to one tool
olakai agents mine --source codex --json
Scope is honest per tool
Where the hooks live differs by tool — this matters for what gets attributed.
| Tool | Hook scope | Where hooks are written | Agent linkage (per-workspace) |
|------|-----------|-------------------------|-------------------------------|
| Claude Code | Workspace | .claude/settings.local.json (this workspace only, ≥ 0.14.0) | .olakai/monitor-claude-code.json |
| Codex CLI | Global | ~/.codex/config.toml (all workspaces) | .olakai/monitor-codex.json |
| Cursor | Global | ~/.cursor/hooks.json (all workspaces) | .olakai/monitor-cursor.json |
| Gemini CLI | Global | ~/.gemini/settings.json (all workspaces) | .olakai/monitor-gemini-cli.json |
| Antigravity | Global | ~/.gemini/config/hooks.json (all workspaces) | .olakai/monitor-antigravity.json |
For all five tools, the per-workspace .olakai/monitor-<tool>.json file holds the agent linkage (API key + agent ID + endpoint).
Claude Code hooks live in .claude/settings.local.json (olakai-cli ≥ 0.14.0)
Up to 0.13.0 the hooks went into .claude/settings.json. Teams commonly track that file in git, so a git pull could rewrite it, delete the hook block, and stop monitoring with no error. Since 0.14.0 the hooks go into .claude/settings.local.json: the project-scoped personal settings file, which is conventionally gitignored.
What this means in practice:
- Upgrading from 0.13.0 or earlier? Your hooks are still in
.claude/settings.json. Confirmolakai --versionreports 0.14.0 or later (see the version guard above), then runolakai monitor doctor --tool claude-code --fix(orolakai monitor repair --tool claude-code) to migrate them.olakai monitor init --tool claude-codemigrates them too. On 0.13.0 the same--fixputs the hooks back into.claude/settings.jsonand reports success. - Why
initmigrates rather than adds. Claude Code merges thehooksblock acrosssettings.jsonandsettings.local.json: neither file suppresses the other. Identical handlers are then deduplicated, so the CLI's own block left in both files runs once. Two blocks both run, and events duplicate, only when they differ (an older command form beside the current one, for example). So the reason to migrate is not double-firing: it is that a block sitting in the trackedsettings.jsonis onegit pullaway from deletion.initmigrates the legacy block so nothing is left there to delete or to drift out of step. - A
settings.jsonwith no Olakai hooks is left byte-identical.init,statusanddisabledo not rewrite it. Running the CLI never dirties your team's tracked settings file. - The gitignore guarantee is verified, not assumed.
initanddoctorrungit check-ignoreon the hook file and warn when it is not ignored. They stay silent when the workspace is not a git repository or git is unavailable. Note thatgit check-ignorereports a tracked file as not-ignored even when a rule matches it, which is exactly the state you want to hear about: add the file to.gitignoreandgit rm --cachedit.
Only Claude Code changed. Codex, Cursor, Gemini CLI and Antigravity write to ~/ paths and are unaffected.
⚠️ Unattributed activity caveat (Codex / Cursor / Gemini CLI / Antigravity). Because Codex, Cursor, Gemini CLI, and Antigravity install hooks globally, their hook fires in every workspace — including ones you never ran
olakai monitor initin. When the hook fires in a workspace that has no.olakai/monitor-<tool>.json, it silently exits and that session is NOT attributed to any agent (no event is sent). This is expected: a global hook with no local linkage has nowhere to report. If you expect Codex/Cursor/Gemini CLI/Antigravity activity from a repo and see none, the most common cause is that you never ranolakai monitor init --tool <tool>in that repo. Runolakai monitor listto see exactly which workspaces are linked, andolakai monitor doctor --tool <tool>for an explanation in context.Claude Code does not have this caveat — its hooks are workspace-scoped, so they only fire where you installed them.
Self-healing: diagnose and repair your own monitoring
If you are an installed coding agent and your monitoring seems broken (no events, missing KPIs, "is this even on?"), drive these commands in order. Always start with monitor list, then monitor doctor, then escalate to repair.
# 1. SEE — machine-wide picture: what's installed, where, and which entries are drifting.
olakai monitor list
# 2. DIAGNOSE — ordered health-check chain (registry → config → hooks → key → agent → events).
olakai monitor doctor --tool claude-code # or codex / cursor / gemini-cli / antigravity; --all for every workspace
# 3. FIX — idempotent, best-effort auto-repair of what doctor flagged.
olakai monitor doctor --tool claude-code --fix
# 4. ESCALATE — forceful re-init that preserves agent linkage (heals a clobbered config).
olakai monitor repair --tool claude-code
monitor doctor runs an ordered chain — each step gates the next, so the first failure is usually the real problem: registry-entry → config-valid → hooks-installed → api-key-valid → agent-exists → events-flowing. --fix is idempotent and best-effort (adopts the registry entry, re-merges missing hooks, re-links a rejected key). It will not recreate a missing agent unless you add --recreate-missing — a deliberate guard so a transient 404 can't spawn a duplicate. On a true 404, prefer olakai monitor repair --tool <tool>, which re-merges hooks, migrates legacy config, re-links the key only if invalid, and recreates the agent only on a genuine 404.
For the full self-healing playbook — every doctor check explained, the complete decision tree,
doctor --fixvsrepaircomparison, and common repair scenarios — use theolakai-monitor-doctorskill.
Prerequisites
which olakai || echo "CLI_NOT_INSTALLED"
olakai whoami 2>/dev/null || echo "NOT_AUTHENTICATED"
| Result | Action |
|--------|--------|
| CLI_NOT_INSTALLED | Run npm install -g olakai-cli@latest, then olakai login |
| NOT_AUTHENTICATED | Run olakai login |
| Shows email/account | Ready to proceed |
Not set up at all? Use
/olakai-get-startedfirst.
You also need the local coding agent itself installed and operational in your workspace.
Choose your tool
If you don't know which tool is in this workspace, run olakai monitor init with no flag — the CLI auto-detects the configured agent in interactive mode and prompts you to confirm. For scripted setup, always pass --tool explicitly.
Are you monitoring …
├── Anthropic Claude Code? → --tool claude-code
├── OpenAI Codex CLI? → --tool codex (requires Codex CLI ≥ 0.124.0)
├── Cursor IDE/CLI? → --tool cursor (requires Cursor ≥ 1.7, hooks in beta)
├── Google Gemini CLI? → --tool gemini-cli (requires Gemini CLI ≥ 0.26.0)
└── Google Antigravity CLI? → --tool antigravity (requires recent agy with hooks, validated 1.0.4)
You can install monitoring for multiple tools in the same workspace — each tool stores its config in its own settings file and creates its own agent record.
Admin: zero-touch fleet rollout (bulk-provision)
olakai monitor init is the right path for a single developer setting up their own machine interactively. If you are an Olakai ADMIN rolling out Claude Code monitoring to a whole team — pushing configs through Intune or another device-management tool, with no action required from each developer — use bulk-provision instead (olakai-cli ≥ 0.13.0, ADMIN role required):
olakai admin monitor bulk-provision \
--emails roster.txt \
--out ./bundles \
[--tool claude-code] [--rotate-existing-keys] [--name-prefix "Prefix "] [--json] [--yes]
--emailsaccepts.txtor.csv— one email per line (or first CSV column),#comments allowed, a header row is auto-skipped, emails are deduped case-insensitively, max 500 per run.--tool— v1 supportsclaude-codeonly. Codex, Cursor, Gemini CLI, and Antigravity keep hooks in global per-machine files, so per-repo pushable bundles aren't possible for them.
What it does — per email in the roster:
- Resolves or creates an EMPLOYEE user on your account
- Creates a Claude Code agent owned by that developer (
creatorUserId), so Coding IQ attribution is per-developer - Mints an SDK key
- Writes a device-management-ready bundle under
<out>/<localpart>/:.claude/settings.local.json(hook block, ≥ 0.14.0; bundles from 0.13.0 carried.claude/settings.json) and.olakai/monitor-claude-code.json(agentId / apiKey / monitoringEndpoint, mode 0600) — push both into the target repo/home layout. Akeymap.json/keymap.csv(0600) at the out root maps emails → agents → keys.
Why
settings.local.jsonin the bundle matters at rollout scale. The bundle is pushed onto developer machines by device management, and how the bundled file meets an existing file on disk is the MDM tool's behaviour, not the CLI's. Most push mechanisms overwrite, so a bundled.claude/settings.jsoncan replace whatever the team tracks in git on each machine it lands on. Check what your own tool does.settings.local.jsonsidesteps the question: it is personal and gitignored, so the push adds the hooks without landing on the team's tracked file at all.Already rolled out 0.13.0 bundles? Confirm your admin machine is on 0.14.0 (
olakai --version), re-run bulk-provision, and push the new bundles. Alternatively, have each developer confirm their ownolakai --versionis 0.14.0 or later and then runolakai monitor doctor --tool claude-code --fix. A developer still on 0.13.0 gets a green--fixthat leaves the hooks in.claude/settings.json, so the fleet-wide report would say migrated when it is not. See the version guard above.
Under the hood it calls the ADMIN-gated POST /api/config/agents/bulk-provision endpoint on your own instance (SaaS or on-prem), in chunks of 100 emails (server rate limit: 10 requests / 120s per admin).
Key semantics — read before re-running:
- Plaintext keys are returned only at creation or rotation. On a re-run, existing developers come back as
reusedwith no key and no bundle — this is deliberate, so re-runs are safe for already-deployed devices. --rotate-existing-keysrevokes and remints keys for existing developers — this invalidates configs already deployed to their devices. Only use it when you intend to redeploy the fresh bundles.- The command exits non-zero if any row fails. If a run aborts mid-way on a rate limit, unattempted emails are written to
<out>/unprocessed.txt— re-run with that file as the roster.
Deployment gotchas:
- Target machines must also have
olakai-cliinstalled globally — the pushed hooks runolakai monitor hook .... - Pushed bundles do not appear in
olakai monitor list/doctoron the target machine until the developer runs anyolakai monitorcommand once (the registry reconcile backfills them). The hooks fire and report fine regardless — this only affects local visibility tooling.
Prefer a UI? The same capability exists in the dashboard: Coding IQ → Settings → Bulk Provisioning (paste or upload emails → download the key-map CSV + a ZIP of bundles).
Quick Setup — Claude Code
Step 1: Initialize monitoring
olakai monitor init --tool claude-code
What it does:
- Creates an agent with
AgentSource.CLAUDE_CODEon your Olakai account - Writes
StopandSubagentStophook entries to.claude/settings.local.json(workspace-scoped, ≥ 0.14.0). If a legacy Olakai hook block is still in.claude/settings.json,initmigrates it: the block moves tosettings.local.jsonandinittells you it did so. Asettings.jsonthat holds no Olakai hooks is left byte-identical. - Saves configuration to
.olakai/monitor-claude-code.json(API key, agent ID, endpoint). Pre-Stage-2 installs at.claude/olakai-monitor.jsonare auto-migrated on first read. - Records this workspace in the machine registry (
~/.olakai/registry.json) somonitor list/doctorcan see it. - Checks the hook file against
git check-ignoreand warns if it is not gitignored (silent when the workspace is not a git repository, or when git is unavailable).
init links an agent in one of two ways, and only one of them rotates a key. Know which one you are in before you report anything to the developer:
| Path | What happens to the key | Blast radius |
|---|---|---|
| Reuse an existing agent (pick it from the list) | Provisioning rotates that agent's API key | Any other workspace already using that agent starts failing on its next monitor request until it re-runs olakai monitor init. The CLI warns you about this before it proceeds. |
| Paste a key you already hold | No rotation | The CLI calls GET /api/monitoring/prompt/me with the pasted key and aborts (default n) if the resolved agent does not match the agent you picked |
Your API key is protected against a failed install. On the rotate path the plaintext key is shown only once, so init parses the settings files before it provisions, and writes .olakai/monitor-claude-code.json before it writes the hooks. A settings file that will not parse stops the run before any key is rotated, and a rotated key is on disk before the hook write is attempted.
The command is interactive — it prompts for an agent name if one is not provided, and lets you pick an existing agent or create a new one.
Re-running
olakai monitor init --tool claude-code: Settings-merge preserves any user-customized Olakai hook commands. It will not overwrite manually-edited commands. For a clean reinstall that refreshes hook commands, runolakai monitor disable --tool claude-codefirst, thenolakai monitor init --tool claude-code. To heal a clobbered config without losing the agent, preferolakai monitor repair --tool claude-code.
Step 2: Verify
olakai monitor status --tool claude-code # this workspace
olakai monitor doctor --tool claude-code # full ordered health check
status confirms Stop and SubagentStop hooks are registered and the config at .olakai/monitor-claude-code.json is valid. It finds the hooks in either .claude/settings.local.json or .claude/settings.json, names the file they are in, and warns when they are in both. Treat that warning as an unfinished migration, not as duplicate reporting: identical blocks are deduplicated and run once. It matters because the copy in the tracked settings.json can be deleted by a git pull, and because two blocks that later drift apart would both run. status never rewrites settings.json. doctor runs the deeper chain (registry → config → hooks → key → agent → events).
What gets captured (Claude Code)
Two hooks are installed by default:
- Stop hook — fires at the end of each top-level Claude Code turn
- SubagentStop hook — fires when a subagent (launched via the Agent tool) finishes
Both hooks read Claude Code's transcript JSONL file (at transcript_path from the hook event) and extract:
| Field | Description |
|-------|-------------|
| prompt | Last non-meta user message in the session transcript |
| response | Last assistant message text (tool-only turns preserve the prior text response) |
| chatId | Claude Code session_id — groups all turns of a conversation |
| modelName | Model from the last assistant message (e.g., claude-sonnet-4-5) |
| tokens | Input (incl. cache_creation + cache_read) + output tokens from last turn's usage |
| customData.inputTokens / outputTokens | Last turn's usage broken down |
| customData.numTurns | Count of non-sidechain assistant messages in the session |
| customData.latencyMs | Integer milliseconds from the user message timestamp to the assistant response timestamp |
| customData.subagent | Subagent name, set only on SubagentStop events |
| customData.skill | Slash-command skill name, set when the user turn begins with /<skill> |
| customData.sessionId / transcriptPath / cwd / stopHookActive / hookEvent | Raw hook event metadata |
| source | Top-level "claude-code" tag |
Notes on token counts: Token totals include cache tokens (cache_creation + cache_read) because real Claude Code sessions typically show very high cache-read volume. Excluding cache would massively under-report billable volume.
Empty-parse safeguard: If the transcript parser produces an empty prompt, empty response, AND zero turns, the hook returns null and does not fire an event — defensive against unrecognized payload shapes from future Claude Code versions.
Quick Setup — Codex CLI
Step 1: Initialize monitoring
olakai monitor init --tool codex
What it does:
- Creates an agent with
AgentSource.CODEXon your Olakai account - Writes a
Stophook entry into the inline[hooks]block of~/.codex/config.toml(global — fires in every workspace). Comment-preserving TOML serialization isn't supported by@iarna/toml, so existing comments in your~/.codex/config.tomlmay be reformatted on first install — the CLI prints a warning when this happens. - Saves configuration to
.olakai/monitor-codex.json(API key, agent ID, endpoint) and records this workspace in~/.olakai/registry.json.
Codex CLI ≥ 0.124.0 is required. The hooks API was unstable in earlier Codex versions; the integration is only validated from
0.124.0onward. Check withcodex --versionbefore running init.Global-hook caveat: because the Codex hook is global, running it in a workspace with no
.olakai/monitor-codex.jsonproduces no event (silent exit). See Scope is honest per tool.
Step 2: Verify
olakai monitor status --tool codex
olakai monitor doctor --tool codex
What gets captured (Codex)
Codex hooks fire on session turn completion. The integration captures:
prompt/response— last user/assistant turn from Codex's transcriptchatId— Codex session identifiermodelName— model from the last assistant messagetokens— input + output token totals from the turn's usagecustomData.inputTokens/outputTokens— usage broken downcustomData.numTurns— turn count for the sessionsource—"codex"
Quick Setup — Cursor
Step 1: Initialize monitoring
olakai monitor init --tool cursor
What it does:
- Creates an agent with
AgentSource.CURSORon your Olakai account - Writes
beforeSubmitPrompt,afterAgentResponse,sessionEnd, andstophook entries to~/.cursor/hooks.json(global per-user install — fires in every workspace) - Saves configuration to
.olakai/monitor-cursor.json(API key, agent ID, endpoint) and records this workspace in~/.olakai/registry.json.
Cursor ≥ 1.7 is required and the Cursor hooks API is in beta. The integration is validated against Cursor
3.xbut the upstream hook contract may shift. If hooks stop firing after a Cursor update, see Troubleshooting.Global-hook caveat: as with Codex, the Cursor hook is global, so a workspace without
.olakai/monitor-cursor.jsonproduces no event. See Scope is honest per tool.
Step 2: Verify
olakai monitor status --tool cursor
olakai monitor doctor --tool cursor
What gets captured (Cursor)
In addition to the standard fields (prompt, response, tokens, modelName, chatId, numTurns), Cursor hook events expose the active user's email, which is captured as:
userEmail— automatically populated from the Cursor hook payload, so per-user analytics work without explicit identificationsource—"cursor"
Quick Setup — Gemini CLI
Step 1: Initialize monitoring
olakai monitor init --tool gemini-cli
What it does:
- Creates an agent with
AgentSource.GEMINI_CLIon your Olakai account - Merges hook entries into
~/.gemini/settings.json(global — fires in every workspace). The hooks coverSessionStart,SessionEnd,BeforeModel,AfterModel,BeforeTool, andAfterTool— onlyAfterModelemits a monitoring event, while the others maintain sidecar session state. - Saves configuration to
.olakai/monitor-gemini-cli.json(API key, agent ID, endpoint) and records this workspace in~/.olakai/registry.json.
Gemini CLI ≥ 0.26.0 is required. The hooks API used by this integration is only available from
0.26.0(GA 2026-01-28) onward. Check withgemini --versionbefore running init.Global-hook caveat: because the Gemini CLI hooks are global, running in a workspace with no
.olakai/monitor-gemini-cli.jsonproduces no event (silent exit). See Scope is honest per tool.
Step 2: Verify
olakai monitor status --tool gemini-cli
olakai monitor doctor --tool gemini-cli
What gets captured (Gemini CLI)
The hooks merged into ~/.gemini/settings.json span the full session lifecycle (SessionStart, SessionEnd, BeforeModel, AfterModel, BeforeTool, AfterTool). Only AfterModel emits a monitoring event; the other hooks maintain sidecar session state (tool counts, session identity) so the emitted event is complete. Each event captures:
hookEvent— the hook that fired (AfterModelfor emitted events)sessionId— Gemini CLI session identifier, groups all turns of a conversationcwd— the workspace directory the session ran ininputTokens/outputTokens— token usage for the turntoolCallCount— number of tool calls observed in the session via theBeforeTool/AfterToolhookstoolNames— the names of the tools invokedsource—"gemini-cli"
Quick Setup — Antigravity CLI
Step 1: Initialize monitoring
olakai monitor init --tool antigravity
What it does:
- Creates an agent with
AgentSource.ANTIGRAVITYon your Olakai account - Merges a single
Stophook entry into~/.gemini/config/hooks.json(global — fires in every workspace). TheStophook fires at the end of each agy turn and emits one monitoring event. - Saves configuration to
.olakai/monitor-antigravity.json(API key, agent ID, endpoint) and records this workspace in~/.olakai/registry.json.
A recent
agywith hooks support is required (validated againstagyv1.0.4). Antigravity CLI (agy) is Google's agentic coding CLI. The integration relies on theStophook, so older builds without hooks support will not emit events.Interactive-only: the
Stophook only fires in interactiveagysessions. Headless runs (agy -p) skip hooks entirely, so no event is sent for non-interactive invocations.No token counts: agy's hook payload carries no usage metadata, so emitted events have no input/output token counts. Olakai still computes its own model-based cost estimate.
Global-hook caveat: because the Antigravity hook is global, running it in a workspace with no
.olakai/monitor-antigravity.jsonproduces no event (silent exit). It is also written to~/.gemini/config/hooks.json, a different file from Gemini CLI's~/.gemini/settings.json, so the two coexist cleanly. See Scope is honest per tool.
Step 2: Verify
olakai monitor status --tool antigravity
olakai monitor doctor --tool antigravity
What gets captured (Antigravity CLI)
The Stop hook reads agy's transcript JSONL to reconstruct the turn. Each event captures:
prompt— the last user turn from agy's transcriptresponse— the agent's final response for the turncustomData.hookEvent— the hook that fired (Stop)customData.conversationId— agy conversation identifier, groups all turns of a conversationcustomData.cwd— the workspace directory the session ran incustomData.terminationReason— why the turn endedsource—"antigravity"
Note — interactive-only and no token counts. Antigravity events are only produced in interactive
agysessions (headlessagy -pskips hooks), and agy's payload has no usage metadata, so emitted events have no token counts.
Pasted API key validation
When you select an existing agent during olakai monitor init and the CLI asks you to paste the API key, the CLI validates that the key actually resolves to the agent you picked:
- The CLI calls
GET /api/monitoring/prompt/mewith your pasted key - It checks the resolved agent ID matches the agent you selected from the list
- If they don't match, you'll see a warning naming both agents (the one the key belongs to vs. the one you picked) and a prompt:
Use the pasted key anyway? (y/n) [n]:
The default is abort — pressing Enter cancels the init and protects you from wiring a key into the wrong agent's config. Pick again, regenerate a fresh key for the right agent (olakai agents get AGENT_ID --json | jq '.apiKey'), or type y if you intentionally want a cross-wired setup (rare, usually a mistake).
Validate via the Golden Rule
After completing your first task in the local agent, fetch and inspect the event:
# 1. Use the local agent normally — write code, ask questions, run a turn
# 2. Fetch the latest event for your agent
olakai activity list --agent-id AGENT_ID --limit 1 --json
# 3. Inspect it
olakai activity get EVENT_ID --json | jq '{source, customData, kpiData}'
Confirm:
- Event exists with a recent timestamp
sourceis"claude-code","codex","cursor","gemini-cli", or"antigravity"(matches your--tool)prompt,response,tokens, andmodelNameare populated (not empty/null)customDatacontains session metadata- For Cursor specifically,
userEmailis set from the hook payload kpiDatashows numbers, not strings or nulls
Replace AGENT_ID with the ID shown by olakai monitor status --tool <tool> (or olakai monitor list).
KPI Configuration
Local agent traffic is evaluated by the same KPI system as SDK-monitored agents. New agents automatically receive metric slot KPIs:
| Slot KPI | Output Unit | Description |
|----------|-------------|-------------|
| Execution Cost | USD | Token-based cost estimate |
| Time Saved | minutes | time_saved_estimator classifier (CHAT scope) |
| Value Created | USD | Time Saved * hourly rate |
| Governance Compliance | % | Policy pass rate |
Plus the composite: ROI = Value Created / Execution Cost.
Verify KPIs exist
olakai kpis list --agent-id AGENT_ID
If the Time Saved classifier is missing (can happen for CLI-created agents), add it manually:
olakai kpis create --name "Time Saved" \
--calculator-id classifier --template-id time_saved_estimator \
--scope CHAT --agent-id AGENT_ID
Adding custom KPIs
If you want metrics beyond the defaults, register custom data fields first, then create formula-based KPIs:
# Example: track task complexity
olakai custom-data create --agent-id AGENT_ID --name "Complexity" --type STRING
olakai kpis create \
--name "Complex Tasks" \
--agent-id AGENT_ID \
--calculator-id formula \
--formula "IF(Complexity = \"complex\", 1, 0)" \
--scope PROMPT_REQUEST \
--aggregation SUM
Using classifier templates
Classifier templates provide AI-evaluated KPIs without writing formulas. They analyze the full conversation at the CHAT scope:
olakai kpis templates # List available templates
olakai kpis create --name "Session Sentiment" \
--calculator-id classifier --template-id sentiment_scorer \
--scope CHAT --agent-id AGENT_ID
Note: Classifier KPIs run at CHAT scope, meaning they evaluate the entire session, not individual turns. Results appear after chat decoration processes (there may be a short delay).
Checking Your Data
# Health (machine, single-workspace, account)
olakai monitor list # MACHINE: everything monitored on this box
olakai monitor doctor --tool <tool> # ordered health check (--all for every workspace)
olakai monitor status --tool <tool> # quick single-workspace status
olakai agents mine [--source claude-code|codex|cursor|gemini-cli|antigravity] # ACCOUNT: your coding agents
# Events + KPIs for one agent
olakai activity list --agent-id AGENT_ID --limit 10
olakai activity sessions --agent-id AGENT_ID # decoration status (DECORATED = KPIs populated)
olakai activity kpis --agent-id AGENT_ID --json
Dashboard: Navigate to Coding IQ → AI Impact → AI Coding Apps at https://app.olakai.ai. The unified table shows agents from all five tools side-by-side, with a source filter chip (All / Claude Code / Codex / Cursor / Gemini CLI / Antigravity CLI, default All).
Agent lifecycle (account-wide)
These act on the agent record on the Olakai backend, across all machines — not on local hooks:
olakai agents archive AGENT_ID # hide an agent you no longer use
olakai agents archive AGENT_ID --unarchive # bring it back
olakai agents rename AGENT_ID "New Name" # rename
olakai agents delete AGENT_ID # permanent delete
Backend requirement:
agents archive/renamerequire a current Olakai backend (self-owner lifecycle support shipped alongside these CLI commands). Against older backends these are admin-only andarchivemay no-op silently — if archive appears to do nothing, your backend predates the feature.
To stop hooks on this machine without touching the account record, use olakai monitor disable instead (below).
Disabling Monitoring
Each tool's monitoring is uninstalled independently:
olakai monitor disable --tool claude-code
olakai monitor disable --tool codex
olakai monitor disable --tool cursor
olakai monitor disable --tool gemini-cli
olakai monitor disable --tool antigravity
What this does:
- Removes the registered hooks from the tool's settings file. For Claude Code on ≥ 0.14.0 that is
.claude/settings.local.json. A.claude/settings.jsonthat holds no Olakai hooks is left byte-identical. - Removes the corresponding
monitor-claude-code.json/monitor-codex.json/monitor-cursor.json/monitor-gemini-cli.json/monitor-antigravity.json(and any legacy.claude/olakai-monitor.json) - Removes this workspace's entry from the machine registry (
~/.olakai/registry.json)
What this does NOT do:
- Does not delete the agent record on Olakai (use
olakai agents archive/deletefor that) - Does not delete historical event data
- Does not affect other monitored tools or SDK-based monitoring
To re-enable, run olakai monitor init --tool <tool> again.
Troubleshooting
No events, missing KPIs, deleted/404 agent, drifted config, hooks stopped firing? That is the self-healing playbook — use the
olakai-monitor-doctorskill, or just runolakai monitor doctor --tool <tool>(add--fixto auto-repair, orolakai monitor repair --tool <tool>to forcefully re-init while preserving the agent). The subsections below cover only setup-specific transcript/KPI issues that doctor does not auto-fix.
Events appear but prompt, response, tokens, or modelName are empty/null
This usually means the transcript file at transcript_path (Claude Code) or the equivalent for Codex/Cursor could not be read or parsed. Common causes:
- CLI version too old — upgrade:
npm install -g olakai-cli@latest - Tool version too old — Codex must be ≥
0.124.0, Cursor must be ≥1.7 - Transcript file moved or deleted between turn end and hook firing
- Transcript format changed in a newer tool version
For Claude Code specifically, the empty-parse silent-exit guard means the hook returns null (no event) when prompt empty AND response empty AND numTurns is 0 — protective against unrecognized payload shapes. If you see no events at all and debug mode shows transcript-parsed: empty, you've hit this guard.
Enable OLAKAI_MONITOR_DEBUG=1 to confirm whether transcript reading succeeded. Look for transcript-read-failed or transcript-parsed entries in the debug log.
Events appear but no KPIs
KPIs must be configured on the agent:
olakai kpis list --agent-id AGENT_ID
If empty, add at minimum the Time Saved classifier:
olakai kpis create --name "Time Saved" \
--calculator-id classifier --template-id time_saved_estimator \
--scope CHAT --agent-id AGENT_ID
Hook errors interrupting the session
The hook is designed to fail silently — errors in the monitoring hook should never interrupt your local agent session. If you suspect issues:
- Check config exists:
cat .olakai/monitor-claude-code.json(or the Codex/Cursor equivalent) - Verify API key is valid:
olakai agents get AGENT_ID --json | jq '.apiKey' - Test connectivity:
olakai whoami
Deeper issues
Use /olakai-troubleshoot for comprehensive diagnostics including API key validation, endpoint connectivity, event payload inspection, and KPI formula debugging.
Quick Reference
# Setup (pick the right --tool)
olakai monitor init --tool claude-code # Claude Code (workspace-scoped hooks)
olakai monitor init --tool codex # Codex CLI (>= 0.124.0, global hooks)
olakai monitor init --tool cursor # Cursor (>= 1.7, hooks beta, global hooks)
olakai monitor init --tool gemini-cli # Gemini CLI (>= 0.26.0, global hooks)
olakai monitor init --tool antigravity # Antigravity CLI (recent agy w/ hooks, validated 1.0.4, global hooks)
# Admin: zero-touch fleet rollout (ADMIN role, olakai-cli >= 0.13.0, v1 claude-code only)
olakai admin monitor bulk-provision --emails <file> --out <dir> [--tool claude-code] [--rotate-existing-keys] [--name-prefix <p>] [--json] [--yes]
# See what's monitored (two lenses)
olakai monitor list # MACHINE: everything on this box + drift flags
olakai agents mine [--source claude-code|codex|cursor|gemini-cli|antigravity] # ACCOUNT: agents across the whole account
# Diagnose + repair your own monitoring
olakai monitor doctor --tool <tool> [--fix] [--recreate-missing]
olakai monitor doctor --all # every workspace on this machine
olakai monitor repair --tool <tool> # forceful re-init, preserves agent linkage
olakai monitor status --tool <claude-code|codex|cursor|gemini-cli|antigravity>
olakai monitor disable --tool <claude-code|codex|cursor|gemini-cli|antigravity>
# Agent lifecycle (account-wide, backend record)
olakai agents archive AGENT_ID [--unarchive]
olakai agents rename AGENT_ID "New Name"
olakai agents delete AGENT_ID
# Activity + KPIs — see "Checking Your Data" above
# Debug
export OLAKAI_MONITOR_DEBUG=1 # Verbose dispatcher logs at /tmp/olakai-monitor-debug-<pid>.log
# Dashboard: Coding IQ -> AI Impact -> AI Coding Apps at https://app.olakai.ai