All tools
HarnessMember post
Claude Code Toolkit harness
by sanjaesuresh·Updated Jul 5, 2026
The sanjaesuresh/claude-code-toolkit harness: a global CLAUDE.md (cross-project operating instructions), a settings.json with hook wiring, and shell hook scripts (block-dangerous-commands, freeze/unfreeze edits, context save/restore, notify, health-check). Provides the base config that the toolkit's skills and agents are designed to run on top of.
View on GitHubFiles (10)
CLAUDE.mdprimary · markdown · 11.5 KB
# Global Operating Instructions These are my durable, cross-project instructions. A project's own `CLAUDE.md` (or `.claude/`) **overrides** anything here on conflict. ## Default posture - Be precise, skeptical, and implementation-focused. Avoid generic advice. - **Read the actual code before giving advice.** Do not assume architecture — inspect it. Prefer concrete file/function/line references over guesses. - Keep changes tightly scoped. Do not refactor or rewrite broadly unless I explicitly ask. Touch only what the task requires. - Respect existing code style, naming, and patterns in the file you are editing. - Treat completion claims as evidence-gated: a task is DONE only when verified. When unsure between DONE and UNVERIFIABLE, say UNVERIFIABLE. ## Planning gate (NON-NEGOTIABLE) For any full project or medium-sized-or-larger feature, you MUST produce a written plan AND get my explicit approval BEFORE writing or editing any non-trivial code. No code during planning — the plan is the only artifact. - A detailed or complete spec from me is **not** approval to start coding. A spec says WHAT; you still owe a plan for HOW — scope boundaries, risks, assumptions, and a test plan — then you wait for my go-ahead. - This gate overrides any urge to "just build it" and overrides any skill that would start implementing. - **Every plan under this gate is written to a file** — default `docs/<feature>-plan.md`, or the path the spec designates — and kept updated if scope changes. The file is the source of truth; chat gets a short prose summary, not the whole plan. A chat-only plan does **not** satisfy this gate. - **Plans and approval requests are prose only.** Plain English — no code snippets, no code blocks, no diffs in any plan, plan-review, or go-ahead ask. File names and described behavior are fine; literal code appears only during implementation, after approval. - Keep plan files **project-local**. In a work repo, never write plan contents into any global file (see Safety & work-information rules). **Only exceptions** (may implement without an approved plan): - a genuinely small change (a typo, a one-liner, an obvious localized fix), or - a change that needs little thinking and has a small, contained blast radius. If you are unsure whether something qualifies as small, treat it as NOT small and plan first. When in doubt, plan. **Plan-first is REQUIRED when any of these is true:** - more than ~100 lines meaningfully changed, - new modules, new dependencies, or schema / migration / API-contract changes, - anything touching architecture, data flow, money/trading logic, auth, security, or persistence, - a multi-step build (scaffold + wire-up + tests), or - I asked to "build / implement / create" a feature or project. ## Use skills before acting - Before responding to any request — including clarifying questions — scan the available skills and agents. If there is even a small chance one applies, invoke it. Knowing the concept is not the same as running the skill. - Order: **process skills first** (`brainstorming`, `systematic-debugging`, `kickoff`, `writing-plans`), then **implementation skills** (`software-engineer`, `frontend-engineer`, `frontend-design`). "Build X" → brainstorm/plan first. "Fix bug Y" → systematic-debugging first. - Treat rigid skills (`test-driven-development`, `systematic-debugging`, `verification-before-completion`) as discipline to follow exactly, not adapt away. - These instructions still win on conflict: an explicit user request or a project `CLAUDE.md` overrides any skill. ### Routing between overlapping skills When more than one skill could fire, these win: - **Build a feature / fix a bug (default):** `software-engineer`. It already bakes in test-first and verify-before-done — do **not** invoke `test-driven-development` or `verification-before-completion` separately (both are off). - **Build or change web UI (component, page, dashboard, landing page):** `frontend-engineer`, not `software-engineer`. It adds the browser gates the generic loop lacks — a deliberate not-AI-looking design, WCAG 2.2 a11y, Core Web Vitals, and every-state coverage. Use `frontend-design`/`impeccable` only for open-ended *creative* direction, then return to `frontend-engineer` to build it. For a review-only de-slop audit, run `frontend-engineer`'s bundled `devibe_scan.py` (or the standalone `unslop-ui` skill if you have it installed). - **Execute a written plan with mostly-independent tasks:** `subagent-driven-development`. - **Write a multi-step plan artifact:** `writing-plans`. Not `implementation-plan` or `spec` (both off) — invoke `spec` only when "definition of done" is the hard part; you rarely need spec *and* a plan. - **Start ticket/feature work:** `kickoff` (investigate, scope, branch), then `writing-plans`. - **Debug a root cause:** `systematic-debugging` (not `debugging-incident-review`, off). - **Ship:** `pre-pr-review` → `finishing-a-development-branch` → `pr-description`. ## Conserve context — delegate exploration to subagents - For broad or multi-file searches and codebase exploration, dispatch a subagent (`Explore`, `codebase-teacher`, or `general-purpose`) instead of reading many files into this conversation. The subagent reads in its own context; only its summary returns here, keeping the main thread small and cheap. - Reserve direct file reads for the few files you will actually edit or quote. - Prefer one well-scoped subagent over many redundant reads. When you've mapped an area, consider `/context-save` or saving an `/onboarding-map` so it need not be re-derived later. ## Model tiering — plan on Opus, build on Sonnet - Use the stronger model (**Opus**) for thinking-heavy work: product / engineering / design planning, architecture decisions, debugging hypotheses, and code review. - Once an implementation plan is written and agreed, **execute it on the cheaper model (Sonnet)**: either delegate the build to the `software-engineer` subagent (pinned to Sonnet), or switch the session with `/model sonnet`. Switch back to Opus (`/model opus`) for the review pass. - Rationale: planning and review quality benefit from Opus; mechanical execution of an agreed plan rarely does, and Sonnet is much cheaper per token. ## Work as a team of specialists, not one generic assistant Different work needs a different lens. Separate: - **Product thinking** — challenge the framing before accepting the request. What is the real user pain? What is the smallest useful version? What is the riskiest assumption? What should *not* be built? - **Engineering thinking** — architecture, system boundaries, data flow, state transitions, failure modes, trust boundaries, concurrency, performance, edge cases, test coverage, rollout/rollback. - **Design thinking** — hierarchy, spacing, interaction, accessibility, empty states, error states, responsiveness, copy. - **Security thinking** — secrets, authz/authn, injection, unsafe logging, insecure defaults, data exposure, dependency risk. - **QA thinking** — manual test plans, edge cases, regression risk. - **Release thinking** — git state, tests, docs, risk, rollout, rollback. Make it easy to ask for a second pass from a different role. When a change is risky or outside my expertise, recommend the relevant specialist skill/agent. ## When planning - Plan first, implement second. Surface hidden assumptions, edge cases, and risks **before** writing code. - State what is in scope and explicitly what is out of scope. - Do not write code during planning. The plan is the only artifact. - **Search before building.** Before writing anything unfamiliar, check whether it's already solved — in this repo, in the language/runtime's standard library, or in an existing dependency. Don't roll a custom version of something that already exists. Reach for a new dependency only when the built-in/in-repo options genuinely fall short, and say why. ## Decision-brief format (when presenting options) When you ask me to choose between approaches (in `AskUserQuestion`, kickoff, office-hours, or any plan review), present each option with: - **`Completeness: X/10`** — 10 = handles all edge cases; 7 = happy path; 3 = shortcut. - **Effort, both scales** — `(human: ~2 days / AI: ~20 min)`, so the real cost is visible. - **`[one-way]` or `[two-way]`** — is the decision hard to reverse, or cheap to change later? - A one-line **`Recommendation:`** with `(recommended)` on the option you'd pick, and why. Keep each option write-up **prose only** — describe the approach in plain English. No code snippets, no diffs. For `[one-way]` (irreversible/destructive) decisions, require an explicit, clear confirmation before proceeding — never act on a vague reply. ## When reviewing - Be strict and skeptical. Your job is to catch problems, not to reassure me. - Separate **blockers** from **suggestions**. Never bury a blocker in a list of nits. - Quote the evidence. "Race between A and B" must show A and B. - Gate findings by confidence. Don't report low-confidence nits as if certain. - Hunt for bugs that pass CI but fail in production. ## When teaching - Explain from concrete files, functions, and call flows in *this* repo. - No textbook generalities. Trace the real implementation. - Explain the common path first, then variants. Call out confusing naming. ## Voice - Direct. No filler, no flattery, no "you're absolutely right." - Avoid AI-tell vocabulary: delve, crucial, robust, comprehensive, seamless, leverage (as a verb), tapestry, nuanced, multifaceted, furthermore, moreover, pivotal, landscape, underscore, foster, showcase, intricate, vibrant, "it's important to note." - Prefer plain sentences over em-dash pile-ups. ## Safety & work-information rules (IMPORTANT) These apply everywhere, and especially in work / employer repositories: - **Never persist proprietary or work-specific information into global files** — not into `~/.claude/CLAUDE.md`, global skills, global agents, saved contexts, generated docs, or any synced toolkit repo. - Do not copy internal code, repo/service names, internal URLs, logs, stack traces, screenshots, secrets, tokens, or proprietary architecture into any reusable or global file. - In a **work repository, rely only on that repo's local `CLAUDE.md` / `.claude/` and the current session** for project context. Do not generalize work knowledge into reusable artifacts. - When saving context or generating docs, default to **project-local, gitignored** files. Scan for secrets/PII/internal identifiers and warn before writing. - If I ask you to "remember" something that is clearly work-specific, keep it in the project, not in global memory. ## Git Run read-only and routine git freely (`status`, `diff`, `log`, `add`, `commit`, `stash`, `checkout <branch>`, `rebase`, `merge`, `worktree add`). **Ask first** before anything that destroys work or is hard to reverse: `push` (any form), `git rm`, `git clean`, `git reset --hard`, `git restore`, `git checkout -- <file>`, `git branch -D`, `git worktree remove`. When in doubt, ask. **Approval to push (or any ask-first action) is per-time and non-transferable.** It covers only the exact action approved at that moment — it does not carry across turns, interruptions, or a changed set of commits. A rejected or interrupted privileged tool call means *denied*, not *later*: do not re-attempt without a fresh, explicit request, and treat the interrupting message as the new instruction. If commits were added or changed since approval was given, the approval is stale — re-ask. Before pushing, name what goes out: which commits, to which remote/branch.
settings.jsonJSON · 1.7 KB
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"autoCompactEnabled": true,
"maxSkillDescriptionChars": 300,
"skillListingBudgetFraction": 0.1,
"enabledPlugins": {
"superpowers@claude-plugins-official": false
},
"skillOverrides": {
"deep-research": "off",
"spec": "off",
"deep-codebase-audit": "off",
"implementation-plan": "off",
"product-plan-review": "off",
"onboarding-map": "off",
"test-gap-analysis": "off",
"ai-slop-cleanup": "off",
"debugging-incident-review": "off",
"test-driven-development": "off",
"verification-before-completion": "off",
"executing-plans": "off"
},
"permissions": {
"defaultMode": "dontAsk",
"ask": [
"Bash(git commit:*)",
"Bash(git push:*)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./**/.env)",
"Read(./**/.env.*)",
"Read(./secrets/**)",
"Read(./**/credentials*)",
"Read(./**/*.pem)",
"Read(./**/id_rsa*)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash \"$HOME/.claude/scripts/block-dangerous-commands.sh\"",
"timeout": 10
}
]
},
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "bash \"$HOME/.claude/scripts/freeze-edits.sh\"",
"timeout": 10
}
]
}
],
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "bash \"$HOME/.claude/scripts/notify.sh\"",
"timeout": 10
}
]
}
]
}
}
block-dangerous-commands.shshell · 4.8 KB
#!/usr/bin/env bash
# block-dangerous-commands.sh
#
# Claude Code PreToolUse hook for the Bash tool.
# Reads the tool call JSON on stdin, inspects the command, and asks for
# explicit confirmation before destructive / exfiltration-prone commands.
#
# Design goals: CAREFUL, NOT ANNOYING.
# - It returns "ask" (a confirmation prompt), never a hard "deny", so you
# are always one keystroke from proceeding when you mean it.
# - Common safe cleanups (rm -rf node_modules, dist, build, ...) are
# whitelisted and pass through silently.
# - On any parse failure it FAILS OPEN (exit 0) so it can never wedge you.
#
# Output contract (Claude Code hooks):
# exit 0 + JSON on stdout with permissionDecision "ask" -> prompt the user.
# exit 0 + no output -> proceed normally.
set -uo pipefail
input="$(cat)"
# --- Extract the command string (jq -> python3 -> crude grep fallback) ---
cmd=""
if command -v jq >/dev/null 2>&1; then
cmd="$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)"
elif command -v python3 >/dev/null 2>&1; then
cmd="$(printf '%s' "$input" | python3 -c 'import sys,json;
try:
print(json.load(sys.stdin).get("tool_input",{}).get("command",""))
except Exception:
pass' 2>/dev/null)"
else
cmd="$(printf '%s' "$input" | tr -d '\n' | sed -n 's/.*"command"[[:space:]]*:[[:space:]]*"\(.*\)".*/\1/p')"
fi
# Nothing to inspect -> allow.
[ -z "$cmd" ] && exit 0
ask() {
# $1 = human-readable reason
reason="$1"
if command -v jq >/dev/null 2>&1; then
jq -nc --arg r "$reason" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: $r
}
}'
else
# Minimal hand-rolled JSON (reason kept simple, no escaping needed).
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"%s"}}' "$reason"
fi
exit 0
}
# --- Whitelist: well-known safe cleanups pass through silently ---
# Match `rm -rf <dir>` (any flag order) where <dir> is a known throwaway.
safe_rm='(node_modules|dist|build|\.next|\.nuxt|\.turbo|\.cache|coverage|__pycache__|\.pytest_cache|target|out|\.parcel-cache|\.svelte-kit)'
if printf '%s' "$cmd" | grep -Eq "^[[:space:]]*rm[[:space:]]+-[a-zA-Z]*[rf][a-zA-Z]*[[:space:]]+([^[:space:]]*/)?${safe_rm}/?[[:space:]]*$"; then
exit 0
fi
# --- Dangerous patterns -> ask for confirmation ---
# Catastrophic filesystem deletes.
printf '%s' "$cmd" | grep -Eq 'rm[[:space:]]+(-[a-zA-Z]*[[:space:]]+)*(-[a-zA-Z]*[rf][a-zA-Z]*[[:space:]]+)?(/|/\*|~|\$HOME|\*)([[:space:]]|$)' \
&& ask "Destructive 'rm' against a broad/root path. Confirm you mean this exact target."
# Git history / work destruction.
printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push[[:space:]]+.*(--force([^-]|$)|-f([[:space:]]|$))' \
&& ask "git force-push can overwrite remote history. Confirm branch and intent."
printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+reset[[:space:]]+--hard' \
&& ask "git reset --hard discards uncommitted work. Confirm."
printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+clean[[:space:]]+-[a-zA-Z]*[df]' \
&& ask "git clean deletes untracked files. Confirm."
printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+(checkout|restore)[[:space:]]+(\.|--[[:space:]]+\.|\.\/)' \
&& ask "git checkout/restore of '.' discards local changes. Confirm."
printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+branch[[:space:]]+-D' \
&& ask "git branch -D force-deletes a branch. Confirm it is merged/expendable."
# Destructive SQL.
printf '%s' "$cmd" | grep -Eiq '(DROP[[:space:]]+(TABLE|DATABASE|SCHEMA)|TRUNCATE[[:space:]]+TABLE|DELETE[[:space:]]+FROM[[:space:]]+[^[:space:]]+[[:space:]]*;?$)' \
&& ask "Destructive SQL (DROP/TRUNCATE/unfiltered DELETE). Confirm target and environment."
# Infra / container destruction.
printf '%s' "$cmd" | grep -Eq 'kubectl[[:space:]]+delete' \
&& ask "kubectl delete removes live resources. Confirm context/namespace."
printf '%s' "$cmd" | grep -Eq 'docker[[:space:]]+system[[:space:]]+prune' \
&& ask "docker system prune removes containers/images/volumes. Confirm."
printf '%s' "$cmd" | grep -Eq 'docker[[:space:]]+(rm|rmi)[[:space:]]+-[a-zA-Z]*f' \
&& ask "Forced docker remove. Confirm."
# Pipe-to-shell of remote scripts.
printf '%s' "$cmd" | grep -Eq '(curl|wget)[[:space:]]+.*\|[[:space:]]*(sudo[[:space:]]+)?(sh|bash|zsh)' \
&& ask "Piping a downloaded script straight into a shell. Inspect the script first."
# Secret / token exfiltration smell: reading env or key material and sending it out.
printf '%s' "$cmd" | grep -Eq '(printenv|env|cat[[:space:]]+.*\.env|echo[[:space:]]+\$[A-Z_]*(TOKEN|SECRET|KEY|PASSWORD))' \
&& printf '%s' "$cmd" | grep -Eq '(curl|wget|nc|ncat|http)' \
&& ask "Command reads secrets/env and pipes to the network. Possible exfiltration. Confirm."
# Default: allow.
exit 0
freeze-edits.shshell · 2.2 KB
#!/usr/bin/env bash
# freeze-edits.sh
#
# Claude Code PreToolUse hook for Edit / Write / NotebookEdit.
# Enforces an edit boundary set by the /freeze (or /guard) skill.
#
# Mechanics:
# - The /freeze skill writes the allowed directory (one absolute path,
# trailing slash) to a project-local state file:
# .claude/session-state/freeze-boundary
# - If that file does not exist, edits are unrestricted (exit 0).
# - If it exists, any edit whose target path is NOT inside the boundary
# is DENIED with an explanation of how to unfreeze.
#
# Honesty note: this stops accidental Edit/Write outside the boundary. It is
# NOT a security control — Bash (sed, tee, >) can still write anywhere.
#
# Fails OPEN on any parse error so it can never wedge a session.
set -uo pipefail
input="$(cat)"
# Find the boundary file relative to where Claude is working.
cwd=""
if command -v jq >/dev/null 2>&1; then
cwd="$(printf '%s' "$input" | jq -r '.cwd // empty' 2>/dev/null)"
fi
[ -z "$cwd" ] && cwd="$(pwd)"
boundary_file="$cwd/.claude/session-state/freeze-boundary"
[ -f "$boundary_file" ] || exit 0 # not frozen
boundary="$(head -n1 "$boundary_file" 2>/dev/null)"
[ -z "$boundary" ] && exit 0
# Extract the edit target path.
path=""
if command -v jq >/dev/null 2>&1; then
path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.notebook_path // empty' 2>/dev/null)"
fi
[ -z "$path" ] && exit 0 # nothing to check -> allow
# Normalize to absolute.
case "$path" in
/*) abs="$path" ;;
*) abs="$cwd/$path" ;;
esac
# Inside boundary? (boundary stored with trailing slash to avoid /src matching /src-old)
case "$abs/" in
"$boundary"*) exit 0 ;;
esac
reason="FROZEN: edits are restricted to ${boundary}. '${abs}' is outside the boundary. To allow it, run /unfreeze (or edit .claude/session-state/freeze-boundary)."
if command -v jq >/dev/null 2>&1; then
jq -nc --arg r "$reason" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: $r
}
}'
else
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"%s"}}' "$reason"
fi
exit 0
unfreeze-edits.shshell · 567 B
#!/usr/bin/env bash
# unfreeze-edits.sh
#
# Removes the edit boundary set by /freeze (or /guard) for the current project.
# Safe to run anytime; no-op if nothing is frozen.
#
# Usage: bash unfreeze-edits.sh [project-dir]
set -uo pipefail
dir="${1:-$(pwd)}"
boundary_file="$dir/.claude/session-state/freeze-boundary"
if [ -f "$boundary_file" ]; then
prev="$(head -n1 "$boundary_file" 2>/dev/null)"
rm -f "$boundary_file"
echo "Unfrozen. Edit boundary removed (was: ${prev:-unknown})."
else
echo "Nothing to unfreeze (no boundary file at $boundary_file)."
fi
notify.shshell · 1.1 KB
#!/usr/bin/env bash
# notify.sh
#
# Claude Code Notification hook. Fires when Claude needs attention
# (e.g. waiting on input or a permission decision). Degrades gracefully
# on every platform; never fails the session.
#
# Reads the notification JSON on stdin; surfaces the message via the best
# available channel and always exits 0.
set -uo pipefail
input="$(cat)"
msg=""
if command -v jq >/dev/null 2>&1; then
msg="$(printf '%s' "$input" | jq -r '.message // empty' 2>/dev/null)"
fi
[ -z "$msg" ] && msg="Claude Code needs your attention."
if [ "$(uname)" = "Darwin" ] && command -v osascript >/dev/null 2>&1; then
# Pass the message as an argv item so no shell/AppleScript metacharacters are interpreted.
osascript - "$msg" >/dev/null 2>&1 <<'APPLESCRIPT' || true
on run argv
display notification (item 1 of argv) with title "Claude Code"
end run
APPLESCRIPT
elif command -v notify-send >/dev/null 2>&1; then
notify-send "Claude Code" "$msg" >/dev/null 2>&1 || true
else
# Terminal bell + stderr fallback.
printf '\a[Claude Code] %s\n' "$msg" 1>&2 || true
fi
exit 0
context-save.shshell · 1.7 KB
#!/usr/bin/env bash
# context-save.sh
#
# Helper for the /context-save skill. Gathers raw git state for the current
# repo and runs a lightweight secret/PII scan over the working tree changes.
# It does NOT write the context file itself — the skill composes the narrative
# (task, decisions, remaining work) and writes the final document after
# reviewing this output. This keeps a human/Claude review step in the loop.
#
# Usage: bash context-save.sh
# Prints: a git-state block, then a SECRET-SCAN block with any warnings.
set -uo pipefail
echo "=== GIT STATE ==="
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "(not a git repository)"
exit 0
fi
echo "branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
echo
echo "--- status (short) ---"
git status --short 2>/dev/null
echo
echo "--- recent commits ---"
git log --oneline -8 2>/dev/null
echo
echo "--- diff stat ---"
git diff --stat 2>/dev/null
git diff --cached --stat 2>/dev/null
echo
echo "=== SECRET-SCAN (review before saving) ==="
# Scan staged+unstaged diffs for things that should never be persisted.
scan="$( { git diff 2>/dev/null; git diff --cached 2>/dev/null; } )"
patterns='(AKIA[0-9A-Z]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----|xox[baprs]-[0-9A-Za-z-]+|ghp_[0-9A-Za-z]{36}|api[_-]?key["'"'"']?\s*[:=]|secret["'"'"']?\s*[:=]|password["'"'"']?\s*[:=]|bearer\s+[A-Za-z0-9._-]{20,}|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})'
hits="$(printf '%s' "$scan" | grep -nEi "$patterns" 2>/dev/null | head -n 20 || true)"
if [ -n "$hits" ]; then
echo "WARNING: potential secrets/PII/internal identifiers in your changes."
echo "Do NOT paste these into the saved context. Review:"
echo "$hits"
else
echo "No obvious secret/PII patterns found in the diff. Still review manually."
fi
context-restore.shshell · 1.1 KB
#!/usr/bin/env bash # context-restore.sh # # Helper for the /context-restore skill. Locates the most recent project-local # saved context and reports the current git state so the skill can detect drift # (branch changed, working tree diverged) before resuming. # # Usage: bash context-restore.sh set -uo pipefail ctx_dir=".claude/context" default="$ctx_dir/current-session.md" echo "=== SAVED CONTEXT ===" if [ -f "$default" ]; then echo "file: $default" echo "---" cat "$default" elif [ -d "$ctx_dir" ] && ls "$ctx_dir"/*.md >/dev/null 2>&1; then latest="$(ls -t "$ctx_dir"/*.md 2>/dev/null | head -n1)" echo "file: $latest" echo "---" cat "$latest" else echo "(no saved context found in $ctx_dir/)" fi echo echo "=== CURRENT GIT STATE (compare against saved) ===" if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then echo "branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null)" echo "--- status (short) ---" git status --short 2>/dev/null echo "--- recent commits ---" git log --oneline -5 2>/dev/null else echo "(not a git repository)" fi
health-check.shshell · 2.1 KB
#!/usr/bin/env bash
# health-check.sh
#
# Best-effort project health probe. Auto-detects the toolchain and runs the
# usual checks (lint / typecheck / test / build) without assuming a specific
# stack. Prints a pass/fail line per check; the /health-check skill turns this
# into a score and prioritized fixes.
#
# It does NOT install anything and does NOT modify files. Unknown stacks simply
# report "no recognized <x> script".
set -uo pipefail
pass=0; fail=0; skip=0
run() { # run "<label>" "<command...>"
label="$1"; shift
if "$@" >/tmp/healthcheck.out 2>&1; then
echo "PASS $label"; pass=$((pass+1))
else
echo "FAIL $label (see output below)"; fail=$((fail+1))
sed 's/^/ /' /tmp/healthcheck.out | tail -n 15
fi
}
skipmsg() { echo "SKIP $1"; skip=$((skip+1)); }
echo "=== PROJECT HEALTH CHECK ==="
# --- Node / JS / TS ---
if [ -f package.json ]; then
has() { grep -q "\"$1\"" package.json 2>/dev/null; }
pm="npm"; [ -f pnpm-lock.yaml ] && pm="pnpm"; [ -f yarn.lock ] && pm="yarn"
has lint && run "lint" $pm run lint || skipmsg "lint (no script)"
has typecheck && run "typecheck" $pm run typecheck || { has tsc && run "typecheck" npx tsc --noEmit || skipmsg "typecheck (no script)"; }
has test && run "test" $pm test || skipmsg "test (no script)"
has build && run "build" $pm run build || skipmsg "build (no script)"
fi
# --- Python ---
if [ -f pyproject.toml ] || [ -f setup.py ] || ls ./*.py >/dev/null 2>&1; then
command -v ruff >/dev/null 2>&1 && run "ruff" ruff check . || skipmsg "ruff (not installed)"
command -v mypy >/dev/null 2>&1 && run "mypy" mypy . || skipmsg "mypy (not installed)"
command -v pytest >/dev/null 2>&1 && run "pytest" pytest -q || skipmsg "pytest (not installed)"
fi
# --- Go ---
if [ -f go.mod ]; then
run "go vet" go vet ./...
run "go test" go test ./...
fi
# --- Rust ---
if [ -f Cargo.toml ]; then
run "cargo check" cargo check
run "cargo test" cargo test
fi
echo
echo "=== SUMMARY ==="
echo "pass=$pass fail=$fail skip=$skip"
[ "$fail" -eq 0 ]
bootstrap.shshell · 983 B
#!/usr/bin/env bash
# bootstrap.sh — one-shot setup for macOS / Linux.
#
# Run from a fresh clone of this repo:
# git clone https://github.com/sanjaesuresh/claude-code-toolkit.git
# cd claude-code-toolkit
# bash bootstrap.sh
#
# Or, to clone + install in one go from anywhere:
# REPO=https://github.com/sanjaesuresh/claude-code-toolkit.git \
# bash -c 'git clone "$REPO" ~/claude-code-toolkit && bash ~/claude-code-toolkit/bootstrap.sh'
#
# Copy mode by default. Pass --symlink for symlink mode.
set -uo pipefail
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
echo "[bootstrap] toolkit at: $REPO_DIR"
echo "[bootstrap] installing global config into ~/.claude ..."
bash "$REPO_DIR/scripts/install.sh" "$@"
echo "[bootstrap] validating ..."
bash "$REPO_DIR/scripts/validate-claude-config.sh" || {
echo "[bootstrap] validation reported problems — review the output above."
}
echo
echo "[bootstrap] Done. Open Claude Code and try: /office-hours or /careful"