ワンクリックで
shelley-hooks
Use when the user wants to customize Shelley by injecting behavior at lifecycle events. It documents Shelley's hooks.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when the user wants to customize Shelley by injecting behavior at lifecycle events. It documents Shelley's hooks.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | shelley-hooks |
| description | Use when the user wants to customize Shelley by injecting behavior at lifecycle events. It documents Shelley's hooks. |
Executable files at ~/.config/shelley/hooks/<name>. Missing or non-executable files are ignored. 30s timeout. Any hook failure (non-zero exit, invalid output, etc.) aborts the operation it belongs to — except end-of-turn, where the operation is already finished, so failures are just logged.
Auth-bearing headers (Cookie, Set-Cookie, Authorization, Proxy-Authorization) are stripped from the headers fields before hooks see them.
system-promptRuns on every system prompt (main, subagent, orchestrator, orchestrator-subagent).
new-conversationRuns once when a conversation is created: user-initiated or the first run of a new subagent.
stdin JSON:
{
"prompt": "...", "model": "...", "cwd": "...",
"readonly": {
"conversation_id": "cXXXXXX",
"is_subagent": false, "parent_id": "...",
"is_orchestrator": false,
"headers": [["X-Exedev-Email", "user@example.com"]]
}
}
parent_id is omitempty. headers is a sorted list of [name, value] pairs (multi-valued headers produce multiple pairs); omitted for subagent and other non-HTTP entry points.
stdout: same top-level shape. Only prompt/model/cwd/slug are read; empty fields mean no change; readonly is ignored. Empty stdout = no-op.
Applied when non-empty and changed:
cwd → conversation's working directorymodel → re-resolves LLM service; falls back to original if unsupportedprompt → first user message (ignored on distillation paths)slug → sanitized to a slug-safe form; falls back to async slug on collisionchat-messageFires when the user posts a follow-up chat message to an existing conversation (POST /api/conversation/<id>/chat). For the first message of a brand-new conversation, use new-conversation. Not fired for subagent conversations.
stdin JSON:
{
"message": "the user's chat message",
"readonly": {
"conversation_id": "cXXXXXX",
"model": "claude-sonnet-4.5",
"reasoning_level": "high",
"queued": false,
"headers": [["X-Exedev-Email", "user@example.com"]]
}
}
reasoning_level is the conversation's explicit reasoning level (off, minimal, low, medium, high, or xhigh), or the service's configured default when no override is set. It is empty only when the provider chooses the default dynamically and Shelley cannot know it in advance. queued is true when the message will be queued (client requested queue mode or the agent is distilling) rather than interrupting the current turn.
stdout: {"message": "..."}. Empty stdout, empty message, or an identical message means no change.
end-of-turnFires when an agent finishes a turn — the same signal that drives end-of-turn notifications (notification channels, push notifications, conversation-hook webhooks). Suppressed for subagent conversations. Stdout is ignored.
stdin JSON:
{
"type": "end_of_turn",
"conversation_id": "cXXXXXX",
"timestamp": "2024-01-02T03:04:05Z",
"hostname": "host.exe.xyz",
"model": "claude-sonnet-4.5",
"slug": "my-slug",
"conversation_url": "https://host.exe.xyz/c/my-slug",
"vm_name": "host",
"final_response": "agent's last text or tool-call summary"
}
Typical uses: play a sound, post a desktop notification, ping a local script.
slash/<command>Pluggable slash commands. When a user sends a message that starts with
/<command> (where <command> matches [a-zA-Z0-9_][a-zA-Z0-9_-]*), Shelley
looks for an executable at ~/.config/shelley/hooks/slash/<command>. If
present, it is run synchronously before the message is recorded or sent to
the LLM. Its stdout replaces the user-message body. Empty stdout leaves the
original message unchanged. Applies to both new conversations and follow-up
messages.
No matching executable → the message is treated as a normal user message (no special handling).
stdin JSON:
{
"command": "foo",
"args": "the rest of the message after /foo",
"raw_message": "/foo the rest of the message after /foo",
"conversation_id": "cXXXXXX",
"is_new_conversation": false,
"cwd": "/home/user/project",
"model": "claude-sonnet-4.5",
"user_email": "you@example.com",
"is_orchestrator": false
}
The same context is also exposed via environment variables for shell-friendly
hooks: SHELLEY_SLASH_COMMAND, SHELLEY_SLASH_ARGS,
SHELLEY_CONVERSATION_ID, SHELLEY_CWD, SHELLEY_MODEL,
SHELLEY_USER_EMAIL.
stdout: replacement user-message text. Empty stdout keeps the original message (useful for hooks that only have side effects). Failure (non-zero exit) surfaces as a 400 to the client and the message is not recorded.
Example: a ~/.config/shelley/hooks/slash/files hook that injects the
contents of files matched by a glob:
#!/bin/sh
set -e
printf 'Here are the files you asked about:\n\n'
for f in $SHELLEY_SLASH_ARGS; do
printf '=== %s ===\n' "$f"
cat "$f"
printf '\n'
done
Then /files src/main.go src/util.go please summarize becomes a normal user
message with file contents inlined.
Use when the user asks for a diagram, sketch, flowchart, architecture diagram, sequence diagram, mind map, or other visual explanation. Renders hand-drawn-style diagrams from Excalidraw JSON via the output_iframe tool.
Use to discover external services and APIs available on this exe.dev VM via network-edge-injected credentials and to discover VM metadata like owner email, VM tags, and default port.
Use when the user needs Node.js or npm installed, or is running a JS framework dev server (Next.js, Vite, webpack, etc.) on an exe.dev VM — especially if the browser logs 'WebSocket ... failed', or the dev server complains about cross-origin requests, allowedDevOrigins, or allowedHosts.
Use when the user references a previous conversation, asks you to continue earlier work, or you need to look up what was discussed before.
Use when a user requests a task to be done later or on a schedule.