
Session Start Hook
Add a Claude Code SessionStart hook so every new session installs dependencies and can run tests and linters without manual setup.
Overview
Session-start-hook is an agent skill for the Build phase that configures Claude Code SessionStart hooks so dependencies and env vars are ready before tests and linters run.
Install
npx skills add https://github.com/camacho/ai-skills --skill session-start-hookWhat is this skill?
- Documents SessionStart stdin JSON payload (session_id, source, cwd, hook_event_name)
- Async hook pattern with asyncTimeout for background npm install during session start
- CLAUDE_ENV_FILE, CLAUDE_PROJECT_DIR, and CLAUDE_CODE_REMOTE environment variables
- Goal: tests and linters work in CLI, web, and API Claude Code sessions
- Race-condition warning when the agent depends on hook work finishing first
- asyncTimeout example: 300000 ms
- Hook event: SessionStart
Adoption & trust: 550 installs on skills.sh; 1 GitHub stars; 1/3 security scanners passed (skills.sh audits).
What problem does it solve?
Every new Claude Code session starts cold—dependencies are missing and your agent cannot run tests or linters until you manually bootstrap the repo.
Who is it for?
Solo developers standardizing Claude Code on a repo with npm, pip, or similar install steps and CI-style test/lint commands.
Skip if: Projects that do not use Claude Code hooks, or repos where installs must be interactive and cannot run unattended at session start.
When should I use this skill?
User wants to set up a repository for Claude Code or create a SessionStart hook so tests and linters work during sessions (CLI, web, or API).
What do I get? / Deliverables
A SessionStart hook installs packages and exports session env vars automatically so the agent can verify code from the first turn.
- SessionStart hook script
- CLAUDE_ENV_FILE exports for session
- Documented async vs sync install choice
Recommended Skills
Journey fit
SessionStart hooks are Claude Code project configuration—canonical shelf is Build/agent-tooling where you wire the agent runtime to your repo. Hooks run at session bootstrap to prepare the workspace; that is agent-tooling setup, not application feature code.
How it compares
Agent runtime bootstrap skill—not a generic DevOps pipeline; complements repo README setup with automatic session initialization.
Common Questions / FAQ
Who is session-start-hook for?
Solo and indie builders using Claude Code who want their project to self-prepare on every session start across CLI, web, or API.
When should I use session-start-hook?
During Build/agent-tooling when setting up a repository for Claude Code or when tests and linters fail until dependencies are installed each session.
Is session-start-hook safe to install?
Hooks can run shell installs and write env files—review hook scripts and the Security Audits panel on this Prism page before enabling in production repos.
SKILL.md
READMESKILL.md - Session Start Hook
# Startup Hook Skill for Claude Code Create SessionStart hooks that install dependencies so tests and linters work in Claude Code sessions (CLI, web, or API). ## Hook Basics ### Input (via stdin) ```json { "session_id": "abc123", "source": "startup|resume|clear|compact", "transcript_path": "/path/to/transcript.jsonl", "permission_mode": "default", "hook_event_name": "SessionStart", "cwd": "/workspace/repo" } ``` ### Async Mode ```bash #!/bin/bash set -euo pipefail echo '{"async": true, "asyncTimeout": 300000}' npm install ``` The hook runs in background while the session starts. Using async mode reduces latency, but introduces a race condition where the agent loop might depend on something that is being done in the startup hook before it completed. ### Environment Variables Available environment variables: - `$CLAUDE_PROJECT_DIR` - Repository root path - `$CLAUDE_ENV_FILE` - Path to write environment variables - `$CLAUDE_CODE_REMOTE` - If running in a remote environment (i.e. Claude code on the web) Use `$CLAUDE_ENV_FILE` to persist variables for the session: ```bash echo 'export PYTHONPATH="."' >> "$CLAUDE_ENV_FILE" ``` Use `$CLAUDE_CODE_REMOTE` to only run a script in a remote env: ```bash if [ "${CLAUDE_CODE_REMOTE:-}" != "true" ]; then exit 0 fi ``` ## Workflow Make a todo list for all the tasks in this workflow and work on them one after another ### 1. Analyze Dependencies Find dependency manifests and analyze them. Examples: - `package.json` / `package-lock.json` → npm - `pyproject.toml` / `requirements.txt` → pip/Poetry - `Cargo.toml` → cargo - `go.mod` → go - `Gemfile` → bundler Additionally, read though any documentation (i.e. README.md or similar) to see if you can get additional context on how the environment setup works ### 2. Design Hook Create a script that installs dependencies. **Key principles:** - Don't use async mode in the first iteration. Only switch to it if the user asks for it - Write the hook only for the web unless user asks otherwise (see $CLAUDE_CODE_REMOTE) - The container state gets cached after the hook completes, prefer dependency install methods that take advantage of that (i.e. prefer npm install over npm ci) - Be idempotent (safe to run multiple times) - Non-interactive (no user input) **What NOT to put in a SessionStart hook:** - Do NOT copy skills between user scope (`~/.claude/skills/`) and project scope (`.claude/skills/`) — that's what `./dotfiles/sync.sh` is for. **Skills freshness check (install if missing or outdated):** ```bash SKILLS_DIR="$HOME/.claude/skills" REPO_SKILLS_DIR="${CLAUDE_PROJECT_DIR}/dotfiles/claude/skills" SKILLS_REPO="${AI_SKILLS_REPO:-camacho/ai-skills}" skills_stale() { [[ ! -d "$SKILLS_DIR" ]] && return 0 # missing → stale if [[ -d "$REPO_SKILLS_DIR" ]]; then # Compare repo snapshot to installed — if different, stale ! diff -rq "$REPO_SKILLS_DIR" "$SKILLS_DIR" >/dev/null 2>&1 && return 0 fi return 1 # up to date } if skills_stale; then echo "Skills missing or outdated — installing from $SKILLS_REPO..." if command -v npx &>/dev/null; then npx skills install "$SKILLS_REPO" --scope personal \ || echo "Warning: skills install failed — project-scope skills still available" >&2 else echo '{"message": "Skills are outdated but npx not found.\n\nRun: ./dotfiles/sync.sh push", "continue": true}' fi fi ``` The check is local (fast `diff`) — network only when stale. The default repo (`camacho/ai-skills`) can be overridden with `AI_SKILLS_REPO`. **Dotfiles-missing check (surface as a session prompt, not a stderr warning):** ```bash # Surface a visible prompt if user dotfiles are missing — informational only if [[ ! -d "$HOM