diff --git a/CLAUDE.md b/CLAUDE.md index dceeef1..91aa6fa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -29,6 +29,11 @@ machine-readable/ # For LLM consumption ├── reference.yaml # Condensed index (~2K tokens) └── llms.txt # AI indexation file +whitepapers/ # Focused whitepapers (FR + EN) +├── fr/ # 10 source files in French (.qmd) +└── en/ # 10 translated files in English (.qmd) +# Published at: https://www.florian.bruniaux.com/guides + tools/ # Interactive utilities ├── audit-prompt.md # Setup audit prompt └── onboarding-prompt.md # Personalized learning prompt diff --git a/README.md b/README.md index 01fdcb4..283fee9 100644 --- a/README.md +++ b/README.md @@ -463,6 +463,24 @@ TDD/SDD/BDD are not optional with Claude Code. AI accelerates bad code as much a --- +## 📄 Whitepapers (FR + EN) + +A series of 9 focused whitepapers covering Claude Code in depth. Each covers a specific topic and is available in both **French and English**. + +- **00** — *De Zéro à Productif / From Zero to Productive* — Foundations, first steps +- **01** — *Prompts qui Marchent / Prompts That Work* — Prompting method, context, hooks +- **02** — *Personnaliser Claude / Customizing Claude* — CLAUDE.md, custom agents, skills +- **03** — *Sécurité en Production / Security in Production* — 17 security hooks, threat DB, permissions +- **04** — *L'Architecture Démystifiée / Architecture Demystified* — Agent loop, context, token pricing +- **05** — *Déployer en Équipe / Team Deployment* — CI/CD, observability, 50+ devs adoption +- **06** — *Privacy & Compliance* — Anthropic data, ZDR, retention policies +- **07** — *Guide de Référence / Reference Guide* — Complete synthesis + advanced workflows +- **08** — *Agent Teams* — Multi-agent orchestration and coordination + +→ **[Download all whitepapers](https://www.florian.bruniaux.com/guides)** + +--- + ## 🌍 Ecosystem ### Claude Cowork (Non-Developers) diff --git a/cheatsheet.pdf b/cheatsheet.pdf index 3cfac64..78fda7b 100644 Binary files a/cheatsheet.pdf and b/cheatsheet.pdf differ diff --git a/examples/hooks/bash/velocity-governor.sh b/examples/hooks/bash/velocity-governor.sh new file mode 100755 index 0000000..ec2bb9d --- /dev/null +++ b/examples/hooks/bash/velocity-governor.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +# velocity-governor.sh — Claude Code PreToolUse hook +# Limite le débit de tokens pour éviter les rate limits API +# +# Variables d'environnement officielles Claude Code : +# CLAUDE_PROJECT_DIR — chemin absolu du projet +# CLAUDE_VELOCITY_MAX_TPM — override du seuil (défaut : 50000 tokens/min) +# +# Headers API Anthropic pour le rate limiting : +# anthropic-ratelimit-tokens-remaining +# anthropic-ratelimit-tokens-reset +# retry-after (sur 429) +# +# Installation : ajouter dans .claude/settings.json sous hooks.PreToolUse +# { +# "hooks": { +# "PreToolUse": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "bash examples/hooks/bash/velocity-governor.sh" }] }] +# } +# } + +set -euo pipefail + +# ── Configuration ────────────────────────────────────────────────────────────── +MAX_TOKENS_PER_MINUTE="${CLAUDE_VELOCITY_MAX_TPM:-50000}" +PROJECT_SLUG="${CLAUDE_PROJECT_DIR//\//-}" +STATE_FILE="/tmp/claude-velocity-${PROJECT_SLUG}.json" + +# ── Lecture stdin (JSON fourni par Claude Code) ──────────────────────────────── +input=$(cat) +# Contient : session_id, cwd, tool_name, tool_input (selon event PreToolUse) + +# ── Récupération ou initialisation de l'état ────────────────────────────────── +now=$(date +%s) + +if [[ -f "$STATE_FILE" ]]; then + window_start=$(jq -r '.window_start // 0' "$STATE_FILE" 2>/dev/null || echo "$now") + tokens_used=$(jq -r '.tokens_used // 0' "$STATE_FILE" 2>/dev/null || echo 0) +else + window_start=$now + tokens_used=0 +fi + +# ── Réinitialisation de la fenêtre glissante (60 secondes) ──────────────────── +window_age=$(( now - window_start )) +if (( window_age >= 60 )); then + window_start=$now + tokens_used=0 +fi + +# ── Estimation conservative du coût de l'outil ──────────────────────────────── +# 1 appel outil ≈ 500 tokens (lecture + écriture courte) +# Ajuster CLAUDE_VELOCITY_MAX_TPM selon votre tier API +estimated_tokens=500 +new_total=$(( tokens_used + estimated_tokens )) + +# ── Throttle si seuil dépassé ───────────────────────────────────────────────── +if (( new_total > MAX_TOKENS_PER_MINUTE )); then + remaining=$(( 60 - window_age )) + if (( remaining > 0 )); then + # Attendre la fin de la fenêtre courante + sleep "$remaining" + window_start=$(date +%s) + new_total=$estimated_tokens + fi +fi + +# ── Persistance de l'état ───────────────────────────────────────────────────── +jq -n \ + --argjson ws "$window_start" \ + --argjson tu "$new_total" \ + '{window_start: $ws, tokens_used: $tu}' > "$STATE_FILE" + +# ── Laisser passer l'outil ───────────────────────────────────────────────────── +# exit 0 = continuer normalement +# exit 1 = bloquer l'outil (non utilisé ici, préférer le throttle) +exit 0 diff --git a/examples/scripts/README.md b/examples/scripts/README.md index 7898767..26fedfb 100644 --- a/examples/scripts/README.md +++ b/examples/scripts/README.md @@ -17,6 +17,7 @@ Utility scripts for Claude Code power users. | `clean-reinstall-claude.sh/.ps1` | Clean reinstall of Claude Code | | `fresh-context-loop.sh` | Run Claude Code in fresh context loops | | `session-search.sh` | Search across Claude Code session histories | +| `cc-sessions.py` | Advanced session search with incremental indexing (Python) | | `session-stats.sh` | Statistics about Claude Code sessions | | `bridge.py` | Bridge: Claude Code → doobidoo → LM Studio | @@ -262,6 +263,38 @@ Search across all Claude Code session histories. --- +## Session Manager (Advanced) + +Advanced CLI for session search, browse & resume with incremental indexing. + +**vs session-search.sh**: Faster search (~200ms vs ~400ms), partial ID resume, branch filter, worktree support, incremental JSONL index. + +```bash +# Search in current project +cc-sessions search "notion" + +# Search all projects +cc-sessions --all search "stripe" + +# Filter by date and branch +cc-sessions search "auth" --since 7d --branch develop + +# Recent sessions +cc-sessions recent 10 + +# Resume with partial ID +cc-sessions resume 8d472d + +# JSON output for scripting +cc-sessions --json search "prisma" | jq -r '.[].id' +``` + +**Installation**: `cp cc-sessions.py ~/bin/cc-sessions && chmod +x ~/bin/cc-sessions` + +> [Gist source](https://gist.github.com/FlorianBruniaux/992d4d1107592d9e98ca9d89838871c6) + +--- + ## Session Stats Get statistics about your Claude Code usage. diff --git a/examples/scripts/cc-sessions.py b/examples/scripts/cc-sessions.py new file mode 100755 index 0000000..40348e6 --- /dev/null +++ b/examples/scripts/cc-sessions.py @@ -0,0 +1,498 @@ +#!/usr/bin/env python3 +""" +cc-sessions — Fast CLI to search, browse & resume Claude Code session history + +OVERVIEW +-------- +Claude Code stores all conversation history locally in ~/.claude/projects/ as JSONL files. +This tool indexes those sessions for fast search and provides a clean CLI interface to: + - Search by keyword across all conversations + - Filter by date, branch, or project + - View recent sessions + - Resume past sessions with partial ID matching + +FEATURES +-------- +- ⚡ Incremental indexing: ~200ms search on 1300+ sessions (vs ~5s full scan) +- 📁 Project-scoped by default: auto-detects current project from pwd +- 🔍 Powerful filters: --since 7d, --branch develop, --limit N +- 🎯 Partial ID matching: 'cc-sessions resume 8d472d' finds full session ID +- 🌳 Worktree support: includes git worktree sessions automatically +- 📊 JSON output: pipe to jq/fzf for advanced workflows +- 🐍 Zero dependencies: Python stdlib only (json, argparse, pathlib) + +USAGE +----- +# Search in current project +cc-sessions search "notion" + +# Search all projects +cc-sessions --all search "stripe" + +# Filter by date and branch +cc-sessions search "auth" --since 7d --branch develop --limit 5 + +# Recent sessions +cc-sessions recent 10 + +# Session details (partial ID match) +cc-sessions info 8d472d2c + +# Resume session (execs: claude --resume ) +cc-sessions resume 8d472d2c + +# Force rebuild index +cc-sessions reindex + +# JSON output for composition +cc-sessions --json search "prisma" | jq -r '.[].id' + +INSTALLATION +------------ +1. Save this script to ~/bin/cc-sessions +2. chmod +x ~/bin/cc-sessions +3. Run: cc-sessions recent 5 + (First run builds index ~10s for 1500 sessions, then <200ms) + +INDEX ARCHITECTURE +------------------ +- Location: ~/.claude/sessions-index.jsonl (~360KB for 1300 sessions) +- Format: One JSON object per line with session metadata +- Update strategy: Incremental (only re-parses modified files) +- Rebuild: Automatic on search/recent, manual with 'reindex' + +Session metadata extracted: + - id: Full session UUID + - project: Encoded project path + - branch: Git branch from JSONL gitBranch field + - context: First significant user message (60 chars) + - timestamp: ISO 8601 datetime + - mtime: File modification time (for incremental updates) + +FILTERING RULES +--------------- +Significant user message = all 3 conditions: + 1. entry['type'] == 'user' + 2. content is string (not array = tool_result) + 3. content doesn't start with '<' (excludes XML internal tags) + +This covers all current and future Claude Code internal messages: + - , , + - , , + - Any future XML-formatted system messages + +Subagent sessions (prefix 'agent-') are excluded by default. + +PERFORMANCE +----------- +- First run (build index): ~10s for 1500 sessions +- Subsequent searches: ~200ms (reads index) +- Incremental rebuild: <1s if no changes +- Index size: ~280 bytes per session + +OUTPUT FORMAT +------------- +2026-02-05 17:15 8d472d2c-128b-4d9b-824d-3944e3409984 develop "Migration Support Slack → Notion..." +│ │ │ │ +Date/Time Full Session ID (for --resume) Branch First user message (60 chars) + +ECOSYSTEM +--------- +Similar tools: + - claude-history (Rust): Fuzzy search with fzf + - cclog (Go): JSONL → HTML/Markdown + TUI + - claude-code-history-viewer (Tauri): Desktop GUI + - fast-resume (Rust): Tantivy index + TUI + +cc-sessions positioning: Unix-style CLI, fast search, powerful filters, no dependencies. + +AUTHOR +------ +Created for terminal power users who prefer CLI over GUI. +Gist: https://gist.github.com/FlorianBruniaux/992d4d1107592d9e98ca9d89838871c6 +""" + +import argparse +import json +import os +import sys +from datetime import datetime, timedelta +from pathlib import Path +from typing import Dict, List, Optional + +CLAUDE_DIR = Path.home() / ".claude" +INDEX_PATH = CLAUDE_DIR / "sessions-index.jsonl" + + +def parse_duration(duration_str: str) -> datetime: + """Parse duration string like '7d', '30d' or ISO date.""" + if duration_str.endswith('d'): + days = int(duration_str[:-1]) + return datetime.now() - timedelta(days=days) + return datetime.fromisoformat(duration_str) + + +def encode_project_path(path: Path) -> str: + """Encode project path to match Claude's format.""" + return str(path).replace('/', '-') # Keep leading - from root / + + +def detect_project() -> Optional[str]: + """Detect current project from pwd.""" + pwd = Path.cwd() + encoded = encode_project_path(pwd) + project_dir = CLAUDE_DIR / "projects" / encoded + + if not project_dir.exists(): + return None + return encoded + + +def get_project_dirs(all_projects: bool = False) -> List[Path]: + """Get project directories to scan.""" + if all_projects: + projects_dir = CLAUDE_DIR / "projects" + if not projects_dir.exists(): + return [] + return [d for d in projects_dir.iterdir() if d.is_dir()] + + current = detect_project() + if not current: + return [] + + dirs = [] + base = CLAUDE_DIR / "projects" / current + dirs.append(base) + + # Include worktrees (glob pattern: --worktrees*) + worktrees = list(base.parent.glob(f"{current}--worktrees*")) + dirs.extend(worktrees) + + return dirs + + +def get_first_user_message(filepath: Path) -> Optional[str]: + """Extract first significant user message from session JSONL.""" + try: + with open(filepath, 'r') as f: + for line in f: + if not line.strip(): + continue + try: + entry = json.loads(line) + + # Rule 1: Must be user message + if entry.get('type') != 'user': + continue + + content = entry.get('message', {}).get('content', '') + + # Rule 2: Must be string (not array = tool_result) + if not isinstance(content, str): + continue + + # Rule 3: Not internal XML message + if content.startswith('<'): + continue + + # Found significant user message + return content[:60].replace('\n', ' ') + except json.JSONDecodeError: + continue + except Exception: + pass + return None + + +def parse_session(filepath: Path) -> Optional[Dict]: + """Extract session metadata.""" + session_id = filepath.stem + + # Skip subagent sessions + if session_id.startswith('agent-'): + return None + + mtime = filepath.stat().st_mtime + context = get_first_user_message(filepath) + + if not context: + return None + + # Extract branch from gitBranch field in JSONL + branch = "unknown" + try: + with open(filepath, 'r') as f: + for line in f: + if not line.strip(): + continue + try: + entry = json.loads(line) + git_branch = entry.get('gitBranch') + if git_branch: + branch = git_branch + break + except json.JSONDecodeError: + continue + except Exception: + pass + + project = filepath.parent.name + + return { + "id": session_id, + "project": project, + "mtime": mtime, + "branch": branch, + "context": context, + "timestamp": datetime.fromtimestamp(mtime).isoformat() + } + + +def build_index(project_dirs: List[Path], existing_index: Dict[str, Dict]) -> Dict[str, Dict]: + """Build or update index incrementally.""" + index = existing_index.copy() + + for project_dir in project_dirs: + jsonl_files = list(project_dir.glob("*.jsonl")) + + for filepath in jsonl_files: + session_id = filepath.stem + file_mtime = filepath.stat().st_mtime + + # Skip if already indexed and not modified + if session_id in index and index[session_id]['mtime'] >= file_mtime: + continue + + # Parse session + session = parse_session(filepath) + if session: + index[session_id] = session + + return index + + +def load_index() -> Dict[str, Dict]: + """Load existing index.""" + if not INDEX_PATH.exists(): + return {} + + index = {} + try: + with open(INDEX_PATH, 'r') as f: + for line in f: + if not line.strip(): + continue + entry = json.loads(line) + index[entry['id']] = entry + except Exception as e: + print(f"Warning: Failed to load index: {e}", file=sys.stderr) + return {} + + return index + + +def save_index(index: Dict[str, Dict]): + """Save index to disk.""" + CLAUDE_DIR.mkdir(exist_ok=True) + + with open(INDEX_PATH, 'w') as f: + for entry in index.values(): + f.write(json.dumps(entry) + '\n') + + +def cmd_search(keyword: str, project_dirs: List[Path], limit: int = 10, + since: Optional[str] = None, branch: Optional[str] = None, + json_output: bool = False): + """Search sessions by keyword.""" + # Build/update index + existing = load_index() + index = build_index(project_dirs, existing) + save_index(index) + + # Filter + matches = [] + since_dt = parse_duration(since) if since else None + + for entry in index.values(): + # Filter by project + if not any(entry['project'] == d.name for d in project_dirs): + continue + + # Filter by keyword (case-insensitive in context) + if keyword.lower() not in entry['context'].lower(): + continue + + # Filter by date + if since_dt: + entry_dt = datetime.fromisoformat(entry['timestamp']) + if entry_dt < since_dt: + continue + + # Filter by branch + if branch and entry['branch'] != branch: + continue + + matches.append(entry) + + # Sort by timestamp desc + matches.sort(key=lambda x: x['timestamp'], reverse=True) + matches = matches[:limit] + + # Output + if json_output: + print(json.dumps(matches, indent=2)) + else: + for m in matches: + dt = datetime.fromisoformat(m['timestamp']) + print(f"{dt.strftime('%Y-%m-%d %H:%M')} {m['id']} {m['branch']:12} \"{m['context']}\"") + + +def cmd_recent(project_dirs: List[Path], limit: int = 10, json_output: bool = False): + """Show recent sessions.""" + # Build/update index + existing = load_index() + index = build_index(project_dirs, existing) + save_index(index) + + # Filter by project + sessions = [e for e in index.values() + if any(e['project'] == d.name for d in project_dirs)] + + # Sort by timestamp desc + sessions.sort(key=lambda x: x['timestamp'], reverse=True) + sessions = sessions[:limit] + + # Output + if json_output: + print(json.dumps(sessions, indent=2)) + else: + for s in sessions: + dt = datetime.fromisoformat(s['timestamp']) + print(f"{dt.strftime('%Y-%m-%d %H:%M')} {s['id']} {s['branch']:12} \"{s['context']}\"") + + +def cmd_info(session_id: str): + """Show session details.""" + # Match partial ID + index = load_index() + + matches = [s for s in index.values() if s['id'].startswith(session_id)] + + if not matches: + print(f"Error: Session not found: {session_id}", file=sys.stderr) + sys.exit(1) + + if len(matches) > 1: + print(f"Error: Ambiguous ID, multiple matches:", file=sys.stderr) + for m in matches: + print(f" {m['id']}", file=sys.stderr) + sys.exit(1) + + session = matches[0] + dt = datetime.fromisoformat(session['timestamp']) + + print(f"Session: {session['id']}") + print(f"Date: {dt.strftime('%Y-%m-%d %H:%M:%S')}") + print(f"Project: {session['project']}") + print(f"Branch: {session['branch']}") + print(f"Context: {session['context']}") + + +def cmd_resume(session_id: str): + """Resume a session.""" + # Match partial ID + index = load_index() + + matches = [s for s in index.values() if s['id'].startswith(session_id)] + + if not matches: + print(f"Error: Session not found: {session_id}", file=sys.stderr) + sys.exit(1) + + if len(matches) > 1: + print(f"Error: Ambiguous ID, multiple matches:", file=sys.stderr) + for m in matches: + print(f" {m['id']}", file=sys.stderr) + sys.exit(1) + + full_id = matches[0]['id'] + + # exec claude --resume + os.execvp('claude', ['claude', '--resume', full_id]) + + +def cmd_reindex(): + """Force rebuild of entire index.""" + print("Rebuilding index...", file=sys.stderr) + + projects_dir = CLAUDE_DIR / "projects" + if not projects_dir.exists(): + print("Error: No projects directory found", file=sys.stderr) + sys.exit(1) + + all_dirs = [d for d in projects_dir.iterdir() if d.is_dir()] + + index = build_index(all_dirs, {}) + save_index(index) + + print(f"Indexed {len(index)} sessions", file=sys.stderr) + + +def main(): + parser = argparse.ArgumentParser(description="Search Claude Code session history") + parser.add_argument('--all', action='store_true', help="Search all projects") + parser.add_argument('--json', action='store_true', help="JSON output") + + subparsers = parser.add_subparsers(dest='command', required=True) + + # search + search_parser = subparsers.add_parser('search', help="Search sessions by keyword") + search_parser.add_argument('keyword', help="Search keyword") + search_parser.add_argument('--limit', type=int, default=10, help="Max results") + search_parser.add_argument('--since', help="Filter by date (7d, 30d, or ISO date)") + search_parser.add_argument('--branch', help="Filter by git branch") + + # recent + recent_parser = subparsers.add_parser('recent', help="Show recent sessions") + recent_parser.add_argument('limit', nargs='?', type=int, default=10, help="Number of sessions") + + # info + info_parser = subparsers.add_parser('info', help="Show session details") + info_parser.add_argument('session_id', help="Session ID (partial match)") + + # resume + resume_parser = subparsers.add_parser('resume', help="Resume a session") + resume_parser.add_argument('session_id', help="Session ID (partial match)") + + # reindex + subparsers.add_parser('reindex', help="Force rebuild index") + + args = parser.parse_args() + + # Get project dirs + if args.command in ['search', 'recent']: + project_dirs = get_project_dirs(args.all) + + if not project_dirs: + if args.all: + print("Error: No projects found", file=sys.stderr) + else: + print("Error: Not in a Claude project directory", file=sys.stderr) + print("Hint: Use --all to search all projects", file=sys.stderr) + sys.exit(1) + + # Execute command + if args.command == 'search': + cmd_search(args.keyword, project_dirs, args.limit, args.since, args.branch, args.json) + elif args.command == 'recent': + cmd_recent(project_dirs, args.limit, args.json) + elif args.command == 'info': + cmd_info(args.session_id) + elif args.command == 'resume': + cmd_resume(args.session_id) + elif args.command == 'reindex': + cmd_reindex() + + +if __name__ == '__main__': + main() diff --git a/guide/cheatsheet.md b/guide/cheatsheet.md index 402f957..7d98121 100644 --- a/guide/cheatsheet.md +++ b/guide/cheatsheet.md @@ -537,6 +537,7 @@ where.exe claude; claude doctor; claude mcp list - **Official docs**: [docs.anthropic.com/claude-code](https://docs.anthropic.com/en/docs/claude-code) - **Advanced guide**: [Claudelog.com](https://claudelog.com/) - Tips & patterns - **Full guide**: `ultimate-guide.md` (this repo) +- **Whitepapers (FR + EN)**: [florian.bruniaux.com/guides](https://www.florian.bruniaux.com/guides) — 9 focused PDFs - **Project memory**: Create `CLAUDE.md` at project root - **DeepSeek (cost-effective)**: Configure via `ANTHROPIC_BASE_URL` diff --git a/guide/ultimate-guide.md b/guide/ultimate-guide.md index f3175d3..ecdacf9 100644 --- a/guide/ultimate-guide.md +++ b/guide/ultimate-guide.md @@ -696,7 +696,8 @@ claude --resume claude mcp call serena list_sessions # Recommended: Fast search with ready-to-use resume commands -# See examples/scripts/session-search.sh (zero dependencies, 15ms list, 400ms search) +# See examples/scripts/session-search.sh (bash, zero dependencies, 15ms list, 400ms search) +# See examples/scripts/cc-sessions.py (Python, incremental index, partial resume, branch filter) cs # List 10 most recent sessions cs "authentication" # Full-text search across all sessions @@ -705,7 +706,7 @@ You: /exit Session ID: abc123def (saved for resume) ``` -> **Session Search Tool**: For fast session search with copy-paste resume commands, see [Observability Guide](./observability.md#session-search--resume) and [session-search.sh](../examples/scripts/session-search.sh). +> **Session Search Tools**: For fast session search, see [session-search.sh](../examples/scripts/session-search.sh) (bash, lightweight) and [cc-sessions.py](../examples/scripts/cc-sessions.py) (Python, advanced features: incremental index, partial ID resume, branch filter). Also: [Observability Guide](./observability.md#session-search--resume). **Common use cases**: @@ -18890,6 +18891,26 @@ If you work with non-technical team members, **Cowork** brings Claude's agentic ## Further Reading +### Whitepapers (FR + EN) + +A series of 9 focused whitepapers covering Claude Code topics in depth, available in French and English: + +| # | Topic | Scope | +|---|-------|-------| +| 00 | Foundations | First steps, core concepts | +| 01 | Effective Prompts | Prompting method, context, hooks | +| 02 | Customization | CLAUDE.md, agents, skills | +| 03 | Security | 17 hooks, threat DB, permissions | +| 04 | Architecture | Agent loop, context, token pricing | +| 05 | Team Deployment | CI/CD, observability, 50+ devs | +| 06 | Privacy & Compliance | Anthropic data, ZDR, retention | +| 07 | Reference Guide | Complete synthesis + workflows | +| 08 | Agent Teams | Multi-agent orchestration | + +→ **[Download all whitepapers (FR + EN)](https://www.florian.bruniaux.com/guides)** + +--- + ### Advanced Workflows For advanced autonomous workflows, see Nick Tune's [Coding Agent Development Workflows](https://medium.com/nick-tune-tech-strategy-blog/coding-agent-development-workflows-af52e6f912aa) - a pipeline-driven approach focusing on fully autonomous PR generation with multi-tool orchestration. diff --git a/machine-readable/llms.txt b/machine-readable/llms.txt index 546424d..1f611f0 100644 --- a/machine-readable/llms.txt +++ b/machine-readable/llms.txt @@ -128,6 +128,7 @@ claude-code-ultimate-guide/ - Official: https://docs.anthropic.com/en/docs/claude-code - 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) ## Author diff --git a/machine-readable/reference.yaml b/machine-readable/reference.yaml index 6683cbe..f3ba7f5 100644 --- a/machine-readable/reference.yaml +++ b/machine-readable/reference.yaml @@ -44,6 +44,7 @@ deep_dive: # Session management session_search: "guide/observability.md:29" session_search_script: "examples/scripts/session-search.sh" + cc_sessions_script: "examples/scripts/cc-sessions.py" session_resume_limitations: "guide/observability.md:117" session_cross_folder_migration: "guide/observability.md:117" session_migration_manual: "guide/observability.md:135" @@ -77,7 +78,11 @@ deep_dive: # PDF Generation pdf_generation: "guide/workflows/pdf-generation.md" pdf_generator_skill: "examples/skills/pdf-generator.md" - whitepapers_example: "whitepapers/README.md" # Local example only (gitignored) + # Whitepapers (FR + EN) — 9 focused whitepapers on Claude Code + whitepapers_url: "https://www.florian.bruniaux.com/guides" + whitepapers_fr: "whitepapers/fr/" # FR sources (Quarto .qmd) + whitepapers_en: "whitepapers/en/" # EN sources (Quarto .qmd) + whitepapers_topics: "foundations, prompting, customization, security, architecture, team, privacy, reference, agent-teams" # Learning with AI (guide/learning-with-ai.md) learning_quick_check: "guide/learning-with-ai.md:31" learning_uval_protocol: "guide/learning-with-ai.md:127"