#!/usr/bin/env bash # SessionStart(clear) hook: after /clear, point the fresh context at the # session-context anchor so a "flush" resumes the same logical session # instead of starting cold. # # Pairs with the /flush skill (rulesets flush/SKILL.md): the skill's # pre-clear half refreshes .ai/session-context.org in place; this hook is the # post-clear half that /clear's blank session can't run itself. # # General by design — not flush-specific: # - anchor present -> resume (read it, say "flushed.", continue) # - anchor absent -> run the startup workflow (covers a stray /clear) # # SessionStart hooks reach the model ONLY through # hookSpecificOutput.additionalContext — plain stdout goes to the debug log. # After /clear the injected context loads but the model still waits for the # user's next message before it acts; that one keystroke is expected. # # Wire in ~/.claude/settings.json: # # { # "hooks": { # "SessionStart": [ # { # "matcher": "clear", # "hooks": [ # { "type": "command", # "command": "~/.claude/hooks/session-clear-resume.sh" } # ] # } # ] # } # } set -euo pipefail # Resolve the AI_AGENT_ID-aware anchor path — mirror of # .ai/scripts/session-context-path, evaluated against the project cwd the # hook inherits. Fall back to the singleton path when the id is unset. id="${AI_AGENT_ID:-}" if [ -n "$id" ]; then safe=$(printf '%s' "$id" | tr -c 'A-Za-z0-9._-' '_') sc=".ai/session-context.d/${safe}.org" else sc=".ai/session-context.org" fi if [ -f "$sc" ]; then # On resume, read notes.org standing knowledge (code-repo paths, # conventions, key contacts) BEFORE the anchor — the anchor carries # session state, notes.org carries the project context a resumed session # needs to act correctly. Same "key sections" scope startup uses. Only # when notes.org is present; otherwise resume from the anchor alone. if [ -f ".ai/notes.org" ]; then read_order="First read .ai/notes.org key sections (Project-Specific Context, Active Reminders, Pending Decisions; skip About This File) for the project's standing knowledge — code-repo paths, conventions, key contacts. Then read the session-context anchor at ${sc}" else read_order="Read the session-context anchor at ${sc}" fi ctx="A context flush just happened (/clear). ${read_order} — the * Summary (Active Goal, Next Steps) plus the most recent * Session Log entries. Then reply with 'flushed.' on its own line, followed by one line restating the Active Goal and the immediate Next Step, and resume that work. This is a mid-session resume, NOT a fresh start: do not run the startup workflow, do not re-pull rulesets or re-sync templates." else ctx="Session started with no session-context anchor present (.ai/session-context.org absent). Run the startup workflow at .ai/workflows/startup.org." fi # Build the whole object in python3 so the additionalContext string is # JSON-escaped correctly regardless of its content. python3 -c 'import json,sys; print(json.dumps({"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":sys.argv[1]}}))' "$ctx"