Six steps
Background on hooks, and on what function hooks change, is in the complete Claude Code hooks guide. What the skill used here can build beyond a redactor is in what /plugin-authoring unlocks.
Step 1. What you need
- →Claude Code 2.1.260 or later inside the desktop app. Updating the app updates the bundled Claude Code. The function hooks runtime and the built-in skill are both inside that build.
- →A local session. Function hooks run in the session's own process on the machine. Cloud sessions do not read the settings file where the switch lives.
- →A throwaway key for the test. A random string with a real key's shape is enough. Never test with a production credential.
Step 2. Turn the preview on
Function hooks are gated behind an environment variable. The desktop app does not read a shell profile for arbitrary variables, so the variable goes into the user settings file, where the env key applies to every session. Open ~/.claude/settings.json (on Windows, %USERPROFILE%\.claude\settings.json) in the desktop file pane, or ask Claude in any session to add this block while keeping the keys already there:
{
"env": {
"CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1"
}
}The alternative is the local environment editor: open the environment dropdown next to the prompt box, hover Local, click the gear, and add the same variable with the value 1.
To confirm it took, start a new local session, type /, and look for plugin-authoring in the list. On the machine this guide was tested on, the skill appeared in an already running session within seconds of the settings edit; a new session is the safe assumption.
Step 3. Hand the skill one prompt
In a local session, send the message below as one paragraph. The skill reads the plugin contract for the running build, generates the type declarations it needs, and writes the plugin into the user-level skills folder, which is where the desktop app auto-loads plugins from.
/plugin-authoring Build a plugin that redacts any secret I paste into this session before it reaches the transcript, replaces each one with a short placeholder like <SECRET_1>, and makes it so the session can still use the real value when it runs a command or calls an API with that placeholder. Detect known API key shapes and anything that looks like a random high-entropy token. Keep the real values in memory only, never on disk and never in the persistent store. Tell the model in a hidden note that placeholders are substituted at run time so it never asks me to paste the value again. Show me a one line notice whenever something was redacted. Put the plugin in my user skills folder so it loads in every session.
Three of those sentences do real work. "Never in the persistent store" matters because the plugin store is a file on disk. The hidden note to the model matters because without it the model tends to ask for the key again. And the user skills folder matters because a project-level folder is not scanned for function hook modules in the current preview.
In Ray Amjad's September 2026 walkthrough, the equivalent prompt produced a working plugin of roughly 300 lines with an in-memory store at the top, and a pasted Anthropic key was replaced by a placeholder the moment Enter was pressed. The request Claude then built with the placeholder still succeeded.
Want the version from the video?
Step 4. Read what it built
Every function hook plugin has the same shape, so the result is easy to check even without reading the code line by line. Ask Claude to open the folder it created, usually ~/.claude/skills/transcript-redactor/ or a similar name, and look for:
- →A manifest at
.claude-plugin/plugin.jsonwith the plugin's name and description. - →A hooks manifest at
hooks/hooks.jsonthat names one module under amoduleskey. That one line is what makes it a function hook plugin rather than a classic one. - →The module itself, a TypeScript file that exports
registerand registers two hooks: one onprompt.submitthat swaps secrets for placeholders, and one ontool.callthat swaps them back inside commands and scrubs any real value out of the tool's output. - →A vault that is a plain in-memory map, not a call to the store and not a file. If the module writes secrets anywhere, ask it to change that.
A short question does the review: "Explain what each hook in this plugin does and confirm that no real value is ever written to disk." Then load it. Send /reload-plugins, or start a new session, and check the + menu next to the prompt box: the plugin appears under Plugins with @skills-dir after its name. A dim line from the plugin also appears in the transcript at session start if the prompt's notice request was honoured.
If nothing seems to happen
Step 5. Test it with a throwaway key
Four checks, in one session, with a random string shaped like a real key:
- Redaction. Paste the throwaway key in a sentence and send it. The message should show
<SECRET_1>where the key was, a notice should report one redacted value, and the reply should refer to the placeholder instead of asking for the key. - Use. Ask Claude to make a request with the placeholder, the way the video asks a model for a short story with the pasted key. The request should succeed, because the real value is put back the moment the command runs.
- Output. Ask Claude to print the placeholder with a shell command. The shell prints the real value, and the tool result Claude sees should show the placeholder again.
- Disk. Ask Claude to find the session's transcript file under
~/.claude/projects/and count how often the key's first characters appear, spelling those characters with spaces in the request so the request itself does not put them in the file. Zero is the pass.
Let a fresh session run the checks
Step 6. Tune it by asking
Changes are follow-up messages to the same skill, followed by /reload-plugins. Reloading empties the in-memory vault, so keys have to be pasted again afterwards. Useful asks:
/plugin-authoring Also redact email addresses and IPv4 addresses in this plugin, with <EMAIL_n> and <IP_n> placeholders.
/plugin-authoring Make sure git commit hashes, article slugs, and long URL path segments are never treated as secrets. Add a small test file I can run with Node that proves it.
/plugin-authoring Show the redaction notice as a toast under the prompt as well as a transcript line, and pin a status line with the number of values currently held in memory.
/plugin-authoring Add the key shapes for Stripe, Resend, Supabase, Apify, and GitHub tokens to the known patterns.
To pause the plugin without deleting it, ask Claude to disable it by name, or run the bundled binary's plugin disable command from the integrated terminal. To remove it, delete the folder. To turn the whole preview off, delete the env block from the settings file.
What to keep in mind
- →The redactor sees prompts and tool calls. A secret that arrives inside a file the model reads is caught only if it is already in the vault from a paste.
- →A key that was already exposed anywhere still needs rotating. The plugin prevents the next leak, not the last one.
- →The API is early access. Regenerate the plugin's types after an app update by asking the skill, and expect the odd change between releases.
- →The whole system fails open by design in this preview. A broken redactor does not block the session; it simply stops redacting, and only the debug log says so.
FAQ
Do I need to write any code?+
No. The built-in plugin-authoring skill writes the plugin from the prompt in this guide. Reading what it wrote is worth ten minutes, and the guide says what to look for, but nothing has to be typed by hand.
Where do the real secrets go?+
Into the plugin's own memory for the length of the session, if the prompt is followed as written. They are not written to disk and not sent to the model. Reloading the plugin or starting a new session empties that memory, so old placeholders stop resolving and the value has to be pasted again.
Does this replace rotating a key that already leaked?+
No. The redactor stops the next leak. A key that has already been exposed anywhere should still be rotated.
Is this a shipped feature?+
No. Function hooks are a proposal opened by an Anthropic engineer on September 3, 2026, with a preview runtime in Claude Code 2.1.260 and later behind an environment variable. The API is marked early access and can change, and a hook that fails is skipped silently in the current preview.
Can it also hide emails and IP addresses like the version in the video?+
Yes, by adding one sentence to the prompt. It is left out of the default prompt here because a session that drafts outreach or checks address lists needs to see them. Add it back if the transcript is shared or recorded.
Sources
- Anthropic, Hooks reference and Automate actions with hooks (Claude Code documentation)
- Anthropic, Plugins reference, including skills-directory plugins, and Desktop application
- Anthropic, Settings reference, the
envkey - Alice Poteat, Function Hooks - make plugins 10x more powerful, anthropics/claude-code issue #91870, September 3, 2026, and the community test reports in its thread
- The
plugin-authoringskill and the/plugin-typesdeclarations shipped inside Claude Code 2.1.260 - cc-function-hooks-poc, a community proof of concept on Claude Code 2.1.261 that documents the user-level plugin requirement
- Ray Amjad, Anthropic Just Dropped the Biggest Claude Code Update Yet, YouTube, September 2026

