My Claude Code setup
/ 13 min read
Updated:This is a snapshot of how I currently extend Claude Code β plugins, hooks, the status line, and the workflow patterns I rely on day to day.
The goal is not to install every tool I can find. I want a setup that makes Claude Code better at five things: finding context, following repeatable development workflows, reviewing its own work, coordinating with other agents, and staying visible while it works.
Documentation and code intelligence
context7as an MCP server for up-to-date documentation lookup against current library versions. I run it as a plain MCP server rather than a plugin, with a small rule in~/.claude/rules/context7.mdthat says when Claude should reach for it.typescript-lsp,pyright-lsp,gopls-lsp,rust-analyzer-lsp, andswift-lspfor language server support.
Development workflow
feature-devfor thecode-architectandcode-explorersubagents I lean on during early architecture work. It is installed but switched off by default; I turn it on when I want those agents.code-reviewfor ad-hoc code reviews via the/code-reviewslash command, separate from the deeper review loops below.reviewercan also use it as a second engine.superpowersfor TDD discipline, systematic debugging, and the verification/review skills I rely on most. Paired with my own routing rules β see Shaping skill behavior below.
My own plugins
git-workflowfor repeatable Git operations and Conventional Commits, mainly/git-workflow:commit.mermaid-validatorfor checking Mermaid diagrams in Markdown with/mermaid-validator:check.reviewerfor spec and implementation review loops:/reviewer:specbefore implementation,/reviewer:resultafter it, and/reviewer:spec-dualto cross-check a spec with Claude and Codex. Result review is multi-angle by default, and--fixruns the fix iterations.digestfor summarizing branches, PRs, diffs, and design docs with/digest:digest.discussfor framing a decision before building:/discuss:discusssizes the decision, then lists assumptions, ranks hypotheses, or interviews me, and converges on an explicit choice.prompt-builderfor turning a messy session or a rough multi-task request into one paste-ready prompt that survives a rewind, with/prompt-builder:build.
git-workflow, reviewer, and digest have more commands than the ones above; the full list is in the agent-plugins README.
A few of them are hook modules, TypeScript hooks that run inside Claude Code 2.1.289 or later, so they change the interface itself:
cache-keepalivekeeps the prompt cache warm while I am away. About five minutes before the cache TTL runs out it sends one tool-less ping, and it turns itself off if a ping does not actually read from the cache./keepalive statusshows its state and/keepalive brb <minutes>keeps the cache warm for longer.cut-inputcopies the prompt box to the clipboard and clears it (Ctrl+Shift+U).image-peekshows a thumbnail of each pasted image above the prompt, in terminals that draw kitty graphics.
These live in my agent-plugins project.
Hooks
session-notifierfor Telegram and macOS notifications on Claude Code hook events β useful when a long-running agent stops and needs me back at the keyboard.rtk hook claudeonPreToolUse, a token-optimized CLI proxy that rewrites shell commands so their output costs fewer tokens.ccstatusline --hookonPreToolUse,UserPromptSubmit, andStop, which feeds the status lineβs skill widget (see Status line).- A small hook that reports whether an agent is waiting on me to cmux, the terminal I run Claude Code in.
Cross-agent and behavior shaping
codexfor delegating work from Claude Code to Codex. I use it selectively β second-opinion spec review and rescue runs, not every code change.andrej-karpathy-skillsfor reducing common LLM coding mistakes (over-engineering, untested assumptions, missing success criteria).security-guidancefor reminders about risky code edits.explanatory-output-stylefor more educational implementation explanations.
Tracking work with issue-graph
issue-graph is my self-hosted dependency graph and workstream tracker for Linear, and it ships a Claude Code plugin of the same name from its own marketplace (/plugin marketplace add shdennlin/issue-graph). I install it per project rather than globally: today that is my OneLegion repo, next to a project-scoped Linear MCP server.
A workstream is a feature in flight, drawn as the pipeline of stages it is moving through. The plugin connects a session to that board in four ways:
- Presence hooks report that a session is alive, working, waiting on me, or blocked on a permission prompt, so the card for the issue named in the branch shows what is happening right now. Only the session id, branch, working directory, and host are sent: no prompt text, file contents, or transcript. With
ISSUE_GRAPH_URLorISSUE_GRAPH_TOKENunset, the plugin does nothing. - A start-of-session briefing tells the session which workstream its branch belongs to, which stage it is on, and what is usually run at that stage. It states facts and gives no orders, and it is restored after a compaction.
- An MCP server with 18 tools for reading workstreams and stages, designing the pipeline, and moving work through it.
next_issueclaims the next unblocked issue in dependency order, andreport_donereleases it and unblocks whatever depended on it. - Two commands and a skill.
/wherereports where the current branch sits in its workstream, and/progressrecords what a session finished (evidence, decisions, and a stage move only if the work really moved), using theworkstream-progressskill.
Mods from Anthropic
Two more hook modules, both from Anthropic rather than me:
next-steps, from the community marketplace, suggests up to three next prompts above the input after each turn. Pressing 1, 2, or 3 drops one into the prompt box as a draft I can edit, and it never submits anything on its own.cc-plugin-you-should-know, a built-in, opt-in mod in which a side agent watches the session and flags things I or Claude might miss. I turned it on with/plugin enable cc-plugin-you-should-know@builtin.
Workflow patterns
Beyond the plugin list, a few patterns I rely on:
- Spec-driven development as the default. Spectra drives my workflow through
/spectra-discussβ/spectra-proposeβ/spectra-applyβ/spectra-archive. In-progress changes live inopenspec/changes/; consolidated truth lives inopenspec/specs/. /goalfor iterative review. I run/reviewer:specor/reviewer:resultunder Claude Codeβs built-in/goal, so the review-fix-review cycle keeps running until the severity gate clears. After each turn a separate evaluator checks the condition and starts another turn if it is not met. MEDIUM is treated as a blocker, not as LOW.- Two-engine spec review for high-stakes specs. For architectural or security-sensitive specs I run
/reviewer:spec-dual: Claude and Codex review the same change in parallel, and a workflow takes the union of their findings and loops the fixes until both engines are MEDIUM-clean. A blocker needs only one engine; clearing needs both. The details live in the reviewer README. - Result review uses one engine by default. Spec errors propagate to all downstream implementation; result errors are localized. Multi-model review pays off on specs (1-3 dispatches per change, high error cost) but rarely on results (10+ iterations, lower marginal value). A second engine is one flag away (
-cadds the built-in/code-review), and I reserve it for security-sensitive, concurrency, or performance-hotpath code.
Shaping skill behavior with rules
~/.claude/rules/skill-routing.md is a user-instruction layer that overrides plugin-defined skill behavior. It is deliberately small β only three rules, each fixing a specific failure mode that Claude wouldnβt avoid on its own:
- Spectra-vs-superpowers routing. In Spectra repos, prefer
spectra-discuss/spectra-debugover the equivalent superpowers skills, so design and debugging stay tied to Spectraβs artifacts. - Suppress
superpowers:brainstormingauto-writing design docs. The design discussion belongs in conversation; file output is friction. - Force-trigger
superpowers:verification-before-completionandsuperpowers:receiving-code-review. These are the two skills with the highest ROI β they keep βI claimed it was doneβ and βI blindly chased a reviewer suggestionβ from happening.
Workflow sequencing (discuss β propose β apply β archive) is not in the rules β thatβs personal habit, not something Claude needs to enforce. User instructions outrank plugin-defined skill behavior, so superpowers stays installed (and gets upstream updates) while its rough edges get sanded down at user-instruction priority.
Full ~/.claude/rules/skill-routing.md
# Skill Routing & Behavior Overrides
These rules override default skill behavior. **User instructions > superpowers skills > defaults**, so this file wins on conflict.
## 1. Spectra-vs-superpowers routing
In Spectra repos (`openspec/` exists at git root), prefer Spectra skills over superpowers equivalents β `spectra-discuss` over `superpowers:brainstorming`, `spectra-debug` over `superpowers:systematic-debugging`. Routing the request to superpowers bypasses Spectra's artifact tracking.
In non-Spectra repos this rule does not apply β superpowers wins because Spectra skills won't trigger anyway.
## 2. Behavior overrides on superpowers skills
### `superpowers:brainstorming`- Do NOT automatically write `docs/superpowers/specs/YYYY-MM-DD-*-design.md` or any design doc file. Present the design in conversation only.- Skip the "Write design doc" checklist step (step 6 in the SKILL).- **Why**: I prefer in-conversation design discussion. File output is friction.
### `superpowers:using-superpowers`- Do NOT add a TodoWrite todo per skill checklist item unless the task has 4+ genuinely independent sub-tasks.- **Why**: TodoWrite spam clutters short tasks.
## 3. Force-trigger these superpowers skills
### `superpowers:verification-before-completion` β MANDATORY- Trigger before claiming work is "done", "fixed", "passing", "ready", or before a commit / PR.- Run the verification command (test, build, manual check) and paste the output. No verification = no claim of completion.
### `superpowers:receiving-code-review` β MANDATORY- Trigger when applying review feedback from any review-fix loop (`reviewer:result-fixer`, `reviewer:spec-fixer`, `/codex:review`, etc.).- For each review item, first verify the claim is technically correct. Push back with evidence on wrong/unnecessary suggestions instead of blindly implementing.Status line
ccstatusline drives a two-line status bar:
- Project and Claude β current directory (via the
showdirhelper below), git branch with ahead/behind and change counts, worktree, model and thinking effort, Claude Code version, and a red alert that only appears when status.claude.com says Claude Code is not operational. The alert comes from a small script,claude-status-alert, that prints nothing when everything is healthy, so the segment stays hidden. - Context, cache, and cost β context-window percentage, prompt-cache hit rate with the
cache-keepalivewidget next to it, a compaction counter (hidden at zero), 5-hour usage with its reset timer, weekly usage, session cost and duration, a short session ID, and the active skill.
Claude Codeβs own statusLine entry runs ccstatusline with refreshInterval set to 30 seconds, so the clock and usage keep moving while I am idle.
The third line in the screenshot (INSERT, auto mode, the agent count) is Claude Codeβs own footer, not part of ccstatusline.
Full ~/.config/ccstatusline/settings.json
{ "version": 4, "lines": [ [ { "type": "custom-command", "commandPath": "showdir --icon" }, { "type": "separator", "character": " β " }, { "type": "git-branch", "color": "brightGreen" }, { "type": "custom-text", "customText": " " }, { "type": "git-ahead-behind", "color": "brightYellow", "metadata": { "hide": "no-upstream" } }, { "type": "custom-text", "customText": " " }, { "type": "git-changes", "color": "brightYellow" }, { "type": "separator", "character": " β " }, { "type": "git-worktree", "color": "blue" }, { "type": "separator", "character": " β " }, { "type": "model", "color": "brightMagenta", "rawValue": true, "bold": true }, { "type": "custom-text", "customText": " Β· ", "color": "brightBlack" }, { "type": "thinking-effort", "color": "white", "rawValue": true }, { "type": "separator", "character": " β " }, { "type": "version", "color": "brightBlue", "bold": true }, { "type": "separator", "character": " β " }, { "type": "custom-command", "color": "brightRed", "bold": true, "commandPath": "~/.local/bin/claude-status-alert" } ], [ { "type": "custom-text", "customText": "ctx ", "color": "brightGreen" }, { "type": "context-percentage", "color": "brightGreen", "rawValue": true }, { "type": "separator", "character": " β " }, { "type": "custom-text", "customText": "cache ", "color": "yellow" }, { "type": "cache-hit-rate", "color": "yellow", "rawValue": true, "metadata": { "hide": "empty" } }, { "type": "custom-command", "color": "yellow", "commandPath": "<agent-plugins>/plugins/cache-keepalive/bin/keepalive-cache --ttl 3600" }, { "type": "separator", "character": " β " }, { "type": "compaction-counter", "color": "brightRed", "metadata": { "format": "icon-space-number", "nerdFont": "true", "hide": "zero" } }, { "type": "separator", "character": " β " }, { "type": "custom-text", "customText": "5h ", "color": "brightCyan" }, { "type": "session-usage", "color": "brightCyan", "rawValue": true }, { "type": "custom-text", "customText": " β»", "color": "brightCyan" }, { "type": "reset-timer", "color": "brightCyan", "rawValue": true, "metadata": { "display": "time", "compact": "true" } }, { "type": "separator", "character": " β " }, { "type": "custom-text", "customText": "wk ", "color": "brightBlue" }, { "type": "weekly-usage", "color": "brightBlue", "rawValue": true }, { "type": "separator", "character": " β " }, { "type": "session-cost", "color": "brightWhite", "rawValue": true }, { "type": "custom-text", "customText": "Β·", "color": "brightBlack" }, { "type": "session-clock", "color": "brightWhite", "rawValue": true }, { "type": "separator", "character": " β " }, { "type": "custom-command", "color": "cyan", "commandPath": "jq -r '.session_id[0:8]'" }, { "type": "separator", "character": " β " }, { "type": "skills", "color": "brightCyan", "metadata": { "hide": "empty" } } ] ], "flexMode": "full", "compactThreshold": 60, "colorLevel": 3}I omitted the per-widget id UUIDs and the defaulted fields for readability, and shortened two paths (<agent-plugins> is wherever the plugin is checked out); ccstatusline regenerates the IDs on first save.
showdir helper
The first widget on line 1 shells out to ~/.local/bin/showdir, a small POSIX script that prints a project-relative path. Inside a git repo it prints <repo>/<relative-path> with a π prefix; outside, <parent>/<dir> with π. Shorter and more useful than the full absolute path that would otherwise eat half the line.
Full ~/.local/bin/showdir
#!/usr/bin/env sh# Usage: showdir [--icon] [-n|--no-newline]
icon=0; noline=0while [ $# -gt 0 ]; do case "$1" in --icon) icon=1 ;; -n|--no-newline) noline=1 ;; esac shiftdone
prefix_icon=""if git_root=$(git rev-parse --show-toplevel 2>/dev/null); then project=${git_root##*/} case "$PWD" in "$git_root"|"${git_root%/}") rel="";; *) rel=${PWD#"$git_root"/};; esac [ "$icon" -eq 1 ] && prefix_icon="π " out=$project${rel:+"/$rel"}else path=$PWD last=${path##*/} parent=${path%/*} second_last=${parent##*/} [ "$second_last" = "$last" ] && out="$last" || out="$second_last/$last" [ "$icon" -eq 1 ] && prefix_icon="π "fi
if [ "$noline" -eq 1 ]; then printf "%s%s" "$prefix_icon" "$out"else printf "%s%s\n" "$prefix_icon" "$out"fiHow I decide whether something stays
A tool is worth keeping if it reduces repeated prompting, improves review quality, catches mistakes, or turns a workflow I already use into something repeatable.
If it only feels impressive once but does not change my daily workflow, it probably does not belong in the setup.
Comments
Local graph
1 linked page Β· full graph β