Install any skill in seconds. Free to start, no credit card required.
Get Started Free →griddynamics/coding-agents-hooks-authoring
To author, register, and test Rosetta hooks, add a SemanticKind, or debug a hook that won't fire.
Passed 21 of 22 test cases with the skill, and 6 of 22 without it.
and 14 more in the full report
15 fixed6 passed either way1 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 15 test cases the skill fixed. Same model, same prompt, with and without the skill.
What command should be run locally after updating hook source files to ensure CJS bundles build, tests pass, and plugin artifacts update?
| Checked | Without skill | With skill |
|---|---|---|
| Specifies running venv/bin/python scripts/pre_commit.py | Missed | Passed |
The instructions your model reads when the skill loads.
<hooks_authoring>
Only files that export defineHook(…) AND call runAsCli(hook, module) belong directly in src/hooks/src/hooks/.
Every .ts at the top level of that directory becomes a standalone CJS bundle distributed to all 6 IDE targets (claude-code, codex, copilot, cursor, windsurf, antigravity).
Helper/data files without runAsCli belong in a named subdirectory: src/hooks/src/hooks/<feature>/.
src/hooks/src/hooks/<feature>/ (e.g. src/hooks/src/hooks/dangerous-actions/patterns.ts).src/hooks/src/runtime/.src/hooks/scripts/build-bundles.mjs:29 uses readdirSync(hooksDir).filter(f => f.endsWith('.ts')).
There is no { recursive: true }. Subdirectories are invisible to the bundler.
Adding a top-level .ts without runAsCli produces a dead bundle for every plugin.
A plugin may opt a hook OUT via excludeHooks in the PLUGINS array (build-bundles.mjs) — e.g. core-antigravity excludes the advise-only hooks, which have no delivery channel there.
When a hook needs a new tool category (e.g. mcp-call):
src/hooks/src/runtime/ide-registry.ts — add a row to TOOL_KINDS with all 6 IDE columns (null where the event doesn't exist). SemanticKind = keyof typeof TOOL_KINDS so TypeScript enforces coverage.src/hooks/src/runtime/ide-rows/<ide>.ts — if the kind requires special logic (e.g. prefix-match for mcp__.*), add a conditional branch at the top of lookupToolKind in the IDE-row file before the table loop. Table-driven lookup alone cannot handle open-ended tool name patterns.def.on.toolKinds.hooks.json.tmpl — widen to include new tool names/patterns.Order matters: run-hook.ts:316 gates on toolKinds before calling def.run(ctx). Matcher passes the event in; toolKinds must include the mapped kind or the call is dropped silently.
Every new hook must appear in each registering plugin's hooks.json. The canonical sources are the hooks.json.tmpl templates; direct edits to generated hooks.json files are overwritten on the next npx rosettify-plugins run.
Template paths by plugin, all under src/rosettify-plugins/plugins/ (templates are generator input only — .tmpl files are not emitted into the generated plugins/ tree):
core-claude/hooks/hooks.json.tmplcore-codex/.codex-plugin/hooks.json.tmplcore-copilot/hooks/hooks.json.tmpl (+ core-copilot/.github/plugin/hooks.json.tmpl)core-cursor/hooks.json.tmpl (+ core-cursor/hooks/hooks.json.tmpl)test cases passed, vs 6 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.