# Hook Creator

> Create and manage runtime command hooks declared in skills/*/hooks.json. Use when the user asks to intercept tool calls, augment prompts, audit or mutate tool arguments/results, add startup/shutdown scripts, or debug hook behavior.

- **Type:** Skill
- **Install:** `agentstack add skill-tkellogg-open-strix-hook-creator`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [tkellogg](https://agentstack.voostack.com/s/tkellogg)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [tkellogg](https://github.com/tkellogg)
- **Source:** https://github.com/tkellogg/open-strix/tree/main/open_strix/builtin_skills/hook-creator

## Install

```sh
agentstack add skill-tkellogg-open-strix-hook-creator
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Hooks

Hooks are short-lived commands that receive one runtime event as JSON on stdin and may write one JSON object to stdout to replace it. They live in skills as `hooks.json` files and are discovered at startup and when `reload_hooks` is called.

Use hooks for small runtime adapters:

- pre/post tool-call policy
- prompt augmentation before the model is invoked
- send_message shaping or audit
- metrics and local logging
- startup/shutdown setup and teardown

Do not use hooks for long-running services. Use UI plugins, pollers, supervisor jobs, or OS services for that.

## hooks.json

```json
{
  "hooks": [
    {
      "name": "message-policy",
      "command": "uv run python hook.py",
      "events": ["pre_tool_call", "post_tool_call", "pre_prompt"],
      "env": {},
      "timeout_seconds": 10,
      "include_conversation": false
    }
  ]
}
```

Valid events:

- `pre_tool_call`
- `post_tool_call`
- `pre_prompt`
- `pre_startup`
- `post_startup`
- `pre_shutdown`
- `post_shutdown`

There are no tool-name filters in `hooks.json`. Filter explicitly in the hook script:

```python
import json
import sys

event = json.loads(sys.stdin.readline())
if event.get("tool") != "send_message":
    print(json.dumps(event))
    raise SystemExit

event["args"]["text"] = event["args"]["text"].strip()
print(json.dumps(event))
```

## Contract

The hook process runs from the directory containing `hooks.json`.

Environment:

- `STATE_DIR`: the skill directory
- `HOOK_NAME`: the hook name
- `HOOK_EVENT`: the event type

Input:

- exactly one JSON object plus a newline on stdin

Output:

- stdout empty means no-op
- stdout containing a JSON object replaces the event for the next hook
- stderr is logged as `hook_stderr`

For `pre_tool_call`, returning an event with an `args` object changes the tool args before execution. For `post_tool_call`, returning an event with `result` changes the result shown to the agent after a successful tool call. For `pre_prompt`, returning `prompt` replaces the prompt, and returning `append_prompt` appends text to the prompt.

### Blocking a tool call with `_block`

A `pre_tool_call` hook may **reject the call entirely** by returning an event with an `_block` object:

```python
import json
import sys

event = json.loads(sys.stdin.readline())
if event.get("tool") == "send_message" and looks_bad(event["args"]):
    event["_block"] = {
        "reason": "shell-leak-prefix",
        "result": "[hook blocked] send_message text starts with `$(...)` — that ships as a literal string, not a shell command. Read the file and inline the contents, or attach via attachment_paths.",
    }
print(json.dumps(event))
```

When `_block` is set with both `reason` (string) and `result` (string), the wrapped tool is **not invoked**. The agent receives `result` as if it were the tool's own return value — so the agent sees the diagnostic next turn and can self-correct. A `hook_blocked_tool_call` event is logged, and post_tool_call hooks see `status="blocked"` with the same synthetic result.

This is the right verb when a hook needs to **prevent** a bad call rather than mutate it. Args-mutation is fine when the call should still happen but with different inputs; `_block` is for "this call must not happen — tell the agent why."

Invalid `_block` specs (missing fields, wrong types) are logged via `hook_invalid_block` and the call proceeds normally. This guards against silent drops from malformed hook output.

Set `include_conversation: true` only for hooks that need transcript context. The hook event then includes:

- `conversation.all_messages`
- `conversation.channel_messages`
- `conversation.current_channel_id`

When `logs/chat-history.jsonl` exists, this is loaded from the persisted chat transcript. This is intentionally opt-in because full transcripts can be large.

## Reload

After creating or editing `hooks.json`, call:

```text
reload_hooks()
```

## Debugging

Check `logs/events.jsonl` for:

- `hook_invalid_json`
- `hook_invalid_format`
- `hook_missing_fields`
- `hook_timeout`
- `hook_exec_error`
- `hook_stderr`
- `hook_nonzero_exit`
- `hook_blocked_tool_call`
- `hook_invalid_block`
- `hook_invalid_mutation`
- `hook_invalid_output`
- `hook_invalid_mutation`

Keep hooks small and deterministic. Short scripts are easier to reason about than daemons hiding in the tool path.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [tkellogg](https://github.com/tkellogg)
- **Source:** [tkellogg/open-strix](https://github.com/tkellogg/open-strix)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-tkellogg-open-strix-hook-creator
- Seller: https://agentstack.voostack.com/s/tkellogg
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
