hooks-session-start-hook

/hooks:session-start-hook

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hooks-session-start-hook" with this command: npx skills add laurigates/claude-plugins/laurigates-claude-plugins-hooks-session-start-hook

/hooks:session-start-hook

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.

When to Use This Skill

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

Context

Detect project stack:

  • Lockfiles: !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' )

  • Project files: !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*'

  • Linter configs: !find . -maxdepth 1 ( -name 'biome.json' -o -name 'biome.jsonc' -o -name '.eslintrc*' -o -name 'eslint.config.*' )

  • Existing settings: !find .claude -maxdepth 1 -name 'settings.json' -type f

  • Existing hooks dir: !find . -maxdepth 2 -type d -name 'scripts'

Parameters

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

Execution

Step 1: Detect project stack

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.

Step 2: Generate hook script

Create the script at scripts/claude-session-start.sh (or .claude/hooks/session-start.sh if no scripts/ directory exists).

Script template — adapt per detected stack:

#!/bin/bash

Claude Code SessionStart Hook

Generated by /hooks:session-start-hook

Installs dependencies and verifies tooling for web sessions

{{ if --remote-only }}

Only run in remote/web sessions

if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then exit 0 fi {{ endif }}

CONTEXT_PARTS=()

──── Dependency Installation ────

{{ if Node.js detected }} if [ -f "package.json" ]; then {{ npm ci / yarn install --frozen-lockfile / pnpm install --frozen-lockfile / bun install --frozen-lockfile }} CONTEXT_PARTS+=("Node.js dependencies installed via {{ pm }}") fi {{ endif }}

{{ if Python detected }} if [ -f "pyproject.toml" ]; then {{ poetry install / uv sync / pip install -e '.[dev]' }} CONTEXT_PARTS+=("Python dependencies installed via {{ pm }}") elif [ -f "requirements.txt" ]; then pip install -r requirements.txt 2>/dev/null CONTEXT_PARTS+=("Python dependencies installed via pip") fi {{ endif }}

{{ if Rust detected }} if [ -f "Cargo.toml" ]; then cargo fetch 2>/dev/null CONTEXT_PARTS+=("Rust dependencies fetched") fi {{ endif }}

{{ if Go detected }} if [ -f "go.mod" ]; then go mod download 2>/dev/null CONTEXT_PARTS+=("Go dependencies downloaded") fi {{ endif }}

{{ if Ruby detected }} if [ -f "Gemfile" ]; then bundle install 2>/dev/null CONTEXT_PARTS+=("Ruby dependencies installed via bundler") fi {{ endif }}

{{ if Java/maven detected }} if [ -f "pom.xml" ]; then mvn dependency:resolve -q 2>/dev/null CONTEXT_PARTS+=("Java dependencies resolved via maven") fi {{ endif }}

{{ if Java/gradle detected }} if [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then gradle dependencies --quiet 2>/dev/null CONTEXT_PARTS+=("Java/Kotlin dependencies resolved via gradle") fi {{ endif }}

──── Environment Variables ────

if [ -n "$CLAUDE_ENV_FILE" ]; then {{ per language: export PATH, NODE_ENV, PYTHONDONTWRITEBYTECODE, etc. }} fi

{{ unless --no-verify }}

──── Verify Tooling ────

{{ if test runner detected }} if {{ test command --bail / -x / quick mode }} 2>/dev/null; then CONTEXT_PARTS+=("Tests: passing") else CONTEXT_PARTS+=("Tests: FAILING - investigate before making changes") fi {{ endif }}

{{ if linter detected }} if {{ lint command --max-diagnostics=0 / --quiet }} 2>/dev/null; then CONTEXT_PARTS+=("Linter: clean") else CONTEXT_PARTS+=("Linter: issues detected") fi {{ endif }} {{ end unless }}

──── Report Context ────

CONTEXT=$(printf '%s\n' "${CONTEXT_PARTS[@]}") if [ -n "$CONTEXT" ]; then jq -n --arg ctx "$CONTEXT" '{ "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": $ctx } }' fi

exit 0

Adapt the template by:

  • Including only sections for detected languages

  • Using the correct package manager commands with frozen lockfile flags

  • Using the correct test runner and linter commands

  • Setting appropriate environment variables per language

Step 3: Configure .claude/settings.json

Read 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:

  • Replace the existing SessionStart hook

  • Add alongside the existing hook (both will run)

  • Abort and keep existing configuration

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/ .

Step 4: Finalize

  • Make the script executable: chmod +x <script-path>

  • Create .claude/ directory if needed for settings.json

  • Report summary of what was created

Step 5: Verify (unless --no-verify)

Run the generated script locally to confirm it executes without errors. Report results.

Post-Actions

After generating the hook:

  • Suggest committing the new files: scripts/claude-session-start.sh .claude/settings.json

  • If --remote-only was NOT used, mention the flag for web-only behavior

  • If the project needs network access beyond defaults, remind about Claude Code web network settings

  • Mention matcher options: "startup" (new sessions), "resume" (resumed), "" (all events)

SessionStart Matcher Reference

Matcher Fires When

"startup"

New session starts

"resume"

Session is resumed

"clear"

After /clear command

"compact"

After context compaction

"" (empty) All SessionStart events

Agentic Optimizations

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

Quick Reference

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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ruff-linting

No summary provided by upstream source.

Repository SourceNeeds Review
General

imagemagick-conversion

No summary provided by upstream source.

Repository SourceNeeds Review
General

jq json processing

No summary provided by upstream source.

Repository SourceNeeds Review