hooks-plugin/skills/hooks-session-start-hook/SKILL.md
Create a SessionStart hook for Claude Code on the web. Use when setting up a repo so dependencies install and tests/linters run automatically on remote session start.
npx skillsauth add laurigates/claude-plugins hooks-session-start-hookInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate a SessionStart hook that prepares your repository for Claude Code on the web — installing dependencies, configuring environment variables, and verifying that tests and linters work.
| Use this skill when... | Use /hooks:hooks-configuration instead when... |
|---|---|
| Setting up a repo for Claude Code on the web | Configuring other hook types (PreToolUse, Stop, etc.) |
| Need automatic dependency install in web sessions | Need general hooks knowledge or debugging |
| Want tests/linters verified on session start | Writing custom hook logic from scratch |
| Onboarding a project to remote Claude Code | Understanding hook lifecycle events |
Detect project stack:
find . -maxdepth 1 \( -name 'package-lock.json' -o -name 'yarn.lock' -o -name 'pnpm-lock.yaml' -o -name 'bun.lockb' -o -name 'poetry.lock' -o -name 'uv.lock' -o -name 'Cargo.lock' -o -name 'go.sum' -o -name 'Gemfile.lock' \)find . -maxdepth 1 \( -name 'package.json' -o -name 'pyproject.toml' -o -name 'requirements.txt' -o -name 'Cargo.toml' -o -name 'go.mod' -o -name 'Gemfile' -o -name 'pom.xml' \) -o -maxdepth 1 -name 'build.gradle*'find . -maxdepth 1 \( -name 'biome.json' -o -name 'biome.jsonc' -o -name '.eslintrc*' -o -name 'eslint.config.*' \)find .claude -maxdepth 1 -name 'settings.json' -type ffind . -maxdepth 2 -type d -name 'scripts'| Flag | Default | Description |
|---|---|---|
| --remote-only | off | Wrap script in CLAUDE_CODE_REMOTE guard — hook exits immediately in local sessions |
| --no-verify | off | Skip test/linter verification step in the generated script |
Identify all languages and tooling from the context above.
Language detection:
| File Present | Language | Package Manager (from lockfile) |
|---|---|---|
| package.json | Node.js | npm (package-lock.json), yarn (yarn.lock), pnpm (pnpm-lock.yaml), bun (bun.lockb) |
| pyproject.toml | Python | poetry (poetry.lock), uv (uv.lock), pip (fallback) |
| requirements.txt | Python | pip |
| Cargo.toml | Rust | cargo |
| go.mod | Go | go modules |
| Gemfile | Ruby | bundler |
| pom.xml | Java | maven |
| build.gradle* | Java/Kotlin | gradle |
Test runner detection:
| Language | How to Detect | Test Command |
|---|---|---|
| Node.js | scripts.test in package.json | npm test / bun test / etc. |
| Python | [tool.pytest] in pyproject.toml, or pytest in deps | pytest |
| Rust | always available | cargo test |
| Go | always available | go test ./... |
| Ruby | Gemfile contains rspec or minitest | bundle exec rspec / bundle exec rake test |
| Java | pom.xml / build.gradle | mvn test / gradle test |
Linter detection:
| Config File | Linter | Command |
|---|---|---|
| biome.json / biome.jsonc | Biome | npx biome check . |
| .eslintrc* / eslint.config.* | ESLint | npx eslint . |
| [tool.ruff] in pyproject.toml | Ruff | ruff check . |
| Cargo.toml | Clippy | cargo clippy |
Report detected stack to user before generating.
Create the script at scripts/claude-session-start.sh (or .claude/hooks/session-start.sh if no scripts/ directory exists).
Use the Script Template from REFERENCE.md. Adapt it by:
.claude/settings.jsonRead existing .claude/settings.json if it exists. Merge the SessionStart hook — preserve all existing configuration.
If a SessionStart hook already exists, ask the user whether to:
Configuration to merge:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/claude-session-start.sh\"",
"timeout": 120
}
]
}
]
}
}
Use timeout: 120 (2 minutes) for dependency installation. Adjust path if script is in .claude/hooks/ instead of scripts/.
chmod +x <script-path>.claude/ directory if needed for settings.jsonRun the generated script locally to confirm it executes without errors. Report results.
After generating the hook:
scripts/claude-session-start.sh
.claude/settings.json
--remote-only was NOT used, mention the flag for web-only behaviormatcher options: "startup" (new sessions), "resume" (resumed), "" (all events)| Matcher | Fires When |
|---|---|
| "startup" | New session starts |
| "resume" | Session is resumed |
| "clear" | After /clear command |
| "compact" | After context compaction |
| "" (empty) | All SessionStart events |
| Context | Approach |
|---|---|
| Quick setup, skip verification | /hooks:session-start-hook --remote-only --no-verify |
| Full setup with verification | /hooks:session-start-hook |
| Web-only with tests | /hooks:session-start-hook --remote-only |
| Dependency install commands | Use --frozen-lockfile / ci variants for reproducibility |
| Test verification | Use --bail=1 / -x for fast failure |
| Linter verification | Use --max-diagnostics=0 / --quiet for pass/fail only |
| Item | Value |
|---|---|
| Script location | scripts/claude-session-start.sh or .claude/hooks/session-start.sh |
| Settings location | .claude/settings.json |
| Timeout | 120 seconds (adjustable) |
| Output format | JSON with hookSpecificOutput.additionalContext |
| Environment persistence | Via CLAUDE_ENV_FILE |
| Remote detection | CLAUDE_CODE_REMOTE=true |
tools
Scaffold a new ComfyUI custom-node repo (pyproject, CI, release-please, vitest+pytest, JS extension skeleton) in the picker/gesture vein. Use when bootstrapping or init-ing a comfyui node pack.
tools
Orchestrate a ComfyUI node pack from idea to registry: scaffold, create + seed the repo, open the gitops adoption PR. Use when releasing or spinning up a new comfyui node pack.
testing
macOS EndpointSecurity/EDR high CPU & battery drain. Use when Kandji ESF / XProtect pegs a core; trace the exec storm via powermetrics + eslogger.
development
odiff pixel-by-pixel image diffing. Use when comparing screenshots, detecting visual regressions, diffing before/after PNGs, asserting golden images.