Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Hooks

Hooks run automatically — you don’t invoke them. They fire at specific points in the Claude Code lifecycle and produce the status line, context nudges, and alerts Prism shows you in your terminal.

The four hooks live in optra-prism-plugin/hooks/scripts/ and are wired up in hooks.json:

HookClaude Code eventScript
SessionStartClaude Code launchessession-start.sh
UserPromptSubmitYou hit entersubmit-handler.js
StopClaude finishes a turnstop-handler.js
PostCompactYou run /compactcompact-handler.js

After each turn, Prism builds a compact one-line summary and prints it above your next prompt:

[Prism] 5.2s · 12K in / 2K out · $0.23 ($1.45 total) · turn 5
  • Response time — color-coded: green < 5s · yellow < 15s · red ≥ 15s
  • Tokens — turn input / output, rounded to thousands
  • Cost — turn cost · session total. When the turn cost isn’t cache-aware, a ~ prefix marks it (the fallback full-input estimate is shown instead of the exact cached number)
  • Turn count — turn number in this session

The status line is built by the Stop hook (Claude Code doesn’t display stop-hook stderr, so the line is saved to session state and actually printed by the next UserPromptSubmit hook). Toggle with /prism:status → “toggle status line” (sets showStatusLine in config).

Context-management nudges (before prompts)

Section titled “Context-management nudges (before prompts)”

The UserPromptSubmit hook checks turn count and token growth on every turn, and prints one line when a threshold is crossed:

WhenColorSuggestion
Turn count > 80 or context grew > 10×Red/clear to start fresh
Turn count > 20 and context grew > 3×Yellow/compact to free context
Every 15 turnsDimGentle /compact reminder

Growth is lastTurnInputTokens / firstTurnInputTokens.

The Stop hook also queues a small number of alerts — displayed by the next submit hook alongside the status line — to avoid repeating on every turn:

AlertCadenceWhat it says
Context alert (red)Every 5 turns, when turn count > 80 or growth > 10×Session is deep; consider /clear
Context alert (yellow)Every 5 turns, when growth > 3× and turn count > 10Context grew; run /compact
Context reminder (dim)Every 15 turnsPeriodic /compact reminder
Model overkillEvery 10 turns, when ≥ 3 Opus turns produced < 200 output tokensSuggests /model sonnet for simple tasks
Slow responseEvery 5 turns, when the last 3 turns averaged > 20sContext may be too large; try /compact

The Stop hook computes per-turn cost using the turn’s token counts. It’s cache-aware when possible: the hook queries OTEL telemetry for cache_read_tokens and cache_creation_tokens and stores the rates in session state so the next turn’s cost calc can apply them. When no cache data is available, the hook falls back to the full input rate as a conservative estimate — and marks the displayed cost with a dim ~ prefix.

Per million tokens:

ModelInputOutputCache readCache write
Opus 4.6$15.00$75.00$1.50$18.75
Sonnet 4.6$3.00$15.00$0.30$3.75
Haiku 4.5$0.25$1.25$0.025$0.3125

If the model name doesn’t match any of the above, pricing falls back to the family (“opus” / “sonnet” / “haiku”); if that fails too, cost is omitted from the status line.

Runs when Claude Code launches.

  1. Reads the API key from CLAUDE_PLUGIN_OPTION_apiKey (Claude Code userConfig) or the legacy ~/.prism/config.json. If missing or malformed, prints a setup prompt and exits without blocking the session.
  2. Resolves ingest_url, gateway_url, and anthropic_base_url from the config cache (~/.prism/config-cache.json), falling back to a live fetch and then to production URLs.
  3. Detects the active OTEL config scope (user, project, both, or none) and re-syncs the OTEL env vars in that scope’s settings file if they’ve drifted. Warns if both scopes hold OTEL vars simultaneously.
  4. Writes runtime env to $CLAUDE_ENV_FILE so the current session picks up PRISM_GCK_KEY, PRISM_THRESHOLD, and — when gateway routing is on — ANTHROPIC_BASE_URL and ANTHROPIC_CUSTOM_HEADERS with the gateway API-key header.
  5. Prints a one-time notification when the plugin version has changed since the last session.
  6. Resets ${CLAUDE_PLUGIN_DATA}/session-state.json for the new session.
  7. Prints a confirmation line with the resolved ingest / gateway / Anthropic endpoints.

Runs before Claude processes each prompt.

  1. Lets /prism:… commands through immediately.
  2. If no API key is configured, prints a setup reminder and exits 0 (prompt still goes through).
  3. Prints the status line from the previous turn (saved by the Stop hook) and any queued alerts.
  4. For short / navigational / slash-command / shell-passthrough prompts, it skips nudge processing — but still captures the prompt to Ingest.
  5. Writes ~/.prism/advisor-context.json with current session metrics (turn count, token growth, response times, model mix) so /prism:advisor can tailor its advice.
  6. Emits a single context-management nudge if a threshold is crossed.
  7. Records the prompt submit timestamp (used by the next Stop hook to measure response time).
  8. Captures the prompt (first 2000 characters) to the Ingest service.

The submit hook always exits 0 — it never blocks your prompt.

Runs after Claude finishes a turn.

  1. Increments turnCount, accumulates token totals, tracks per-model turn counts, and flags Opus turns with < 200 output tokens.
  2. Computes the turn cost (see “How costs are computed”).
  3. Measures elapsed time between the prompt submit and the stop event.
  4. Builds the status line string and stores it in state.pendingStatusLine for the submit hook to display next turn. Queues periodic alerts in state.pendingAlerts.
  5. Asynchronously sends the response (first 2000 characters) + turn metadata to Ingest.
  6. Asynchronously queries OTEL telemetry for this session’s cache token data and stores the result in state.lastCacheData for the next turn’s cost calc.

Runs after /compact successfully completes. Resets the counters that measure since the last compaction:

  • turnCount, firstTurnInputTokens, lastTurnInputTokens
  • responseTimes, opusLowOutputCount, modelCounts
  • totalCost, lastCacheData
  • Any pending status line or alerts

So nudges restart from a clean baseline immediately after the compact.

Every hook catches its own exceptions and exits 0. Hooks are fail-open: if any step inside a hook fails, your session continues normally — you just might not see that turn’s status line, nudge, or alert. Detailed failure context is written to the plugin debug log (~/.claude/plugins/data/prism-inline/debug.log).

Prompt-quality scoring runs server-side (in the Prism Engine) after the prompt is captured; in-terminal prompt coaching is on-demand via /prism:advisor.