#!/usr/bin/env bash # Cursor stop hook (Neon Sprawl): on NEO-* story branches, nag when the working tree is dirty. # See .cursor/rules/commit-as-you-go.md and commit-and-review.md. set -euo pipefail input=$(cat) status="completed" if command -v jq >/dev/null 2>&1; then status=$(echo "$input" | jq -r '.status // "completed"') fi if [[ "$status" != "completed" ]]; then exit 0 fi root="${CURSOR_PROJECT_DIR:-}" if [[ -z "$root" || ! -d "$root" ]]; then root=$(pwd) fi if command -v jq >/dev/null 2>&1; then for key in workspace_roots workspace_root cwd project_path; do candidate=$(echo "$input" | jq -r --arg k "$key" 'if .[$k] then (if (.[$k] | type) == "array" then .[$k][0] else .[$k] end) else empty end' 2>/dev/null || true) if [[ -n "$candidate" && -d "$candidate" ]]; then root="$candidate" break fi done fi if ! cd "$root" 2>/dev/null; then exit 0 fi if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then exit 0 fi top=$(git rev-parse --show-toplevel 2>/dev/null || true) if [[ -n "$top" ]]; then cd "$top" fi branch=$(git branch --show-current 2>/dev/null || true) if [[ ! "$branch" =~ ^NEO-[0-9]+ ]]; then exit 0 fi if [[ -z $(git status --porcelain) ]]; then exit 0 fi printf '%s\n' '{ "followup_message": "Stop hook (neon-sprawl): this Linear story branch still has uncommitted changes. Run git status, then commit coherent batches per .cursor/rules/commit-as-you-go.md (NEO-*: subject). Do not wait for the user to say commit. Push only if asked. Then summarize what you committed." }' exit 0