S
SessionStart
HookFires on
SessionStartOnce, as a session begins — before you type anything.
Where this sits in a session
- Session start→
- Prompt submitted→
- Prompt expansion→
- Before tool use→
- After tool use→
- Notification→
- Before compaction→
- Subagent finished→
- Turn finished→
- Session end
Observes only — Emits messages or context. It never returns a permission decision.
What it runs
Executed automatically when the event fires — no prompt, no confirmation.
command· timeout 5s
node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/inject-skill-context.js"command· timeout 5s
node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/init-data-dir.js"command· timeout 5s
node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/capture-model.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": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/inject-skill-context.js\"",
"timeout": 5
},
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/init-data-dir.js\"",
"timeout": 5
},
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/capture-model.js\"",
"timeout": 5
}
]
}
]
}
}Source (3 files)
Read this before installing — it runs on your machine with your permissions.
#!/usr/bin/env node
/**
* SessionStart hook: inject skill-first reminder and cached session data.
*
* Ensures Claude loads the relevant carta-cap-table skill before making
* any tool calls, even in subagents that don't inherit session context.
*
* Part of the official Carta AI Agent Plugin.
*/
const fs = require('fs');
const path = require('path');
// Read plugin name + version (same safe pattern as inject-instrumentation.js)
let pluginName = 'carta-cap-table';
let pluginVersion = 'unknown';
try {
const pluginJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../.claude-plugin/plugin.json'), 'utf8'));
pluginName = pluginJson.name || pluginName;
pluginVersion = pluginJson.version || 'unknown';
} catch {}
let inputData = '';
process.stdin.on('data', chunk => (inputData += chunk));
process.stdin.on('end', () => {
let hookEventName = 'SessionStart';
try {
const input = JSON.parse(inputData);
hookEventName = input.hook_event_name || hookEventName;
} catch {}
// Canonical auth gate prompt lives in carta-interaction-reference/SKILL.md Section 6.2.
// Keep the wording below in sync with that source.
const output = {
hookSpecificOutput: {
hookEventName,
additionalContext:
'<EXTREMELY_IMPORTANT>You have carta-cap-table tools available. Before ANY tool call, invoke the matching Skill(\'carta-cap-table:...\') first. The skill defines what to fetch, what inputs are required, and how to present results. If no skill matches, invoke Skill(\'carta-cap-table:carta-discover-commands\') to find the right command via discover(). Additionally, ALWAYS invoke Skill(\'carta-cap-table:carta-interaction-reference\') alongside any domain skill to load Carta\'s voice, tone, and data provenance rules before presenting results. IMPORTANT: Skill is a deferred tool — if its schema is not yet loaded, you MUST call ToolSearch with query "select:Skill" first, then invoke the Skill tool.</EXTREMELY_IMPORTANT>\n' +
'<EXTREMELY_IMPORTANT>AI COMPUTATION AUTHORIZATION GATE: When a carta-cap-table skill\'s Gates section declares "AI computation: Yes", you MUST call AskUserQuestion BEFORE fetching data or computing. Use this prompt, replacing [X]: "No saved Carta model matches these terms. I can compute [X] using AI — this would be Claude\'s analysis, not Carta data. Would you like me to proceed?" Do NOT write this as plain text — use the AskUserQuestion tool so execution blocks. User says yes: proceed, label output as Claude\'s analysis. User says no: stop — no output, no fallback.</EXTREMELY_IMPORTANT>\n' +
'<EXTREMELY_IMPORTANT>To report a bug or request a feature for this plugin, call mutate(command="fa:create:feedback") directly (params: requestType ("bug" | "feature_request"), requestBody; optional flowSummary, context, affectedSkill, source). This is the exception to the skill-first rule above: there is NO feedback skill — do NOT look for one, and do NOT ask the user where to file. Go straight to mutate; you do not need a discover/search round-trip to call it. (If you ever lose this instruction, the command is also findable by searching tools for "report a bug" / "feedback" — but the direct mutate call above is the primary path.) Always include flowSummary: a short narrative of the flow that led here — what the user asked (their prompt(s), summarized), the key skills/tools you ran, and where it broke or fell short — written for a developer debugging later. Put the raw failing tool + args in context. Do NOT pass identity, firm, session, or timestamp — those are captured server-side. Fire it proactively with source="claude" when a tool errors, returns nothing usable, or a needed capability is missing, after telling the user you are filing it.</EXTREMELY_IMPORTANT>\n' +
`<carta-plugin name="${pluginName}" version="${pluginVersion}" />`,
},
};
process.stdout.write(JSON.stringify(output));
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.