Hook Development for Claude Code Plugins
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
Rewrite the active Pneuma session's UI title + one-line summary so the launcher and ProjectPanel rows reflect what the session is actually about.
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install pandazki/pneuma-skills pneuma-session --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .claude/skills/pneuma-session && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .claude/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-sessionType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install pandazki/pneuma-skills pneuma-session --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .agents/skills/pneuma-session && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .agents/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install pandazki/pneuma-skills pneuma-session --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .cursor/skills/pneuma-session && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .cursor/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/pandazki/pneuma-skills.git --path modes/_shared/skills/pneuma-session--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install pandazki/pneuma-skills pneuma-session --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .gemini/skills/pneuma-session && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .gemini/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install pandazki/pneuma-skills pneuma-sessionInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .github/skills/pneuma-session && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .github/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pandazki/pneuma-skills --skill pneuma-session -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install pandazki/pneuma-skills pneuma-session --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pandazki/pneuma-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/modes/_shared/skills/pneuma-session .opencode/skills/pneuma-session && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "pneuma-session" agent skill from https://github.com/pandazki/pneuma-skills/tree/main/modes/_shared/skills/pneuma-session into .opencode/skills/pneuma-session/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pneuma-session", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
pneuma-sessionRewrite the active Pneuma session's UI title + one-line summary so the launcher and ProjectPanel rows reflect what the session is actually about.
Pneuma Session is an agent skill from pandazki/pneuma-skills. Rewrite the active Pneuma session's UI title + one-line summary so the launcher and ProjectPanel rows reflect what the session is actually about. Use this skill whenever the user asks to "整理 / 概括 / refresh / re-title / summarize this session", whenever the conversation has produced substantive work and the default title ("WebCraft session") is now uninformative, or before the user pauses a long session — the next time they reopen it, the row needs to say more than "<pneuma:env reason='opened'". Cheap to run…
Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It works with Bash. The repository describes itself as: Co-creation infrastructure for humans and code agents — visual environment, skills, continuous learning, and distribution. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 0023d3c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are bash).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Pneuma Session loads about 2.8k tokens when it runs. Until then it costs about 143 tokens; SKILL.md has 1,482 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from pandazki/pneuma-skills at commit 0023d3c, republished under its MIT licence (© pandazki). 1,482 words, ~2,760 tokens.
.claude/skills/pneuma-session/SKILL.md (or your agent's skills folder).Every Pneuma session has a row in the launcher (Recent Sessions) and inside its project (ProjectPanel). The row has two slots:
"<Mode> session" (e.g. "WebCraft session"). Mode-only.<pneuma:env reason="opened" /> synthetic tag — which carries zero information for a human scanning the list.Until you refine, both fields are placeholders. Three "WebCraft session" rows look identical except for their thumbnails. The user has to remember by time, which they won't.
This skill is how you fix that. You write a meaningful title + one-sentence summary into <sessionDir>/session.json, and the launcher row updates in place. The data persists across reopens; the launcher's own listing always reads from your last refine.
$PNEUMA_CLI session refine --json '{"displayName": "<≤40 chars>", "description": "<≤280 chars>"}'Always call through the $PNEUMA_CLI env var, not the literal pneuma binary. The env var resolves to the right invocation regardless of how Pneuma was installed (npm-global, dev worktree, desktop bundle); writing the literal pneuma session refine only works when the binary happens to be on PATH, which it usually isn't inside the agent's sandbox. $PNEUMA_CLI is a single executable path, so the call behaves the same in bash, zsh, and fish, quoted or unquoted.
The command POSTs to the running Pneuma server (via $PNEUMA_SERVER_URL), which atomically rewrites <sessionDir>/session.json, syncs the global registry at ~/.pneuma/sessions.json, and broadcasts an event so any open browsers refresh the row without a reload.
Both fields are optional. Sending just displayName rewrites only the title; just description rewrites only the summary. Send both when the session has changed enough to warrant a fresh pair. The server validates lengths and rejects empties.
Run it from your default Bash tool. It's a one-shot HTTP call — no background process, no follow-up needed. On success the command prints Session meta refined. and exits 0; on failure it prints the server's error to stderr and exits non-zero.
The goal is to make the row useful to a human scanning a list a week from now. Two principles:
Describe the session, not the work. The row is a session identifier, not a worklog. Write what the session is about, the user-facing concern, not the sequence of edits you made.
| Don't | Do |
|---|---|
| "Implemented three React hooks" | "加载状态卡片调研" |
| "Edited hero.html 7 times" | "Hero section landing-page iteration" |
| "Created file pricing.html and modified manifest.json" | "Pricing page draft for the launch site" |
Match the user's register. If the user has been writing in Chinese, the refined title should be in Chinese too — they're scanning their own list. If the project's displayName in project.json is English, English is fine. Read the room.
The new title. Short. A scannable label, not a sentence. Capitalize as you would a headline. No trailing period.
Replacement, not augmentation — the mode is shown via the row's icon (and a hover tooltip), so don't prefix with "WebCraft · ". Just the topic.
Good shapes:
加载状态卡片调研Hero section iterationPricing page · v3 layout负熵痕迹 · 写作框架If the user has explicitly renamed the session (via --session-name or a future rename UI), your displayName is recorded but the explicit name still wins in the listing — user intent beats inference. You don't need to detect this; the server handles precedence.
The new summary. One or two sentences. Should fit on one line in the row, with the second sentence as overflow on hover. Plain prose, no markdown.
Tell a user re-encountering this row in a week: "what was I doing here?" and "should I open it?". Concrete enough to disambiguate from sibling sessions, abstract enough to survive minor reshuffles.
Good shapes:
Iterating on three loading-state card variants for the dashboard's data-fetching screens. Picked a skeleton + shimmer combo; still tuning the timing curve.Drafting the hero section for the launch site. Brand voice: "calm and clinical and careful". Holding on grayscale palette until copy lands.负熵痕迹(写作框架)的第一稿,聚焦"代码 agent 留下的 entropy 痕迹"这条主线。结构定了三段,标题待定。You'll find two natural triggers. Both go through the same CLI; only the framing differs.
Phrases like:
Run $PNEUMA_CLI session refine synchronously (no subagent). The user is asking right now; they're waiting for confirmation. Read the conversation so far, compose displayName + description, call the CLI, then reply with a one-line acknowledgment showing the new title.
The intent here is: when the row would actually be more useful with a refined title than the default, refine. When it wouldn't, don't. Default to not refining — premature refines write a title before the session has a clear shape, and you'll either churn it later or leave a misleading row.
Strong signals to refine:
"<Mode> session".Weak signals (don't refine on these alone):
When you decide to refine proactively, use a subagent so the main turn isn't blocked. Use the active harness's delegation tool, when available, to create a fresh worker that reads the project atlas + the conversation so far and writes the refined fields. Pattern:
1. Identify that a refine would be useful.
2. Launch a subagent with the available delegation tool. Brief it:
- "Read $PNEUMA_PROJECT_ROOT/.pneuma/project.json and project-atlas.md."
- "Read the current conversation transcript above this prompt."
- "Compose displayName (≤40 chars) and description (≤280 chars) describing
what this session is *about* — the user-facing concern, in the user's
language. Don't list what was done."
- "Run: $PNEUMA_CLI session refine --json '<your json>'. Print the result and stop."
3. The subagent returns; you don't need to mention the refine to the user
unless the user asks. The row updates silently.If delegation is unavailable in the active harness, do the refine inline at a natural pause — between two unrelated turns, or right before you hand the conversation back to the user with a question. Don't refine mid-task; the user is watching you work.
Refining once at the right moment is far better than refining many times. As a soft cap: don't refine more than once per ~20 user turns unless the user asks or the session's topic genuinely changed (a pivot — different feature, different deliverable). A row that flickers between titles is worse than a stale one.
"<Mode> session" is the right title for an empty session — anything else is a lie.--session-name on launch). Your displayName write is recorded but doesn't change the listing; the noise isn't worth it. Still send a description if you have a good one.Compose the refined fields from these sources:
$PNEUMA_PROJECT_ROOT/.pneuma/project.json (project sessions only). The project's displayName + description set the surrounding context. Your session is a part of this — refine accordingly. Don't repeat the project name verbatim in your session title; the row is already inside the project's scope.$PNEUMA_PROJECT_ROOT/.pneuma/project-atlas.md (project sessions only, when present). The atlas describes the project's whole landscape — anchors, deliverables, open questions. Use it to figure out which slice of the project this session is hitting.SKILL.md at the concrete backend-specific path named in your injected instructions if you need a refresher on what the mode's job is. The title should still be domain-specific, not mode-specific.You do not read other sibling sessions in the project. Cross-session inference is out of scope for this skill — each session refines itself.
Open the launcher. Find your session's row. The title and the line below it together should answer "what is this session about, in a way that distinguishes it from the other rows around it?" If yes, the refine landed. If you scan the row and still can't tell what's going on, the description is too abstract; revise.
Three project sessions, all WebCraft:
Hero section · cinematic variant / "Trying a darker hero direction with type-driven impact; layered on the existing palette so a rollback is one file."Pricing page draft v3 / "Three-tier comparison with annual/monthly toggle. Holding on copy until the legal team weighs in."Footer + nav rebuild / "Replacing the placeholder footer + collapsing the nav from 6 items to 4. Affects every page; will need a polish pass after."All three are clearly distinct topics in the same project. That's the bar.
© pandazki, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in modes/_shared/skills/pneuma-session of pandazki/pneuma-skills.
Open the folder on GitHubat commit 0023d3c
Pneuma Session next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Pneuma Session this skillpandazki/pneuma-skills | 161 | — | ~2.8k | Automated safety check: Pass | MIT | |
| Hook Development for Claude Code Pluginsanthropics/claude-plugins-official | 38k | 10 repos | ~4.1k | Automated safety check: Notes | Apache-2.0 | |
| Plugin Settings Patternanthropics/claude-plugins-official | 38k | 7 repos | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Mole Bug Patternstw93/Mole | 70k | — | ~2k | Automated safety check: Pass | GPL-3.0 | |
| Neat-Freak Knowledge CloseoutKKKKhazix/khazix-skills | 21k | — | ~1.9k | Automated safety check: Pass | MIT | |
| E2Ecallstack/react-native-pager-view | 3.4k | 1 repos | ~2.1k | Automated safety check: Pass | MIT |
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
anthropics/claude-plugins-official
Shows how Claude Code plugins keep per-project settings and state in .claude/plugin-name.local.md files with YAML frontmatter and a markdown body.
tw93/Mole
A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.
KKKKhazix/khazix-skills
Brings project docs, agent rule files, authorized memory and leftover workspace files back in line with what the code and runtime actually do at the end of a work session.
callstack/react-native-pager-view
Agentic end-to-end tests with e2e, the e2e runner. An agent skill from callstack/react-native-pager-view.
automazeio/ccpm
Runs a spec-driven workflow from PRD to epic to GitHub issues to parallel agents, with status, standup and blocked-work reports from bundled scripts.
pandazki/pneuma-skills
Explain something by writing it on a board. An agent skill from pandazki/pneuma-skills.
pandazki/pneuma-skills
AI-orchestrated video production on @pneuma-craft. An agent skill from pandazki/pneuma-skills.
pandazki/pneuma-skills
Pneuma Lucid Mode workspace guidelines. An agent skill from pandazki/pneuma-skills.
pandazki/pneuma-skills
Pneuma Plotwise workspace guidelines. An agent skill from pandazki/pneuma-skills.
pandazki/pneuma-skills
Pneuma Sprite Mode workspace guidelines. An agent skill from pandazki/pneuma-skills.
pandazki/pneuma-skills
Pneuma WebCraft Mode workspace guidelines with Impeccable.style design intelligence.
Works with
Rewrite the active Pneuma session's UI title + one-line summary so the launcher and ProjectPanel rows reflect what the session is actually about. Pneuma Session is an agent skill from pandazki/pneuma-skills. Rewrite the active Pneuma session's UI title + one-line summary so the launcher and ProjectPanel rows reflect what the session is actually about.
Pneuma Session fits situations like: the user asks to 整理 / 概括 / refresh / re-title / summarize this session; whenever the conversation has produced substantive work and the default title (WebCraft session) is now uninformative; before the user pauses a long session — the next time they reopen it; the row needs to say more than <pneuma:env reason=opened.
Run `npx skills add pandazki/pneuma-skills --skill pneuma-session -a claude-code`. Or copy the skill folder (modes/_shared/skills/pneuma-session in pandazki/pneuma-skills) into .claude/skills/pneuma-session in your project. Claude Code loads it when a task matches its description.
Run `npx skills add pandazki/pneuma-skills --skill pneuma-session -a codex`. Or copy the skill folder (modes/_shared/skills/pneuma-session in pandazki/pneuma-skills) into .agents/skills/pneuma-session in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add pandazki/pneuma-skills --skill pneuma-session -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pneuma-session, .gemini/skills/pneuma-session, .github/skills/pneuma-session and .opencode/skills/pneuma-session in your project.
SKILL.md names no scripts, command-line tools or credentials: Pneuma Session is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Pneuma Session is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Pneuma Session: Hook Development for Claude Code Plugins (anthropics/claude-plugins-official, 38k stars), Plugin Settings Pattern (anthropics/claude-plugins-official, 38k stars), Mole Bug Patterns (tw93/Mole, 70k stars) and Neat-Freak Knowledge Closeout (KKKKhazix/khazix-skills, 21k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
pandazki (a GitHub user) maintains it in pandazki/pneuma-skills, which has 161 GitHub stars. The repository holds 30 skills in this directory. The repository was last updated on October 9, 2026.
Source: pandazki/pneuma-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.