trailofbits-skills
A Claude Code plugin marketplace from Trail of Bits providing skills to enhance AI-assisted security analysis, testing, and development workflows. Codex can load this marketplace through its Claude marketplace compatibility.
Opinionated defaults, documentation, and workflows for Claude Code at Trail of Bits. Covers sandboxing, permissions, hooks, skills, MCP servers, and usage patterns we've found effective across security audits, development, and research.
Repo: trailofbits/claude-code-config
What's inside
Opinionated defaults, documentation, and workflows for Claude Code at Trail of Bits. Covers sandboxing, permissions, hooks, skills, MCP servers, and usage patterns we've found effective across security audits, development, and research.
Also see: skills · skills-curated · claude-code-devcontainer · dropkit
First-time setup:
git clone https://github.com/trailofbits/claude-code-config.git
cd claude-code-config
claude
Then inside the session, run /trailofbits:config. It walks you through installing each component, detects what you already have, and self-installs the command so future runs work from any directory. Run /trailofbits:config again after updates.
Getting Started
Configuration
Usage
Before configuring anything, read these to understand the context for why this setup works the way it does:
Use Ghostty. It's the best terminal for Claude Code because it uses native Metal GPU rendering, so it handles the high-volume text output from long AI sessions without lag or memory bloat (~500MB vs ~8GB for two VS Code terminal sessions). Shift+Enter and key bindings work out of the box with no /terminal-setup needed, built-in split panes (Cmd+D / Cmd+Shift+D) let you run Claude Code alongside a dev server without tmux, and it never crashes during extended autonomous runs.
brew install --cask ghostty
macOS only. On Linux, see the Ghostty install docs. No Windows support yet -- use WezTerm there.
Install core tools via Homebrew:
brew install jq ripgrep fd ast-grep shellcheck shfmt \
actionlint zizmor macos-trash node@22 pnpm uv
Python tools (via uv):
uv tool install ruff
uv tool install ty
uv tool install pip-audit
Rust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install prek worktrunk cargo-deny cargo-careful
Node tools:
npm install -g oxlint agent-browser
LM Studio (for local models):
curl -fsSL https://lmstudio.ai/install.sh | bash
This installs lms (the CLI) and llmster (the headless daemon). Or install the LM Studio desktop app if you prefer a GUI.
Add to ~/.zshrc:
alias claude-yolo="claude --dangerously-skip-permissions"
--dangerously-skip-permissions bypasses all permission prompts. This is the recommended way to run Claude Code for maximum throughput -- pair it with sandboxing (below).
If you're using local models, also add:
claude-local() {
ANTHROPIC_BASE_URL=http://localhost:1234 \
ANTHROPIC_AUTH_TOKEN=lmstudio \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude --model qwen/qwen3-coder-next "$@"
}
claude-local wraps claude with the local server env vars and disables telemetry pings that won't reach Anthropic anyway. Use it anywhere you'd normally run claude.
Copy settings.json to ~/.claude/settings.json (or merge entries into your existing file). The $schema key enables autocomplete and validation in editors that support JSON Schema. The template includes:
env (privacy) -- disables three non-essential outbound streams: Statsig telemetry (DISABLE_TELEMETRY), Sentry error reporting (DISABLE_ERROR_REPORTING), and feedback surveys (CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY). Avoid the umbrella CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC -- it also disables auto-updates.env (agent teams) -- CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS enables multi-agent teams where one session coordinates multiple teammates with independent context windows. Experimental -- known limitations around session resumption and task coordination. Note that it also changes ordinary delegation: while agent teams are on, a subagent Claude names on its own launches as a full teammate, so teams can form when you didn't ask for one.env (subagent depth) -- CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH: "3" pins how many layers of subagents can nest below the main agent. Three is the current built-in default, so this changes nothing today -- the point is that the default is delivered by a remote feature flag (observed in the binary; the docs don't say so), so without pinning it the effective nesting limit can move without a release. Claude 5 models delegate more readily than previous ones, and this limit is enforced at spawn time rather than being prompt guidance. Set it to 1 to stop subagents from spawning their own. The companion CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS (default 20) is left unset here: 20 is already generous, and picking a lower number is a throughput guess. Both env vars exist since Claude Code v2.1.217; the built-in depth default of 3 dates from v2.1.219, so earlier releases default differently.enableAllProjectMcpServers: false -- this is the default, set explicitly so it doesn't get flipped by accident. Project .mcp.json files live in git, so a compromised repo could ship malicious MCP servers.alwaysThinkingEnabled -- absent and true behave identically: thinking is enabled automatically for supported models unless the setting is false, so setting it to true bought nothing. Setting it to false still disables thinking on Opus 5 (at high effort or below) and on Sonnet 5; Fable 5 can't turn thinking off at all. MAX_THINKING_TOKENS=0 does the same and takes precedence over the setting. What's gone on Claude 5 is manual thinking budgets, so effort is the lever for the intelligence-versus-cost tradeoff -- set it with /effort. Anthropic's guidance is high as the default, xhigh for the hardest coding and agentic work, and low or medium liberally for routine work where quality holds, since lower settings on Claude 5 often beat xhigh on the previous generation.permissions -- deny rules that block reading credentials/secrets and editing shell config (see Sandboxing)cleanupPeriodDays: 365 -- keeps conversation history for a year instead of the default 30 days, so /insights has more datahooks -- two PreToolUse hooks on Bash that block rm -rf and direct push to main (see Hooks)statusLine -- points to the statusline script (see below)A two-line status bar at the bottom of the terminal:
[Opus 4.6] 📁 claude-code-config │ 🌿 main
████⣿⣿⣿⣿⣿⣿⣿⣿ 28% │ $0.83 │ ⏱ 12m 34s ↻89%
Line 1 shows the model, current folder, and git branch. Line 2 shows a visual context usage bar (color-coded: green <50%, yellow 50-79%, red 80%+), session cost, elapsed time, and prompt cache hit rate.
Copy the script:
mkdir -p ~/.claude
cp scripts/statusline.sh ~/.claude/statusline.sh
chmod +x ~/.claude/statusline.sh
The statusLine entry in settings.json points to this script. Requires jq.
The global CLAUDE.md file at ~/.claude/CLAUDE.md sets default instructions for every Claude Code session. It's split into two layers so that each session only pays for what it needs.
claude-md-template.md is the always-loaded layer, kept to about 100 lines. It carries only what has to hold before any file is read: task scoping, communication and progress-reporting standards, quality gates, testing methodology, code review order, the CLI tool table, one default toolchain per language, and workflow conventions (commits, hooks, subagents, memory, PRs).
rules/ is the on-demand layer. Each file is a path-scoped rule carrying the detailed configuration for one language -- ruff and clippy lint blocks, tsconfig strictness flags, supply-chain settings, workflow hardening. The paths: frontmatter means a rule loads only when Claude touches a matching file, so a Rust project never pays context for the Python guidance:
| file | loads when Claude touches |
|---|---|
rules/python.md | *.py, *.pyi, *.ipynb, pyproject.toml, uv.lock |
rules/rust.md | *.rs, Cargo.toml, Cargo.lock |
rules/typescript.md | *.ts, *.tsx, *.mts, *.cts, *.js, *.jsx, *.mjs, *.cjs, package.json, tsconfig.json |
rules/bash.md | *.sh, *.bash |
rules/github-actions.md | .github/workflows/**, .github/actions/**, dependabot.yml, dependabot.yaml |
The globs match file paths, not contents, so extensionless shell scripts (git hooks, bin/ tools) never trigger rules/bash.md -- the always-loaded tool table still covers shellcheck and shfmt for those.
/trailofbits:config installs both layers and handles a non-default CLAUDE_CONFIG_DIR. To do it by hand:
mkdir -p ~/.claude/rules
cp claude-md-template.md ~/.claude/CLAUDE.md
cp rules/*.md ~/.claude/rules/
Review and customize both layers -- adjust the toolchain table and the rule files to match your stack. One rule of thumb when deciding which layer something goes in: path-scoped rules are not automatically re-injected after auto-compaction -- they come back only when Claude next reads a matching file -- so anything that must hold unconditionally belongs in CLAUDE.md, and anything that must hold regardless of what Claude decides belongs in a hook.
For background on how CLAUDE.md files work, see Manage Claude's memory. To debug which files actually loaded and why, use the InstructionsLoaded hook; /context shows the session-start set. Note that @path imports load at launch like the rest of CLAUDE.md, so they help organization but don't reduce context -- path-scoped rules are the mechanism that does.
A Claude Code plugin marketplace from Trail of Bits providing skills to enhance AI-assisted security analysis, testing, and development workflows. Codex can load this marketplace through its Claude marketplace compatibility.
FAQ
claude-code-config is a Claude Code plugin with hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it