Skip to content

Ingest Hooks CLI

Use provon ingest hooks install to write trace hooks into AI coding tools so that agent sessions are reported to Provon as OTel traces in real time. Unlike provon ingest sync, whic

View as Markdown Open the plain-text version of this page.
text
agent session event -> tool hook -> provon ingest trace <source> <hook> -> parse transcript -> OTLP -> POST /v1/traces

The hook command is non-blocking: it hands the payload to a detached child process and returns immediately, so it never slows down the agent or trips a hook timeout.

Supported Tools#

Tool Hook events Config location
Claude PostToolUse, Stop ~/.claude/settings.json (or <dir>/.claude/)
Codex PostToolUse, Stop ~/.codex/hooks.json + trust in config.toml
OpenCode session.idle generated plugin ~/.config/opencode/plugins/
dsh agent/turn-stopping, tools/post-execute generated plugin $DSH_HOME/ (global only)
Cursor stop, sessionEnd ~/.cursor/hooks.json (or <dir>/.cursor/)
Pi agent_settled, session_shutdown generated extension ~/.pi/agent/extensions/

Installation is idempotent: re-running ingest hooks install updates existing entries rather than duplicating them. Only hooks that invoke provon ingest trace are modified; hooks owned by other tools are left untouched.

Prerequisites#

  1. Authenticate the CLI or provide a project API key:

    bash
    provon auth login
    # or
    export PROVON_API_KEY="your_project_api_key"
    export PROVON_PROJECT_ID="your_project_id"
  2. The provon binary must be on PATH (or the hook will bake in the absolute node directory at install time).

Quick Start#

Install hooks for every detected tool on the system:

bash
provon ingest hooks install

The command auto-detects targets by checking for the tool's config directory or the command on PATH. Skipped tools are listed in the output with the reason.

Install for a single tool:

bash
provon ingest hooks install --claude
provon ingest hooks install --codex --cursor

Force install even when a tool is not detected:

bash
provon ingest hooks install --pi --skip-check

Project-Level vs Global#

By default hooks are written to the user's global config (~/.claude/, ~/.codex/, etc.), so they apply to every project. To install only for a specific project:

bash
provon ingest hooks install --project-dir /path/to/project

This writes to <project-dir>/.claude/settings.json, <project-dir>/.cursor/hooks.json, etc. dsh has no project-level config and is skipped when --project-dir is set.

Reporting Configuration#

Reporting credentials are resolved from the global CLI options and the active auth profile:

  1. Global --project <id> / --api-key <key> flags
  2. The active local auth profile (provon auth login)
bash
# Using global flags
provon --project proj_abc123 --api-key pk_live_xxx ingest hooks install

# Or after `provon auth login`, credentials are read from the profile automatically
provon ingest hooks install

All reporting config is baked into the hook command as a PROVON_TRACE_CONFIG environment variable, so hooks work in non-interactive shells and CI without extra env setup.

Filtering#

Limit which sessions are reported by adding filters at install time:

bash
provon ingest hooks install \
  --repo my-org/my-repo \
  --path /workspace/project \
  --skill dangerous-bash \
  --mcp github \
  --keyword "deploy"

All filters are repeatable. A session is reported if it matches at least one value in each provided filter category.

Report Mode and Level#

bash
provon ingest hooks install --mode coding_write --report-level summary
Option Values Default
--mode coding, coding_write, in_repo, all all
--report-level full, summary full

Disabled Hooks#

Install hooks in a switched-off state (registered but not reporting):

bash
provon ingest hooks install --disable 1

Reinstall without --disable to turn reporting on.

Multiple Reporting Targets#

By default, installing for a project replaces any existing reporting target for that project in the same hooks file. To append an additional target instead:

bash
provon --project second-project --api-key second-key ingest hooks install --append

The same project can only have one target per hooks file. If another tool already reports to the same project, installation is aborted with a TARGET_CONFLICT error to prevent double-reporting.

Uninstall#

Remove all Provon trace hooks from every tool:

bash
provon ingest hooks uninstall

Or from specific tools:

bash
provon ingest hooks uninstall --claude --codex

Only hooks that invoke provon ingest trace are removed. Other tools' hooks and unrelated config keys are preserved. For Codex, the trust-state entries in config.toml are also cleared.

How It Works#

Install phase#

  1. Resolve project ID, API key, and endpoint from global flags or the stored auth profile.
  2. Detect which tools are present (config directory or command on PATH).
  3. Check for cross-tool conflicts (same project reported by another tool's hooks).
  4. For each target: write hook entries (Claude, Codex, Cursor) or generate a plugin file (OpenCode, dsh, Pi) that invokes provon ingest trace <source> <hook>.
  5. For Codex: compute the sha256 trust fingerprint and write it to config.toml before writing hooks.json, so Codex does not park the hook as "pending trust".

Runtime phase#

  1. The tool fires the hook and pipes a JSON payload (containing transcript_path or session data) to provon ingest trace <source> <hook> on stdin.
  2. The trace entry reads PROVON_TRACE_CONFIG to determine the reporting target.
  3. It re-executes itself as a detached child process, hands over the payload, and returns immediately (milliseconds).
  4. The detached child parses the transcript with @provon/agent-transcripts, projects it to OTel spans with @provon/observability, and POSTs to the OTLP endpoint.
  5. Failures are logged to stderr only when PROVON_TRACE_DEBUG=1; they never surface to the agent.

Environment Variables#

Variable Purpose
PROVON_TRACE_CONFIG Baked into hooks; carries project ID, API key, endpoints, filters
PROVON_TRACE_DISABLE Set to 1 to kill-switch all trace reporting
PROVON_TRACE_DEBUG Set to 1 to print debug logs to stderr
PROVON_TRACE_SYNC Set to 1 to run ingest in-process (for testing)

Troubleshooting#

No traces appear after installation#

  1. Confirm the tool was detected: provon ingest hooks install lists skipped targets with reasons.

  2. Verify the hook entry exists in the tool's config file (see table above).

  3. Run the trace entry manually with debug logging:

    bash
    echo '{"transcript_path":"/path/to/session.jsonl"}' | \
      PROVON_TRACE_CONFIG='{"project_id":"...","api_key":"..."}' \
      PROVON_TRACE_DEBUG=1 PROVON_TRACE_SYNC=1 \
      provon ingest trace claude stop
  4. Check that the API key has the telemetry:ingest scope.

Codex hooks show "pending trust"#

Re-run provon ingest hooks install --codex. The installer writes the trust fingerprint to ~/.codex/config.toml before updating hooks.json. If Codex was running during install, restart it to pick up the new trust state.

Hooks slow down the agent#

The hook command returns immediately after forking a detached child. If you still observe latency, set PROVON_TRACE_SYNC=0 (default) and ensure the provon binary is on PATH.

Double-reporting#

Each project can only have one reporting target per hooks file. If you see duplicate traces, run provon ingest hooks uninstall and reinstall, or check that another tool is not also reporting to the same project.