Documentation Index
Fetch the complete documentation index at: https://docs.trytrellis.app/llms.txt
Use this file to discover all available pages before exploring further.
Custom Hooks
Hook support varies by platform and by event — see the per-event matrix below.
SessionStarthook / extension ships on Claude Code, Cursor, OpenCode, Gemini CLI, Qoder, CodeBuddy, Copilot, Droid, Pi Agent (and Codex withfeatures.hooks = truein~/.codex/config.toml; Codex < 0.129 uses the legacycodex_hooks = true). Kiro’s Agent Hooks are user-configured — Trellis does not install any out of the box.PreToolUse/ extension sub-agent context injection ships on Claude Code, Cursor, OpenCode, CodeBuddy, Droid, Pi Agent. The other hook-capable platforms rely on a pull-based prelude inside each sub-agent instead.UserPromptSubmit/ workflow-state nudge ships on the same platforms asSessionStart.- Kilo, Antigravity, Windsurf have no hook primitive at all; behavior is delivered via workflow files + skills.
Hook types
| Hook | Trigger | Purpose |
|---|---|---|
SessionStart | A new session starts | Load context, initialize environment |
UserPromptSubmit | User submits a prompt | Nudge the AI toward the current task state |
PreToolUse | Before a tool invocation | Intercept, modify parameters, inject context |
PostToolUse | After a tool invocation | Log activity, trigger follow-up actions |
settings.json or hooks.json referencing Python scripts). OpenCode uses JS plugins (factory functions in .opencode/plugins/) with the same event semantics. Pi Agent uses .pi/extensions/trellis/index.ts instead of Python hook files. The rest of the hook-capable platforms (Codex, Gemini, Qoder, Copilot) run a session-start.py only — no PreToolUse — and configure it via a platform-native config file.
settings.json configuration (Claude Code)
Configure hooks in .claude/settings.json:
- Each event type is an array of
{ matcher, hooks }blocks. matcher: pattern to match ("startup"matches session start,"Task"matches Task tool calls,"*"matches everything).hooks: array of commands that run when matched, in order.$CLAUDE_PROJECT_DIR: expanded by Claude Code to the project root.timeout: seconds; if exceeded, the hook is skipped.
statusLine by default. New installs do not create .claude/hooks/statusline.py or add statusLine to .claude/settings.json. Existing projects that already have a statusLine keep it during update. If your project needs a custom status line, add a local Claude Code statusLine command manually; Trellis does not manage that file.
Shipped hooks
session-start.py: context loading
Trigger: SessionStart.
What it does:
- Reads
.trellis/.developerfor developer identity. - Reads
.trellis/workflow.mdfor the workflow contract. - Reads
.trellis/workspace/{name}/index.mdfor session history. - Reads
git logfor recent commits. - Reads active tasks.
inject-workflow-state.py: workflow-state nudge
Trigger: UserPromptSubmit.
What it does: parses [workflow-state:STATUS] blocks from .trellis/workflow.md and emits the body matching the active task’s status as a <workflow-state> preamble for the turn. Parser-only — the hook does not embed any fallback body text. When the active task’s status has no matching block, the hook emits the generic line Refer to workflow.md for current step. so the AI re-reads the workflow contract.
To customize per-turn wording, edit the [workflow-state:STATUS] block in .trellis/workflow.md. No script change required.
inject-subagent-context.py: spec injection engine
Trigger: PreToolUse, matching Task tool calls.
What it does:
- Intercepts Task tool calls.
- Reads the JSONL matching the
subagent_type(implement.jsonl,check.jsonl,research.jsonl). - Reads all files referenced in the JSONL.
- Assembles the sub-agent prompt (specs + requirements + original instructions).
- Each sub-agent receives its full context at launch; there is no resume.
- Only
trellis-*sub-agents are hooked; custom sub-agents must opt in by editing this file or using their own injection.
Pi extension: equivalent hook behavior
Pi Agent does not load.py hook scripts. Trellis writes .pi/extensions/trellis/index.ts, which implements the same three behaviors in extension form:
- session start context injection
- workflow-state breadcrumb injection
- sub-agent JSONL context injection
TRELLIS_CONTEXT_ID into Bash commands so task.py start/current/finish can resolve the correct .trellis/.runtime/sessions/<session-key>.json file for the current Pi session.
Writing a custom hook
Hooks receive JSON input on stdin and emit JSON results on stdout. Input format (PreToolUse example):Example: an auto-test hook
.claude/hooks/auto-test.py:
settings.json: