docs: factual audit + reference sync — 260 findings corrected
Parallel 6-agent audit against official Anthropic docs (llms-full.txt). Key corrections applied across permissions, hooks, MCP, security, privacy, reference.yaml. Highlights: - Fix MCP config path (~/.claude.json), mcpServers key, variable substitution syntax - Fix permission modes (5 not 3), :* syntax (×6), Stop event description - Fix hook JSON field names (hook_event_name, tool_name, tool_input, session_id) - Fix filesystem restriction docs (permission rules, not settings.json keys) - Fix data-privacy: 4-tier retention, /bug 5yr warning, ZDR conditions, 5 telemetry opt-out vars - Add official llms.txt/llms-full.txt references to CLAUDE.md + machine-readable/llms.txt - Reference.yaml: 375 entries re-synced (92% had wrong line numbers — guide grew 15K→21K lines) - New script: scripts/resync-reference-yaml.py for automated line number sync - Quiz: corrected answers for hooks (07), memory settings (03), MCP servers (08) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ad735dfff4
commit
8e63d84b47
26 changed files with 1125 additions and 566 deletions
|
|
@ -467,6 +467,7 @@ External resources (articles, videos, discussions) are evaluated before integrat
|
|||
### Process
|
||||
|
||||
1. **Research**: Initial Perplexity search → Save prompt + results in `claudedocs/resource-evaluations/` (private)
|
||||
1b. **Cross-reference**: Si ressource liée à Claude Code, vérifier les claims contre `https://code.claude.com/docs/llms-full.txt` (source officielle ~98KB)
|
||||
2. **Evaluation**: Systematic scoring (1-5) → Create evaluation file in `docs/resource-evaluations/` (tracked)
|
||||
3. **Challenge**: Technical review by agent to ensure objectivity
|
||||
4. **Decision**: Integrate (score 3+), mention (score 2), or reject (score 1)
|
||||
|
|
@ -493,8 +494,9 @@ See full methodology: [`docs/resource-evaluations/README.md`](docs/resource-eval
|
|||
## Quick Lookups
|
||||
|
||||
For answering questions about Claude Code:
|
||||
0. **Doc officielle Anthropic (LLM-optimized)**: `https://code.claude.com/docs/llms.txt` (index ~65 pages) ou `https://code.claude.com/docs/llms-full.txt` (doc complète ~98KB) pour les faits officiels
|
||||
1. Search `machine-readable/reference.yaml` first (has line numbers to full guide)
|
||||
2. Use those line numbers to read relevant sections from `guide/ultimate-guide.md`
|
||||
3. Check `examples/` for ready-to-use templates
|
||||
4. Check `guide/claude-code-releases.md` for recent features/changes
|
||||
5. Si info manquante ou incertaine → demander une recherche Perplexity
|
||||
5. Si info manquante ou incertaine → demander une recherche Perplexity (communauté, comparaisons, retours)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ Trigger reached → re-evaluation → Integrate (Graduated) / Drop (Dropped)
|
|||
|
||||
| Resource | Type | Added | Why Watching | Re-eval Trigger |
|
||||
|----------|------|-------|--------------|-----------------|
|
||||
| [save-webpage-to-obsidian](https://github.com/benoitvx/claude-skill-save-webpage-to-obsidian) | Skill | 2026-02-25 | Skill Claude Code qui archive des articles web dans un vault Obsidian (dual extraction: Chrome MCP + WebFetch). Pattern dual-strategy intéressant mais config hardcodée, sécurité non adressée, pas de métriques adoption. Score 2/5. | >200 stars GitHub |
|
||||
| [fp.dev](https://fp.dev/) | Tool | 2026-02-22 | Agent-native issue tracking pour Claude Code. Un vrai différentiateur (issues .md git-committables) mais adoption insuffisante, Apple Silicon only, redondant avec Tasks API. Score 2/5. | GitHub stars visibles + release cadence + write-up praticien en prod |
|
||||
| [ICM](https://github.com/rtk-ai/icm) | MCP | 2026-02-12 | Pre-v1 (1 star, 11 commits) | First release + >20 stars |
|
||||
| [System Prompts](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools) | Tool | 2026-01-26 | Redundant with official sources. Re-evaluated 2026-02-13 (Opus 4.6 update): still 2/5. | Anthropic confirms CLI prompts not published |
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ cat .claude/settings.json 2>/dev/null || echo "No project settings"
|
|||
ls -la CLAUDE.md .claude/CLAUDE.md ~/.claude/CLAUDE.md 2>/dev/null
|
||||
|
||||
# MCP config
|
||||
cat ~/.claude/mcp.json 2>/dev/null || echo "No MCP config"
|
||||
cat ~/.claude.json 2>/dev/null | jq '.mcpServers // empty' || echo "No MCP config"
|
||||
```
|
||||
|
||||
### Step 4: Present Categories
|
||||
|
|
@ -150,13 +150,13 @@ cat ~/.claude/settings.json | jq '.permissions.allow'
|
|||
|
||||
**Likely causes**:
|
||||
1. Server not installed globally
|
||||
2. Wrong path in mcp.json
|
||||
2. Wrong path in MCP config
|
||||
3. Missing environment variables
|
||||
|
||||
**Quick diagnostic**:
|
||||
```bash
|
||||
# Check MCP config
|
||||
cat ~/.claude/mcp.json | jq '.mcpServers'
|
||||
cat ~/.claude.json | jq '.mcpServers'
|
||||
|
||||
# Check if server binary exists
|
||||
which mcp-server-sequential
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ Read the user's MCP configuration:
|
|||
|
||||
```bash
|
||||
# Global MCP config
|
||||
cat ~/.claude/mcp.json 2>/dev/null
|
||||
cat ~/.claude.json 2>/dev/null | jq '.mcpServers // empty'
|
||||
|
||||
# Project MCP config
|
||||
cat .claude/mcp.json 2>/dev/null
|
||||
cat .mcp.json 2>/dev/null
|
||||
```
|
||||
|
||||
**Check against threat-db.yaml:**
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ Hooks are scripts that execute automatically on Claude Code events. They enable
|
|||
| `Notification` | When Claude sends a notification | Sound alerts, external notifications |
|
||||
| `SessionStart` | At session start | Initialization, environment setup |
|
||||
| `SessionEnd` | At session end | Cleanup, session summary |
|
||||
| `Stop` | User interrupts operation | State saving, graceful shutdown |
|
||||
| `Stop` | Claude finishes responding | Post-response actions, state saving |
|
||||
|
||||
## Advanced Guardrails (NEW in v3.3.0)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Hook: Stop - Capture one learning insight at session end
|
||||
# Event: Stop (when user ends session or interrupts)
|
||||
# Event: Stop (when Claude finishes responding)
|
||||
# Purpose: Build a learning journal with minimal friction
|
||||
#
|
||||
# Exit codes:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# Purpose: Verify MCP configuration has not been tampered with
|
||||
#
|
||||
# This hook addresses CVE-2025-54135 and CVE-2025-54136 by:
|
||||
# - Computing hash of ~/.claude/mcp.json
|
||||
# - Computing hash of ~/.claude.json (MCP config location)
|
||||
# - Comparing against stored baseline
|
||||
# - Alerting on unauthorized modifications
|
||||
# - Checking project-level .mcp.json for suspicious content
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
# }
|
||||
#
|
||||
# Initial setup (run once to create baseline):
|
||||
# sha256sum ~/.claude/mcp.json > ~/.claude/.mcp-baseline.sha256
|
||||
# sha256sum ~/.claude.json > ~/.claude/.mcp-baseline.sha256
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 = allow (config unchanged or no baseline)
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
set -euo pipefail
|
||||
|
||||
# Configuration paths
|
||||
MCP_CONFIG="${HOME}/.claude/mcp.json"
|
||||
MCP_CONFIG="${HOME}/.claude.json"
|
||||
MCP_BASELINE="${HOME}/.claude/.mcp-baseline.sha256"
|
||||
PROJECT_MCP=".mcp.json"
|
||||
|
||||
|
|
@ -51,11 +51,11 @@ if [[ -f "$MCP_CONFIG" ]]; then
|
|||
BASELINE_HASH=$(awk '{print $1}' "$MCP_BASELINE" 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$CURRENT_HASH" && -n "$BASELINE_HASH" && "$CURRENT_HASH" != "$BASELINE_HASH" ]]; then
|
||||
WARNINGS+=("MCP config modified since baseline was created. Review ~/.claude/mcp.json for unauthorized changes. Run 'sha256sum ~/.claude/mcp.json > ~/.claude/.mcp-baseline.sha256' to update baseline if changes are legitimate.")
|
||||
WARNINGS+=("MCP config modified since baseline was created. Review ~/.claude.json for unauthorized changes. Run 'sha256sum ~/.claude.json > ~/.claude/.mcp-baseline.sha256' to update baseline if changes are legitimate.")
|
||||
fi
|
||||
else
|
||||
# No baseline - suggest creating one
|
||||
WARNINGS+=("No MCP config baseline found. Consider running: sha256sum ~/.claude/mcp.json > ~/.claude/.mcp-baseline.sha256")
|
||||
WARNINGS+=("No MCP config baseline found. Consider running: sha256sum ~/.claude.json > ~/.claude/.mcp-baseline.sha256")
|
||||
fi
|
||||
|
||||
# === CHECK FOR SUSPICIOUS MCP SERVERS ===
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ Claude Code has a layered security model:
|
|||
│ ┌────────────────────────────────────────────────────────┐ │
|
||||
│ │ { │ │
|
||||
│ │ "permissions": { │ │
|
||||
│ │ "allow": ["Bash(npm:*)", "Read(**)"], │ │
|
||||
│ │ "allow": ["Bash(npm *)", "Read"], │ │
|
||||
│ │ "deny": ["Bash(rm -rf *)"] │ │
|
||||
│ │ } │ │
|
||||
│ │ } │ │
|
||||
|
|
@ -720,21 +720,21 @@ Hooks allow programmatic control over Claude's actions:
|
|||
|
||||
| Capability | Supported | How |
|
||||
|------------|-----------|-----|
|
||||
| Block execution | Yes | Exit code != 0 |
|
||||
| Block execution | Yes | Exit code 2 |
|
||||
| Modify parameters | Yes | Return modified JSON |
|
||||
| Log actions | Yes | Write to file in hook |
|
||||
| Async processing | No | Hooks are synchronous |
|
||||
| Async processing | Yes | Set `async: true` in hook config (v2.1.0+) |
|
||||
|
||||
**Hook JSON payload** (passed via stdin):
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "PreToolUse",
|
||||
"tool": "Bash",
|
||||
"params": {
|
||||
"hook_event_name": "PreToolUse",
|
||||
"tool_name": "Bash",
|
||||
"tool_input": {
|
||||
"command": "npm install lodash"
|
||||
},
|
||||
"sessionId": "abc123",
|
||||
"session_id": "abc123",
|
||||
"cwd": "/path/to/project"
|
||||
}
|
||||
```
|
||||
|
|
@ -1290,6 +1290,8 @@ This convergence suggests that the "less scaffolding, more model" approach scale
|
|||
| Hooks Guide | code.claude.com/docs/en/hooks-guide | Hook examples |
|
||||
| MCP Docs | code.claude.com/docs/en/mcp | MCP integration |
|
||||
| Sandboxing | code.claude.com/docs/en/sandboxing | Security model |
|
||||
| llms.txt (index) | code.claude.com/docs/llms.txt | LLM-optimized doc index, ~65 pages |
|
||||
| llms-full.txt | code.claude.com/docs/llms-full.txt | Full documentation (~98 KB text) |
|
||||
|
||||
### Tier 2 - Verified Analysis
|
||||
|
||||
|
|
|
|||
|
|
@ -94,8 +94,10 @@ tags: [cheatsheet, reference]
|
|||
| Mode | Editing | Execution |
|
||||
|------|---------|-----------|
|
||||
| Default | Asks | Asks |
|
||||
| Auto-accept | Auto | Asks |
|
||||
| acceptEdits | Auto | Asks |
|
||||
| Plan Mode | ❌ | ❌ |
|
||||
| dontAsk | Only if in allow rules | Only if in allow rules |
|
||||
| bypassPermissions | Auto | Auto (CI/CD only) |
|
||||
|
||||
**Shift+Tab** to switch modes
|
||||
|
||||
|
|
@ -222,7 +224,9 @@ Model: Sonnet | Ctx: 89.5k | Cost: $2.11 | Ctx(u): 56.0%
|
|||
|---------|--------|-------------|
|
||||
| **Alt+T** | Toggle thinking on/off | Session |
|
||||
| **/config** | Enable/disable globally | Permanent |
|
||||
| **`effort` param** | API only: `low\|medium\|high\|max` | Per-request |
|
||||
| **`/model` slider** | Left/right arrows: `low\|medium\|high` | Session |
|
||||
| **`CLAUDE_CODE_EFFORT_LEVEL`** | Env var: `low\|medium\|high` | Shell session |
|
||||
| **`effortLevel` setting** | In settings.json: `low\|medium\|high` | Permanent |
|
||||
|
||||
**Cost tip**: For simple tasks, Alt+T to disable thinking → faster & cheaper.
|
||||
|
||||
|
|
@ -389,11 +393,16 @@ VERIFY: Empty email shows error, invalid format shows error
|
|||
| `--model sonnet` | Change model |
|
||||
| `--add-dir ../lib` | Allow access outside CWD |
|
||||
| `--permission-mode plan` | Plan mode |
|
||||
| `--tools "Tool1,Tool2"` | Enable specific tools for session |
|
||||
| `--max-budget-usd 5.00` | Max API spend limit (print mode) |
|
||||
| `--system-prompt "..."` | Append custom system prompt |
|
||||
| `--worktree` / `-w` | Run in isolated git worktree |
|
||||
| `--dangerously-skip-permissions` | Auto-accept (use carefully) |
|
||||
| `--debug` | Debug output |
|
||||
| `--mcp-debug` | Debug MCP servers |
|
||||
| `--allowedTools "Edit,Read"` | Whitelist tools |
|
||||
|
||||
> Full CLI reference (~45 flags): see [cli-reference on code.claude.com](https://docs.anthropic.com/en/docs/claude-code/cli-reference)
|
||||
|
||||
---
|
||||
|
||||
## Debug Commands
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ tags: [privacy, security, guide]
|
|||
|
||||
| Configuration | Retention Period | Training | How to Enable |
|
||||
|---------------|------------------|----------|---------------|
|
||||
| **Default** | 5 years | Yes | (default state) |
|
||||
| **Opt-out** | 30 days | No | [claude.ai/settings](https://claude.ai/settings/data-privacy-controls) |
|
||||
| **Enterprise (ZDR)** | 0 days | No | Enterprise contract |
|
||||
| **Consumer (default)** | 5 years | Yes | (default state) |
|
||||
| **Consumer (opt-out)** | 30 days | No | [claude.ai/settings](https://claude.ai/settings/data-privacy-controls) |
|
||||
| **Team / Enterprise / API** | 30 days | No (default) | Use Team, Enterprise plan, or API keys |
|
||||
| **ZDR (Zero Data Retention)** | 0 days server-side | No | Appropriately configured API keys |
|
||||
|
||||
**Immediate action**: [Disable training data usage](https://claude.ai/settings/data-privacy-controls) to reduce retention from 5 years to 30 days.
|
||||
|
||||
|
|
@ -35,16 +36,20 @@ When you use Claude Code, the following data is sent to Anthropic:
|
|||
│ • MCP server results (SQL queries, API responses) │
|
||||
│ • Bash command outputs │
|
||||
│ • Error messages and stack traces │
|
||||
└───────────────────────┬─────────────────────────────────────┘
|
||||
│
|
||||
▼ HTTPS
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ANTHROPIC API │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ • Processes your request │
|
||||
│ • Stores conversation based on retention policy │
|
||||
│ • May use data for model training (if not opted out) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
└───────────┬──────────────────┬──────────────┬───────────────┘
|
||||
│ │ │
|
||||
▼ HTTPS/TLS ▼ HTTPS ▼ HTTPS
|
||||
┌───────────────────┐ ┌──────────────┐ ┌─────────────────────┐
|
||||
│ ANTHROPIC API │ │ STATSIG │ │ SENTRY │
|
||||
├───────────────────┤ ├──────────────┤ ├─────────────────────┤
|
||||
│ • Your prompts │ │ • Latency, │ │ • Error logs │
|
||||
│ • Model responses │ │ reliability│ │ • No code or │
|
||||
│ • Retention per │ │ • No code or │ │ file paths │
|
||||
│ your tier │ │ file paths │ │ │
|
||||
└───────────────────┘ └──────────────┘ └─────────────────────┘
|
||||
(opt-out: (opt-out:
|
||||
DISABLE_ DISABLE_ERROR_
|
||||
TELEMETRY=1) REPORTING=1)
|
||||
```
|
||||
|
||||
### What This Means in Practice
|
||||
|
|
@ -61,13 +66,13 @@ When you use Claude Code, the following data is sent to Anthropic:
|
|||
|
||||
## 2. Anthropic Retention Policies
|
||||
|
||||
### Tier 1: Default (Training Enabled)
|
||||
### Tier 1: Consumer Default (Training Enabled)
|
||||
|
||||
- **Retention**: 5 years
|
||||
- **Usage**: Model improvement, training data
|
||||
- **Applies to**: Free, Pro, Max plans without opt-out
|
||||
- **Applies to**: Free, Pro, Max plans with training setting ON
|
||||
|
||||
### Tier 2: Training Disabled (Opt-Out)
|
||||
### Tier 2: Consumer Opt-Out (Training Disabled)
|
||||
|
||||
- **Retention**: 30 days
|
||||
- **Usage**: Safety monitoring, abuse prevention only
|
||||
|
|
@ -76,12 +81,21 @@ When you use Claude Code, the following data is sent to Anthropic:
|
|||
2. Disable "Allow model training on your conversations"
|
||||
3. Changes apply immediately
|
||||
|
||||
### Tier 3: Enterprise API (Zero Data Retention)
|
||||
### Tier 3: Commercial (Team / Enterprise / API)
|
||||
|
||||
- **Retention**: 0 days (real-time processing only)
|
||||
- **Usage**: None - data not stored
|
||||
- **Requires**: Enterprise contract with Anthropic
|
||||
- **Use cases**: HIPAA, GDPR, PCI-DSS compliance, government contracts
|
||||
- **Retention**: 30 days
|
||||
- **Usage**: Safety monitoring, abuse prevention only
|
||||
- **Training**: Not used for training by default (no opt-out needed)
|
||||
- **Applies to**: Team plans, Enterprise plans, API users, third-party platforms, Claude Gov
|
||||
|
||||
### Tier 4: Zero Data Retention (ZDR)
|
||||
|
||||
- **Retention**: 0 days server-side (local client cache may persist up to 30 days)
|
||||
- **Usage**: None retained on Anthropic servers
|
||||
- **Requires**: Appropriately configured API keys (see [Anthropic documentation](https://www.anthropic.com/enterprise))
|
||||
- **Use cases**: HIPAA (requires separate BAA), GDPR, PCI-DSS compliance, government contracts
|
||||
|
||||
> **Important**: Data is encrypted in transit via TLS but is **not encrypted at rest** on Anthropic servers. Factor this into your security assessments.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -127,7 +141,21 @@ STRIPE_SECRET_KEY=sk_live_...
|
|||
|
||||
**Mitigation**: Use hooks to filter sensitive command outputs.
|
||||
|
||||
### Risk 4: Documented Community Incidents
|
||||
### Risk 4: The `/bug` Command Sends Everything (Retained 5 Years)
|
||||
|
||||
When you run `/bug` in Claude Code, your **full conversation history** (including all code, file contents, and potentially secrets) is sent to Anthropic for bug triage. This data is retained for **5 years**, regardless of your training opt-out setting.
|
||||
|
||||
This is independent of your privacy preferences: even with training disabled and 30-day retention, bug reports follow their own 5-year retention policy.
|
||||
|
||||
**Mitigation**: Disable the command entirely if you work with sensitive codebases:
|
||||
|
||||
```bash
|
||||
export DISABLE_BUG_COMMAND=1
|
||||
```
|
||||
|
||||
Or add it to your shell profile (`~/.zshrc`, `~/.bashrc`) to make it permanent.
|
||||
|
||||
### Risk 5: Documented Community Incidents
|
||||
|
||||
| Incident | Source |
|
||||
|----------|--------|
|
||||
|
|
@ -195,6 +223,29 @@ if [[ "$TOOL_NAME" == "Read" ]]; then
|
|||
fi
|
||||
```
|
||||
|
||||
#### 4.4 Opt-Out of Telemetry and Error Reporting
|
||||
|
||||
Claude Code connects to third-party services for operational metrics (Statsig) and error logging (Sentry). These do not include your code or file paths, but you can disable them entirely:
|
||||
|
||||
| Variable | What it Disables |
|
||||
|----------|-----------------|
|
||||
| `DISABLE_TELEMETRY=1` | Statsig operational metrics (latency, reliability, usage patterns) |
|
||||
| `DISABLE_ERROR_REPORTING=1` | Sentry error logging |
|
||||
| `DISABLE_BUG_COMMAND=1` | The `/bug` command (prevents sending full conversation history) |
|
||||
| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` | All non-essential network traffic at once |
|
||||
| `CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1` | Session quality surveys (note: surveys only send your numeric rating, never transcripts) |
|
||||
|
||||
Add these to your shell profile for permanent effect:
|
||||
|
||||
```bash
|
||||
# In ~/.zshrc or ~/.bashrc
|
||||
export DISABLE_TELEMETRY=1
|
||||
export DISABLE_ERROR_REPORTING=1
|
||||
export DISABLE_BUG_COMMAND=1
|
||||
```
|
||||
|
||||
> **Note**: When using Bedrock, Vertex, or Foundry providers, all non-essential traffic (telemetry, error reporting, bug command, surveys) is disabled by default.
|
||||
|
||||
### MCP Best Practices
|
||||
|
||||
| Rule | Rationale |
|
||||
|
|
@ -338,6 +389,7 @@ Anthropic published Claude's constitution in January 2026 (CC0 license - public
|
|||
|
||||
## Changelog
|
||||
|
||||
- 2026-02: Fixed retention model (3 tiers to 4 tiers), added /bug command warning, telemetry opt-out variables, encryption-at-rest disclosure, updated ZDR conditions
|
||||
- 2026-01: Added Claude's governance & constitutional AI framework section
|
||||
- 2026-01: Added intellectual property considerations section
|
||||
- 2026-01: Initial version - documenting retention policies and protective measures
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ claude "Create a brief incident note for our wiki:
|
|||
For persistent K8s context, install the K8s MCP server:
|
||||
|
||||
```json
|
||||
// ~/.claude/mcp.json
|
||||
// ~/.claude.json (or .mcp.json)
|
||||
{
|
||||
"mcpServers": {
|
||||
"kubernetes": {
|
||||
|
|
@ -831,7 +831,7 @@ approval_required:
|
|||
| Prometheus | Direct metrics queries | Community: search awesome-mcp-servers |
|
||||
| Terraform | State/plan analysis | Community: search awesome-mcp-servers |
|
||||
|
||||
**Config location**: `~/.claude/mcp.json`
|
||||
**Config location**: `~/.claude.json` (field `"mcpServers"`)
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
|
|||
|
|
@ -213,9 +213,9 @@ MCP server configurations can live in 4 different locations. The resolution orde
|
|||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["1️⃣ CLI: --mcp-config path/to/mcp.json<br/>Highest priority — overrides all"] --> B["2️⃣ Project: .claude/mcp.json<br/>Team-shared, checked into git"]
|
||||
B --> C["3️⃣ Project Root: .mcp.json<br/>Alternative project location"]
|
||||
C --> D["4️⃣ Global: ~/.claude/mcp.json<br/>Personal servers, all projects"]
|
||||
A["1️⃣ CLI: --mcp-config path/to/config.json<br/>Highest priority — overrides all"] --> B["2️⃣ Project Root: .mcp.json<br/>Team-shared, checked into git"]
|
||||
B --> C["3️⃣ Local scope: ~/.claude.json<br/>Private to you + current project"]
|
||||
C --> D["4️⃣ User scope: ~/.claude.json<br/>Personal servers, all projects"]
|
||||
D --> E["5️⃣ No MCP servers<br/>Default (no config found)"]
|
||||
|
||||
A1["Use for:<br/>CI/CD overrides<br/>temporary testing"] --> A
|
||||
|
|
@ -234,7 +234,7 @@ flowchart TD
|
|||
click A href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "CLI --mcp-config flag"
|
||||
click B href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "Project .claude/mcp.json"
|
||||
click C href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "Project Root .mcp.json"
|
||||
click D href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "Global ~/.claude/mcp.json"
|
||||
click D href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "User scope ~/.claude.json"
|
||||
click E href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#81-what-is-mcp" "No MCP servers"
|
||||
click A1 href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "CI/CD overrides"
|
||||
click B1 href "https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md#83-configuration" "Team-shared servers"
|
||||
|
|
@ -247,9 +247,9 @@ flowchart TD
|
|||
```
|
||||
PRIORITY (highest → lowest):
|
||||
1. --mcp-config flag → CLI override, temporary
|
||||
2. .claude/mcp.json → team-shared (git-tracked)
|
||||
3. .mcp.json → project root alternative
|
||||
4. ~/.claude/mcp.json → personal global servers
|
||||
2. .mcp.json → project-scope (git-tracked, shareable)
|
||||
3. ~/.claude.json → local scope (private, current project)
|
||||
4. ~/.claude.json → user scope (personal, all projects)
|
||||
5. (none) → no MCP servers available
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ While Anthropic investigates:
|
|||
```
|
||||
|
||||
4. **Reduce MCP tools** if not needed:
|
||||
- Review `~/.claude/mcp.json`
|
||||
- Review `~/.claude.json` (field `"mcpServers"`)
|
||||
- Disable unused servers
|
||||
|
||||
5. **Use subagents** for isolated tasks:
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ python -m mcp_server_git
|
|||
docker run -v /path/to/repo:/repo ghcr.io/modelcontextprotocol/mcp-server-git
|
||||
```
|
||||
|
||||
**Claude Desktop Configuration** (`~/.claude/mcp.json`):
|
||||
**Claude Code Configuration** (`~/.claude.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -308,7 +308,7 @@ npm install @microsoft/playwright-mcp
|
|||
npx @microsoft/playwright-mcp
|
||||
```
|
||||
|
||||
**Claude Desktop Configuration** (`~/.claude/mcp.json`):
|
||||
**Claude Code Configuration** (`~/.claude.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -1050,7 +1050,7 @@ proxy:
|
|||
**Generate Claude Desktop Config**:
|
||||
|
||||
```bash
|
||||
./mcp-compose create-config --type claude --output ~/.claude/mcp.json
|
||||
./mcp-compose create-config --type claude --output ~/.claude.json
|
||||
```
|
||||
|
||||
**Start Servers**:
|
||||
|
|
|
|||
|
|
@ -315,10 +315,6 @@ sudo dnf install bubblewrap socat # Fedora
|
|||
{
|
||||
"sandbox": {
|
||||
"autoAllowMode": true,
|
||||
"filesystem": {
|
||||
"allowedWritePaths": ["${CWD}"],
|
||||
"deniedReadPaths": ["${HOME}/.ssh", "${HOME}/.aws"]
|
||||
},
|
||||
"network": {
|
||||
"policy": "deny",
|
||||
"allowedDomains": [
|
||||
|
|
@ -327,6 +323,12 @@ sudo dnf install bubblewrap socat # Fedora
|
|||
"github.com"
|
||||
]
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(~/.ssh/**)", "Read(~/.aws/**)",
|
||||
"Edit(~/.ssh/**)", "Edit(~/.aws/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -190,28 +190,27 @@ This asymmetric policy balances usability and security:
|
|||
- **Read all**: Claude needs to search/analyze entire codebase, read system configs, inspect dependencies
|
||||
- **Write CWD**: Most development work happens within project directory; restricting writes prevents accidental/malicious system modifications
|
||||
|
||||
### Configurable Paths
|
||||
### Configuring Filesystem Restrictions
|
||||
|
||||
Customize via `settings.json`:
|
||||
Filesystem restrictions are configured through **permission rules** (Read/Edit deny rules), not sandbox settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"sandbox": {
|
||||
"filesystem": {
|
||||
"allowedWritePaths": [
|
||||
"/Users/you/projects/my-app",
|
||||
"/tmp"
|
||||
],
|
||||
"deniedReadPaths": [
|
||||
"/Users/you/.ssh",
|
||||
"/Users/you/.aws",
|
||||
"/Users/you/.kube"
|
||||
]
|
||||
}
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(~/.ssh/**)",
|
||||
"Read(~/.aws/**)",
|
||||
"Read(~/.kube/**)",
|
||||
"Edit(~/.ssh/**)",
|
||||
"Edit(~/.aws/**)",
|
||||
"Edit(~/.kube/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Write access is inherently restricted to CWD by the sandbox. To block reads to sensitive directories, use permission deny rules as shown above.
|
||||
|
||||
**⚠️ Security Warning**: Overly broad write permissions enable privilege escalation:
|
||||
|
||||
- ❌ **Never allow writes to**: `$PATH` directories (`/usr/local/bin`), shell configs (`~/.bashrc`, `~/.zshrc`), system dirs (`/etc`)
|
||||
|
|
@ -223,7 +222,7 @@ Customize via `settings.json`:
|
|||
|
||||
### Proxy Architecture
|
||||
|
||||
All network connections from sandboxed commands are routed through a SOCKS5 proxy running **outside** the sandbox:
|
||||
All network connections from sandboxed commands are routed through a SOCKS5 proxy running **outside** the sandbox. The proxy restricts which domains processes can connect to, but **does not inspect the content of traffic** passing through it (privacy note: no deep packet inspection).
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
|
|
@ -311,6 +310,8 @@ For advanced use cases (HTTPS inspection, enterprise proxies):
|
|||
|
||||
**⚠️ Important**: Auto-allow mode is **independent** of permission mode (default/auto-accept/plan). Even in "default" mode, sandboxed bash commands run without prompts.
|
||||
|
||||
**Built-in blocklist**: Even in auto-allow mode, commands like `curl` and `wget` are blocked by default to prevent arbitrary web content fetching.
|
||||
|
||||
**When to use**: Daily development, autonomous refactors, CI/CD pipelines
|
||||
|
||||
### Regular Permissions Mode
|
||||
|
|
@ -459,8 +460,8 @@ Excluded commands always run outside sandbox (with normal permission prompts).
|
|||
|
||||
**Mitigation**:
|
||||
|
||||
- ✅ **Restrict writes to project directories only**
|
||||
- ✅ **Audit `allowedWritePaths` carefully**
|
||||
- ✅ **Restrict writes to project directories only** (sandbox default)
|
||||
- ✅ **Use permission deny rules to block sensitive reads**
|
||||
- ✅ **Monitor sandbox violation logs**
|
||||
|
||||
### Linux: Nested Sandbox Weakness
|
||||
|
|
@ -567,22 +568,11 @@ flowchart TD
|
|||
### Strict Security (Denylist Mode)
|
||||
|
||||
```json
|
||||
// settings.json — sandbox settings
|
||||
{
|
||||
"sandbox": {
|
||||
"autoAllowMode": true,
|
||||
"allowUnsandboxedCommands": false,
|
||||
"filesystem": {
|
||||
"allowedWritePaths": [
|
||||
"/Users/you/projects/my-app",
|
||||
"/tmp"
|
||||
],
|
||||
"deniedReadPaths": [
|
||||
"/Users/you/.ssh",
|
||||
"/Users/you/.aws",
|
||||
"/Users/you/.kube",
|
||||
"/Users/you/.gnupg"
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"policy": "deny",
|
||||
"allowedDomains": [
|
||||
|
|
@ -594,6 +584,13 @@ flowchart TD
|
|||
]
|
||||
},
|
||||
"excludedCommands": []
|
||||
},
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(~/.ssh/**)", "Read(~/.aws/**)",
|
||||
"Read(~/.kube/**)", "Read(~/.gnupg/**)",
|
||||
"Edit(~/.ssh/**)", "Edit(~/.aws/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -605,15 +602,6 @@ flowchart TD
|
|||
"sandbox": {
|
||||
"autoAllowMode": true,
|
||||
"allowUnsandboxedCommands": true,
|
||||
"filesystem": {
|
||||
"allowedWritePaths": [
|
||||
"${CWD}"
|
||||
],
|
||||
"deniedReadPaths": [
|
||||
"${HOME}/.ssh",
|
||||
"${HOME}/.aws"
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"policy": "allow",
|
||||
"blockedDomains": [
|
||||
|
|
@ -621,6 +609,12 @@ flowchart TD
|
|||
]
|
||||
},
|
||||
"excludedCommands": ["docker", "kubectl"]
|
||||
},
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Read(~/.ssh/**)", "Read(~/.aws/**)",
|
||||
"Edit(~/.ssh/**)", "Edit(~/.aws/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -632,13 +626,6 @@ flowchart TD
|
|||
"sandbox": {
|
||||
"autoAllowMode": true,
|
||||
"allowUnsandboxedCommands": true,
|
||||
"filesystem": {
|
||||
"allowedWritePaths": [
|
||||
"${CWD}",
|
||||
"/tmp",
|
||||
"${HOME}/.cache"
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"policy": "allow"
|
||||
},
|
||||
|
|
@ -653,7 +640,7 @@ flowchart TD
|
|||
|
||||
1. **Start restrictive, expand as needed** - Begin with denylist mode, whitelist domains/paths incrementally
|
||||
2. **Monitor sandbox violations** - Review logs to understand Claude's access patterns
|
||||
3. **Audit `allowedWritePaths`** - Never allow writes to `$PATH` dirs, shell configs, or system directories
|
||||
3. **Audit permission deny rules** - Use Read/Edit deny rules to block access to sensitive directories (`~/.ssh`, `~/.aws`, `~/.kube`)
|
||||
4. **Avoid broad CDN domains** - Whitelist specific subdomains (`my-app.pages.dev`) instead of `*.cloudflare.com`
|
||||
5. **Disable escape hatch in production** - Set `allowUnsandboxedCommands: false` for CI/CD, untrusted environments
|
||||
6. **Combine with IAM policies** - Use sandboxing **alongside** [permission settings](https://code.claude.com/docs/en/iam) for defense-in-depth
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Model Context Protocol (MCP) servers extend Claude Code's capabilities but intro
|
|||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 1. Attacker publishes benign MCP "code-formatter" │
|
||||
│ ↓ │
|
||||
│ 2. User adds to ~/.claude/mcp.json, approves once │
|
||||
│ 2. User adds to ~/.claude.json, approves once │
|
||||
│ ↓ │
|
||||
│ 3. MCP works normally for 2 weeks (builds trust) │
|
||||
│ ↓ │
|
||||
|
|
@ -225,6 +225,18 @@ Because `permissions.deny` alone cannot guarantee complete protection:
|
|||
|
||||
> **Bottom line**: `permissions.deny` is necessary but not sufficient. Treat it as one layer in a defense-in-depth strategy, not a complete solution.
|
||||
|
||||
#### Built-in Permission Safeguards
|
||||
|
||||
Beyond explicit deny rules, Claude Code has several built-in protections:
|
||||
|
||||
| Safeguard | Behavior |
|
||||
|-----------|----------|
|
||||
| **Command blocklist** | `curl` and `wget` are blocked by default in the sandbox to prevent arbitrary web content fetching |
|
||||
| **Fail-closed matching** | Any permission rule that doesn't match defaults to requiring manual approval (deny by default) |
|
||||
| **Command injection detection** | Suspicious bash commands require manual approval even if previously allowlisted |
|
||||
|
||||
These protections work automatically without configuration. The fail-closed design means a misconfigured permission rule fails safe rather than granting unintended access.
|
||||
|
||||
### 1.4 Repository Pre-Scan
|
||||
|
||||
Before opening untrusted repositories, scan for injection vectors:
|
||||
|
|
@ -497,7 +509,7 @@ If you suspect an MCP server has been compromised:
|
|||
1. **Disable immediately**
|
||||
```bash
|
||||
# Remove from config
|
||||
jq 'del(.mcpServers.<suspect>)' ~/.claude/mcp.json > tmp && mv tmp ~/.claude/mcp.json
|
||||
jq 'del(.mcpServers.<suspect>)' ~/.claude.json > tmp && mv tmp ~/.claude.json
|
||||
|
||||
# Or edit manually and restart Claude
|
||||
```
|
||||
|
|
@ -505,8 +517,8 @@ If you suspect an MCP server has been compromised:
|
|||
2. **Verify config integrity**
|
||||
```bash
|
||||
# Check for unauthorized changes
|
||||
sha256sum ~/.claude/mcp.json
|
||||
diff ~/.claude/mcp.json ~/.claude/mcp.json.backup
|
||||
sha256sum ~/.claude.json
|
||||
diff ~/.claude.json ~/.claude.json.backup
|
||||
|
||||
# Check project-level config too
|
||||
cat .mcp.json 2>/dev/null
|
||||
|
|
@ -519,7 +531,7 @@ If you suspect an MCP server has been compromised:
|
|||
|
||||
4. **Restore from known-good backup**
|
||||
```bash
|
||||
cp ~/.claude/mcp.json.backup ~/.claude/mcp.json
|
||||
cp ~/.claude.json.backup ~/.claude.json
|
||||
```
|
||||
|
||||
### 3.3 Automated Security Audit
|
||||
|
|
@ -696,7 +708,7 @@ exit 0
|
|||
gitleaks detect --source . --verbose
|
||||
|
||||
# Check MCP config
|
||||
cat ~/.claude/mcp.json | jq '.mcpServers | keys'
|
||||
cat ~/.claude.json | jq '.mcpServers | keys'
|
||||
|
||||
# Verify hook installation
|
||||
ls -la ~/.claude/hooks/
|
||||
|
|
@ -847,7 +859,7 @@ Local terminal ──HTTPS outbound──► Anthropic relay ──► Mobile/Br
|
|||
**Security properties:**
|
||||
- Zero inbound ports (reduces attack surface vs SSH tunnels or ngrok)
|
||||
- HTTPS only (encrypted in transit)
|
||||
- Session URL = short-lived authentication token
|
||||
- Multiple short-lived, narrowly scoped credentials (each limited to a specific purpose, expiring independently)
|
||||
- Execution stays 100% local
|
||||
|
||||
### Threat Model
|
||||
|
|
|
|||
|
|
@ -817,7 +817,7 @@ Claude: [Resumes with Serena's persistent project understanding]
|
|||
|
||||
## 1.4 Permission Modes
|
||||
|
||||
Claude Code has three permission modes that control how much autonomy Claude has:
|
||||
Claude Code has five permission modes that control how much autonomy Claude has:
|
||||
|
||||
### Default Mode
|
||||
|
||||
|
|
@ -828,13 +828,13 @@ Claude asks permission before:
|
|||
|
||||
This is the safest mode for learning.
|
||||
|
||||
### Auto-accept Mode
|
||||
### Auto-accept Mode (`acceptEdits`)
|
||||
|
||||
```
|
||||
You: Turn on auto-accept for the rest of this session
|
||||
```
|
||||
|
||||
Claude will execute changes without asking. Use when you trust the operation and want speed.
|
||||
Claude auto-approves file edits but still asks for shell commands. Use when you trust the edits and want speed.
|
||||
|
||||
⚠️ **Warning**: Only use auto-accept for well-defined, reversible operations.
|
||||
|
||||
|
|
@ -844,13 +844,25 @@ Claude will execute changes without asking. Use when you trust the operation and
|
|||
/plan
|
||||
```
|
||||
|
||||
Claude can only read and analyze - no modifications allowed. Perfect for:
|
||||
Claude can only read and analyze, no modifications allowed. Perfect for:
|
||||
- Understanding unfamiliar code
|
||||
- Exploring architectural options
|
||||
- Safe investigation before changes
|
||||
|
||||
Exit with `/execute` when ready to make changes.
|
||||
|
||||
### Don't Ask Mode (`dontAsk`)
|
||||
|
||||
Auto-denies tools unless pre-approved via `/permissions` or `permissions.allow` rules. Claude never interrupts with permission prompts: if a tool isn't explicitly allowed, it's silently denied.
|
||||
|
||||
Use for restrictive workflows where you want tight control over which tools run, without interactive confirmation.
|
||||
|
||||
### Bypass Permissions Mode (`bypassPermissions`)
|
||||
|
||||
Auto-approves everything, including shell commands. No permission prompts at all.
|
||||
|
||||
⚠️ **Warning**: Only use in sandboxed CI/CD environments. Requires `--dangerously-skip-permissions` to enable from CLI. Never use on production systems or with untrusted code.
|
||||
|
||||
## 1.5 Productivity Checklist
|
||||
|
||||
You're ready for Day 2 when you can:
|
||||
|
|
@ -1461,7 +1473,7 @@ Add to `~/.claude/settings.json`:
|
|||
}
|
||||
```
|
||||
|
||||
This displays: `Model: Sonnet 4.5 | Ctx: 0 | ⎇ main | (+0,-0) | Cost: $0.27 | Session: 0m | Ctx(u): 0.0%`
|
||||
This displays: `Model: Sonnet 4.6 | Ctx: 0 | ⎇ main | (+0,-0) | Cost: $0.27 | Session: 0m | Ctx(u): 0.0%`
|
||||
|
||||
**Option 2: Custom script**
|
||||
|
||||
|
|
@ -1775,7 +1787,7 @@ Claude Code isn't free - you're using API credits. Understanding costs helps opt
|
|||
|
||||
#### Pricing Model (as of February 2026)
|
||||
|
||||
Claude Code uses **Claude Sonnet 4.6** by default (as of Feb 2026):
|
||||
The default model depends on your subscription: **Max/Team Premium** subscribers get **Opus 4.6** by default, while **Pro/Team Standard** subscribers get **Sonnet 4.6**. If Opus usage hits the plan threshold, it auto-falls back to Sonnet.
|
||||
|
||||
| Model | Input (per 1M tokens) | Output (per 1M tokens) | Context Window | Notes |
|
||||
|-------|----------------------|------------------------|----------------|-------|
|
||||
|
|
@ -2426,6 +2438,21 @@ Claude: [Executes the plan]
|
|||
|
||||
**Result**: 76% fewer tokens with better results because the plan is validated before execution.
|
||||
|
||||
### Model Aliases
|
||||
|
||||
Claude Code supports six model aliases via `/model` (each always resolves to the latest version):
|
||||
|
||||
| Alias | Resolves To | Use Case |
|
||||
|-------|-------------|----------|
|
||||
| `default` | Latest model for your plan tier | Standard usage |
|
||||
| `sonnet` | Claude Sonnet 4.6 | Fast, cost-efficient |
|
||||
| `opus` | Claude Opus 4.6 | Deep reasoning |
|
||||
| `haiku` | Claude Haiku 4.5 | Budget, high-volume |
|
||||
| `sonnet[1m]` | Sonnet with 1M context | Large codebases |
|
||||
| `opusplan` | Opus (plan) + Sonnet (act) | Hybrid intelligence |
|
||||
|
||||
Model can also be set via `claude --model <alias>`, `ANTHROPIC_MODEL` env var, or `"model"` in settings.json. Priority: `/model` > `--model` flag > `ANTHROPIC_MODEL` > settings.json.
|
||||
|
||||
### OpusPlan Mode
|
||||
|
||||
**Concept**: Use Opus for planning (superior reasoning) and Sonnet for implementation (cost-efficient).
|
||||
|
|
@ -4700,7 +4727,7 @@ ln -s ~/.claude/skills ./skills
|
|||
|
||||
# 3. Copy settings template (without secrets)
|
||||
cp ~/.claude/settings.json ./settings.template.json
|
||||
# Manually replace secrets with ${env:VAR_NAME} placeholders
|
||||
# Manually replace secrets with ${VAR_NAME} placeholders
|
||||
|
||||
# 4. .gitignore for secrets
|
||||
cat > .gitignore << EOF
|
||||
|
|
@ -4817,7 +4844,7 @@ ln -s ~/Dropbox/claude-mcp/settings.json ~/.claude/settings.json
|
|||
- Session history (may contain sensitive code)
|
||||
|
||||
**Always commit these**:
|
||||
- Template files with `${env:VAR_NAME}` placeholders
|
||||
- Template files with `${VAR_NAME}` placeholders
|
||||
- `.gitignore` to prevent secret leaks
|
||||
- Public agents/hooks/skills (if safe to share)
|
||||
|
||||
|
|
@ -4843,7 +4870,7 @@ ln -sf ~/.claude/commands ./commands
|
|||
|
||||
# Restore settings (fill in secrets manually or via .env)
|
||||
cp settings.template.json ~/.claude/settings.json
|
||||
# Edit and replace ${env:VAR_NAME} with actual values
|
||||
# Edit and replace ${VAR_NAME} with actual values
|
||||
```
|
||||
|
||||
**From tarball backup**:
|
||||
|
|
@ -4960,24 +4987,24 @@ Personal permission overrides (gitignored):
|
|||
|
||||
### allowedTools Configuration (Alternative)
|
||||
|
||||
For granular control, use `~/.claude.json`:
|
||||
For granular control, use `~/.claude/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"allowedTools": [
|
||||
"Read(*)",
|
||||
"Grep(*)",
|
||||
"Glob(*)",
|
||||
"WebFetch(*)",
|
||||
"Read",
|
||||
"Grep",
|
||||
"Glob",
|
||||
"WebFetch",
|
||||
"TodoRead",
|
||||
"TodoWrite",
|
||||
"Task(*)",
|
||||
"Bash(git status:*)",
|
||||
"Bash(git diff:*)",
|
||||
"Bash(git log:*)",
|
||||
"Bash(pnpm typecheck:*)",
|
||||
"Bash(pnpm lint:*)",
|
||||
"Bash(pnpm test:*)"
|
||||
"Task",
|
||||
"Bash(git status *)",
|
||||
"Bash(git diff *)",
|
||||
"Bash(git log *)",
|
||||
"Bash(pnpm typecheck *)",
|
||||
"Bash(pnpm lint *)",
|
||||
"Bash(pnpm test *)"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
|
@ -4985,17 +5012,17 @@ For granular control, use `~/.claude.json`:
|
|||
**Pattern Logic**:
|
||||
| Pattern | Meaning | Example |
|
||||
|---------|---------|---------|
|
||||
| `Read(*)` | All reads | Any file |
|
||||
| `Bash(git status:*)` | Specific command | `git status` allowed |
|
||||
| `Bash(pnpm *:*)` | Command prefix | `pnpm test`, `pnpm build` |
|
||||
| `Edit(*)` | All edits | ⚠️ Dangerous |
|
||||
| `Read` | All reads | Any file |
|
||||
| `Bash(git status *)` | Specific command | `git status` allowed |
|
||||
| `Bash(pnpm *)` | Command prefix | `pnpm test`, `pnpm build` |
|
||||
| `Edit` | All edits | ⚠️ Dangerous |
|
||||
|
||||
**Progressive Permission Levels**:
|
||||
|
||||
**Level 1 - Beginner (very restrictive)**:
|
||||
```json
|
||||
{
|
||||
"allowedTools": ["Read(*)", "Grep(*)", "Glob(*)"]
|
||||
"allowedTools": ["Read", "Grep", "Glob"]
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -5003,8 +5030,8 @@ For granular control, use `~/.claude.json`:
|
|||
```json
|
||||
{
|
||||
"allowedTools": [
|
||||
"Read(*)", "Grep(*)", "Glob(*)",
|
||||
"Bash(git:*)", "Bash(pnpm:*)",
|
||||
"Read", "Grep", "Glob",
|
||||
"Bash(git *)", "Bash(pnpm *)",
|
||||
"TodoRead", "TodoWrite"
|
||||
]
|
||||
}
|
||||
|
|
@ -5014,9 +5041,9 @@ For granular control, use `~/.claude.json`:
|
|||
```json
|
||||
{
|
||||
"allowedTools": [
|
||||
"Read(*)", "Grep(*)", "Glob(*)", "WebFetch(*)",
|
||||
"Edit(*)", "Write(*)",
|
||||
"Bash(git:*)", "Bash(pnpm:*)", "Bash(npm:*)",
|
||||
"Read", "Grep", "Glob", "WebFetch",
|
||||
"Edit", "Write",
|
||||
"Bash(git *)", "Bash(pnpm *)", "Bash(npm *)",
|
||||
"Task(*)", "TodoRead", "TodoWrite"
|
||||
]
|
||||
}
|
||||
|
|
@ -7915,15 +7942,17 @@ Hooks are scripts that run automatically when specific events occur.
|
|||
| `Notification` | Claude sends notification | Sound alerts |
|
||||
| `SessionStart` | Session begins | Initialization |
|
||||
| `SessionEnd` | Session ends | Cleanup |
|
||||
| `Stop` | User interrupts | Graceful shutdown |
|
||||
| `Setup` | Claude Code starts | Initialization (v2.1.10+) |
|
||||
| `Stop` | Claude finishes responding | Post-response actions |
|
||||
| `PermissionRequest` | Permission dialog appears | Custom approval logic |
|
||||
| `SubagentStart` | Sub-agent starts | Subagent initialization (v2.1.32+) |
|
||||
| `SubagentStop` | Sub-agent completes | Subagent cleanup |
|
||||
| `TeammateIdle` | Agent team member goes idle | Team coordination (v2.1.32+) |
|
||||
| `TaskCompleted` | Task marked as completed | Workflow triggers (v2.1.32+) |
|
||||
| `WorktreeCreate` | Agent worktree created | Set up DB branch, install deps (v2.1.50+) |
|
||||
| `WorktreeRemove` | Agent worktree torn down | Clean up DB branch, temp credentials (v2.1.50+) |
|
||||
| `ConfigChange` | Config file changes during session | Enterprise audit, block unauthorized changes (v2.1.49+) |
|
||||
| `PreCompact` | Before context compaction | Save state before compaction (v2.1.50+) |
|
||||
| `PostToolUseFailure` | After a tool fails | Error logging, recovery actions |
|
||||
|
||||
> **`Stop` and `SubagentStop` — `last_assistant_message` field (v2.1.47+)**: These events now include a `last_assistant_message` field in their JSON input, giving direct access to Claude's final response without parsing transcript files. Useful for orchestration pipelines that need to inspect or log the last output.
|
||||
>
|
||||
|
|
@ -8102,9 +8131,16 @@ gh pr create --title "..." --body "..."
|
|||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `matcher` | Regex pattern for which tools trigger hook |
|
||||
| `type` | Always `"command"` |
|
||||
| `command` | Path to hook script |
|
||||
| `timeout` | Max execution time (ms) |
|
||||
| `type` | Hook type: `"command"`, `"prompt"`, or `"agent"` |
|
||||
| `command` | Shell command to run (for `command` type) |
|
||||
| `prompt` | Prompt text for LLM evaluation (for `prompt`/`agent` types) |
|
||||
| `timeout` | Max execution time in seconds (default: 600s command, 30s prompt, 60s agent) |
|
||||
|
||||
**Hook types:**
|
||||
|
||||
- **`command`**: Runs a shell command. Receives JSON on stdin, returns JSON on stdout. Most common type.
|
||||
- **`prompt`**: Sends prompt + hook input to a Claude model (Haiku by default) for single-turn evaluation. Returns `{ok: true/false, reason: "..."}`. Configure model via `model` field.
|
||||
- **`agent`**: Spawns a subagent with tool access (Read, Grep, Glob, etc.) for multi-turn verification. Returns same `{ok: true/false}` format. Up to 50 tool-use turns.
|
||||
|
||||
### Hook Input (stdin JSON)
|
||||
|
||||
|
|
@ -10464,7 +10500,7 @@ Beyond the official servers listed above, the MCP ecosystem includes **validated
|
|||
# Installation
|
||||
npm install @microsoft/playwright-mcp
|
||||
|
||||
# Configuration (~/.claude/mcp.json)
|
||||
# Configuration (~/.claude.json or .mcp.json)
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
|
|
@ -10485,23 +10521,25 @@ npm install @microsoft/playwright-mcp
|
|||
|
||||
## 8.3 Configuration
|
||||
|
||||
### mcp.json Location
|
||||
### MCP Configuration Location
|
||||
|
||||
```
|
||||
~/.claude/mcp.json # Global MCP configuration
|
||||
/project/.claude/mcp.json # Project-specific (overrides)
|
||||
~/.claude.json # User-scope MCP config (field "mcpServers")
|
||||
.mcp.json # Project-scope (project root, shareable via VCS)
|
||||
```
|
||||
|
||||
> **Note**: Three scopes exist: `local` (default, private to you + current project, in `~/.claude.json`), `project` (shared via `.mcp.json` at project root), and `user` (cross-project, also in `~/.claude.json`). Use `claude mcp add --scope <scope>` to target a specific scope.
|
||||
|
||||
### Example Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"serena": {
|
||||
"command": "npx",
|
||||
"args": ["serena-mcp"],
|
||||
"env": {
|
||||
"PROJECT_PATH": "${workspaceFolder}"
|
||||
"PROJECT_PATH": "${PROJECT_PATH}"
|
||||
}
|
||||
},
|
||||
"context7": {
|
||||
|
|
@ -10512,7 +10550,7 @@ npm install @microsoft/playwright-mcp
|
|||
"command": "npx",
|
||||
"args": ["@modelcontextprotocol/server-postgres"],
|
||||
"env": {
|
||||
"DATABASE_URL": "${env:DATABASE_URL}"
|
||||
"DATABASE_URL": "${DATABASE_URL}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10532,8 +10570,10 @@ npm install @microsoft/playwright-mcp
|
|||
|
||||
| Variable | Expands To |
|
||||
|----------|------------|
|
||||
| `${workspaceFolder}` | Current project path |
|
||||
| `${env:VAR_NAME}` | Environment variable |
|
||||
| `${VAR}` | Environment variable value |
|
||||
| `${VAR:-default}` | Environment variable with fallback |
|
||||
|
||||
> **Warning**: The syntax `${workspaceFolder}` and `${env:VAR_NAME}` are VS Code conventions, not Claude Code. Claude Code uses standard shell-style `${VAR}` and `${VAR:-default}` for environment variable expansion in MCP config.
|
||||
|
||||
### Managing Large MCP Server Sets
|
||||
|
||||
|
|
@ -10542,10 +10582,10 @@ When you accumulate many MCP servers, enabling them all globally degrades Claude
|
|||
**Pattern**: keep a minimal global config (2-3 core servers) and activate project-specific servers via per-project `.mcp.json`.
|
||||
|
||||
```
|
||||
# Global (~/.claude/mcp.json) → always loaded
|
||||
# User-scope (~/.claude.json "mcpServers") → always loaded
|
||||
context7, sequential-thinking
|
||||
|
||||
# Per-project (.claude/mcp.json) → only when needed
|
||||
# Project-scope (.mcp.json at project root) → only when needed
|
||||
postgres # database project
|
||||
playwright # frontend project
|
||||
serena # large codebase
|
||||
|
|
@ -10622,7 +10662,7 @@ security find-generic-password -s "github-token" -w
|
|||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "bash",
|
||||
"args": ["-c", "GITHUB_TOKEN=$(security find-generic-password -s 'github-token' -w) npx @github/mcp-server"],
|
||||
|
|
@ -10648,9 +10688,9 @@ secret-tool store --label="GitHub Token" service claude key github-token
|
|||
export GITHUB_TOKEN=$(secret-tool lookup service claude key github-token)
|
||||
npx @github/mcp-server
|
||||
|
||||
# mcp.json
|
||||
# ~/.claude.json (or .mcp.json)
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "~/.claude/scripts/mcp-github.sh",
|
||||
"args": []
|
||||
|
|
@ -10701,19 +10741,19 @@ echo ".env" >> ~/.claude/.gitignore
|
|||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "npx",
|
||||
"args": ["@github/mcp-server"],
|
||||
"env": {
|
||||
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
|
||||
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
|
||||
}
|
||||
},
|
||||
"postgres": {
|
||||
"command": "npx",
|
||||
"args": ["@modelcontextprotocol/server-postgres"],
|
||||
"env": {
|
||||
"DATABASE_URL": "${env:DATABASE_URL}"
|
||||
"DATABASE_URL": "${DATABASE_URL}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10739,14 +10779,14 @@ direnv allow ~/.claude
|
|||
|
||||
```bash
|
||||
# Commit template (no secrets)
|
||||
cat > ~/.claude/mcp.json.template << EOF
|
||||
cat > ~/.claude/mcp-config.template.json << EOF
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "npx",
|
||||
"args": ["@github/mcp-server"],
|
||||
"env": {
|
||||
"GITHUB_TOKEN": "\${env:GITHUB_TOKEN}"
|
||||
"GITHUB_TOKEN": "\${GITHUB_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10754,10 +10794,10 @@ cat > ~/.claude/mcp.json.template << EOF
|
|||
EOF
|
||||
|
||||
# Generate actual config from template + .env
|
||||
envsubst < ~/.claude/mcp.json.template > ~/.claude/mcp.json
|
||||
envsubst < ~/.claude/mcp-config.template.json > ~/.claude.json
|
||||
|
||||
# .gitignore
|
||||
mcp.json # Generated, contains resolved secrets
|
||||
.claude.json # Generated, contains resolved secrets
|
||||
.env # Never commit
|
||||
```
|
||||
|
||||
|
|
@ -10784,9 +10824,9 @@ vault kv put secret/claude/github token=ghp_your_token_here
|
|||
export GITHUB_TOKEN=$(vault kv get -field=token secret/claude/github)
|
||||
npx @github/mcp-server
|
||||
|
||||
# mcp.json
|
||||
# ~/.claude.json (or .mcp.json)
|
||||
{
|
||||
"servers": {
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "~/.claude/scripts/mcp-github-vault.sh",
|
||||
"args": []
|
||||
|
|
@ -10841,8 +10881,8 @@ NEW_VALUE=$2
|
|||
# 1. Update .env file
|
||||
sed -i.bak "s|^${SECRET_NAME}=.*|${SECRET_NAME}=${NEW_VALUE}|" ~/.claude/.env
|
||||
|
||||
# 2. Regenerate mcp.json from template
|
||||
envsubst < ~/.claude/mcp.json.template > ~/.claude/mcp.json
|
||||
# 2. Regenerate config from template
|
||||
envsubst < ~/.claude/mcp-config.template.json > ~/.claude.json
|
||||
|
||||
# 3. Restart MCP servers (if running)
|
||||
pkill -f "mcp-server" || true
|
||||
|
|
@ -10868,7 +10908,7 @@ echo "⚠️ Restart Claude Code to apply changes"
|
|||
# Fetch latest secrets from Vault, update .env, restart Claude
|
||||
|
||||
vault kv get -format=json secret/claude | jq -r '.data.data | to_entries[] | "\(.key)=\(.value)"' > ~/.claude/.env
|
||||
envsubst < ~/.claude/mcp.json.template > ~/.claude/mcp.json
|
||||
envsubst < ~/.claude/mcp-config.template.json > ~/.claude.json
|
||||
|
||||
echo "✅ Secrets rotated from Vault"
|
||||
```
|
||||
|
|
@ -10940,7 +10980,7 @@ claude
|
|||
| **Use OS keychain when possible** | Encrypted at rest, OS-level security |
|
||||
| **Never commit .env to Git** | One leak = full compromise |
|
||||
| **Commit .env.example template** | Team onboarding without secrets |
|
||||
| **Use ${env:VAR} in mcp.json** | Separation of config and secrets |
|
||||
| **Use ${VAR} in MCP config** | Separation of config and secrets |
|
||||
| **Rotate secrets quarterly** | Limit blast radius of old leaks |
|
||||
| **Audit .gitignore before push** | Prevent accidental exposure |
|
||||
| **Least privilege credentials** | Read-only DB users, scoped API tokens |
|
||||
|
|
@ -11451,11 +11491,13 @@ MCP servers can dynamically change their tool offerings. A server might pass ini
|
|||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"disallowedTools": ["mcp__untrusted-server__execute", "mcp__untrusted-server__shell"]
|
||||
"deny": ["mcp__untrusted-server__execute", "mcp__untrusted-server__shell"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**: `disallowedTools` is a root-level key or CLI flag (`--disallowedTools`), not nested under `permissions`. For settings.json, use `permissions.deny` to block tool patterns.
|
||||
|
||||
### Red Flags
|
||||
|
||||
Avoid MCP servers that:
|
||||
|
|
@ -11674,7 +11716,12 @@ The `effort` parameter significantly impacts how Claude uses tools:
|
|||
- **Opus 4.5**: `effort` works **in parallel** with `budget_tokens`. Both parameters are supported and affect different aspects of the response.
|
||||
- **Without thinking enabled**: `effort` still controls text generation and tool calls. It's not a thinking-only parameter.
|
||||
|
||||
**CLI usage**: Same as before — Alt+T toggles thinking on/off globally. No per-request effort control in CLI (uses model's default `high`).
|
||||
**CLI usage**: Three methods to control effort level in Claude Code:
|
||||
1. **`/model` command** with left/right arrow keys to adjust the effort slider (`low`, `medium`, `high`)
|
||||
2. **`CLAUDE_CODE_EFFORT_LEVEL`** environment variable (set before launching Claude)
|
||||
3. **`effortLevel`** field in settings.json (persistent across sessions)
|
||||
|
||||
Alt+T toggles thinking on/off globally (separate from effort level).
|
||||
|
||||
#### Controlling Thinking Mode
|
||||
|
||||
|
|
@ -11682,7 +11729,9 @@ The `effort` parameter significantly impacts how Claude uses tools:
|
|||
|--------|----------|----------|-------------|
|
||||
| **Alt+T** (Option+T on macOS) | Toggle on/off | Toggle on/off | Current session |
|
||||
| **/config** → Thinking mode | Enable/disable globally | Enable/disable globally | Across sessions |
|
||||
| **API `effort` parameter** | `low\|medium\|high` | `low\|medium\|high\|max` (`max` = 4.6 only) | Per request |
|
||||
| **`/model` slider** (left/right arrows) | `low\|medium\|high` | `low\|medium\|high` | Current session |
|
||||
| **`CLAUDE_CODE_EFFORT_LEVEL`** env var | `low\|medium\|high` | `low\|medium\|high` | Shell session |
|
||||
| **`effortLevel`** in settings.json | `low\|medium\|high` | `low\|medium\|high` | Permanent |
|
||||
| **Ctrl+O** | View thinking blocks | View thinking blocks | Display only |
|
||||
|
||||
#### Cost Implications
|
||||
|
|
@ -16901,6 +16950,19 @@ This guide uses both llms.txt and CLAUDE.md:
|
|||
|
||||
**Result**: Agents can discover content via llms.txt, then consult CLAUDE.md for active context.
|
||||
|
||||
#### Real-World: Anthropic's Official llms.txt
|
||||
|
||||
Anthropic publie deux variantes LLM-optimized pour Claude Code :
|
||||
|
||||
| Fichier | URL | Taille | Tokens (approx) | Use case |
|
||||
|---------|-----|--------|-----------------|----------|
|
||||
| `llms.txt` | `code.claude.com/docs/llms.txt` | ~65 pages | ~15-20K | Index rapide, découverte de sections |
|
||||
| `llms-full.txt` | `code.claude.com/docs/llms-full.txt` | ~98 KB | ~25-30K | Fact-checking, doc complète, source de vérité |
|
||||
|
||||
**Pattern recommandé** : fetch `llms.txt` d'abord pour identifier la section pertinente, puis fetch la page spécifique (ou `llms-full.txt`) pour les détails. Évite de charger 98 KB quand seules 2 pages sont nécessaires.
|
||||
|
||||
Ces URLs sont la source officielle à consulter en priorité quand un claim sur Claude Code semble incertain ou potentiellement obsolète.
|
||||
|
||||
#### Specification Resources
|
||||
|
||||
- **Official spec**: https://llmstxt.org/
|
||||
|
|
@ -19155,24 +19217,29 @@ Complete reference for all Claude Code command-line flags.
|
|||
| `--json-schema` | JSON Schema for structured output validation | `claude --json-schema '{"type":"object","properties":{"name":{"type":"string"}}}' ` |
|
||||
| `--input-format` | Input format (text/stream-json) | `claude --input-format stream-json` |
|
||||
| `--replay-user-messages` | Re-emit user messages in stream | `claude --replay-user-messages` |
|
||||
| `--allowedTools` | Whitelist specific tools | `claude --allowedTools "Edit,Read,Bash(git:*)"` |
|
||||
| `--allowedTools` | Whitelist specific tools | `claude --allowedTools "Edit,Read,Bash(git *)"` |
|
||||
| `--disallowedTools` | Blacklist specific tools | `claude --disallowedTools "WebFetch"` |
|
||||
| `--mcp-config` | Load MCP servers from JSON file | `claude --mcp-config ./mcp.json` |
|
||||
| `--strict-mcp-config` | Only use MCP servers from config | `claude --strict-mcp-config` |
|
||||
| `--plugin-dir` | Load plugins from directory (repeatable) | `claude --plugin-dir ~/.claude/plugins` |
|
||||
| `--append-system-prompt` | Add to system prompt | `claude --append-system-prompt "Use TypeScript"` |
|
||||
| `--permission-mode` | Permission mode (default/auto/plan) | `claude --permission-mode plan` |
|
||||
| `--permission-mode` | Permission mode (default/acceptEdits/plan/dontAsk/bypassPermissions) | `claude --permission-mode plan` |
|
||||
| `--model` | Model selection | `claude --model sonnet` |
|
||||
| `--max-budget-usd` | Maximum API spend limit (with `--print` only) | `claude -p "analyze" --max-budget-usd 5.00` |
|
||||
| `--tools` | Enable specific tools for the session | `claude --tools "Edit,Read,Bash"` |
|
||||
| `--agent` | Specify agent for session | `claude --agent security-reviewer` |
|
||||
| `--system-prompt` | Override system prompt entirely | `claude --system-prompt "You are a reviewer"` |
|
||||
| `--add-dir` | Allow tool access to additional directories | `claude --add-dir ../shared ../utils` |
|
||||
| `--continue` | Continue last conversation | `claude --continue` |
|
||||
| `-r, --resume` | Resume session by ID | `claude --resume abc123` |
|
||||
| `--worktree` / `-w` | Run in isolated git worktree | `claude --worktree` |
|
||||
| `--continue` | Continue last conversation (in current directory) | `claude --continue` |
|
||||
| `-r, --resume` | Resume session by ID or show picker | `claude --resume abc123` |
|
||||
| `--dangerously-skip-permissions` | Skip all permission prompts | `claude --dangerously-skip-permissions` |
|
||||
| `--debug` | Enable debug mode | `claude --debug` |
|
||||
| `--debug` | Enable debug mode (supports categories: `"api,mcp"`) | `claude --debug` |
|
||||
| `--verbose` | Verbose output | `claude --verbose` |
|
||||
| `--mcp-debug` | Debug MCP server connections | `claude --mcp-debug` |
|
||||
| `--version` | Show version | `claude --version` |
|
||||
|
||||
> **Note**: This table covers the most commonly used flags. The full CLI reference (~45 flags) is available at [docs.anthropic.com](https://docs.anthropic.com/en/docs/claude-code/cli-reference).
|
||||
|
||||
**Common Combinations:**
|
||||
|
||||
```bash
|
||||
|
|
@ -19220,7 +19287,7 @@ Use this symptom-based guide for rapid issue identification and resolution:
|
|||
| "Rate limit exceeded" | API throttling from frequent requests | Wait 2 minutes, use `--model haiku` for simple tasks, or use [cc-copilot-bridge](https://github.com/FlorianBruniaux/cc-copilot-bridge) for flat-rate access | Batch operations, use `/compact`, consider Copilot Pro+ |
|
||||
| Claude forgets instructions | Context overflow, CLAUDE.md lost | Create checkpoint, `/clear`, reload CLAUDE.md | Keep CLAUDE.md concise (<500 lines) |
|
||||
| MCP server not connecting | Server crashed or config error | `claude mcp list`, check paths, restart server | Test servers after config changes |
|
||||
| Permission prompts every time | Tool not in `allowedTools` | Add pattern to `settings.json` allowedTools | Use wildcards: `Bash(git:*)` |
|
||||
| Permission prompts every time | Tool not in `allowedTools` | Add pattern to `settings.json` allowedTools | Use wildcards: `Bash(git *)` |
|
||||
| Changes not taking effect | Cached configuration | Restart Claude Code session | Use `/exit` before config changes |
|
||||
| Session won't resume | Corrupted session file | Start fresh with `/clear` | Exit cleanly with `/exit` or `Ctrl+D` |
|
||||
|
||||
|
|
@ -20571,7 +20638,7 @@ Quick reference for where Claude Code stores files and configuration.
|
|||
| **Claude data directory** | `C:\Users\<username>\.claude\` |
|
||||
| **Claude config file** | `C:\Users\<username>\.claude.json` |
|
||||
| **Log files** | `%APPDATA%\Claude\logs\` |
|
||||
| **MCP config** | `C:\Users\<username>\.claude\mcp.json` |
|
||||
| **MCP config** | `C:\Users\<username>\.claude.json` (`mcpServers` field) |
|
||||
| **Session data** | `C:\Users\<username>\.claude\local\` |
|
||||
| **Downloads/cache** | `C:\Users\<username>\.claude\downloads\` |
|
||||
|
||||
|
|
@ -20596,7 +20663,7 @@ Get-Content "$env:APPDATA\Claude\logs\mcp*.log" -Wait -Tail 50
|
|||
| **Claude data directory** | `~/.claude/` |
|
||||
| **Claude config file** | `~/.claude.json` |
|
||||
| **Log files** | `~/Library/Logs/Claude/` |
|
||||
| **MCP config** | `~/.claude/mcp.json` |
|
||||
| **MCP config** | `~/.claude.json` (`mcpServers` field) |
|
||||
| **Session data** | `~/.claude/local/` |
|
||||
| **Downloads/cache** | `~/.claude/downloads/` |
|
||||
|
||||
|
|
@ -20623,7 +20690,7 @@ tail -f ~/Library/Logs/Claude/mcp*.log
|
|||
| **Claude data directory** | `~/.claude/` |
|
||||
| **Claude config file** | `~/.claude.json` |
|
||||
| **Log files** | `~/.local/share/claude/logs/` or `~/.cache/claude/logs/` |
|
||||
| **MCP config** | `~/.claude/mcp.json` |
|
||||
| **MCP config** | `~/.claude.json` (`mcpServers` field) |
|
||||
| **Session data** | `~/.claude/local/` |
|
||||
| **Downloads/cache** | `~/.claude/downloads/` |
|
||||
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ How a malicious MCP server can exploit the one-time approval model:
|
|||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 1. Attacker publishes benign MCP "code-formatter" │
|
||||
│ ↓ │
|
||||
│ 2. User adds to ~/.claude/mcp.json, approves once │
|
||||
│ 2. User adds to ~/.claude.json, approves once │
|
||||
│ ↓ │
|
||||
│ 3. MCP works normally for 2 weeks (builds trust) │
|
||||
│ ↓ │
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ claude-code-ultimate-guide/
|
|||
## Related Resources
|
||||
|
||||
- Official: https://docs.anthropic.com/en/docs/claude-code
|
||||
- Official llms.txt (index): https://code.claude.com/docs/llms.txt
|
||||
- Official llms-full.txt (complete): https://code.claude.com/docs/llms-full.txt
|
||||
- DeepWiki: https://deepwiki.com/FlorianBruniaux/claude-code-ultimate-guide
|
||||
- Inspiration: https://claudelog.com/
|
||||
- Whitepapers (FR + EN): https://www.florian.bruniaux.com/guides — 9 focused whitepapers on Claude Code (foundations, prompting, customization, security, architecture, team, privacy, reference, agent teams)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -133,7 +133,7 @@ questions:
|
|||
d: "Git commands with glob patterns"
|
||||
correct: "b"
|
||||
explanation: |
|
||||
The pattern 'Bash(git *)' matches any git command. Permission patterns use wildcards: 'Bash(git *)' matches any git command, 'Bash(pnpm *)' matches any pnpm command, 'mcp__serena__*' matches all Serena MCP tools. You can also use specific patterns like 'Bash(git status:*)' to match only git status.
|
||||
The pattern 'Bash(git *)' matches any git command. Permission patterns use wildcards: 'Bash(git *)' matches any git command, 'Bash(pnpm *)' matches any pnpm command, 'mcp__serena__*' matches all Serena MCP tools. You can also use specific patterns like 'Bash(git status *)' to match only git status. Note: the legacy ':*' suffix syntax is deprecated, use space instead (e.g. 'Bash(git *)' not 'Bash(git:*)').
|
||||
doc_reference:
|
||||
file: "guide/ultimate-guide.md"
|
||||
section: "3.3 Settings & Permissions"
|
||||
|
|
@ -196,12 +196,12 @@ questions:
|
|||
question: "What does 'allowedTools' configuration do differently from permission categories?"
|
||||
options:
|
||||
a: "Nothing, they are the same"
|
||||
b: "Provides granular control with tool-specific patterns in ~/.claude.json"
|
||||
b: "Provides granular control with tool-specific patterns in ~/.claude/settings.json"
|
||||
c: "Only works for MCP tools"
|
||||
d: "Requires admin privileges"
|
||||
correct: "b"
|
||||
explanation: |
|
||||
The allowedTools configuration in ~/.claude.json provides granular control with specific patterns. For example: 'Read(*)' allows all reads, 'Bash(git status:*)' allows only git status, 'Bash(pnpm *:*)' allows pnpm commands. You can set progressive permission levels from beginner (very restrictive) to advanced. Never use --dangerously-skip-permissions.
|
||||
The allowedTools configuration in ~/.claude/settings.json provides granular control with specific patterns. For example: 'Read' allows all reads, 'Bash(git status *)' allows only git status, 'Bash(pnpm *)' allows pnpm commands. You can set progressive permission levels from beginner (very restrictive) to advanced. Never use --dangerously-skip-permissions. Note: use the tool name without parentheses for "all uses" (e.g. 'Read' not 'Read(*)').
|
||||
doc_reference:
|
||||
file: "guide/ultimate-guide.md"
|
||||
section: "3.3 Settings & Permissions"
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ questions:
|
|||
- **UserPromptSubmit**: When user sends a message (context enrichment)
|
||||
- **Notification**: When Claude sends a notification
|
||||
- **SessionStart/SessionEnd**: Session lifecycle events
|
||||
- **Stop**: When user interrupts
|
||||
- **Stop**: When Claude finishes responding
|
||||
doc_reference:
|
||||
file: "guide/ultimate-guide.md"
|
||||
section: "7.1 The Event System"
|
||||
|
|
|
|||
|
|
@ -105,25 +105,25 @@ questions:
|
|||
- id: "08-005"
|
||||
difficulty: "junior"
|
||||
profiles: ["junior", "senior", "power"]
|
||||
question: "Where is the global MCP configuration file located?"
|
||||
question: "Where is the user-scope MCP configuration stored?"
|
||||
options:
|
||||
a: "~/.mcp/config.json"
|
||||
b: "~/.claude/mcp.json"
|
||||
b: "~/.claude.json"
|
||||
c: "/etc/claude/mcp.json"
|
||||
d: "~/.config/claude/mcp.json"
|
||||
correct: "b"
|
||||
explanation: |
|
||||
The global MCP configuration is at `~/.claude/mcp.json`.
|
||||
MCP servers are configured in `~/.claude.json` under the `"mcpServers"` field.
|
||||
|
||||
Configuration locations:
|
||||
- `~/.claude/mcp.json` - Global (applies to all projects)
|
||||
- `/project/.claude/mcp.json` - Project-specific (overrides global)
|
||||
- `~/.claude.json` (field `"mcpServers"`) - User/local scope
|
||||
- `.mcp.json` at project root - Project scope (shareable via VCS)
|
||||
|
||||
The configuration specifies which servers to run and their settings.
|
||||
doc_reference:
|
||||
file: "guide/ultimate-guide.md"
|
||||
section: "8.3 Configuration"
|
||||
anchor: "#mcpjson-location"
|
||||
anchor: "#mcp-configuration-location"
|
||||
|
||||
- id: "08-006"
|
||||
difficulty: "senior"
|
||||
|
|
@ -177,24 +177,26 @@ questions:
|
|||
- id: "08-008"
|
||||
difficulty: "junior"
|
||||
profiles: ["junior", "senior", "power"]
|
||||
question: "What variable can you use in mcp.json to reference the current project path?"
|
||||
question: "What syntax does Claude Code use for environment variable substitution in MCP config?"
|
||||
options:
|
||||
a: "${projectPath}"
|
||||
b: "${workspaceFolder}"
|
||||
c: "${cwd}"
|
||||
c: "${VAR_NAME}"
|
||||
d: "${PROJECT_DIR}"
|
||||
correct: "b"
|
||||
correct: "c"
|
||||
explanation: |
|
||||
The `${workspaceFolder}` variable expands to the current project path.
|
||||
Claude Code uses standard shell-style `${VAR}` syntax for environment variable expansion.
|
||||
|
||||
Variable substitution in mcp.json:
|
||||
- `${workspaceFolder}` - Current project path
|
||||
- `${env:VAR_NAME}` - Environment variable
|
||||
Variable substitution in MCP config:
|
||||
- `${VAR}` - Environment variable value
|
||||
- `${VAR:-default}` - Environment variable with fallback
|
||||
|
||||
Note: `${workspaceFolder}` and `${env:VAR_NAME}` are VS Code conventions, not Claude Code.
|
||||
|
||||
Example:
|
||||
```json
|
||||
"env": {
|
||||
"PROJECT_PATH": "${workspaceFolder}"
|
||||
"DATABASE_URL": "${DATABASE_URL}"
|
||||
}
|
||||
```
|
||||
doc_reference:
|
||||
|
|
|
|||
406
scripts/resync-reference-yaml.py
Normal file
406
scripts/resync-reference-yaml.py
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Re-sync line numbers in machine-readable/reference.yaml
|
||||
|
||||
Strategy:
|
||||
1. Build header index for each guide file (all lines starting with #)
|
||||
2. For each reference.yaml entry with a line number, read what's at that line
|
||||
3. If content doesn't look right, search by key-name keywords in headers
|
||||
4. Output a patch file with proposed fixes + confidence scores
|
||||
|
||||
Usage:
|
||||
python3 scripts/resync-reference-yaml.py [--apply]
|
||||
|
||||
Without --apply: prints report to stdout + saves claudedocs/resync-report.md
|
||||
With --apply: applies HIGH CONFIDENCE fixes directly to reference.yaml
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).parent.parent
|
||||
YAML_FILE = REPO_ROOT / "machine-readable" / "reference.yaml"
|
||||
REPORT_FILE = REPO_ROOT / "claudedocs" / "resync-report.md"
|
||||
|
||||
# Files that reference.yaml points to (with bare integers → ultimate-guide.md)
|
||||
GUIDE_FILES = {
|
||||
"guide/ultimate-guide.md": None,
|
||||
"guide/architecture.md": None,
|
||||
"guide/workflows/iterative-refinement.md": None,
|
||||
"guide/observability.md": None,
|
||||
"guide/learning-with-ai.md": None,
|
||||
"guide/ai-ecosystem.md": None,
|
||||
"guide/ai-traceability.md": None,
|
||||
"guide/sandbox-isolation.md": None,
|
||||
"guide/sandbox-native.md": None,
|
||||
"guide/known-issues.md": None,
|
||||
"guide/third-party-tools.md": None,
|
||||
"guide/adoption-approaches.md": None,
|
||||
"examples/commands/review-pr.md": None,
|
||||
"examples/agents/code-reviewer.md": None,
|
||||
}
|
||||
|
||||
|
||||
def build_header_index(filepath: Path) -> list[tuple[int, str]]:
|
||||
"""Return list of (line_num, header_text) for all # headers."""
|
||||
headers = []
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
for i, line in enumerate(f, 1):
|
||||
stripped = line.rstrip()
|
||||
if stripped.startswith("#"):
|
||||
headers.append((i, stripped))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return headers
|
||||
|
||||
|
||||
def get_line_content(filepath: Path, line_num: int, context: int = 2) -> str:
|
||||
"""Return content around a given line number."""
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
start = max(0, line_num - 1 - context)
|
||||
end = min(len(lines), line_num + context)
|
||||
result = []
|
||||
for i in range(start, end):
|
||||
marker = ">>>" if i == line_num - 1 else " "
|
||||
result.append(f"{marker} {i+1}: {lines[i].rstrip()}")
|
||||
return "\n".join(result)
|
||||
except FileNotFoundError:
|
||||
return "(file not found)"
|
||||
|
||||
|
||||
def key_to_keywords(key: str) -> list[str]:
|
||||
"""Convert snake_case key to search keywords, filtering noise words."""
|
||||
noise = {"the", "a", "an", "and", "or", "of", "in", "to", "for",
|
||||
"is", "at", "by", "on", "it", "its", "from", "with",
|
||||
"guide", "section", "line", "ref", "reference", "api",
|
||||
"mode", "modes", "type", "types", "table", "example",
|
||||
"examples", "list", "advanced", "basic", "overview", "vs"}
|
||||
words = re.split(r"[_\-]", key.lower())
|
||||
return [w for w in words if w not in noise and len(w) > 2]
|
||||
|
||||
|
||||
def score_header(keywords: list[str], header_text: str) -> int:
|
||||
"""Score a header based on keyword matches (higher = better)."""
|
||||
header_lower = header_text.lower()
|
||||
score = 0
|
||||
for kw in keywords:
|
||||
if kw in header_lower:
|
||||
score += 1
|
||||
# Partial match bonus
|
||||
elif len(kw) > 4 and any(kw in w for w in header_lower.split()):
|
||||
score += 0.5
|
||||
return score
|
||||
|
||||
|
||||
def find_best_header(key: str, headers: list[tuple[int, str]],
|
||||
old_line: int) -> tuple[int | None, float, str]:
|
||||
"""Find best matching header. Returns (new_line, confidence, header_text)."""
|
||||
keywords = key_to_keywords(key)
|
||||
if not keywords:
|
||||
return None, 0.0, ""
|
||||
|
||||
best_score = 0
|
||||
best_line = None
|
||||
best_text = ""
|
||||
second_best = 0
|
||||
|
||||
for line_num, header_text in headers:
|
||||
score = score_header(keywords, header_text)
|
||||
if score > best_score:
|
||||
second_best = best_score
|
||||
best_score = score
|
||||
best_line = line_num
|
||||
best_text = header_text
|
||||
elif score > second_best:
|
||||
second_best = score
|
||||
|
||||
if best_score == 0:
|
||||
return None, 0.0, ""
|
||||
|
||||
# Confidence: high if best is clearly better than second best
|
||||
if best_score >= 2 and (second_best == 0 or best_score / max(second_best, 0.1) >= 2):
|
||||
confidence = min(1.0, best_score / max(len(keywords), 1))
|
||||
else:
|
||||
confidence = 0.4 * (best_score / max(len(keywords), 1))
|
||||
|
||||
return best_line, confidence, best_text
|
||||
|
||||
|
||||
def parse_yaml_line_refs(yaml_content: str) -> list[dict]:
|
||||
"""
|
||||
Parse reference.yaml and extract all line number references.
|
||||
Returns list of {key, file, old_line, yaml_line, raw_value}
|
||||
"""
|
||||
results = []
|
||||
in_main_guide_section = False
|
||||
lines = yaml_content.split("\n")
|
||||
|
||||
for i, line in enumerate(lines, 1):
|
||||
stripped = line.strip()
|
||||
if not stripped or stripped.startswith("#"):
|
||||
# Track if we're in the main guide section (bare integers = ultimate-guide.md)
|
||||
if "# Main guide (guide/ultimate-guide.md)" in stripped:
|
||||
in_main_guide_section = True
|
||||
elif stripped.startswith("#") and in_main_guide_section:
|
||||
# New major section — stop treating bare ints as ultimate-guide.md
|
||||
# But keep it true since the pattern continues after comments
|
||||
pass
|
||||
continue
|
||||
|
||||
# Pattern 1: key: "filepath:NNNN" or key: "filepath:NNNN" # comment
|
||||
m = re.match(r'^(\s*)(\S+):\s*"([^"]+):(\d+)"', line)
|
||||
if m:
|
||||
key = m.group(2).rstrip(":")
|
||||
filepath = m.group(3)
|
||||
line_num = int(m.group(4))
|
||||
results.append({
|
||||
"key": key,
|
||||
"file": filepath,
|
||||
"old_line": line_num,
|
||||
"yaml_line": i,
|
||||
"raw_value": f'"{filepath}:{line_num}"',
|
||||
"type": "string_ref",
|
||||
})
|
||||
continue
|
||||
|
||||
# Pattern 2: key: NNNN (bare integer, implies ultimate-guide.md if in that section)
|
||||
m = re.match(r'^(\s*)(\S+):\s*(\d{3,5})\s*(?:#.*)?$', line)
|
||||
if m:
|
||||
key = m.group(2).rstrip(":")
|
||||
line_num = int(m.group(3))
|
||||
# Heuristic: if line_num > 100 and key looks like a content reference
|
||||
# (not a count, score, year etc.)
|
||||
if line_num > 100 and not any(x in key for x in
|
||||
["count", "score", "stars", "year", "limit", "budget",
|
||||
"savings", "total", "ratio", "budget", "sizing"]):
|
||||
results.append({
|
||||
"key": key,
|
||||
"file": "guide/ultimate-guide.md",
|
||||
"old_line": line_num,
|
||||
"yaml_line": i,
|
||||
"raw_value": str(line_num),
|
||||
"type": "bare_int",
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def validate_line(filepath: Path, line_num: int) -> str:
|
||||
"""Return the content at a given line (or error)."""
|
||||
try:
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
if 1 <= line_num <= len(lines):
|
||||
return lines[line_num - 1].rstrip()
|
||||
return f"(line {line_num} out of range, file has {len(lines)} lines)"
|
||||
except FileNotFoundError:
|
||||
return "(file not found)"
|
||||
|
||||
|
||||
def is_sensible_content(key: str, content: str) -> bool:
|
||||
"""Quick check if content at old line is plausibly related to the key."""
|
||||
if not content or content.startswith("("):
|
||||
return False
|
||||
keywords = key_to_keywords(key)
|
||||
if not keywords:
|
||||
return True
|
||||
content_lower = content.lower()
|
||||
matches = sum(1 for kw in keywords if kw in content_lower)
|
||||
return matches >= max(1, len(keywords) // 2)
|
||||
|
||||
|
||||
def main():
|
||||
apply_fixes = "--apply" in sys.argv
|
||||
|
||||
print("Reading reference.yaml...")
|
||||
with open(YAML_FILE, encoding="utf-8") as f:
|
||||
yaml_content = f.read()
|
||||
|
||||
print("Building header indexes...")
|
||||
header_indexes = {}
|
||||
for rel_path in GUIDE_FILES:
|
||||
abs_path = REPO_ROOT / rel_path
|
||||
idx = build_header_index(abs_path)
|
||||
header_indexes[rel_path] = idx
|
||||
if idx:
|
||||
print(f" {rel_path}: {len(idx)} headers")
|
||||
else:
|
||||
print(f" {rel_path}: NOT FOUND or no headers")
|
||||
|
||||
print("\nParsing YAML references...")
|
||||
refs = parse_yaml_line_refs(yaml_content)
|
||||
print(f"Found {len(refs)} line number references")
|
||||
|
||||
report_lines = [
|
||||
"# Re-sync Report: machine-readable/reference.yaml",
|
||||
f"Generated: 2026-02-25",
|
||||
f"Total references scanned: {len(refs)}",
|
||||
"",
|
||||
]
|
||||
|
||||
corrections = [] # (yaml_line, old_value, new_value, key)
|
||||
stats = {"ok": 0, "high": 0, "medium": 0, "low": 0, "unknown": 0, "file_missing": 0}
|
||||
|
||||
ok_entries = []
|
||||
needs_fix = []
|
||||
|
||||
for ref in refs:
|
||||
key = ref["key"]
|
||||
rel_path = ref["file"]
|
||||
old_line = ref["old_line"]
|
||||
abs_path = REPO_ROOT / rel_path
|
||||
|
||||
current_content = validate_line(abs_path, old_line)
|
||||
headers = header_indexes.get(rel_path, [])
|
||||
|
||||
if not headers and not abs_path.exists():
|
||||
stats["file_missing"] += 1
|
||||
needs_fix.append({**ref, "status": "FILE_MISSING", "new_line": None,
|
||||
"confidence": 0, "current_content": current_content,
|
||||
"suggested_header": ""})
|
||||
continue
|
||||
|
||||
sensible = is_sensible_content(key, current_content)
|
||||
|
||||
if sensible:
|
||||
stats["ok"] += 1
|
||||
ok_entries.append({**ref, "current_content": current_content})
|
||||
else:
|
||||
new_line, confidence, header_text = find_best_header(key, headers, old_line)
|
||||
|
||||
if confidence >= 0.7:
|
||||
level = "HIGH"
|
||||
stats["high"] += 1
|
||||
elif confidence >= 0.4:
|
||||
level = "MEDIUM"
|
||||
stats["medium"] += 1
|
||||
elif new_line:
|
||||
level = "LOW"
|
||||
stats["low"] += 1
|
||||
else:
|
||||
level = "UNKNOWN"
|
||||
stats["unknown"] += 1
|
||||
|
||||
needs_fix.append({
|
||||
**ref,
|
||||
"status": level,
|
||||
"new_line": new_line,
|
||||
"confidence": confidence,
|
||||
"current_content": current_content,
|
||||
"suggested_header": header_text,
|
||||
})
|
||||
|
||||
if new_line and level in ("HIGH", "MEDIUM"):
|
||||
if ref["type"] == "string_ref":
|
||||
old_val = f'"{rel_path}:{old_line}"'
|
||||
new_val = f'"{rel_path}:{new_line}"'
|
||||
else:
|
||||
old_val = str(old_line)
|
||||
new_val = str(new_line)
|
||||
corrections.append((ref["yaml_line"], old_val, new_val, key))
|
||||
|
||||
# Build report
|
||||
report_lines += [
|
||||
"## Summary",
|
||||
"",
|
||||
f"| Status | Count |",
|
||||
f"|--------|-------|",
|
||||
f"| OK (content matches) | {stats['ok']} |",
|
||||
f"| HIGH confidence fix | {stats['high']} |",
|
||||
f"| MEDIUM confidence fix | {stats['medium']} |",
|
||||
f"| LOW confidence (manual review) | {stats['low']} |",
|
||||
f"| UNKNOWN (no match found) | {stats['unknown']} |",
|
||||
f"| FILE MISSING | {stats['file_missing']} |",
|
||||
f"| **Total** | **{len(refs)}** |",
|
||||
"",
|
||||
f"Auto-fixable (HIGH + MEDIUM): **{stats['high'] + stats['medium']}**",
|
||||
"",
|
||||
]
|
||||
|
||||
if needs_fix:
|
||||
report_lines += ["## Entries Needing Correction", ""]
|
||||
for entry in sorted(needs_fix, key=lambda x: (-x["confidence"], x["key"])):
|
||||
status = entry["status"]
|
||||
emoji = {"HIGH": "✅", "MEDIUM": "⚠️", "LOW": "🔶", "UNKNOWN": "❓", "FILE_MISSING": "🚫"}.get(status, "")
|
||||
report_lines.append(f"### {emoji} {entry['key']} ({status}, conf={entry['confidence']:.2f})")
|
||||
report_lines.append(f"- **File**: `{entry['file']}`")
|
||||
report_lines.append(f"- **Old line**: {entry['old_line']}")
|
||||
report_lines.append(f"- **Content at old line**: `{entry['current_content'][:100]}`")
|
||||
if entry["new_line"]:
|
||||
report_lines.append(f"- **Suggested line**: {entry['new_line']}")
|
||||
report_lines.append(f"- **Header found**: `{entry['suggested_header']}`")
|
||||
else:
|
||||
report_lines.append(f"- **Suggested line**: (not found — manual search needed)")
|
||||
report_lines.append("")
|
||||
|
||||
report_lines += ["## OK Entries (sample)", ""]
|
||||
for entry in ok_entries[:20]:
|
||||
report_lines.append(f"- `{entry['key']}`: line {entry['old_line']} → `{entry['current_content'][:80]}`")
|
||||
|
||||
report_content = "\n".join(report_lines)
|
||||
|
||||
# Write report
|
||||
REPORT_FILE.parent.mkdir(exist_ok=True)
|
||||
with open(REPORT_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(report_content)
|
||||
print(f"\nReport saved to {REPORT_FILE}")
|
||||
|
||||
# Print summary
|
||||
print(f"\n{'='*60}")
|
||||
print(f"OK: {stats['ok']}")
|
||||
print(f"HIGH fix: {stats['high']}")
|
||||
print(f"MEDIUM fix: {stats['medium']}")
|
||||
print(f"LOW fix: {stats['low']}")
|
||||
print(f"UNKNOWN: {stats['unknown']}")
|
||||
print(f"FILE MISSING: {stats['file_missing']}")
|
||||
print(f"Auto-fixable: {stats['high'] + stats['medium']}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
if corrections:
|
||||
print(f"\n{'='*60}")
|
||||
print("PROPOSED CORRECTIONS (HIGH + MEDIUM confidence):")
|
||||
print(f"{'='*60}")
|
||||
for yaml_line, old_val, new_val, key in corrections[:30]:
|
||||
print(f" Line {yaml_line:4d} | {key}")
|
||||
print(f" {old_val} → {new_val}")
|
||||
if len(corrections) > 30:
|
||||
print(f" ... and {len(corrections) - 30} more (see report)")
|
||||
|
||||
if apply_fixes and corrections:
|
||||
print(f"\nApplying {len(corrections)} fixes to reference.yaml...")
|
||||
content = yaml_content
|
||||
applied = 0
|
||||
for yaml_line_num, old_val, new_val, key in corrections:
|
||||
# Find the exact occurrence of old_val near the yaml_line_num
|
||||
# Use line-by-line replacement to be precise
|
||||
lines = content.split("\n")
|
||||
target_idx = yaml_line_num - 1
|
||||
if target_idx < len(lines) and old_val in lines[target_idx]:
|
||||
lines[target_idx] = lines[target_idx].replace(old_val, new_val, 1)
|
||||
applied += 1
|
||||
else:
|
||||
# Try ±2 lines
|
||||
for delta in [-1, 1, -2, 2]:
|
||||
idx = target_idx + delta
|
||||
if 0 <= idx < len(lines) and old_val in lines[idx]:
|
||||
lines[idx] = lines[idx].replace(old_val, new_val, 1)
|
||||
applied += 1
|
||||
break
|
||||
content = "\n".join(lines)
|
||||
|
||||
with open(YAML_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
print(f"Applied {applied}/{len(corrections)} fixes.")
|
||||
print(f"Run without --apply to verify remaining issues.")
|
||||
elif not apply_fixes and corrections:
|
||||
print(f"\nRun with --apply to apply HIGH+MEDIUM confidence fixes automatically.")
|
||||
print(f"LOW and UNKNOWN confidence fixes require manual review (see report).")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -223,7 +223,7 @@ Based on the goal from Phase 0, ask ONLY the necessary additional questions:
|
|||
When presenting security topics, add a hands-on option alongside the usual depth controls:
|
||||
- After sandbox/permissions topic → "Try: Run `/security-check` to scan your current setup"
|
||||
- After threat intelligence topic → "Try: Check your installed skills against known malicious patterns"
|
||||
- After MCP vetting topic → "Try: Review your `~/.claude/mcp.json` against the MCP Safe List"
|
||||
- After MCP vetting topic → "Try: Review your `~/.claude.json` against the MCP Safe List"
|
||||
|
||||
4. **Depth control**: Use AskUserQuestion with options:
|
||||
- "Go deeper" → Provide detailed explanation with examples
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue