Skip to main content
Agents spend tokens every time they fetch context at runtime — cloning repos, listing issues, calling APIs. Hooks let you stage this data before the LLM session starts, so the agent begins with everything it needs.

The Problem

Without hooks, a typical agent run looks like:
  1. LLM starts
  2. LLM runs git clone (waits, uses tokens to read output)
  3. LLM runs gh issue list (waits, uses tokens to parse JSON)
  4. LLM starts actual work
Steps 2-3 are mechanical — the agent always needs to do them, and they don’t benefit from LLM reasoning.

The Solution: Hooks

Pre-hooks run after credentials are loaded but before the LLM session starts. They execute inside the container with full access to credentials and environment variables. Define them in the agent’s config.toml:
# agents/<name>/config.toml
[hooks]
pre = [
  "gh repo clone acme/app /tmp/repo --depth 1",
  "gh issue list --repo acme/app --label bug --json number,title,body --limit 20 > /tmp/context/issues.json",
]
Then reference the staged files in the body of your SKILL.md:
## Context

- The repo is cloned at `/tmp/repo`
- Open bug issues are at `/tmp/context/issues.json`

Example: Git clone

The most common hook — clone the repo the agent will work on:
[hooks]
pre = ["gh repo clone acme/app /tmp/repo --depth 1"]

Example: Shell command

Run any shell command. GITHUB_TOKEN, GH_TOKEN, and other credential env vars are already set:
[hooks]
pre = ["gh issue list --repo acme/app --label P1 --json number,title,body --limit 20 > /tmp/context/issues.json"]

Example: HTTP fetch

Fetch data from an API endpoint:
[hooks]
pre = ["curl -sf -H 'Authorization: Bearer ${INTERNAL_TOKEN}' https://api.internal/v1/feature-flags -o /tmp/context/flags.json"]
Environment variable interpolation (${VAR_NAME}) is supported since commands run via /bin/sh.

Post-hooks

Post-hooks run after the LLM session completes. Use them for cleanup, artifact upload, or reporting:
[hooks]
pre = ["gh repo clone acme/app /tmp/repo --depth 1"]
post = [
  "upload-artifacts.sh",
  "curl -X POST https://hooks.slack.com/... -d '{\"text\": \"Agent run complete\"}'",
]

Referencing Staged Files in SKILL.md

After hooks run, tell the agent what’s available in the body of your SKILL.md:
## Context

- The repo is cloned at `/tmp/repo`
- Open P1 issues are at `/tmp/context/issues.json`
- Feature flags (if available) are at `/tmp/context/flags.json`

Direct Context Injection

For simple, inline data that needs to be embedded directly in your SKILL.md instructions, use direct context injection with the !`command` syntax. Commands are executed after pre-hooks but before the LLM session starts, and their output replaces the expression inline.

Syntax

The current time is !`date`.
There are !`ls /tmp/repo/src | wc -l` source files in the repo.
Becomes:
The current time is Mon Mar 22 21:30:45 UTC 2026.
There are 42 source files in the repo.

When to use

  • Hooks: For setup tasks like cloning repos or downloading data files
  • Direct injection: For inline values the agent needs to reference in instructions

Examples

Basic usage:
You are analyzing code at !`date +"%Y-%m-%d %H:%M"`.
With pre-staged data:
[hooks]
pre = ["gh issue list --repo acme/app --label bug --json number --limit 20 > /tmp/issues.json"]
There are !`cat /tmp/issues.json | jq length` open bug issues to work on.
Error handling: If a command fails, it’s replaced with [Error: <message>]:
Config value: !`cat /nonexistent/file`
Becomes:
Config value: [Error: cat: can't open '/nonexistent/file': No such file or directory]

Limitations

  • Commands have a 60-second timeout
  • Output is limited to prevent prompt explosion
  • Errors are inline — use hooks for critical setup that should fail the run

Tips

  • Hooks run sequentially in the order defined in config.toml
  • Each hook has a 5-minute timeout — hooks are also bounded by the container-level timeout
  • If a command fails (non-zero exit), the run aborts with an error
  • Environment variables set inside hook commands do not propagate back to the agent’s process.env
  • Use hooks for setup, direct injection for values — hooks for cloning repos or staging files, direct context injection for inline dynamic values the agent needs to reference

Next steps