feat: initial open marketplace with llm-security, config-audit, ultraplan-local

This commit is contained in:
Kjell Tore Guttormsen 2026-04-06 18:47:49 +02:00
commit f93d6abdae
380 changed files with 65935 additions and 0 deletions

View file

@ -0,0 +1,44 @@
# Configuration Anti-Patterns
> 28 anti-patterns with detection IDs, severity, and fix. Mapped to scanner finding IDs where applicable.
| # | Pattern | Detection | Severity | Fix |
|---|---------|-----------|----------|-----|
| 1 | CLAUDE.md over 200 lines | CA-CML-001 | medium | Extract sections with `@import`. Split into domain-specific rule files in `.claude/rules/`. |
| 2 | No `@import` in CLAUDE.md over 100 lines | CA-CML-002 | low | Move large specs/docs to separate files, reference with `@path/to/file`. |
| 3 | No CLAUDE.local.md alongside CLAUDE.md | CA-CML-003 | low | Create `CLAUDE.local.md`, add to `.gitignore`. Move personal dev notes and sandbox URLs there. |
| 4 | Duplicate content in CLAUDE.md sections | CA-CML-004 | low | Deduplicate. If the same instruction appears in multiple sections, it suggests the file has grown without review. |
| 5 | TODO/FIXME comments in CLAUDE.md | CA-CML-005 | low | Remove stale TODOs or complete them. Unresolved TODOs add noise to every session. |
| 6 | Broken `@import` path in CLAUDE.md | CA-CML-006 | high | Verify the imported file exists at the referenced path. Broken imports silently drop content. |
| 7 | No section headers in CLAUDE.md | CA-CML-007 | medium | Add `##` section headers. Claude uses structure to navigate selectively; flat text loads entirely. |
| 8 | settings.json missing `$schema` | CA-SET-001 | low | Add `"$schema": "https://json.schemastore.org/claude-code-settings.json"` as first key. |
| 9 | Unknown or deprecated key in settings.json | CA-SET-002 | medium | Remove/replace. `includeCoAuthoredBy` is deprecated — use `attribution`. Unknown keys are silently ignored. |
| 10 | Type mismatch in settings.json | CA-SET-003 | high | Fix value type. E.g., `disableAllHooks` must be bool (`true`), not string (`"true"`). Wrong types are silently ignored. |
| 11 | No `permissions.deny` rules | CA-SET-004 | high | Add deny rules for `.env`, `secrets/`, credentials. Without them, Claude can read sensitive files. |
| 12 | No `permissions.allow` rules in active project | CA-SET-005 | medium | Pre-allow safe commands: `Bash(npm run *)`, `Bash(git log *)`. Reduces constant permission prompts. |
| 13 | `defaultMode` left at `"default"` for all projects | CA-SET-006 | low | Set `"defaultMode": "acceptEdits"` for development repos, `"plan"` for infrastructure/prod repos. |
| 14 | hooks.json as array instead of object | CA-HKV-001 | high | Convert to event-keyed object. `{"hooks": {"PreToolUse": [...]}}` not `{"hooks": [...]}`. Array format is silently ignored. |
| 15 | Hook script path not found | CA-HKV-002 | high | Verify script exists at referenced path. Use `${CLAUDE_PLUGIN_ROOT}` for plugin scripts to prevent path fragility. |
| 16 | Invalid event name in hooks.json | CA-HKV-003 | high | Use only valid event names: SessionStart, PreToolUse, PostToolUse, Stop, etc. Typos (e.g., `PreTool`) are ignored. |
| 17 | Hook timeout not set on long-running script | CA-HKV-004 | medium | Add `"timeout": 30000` (ms) for scripts that may take time. Default timeout may kill scripts prematurely. |
| 18 | hooks.json `matcher` as nested object | CA-HKV-005 | high | `"matcher"` must be a plain string (`"Bash"`), not `{"tool": "Bash"}`. Nested object format is never matched. |
| 19 | `"hooks"` key in plugin.json | CA-HKV-006 | medium | Remove from plugin.json. Hooks are auto-discovered from `hooks/hooks.json`. Declaring in plugin.json causes duplicate registration. |
| 20 | Rules file without `paths:` frontmatter | CA-RUL-001 | medium | Add `paths:` glob patterns. Without paths, the rule loads for every session regardless of file context. |
| 21 | Rules file glob doesn't match any project files | CA-RUL-002 | low | Fix the glob pattern. `src/**/*.ts` won't match `./src/file.ts` — test actual paths. |
| 22 | Deprecated frontmatter field in rules file | CA-RUL-003 | low | Remove/replace deprecated fields. Check official docs for current frontmatter schema. |
| 23 | `.claude/rules/` directory missing entirely | CA-RUL-004 | medium | Create directory and split CLAUDE.md by domain. Path-specific rules dramatically reduce context overhead. |
| 24 | MCP server with no trust level set | CA-MCP-001 | medium | Set `"trust": "workspace"` or `"trusted"` explicitly. Default is untrusted/sandboxed; may cause unexpected failures. |
| 25 | User MCP servers in project `.mcp.json` | CA-MCP-002 | low | Move personal MCP servers to `~/.claude.json`. Project `.mcp.json` is for servers the whole team needs. |
| 26 | No custom skills when team has repeated workflows | CA-GAP-001 | medium | Create skills for `/deploy`, `/review-pr`, `/fix-issue`. Repeated multi-step workflows are the target. |
| 27 | Custom agents without `description` field | CA-GAP-002 | medium | Add a description explaining when to delegate to this agent. Without it, Claude never auto-invokes it. |
| 28 | No hooks configured at all | CA-GAP-003 | high | Add at minimum a `Stop` hook for session summaries. Zero hooks is the most common high-value gap. |
---
## Severity Scale
| Severity | Meaning |
|----------|---------|
| high | Silent failure or security risk — config item is ignored OR sensitive data exposed |
| medium | Significant productivity loss or maintenance risk |
| low | Missed optimization; config works but suboptimally |

View file

@ -0,0 +1,345 @@
# Claude Code Configuration Capabilities
> Source: Official Claude Code documentation (code.claude.com/docs), 75 pages, verified 2026-04-03.
## Official Configuration Guidance (Anthropic)
These principles are backed by official docs and verified community reports. Use them to ground recommendations.
### Core Architecture
- **CLAUDE.md is advisory, not enforced.** It's injected as user-message context — Claude reads it and tries to follow it, but there is no guarantee of strict compliance. Compliance depends on specificity and file length.
- **settings.json is the enforcement layer.** Permissions, sandbox rules, and tool grants are enforced by the client regardless of what Claude decides to do.
- **Hooks are deterministic.** Unlike CLAUDE.md instructions which are advisory, hooks guarantee the action happens every time with zero exceptions.
### Proven Impact
- **CLAUDE.md over 200 lines degrades adherence.** GitHub issue #22503 documents 300-line CLAUDE.md being "ignored 80+ times." Official docs now explicitly call this out: "important rules get lost in the noise."
- **Path-scoped rules reduce context noise.** Rules without `paths:` frontmatter load every session regardless of relevance. Scoped rules trigger only when Claude reads matching files.
- **Conflicting instructions cause arbitrary behavior.** When CLAUDE.md contains contradictions, Claude picks one arbitrarily. No priority mechanism resolves conflicts within a single CLAUDE.md.
- **System prompt takes precedence over CLAUDE.md.** Built-in system prompts (plan mode, agent launching) can override user-defined CLAUDE.md instructions.
### When Each Feature Is Relevant
| Feature | Relevant when... | Not needed when... |
|---------|-----------------|-------------------|
| permissions.deny | Sensitive files exist (.env, secrets/) | Fully trusted solo dev environment |
| hooks | Repeatable automation or safety checks needed | Occasional manual workflows |
| path-scoped rules | Multiple languages, contexts, or large codebase | Single-language, small project |
| MCP servers (.mcp.json in git) | Team shares tool access | Solo project, personal tools only |
| custom agents | Specialized parallel workflows | Linear single-task coding |
| custom skills | Repeated multi-step workflows | One-off tasks |
| CLAUDE.local.md | Personal preferences differ from team | Solo developer |
| model overrides | Different tasks need different cost/capability | Default model works for all tasks |
| output styles | Team has specific formatting needs | Default style is sufficient |
| managed settings | Organization-wide policy enforcement | No org, solo developer |
---
## 1. CLAUDE.md — Project Memory
**What it is:** Markdown file injected into every session as user-message context.
| Scope | Location |
|-------|----------|
| Project (shared) | `./CLAUDE.md` or `./.claude/CLAUDE.md` |
| Project (personal) | `./CLAUDE.local.md` (gitignored) |
| User (all projects) | `~/.claude/CLAUDE.md` |
| Org-managed (macOS) | `/Library/Application Support/ClaudeCode/CLAUDE.md` |
| Org-managed (Linux) | `/etc/claude-code/CLAUDE.md` |
**Key features:** `@import` syntax inlines other files (max 5 hops); HTML comments `<!-- -->` stripped before injection (free maintainer notes); lazy loading of subdirectory files; `claudeMdExcludes` setting skips files by glob.
**Fully utilizing:** CLAUDE.md under 200 lines with clear headers; `@import` for large specs; `CLAUDE.local.md` for personal sandbox URLs; auto-memory enabled.
**Common gaps:** No `CLAUDE.local.md`; no `@imports` (one huge file); no user-level `~/.claude/CLAUDE.md`; file over 200 lines reducing adherence.
---
## 2. CLAUDE.local.md — Personal Project Config
**What it is:** Companion to CLAUDE.md; appended after it; gitignored by default.
**Config location:** `./CLAUDE.local.md` (project root)
**Key fields/options:** Free-form markdown, same syntax as CLAUDE.md. Ideal for personal API keys, sandbox URLs, local dev notes.
**Fully utilizing:** Personal overrides that shouldn't be committed; local tool paths; developer-specific preferences.
**Common gaps:** File never created; personal preferences mixed into shared CLAUDE.md.
---
## 3. ~/.claude/CLAUDE.md — User-Level Memory
**What it is:** Loaded for every project; lower precedence than project CLAUDE.md.
**Config location:** `~/.claude/CLAUDE.md`
**Key fields/options:** Same markdown as project CLAUDE.md; `@import` supported.
**Fully utilizing:** Personal coding style, preferred tools, communication preferences applied everywhere.
**Common gaps:** File never created; duplicating same instructions in every project CLAUDE.md.
---
## 4. User Rules — ~/.claude/rules/
**What it is:** Personal rules files that load based on path patterns.
**Config location:** `~/.claude/rules/*.md`
**Key fields/options:** YAML frontmatter `paths:` field with glob patterns — file loads only when Claude works on matching paths. Symlinks supported. Recursive discovery.
```yaml
---
paths: ["src/**/*.ts"]
---
# TypeScript-specific rules here
```
**Fully utilizing:** Separate rule files per language, per domain, per tool; prevents irrelevant rules loading.
**Common gaps:** No `~/.claude/rules/` at all; everything in one CLAUDE.md that always loads.
---
## 5. Project Rules — .claude/rules/
**What it is:** Project-scoped rules with path-specific activation.
**Config location:** `./.claude/rules/*.md`
**Key fields/options:** Same `paths:` frontmatter as user rules. Committed to git for team sharing.
**Fully utilizing:** TypeScript rules only load for `.ts` files; migration rules only load for `db/**` paths; test rules only load for `**/*.test.*`.
**Common gaps:** No `.claude/rules/` directory; path-specific rules not used; all rules always load.
---
## 6. Org-Managed CLAUDE.md
**What it is:** Org-controlled instructions that cannot be overridden by users.
**Config locations:** `/Library/Application Support/ClaudeCode/CLAUDE.md` (macOS), `/etc/claude-code/CLAUDE.md` (Linux), `C:\Program Files\ClaudeCode\CLAUDE.md` (Windows)
**Fully utilizing:** Org-wide security policies, required compliance notes, standard workflow rules.
**Common gaps:** Not used in org deployments; individual teams manage their own configs without coordination.
---
## 7. Project settings.json
**What it is:** Project-level settings committed to git; shared with team.
**Config location:** `./.claude/settings.json`
**Key fields:** `permissions.allow/deny/ask`, `env`, `hooks`, `model`, `effortLevel`, `attribution`, `enabledPlugins`, `enableAllProjectMcpServers`
**Fully utilizing:** Team-agreed allow/deny rules; project env vars; attribution config; plugin list for team.
**Common gaps:** File doesn't exist; no permissions configured; no env block; missing `$schema` line.
---
## 8. User settings.json
**What it is:** Personal settings applied to all projects.
**Config location:** `~/.claude/settings.json`
**Key fields:** `model`, `effortLevel`, `outputStyle`, `language`, `statusLine`, `autoMemoryEnabled`, `autoMemoryDirectory`, `hooks`, `defaultShell`, `voiceEnabled`, `editorMode` (in `~/.claude.json`)
**Fully utilizing:** Personal model preference; default effort level; status line config; user-level hooks.
**Common gaps:** File never touched; relying on project settings only; no personal preferences set.
---
## 9. Local settings.json
**What it is:** Per-project personal overrides; gitignored.
**Config location:** `./.claude/settings.local.json`
**Key fields:** Same as project settings.json; `autoMode` classifier (user/local settings only, not project).
**Fully utilizing:** Local dev API endpoints; personal permission overrides; local-only env vars.
**Common gaps:** Never created; personal overrides committed to shared settings.json.
---
## 10. Managed Settings
**What it is:** Org-controlled settings at highest precedence; cannot be overridden.
**Config locations:** `managed-settings.json` in system dirs; `managed-settings.d/*.json` (alphabetical merge)
**Key fields (managed-only):** `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`, `allowManagedHooksOnly`, `allowManagedPermissionRulesOnly`, `allowedChannelPlugins`, `blockedMarketplaces`, `strictKnownMarketplaces`, `pluginTrustMessage`
**Fully utilizing:** Lock MCP servers to org-approved list; enforce hook policies; org announcements via `companyAnnouncements`.
---
## 11. .mcp.json — Project MCP Config
**What it is:** Project-level MCP server configuration; committed to git.
**Config location:** `./.mcp.json`
**Key fields:**
```json
{
"mcpServers": {
"name": {
"type": "stdio|http",
"command": "...", "args": [...],
"url": "...",
"env": {}, "timeout": 30000, "trust": "workspace|trusted|untrusted"
}
}
}
```
**Fully utilizing:** Team-shared MCP servers (GitHub, Jira, DBs); MCP resources via `@server:path`; MCP prompts as slash commands; `enableAllProjectMcpServers: true` for zero-friction team onboarding.
**Common gaps:** No `.mcp.json`; MCP only configured in `~/.claude.json` (not shared); trust levels not set; MCP resources not used.
---
## 12. ~/.claude.json — Global Config
**What it is:** Global non-settings preferences (separate file from settings.json).
**Config location:** `~/.claude.json`
**Key fields:** `mcpServers` (user-scope MCP), `autoConnectIde`, `autoInstallIdeExtension`, `editorMode` ("normal"/"vim"), `showTurnDuration`, `terminalProgressBarEnabled`, `teammateMode` ("auto"/"in-process"/"tmux")
**Fully utilizing:** User-level MCP servers; vim mode enabled; IDE auto-connect.
**Common gaps:** MCP servers configured per-project instead of here when they should be global; editorMode never set.
---
## 13. managed-mcp.json — Org MCP Config
**What it is:** Org-managed MCP servers deployed to all users.
**Config locations:** System directories (same as managed-settings.json).
**Key fields:** Same `mcpServers` format as `.mcp.json`.
**Fully utilizing:** Org-wide MCP servers (internal APIs, knowledge bases) available everywhere.
**Common gaps:** Not deployed in org setups; teams configure MCP independently.
---
## 14. keybindings.json
**What it is:** Custom keyboard shortcuts for Claude Code UI.
**Config location:** `~/.claude/keybindings.json` (open with `/keybindings`)
**Key fields:**
```json
{
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
"bindings": [{"context": "Chat", "bindings": {"shift+enter": "chat:newline"}}]
}
```
**Key actions:** `chat:submit`, `chat:newline`, `chat:externalEditor`, `chat:cycleMode`, `chat:thinkingToggle`, `chat:fastMode`, `voice:pushToTalk`
**Contexts:** Global, Chat, Autocomplete, Settings, Confirmation, Tabs, Help, Transcript, HistorySearch, Task, ThemePicker, Attachments, Footer, MessageSelector, DiffDialog, ModelPicker, Select, Plugin
**Fully utilizing:** `chat:newline` bound to Shift+Enter; external editor for complex prompts; chord bindings for workflows.
**Common gaps:** File never created; `chat:newline` not bound (most common friction); vim mode not enabled for vim users.
---
## 15. Skills
**What it is:** Custom slash commands with full tool access.
**Config locations:** `~/.claude/skills/<name>/SKILL.md` (user); `.claude/skills/<name>/SKILL.md` (project); `.claude/commands/<name>.md` (legacy)
**Key frontmatter:** `name`, `description`, `argument-hint`, `allowed-tools`, `model`, `effort`, `context` (fork), `agent`, `hooks`, `paths`, `disable-model-invocation`, `user-invocable`, `shell`
**String substitutions:** `$ARGUMENTS`, `$ARGUMENTS[N]`, `$N`, `${CLAUDE_SESSION_ID}`, `${CLAUDE_SKILL_DIR}`
**Dynamic context:** `` !`command` `` executes shell command and inlines output.
**Bundled skills:** `/batch`, `/claude-api`, `/debug`, `/loop`, `/simplify`
**Fully utilizing:** Custom deploy/review workflows; `disable-model-invocation: true` on side-effect skills; `context: fork` for isolated research; `!`git diff HEAD`` for dynamic context; `argument-hint` for UX.
**Common gaps:** No custom skills; skills missing `description` (never auto-invoked); no `!`command`` dynamic context; bundled skills not used.
---
## 16. Agents (Subagents)
**What it is:** Named AI workers with scoped tools, models, and permissions.
**Config locations:** `.claude/agents/<name>.md` (project); `~/.claude/agents/<name>.md` (user); plugin `agents/`; managed `agents/`
**Key frontmatter:** `name`, `description`, `model`, `tools`, `disallowedTools`, `permissionMode`, `mcpServers`, `hooks`, `maxTurns`, `skills`, `initialPrompt`, `memory` ("user"/"none"), `effort`, `background`, `isolation` ("worktree"), `color`
**Built-in agents:** `Explore` (read-only, Haiku), `Plan` (read-only), `general-purpose` (all tools), `Claude Code Guide` (Haiku)
**Fully utilizing:** Domain agents (security-reviewer, test-writer); restricted tool sets; Haiku for scanning, Opus for analysis; `isolation: worktree` for parallel work; `memory: "user"` for persistent learning; `maxTurns` guard.
**Common gaps:** No custom agents; no tool restrictions; no model optimization; no persistent memory; no worktree isolation; missing `description` (never auto-delegated).
---
## 17. Plugins
**What it is:** Namespaced bundles of skills + agents + hooks + MCP + tools.
**Config location:** `.claude-plugin/plugin.json` (manifest); enabled via `enabledPlugins` in settings.json
**Key plugin.json fields:** `name`, `description`, `version`, `author`, `homepage`, `repository`, `license`
**Structure:** `skills/`, `agents/`, `hooks/hooks.json`, `.mcp.json`, `.lsp.json`, `bin/`, `settings.json`
**Enabling:**
```json
{"enabledPlugins": {"plugin-name@marketplace": true}}
```
**Fully utilizing:** Team plugins in shared marketplace; org tool bundles (MCP + skills + agents); LSP plugins for all languages; `bin/` for custom CLI tools.
**Common gaps:** No plugins; `.claude/` configs that should be plugins (not shareable); no LSP plugins; no team marketplace configured.
---
## 18. Output Styles
**What it is:** Named system prompt variants that change Claude's default behavior.
**Config locations:** `~/.claude/output-styles/*.md` (user); `.claude/output-styles/*.md` (project); `outputStyle` key in settings.json
**Built-in styles:** `Default` (SE assistant), `Explanatory` (educational Insights blocks), `Learning` (collaborative, TODO(human) markers)
**Custom format:**
```markdown
---
name: My Style
description: What this does
keep-coding-instructions: false
---
Instructions here...
```
**Key distinction:** Output styles replace the system prompt; CLAUDE.md adds a user message. Use output styles when you need stronger enforcement.
**Fully utilizing:** Custom style for documentation/analysis work; `Explanatory` for onboarding; project styles for specialized domains.
**Common gaps:** Never changed from Default; not knowing styles modify the system prompt (vs CLAUDE.md); no custom styles for specialized workflows.

View file

@ -0,0 +1,93 @@
# Configuration Best Practices
> Concrete, actionable patterns. No generic advice.
---
## CLAUDE.md
1. **Keep under 200 lines.** Claude's adherence drops on longer files. If the file exceeds 200 lines, extract sections with `@import`.
2. **Use `@import` for specs/docs.** `@path/to/spec.md` inlines the file at session start. Max 5 hops. Keeps the main file scannable.
3. **Use HTML comments for maintainer notes.** `<!-- Updated 2026-01-01: reason -->` is stripped before context injection — zero token cost.
4. **Put personal dev notes in `CLAUDE.local.md`**, not `CLAUDE.md`. Add `CLAUDE.local.md` to `.gitignore`. Team members' sandbox URLs should never appear in git.
5. **Write `~/.claude/CLAUDE.md` for preferences that apply everywhere.** Communication style, preferred tools, output format — not project-specific config.
6. **Use clear markdown headers** (`##` sections). Claude uses the structure to navigate; unstructured text is harder to follow selectively.
7. **Avoid contradicting project settings.json.** CLAUDE.md is a user message; settings.json permissions take precedence. Don't document permissions in CLAUDE.md — put them in settings.json where they're enforced.
---
## settings.json
1. **Add `$schema` to every settings.json.** `"$schema": "https://json.schemastore.org/claude-code-settings.json"` enables autocomplete in VS Code and Cursor. Takes 2 seconds, saves every future edit.
2. **Use all three scopes: user, project, local.** User (`~/.claude/settings.json`) for personal defaults. Project (`.claude/settings.json`) for team agreements. Local (`.claude/settings.local.json`) for personal project overrides.
3. **Put env vars in `settings.json` `env` block, not shell.** `{"env": {"NODE_ENV": "development"}}` ensures they're always set in Claude sessions, regardless of how the shell was launched.
4. **Set `defaultMode: "acceptEdits"` for active development projects.** Eliminates per-file permission prompts. Use `"plan"` for infrastructure repos where you want read-only analysis by default.
5. **Deny `.env` and `secrets/` explicitly.** `{"permissions": {"deny": ["Read(./.env)", "Read(./secrets/**)"]}}` — Claude cannot read these even if it reasons it should.
6. **Pre-allow repetitive safe commands.** `{"permissions": {"allow": ["Bash(npm run *)", "Bash(git status)", "Bash(git log *)"]}}` — eliminates constant prompts for read-only git operations.
7. **Configure `attribution` for org identity.** `{"attribution": {"commit": "Generated with Claude Code [bot]", "pr": ""}}` — keeps commit history clean and attributable.
8. **Set `effortLevel` per project, not per prompt.** `{"effortLevel": "high"}` for complex codebases, `"low"` for simple scripts. Avoids forgetting to set it each session.
---
## Hooks
1. **Add a `Stop` hook before anything else.** `Stop` hook on session end is the most useful starting point — session summary, auto-commit prompt, notification. Many users have zero hooks; one Stop hook delivers immediate value.
2. **Use `PostToolUse` on Write/Edit for auto-formatting.** `{"PostToolUse": [{"matcher": "Write|Edit", "hooks": [{"type": "command", "command": "prettier --write ${CLAUDE_TOOL_OUTPUT_PATH}"}]}]}` — eliminates manual format steps.
3. **Use `PreToolUse` on Bash for security.** Validate shell commands before execution. Exit code 2 blocks the tool call with an error message shown to Claude.
4. **Use `SessionStart` for context injection.** Inject git branch name, active Linear issue, or CI status into context at session start. Cheaper than asking Claude to fetch it.
5. **Add `Notification` hook for desktop alerts.** When Claude needs input (permission prompt, idle), get a system notification. Without this, long sessions require constant manual checking.
6. **Match MCP tools precisely.** `"mcp__.*__write.*"` matches all write tools from all MCP servers. `"mcp__filesystem__.*"` matches all filesystem tools. Use patterns, not exact names.
7. **Keep hook scripts fast (< 2s for PreToolUse).** Blocking hooks run synchronously. Slow PreToolUse hooks add latency to every tool call. Use async for logging/reporting.
8. **Use `${CLAUDE_PLUGIN_ROOT}` for paths in plugin hooks.** Absolute paths break when plugins move. `${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check.sh` is portable.
---
## Rules (.claude/rules/)
1. **Use `paths:` frontmatter on every rules file.** Rules without `paths:` load for every file. A TypeScript rules file with `paths: ["**/*.ts", "**/*.tsx"]` only loads for TypeScript work — zero overhead otherwise.
2. **One rules file per domain or language.** `typescript.md`, `python.md`, `testing.md`, `migrations.md` — not one big `coding-rules.md`. Granular files = granular loading.
3. **Put project rules in `.claude/rules/`, user rules in `~/.claude/rules/`.** Project rules are team-specific and committed; user rules are personal preferences across all projects.
4. **Symlink shared rule sets.** If multiple projects share rules, symlink: `ln -s ../../shared/rules/security.md .claude/rules/security.md`. Claude follows symlinks.
5. **Test path globs before committing.** `paths: ["src/**"]` doesn't match `./src/file.ts` — leading `./` matters. Test with the actual file paths Claude will encounter.
---
## MCP
1. **Commit `.mcp.json` to git.** Team-shared MCP servers belong in `.mcp.json` at project root, not in individual `~/.claude.json` files. One commit, everyone gets the servers.
2. **Set `enableAllProjectMcpServers: true` in project settings.json** for zero-friction team onboarding. New team members don't have to manually approve each server.
3. **Set trust levels explicitly.** `"trust": "workspace"` for project-specific servers; `"trust": "trusted"` only for servers you fully control. Default is untrusted (sandboxed).
4. **Use `@server:resource/path` for dynamic data.** `@github:repos/owner/repo/issues` pulls live data into context. More reliable than asking Claude to fetch and parse.
5. **Deny MCP tools you don't want Claude to invoke.** `{"permissions": {"deny": ["mcp__filesystem__write_file"]}}` — even with a server connected, specific tools can be blocked.
---
## Skills
1. **Add `description` to every skill.** Without `description`, Claude never auto-invokes the skill. The description is the trigger — be specific about when to use it.
2. **Set `disable-model-invocation: true` on deploy/delete skills.** Side-effect commands should only run when the user explicitly types `/deploy`, not when Claude decides it's appropriate.
3. **Use `!`git diff HEAD`` for dynamic context.** Dynamic shell execution inlines current state at invocation time. Better than hardcoded file references that go stale.
4. **Use `context: fork` with a custom agent for isolated research.** Forks run in a separate context (and optionally a separate model), keeping research overhead out of the main session.
5. **Add `argument-hint` to all parameterized skills.** `argument-hint: "[issue-number]"` shows in the `/` menu autocomplete. Without it, users forget the expected argument format.
6. **Store large reference docs in skill subdirectory, not SKILL.md.** SKILL.md describes *when to load* each reference file. The references themselves stay separate so they're only loaded when needed.
---
## Agents
1. **Restrict tools to the minimum needed.** A read-only research agent should have `tools: ["Read", "Glob", "Grep"]`, not all tools. Scoped agents are safer and faster.
2. **Match model to task complexity.** Haiku for file discovery and scanning; Sonnet for implementation; Opus for architecture and analysis. Don't use Opus for tasks that are primarily file reading.
3. **Set `maxTurns` on autonomous agents.** Without a turn limit, a misconfigured agent can run indefinitely. `maxTurns: 20` is a reasonable default for most tasks.
4. **Write `description` as a trigger condition, not a title.** "Use when analyzing TypeScript files for type errors" beats "TypeScript analyzer". Claude uses the description to decide delegation.
5. **Use `isolation: worktree` for agents that make file changes.** Agents running in their own worktree can't interfere with the main session. Changes are reviewable before merge.
6. **Enable `memory: "user"` for domain-expert agents.** A security-reviewer agent that accumulates codebase knowledge across sessions gets better over time. Add `memory: "user"` to the frontmatter.
---
## Permissions
1. **Start with `defaultMode: "acceptEdits"`** for most projects. Then add specific `deny` rules for sensitive paths. More productive than prompting for every file write.
2. **Block secrets files by pattern, not by name.** `"deny": ["Read(./.env*)", "Read(./**/secrets/**)", "Read(./**/*.pem)"]` — catch all variants, not just `.env`.
3. **Use `additionalDirectories` for cross-repo work.** If Claude regularly reads `../shared-lib/`, add it: `{"additionalDirectories": ["../shared-lib/"]}`. Otherwise Claude can't access it without prompts.
4. **Configure `autoMode.environment` before using auto mode.** Without it, Claude's background safety classifier triggers false positives on your org's internal tool names and domains.
5. **Add `Agent()` deny rules for sensitive agents.** `{"deny": ["Agent(general-purpose)"]}` prevents the most powerful agent from running without explicit permission.

View file

@ -0,0 +1,60 @@
# Claude Code Feature Evolution
> Timeline of major features, most recent first. Covers features with configuration impact.
> Source: Official Claude Code documentation, verified 2026-04-03.
---
## 2026
| Approx. Date | Feature | Config Impact |
|-------------|---------|---------------|
| Q1 2026 | **Agent Teams (experimental)** | Enable via `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` or env in settings.json. Configure display mode via `~/.claude.json` `teammateMode`. Hooks: `TeammateIdle`, `TaskCreated`, `TaskCompleted`. |
| Q1 2026 | **Elicitation events** | `Elicitation` and `ElicitationResult` hook events added. MCP servers can request user input; hooks control and log these requests. |
| Q1 2026 | **`SubagentStart` / `SubagentStop` hooks** | Added hook events for subagent lifecycle. `SubagentStop` is blocking — exit code 2 acts as a quality gate. |
| Q1 2026 | **`ConfigChange` hook event** | Fires when any config file changes on disk. Matcher: `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills`. |
| Q1 2026 | **`InstructionsLoaded` hook event** | Fires when CLAUDE.md/.claude/rules files load. Useful for debugging instruction loading order and content. |
| Q1 2026 | **`StopFailure` / `PostToolUseFailure` hooks** | Error-path hooks added for better error observability and retry logic. |
| Q1 2026 | **`WorktreeCreate` / `WorktreeRemove` hooks** | `WorktreeCreate` is blocking; hook can return custom worktree path to replace Claude's default git worktree logic. Enables non-git VCS support. |
| Q1 2026 | **`PermissionDenied` hook** | Info-only event when auto mode denies a tool. Useful for logging and auditing denied operations. |
| Q1 2026 | **`SessionEnd` hook** | Fires on session termination. Matcher: `clear`, `resume`, `logout`, `prompt_input_exit`, `other`. |
| Q1 2026 | **HTTP hook type** | `type: "http"` hook handler posts to HTTP endpoints. `allowedHttpHookUrls` and `httpHookAllowedEnvVars` settings for security controls. |
| Q1 2026 | **Agent-type hooks** | `type: "agent"` hook handler — full subagent with tools for complex validation. |
---
## 2025
| Approx. Date | Feature | Config Impact |
|-------------|---------|---------------|
| Late 2025 | **Plugins system** | Namespaced skill/agent/hook/MCP bundles. `enabledPlugins` in settings.json. Plugin marketplace support. `--plugin-dir` for development. `/reload-plugins` command. `bin/` for CLI tools. |
| Late 2025 | **LSP plugins** | `.lsp.json` at plugin root provides real-time code intelligence. Official LSP plugins for TypeScript, Python, Rust, etc. |
| Late 2025 | **Output styles** | `outputStyle` setting; `~/.claude/output-styles/*.md` and `.claude/output-styles/*.md`. System prompt modification (stronger than CLAUDE.md). Built-in: Default, Explanatory, Learning. |
| Late 2025 | **Status line** | `statusLine` key in settings.json. Script receives stdin JSON with cost, context window %, model, worktree, session info. `/statusline` command for natural language config. |
| Late 2025 | **Skills system (v2)** | Major expansion of frontmatter fields: `context: fork`, `disable-model-invocation`, `user-invocable`, `paths`, `hooks`, `shell`. `!`command`` dynamic context. `$ARGUMENTS[N]` indexing. |
| Late 2025 | **Subagent isolation: worktree** | `isolation: worktree` in agent frontmatter. Each invocation gets own git worktree. Auto-cleaned on completion. |
| Late 2025 | **Subagent persistent memory** | `memory: "user"` in agent frontmatter. Accumulates knowledge to `~/.claude/agent-memory/`. |
| Late 2025 | **Subagent preloaded skills** | `skills:` array in agent frontmatter. Full skill content injected at agent startup (vs. description-only in regular sessions). |
| Mid 2025 | **Worktrees** | `claude --worktree <name>` CLI flag. `.worktreeinclude` for gitignored file propagation. `worktree.symlinkDirectories` and `worktree.sparsePaths` settings. |
| Mid 2025 | **MCP integration** | `.mcp.json` project-level config. `~/.claude.json` `mcpServers`. Three server types: stdio, http, sse. Resources via `@server:path`. Prompts as slash commands. |
| Mid 2025 | **Auto-memory** | `~/.claude/projects/<project>/memory/MEMORY.md`. `autoMemoryEnabled` setting. `autoMemoryDirectory` for custom path. Topic files loaded on demand. |
| Mid 2025 | **Managed settings** | `managed-settings.json`, `managed-settings.d/*.json`. Org-wide config at highest precedence. Managed-only keys for enterprise lockdown. |
| Mid 2025 | **`PreCompact`/`PostCompact` hooks** | Hooks for context compaction lifecycle. Matcher: `manual`, `auto`. |
| Early 2025 | **Hooks system (v1)** | Initial hooks in settings.json. Events: `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PermissionRequest`, `PostToolUse`, `Stop`, `Notification`, `CwdChanged`, `FileChanged`, `PreCompact`, `PostCompact`. `command` and `prompt` handler types. |
| Early 2025 | **`.claude/rules/` directory** | Path-specific rules with `paths:` frontmatter. Lazy loading — only loads when Claude works on matching files. |
| Early 2025 | **Keybindings** | `~/.claude/keybindings.json`. JSON Schema available. Chord support. Vim mode. 20+ contexts and 40+ bindable actions. |
| Early 2025 | **`CLAUDE.local.md`** | Project-local personal companion file. Gitignored. Appended after CLAUDE.md. |
| Early 2025 | **Extended thinking** | `alwaysThinkingEnabled` setting. `effortLevel` (low/medium/high/max). `MAX_THINKING_TOKENS` env var. |
| Early 2025 | **Auto mode** | `autoMode` object in settings.json (user/local only). `environment`, `allow`, `soft_deny` arrays. `disableAutoMode` setting. |
---
## 2024
| Approx. Date | Feature | Config Impact |
|-------------|---------|---------------|
| Late 2024 | **Subagents (v1)** | `.claude/agents/<name>.md`. `~/.claude/agents/`. Frontmatter: `model`, `tools`, `disallowedTools`, `permissionMode`, `color`, `maxTurns`. |
| Late 2024 | **Skills system (v1)** | `~/.claude/skills/<name>/SKILL.md`. `.claude/skills/<name>/SKILL.md`. Legacy `.claude/commands/<name>.md` also supported. Basic frontmatter. |
| Mid 2024 | **`@import` in CLAUDE.md** | `@path/to/file` syntax for modular CLAUDE.md. Max 5 hops. HTML comment stripping. |
| Mid 2024 | **settings.json** | `.claude/settings.json` (project), `~/.claude/settings.json` (user), `.claude/settings.local.json` (local). Permissions, env, hooks. |
| Early 2024 | **CLAUDE.md** | Initial project-level instructions. User-level `~/.claude/CLAUDE.md`. Lazy loading of subdirectory files. Directory walk. |

View file

@ -0,0 +1,207 @@
# Gap Closure Templates
Config-specific templates for closing feature gaps. Each template targets specific gap IDs, with effort estimate and expected utilization gain.
## CLAUDE.md Optimization
### Modular CLAUDE.md with @imports
**Closes:** t2_2 (CLAUDE.md not modular)
**Effort:** Low (15 min)
**Gain:** +5% utilization
Split large CLAUDE.md into focused modules:
1. Create `.claude/rules/` directory
2. Move topic-specific sections to individual `.md` files
3. Use `@.claude/rules/topic.md` imports in CLAUDE.md
### Path-Scoped Rules
**Closes:** t2_3 (No path-scoped rules)
**Effort:** Low (10 min)
**Gain:** +5% utilization
Add context-specific rules that only apply to matching files:
```yaml
---
paths: src/**/*.ts
---
# TypeScript Rules
Use strict TypeScript. No `any` types.
```
## Hook Automation
### Multi-Event Hook Setup
**Closes:** t1_3 (No hooks), t2_5 (Low hook diversity)
**Effort:** Medium (30 min)
**Gain:** +12% utilization
Configure hooks across 3+ events:
1. `PreToolUse` — security checks on Bash/Write
2. `Stop` — session summaries, state reminders
3. `SessionStart` — load context, check state
### Hooks in settings.json
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "echo ok", "timeout": 5000}]
}
],
"Stop": [
{
"hooks": [{"type": "prompt", "prompt": "Summarize session progress."}]
}
]
}
}
```
## MCP Integration
### Basic MCP Setup
**Closes:** t1_5 (No MCP), t4_1 (No project .mcp.json in git)
**Effort:** Low (15 min)
**Gain:** +10% utilization
Create `.mcp.json` at project root:
```json
{
"mcpServers": {
"memory": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"],
"trust": "workspace"
}
}
}
```
Commit to git for team sharing.
## Skill & Command Development
### Custom Skills
**Closes:** t1_4 (No custom skills/commands)
**Effort:** Medium (30 min)
**Gain:** +7% utilization
Create project-specific skills in `.claude/commands/`:
```markdown
---
name: project:build
description: Build and test the project
allowed-tools: Bash, Read
model: sonnet
---
Run: `npm run build && npm test`
Report results.
```
### Advanced Skill Frontmatter
**Closes:** t3_5 (No advanced skill frontmatter), t3_7 (No dynamic skill context)
**Effort:** Low (15 min)
**Gain:** +5% utilization
Add dynamic context and fork mode:
```yaml
---
name: project:deploy
context: fork
argument-hint: "[environment]"
---
Current branch: !`git branch --show-current`
```
## Agent Architecture
### Custom Subagents
**Closes:** t2_6 (No custom subagents)
**Effort:** Medium (45 min)
**Gain:** +5% utilization
Create specialized agents in `.claude/agents/`:
```yaml
---
name: reviewer
description: |
Code review agent for pull requests.
model: sonnet
color: blue
tools: ["Read", "Glob", "Grep"]
---
```
### Subagent Isolation
**Closes:** t3_6 (No subagent isolation)
**Effort:** Low (5 min)
**Gain:** +2% utilization
Add `isolation: worktree` to agents that modify files:
```yaml
---
isolation: worktree
---
```
## Plugin Architecture
### Custom Plugin
**Closes:** t4_2 (No custom plugin)
**Effort:** High (2-4 hours)
**Gain:** +2% utilization
Package reusable skills, agents, and hooks:
```
.claude-plugin/
├── plugin.json
├── commands/
├── agents/
└── hooks/
└── hooks.json
```
## Settings Optimization
### Multi-Scope Settings
**Closes:** t2_1 (Settings only at one scope)
**Effort:** Low (10 min)
**Gain:** +5% utilization
Use all 3 settings scopes:
- `~/.claude/settings.json` — global defaults
- `.claude/settings.json` — project (committed)
- `.claude/settings.local.json` — personal overrides (gitignored)
### Model Configuration
**Closes:** t2_7 (No model configuration)
**Effort:** Low (5 min)
**Gain:** +5% utilization
Set model preferences in settings:
```json
{
"model": "sonnet",
"modelOverrides": {
"planMode": "opus"
}
}
```
## Impact Summary
| Template | Gaps Closed | Effort | Gain |
|----------|-------------|--------|------|
| Modular CLAUDE.md | t2_2 | Low | +5% |
| Path-Scoped Rules | t2_3 | Low | +5% |
| Multi-Event Hooks | t1_3, t2_5 | Medium | +12% |
| MCP Setup | t1_5, t4_1 | Low | +10% |
| Custom Skills | t1_4 | Medium | +7% |
| Advanced Frontmatter | t3_5, t3_7 | Low | +5% |
| Custom Subagents | t2_6 | Medium | +5% |
| Subagent Isolation | t3_6 | Low | +2% |
| Custom Plugin | t4_2 | High | +2% |
| Multi-Scope Settings | t2_1 | Low | +5% |
| Model Configuration | t2_7 | Low | +5% |

View file

@ -0,0 +1,117 @@
# Hook Events Reference
> All 26 hook events as of April 2026. Source: code.claude.com/docs/en/hooks.md
---
## Event Table
| Event | Trigger | Blocking? | Matcher Support | Common Use Cases |
|-------|---------|-----------|-----------------|------------------|
| `SessionStart` | Session begins or resumes | No | `startup`, `resume`, `clear`, `compact` | Inject git branch/env into context; show session state; load external context |
| `InstructionsLoaded` | CLAUDE.md / .claude/rules files are loaded | No | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` | Debug which instruction files loaded; log instruction sources; validate rule sets |
| `UserPromptSubmit` | User submits a prompt | Yes | No matcher | Validate prompt length; inject context; block disallowed prompt patterns; add mandatory context |
| `PreToolUse` | Before any tool executes | Yes | Tool name (e.g., `Bash`, `Write`, `mcp__.*`) | Security validation; confirm destructive ops; log tool calls; rate limiting |
| `PermissionRequest` | Permission dialog appears | Yes | Tool name | Auto-approve known-safe patterns; add approval context; integrate with approval workflows |
| `PermissionDenied` | Auto mode denies a tool call | No (info only) | Tool name | Log denied operations; alert on unexpected denials; track permission patterns |
| `PostToolUse` | Tool completes successfully | No | Tool name | Auto-format after Write/Edit; run linting; update docs; log completions |
| `PostToolUseFailure` | Tool ends in error | No | Tool name | Log failures; send alerts; trigger retry logic; update error tracking |
| `SubagentStart` | Subagent is spawned | No | Agent type (name) | Log agent invocations; inject agent-specific context; record spawn times |
| `SubagentStop` | Subagent finishes | Yes | Agent type (name) | Quality gates (exit 2 to reject); validate agent output; run post-agent checks |
| `TaskCreated` | A task is created in the task list | Yes | No matcher | Validate task format; enforce naming conventions; block disallowed task types |
| `TaskCompleted` | A task is marked complete | Yes | No matcher | Verify completion criteria; run acceptance checks; require sign-off |
| `Stop` | Claude finishes a response turn | Yes | No matcher | Session summaries; commit prompts; send desktop notifications; log turn metadata |
| `StopFailure` | Turn ends in an API error | No | Error type | Alert on API errors; retry logic; log error context |
| `TeammateIdle` | An agent team member has no tasks | Yes | No matcher | Assign next task (exit 2 to keep working); log team status; rebalance work |
| `Notification` | A notification is sent (permission prompt, idle, auth) | No | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog` | Desktop notifications; Slack/webhook alerts; mobile push; audio cues |
| `ConfigChange` | A config file changes on disk | Yes | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` | Validate config changes; block invalid edits; reload dependent processes |
| `CwdChanged` | Working directory changes | No | No matcher | Inject new directory context; update env vars via `$CLAUDE_ENV_FILE`; log navigation |
| `FileChanged` | A watched file changes | No | Filename pattern | Auto-reload when config changes; trigger builds on source change; sync state |
| `WorktreeCreate` | A git worktree is being created | Yes (path return) | No matcher | Custom worktree path via stdout; non-git VCS support; worktree naming conventions |
| `WorktreeRemove` | A git worktree is removed | No | No matcher | Cleanup resources; log worktree lifecycle; update team state |
| `PreCompact` | Before context compaction | No | `manual`, `auto` | Save current state; checkpoint important context; log pre-compact state |
| `PostCompact` | After context compaction | No | `manual`, `auto` | Reinject critical context; validate compaction; log post-compact state |
| `Elicitation` | An MCP server requests user input | Yes | MCP server name | Control which servers can request input; log elicitations; pre-fill responses |
| `ElicitationResult` | User responds to MCP elicitation | Yes | MCP server name | Validate responses; log user input; transform before sending to MCP |
| `SessionEnd` | Session terminates | No | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` | Final session summary; save state; cleanup temp files; send end-of-session report |
---
## Hook Handler Types
| Type | Description | Use When |
|------|-------------|----------|
| `command` | Shell command (bash/powershell) | Fast scripts, file checks, security validation |
| `http` | HTTP POST to endpoint | Remote logging, webhooks, approval systems |
| `prompt` | LLM evaluation (yes/no decision) | Semantic validation that needs language understanding |
| `agent` | Full subagent with tools | Complex validation requiring file reads or multi-step logic |
---
## Handler Configuration Fields
| Field | Type | Description |
|-------|------|-------------|
| `type` | string | `command`, `http`, `prompt`, `agent` |
| `command` | string | Shell command (type: command only) |
| `url` | string | HTTP endpoint (type: http only) |
| `prompt` | string | LLM prompt (type: prompt only) |
| `if` | string | Conditional expression — only fires when true (e.g., `Bash(rm *)`) |
| `timeout` | number | Milliseconds before hook is killed (default: varies) |
| `statusMessage` | string | Message shown in UI while hook runs |
| `async` | bool | `true` = fire and forget, don't wait for result |
| `shell` | string | `"bash"` or `"powershell"` |
---
## Exit Code Semantics
| Exit Code | Blocking Event | Non-Blocking Event |
|-----------|---------------|---------------------|
| `0` | Proceed; JSON on stdout is parsed | Success; JSON on stdout parsed |
| `2` | **Block** — stderr shown to Claude as error | Non-blocking; treated as informational |
| other | Non-blocking; stderr in verbose log only | Non-blocking; stderr in verbose log only |
---
## Blocking Event Output Fields
**PreToolUse** (exit 0):
- `permissionDecision`: `"allow"` / `"deny"` / `"ask"` / `"defer"`
- `updatedInput`: modified tool input
- `additionalContext`: string appended to Claude's context
**PermissionRequest** (exit 0):
- `decision.behavior`: `"allow"` / `"deny"`
- `updatedInput`: modified input
- `updatedPermissions`: modified permission set
**WorktreeCreate** (exit 0):
- stdout: path string OR `hookSpecificOutput.worktreePath`
**SessionStart** (exit 0):
- `additionalContext`: string injected into context
- Or: write env vars to `$CLAUDE_ENV_FILE`
---
## Environment Variables Available in Hooks
| Variable | Available In | Description |
|----------|-------------|-------------|
| `$CLAUDE_PROJECT_DIR` | All hooks | Absolute path to project root |
| `${CLAUDE_PLUGIN_ROOT}` | Plugin hooks | Plugin installation directory |
| `${CLAUDE_PLUGIN_DATA}` | Plugin hooks | Plugin persistent data directory |
| `$CLAUDE_ENV_FILE` | SessionStart, CwdChanged, FileChanged | Path to write env var exports |
| `$CLAUDE_CODE_REMOTE` | All hooks | `"true"` when running in web sessions |
---
## MCP Tool Matcher Patterns
| Pattern | Matches |
|---------|---------|
| `mcp__memory__.*` | All tools from the `memory` server |
| `mcp__.*__write.*` | Any tool named `write*` from any server |
| `mcp__filesystem__read_file` | Specific tool on specific server |
| `mcp__.*` | All MCP tools from all servers |