All tools
HarnessMember post

Claude Code Toolkit harness

by sanjaesureshUpdated 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 GitHub

Files (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"