My working Claude Code environment — the skills, hooks, and background scripts I actually run day to day, extracted and de-personalized.
Everything here I wrote myself. Third-party and vendor skills I use are listed below but deliberately not vendored — this repo is meant to show what I built, not what I installed.
The interesting part isn't the markdown. It's that several of these are not
prompts at all: overnight is a control loop spanning a status line, a
PostToolUse hook, a launchd agent, and a background sleeper process, built to
keep a long unattended run alive across subscription rate limits without burning
quota.
Skills alone can't observe or interrupt a run — they only execute once Claude decides to invoke them. Anything that needs to watch has to live in the harness. So the overnight stack splits across four layers:
flowchart TB
subgraph sensor["Sensor — runs every render"]
SL["statusline-command.sh<br/>tees rate_limits → usage-cache.json"]
end
subgraph guard["Guard — PostToolUse hook, 5 min throttle"]
LG["limit-guard.sh<br/>reads cache, compares vs thresholds<br/>5h ≥ 85% · 7d ≥ 70%"]
end
subgraph agent["Agent — skills Claude executes"]
OV["overnight/<br/>kickoff, gates, verify-before-done"]
PK["overnight-park/<br/>park · weekly-stop · resume"]
end
subgraph os["OS — outside the session"]
SW["stall-watcher.sh<br/>launchd, every 5 min"]
PS["park-sleeper.sh<br/>55-min heartbeat ticks"]
IM["imessage-self.sh<br/>alert to phone"]
OA["orphan-agents.sh<br/>transcript-idle sweep"]
end
SL -->|"usage-cache.json"| LG
LG -->|"injects LIMIT GUARD<br/>into context"| PK
OV -->|"arms"| SW
OV -->|"sweeps before summary"| OA
PK -->|"launches"| PS
PS -->|"PARK HEARTBEAT / WINDOW RESET"| PK
SW --> IM
PK --> IM
Four design constraints drove that shape:
The hook can't ask Claude to stop — it can only inject text. So limit-guard.sh
writes a LIMIT GUARD message naming the exact skill, mode, and reset epoch, and
overnight-park is written to be triggered only by that injection. The hook is a
sensor with an opinion; the skill is the actuator.
A parked session goes cold. The naive park is one long sleep until the rate
limit resets. That means zero API turns for hours, the prompt cache expires, and
resuming re-ingests the entire transcript at full price. park-sleeper.sh instead
wakes every 55 minutes — inside the cache TTL — and each cheap tick keeps the lead
session warm. The skill's job on a heartbeat is to relaunch the sleeper and do
nothing else; padding the tick defeats the whole mechanism.
Killed subagents must not be resumed. Cold-resuming a large-context subagent
re-ingests its full transcript. Doing that to several at once once cost ~30% of a
5-hour window. So the park protocol treats stopped agents as abandoned: their
findings already live in the lead's context and in docs/overnight-gates/, and
resume spawns fresh small-context agents briefed from those files.
A finished subagent does not necessarily stop. The line above assumes findings
reach docs/overnight-gates/; when they don't, both halves of that assumption fail
at once. A subagent spawned with a name is an addressable teammate, so if it
delivers its report via SendMessage and ends its turn it parks awaiting a reply
that never comes — it never exits, and the task panel keeps counting wall-clock at
it, which is indistinguishable from work in progress. Meanwhile its findings exist
only in the lead's context, which the next compaction discards. On 2026-08-06 six
agents sat orphaned for over four hours while the run's ledger still showed their
gates "in flight" and docs/overnight-gates/ held nothing but ledgers.
So gates are spawned unnamed and return their verdict (unnamed subagents
terminate on return), the report file is the deliverable rather than the message,
and orphan-agents.sh sweeps before the morning summary. It compares each
subagent transcript's mtime against now — transcript activity is evidence, the
panel's since-spawn timer is not.
State files are keyed by $CLAUDE_CODE_SESSION_ID throughout, so concurrent
overnight runs in different projects don't clobber each other's park state — an
earlier version keyed them globally and one stalled session masked another.
Runs an implementation task unattended, overnight, and survives hitting the subscription rate limit mid-run.
- Pre-flight: refuses to start a run that won't fit the remaining weekly quota — the only permitted question, asked while the user is still awake.
- Verified-not-implemented gate: nothing is marked done until tests pass and, where there's a runtime surface, behavior was actually exercised. Waking up to a green checklist over a broken tree is the failure mode this exists to prevent.
- Quality gates by diff shape (
gates.md): best-practices always; task-conformance on any multi-file step; security when the diff touches auth/crypto/IO/deserialization or adds a dependency; a11y when it touches UI surfaces. Gates that didn't fire get logged too — silent skipping reads as "reviewed" when it wasn't. - Task conformance as its own gate (
task-conformance-verifier): the other three grade the diff, and all three pass a clean, well-written implementation of the wrong thing. This one gets the original task text verbatim — never the lead's restatement or the worker's account — and its mandatoryNot checkedsection means unchecked never silently counts as passed. - Run ledger (
docs/overnight-gates/ledger.md): baseline commit, one row per atomic step with its declared write set, append-only attempt log. Gate reports dedup findings; the ledger is what survives a park/resume, so a resumed lead reconciles againstgit statusinstead of guessing. - Explicit model routing: every subagent dispatch passes
modelexplicitly. Omitting it inherits the lead's tier, and overnight leads deliberately run on a premium model for coordination quality — so an omitted param silently bills every grep and lint pass at lead rates. - Two limit modes: 5h cap → park and resume. 7d cap → stop cleanly, because a fresh 5h window drawn from a dead weekly budget buys nothing.
The one that's pure judgment, no code. Encodes how a design conversation should go: lead with a real position rather than "what do you think?", name the latent distinction the user hasn't articulated yet, give concrete numbers with units, partition v1/v1.x/v2 with reasons, surface adjacent risks unprompted, and end a turn on the single load-bearing question rather than burying it.
Included because most of what makes an agent useful in design work is refusing to be agreeable, and that turns out to be specifiable.
Wraps NVIDIA SkillSpector in Docker to scan agent skills for malicious patterns before installing them. I run this on every skill I install, from any source.
The non-obvious part is the triage guidance, which is most of the file. Both scanner
passes overstate: static/YARA mode flags any doc that merely mentions rm -rf or
shell=True, and the LLM pass reports data flows that read as RCE but never execute.
The skill's rule is to open the cited file:line, trace whether attacker-controlled
input actually reaches execution, and report ground truth — not the scanner's severity
verbatim. A security tool you relay uncritically is worse than none.
Markdown → print-ready PDF via python-markdown → tuned CSS → headless Chrome, with a mandatory two-step review: render the PDF pages back as images and inspect them, then hand to a second-opinion subagent that judges print-readiness without knowing how the file was produced.
The review steps are the skill. PDF generation is one-shot and unpreviewed — a clipped table stays clipped forever once the file leaves the machine — and after choosing the rendering parameters yourself you stop seeing its problems.
The long tail. Small, but they're most of what daily use actually looks like.
| Skill | What it does |
|---|---|
session-log → claude-second-brain |
Session logging and its Stop/SessionStart hooks moved to their own repo: a self-installing Obsidian "second brain" (vault scaffold, session-log skill, cross-platform Node hooks, Claude-driven installer). I run what it ships, installed the same way anyone else would. |
commit-push |
Commit and push, no PR. Writes the message to a session-unique file — never -m, never a shared /tmp path, both of which have corrupted commits for me in practice. |
screenshot |
Pulls the newest file from the screenshots folder into the conversation. Removes the drag-and-drop step from every visual debugging loop. |
rename-to-dir |
Renames the session to the working directory's basename. Three lines. Makes session history navigable when you keep a dozen open. |
skills/ the skills themselves → ~/.claude/skills/
hooks/ limit-guard.sh (PostToolUse) → ~/.claude/hooks/
scripts/ background helpers → ~/.claude/scripts/
agents/ a11y-reviewer, → ~/.claude/agents/
task-conformance-verifier
statusline/ rate-limit sensor → ~/.claude/
launchagents/ stall-watcher plist → ~/Library/LaunchAgents/
Copy what you want; nothing here depends on taking all of it. The four utilities
and design-mode are standalone — drop the directory into ~/.claude/skills/
and you're done.
The overnight stack needs all four layers wired together:
ditto skills/overnight ~/.claude/skills/overnight
ditto skills/overnight-park ~/.claude/skills/overnight-park
ditto scripts ~/.claude/scripts
ditto agents ~/.claude/agents
cp hooks/limit-guard.sh ~/.claude/hooks/
cp statusline/statusline-command.sh ~/.claude/
chmod +x ~/.claude/hooks/limit-guard.sh ~/.claude/scripts/*.sh ~/.claude/statusline-command.shThen register the status line and hook in ~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/statusline-command.sh"
},
"hooks": {
"PostToolUse": [
{ "matcher": "*", "hooks": [
{ "type": "command", "command": "~/.claude/hooks/limit-guard.sh" }
]}
]
}
}The status line is not cosmetic here — it is the only place the native
rate_limits block is exposed, so it's what feeds the guard. Without it the hook
reads no cache and silently never fires.
For phone alerts and the stall watcher, see
launchagents/.
| Variable | Used by | Purpose |
|---|---|---|
IMSG_TARGET |
scripts/imessage-self.sh |
iMessage recipient for alerts. Unset → local notification only. |
SKILLSPECTOR_REPO |
skillspector |
Local clone of NVIDIA/skillspector. |
| Skill | Needs |
|---|---|
overnight |
jq, macOS (launchd + Messages), a Claude subscription exposing rate_limits |
skillspector |
Docker, a clone of NVIDIA/skillspector, an Anthropic API key for the LLM pass |
md2pdf |
python3 + markdown, Chrome or Chromium |
I scanned this repo with NVIDIA SkillSpector
(LLM mode, v2.2.3) — the same tool the skillspector skill wraps. It returned
38 findings, CRITICAL, DO_NOT_INSTALL. I read every one against the source. None
are exploitable, and several are factually wrong about the code:
- 5 × "unquoted variable expansion" in
rm -f(plus 2 more flagging&&chaining on the same lines) — every one of those expansions is quoted:rm -f ~/.claude/park-state-"${CLAUDE_CODE_SESSION_ID:-main}".json. The variable is set by Claude Code, so reaching it already requires code execution. - "AppleScript injection" in
imessage-self.sh— inverted. The values go throughosascript'sargvwith a quoted heredoc, which is the injection-safe pattern; nothing is interpolated into the script body. subprocesscall inmd2pdf.py— array-arg, noshell=True, noeval/exec.- 6 × "session persistence" on the LaunchAgent — accurate, and the documented purpose of a LaunchAgent.
- 16 × a generic shell-command rule firing on things like
git rev-parse,ls, and appending to a log file.
Three findings were worth acting on, and are fixed:
- The LaunchAgent shipped with install but no uninstall instructions.
session-log's description promised "save a log" while the skill could also rewrite footers across the vault. The description and a scope banner now disclose exactly what it writes, and which part asks first. (The skill has since moved to claude-second-brain.)- Not flagged by the scanner, found while triaging it:
md2pdf.pypassed--no-sandboxto headless Chrome. Unnecessary on a normal user account — verified identical output without it, and removed.
One finding is real but by design, and worth stating plainly: park-sleeper.sh writes
instructions to stdout that land in the agent's context and steer its next turn
("relaunch the sleeper, do nothing else"). That is structurally the same channel as a
prompt injection — the difference is only that the script is mine and I launched it.
If you install this, you are trusting that script the way you'd trust a shell alias.
It's the one place in the repo where reading the source before running it genuinely
matters.
The broader lesson is the one the skillspector skill is built around: a scanner
verdict is a place to look, not a conclusion. A CRITICAL that nobody traces to source
is indistinguishable from noise.
- macOS-only in places.
imessage-self.shis AppleScript, the stall watcher is launchd,screenshotassumes a macOS screenshots folder. The skills themselves are portable; the OS layer isn't. overnightis coupled to subscription rate limits. The whole park/resume design assumes therate_limitsblock exists in the status line payload. On API-key billing there's nothing to park against and the guard is dead weight.- Thresholds are hardcoded (85% / 5h, 70% / 7d) rather than configurable. They're tuned to my usage. There's a time-boxed override file for the weekly threshold that self-expires — deliberately, so a temporary loosening can't quietly become permanent — but the 5h number needs a source edit.
- The gates depend on subagents I didn't vendor.
gates.mdroutes the best-practices gate to a third-party reviewer subagent; a stock substitute is named inline. The a11y and task-conformance subagents are included. - The task-conformance gate and run ledger are new and unexercised. Both were
added on top of a working stack rather than shaken out by a run that needed them.
The failure mode to watch for on first use is the gate passing everything with a
thin
Not checkedsection — that means it's rubber-stamping, usually because it was handed a restatement instead of the original spec text. - No tests. These are prompt + shell artifacts validated by daily use, not a test suite. The shell scripts are the part that most deserves one.
Not mine, so not here. Listed for completeness, since they show up in the routing
above or in the environment these were built for: Anthropic's document skills
(docx, pdf, pptx, xlsx, mcp-builder), drawio-skill (Agents365-ai),
humanizer (@blader), graphify, agent-browser, and the caveman plugin's
cavecrew-* reviewer subagents.
MIT — see LICENSE.