Shell environment
🦉 HooKit
Reference

Shell environment

The environment variables every reached Hook shell receives.

Every reached when and main shell inherits the ambient environment plus bounded Pi metadata and Invocation fields. HooKit clears its managed keys from the ambient environment before each real shell, so stale parent values cannot leak into a decision.

Invocation and event fields

VariableAvailableMeaning
PI_HOOK_REFevery reached shellSource-qualified Hook Reference (local/no-env-access).
PI_HOOK_EVENTevery reached shellThe Hook’s configured Event.
PI_HOOK_INVOCATION_IDevery reached shellIdentity shared by this Invocation, its Hook Result, Action Request, and projected Hook Result Event.
PI_EVENTevery reached shellThe Event being evaluated.
PI_CWDevery reached shellThe project working directory.
PI_TOOL_NAMEtool EventsThe tool name being called or returning.
PI_TOOL_CALL_IDtool EventsThe tool call identity.
PI_TOOL_INPUTtool EventsThe tool input as JSON text.
PI_TOOL_RESULTtool_resultThe tool’s text content joined with newlines.
PI_TOOL_IS_ERRORtool_result"true" or "false".
PI_EVENT_PAYLOADlifecycle Events and hook_resultJSON object containing exactly the bounded Event candidate fields listed below.

All environment values are strings. PI_TOOL_INPUT is serialized JSON, not shell words; quote it and parse it with a JSON parser. PI_TOOL_RESULT contains only text blocks, joined with \n; images and other content blocks are omitted. PI_TOOL_IS_ERROR describes the original result before HooKit’s replacement. Unavailable or inapplicable managed fields are absent, not inherited from the parent and not filled with placeholder "undefined" or "null" strings.

Event payload formats

EventPI_EVENT_PAYLOAD fields
turn_endevent: "turn_end", numeric turnIndex
agent_endevent: "agent_end"
agent_settledevent: "agent_settled"
session_before_switchevent, reason: "new" or "resume", optional string targetSessionFile
session_before_forkevent, string entryId, position: "before" or "at"
hook_resultevent: "hook_result", string hookRef, string invocationId, canonical outcome, numeric or JSON null code

Tool Events use their PI_TOOL_* variables instead of PI_EVENT_PAYLOAD. For hook_result, the payload identifies the originating Hook Result; PI_HOOK_REF and PI_HOOK_INVOCATION_ID identify the handler’s own Hook Invocation. Do not confuse those two identities.

Captured session metadata

When available, HooKit snapshots bounded session, model, provider, reasoning, trust, and context values before evaluation:

VariableMeaning
PI_SESSION_IDCurrent session id.
PI_SESSION_FILECurrent session path.
PI_SESSION_NAMECurrent session name.
PI_SESSION_LEAF_IDCurrent session leaf id.
PI_PROVIDERActive model provider.
PI_MODELActive model id.
PI_REASONING_LEVELReasoning level, when the runtime exposes it.
PI_MODEActual Pi mode: tui, rpc, json, or print. See Runtime modes.
PI_PROJECT_TRUSTED"true"/"false" when the runtime can report project trust.
PI_CONTEXT_TOKENSCurrent context token count as a numeric string, when reported.
PI_CONTEXT_WINDOWConfigured context window as a numeric string, when reported.
PI_CONTEXT_PERCENTContext usage percentage as a numeric string (no % suffix), when reported.

Metadata is captured once per Evaluation from Pi’s rich callback context and projected onto these bounded scalar names—rich callback objects are not exposed to shells. Session/model/provider/reasoning values are plain strings; context metrics use JavaScript’s String(number) representation of finite numbers. Missing session names, model data, or context usage remain absent.

Optional environment diagnostics

Set PIHOOKIT_LOG_ENV=true in Pi’s ambient environment before launch to append projected Event environments as JSON Lines under ~/.pi/agent/.hook-env-log/YYYY-MM-DD.jsonl (the configured Pi agent directory is used when customized). Each record contains ts, event, and env. This is an opt-in diagnostic switch, not a managed Hook metadata key. Logging failures cannot change an Outcome.

Sensitive data warning: tool inputs and results may contain credentials or private source text. Environment logs can disclose them; review, protect, and remove logs appropriately. Prefer dummy data for debugging.

Example—a tool_call Hook that rejects a suspicious piped command:

{
  "local": {
    "inspect-bash": {
      "description": "Inspect every bash command once",
      "event": "tool_call",
      "filter": { "toolName": "^bash$" },
      "when": "test \"$PI_HOOK_REF\" = local/inspect-bash",
      "shell": "if echo \"$PI_TOOL_INPUT\" | grep -q 'rm -rf'; then exit 1; fi"
    }
  }
}

A when and its main shell share one Invocation ID, so both see the same PI_HOOK_INVOCATION_ID. Owned Actions share the owner’s source-qualified ref and Invocation ID but carry only static payload—they never receive shell output or interpolated variables.