Development
Hook
Hooks
What sf runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.
Install
> /plugin marketplace add bitcraft-apps/spec-first > /plugin install sf@spec-first
Ships with sf. Installing the plugin gets these hooks.
What fires, and when
Stop
bash ${CLAUDE_PLUGIN_ROOT}/hooks/validate-spec.shbash ${CLAUDE_PLUGIN_ROOT}/hooks/validate-implementation.sh
Where it lives
- hooks/validate-implementation.shRunsGitHub
Read the script
#!/bin/bash # Claude Stop hook adapter - runs scripts/validate-implementation.sh and reports its result INPUT=$(cat) [ "$(echo "$INPUT" | jq -r '.stop_hook_active // false')" = "true" ] && exit 0 PROJECT_DIR=$(echo "$INPUT" | jq -r '.cwd // ""') SCRIPT="$(dirname "$0")/../scripts/validate-implementation.sh" REASON=$(bash "$SCRIPT" "${SF_DIR:-$PROJECT_DIR/.sf}" 2>&1 >/dev/null) \ || jq -nc --arg reason "$REASON" '{decision:"block",reason:$reason}' exit 0 - hooks/validate-spec.shRunsGitHub
Read the script
#!/bin/bash # Claude Stop hook adapter - runs scripts/validate-spec.sh and reports its result INPUT=$(cat) [ "$(echo "$INPUT" | jq -r '.stop_hook_active // false')" = "true" ] && exit 0 PROJECT_DIR=$(echo "$INPUT" | jq -r '.cwd // ""') SCRIPT="$(dirname "$0")/../scripts/validate-spec.sh" REASON=$(bash "$SCRIPT" "${SF_DIR:-$PROJECT_DIR/.sf}" 2>&1 >/dev/null) \ || jq -nc --arg reason "$REASON" '{decision:"block",reason:$reason}' exit 0
Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.
Ships withsf
Write the requirements before you write the code. Spec First gives you a workflow with three steps. First, define what to build. Then implement it from the spec. Last, generate the documentation. All steps run in your terminal.
Get the whole plugin

