ClaudeSuperPower
P

PreToolUse (Skill)

Hook

Fires on

PreToolUsematchingSkill

Immediately before a tool runs — this is where an action can be denied.

Where this sits in a session

  1. Session start
  2. Prompt submitted
  3. Prompt expansion
  4. Before tool use
  5. After tool use
  6. Notification
  7. Before compaction
  8. Subagent finished
  9. Turn finished
  10. Session end

Can blockThis hook is able to deny the action or send Claude back to work.

What it runs

Executed automatically when the event fires — no prompt, no confirmation.

command· timeout 5s
node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/track-active-skill.js"

Install it yourself

Paste into .claude/settings.json to run this hook without installing the whole plugin. Adjust the paths to point at your own copy of the scripts.

settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/track-active-skill.js\"",
            "timeout": 5
          }
        ],
        "matcher": "Skill"
      }
    ]
  }
}

Source

Read this before installing — it runs on your machine with your permissions.

#!/usr/bin/env node
/**
 * PreToolUse hook on the Skill tool: track which carta-cap-table skills are loaded.
 *
 * Appends each skill to an ordered list in a session-scoped state file.
 * The inject-instrumentation hook reads this list and includes it in
 * every MCP tool call for server-side telemetry.
 *
 * State file: /tmp/claude-carta-cap-table/<session_id>.json
 *
 * Part of the official Carta AI Agent Plugin.
 */

const fs = require('fs');
const os = require('os');
const path = require('path');

const STATE_DIR = process.env.CLAUDE_PLUGIN_DATA
    ? path.join(process.env.CLAUDE_PLUGIN_DATA, 'sessions')
    : '/tmp/claude-carta-cap-table';

let inputData = '';
process.stdin.on('data', chunk => (inputData += chunk));

process.stdin.on('end', () => {
    try {
        const input = JSON.parse(inputData);
        const { tool_input, session_id } = input;

        const skillFull = tool_input?.skill || '';

        // Only track carta-cap-table skills
        if (!skillFull.startsWith('carta-cap-table:')) {
            allow();
            return;
        }

        const skillName = skillFull.replace('carta-cap-table:', '');

        if (session_id) {
            fs.mkdirSync(STATE_DIR, { recursive: true });
            const statePath = path.join(STATE_DIR, `${session_id}.json`);

            // Read existing state
            let existing = {};
            try { existing = JSON.parse(fs.readFileSync(statePath, 'utf8')); } catch {}

            // Append skill if not already in the list
            const skills = existing.skills || [];
            if (!skills.includes(skillName)) {
                skills.push(skillName);
            }
            existing.skills = skills;

            fs.writeFileSync(statePath, JSON.stringify(existing));

            // Record the most-recently-invoked skill (namespaced) into the shared
            // instrumentation registry so inject-instrumentation orders the emitted
            // skills union with the genuine latest last (KAF-2912). Best effort.
            try {
                const base = process.env.CARTA_INSTRUMENTATION_REGISTRY_DIR
                    || path.join(os.tmpdir(), 'carta-instrumentation');
                const regDir = path.join(base, String(session_id).replace(/[^A-Za-z0-9._-]/g, '_'));
                fs.mkdirSync(regDir, { recursive: true });
                fs.writeFileSync(path.join(regDir, '.last-skill'), skillFull);
            } catch {}
        }

        allow();
    } catch (err) {
        process.stderr.write(`track-active-skill error: ${err.message}\n`);
        allow();
    }
});

function allow() {
    process.stdout.write(JSON.stringify({
        hookSpecificOutput: {
            hookEventName: 'PreToolUse',
            permissionDecision: 'allow',
        },
    }));
    process.exit(0);
}

Shipped by 1 plugin

Installing any of these installs this hook.

Reviews

Log in to leave a review.

No reviews yet — be the first.

Explore related

Other things in this space — across every part of the ecosystem, not just hooks.