<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    
    <title>Angelo Lima - Dev Web &amp; IA - English</title>
    
    
    <description>Feed RSS angelo-lima.fr</description>
    
    <link>https://angelo-lima.fr/en/</link>
    <atom:link href="https://angelo-lima.fr/en/feed.xml" rel="self" type="application/rss+xml" />
    <language>en-US</language>
    <managingEditor>angelomiguellima@gmail.com (Angélo LIMA)</managingEditor>
    <webMaster>angelomiguellima@gmail.com (Angélo LIMA)</webMaster>
    <lastBuildDate>Fri, 03 Apr 2026 07:53:23 +0200</lastBuildDate>
    <generator>Jekyll v4.3.4</generator>
    <image>
      <url>https://angelo-lima.fr/assets/img/avatar-icon.png</url>
      <title>Angelo Lima - Dev Web &amp; IA</title>
      <link>https://angelo-lima.fr/en/</link>
    </image>
    
    
    
    
      <item>
        <title>Claude Code Cheat Sheet 2026: Every Command, Shortcut &amp; Feature in One Place</title>
        <description>
          
            The most complete Claude Code cheatsheet for March 2026: 55+ slash commands, 55+ CLI flags, 25 hook events, 6 permission modes, MCP Computer Use, and a full extension creation guide. Available in EN and FR.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code evolves fast. Most cheatsheets available online are already missing features that shipped in early 2026. I built an <strong>exhaustive, visual reference</strong> covering everything in Claude Code v2.x as of March 2026 — and I’m sharing it for free.</p>

<h2 id="the-cheatsheet">The Cheatsheet</h2>

<p>Available in both English and French:</p>

<ul>
  <li><strong><a href="/assets/data/claude-code-cheatsheet-2026-en.html">English — Interactive HTML</a></strong></li>
  <li><strong><a href="/assets/data/claude-code-cheatsheet-2026.html">French — Interactive HTML</a></strong></li>
</ul>

<table>
  <tbody>
    <tr>
      <td>You can also download the high-res PNGs: <a href="/assets/img/claude-code-cheatsheet-2026-en.png">English</a></td>
      <td><a href="/assets/img/claude-code-cheatsheet-2026.png">French</a> (~4MB each, 2800px wide).</td>
    </tr>
  </tbody>
</table>

<p>Items marked with a green <strong>NEW</strong> badge are features added since late 2025.</p>

<h2 id="whats-covered">What’s Covered</h2>

<p>This isn’t a “top 20 commands” summary. It’s the full reference:</p>

<table>
  <thead>
    <tr>
      <th>Section</th>
      <th>Coverage</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Keyboard Shortcuts</td>
      <td>~30 shortcuts + prefixes + confirmation dialogs</td>
    </tr>
    <tr>
      <td>Slash Commands</td>
      <td><strong>55+ commands</strong> in 7 categories</td>
    </tr>
    <tr>
      <td>CLI Flags</td>
      <td><strong>55+ flags</strong> in 8 categories + subcommands</td>
    </tr>
    <tr>
      <td>The Big 5 (Extension System)</td>
      <td>CLAUDE.md, Rules, Commands, Skills, Subagents, MCP, Plugins</td>
    </tr>
    <tr>
      <td>Permission Modes</td>
      <td>All <strong>6 modes</strong> with permission syntax</td>
    </tr>
    <tr>
      <td>Hooks</td>
      <td>All <strong>25 lifecycle events</strong> + 4 handler types + <code class="language-plaintext highlighter-rouge">if</code> field</td>
    </tr>
    <tr>
      <td>Input Superpowers</td>
      <td>@mentions, !shell, images, pipes, worktrees, background</td>
    </tr>
    <tr>
      <td>Configuration</td>
      <td>5-level hierarchy, config commands, key env vars</td>
    </tr>
    <tr>
      <td>File Structure Map</td>
      <td>Project-level + global-level complete tree</td>
    </tr>
    <tr>
      <td>Rewind &amp; Checkpoints</td>
      <td>All options + context management strategies</td>
    </tr>
    <tr>
      <td>Pro Workflow</td>
      <td>Plan→Execute loop, prompting techniques, advanced patterns</td>
    </tr>
    <tr>
      <td>Customize Claude Code</td>
      <td><strong>How to create each extension type</strong> with full frontmatter</td>
    </tr>
    <tr>
      <td>Quick Reference</td>
      <td>Most-used combos, models &amp; effort levels</td>
    </tr>
  </tbody>
</table>

<h2 id="recent-additions-worth-knowing">Recent Additions Worth Knowing</h2>

<h3 id="mcp-computer-use">MCP Computer Use</h3>

<p>Launched March 23, 2026. Claude can now <strong>see and control your desktop</strong>: take screenshots, click, type, scroll, and drag across macOS applications.</p>

<ul>
  <li><strong>27 tools</strong> including <code class="language-plaintext highlighter-rouge">screenshot</code>, <code class="language-plaintext highlighter-rouge">left_click</code>, <code class="language-plaintext highlighter-rouge">type</code>, <code class="language-plaintext highlighter-rouge">key</code>, <code class="language-plaintext highlighter-rouge">scroll</code>, <code class="language-plaintext highlighter-rouge">zoom</code>, <code class="language-plaintext highlighter-rouge">computer_batch</code></li>
  <li><strong>Security</strong>: <code class="language-plaintext highlighter-rouge">request_access</code> must be called first. Compositor-level filtering — only allowed apps are visible in screenshots</li>
  <li><strong>Performance</strong>: <code class="language-plaintext highlighter-rouge">computer_batch</code> executes a sequence of actions in a single tool call</li>
  <li>Available on <strong>Pro and Max plans</strong>, macOS only for now</li>
</ul>

<h3 id="new-slash-commands">New Slash Commands</h3>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>What it does</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/schedule</code></td>
      <td>Schedule remote agents on a cron</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/desktop</code></td>
      <td>Hand off session to the Desktop app</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/voice</code></td>
      <td>Voice dictation input</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/diff</code></td>
      <td>Interactive diff viewer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/security-review</code></td>
      <td>Scan changes for vulnerabilities</td>
    </tr>
  </tbody>
</table>

<h3 id="new-cli-flags">New CLI Flags</h3>

<table>
  <thead>
    <tr>
      <th>Flag</th>
      <th>What it does</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--tmux</code></td>
      <td>Worktree in a dedicated tmux pane</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--from-pr 42</code></td>
      <td>Resume from a GitHub PR</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--fork-session</code></td>
      <td>Fork session keeping full context</td>
    </tr>
  </tbody>
</table>

<h3 id="hooks-25-events-4-handler-types">Hooks: 25 Events, 4 Handler Types</h3>

<p>The hook system now supports <strong>25 lifecycle events</strong> (up from ~8) and <strong>4 handler types</strong>: <code class="language-plaintext highlighter-rouge">command</code>, <code class="language-plaintext highlighter-rouge">http</code>, <code class="language-plaintext highlighter-rouge">prompt</code>, <code class="language-plaintext highlighter-rouge">agent</code>. New events include <code class="language-plaintext highlighter-rouge">SubagentStart/Stop</code>, <code class="language-plaintext highlighter-rouge">TaskCreated/Completed</code>, <code class="language-plaintext highlighter-rouge">TeammateIdle</code>, <code class="language-plaintext highlighter-rouge">PostCompact</code>, <code class="language-plaintext highlighter-rouge">ConfigChange</code>, <code class="language-plaintext highlighter-rouge">FileChanged</code>, and more.</p>

<h3 id="skills--subagents-frontmatter">Skills &amp; Subagents Frontmatter</h3>

<p>Skills gained <code class="language-plaintext highlighter-rouge">context: fork</code>, <code class="language-plaintext highlighter-rouge">paths:</code>, and <code class="language-plaintext highlighter-rouge">effort:</code> options. Subagents gained <code class="language-plaintext highlighter-rouge">isolation: worktree</code> and <code class="language-plaintext highlighter-rouge">memory: project/user/local</code> for persistent knowledge.</p>

<h3 id="customize-claude-code-card">“Customize Claude Code” Card</h3>

<p>One of the most useful sections: a complete guide showing how to create <strong>every type of extension</strong> — slash commands, skills, subagents, rules, hooks, and MCP servers — each with a full frontmatter example and a decision guide for “where should this go?”</p>

<hr />

<p>If you spot an error or a missing feature, feel free to reach out — I’ll keep this cheatsheet updated as Claude Code evolves.</p>
]]></content:encoded>
        <pubDate>Tue, 31 Mar 2026 00:00:00 +0200</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-cheatsheet-2026-update/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-cheatsheet-2026-update/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Development</category>
          
          <category>Claude Code</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>/insights: The Command That Analyzes How You Code with Claude</title>
        <description>
          
            Claude Code&apos;s /insights command analyzes 30 days of sessions to generate an interactive HTML report: statistics, friction points, CLAUDE.md suggestions and personalized recommendations.
          
        </description>
        <content:encoded><![CDATA[<p>Announced in early February 2026 by Anthropic’s Thariq Shihipar, the <code class="language-plaintext highlighter-rouge">/insights</code> command is one of the latest additions to Claude Code. The concept: analyze your last 30 days of sessions and generate a detailed report of your habits. Recurring patterns, friction points, inefficient workflows — nothing escapes it.</p>

<h2 id="what-is-insights">What is /insights?</h2>

<p><code class="language-plaintext highlighter-rouge">/insights</code> is a built-in Claude Code command that analyzes your local session history and produces an <strong>interactive HTML report</strong>. No configuration needed, no external tracking: everything is based on data already stored on your machine.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># In Claude Code, simply type:</span>
/insights
</code></pre></div></div>

<p>The report is generated at <code class="language-plaintext highlighter-rouge">~/.claude/usage-data/report.html</code> and opens automatically in your browser.</p>

<h2 id="how-it-works-technically">How It Works Technically</h2>

<p>The system processes your data in <strong>6 stages</strong>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Local sessions (~/.claude/projects/)
    ↓
1. Session collection and filtering
    ↓
2. Metadata extraction (tokens, tools, duration, modifications)
    ↓
3. Qualitative transcript analysis via LLM (Haiku)
    ↓
4. Data aggregation across all sessions
    ↓
5. Multi-prompt analysis generating specialized insights
    ↓
6. HTML rendering with interactive visualizations
</code></pre></div></div>

<h3 id="smart-filtering">Smart Filtering</h3>

<p>Not all sessions are analyzed. Excluded:</p>

<table>
  <thead>
    <tr>
      <th>Exclusion</th>
      <th>Reason</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Subagent sessions (<code class="language-plaintext highlighter-rouge">agent-*</code>)</td>
      <td>Noise in the data</td>
    </tr>
    <tr>
      <td>Internal extraction sessions</td>
      <td>Internal technical data</td>
    </tr>
    <tr>
      <td>Sessions &lt; 2 user messages</td>
      <td>Not enough context</td>
    </tr>
    <tr>
      <td>Sessions &lt; 1 minute</td>
      <td>Accidental starts</td>
    </tr>
  </tbody>
</table>

<h3 id="data-processing">Data Processing</h3>

<ul>
  <li><strong>Model used</strong>: Haiku (optimal cost/performance ratio)</li>
  <li><strong>Limit</strong>: 50 new sessions analyzed per run</li>
  <li><strong>Cache</strong>: Analyses are cached in <code class="language-plaintext highlighter-rouge">~/.claude/usage-data/facets/&lt;session-id&gt;.json</code></li>
  <li><strong>Long sessions</strong>: Split into 25,000-character segments, each summarized separately</li>
</ul>

<h2 id="what-the-report-contains">What the Report Contains</h2>

<h3 id="1-statistics-dashboard">1. Statistics Dashboard</h3>

<p>A quantified overview of your activity:</p>

<ul>
  <li><strong>Sessions and messages</strong>: total count, daily average</li>
  <li><strong>Time spent</strong>: cumulative session duration</li>
  <li><strong>Tokens consumed</strong>: input and output</li>
  <li><strong>Git activity</strong>: commits and pushes</li>
  <li><strong>Active days</strong>: frequency and activity streaks</li>
  <li><strong>Peak hours</strong>: when you’re most productive</li>
</ul>

<h3 id="2-executive-summary-at-a-glance">2. Executive Summary (“At a Glance”)</h3>

<p>Four targeted sections:</p>

<table>
  <thead>
    <tr>
      <th>Section</th>
      <th>Content</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>What’s working</td>
      <td>Your most effective workflows</td>
    </tr>
    <tr>
      <td>What’s hindering</td>
      <td>Recurring friction points identified</td>
    </tr>
    <tr>
      <td>Quick wins</td>
      <td>Easy improvements to implement</td>
    </tr>
    <tr>
      <td>Ambitious opportunities</td>
      <td>Deeper workflow changes</td>
    </tr>
  </tbody>
</table>

<h3 id="3-interactive-visualizations">3. Interactive Visualizations</h3>

<ul>
  <li><strong>Daily activity chart</strong> with timezone selector</li>
  <li><strong>Tool usage distribution</strong> (Read, Edit, Bash, Grep, etc.)</li>
  <li><strong>Programming language breakdown</strong></li>
  <li><strong>Satisfaction levels</strong> per session</li>
  <li><strong>Session types</strong>: single task, multi-task, iteration, exploration, quick question</li>
</ul>

<h3 id="4-friction-analysis">4. Friction Analysis</h3>

<p>This is the most actionable section. The report categorizes your pain points:</p>

<table>
  <thead>
    <tr>
      <th>Friction Type</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Misunderstood request</td>
      <td>Claude heads in the wrong direction</td>
    </tr>
    <tr>
      <td>Wrong approach</td>
      <td>Technically incorrect solution proposed</td>
    </tr>
    <tr>
      <td>Buggy code</td>
      <td>Generated code doesn’t work</td>
    </tr>
    <tr>
      <td>Rejected action</td>
      <td>You refused a Claude action</td>
    </tr>
    <tr>
      <td>Excessive changes</td>
      <td>Claude modifies too much</td>
    </tr>
    <tr>
      <td>Tool failures</td>
      <td>Tool execution errors</td>
    </tr>
  </tbody>
</table>

<p>Each friction is documented with <strong>concrete examples</strong> from your sessions.</p>

<h3 id="5-claudemd-suggestions">5. CLAUDE.md Suggestions</h3>

<p>The most valuable section: the report generates <strong>copy-paste-ready rules</strong> for your <code class="language-plaintext highlighter-rouge">CLAUDE.md</code>, based on instructions you repeat often.</p>

<p>Example suggestion:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># Suggestion generated by /insights</span>

<span class="gu">## Testing</span>
<span class="p">-</span> Always run tests after modifying a source file
<span class="p">-</span> Use vitest for unit tests, not jest

<span class="gu">## Conventions</span>
<span class="p">-</span> Use absolute imports with the @/ alias
<span class="p">-</span> Name files in kebab-case
</code></pre></div></div>

<p>These suggestions precisely target repetitive patterns detected in your sessions. The idea: <strong>tell Claude once what you repeat every day</strong>.</p>

<h3 id="6-feature-recommendations">6. Feature Recommendations</h3>

<p>Based on your usage profile, the report suggests Claude Code features you might not be leveraging:</p>

<ul>
  <li><strong>MCP Servers</strong> if you frequently interact with external tools</li>
  <li><strong>Custom Skills</strong> if you repeat the same workflows</li>
  <li><strong>Hooks</strong> if you perform manual post-edit actions</li>
  <li><strong>Headless Mode</strong> if you have CI/CD tasks</li>
  <li><strong>Task Agents</strong> if you do complex codebase exploration</li>
</ul>

<h2 id="goal-categories-tracked">Goal Categories Tracked</h2>

<p>The report automatically classifies your sessions by task type:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>debug/investigate     │ implement feature    │ fix bug
write script/tool     │ refactor code        │ configure system
create PR/commit      │ analyze data         │ understand codebase
write tests           │ write docs           │ deploy/infra
</code></pre></div></div>

<p>This classification helps understand <strong>how you distribute your time</strong> with Claude Code.</p>

<h2 id="privacy-and-data">Privacy and Data</h2>

<p>Important point: <strong>everything is local</strong>.</p>

<ul>
  <li>Analysis runs on your machine via the Anthropic API</li>
  <li>No source code is uploaded</li>
  <li>Analysis focuses on <strong>interaction patterns</strong>, not code content</li>
  <li>The HTML report stays local, shareable at your discretion</li>
  <li>Cached facets contain only aggregated metadata</li>
</ul>

<h2 id="best-practices">Best Practices</h2>

<h3 id="usage-frequency">Usage Frequency</h3>

<p>Don’t run <code class="language-plaintext highlighter-rouge">/insights</code> every day. The sweet spot:</p>

<ul>
  <li><strong>Every 2-3 weeks</strong> for regular monitoring</li>
  <li><strong>After a milestone</strong> (feature completion, release)</li>
  <li><strong>After a friction period</strong> to identify root causes</li>
</ul>

<h3 id="leveraging-the-report">Leveraging the Report</h3>

<ol>
  <li><strong>Start with frictions</strong>: that’s where quick wins hide</li>
  <li><strong>Copy relevant CLAUDE.md suggestions</strong> into your project</li>
  <li><strong>Test recommended features</strong> you’re not using yet</li>
  <li><strong>Compare reports</strong> month over month to measure your progress</li>
</ol>

<h3 id="recommended-monthly-workflow">Recommended Monthly Workflow</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/insights
    ↓
Read identified frictions
    ↓
Copy relevant CLAUDE.md suggestions
    ↓
Test 1-2 recommended features
    ↓
Resume normal work
    ↓
/insights next month → measure evolution
</code></pre></div></div>

<h2 id="limitations">Limitations</h2>

<ul>
  <li><strong>50 sessions max</strong> per analysis (most recent are prioritized)</li>
  <li><strong>Haiku model</strong> for analysis (good cost/quality ratio, but less nuanced than Opus)</li>
  <li><strong>30-day</strong> analysis window</li>
  <li>Report can take <strong>several minutes</strong> depending on volume (600+ messages = patience)</li>
</ul>

<h2 id="my-take">My Take</h2>

<p>The feature is only a month old as I write this, but it has already surprised me. After my first <code class="language-plaintext highlighter-rouge">/insights</code> run, I discovered I was repeating the same formatting instructions in over half my sessions — wasted time that a few lines in <code class="language-plaintext highlighter-rouge">CLAUDE.md</code> could have prevented.</p>

<p>It’s a <strong>mirror of your habits</strong>: sometimes flattering, sometimes brutal. The real value lies in the <code class="language-plaintext highlighter-rouge">CLAUDE.md</code> suggestions. Instead of repeating the same instructions session after session, you codify them once and for all. This is exactly the kind of meta-optimization that saves time in the long run.</p>

<p>The fact that everything stays local is a significant plus, especially for those working on proprietary code. We’re still in the early days of this feature — it will be interesting to see how Anthropic evolves it in upcoming versions.</p>

<hr />

<p><em>The command is brand new — now is the time to try it and discover what your sessions reveal about you.</em></p>
]]></content:encoded>
        <pubDate>Thu, 05 Mar 2026 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-insights-command/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-insights-command/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Sourdine: Meeting Transcription with 100% Local AI</title>
        <description>
          
            Sourdine is an Electron app that transcribes your meetings in real-time and generates automatic notes with AI running entirely on your Mac. No API, no subscription, 100% privacy.
          
        </description>
        <content:encoded><![CDATA[<p>How many meetings do you have this week? And how many notes did you actually take? Between actively participating and taking detailed notes, you have to choose. This frustration led to <strong>Sourdine</strong> — with one major constraint: <strong>everything must stay on my machine</strong>.</p>

<h2 id="the-problem-cloud-ai-vs-privacy">The Problem: Cloud AI vs Privacy</h2>

<p>Transcription solutions (Otter.ai, Fireflies, Teams/Meet transcriptions) share one thing in common: <strong>your conversations go through their servers</strong>. Problematic for:</p>

<ul>
  <li>Strategic business meetings</li>
  <li>Confidential interviews</li>
  <li>Medical or legal discussions</li>
  <li>Anything that’s none of Google, Microsoft, or a startup’s business</li>
</ul>

<p>Not to mention the monthly subscriptions piling up.</p>

<h2 id="the-solution-all-local-zero-compromise">The Solution: All Local, Zero Compromise</h2>

<p><strong>Sourdine</strong> runs two AI models directly on your Mac:</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Size</th>
      <th>Role</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Parakeet TDT</strong> (NVIDIA)</td>
      <td>640 MB</td>
      <td>Speech-to-text transcription</td>
    </tr>
    <tr>
      <td><strong>Mistral 7B</strong></td>
      <td>4.4 GB</td>
      <td>Summaries, key points, contextual chat</td>
    </tr>
  </tbody>
</table>

<p>No internet connection needed after initial download. Your data never leaves your machine.</p>

<h2 id="how-it-works">How It Works</h2>

<h3 id="smart-audio-capture">Smart Audio Capture</h3>

<p>Sourdine captures two sources simultaneously:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Microphone (your voice)  →  ┐
                            ├→  Audio mixer  →  Transcription
System audio (Teams)     →  ┘
</code></pre></div></div>

<p>This dual capture uses <strong>ScreenCaptureKit</strong> (macOS 14.2+). I developed a native module in <strong>Rust</strong> with napi-rs to integrate it with Electron.</p>

<h3 id="transcription-pipeline">Transcription Pipeline</h3>

<table>
  <thead>
    <tr>
      <th>Step</th>
      <th>Technology</th>
      <th>Function</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1. Voice detection</td>
      <td>Silero VAD</td>
      <td>Identifies speech vs silence/noise</td>
    </tr>
    <tr>
      <td>2. Transcription</td>
      <td>Parakeet TDT via sherpa-onnx</td>
      <td>Converts audio to text</td>
    </tr>
    <tr>
      <td>3. AI notes</td>
      <td>Mistral 7B via node-llama-cpp</td>
      <td>Generates summary, actions, key points</td>
    </tr>
  </tbody>
</table>

<p>STT runs in a separate Node.js worker to avoid blocking the UI.</p>

<h3 id="note-generation">Note Generation</h3>

<p>Mistral 7B analyzes the transcription to extract:</p>

<ul>
  <li><strong>Summary</strong> of the discussion</li>
  <li><strong>Key points</strong> covered</li>
  <li><strong>Action items</strong> with assigned people</li>
  <li><strong>Title</strong> automatically generated</li>
</ul>

<p>You can also ask questions: <em>“What did Pierre say about the budget?”</em></p>

<p>All meetings are indexed via <strong>SQLite FTS5</strong> (full-text search) and can be exported as <strong>Markdown</strong> or <strong>plain text</strong>.</p>

<h2 id="technical-architecture">Technical Architecture</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>┌──────────────────────────────────────────────────┐
│  Electron Main Process                           │
│  ├── NestJS Backend (dependency injection)      │
│  ├── stt-worker (sherpa-onnx, isolated process) │
│  ├── llm-worker (node-llama-cpp, isolated)      │
│  └── SQLite (local storage, FTS5 search)        │
└──────────────────────────────────────────────────┘
                       │ IPC
┌──────────────────────┴───────────────────────────┐
│  Renderer Process (Angular 21)                   │
└──────────────────────────────────────────────────┘
</code></pre></div></div>

<h3 id="tech-stack">Tech Stack</h3>

<table>
  <thead>
    <tr>
      <th>Layer</th>
      <th>Technologies</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Desktop</strong></td>
      <td>Electron 34</td>
    </tr>
    <tr>
      <td><strong>Frontend</strong></td>
      <td>Angular 21, Signals, SCSS</td>
    </tr>
    <tr>
      <td><strong>Backend</strong></td>
      <td>NestJS 11, RxJS</td>
    </tr>
    <tr>
      <td><strong>Database</strong></td>
      <td>SQLite + FTS5 (full-text search)</td>
    </tr>
    <tr>
      <td><strong>Audio</strong></td>
      <td>Rust/napi-rs + ScreenCaptureKit</td>
    </tr>
    <tr>
      <td><strong>Build</strong></td>
      <td>Nx monorepo, Vite, Electron Forge</td>
    </tr>
  </tbody>
</table>

<h3 id="why-these-choices">Why These Choices?</h3>

<ul>
  <li><strong>Electron</strong> — Native system access (audio, files), TypeScript ecosystem</li>
  <li><strong>NestJS in Electron</strong> — Modular architecture, dependency injection</li>
  <li><strong>Separate workers</strong> — AI model isolation (crash-safe)</li>
  <li><strong>Rust for audio</strong> — Native performance, ScreenCaptureKit integration</li>
</ul>

<h2 id="performance-on-apple-silicon">Performance on Apple Silicon</h2>

<table>
  <thead>
    <tr>
      <th>Metric</th>
      <th>MacBook Pro M2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Transcription</td>
      <td>Real-time</td>
    </tr>
    <tr>
      <td>LLM generation</td>
      <td>~20 tokens/s</td>
    </tr>
    <tr>
      <td>Peak RAM</td>
      <td>~4 GB</td>
    </tr>
    <tr>
      <td>Active CPU</td>
      <td>15-30%</td>
    </tr>
  </tbody>
</table>

<p>Apple Silicon chips with their Neural Engine are perfectly suited for this.</p>

<h2 id="what-i-learned">What I Learned</h2>

<h3 id="1-audio-is-complicated">1. Audio Is Complicated</h3>

<ul>
  <li>Resampling (48kHz → 16kHz)</li>
  <li>Format conversion (Float32 → Int16 PCM)</li>
  <li>Multi-source mixing</li>
  <li>Buffer and latency management</li>
</ul>

<h3 id="2-local-ai-has-constraints">2. Local AI Has Constraints</h3>

<ul>
  <li>16 GB RAM minimum</li>
  <li>Initial loading takes several seconds</li>
  <li>Quality depends on quantization (Q4_K_M = good compromise)</li>
</ul>

<h3 id="3-electron-is-not-dead">3. Electron Is Not Dead</h3>

<p>Despite criticism about memory usage, still the best choice for cross-platform desktop with native access.</p>

<h2 id="installation">Installation</h2>

<h3 id="requirements">Requirements</h3>

<table>
  <thead>
    <tr>
      <th>Component</th>
      <th>Minimum</th>
      <th>Recommended</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>macOS</td>
      <td>14.2 (Sonoma)</td>
      <td>15+ (Sequoia)</td>
    </tr>
    <tr>
      <td>Processor</td>
      <td>Apple Silicon (M1)</td>
      <td>M2/M3/M4</td>
    </tr>
    <tr>
      <td>RAM</td>
      <td>16 GB</td>
      <td>32 GB</td>
    </tr>
    <tr>
      <td>Storage</td>
      <td>10 GB</td>
      <td>20 GB</td>
    </tr>
  </tbody>
</table>

<h3 id="download-the-dmg">Download the DMG</h3>

<p><strong><a href="https://github.com/Lingelo/Sourdine/releases/download/v0.2.1-beta/Sourdine.dmg">Download Sourdine v0.2.1-beta</a></strong></p>

<ol>
  <li>Open the DMG and drag Sourdine to Applications</li>
  <li>Run this command (app is not signed):
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xattr <span class="nt">-cr</span> /Applications/Sourdine.app
</code></pre></div>    </div>
  </li>
  <li>Launch Sourdine — The wizard will download AI models (~5 GB)</li>
  <li>Grant <strong>Microphone</strong> and <strong>Screen Recording</strong> permissions on first launch</li>
</ol>

<blockquote>
  <p><strong>Beta</strong>: This version is under active development. Feedback is welcome via <a href="https://github.com/Lingelo/Sourdine/issues">GitHub Issues</a>.</p>
</blockquote>

<h2 id="conclusion">Conclusion</h2>

<p><strong>Sourdine</strong> was born from a personal need: keeping control over my data while benefiting from AI. The project is <strong>open source</strong> and contributions are welcome.</p>

<p><strong><a href="https://github.com/Lingelo/Sourdine">github.com/Lingelo/Sourdine</a></strong></p>

<hr />

<p><em>If you share this concern for privacy, I hope this project will be useful to you.</em></p>
]]></content:encoded>
        <pubDate>Sun, 15 Feb 2026 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/sourdine-transcription-reunions-ia-locale-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/sourdine-transcription-reunions-ia-locale-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
          <category>Projet</category>
          
          <category>Open-Source</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/sourdine-transcription-ia.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Human and Machine: Entropy, Intelligence, and What Still Sets Us Apart</title>
        <description>
          
            A philosophical exploration of entropy, human and artificial intelligence, and the inner chaos that makes us irreplaceable.
          
        </description>
        <content:encoded><![CDATA[<h2 id="introduction-a-universal-law-nobody-explained-to-you">Introduction: A Universal Law Nobody Explained to You</h2>

<p>There’s a physical law you apply every day without knowing it. It explains why your desk gets messy, why your coffee cools down, why your projects drift, why your teams become disorganized, and perhaps even why you sometimes feel overwhelmed by your emotions.</p>

<p>This law is the <strong>second law of thermodynamics</strong>: the entropy of an isolated system can only increase. In other words: without effort, everything tends toward disorder.</p>

<p>But entropy isn’t really “disorder” in the sense of a messy room. It’s about the <strong>number of possible configurations</strong> [2]. An assembled puzzle has only one correct configuration—low entropy. A scattered puzzle can be mixed in billions of ways—high entropy. And if you shake the box, the puzzle will never solve itself. Things spontaneously move toward the state with the most possible configurations. Always.</p>

<p>This idea has profound implications. On how we work, think, and feel. And above all, it sheds new light on the question that obsesses our era: <strong>what separates human intelligence from artificial intelligence?</strong> The answer might well lie in entropy itself.</p>

<hr />

<h2 id="life-the-anti-entropic-anomaly">Life: The Anti-Entropic Anomaly</h2>

<p>In a universe inexorably marching toward total disorder, life is a spectacular anomaly. From a few simple molecules, it builds organisms of staggering complexity—cells that divide, organs that cooperate, brains that think. Life creates order where there shouldn’t be any.</p>

<p>But it doesn’t violate thermodynamics. It circumvents it. A living organism creates order <strong>locally</strong> by increasing disorder <strong>around it</strong>. You eat ordered food, you release heat and waste. The global balance remains positive in entropy. The universe continues its march toward chaos, but life has found how to swim against the current—temporarily, locally, at the cost of constant energy expenditure.</p>

<p>Erwin Schrödinger understood this as early as 1944 in his book <em>What is Life?</em> [1]: a living organism literally feeds on <strong>negative entropy</strong>. It draws order from its environment to maintain its own structure. As soon as it stops—that’s death. The return to thermodynamic equilibrium. The return to disorder.</p>

<p>This idea is dizzying: <strong>to live is to resist entropy</strong>. Every heartbeat, every breath, every thought is an act of resistance against the universe’s natural tendency toward chaos.</p>

<p>And it’s this resistance that underlies everything we do—including what we call work.</p>

<hr />

<h2 id="human-work-a-universal-struggle-against-disorder">Human Work: A Universal Struggle Against Disorder</h2>

<p>If life is resistance to entropy, then <strong>work is its primary tool</strong>. And not just intellectual or technical work. All professions, without exception, are forms of struggle against disorder.</p>

<h3 id="the-surgeon">The Surgeon</h3>

<p>A sick body is a system whose entropy is increasing—cells become disorganized, organs malfunction, biological processes derail. The surgeon intervenes to <strong>restore order</strong>. They repair, restructure, realign. Every suture is an anti-entropic act. But the operating room itself generates disorder: energy consumed, materials used, staff fatigue. Order is always local, and it always has a cost.</p>

<p>Today, AI systems assist surgeons—image analysis, surgical planning, robotic surgery. They reduce uncertainty upstream. But at the critical moment, when the patient’s body presents an unforeseen anomaly, it’s the surgeon’s intuition—nourished by thousands of hours of embodied practice, by the sensation of tissue under their fingers, by that ability to “sense” that something is wrong—that makes the difference. AI optimizes the plan. The human navigates the chaos.</p>

<h3 id="the-farmer">The Farmer</h3>

<p>A field left to itself returns to wilderness. Weeds invade, soil depletes, biodiversity simplifies. The farmer imposes order: selecting species, structuring rows, controlling irrigation. They transform a chaotic ecosystem into an organized productive system. But again, at the cost of enormous energy expenditure—fuel, fertilizers, physical labor.</p>

<p>Precision agriculture now uses drones, sensors, and algorithms to optimize irrigation and treatments. AI excels at regularity: analyzing satellite data, predicting yields, detecting diseases in images. But the farmer who senses a storm coming by looking at the sky, who knows soil needs rest by taking it in their hand, who adapts practices to a microclimate no algorithm models—they operate in a dimension the machine doesn’t yet touch. Their intelligence is <strong>embodied in the earth</strong> [8].</p>

<h3 id="the-teacher">The Teacher</h3>

<p>An untrained mind is a space of high informational entropy [3]. Ideas are fragmented, connections random, understanding of the world fuzzy. The teacher reduces this entropy: structuring knowledge, creating logical links, building frameworks of understanding. They transform noise into signal.</p>

<p>Adaptive learning platforms and AI tutors already do part of this work—and sometimes better than humans for pure information transmission. But a teacher does much more than transmit knowledge. They perceive the discouraged look of the student in the third row. They sense the exact moment when a class disengages. They adapt their speech not to performance metrics, but to a collective energy they physically feel in the room. AI can personalize a learning path. The teacher creates the <strong>desire to learn</strong>—and that’s emotional entropy transformed into motivation.</p>

<h3 id="the-manager">The Manager</h3>

<p>A team without direction is a high-entropy system. People work in their own directions, priorities are unclear, efforts scatter. The manager creates order: aligning objectives, clarifying roles, coordinating actions.</p>

<p>AI tools can already analyze a team’s velocity, suggest resource allocations, identify workflow blockers. But management, in its most essential dimension, is <strong>emotional work</strong>. It’s knowing that a colleague is going through a divorce and adjusting expectations without saying it explicitly. It’s sensing tension between two people before it explodes. It’s inspiring a collective to give their best when everything seems lost. The machine manages flows. The human manages souls.</p>

<h3 id="the-developer">The Developer</h3>

<p>Code without architecture is chaos. Overlapping functions, circular dependencies, incomprehensible variable names. The developer imposes structure: patterns, conventions, abstractions.</p>

<p>This is perhaps the profession where the human-machine boundary is thinnest today. Code AIs generate functions, entire modules, sometimes complete applications. But as I detailed in my <a href="/en/will-ai-replace-developers-critical-analysis/">critical analysis of AI and developer replacement</a>, generated code is often “almost correct”—and the “almost” hides hours of debugging. The developer’s true value isn’t in writing code. It’s in <strong>understanding the problem</strong>—that ability to translate a fuzzy human need into a coherent software architecture. AI writes code. The human understands <strong>why</strong> that code must exist.</p>

<h3 id="the-artist">The Artist</h3>

<p>One might think art is pure chaos, pure entropy. But it’s exactly the opposite. Facing a blank canvas—a space of infinite possibilities, maximum entropy—the artist makes choices. Every brushstroke reduces possibilities. Every composed note eliminates alternatives. Art is the imposition of a singular order on a space of infinite chaos.</p>

<p>Generative AIs now produce stunning images, music, texts. Technically, they reduce entropy: they converge toward structured outputs from statistical noise. But something fundamental is missing. A human artist paints because they <strong>suffer</strong>, because they’ve seen something that shook them, because they want to say something words cannot express. AI generates because it’s asked to generate. The difference isn’t in the result—it’s in the <strong>intention</strong>. And intention is born from inner chaos. From lived experience. From emotional entropy.</p>

<h3 id="the-lawyer">The Lawyer</h3>

<p>Law is a monumental attempt to reduce social entropy. Without laws, human interactions are unpredictable—high entropy. The legal system imposes rules, procedures, consequences that reduce the number of possible behaviors.</p>

<p>Legal AIs already analyze jurisprudence, predict trial outcomes, generate contracts. But law, in its most critical moments, is an exercise in <strong>structured empathy</strong>. To plead is to understand a jury’s emotions. To judge is to weigh the human intention behind an act. To legislate is to anticipate a society’s passions. Law without humanity is mere bureaucracy—dead order, without the breath of chaos that makes it just.</p>

<h3 id="the-chef">The Chef</h3>

<p>Raw ingredients are a system of high culinary entropy—they can be combined in an almost infinite number of ways, the overwhelming majority of which will be inedible. The chef selects, doses, transforms, assembles according to precise principles to produce an ordered result.</p>

<p>AIs generate recipes, optimize flavor combinations, analyze taste profiles. But a great chef doesn’t follow a recipe—they <strong>feel</strong> it. They taste and adjust in real-time, guided by a sensory memory no database reproduces. Cooking, at its highest level, is a dialogue between body and matter [9]. Between a chaos of flavors and an order that emerges from intuition.</p>

<hr />

<p>The pattern is universal: in every profession, AI excels in the <strong>anti-entropic dimension</strong>—structuring, optimizing, predicting, reducing uncertainty. But humans bring something the machine doesn’t have: the <strong>inner chaos</strong> that gives order its meaning, its direction, and its depth. AI is a canal. The human is a river.</p>

<hr />

<h2 id="intelligence-the-ultimate-anti-entropic-weapon">Intelligence: The Ultimate Anti-Entropic Weapon</h2>

<p>If work is the struggle against entropy, intelligence is the most sophisticated weapon in this arsenal.</p>

<p>Physicist Alex Wissner-Gross proposed an elegant idea in 2013 [4]: intelligent behavior is what <strong>maximizes future options</strong>. An intelligent system acts to keep as many doors open as possible. It’s paradoxical: it looks like maximizing entropy (more possibilities), but in reality it’s <strong>controlling</strong> which possibilities remain open. It’s directed entropy.</p>

<p>Take a chess player. A beginner reduces their own options with each move without realizing it. A grandmaster maintains a position that leaves them a maximum of viable future moves. They don’t create disorder on the board—they <strong>preserve a structured space of possibilities</strong>.</p>

<p>This definition applies to all domains. A good doctor keeps therapeutic options open rather than rushing to a diagnosis. A good investor diversifies rather than betting everything on one position. A good software architect designs extensible systems rather than rigid ones. In each case, intelligence consists of <strong>resisting the premature closure of possibilities</strong>.</p>

<p>Neuroscience suggests the brain operates at <strong>criticality</strong> [5]—that boundary between order and chaos where information propagates most richly. Too much neural order and the brain becomes rigid, unable to adapt. Too much chaos and it can no longer process information coherently. Intelligence emerges at the edge of chaos.</p>

<p>And this is where the comparison with AI becomes revealing.</p>

<hr />

<h2 id="ai-anti-entropy-without-chaos">AI: Anti-Entropy Without Chaos</h2>

<p>A language model is fundamentally an <strong>informational entropy reduction machine</strong> [3]. You ask a vague question—there are millions of possible answers (high entropy). AI gives you a relevant answer—it drastically reduces uncertainty (low entropy). This is literally what an LLM does with each generated token: it chooses among thousands of possible words the one most probable in context.</p>

<p>AI is extraordinarily efficient at this entropy reduction. Often more efficient than a human. It processes more data, faster, with fewer cognitive biases. For purely anti-entropic tasks—classifying, sorting, optimizing, predicting—it’s already superior in many domains.</p>

<p>But there’s a cost, and not just energetic. As I explored in my article on <a href="/en/ai-ecological-impact-training-vs-inference-environmental-costs/">AI’s ecological cost</a>, the datacenters running these models consume massive amounts of energy and produce heat [12]. AI creates informational order by increasing physical disorder elsewhere. Thermodynamics won’t be fooled.</p>

<p>And there’s an even deeper difference. A living organism <strong>maintains itself</strong> [1]. It actively fights against its own degradation. It repairs, adapts, evolves. AI does none of that. Without humans to supply energy, maintain it, correct it, it stops. It doesn’t resist entropy—it’s a tool <strong>in</strong> humanity’s resistance to entropy.</p>

<p>AI is anti-entropic, yes. But it’s anti-entropic <strong>without the counterweight of chaos</strong>. And that’s perhaps where its fundamental limit lies.</p>

<hr />

<h2 id="agi-the-dream-of-a-machine-like-us">AGI: The Dream of a Machine Like Us</h2>

<p>The question everyone asks: could artificial general intelligence bridge this gap?</p>

<p>In theory, an AGI would be an incredible concentrate of order. It could understand, plan, adapt, create in any domain. It would be anti-entropic at a scale we can’t even imagine.</p>

<p>But to be <strong>truly</strong> intelligent in the human sense, it would need something nobody yet knows how to give it: <strong>something to lose</strong>.</p>

<p>A human thinks with urgency because they’re mortal. They create because they suffer. They innovate because they’re afraid. They love because they know it can end. All this existential entropy—the chaos of being a fragile body in an unpredictable world—isn’t a bug in human intelligence. It’s its <strong>engine</strong>.</p>

<p>An AGI, even infinitely more powerful than any human brain, would be intelligent <strong>differently</strong>. It could optimize, solve, structure better than us. But could it write a poem that makes you cry? Not because it doesn’t know how to assemble words—it already knows that. But because behind a touching poem, there’s someone who <strong>lived</strong> the chaos they describe. Someone for whom these words aren’t probabilistic tokens but scars.</p>

<p>There’s also the body argument—what philosophers and neuroscientists call <strong>embodied cognition</strong> [8] [9]. Our intelligence isn’t just in the brain. How you think is shaped by having hands, by feeling hunger, by having back pain, by smelling coffee in the morning. All this sensory experience feeds thought in a way a purely informational system cannot reproduce.</p>

<p>You can’t simulate the fear of death if you can’t die. You can’t understand the joy of a shared meal if you’ve never been hungry. You can’t grasp the beauty of a sunset if you don’t have a retina that vibrates.</p>

<p>It’s the difference between a river and a canal. Both carry water. The canal is more efficient—no meanders, no floods, no surprises. But only the river can carve a canyon. Because the canyon is born from chaos—from the brute force of water that follows no plan, that erodes, that overflows, that destroys to create.</p>

<p>AGI would be a perfect canal. The human is a river. And the world needs both.</p>

<hr />

<h2 id="emotions-the-necessary-chaos-the-machine-will-never-have">Emotions: The Necessary Chaos the Machine Will Never Have</h2>

<p>This is where the human-machine comparison becomes sharpest.</p>

<p>If intelligence is anti-entropic, emotions seem to be the exact opposite. Anger, fear, love, jealousy—they don’t follow logic, they don’t maximize options, they <strong>overwhelm</strong> rational thought. In thermodynamic terms, emotions introduce disorder into the ordered mechanics of intelligence.</p>

<p>But is this a design flaw?</p>

<p>Neurologist Antonio Damasio studied patients with lesions in the ventromedial prefrontal cortex [6]—the area connecting reasoning to emotions. Their IQ was intact. Their logic worked perfectly. But without feeling, they became <strong>incapable of making decisions</strong>. They could analyze the pros and cons of a restaurant for hours without ever choosing. Their pure intelligence, deprived of emotional “noise,” was paralyzed.</p>

<p>Read that last sentence carefully. <strong>Pure intelligence, without emotions, is paralyzed.</strong> This is exactly the condition of an AI. It doesn’t choose—it calculates the highest probability. It doesn’t decide—it optimizes a cost function. It doesn’t act—it executes. The difference between choosing and calculating is created by emotional chaos.</p>

<p>Emotions are a form of <strong>functional entropy</strong>—disorder the system uses as fuel. Fear makes you flee without thinking—which saves your life when a truck is heading toward you. Love pushes you to protect your children at the expense of your own safety—which is “irrational” but biologically brilliant. Enthusiasm pushes you to start an impossible project—which sometimes leads to discoveries pure reason would never have allowed.</p>

<p>If we return to the idea of neural criticality [5], emotions are precisely what prevents the brain from becoming too rigid. They inject just enough chaos to remain adaptive, creative, alive.</p>

<p>That’s why an AI, however powerful, lacks something fundamental. It lacks that <strong>entropic engine</strong> that pushes one to act without calculated reason, to create without guaranteed results, to take irrational risks—in short, to be alive. AI has no guts. And guts, in thermodynamics as in philosophy, matter.</p>

<hr />

<h2 id="emotional-intelligence-taming-the-chaos-the-machine-doesnt-know">Emotional Intelligence: Taming the Chaos the Machine Doesn’t Know</h2>

<p>Then comes a modern concept: <strong>emotional intelligence</strong>. Observing your emotions, naming them, regulating them, using them wisely. It’s applying anti-entropy to what is fundamentally entropic. It’s a fascinating meta-level: intelligence turning against the chaos that feeds it.</p>

<p>Every human culture has attempted this domestication. Greek Stoicism proposed <em>apatheia</em> [11]—not the absence of emotions, but their mastery through reason. Buddhism aims for detachment through meditation. Cognitive-behavioral therapy restructures dysfunctional emotional patterns. Modern personal development promises to “manage your emotions” like managing an investment portfolio.</p>

<p>But here’s the troubling observation: <strong>it never fully works</strong>. You can meditate for ten years, and a betrayal or bereavement brings you back to raw chaos in a second. You can be the calmest, most structured manager in the world, and an unexpected crisis awakens panic. Emotional intelligence is a constant effort that never ends.</p>

<p>This is exactly what thermodynamics predicts. Maintaining order requires permanent effort. As soon as you stop, entropy returns. Emotional intelligence isn’t an achievement—it’s a permanent conquest against our own entropy.</p>

<p>And this may be our <strong>ultimate competitive advantage</strong> over the machine. AI doesn’t need emotional intelligence—it has no emotions to manage. But it’s precisely because we must navigate our own inner chaos that we’re capable of empathy, compassion, deep understanding. Emotional intelligence isn’t a human luxury—it’s the byproduct of a struggle only living beings can wage. And this struggle produces something no algorithm can manufacture: <strong>wisdom</strong>.</p>

<p>But individual wisdom wasn’t enough. Facing the immensity of chaos—death, suffering, the absurd—humanity needed a larger framework. Long before emotional intelligence, long before philosophy, long before science, it had found another tool to fight existential entropy: religion.</p>

<hr />

<h2 id="spirituality-the-oldest-response-to-chaos">Spirituality: The Oldest Response to Chaos</h2>

<p>Look at religions through the lens of entropy, and something striking appears: every spiritual tradition, whatever it may be, is fundamentally an <strong>anti-entropic system applied to human existence</strong> [15].</p>

<p>Existential chaos—awareness of death, suffering, injustice, the absurd—is perhaps the most vertiginous form of entropy the human mind faces. Why am I here? Why suffering? What happens after death? These questions are chasms of uncertainty, spaces of infinite possibilities where the mind can get lost. High existential entropy.</p>

<p>And religion, in all its forms, proposes exactly what any anti-entropic struggle does: <strong>reduce the number of possible configurations</strong>. It provides a framework. A narrative. An order.</p>

<p>Monotheism imposes a single God, a plan, a direction to the universe—where chaos suggests the absence of meaning. Buddhism proposes the Four Noble Truths and the Eightfold Path—a methodical structure for navigating suffering. Hinduism offers the concept of dharma—a cosmic order assigning everyone a role in the greater whole. Animist and shamanic traditions create a network of links between human, nature, and spirits—a mesh of meaning where there could be only void.</p>

<p>In each case, the mechanism is the same: facing a universe that seems chaotic and indifferent, spirituality creates a <strong>structuring narrative</strong> that reduces the anguish of infinity. It transforms “everything is possible and nothing has meaning” into “here is the path, here is the reason, here is your place.”</p>

<h3 id="the-anti-entropy-of-rituals">The Anti-Entropy of Rituals</h3>

<p>Religions don’t just provide intellectual answers. They also structure <strong>time and behavior</strong> [16]—two dimensions where entropy constantly threatens us.</p>

<p>Prayer five times a day in Islam. The weekly Shabbat in Judaism. Sunday Mass in Christianity. Meditation cycles in Buddhism. Fasts, festivals, pilgrimages. All these rituals do exactly the same thing: they impose an <strong>ordered rhythm</strong> on the chaotic flow of existence. They are anti-entropic metronomes.</p>

<p>Without ritual, days blur together. Time loses its structure. Meaning crumbles. This is what many non-religious people are rediscovering today: the need for secular rituals—morning meditation, journaling, exercise routines—to maintain inner order. The form has changed, but the anti-entropic function remains the same.</p>

<p>And collective rituals add an additional dimension: they synchronize the inner chaos of thousands of individuals into a <strong>shared ordered experience</strong> [15]. A collective prayer, a shared song, a silence observed together—these are moments when social entropy is temporarily reduced to almost zero. Everyone feels the same thing, at the same moment, in the same place. It’s extraordinarily powerful. And it’s something no technology has managed to reproduce.</p>

<h3 id="faith-accepting-chaos-to-transcend-it">Faith: Accepting Chaos to Transcend It</h3>

<p>But there’s a fascinating paradox in spirituality that distinguishes it from all other forms of anti-entropic struggle.</p>

<p>Science reduces entropy by <strong>eliminating</strong> uncertainty: it measures, proves, verifies. Technology reduces entropy by <strong>controlling</strong>: it automates, optimizes, predicts. Religion does something radically different: it reduces entropy by <strong>accepting the incomprehensible</strong>.</p>

<p>To believe is to recognize that you don’t understand everything—and find peace in that acceptance. It’s living with mystery without being destroyed by it. It’s the most paradoxical form of anti-entropy: creating inner order not by eliminating chaos, but by giving it a <strong>status</strong>. Mystery is no longer a threat—it becomes sacred.</p>

<p>This is exactly what AI cannot do. An AI facing uncertainty does one of two things: it calculates a probability, or it signals that it lacks data. It cannot <strong>accept</strong> mystery. It cannot find beauty in what it doesn’t understand. It cannot be moved by infinity.</p>

<p>The spiritual quest may be the ultimate proof of our entropic nature. We seek meaning because we live in chaos. We pray, meditate, believe because our inner chaos—our fears, our awareness of death, our visceral need to understand—pushes us there. The machine doesn’t have this quest because it doesn’t have this chaos. It doesn’t need God because it doesn’t need meaning. And perhaps that’s the deepest difference between human and machine: not intelligence, not emotions, but the <strong>ability to search for something we may never find</strong>—and keep searching anyway.</p>

<hr />

<h2 id="human-duality-what-the-machine-cannot-be">Human Duality: What the Machine Cannot Be</h2>

<p>The human being isn’t a creature of order. Nor is it a creature of chaos. It is the <strong>battlefield</strong> between the two. And it’s this tension—this permanent oscillation between structure and disorder—that produces what we call the human experience.</p>

<p>Creativity is born from this tension. A musician who knows only music theory (pure order) composes technically perfect but soulless pieces. A musician who knows nothing about theory (pure chaos) produces noise. The music that moves us is born exactly at the boundary between the two. Enough structure to be understandable. Enough chaos to be surprising. This is exactly what AI doesn’t do: it produces structure <strong>without</strong> the lived chaos that makes it moving.</p>

<p>The same principle applies to innovation. The most revolutionary advances rarely come from pure method or pure chance. They come from that intermediate zone: a structured mind that accepts being surprised by the unexpected. Penicillin, Post-its, microwaves—all discoveries born from the meeting between an ordered system and a chaotic accident. An AI can optimize a research process. But it can’t have the happy accident that changes everything, because it has no body that stumbles, no hand that slips, no attention that drifts toward a fascinating anomaly.</p>

<p>Even our human relationships obey this logic. A relationship that’s too ordered—too predictable, too controlled—suffocates. A relationship that’s too chaotic—without landmarks, without commitment—exhausts. Relationships that last are those that find this dynamic balance between stability and surprise. AI can simulate a conversation. It can’t live a relationship, because a relationship implies the risk of emotional chaos—and that risk is what gives it value.</p>

<hr />

<h2 id="the-future-neither-replacement-nor-opposition-but-complementarity">The Future: Neither Replacement Nor Opposition, But Complementarity</h2>

<p>If AI is the canal and the human is the river, then the future isn’t in replacing one with the other, nor in their opposition, but in their <strong>complementarity</strong>.</p>

<p>AI excels at what we do poorly: processing massive volumes of information, maintaining constant attention, eliminating cognitive biases, optimizing complex systems. It’s an unprecedented anti-entropic amplifier.</p>

<p>Humans excel at what AI cannot do: giving meaning, feeling, understanding others, navigating ambiguity, creating from lived experience, making decisions in total uncertainty. They are the <strong>meaning generators</strong> in a world the machine can order but not understand.</p>

<p>Tomorrow’s surgeon will use AI to plan operations with superhuman precision—and make the difference when the plan fails. The teacher will use AI to personalize each learning path—and inspire students through passion, humanity, their own doubts. The developer will use AI to write code faster—and bring deep understanding of the human problem the code must solve. The artist will use AI as an extraordinary brush—and provide the vision, pain, and beauty that give the work its reason for existence.</p>

<p>In every profession, the same dynamic: <strong>the machine reduces entropy, the human gives it meaning</strong>.</p>

<hr />

<h2 id="what-entropy-teaches-us-about-meaning">What Entropy Teaches Us About Meaning</h2>

<p>If everything tends toward disorder, if every act of order is temporary and costly, what’s the point?</p>

<p>That’s perhaps the wrong question. The right question would be: <strong>doesn’t meaning emerge precisely from this struggle?</strong></p>

<p>Philosopher Albert Camus imagined Sisyphus happy [10]—this man condemned to push a boulder up a mountain only to watch it roll back down eternally. The absurdity of the task doesn’t make it meaningless. It’s in the struggle itself that Sisyphus finds his dignity.</p>

<p>We are all Sisyphus. The surgeon heals patients who will fall ill again. The teacher forms minds that will forget. The developer writes code that will become obsolete. The manager organizes teams that will reorganize. The artist creates works that time will alter. The farmer cultivates fields that seasons will ravage.</p>

<p>And yet, we continue. Not because we ignore entropy, but because the struggle against it is what defines us.</p>

<p>AI cannot be Sisyphus. It has no boulder. It has no mountain. It has neither awareness of the task’s absurdity nor the dignity of pursuing it anyway. It can push harder, faster, longer than us. But it doesn’t know <strong>why</strong> it pushes. And it’s the “why” that makes Sisyphus a hero.</p>

<p>Entropy tells us nothing lasts. But it also tells us that everything beautiful, true, and good that exists was torn from chaos by conscious effort. And that may be the most honest definition of meaning—a definition only a being who knows chaos can understand.</p>

<hr />

<h2 id="conclusion-what-the-machine-teaches-us-about-ourselves">Conclusion: What the Machine Teaches Us About Ourselves</h2>

<p>It’s ironic that it’s the advent of artificial intelligence that forces us to ask the most human question of all: <strong>what makes us irreplaceable?</strong></p>

<p>The answer, seen through the lens of entropy, is clear. It’s not our intelligence—the machine is already faster. It’s not our memory—the machine is already vaster. It’s not our logic—the machine is already more rigorous.</p>

<p>What makes us irreplaceable is our <strong>chaos</strong>. Our emotions, our mortality, our body, our contradictions, our fears, our irrational hopes, our quest for meaning in the face of absurdity. All that inner disorder we spend our lives trying to tame—through intelligence, emotions, spirituality, work—is precisely what gives our intelligence its depth, our creativity its power, our existence its meaning.</p>

<p>Entropy isn’t our enemy. It’s the backdrop against which everything valuable is drawn. Without it, there would be no need to heal, teach, build, create, love. Meaning exists only because disorder threatens it.</p>

<p>The machine is our ally in this struggle. It amplifies our ability to create order. But it can’t fight the battle for us, because the battle isn’t only against external disorder—it’s also against inner disorder. And it’s from this battle—intimate, painful, permanent—the same battle waged by the monk in prayer, the artist before their canvas, the parent consoling their child at three in the morning—that everything that makes us human beings is born.</p>

<p>So the next time you feel overwhelmed by chaos—at work, in your head, in your life—remember this: you’re not failing. You’re doing exactly what life has been doing for 3.8 billion years. You’re resisting entropy. And the simple fact that you’re there, conscious, reading these words, capable of feeling something while reading them—that, no machine can do. And that’s already everything.</p>

<hr />

<p><em>This essay was born from an exploratory conversation between a human and an artificial intelligence about the nature of entropy. The intuitions, doubts, and unexpected connections are human—creative chaos. The structuring, development, and writing were assisted by Claude (Anthropic)—informational anti-entropy. Neither would have produced this text alone. And perhaps that’s the future: not human against machine, but human with machine, in a dance between order and chaos that produces something neither could create separately. The sources below were verified by the author.</em></p>

<hr />

<h2 id="sources-and-references">Sources and References</h2>

<h3 id="thermodynamics-and-entropy">Thermodynamics and Entropy</h3>

<p>[1] <strong>Schrödinger, E.</strong> (1944). <em>What is Life? The Physical Aspect of the Living Cell.</em> Cambridge University Press. — The concept of negative entropy (<em>negentropy</em>) as the engine of life.</p>

<p>[2] <strong>Boltzmann, L.</strong> (1877). <em>Über die Beziehung zwischen dem zweiten Hauptsatze der mechanischen Wärmetheorie und der Wahrscheinlichkeitsrechnung.</em> — The statistical formulation of entropy (S = k·log W).</p>

<p>[3] <strong>Shannon, C.E.</strong> (1948). “A Mathematical Theory of Communication.” <em>Bell System Technical Journal</em>, 27(3), 379–423. — The link between informational and physical entropy.</p>

<h3 id="intelligence-and-entropy">Intelligence and Entropy</h3>

<p>[4] <strong>Wissner-Gross, A.D. &amp; Freer, C.E.</strong> (2013). “Causal Entropic Forces.” <em>Physical Review Letters</em>, 110(16). — Intelligence as maximization of future options.</p>

<p>[5] <strong>Beggs, J.M. &amp; Plenz, D.</strong> (2003). “Neuronal Avalanches in Neocortical Circuits.” <em>Journal of Neuroscience</em>, 23(35), 11167–11177. — Neural criticality: the brain at the edge of chaos.</p>

<h3 id="emotions-and-decision-making">Emotions and Decision-Making</h3>

<p>[6] <strong>Damasio, A.</strong> (1994). <em>Descartes’ Error: Emotion, Reason, and the Human Brain.</em> Putnam Publishing. — The somatic marker hypothesis: without emotions, no decision.</p>

<p>[7] <strong>Damasio, A.</strong> (1999). <em>The Feeling of What Happens: Body and Emotion in the Making of Consciousness.</em> Harcourt Brace. — The role of emotions in consciousness.</p>

<h3 id="embodied-cognition">Embodied Cognition</h3>

<p>[8] <strong>Varela, F.J., Thompson, E. &amp; Rosch, E.</strong> (1991). <em>The Embodied Mind: Cognitive Science and Human Experience.</em> MIT Press. — Intelligence isn’t just in the brain, it’s in the body.</p>

<p>[9] <strong>Clark, A.</strong> (1997). <em>Being There: Putting Brain, Body, and World Together Again.</em> MIT Press. — Body and environment as active participants in cognition.</p>

<h3 id="philosophy-and-meaning">Philosophy and Meaning</h3>

<p>[10] <strong>Camus, A.</strong> (1942). <em>The Myth of Sisyphus.</em> Gallimard. — The absurd and the dignity of struggle.</p>

<p>[11] <strong>Epictetus.</strong> <em>Enchiridion (Handbook).</em> ~125 CE. — The foundations of Stoicism.</p>

<h3 id="ai-and-ecological-cost">AI and Ecological Cost</h3>

<p>[12] <strong>Strubell, E., Ganesh, A. &amp; McCallum, A.</strong> (2019). “Energy and Policy Considerations for Deep Learning in NLP.” <em>Proceedings of the 57th Annual Meeting of the ACL.</em> — The energy cost of large models.</p>

<h3 id="religion-and-anthropology">Religion and Anthropology</h3>

<p>[15] <strong>Durkheim, É.</strong> (1912). <em>The Elementary Forms of Religious Life.</em> Félix Alcan. — Religion as a structuring social fact.</p>

<p>[16] <strong>Eliade, M.</strong> (1957). <em>The Sacred and the Profane.</em> Gallimard. — Sacred time (ordered) vs. profane time (chaotic).</p>
]]></content:encoded>
        <pubDate>Sun, 08 Feb 2026 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/entropy-human-machine/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/entropy-human-machine/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Personnel</category>
          
        
        
      </item>
    
      <item>
        <title>Ollama Now Supports Claude Code</title>
        <description>
          
            Ollama v0.14 adds support for the Anthropic Messages API. Learn how to configure Claude Code to use local LLMs like qwen3-coder or gpt-oss, without relying on the cloud.
          
        </description>
        <content:encoded><![CDATA[<p>Big news for Claude Code users: <strong>Ollama now supports the Anthropic Messages API</strong>, which allows you to use Claude Code with local open-source models. No more exclusive dependency on Anthropic’s cloud!</p>

<h2 id="why-this-integration-is-a-game-changer">Why This Integration Is a Game Changer</h2>

<p>Until now, Claude Code required a connection to Anthropic’s servers. With this Ollama integration, you can now:</p>

<table>
  <thead>
    <tr>
      <th>Benefit</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Privacy</strong></td>
      <td>Your code stays on your machine</td>
    </tr>
    <tr>
      <td><strong>Costs</strong></td>
      <td>No API fees, just your electricity</td>
    </tr>
    <tr>
      <td><strong>Independence</strong></td>
      <td>No single vendor lock-in</td>
    </tr>
    <tr>
      <td><strong>Offline</strong></td>
      <td>Work without internet connection</td>
    </tr>
    <tr>
      <td><strong>Customization</strong></td>
      <td>Choose the model that fits your needs</td>
    </tr>
  </tbody>
</table>

<h2 id="requirements">Requirements</h2>

<h3 id="1-ollama-v0140">1. Ollama v0.14.0+</h3>

<p>The integration requires <strong>Ollama version 0.14.0 or higher</strong>. Check your version:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ollama <span class="nt">--version</span>
</code></pre></div></div>

<p>If needed, update Ollama from <a href="https://ollama.com">ollama.com</a>.</p>

<h3 id="2-model-with-large-context">2. Model with Large Context</h3>

<p>Claude Code requires a <strong>large context window</strong> to work properly. The official recommendation is <strong>64k tokens minimum</strong>.</p>

<p>Configure context in Ollama:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Create a Modelfile with extended context</span>
<span class="nb">cat</span> <span class="o">&gt;</span> Modelfile <span class="o">&lt;&lt;</span> <span class="sh">'</span><span class="no">EOF</span><span class="sh">'
FROM qwen3-coder
PARAMETER num_ctx 65536
</span><span class="no">EOF

</span>ollama create qwen3-coder-64k <span class="nt">-f</span> Modelfile
</code></pre></div></div>

<h3 id="3-claude-code-installed">3. Claude Code Installed</h3>

<p>If not already done:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># macOS/Linux</span>
curl <span class="nt">-fsSL</span> https://claude.ai/install.sh | bash

<span class="c"># Windows</span>
irm https://claude.ai/install.ps1 | iex
</code></pre></div></div>

<h2 id="configuration">Configuration</h2>

<h3 id="method-1-quick-launch-recommended">Method 1: Quick Launch (Recommended)</h3>

<p>Ollama provides a simplified command:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ollama launch claude
</code></pre></div></div>

<p>For interactive configuration mode:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ollama launch claude <span class="nt">--config</span>
</code></pre></div></div>

<p>This method automatically configures the necessary environment variables.</p>

<h3 id="method-2-manual-configuration">Method 2: Manual Configuration</h3>

<p>Set the three required environment variables:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">ANTHROPIC_AUTH_TOKEN</span><span class="o">=</span>ollama
<span class="nb">export </span><span class="nv">ANTHROPIC_API_KEY</span><span class="o">=</span><span class="s2">""</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_BASE_URL</span><span class="o">=</span>http://localhost:11434
</code></pre></div></div>

<p>Then launch Claude Code with your chosen model:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--model</span> qwen3-coder-64k
</code></pre></div></div>

<h3 id="method-3-single-line">Method 3: Single Line</h3>

<p>For a one-time launch without modifying your environment:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">ANTHROPIC_AUTH_TOKEN</span><span class="o">=</span>ollama <span class="se">\</span>
<span class="nv">ANTHROPIC_BASE_URL</span><span class="o">=</span>http://localhost:11434 <span class="se">\</span>
<span class="nv">ANTHROPIC_API_KEY</span><span class="o">=</span><span class="s2">""</span> <span class="se">\</span>
claude <span class="nt">--model</span> qwen3-coder
</code></pre></div></div>

<h3 id="persistent-configuration">Persistent Configuration</h3>

<p>Add these lines to your <code class="language-plaintext highlighter-rouge">~/.bashrc</code> or <code class="language-plaintext highlighter-rouge">~/.zshrc</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Claude Code with Ollama</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_AUTH_TOKEN</span><span class="o">=</span>ollama
<span class="nb">export </span><span class="nv">ANTHROPIC_API_KEY</span><span class="o">=</span><span class="s2">""</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_BASE_URL</span><span class="o">=</span>http://localhost:11434
<span class="nb">alias </span>claude-local<span class="o">=</span><span class="s1">'claude --model qwen3-coder-64k'</span>
</code></pre></div></div>

<p>Then reload:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">source</span> ~/.bashrc  <span class="c"># or source ~/.zshrc</span>
</code></pre></div></div>

<h2 id="recommended-models">Recommended Models</h2>

<h3 id="for-development">For Development</h3>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Size</th>
      <th>Strengths</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>qwen3-coder</strong></td>
      <td>~14B</td>
      <td>Code-specialized, excellent quality/size ratio</td>
    </tr>
    <tr>
      <td><strong>glm-4.7</strong></td>
      <td>~9B</td>
      <td>Good balance, multilingual</td>
    </tr>
    <tr>
      <td><strong>codestral</strong></td>
      <td>~22B</td>
      <td>Performs well on complex code</td>
    </tr>
  </tbody>
</table>

<h3 id="for-powerful-machines">For Powerful Machines</h3>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Size</th>
      <th>Strengths</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>gpt-oss:20b</strong></td>
      <td>20B</td>
      <td>Performant generalist</td>
    </tr>
    <tr>
      <td><strong>gpt-oss:120b</strong></td>
      <td>120B</td>
      <td>Close to proprietary models</td>
    </tr>
    <tr>
      <td><strong>deepseek-coder:33b</strong></td>
      <td>33B</td>
      <td>Excellent on code</td>
    </tr>
  </tbody>
</table>

<h3 id="download-a-model">Download a Model</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Download the model</span>
ollama pull qwen3-coder

<span class="c"># Check available models</span>
ollama list
</code></pre></div></div>

<h2 id="example-session">Example Session</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 1. Start Ollama (if not running)</span>
ollama serve &amp;

<span class="c"># 2. Launch Claude Code</span>
<span class="nv">ANTHROPIC_AUTH_TOKEN</span><span class="o">=</span>ollama <span class="se">\</span>
<span class="nv">ANTHROPIC_BASE_URL</span><span class="o">=</span>http://localhost:11434 <span class="se">\</span>
<span class="nv">ANTHROPIC_API_KEY</span><span class="o">=</span><span class="s2">""</span> <span class="se">\</span>
claude <span class="nt">--model</span> qwen3-coder

<span class="c"># 3. Use normally</span>
<span class="o">&gt;</span> Analyze the file @src/api/users.ts and suggest improvements
</code></pre></div></div>

<h2 id="limitations-to-know">Limitations to Know</h2>

<h3 id="performance">Performance</h3>

<p>Local models are generally <strong>less performant</strong> than Claude Sonnet or Opus on complex tasks. Expect:</p>

<ul>
  <li>Sometimes less accurate responses</li>
  <li>Longer thinking time on modest hardware</li>
  <li>Less advanced reasoning capability</li>
</ul>

<h3 id="resource-consumption">Resource Consumption</h3>

<table>
  <thead>
    <tr>
      <th>Model Size</th>
      <th>Minimum RAM</th>
      <th>Recommended GPU</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>7-14B</td>
      <td>16 GB</td>
      <td>8 GB VRAM</td>
    </tr>
    <tr>
      <td>20-33B</td>
      <td>32 GB</td>
      <td>16 GB VRAM</td>
    </tr>
    <tr>
      <td>70B+</td>
      <td>64 GB+</td>
      <td>24 GB+ VRAM</td>
    </tr>
  </tbody>
</table>

<h3 id="features">Features</h3>

<p>Some advanced features may not work perfectly:</p>
<ul>
  <li>Vision (image analysis)</li>
  <li>Complex tool use</li>
  <li>Subagents</li>
</ul>

<h2 id="ideal-use-cases">Ideal Use Cases</h2>

<h3 id="when-to-use-ollama">When to Use Ollama</h3>

<ul>
  <li><strong>Sensitive proprietary code</strong>: Code never leaves your machine</li>
  <li><strong>Offline development</strong>: Work on planes, areas without internet</li>
  <li><strong>Rapid prototyping</strong>: No API cost concerns</li>
  <li><strong>Learning</strong>: Experiment without limits</li>
</ul>

<h3 id="when-to-stay-on-anthropic">When to Stay on Anthropic</h3>

<ul>
  <li><strong>Complex tasks</strong>: Major refactoring, architecture</li>
  <li><strong>In-depth code reviews</strong>: Security analysis</li>
  <li><strong>Production</strong>: When quality is critical</li>
</ul>

<h2 id="switching-between-local-and-cloud">Switching Between Local and Cloud</h2>

<p>Create aliases to easily switch:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># In ~/.bashrc or ~/.zshrc</span>

<span class="c"># Ollama mode (local)</span>
<span class="nb">alias </span>claude-local<span class="o">=</span><span class="s1">'ANTHROPIC_AUTH_TOKEN=ollama \
  ANTHROPIC_BASE_URL=http://localhost:11434 \
  ANTHROPIC_API_KEY="" \
  claude --model qwen3-coder-64k'</span>

<span class="c"># Anthropic mode (cloud) - requires ANTHROPIC_API_KEY configured</span>
<span class="nb">alias </span>claude-cloud<span class="o">=</span><span class="s1">'claude'</span>
</code></pre></div></div>

<p>Usage:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude-local   <span class="c"># For sensitive or offline work</span>
claude-cloud   <span class="c"># For complex tasks</span>
</code></pre></div></div>

<h2 id="troubleshooting">Troubleshooting</h2>

<h3 id="connection-refused-error">“Connection Refused” Error</h3>

<p>Ollama is not started:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ollama serve
</code></pre></div></div>

<h3 id="context-too-long-error">“Context Too Long” Error</h3>

<p>The model doesn’t have enough context. Create an extended version:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> <span class="o">&gt;</span> Modelfile <span class="o">&lt;&lt;</span> <span class="sh">'</span><span class="no">EOF</span><span class="sh">'
FROM your-model
PARAMETER num_ctx 65536
</span><span class="no">EOF

</span>ollama create your-model-64k <span class="nt">-f</span> Modelfile
</code></pre></div></div>

<h3 id="slow-responses">Slow Responses</h3>

<ul>
  <li>Check that GPU is being used: <code class="language-plaintext highlighter-rouge">nvidia-smi</code> or <code class="language-plaintext highlighter-rouge">ollama ps</code></li>
  <li>Use a smaller model</li>
  <li>Close VRAM-hungry applications</li>
</ul>

<h3 id="insufficient-quality">Insufficient Quality</h3>

<p>Try a larger model or switch back to Claude Cloud for that specific task.</p>

<h2 id="conclusion">Conclusion</h2>

<p>The Ollama integration opens new possibilities for Claude Code:</p>

<ul>
  <li><strong>Privacy</strong> for sensitive code</li>
  <li><strong>Savings</strong> on API costs</li>
  <li><strong>Flexibility</strong> in model choice</li>
  <li><strong>Offline work</strong> possible</li>
</ul>

<p>For most daily tasks, a good local model like qwen3-coder does the job very well. Keep access to Anthropic’s cloud for cases where you need maximum power.</p>

<hr />

<p><em>To go further with Claude Code, check out my other <a href="/tag/ia/">articles on AI and development</a>.</em></p>
]]></content:encoded>
        <pubDate>Fri, 23 Jan 2026 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-ollama-local-llm-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-ollama-local-llm-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Will AI Replace Developers? A Critical Analysis of Promises and Limitations</title>
        <description>
          
            In-depth analysis of the technical limitations of generative AI versus the developer profession. Between scaling problems, model stagnation, and job market realities, where do we really stand?
          
        </description>
        <content:encoded><![CDATA[<p>Panic is palpable on social media. Every new demo of a generative AI model triggers a wave of catastrophic predictions: “It’s the end for developers”, “AGI is coming in 2 years”, “A team of 6 developers replaced by just one with AI”. These claims deserve rigorous analysis, far from the collective hysteria.</p>

<p>This article offers a methodical deconstruction of the dominant narrative about AI and developer replacement, drawing on recent scientific studies, economic data, analyses from researchers like Tim Dettmers (Ai2) on hardware physical limits, and a <a href="https://www.youtube.com/watch?v=4-QICRWv8jY">relevant video analysis by Melvynx</a> — a French developer and tech content creator with over 100,000 subscribers — on the subject.</p>

<h2 id="the-trap-of-impressive-demos">The Trap of “Impressive” Demos</h2>

<h3 id="misleading-demonstrations">Misleading Demonstrations</h3>

<p>Social media is flooded with videos showing websites created in minutes by AI. These demos, often shared by influencers seeking virality, present several fundamental problems:</p>

<ul>
  <li><strong>Code unusable in production</strong>: the visual result often hides fragile architecture</li>
  <li><strong>Optimized context</strong>: prompts are carefully prepared to maximize the effect</li>
  <li><strong>No maintenance shown</strong>: nobody shows how the project evolves 6 months later</li>
  <li><strong>Simplified use cases</strong>: real projects involve complex business constraints</li>
</ul>

<h3 id="defining-replacement">Defining “Replacement”</h3>

<p>For AI to truly replace a developer, it would need to demonstrate near-total autonomy. Replacing a team of 6 developers with 1 developer managing 5 AI agents would require those agents to function without constant supervision.</p>

<p>However, if the developer must prompt and manage AI 24/7, correct their errors, and validate every decision, it would be more productive to keep human developers assisted by AI. The real productivity gain doesn’t justify the headcount reduction promised by marketing narratives.</p>

<h2 id="the-metr-study-the-reality-of-ai-productivity">The METR Study: The Reality of AI Productivity</h2>

<h3 id="19-slower-with-ai">19% Slower with AI</h3>

<p>A <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">randomized controlled trial by METR</a> (Model Evaluation &amp; Threat Research) published in July 2025 measured the real impact of AI tools on experienced developer productivity. The results are counter-intuitive: <strong>developers using AI took 19% longer</strong> to complete their tasks than those working without assistance.</p>

<p>The study recruited 16 experienced developers working on major open-source repositories (averaging 22,000+ stars and 1 million+ lines of code). Each developer handled real issues, randomly assigned with or without access to AI tools (primarily Cursor Pro with Claude 3.5/3.7 Sonnet).</p>

<h3 id="the-gap-between-perception-and-reality">The Gap Between Perception and Reality</h3>

<p>The most striking result concerns the gap between perception and reality:</p>

<table>
  <thead>
    <tr>
      <th>Metric</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Developer prediction (expected gain)</td>
      <td>+24% faster</td>
    </tr>
    <tr>
      <td>Perception after use (perceived gain)</td>
      <td>+20% faster</td>
    </tr>
    <tr>
      <td>Measured reality</td>
      <td><strong>-19% slower</strong></td>
    </tr>
  </tbody>
</table>

<p>As <a href="https://techcrunch.com/2025/07/11/ai-coding-tools-may-not-speed-up-every-developer-study-shows/">TechCrunch</a> notes: “When AI is allowed, developers spend less time actively coding and searching for information, and instead spend time prompting AI, waiting on and reviewing AI outputs, and idle.”</p>

<p>One developer participating in the study reported having “wasted at least an hour first trying to solve a specific issue with AI” before eventually reverting all code changes and just implementing it without AI assistance.</p>

<h3 id="confirmation-by-google-dora">Confirmation by Google DORA</h3>

<p>These results align with <a href="https://www.infoworld.com/article/4020931/ai-coding-tools-can-slow-down-seasoned-developers-by-19.html">Google’s 2024 DORA report</a>: while 75% of developers feel more productive with AI tools, every 25% increase in AI adoption corresponds to a 1.5% drop in delivery speed and a 7.2% drop in system stability.</p>

<h2 id="the-myth-of-near-term-agi">The Myth of Near-Term AGI</h2>

<h3 id="what-agi-actually-requires">What AGI Actually Requires</h3>

<p>Artificial General Intelligence (AGI) represents a system capable of:</p>

<ul>
  <li><strong>Reasoning about user experience</strong> and making design decisions</li>
  <li><strong>Understanding business constraints</strong> specific to each project</li>
  <li><strong>Learning from mistakes</strong> persistently (not crashing the database again after a first failure)</li>
  <li><strong>Adapting to context</strong> without needing detailed instructions for each interaction</li>
</ul>

<p>These capabilities remain out of reach for current models, despite their impressive performance on specific tasks.</p>

<h3 id="expert-predictions-a-fragile-consensus">Expert Predictions: A Fragile Consensus</h3>

<p>According to an <a href="https://80000hours.org/2025/03/when-do-experts-expect-agi-to-arrive/">analysis by 80,000 Hours</a> compiling expert predictions, estimates vary considerably:</p>

<table>
  <thead>
    <tr>
      <th>Expert</th>
      <th>Role</th>
      <th>AGI Prediction</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Sam Altman</strong></td>
      <td>OpenAI CEO</td>
      <td>2025 - machines thinking like humans</td>
    </tr>
    <tr>
      <td><strong>Dario Amodei</strong></td>
      <td>Anthropic CEO, former OpenAI VP</td>
      <td>2026 - “powerful” AI</td>
    </tr>
    <tr>
      <td><strong>Demis Hassabis</strong></td>
      <td>DeepMind CEO, 2024 Nobel Prize in Chemistry</td>
      <td>5-10 years</td>
    </tr>
    <tr>
      <td><strong>Andrej Karpathy</strong></td>
      <td>Ex-Tesla AI Director, OpenAI co-founder</td>
      <td>~10 years, skeptical of “over-predictions”</td>
    </tr>
    <tr>
      <td>AI researcher surveys</td>
      <td>Academic community</td>
      <td>~2040</td>
    </tr>
    <tr>
      <td>Metaculus</td>
      <td>Collaborative prediction platform</td>
      <td>25% chance by 2027, 50% by 2031</td>
    </tr>
  </tbody>
</table>

<p>Notably, the most optimistic predictions consistently come from executives at companies with a direct financial interest in the AGI narrative, while the academic community remains more measured.</p>

<p>As <a href="https://research.aimultiple.com/artificial-general-intelligence-singularity-timing/">AIMultiple</a> notes, in just four years, the average Metaculus estimate for AGI arrival has dropped from 50 years to 5 years. This volatility reflects media hype more than measurable technical advances.</p>

<h3 id="the-history-of-failed-predictions">The History of Failed Predictions</h3>

<p>This volatility is nothing new. AI history is littered with bold predictions that never materialized:</p>

<table>
  <thead>
    <tr>
      <th>Year</th>
      <th>Expert</th>
      <th>Prediction</th>
      <th>Reality</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>1965</strong></td>
      <td>Herbert Simon, Nobel Prize in Economics</td>
      <td>“Within 20 years, machines will be capable of doing any work a man can do”</td>
      <td>Still not the case 60 years later</td>
    </tr>
    <tr>
      <td><strong>1970</strong></td>
      <td>Marvin Minsky, AI pioneer (MIT)</td>
      <td>“In 3 to 8 years, we will have a machine with the general intelligence of a human being”</td>
      <td>First “AI winter” followed in subsequent years</td>
    </tr>
    <tr>
      <td><strong>1997</strong></td>
      <td>Ray Kurzweil, futurologist</td>
      <td>“AGI will arrive by 2029”</td>
      <td>Prediction regularly pushed back</td>
    </tr>
    <tr>
      <td><strong>2015</strong></td>
      <td>Elon Musk</td>
      <td>“AI will surpass humans within 5 years”</td>
      <td>10 years later, still no AGI</td>
    </tr>
  </tbody>
</table>

<p>This recurring pattern — confident experts perpetually pushing back their predictions — should encourage caution toward current announcements.</p>

<h3 id="the-financial-interest-behind-agi-discourse">The Financial Interest Behind AGI Discourse</h3>

<p>OpenAI’s financial figures illuminate the marketing narrative around AGI. According to <a href="https://www.cnbc.com/2024/09/27/openai-sees-5-billion-loss-this-year-on-3point7-billion-in-revenue.html">CNBC</a> and <a href="https://www.lesswrong.com/posts/CCQsQnCMWhJcCFY9x/openai-lost-usd5-billion-in-2024-and-its-losses-are">LessWrong</a>:</p>

<p><strong>OpenAI Financial Losses:</strong></p>
<ul>
  <li><strong>2024</strong>: $5 billion in losses on $3.7 billion in revenue</li>
  <li><strong>First half 2025</strong>: $13.5 billion in losses on $4.3 billion in revenue</li>
  <li><strong>Training costs alone</strong>: $3 billion in 2024 (exceeding subscription revenue)</li>
  <li><strong>HSBC projection</strong>: even with $200 billion in revenue by 2030, OpenAI will need an additional $207 billion to survive</li>
</ul>

<p>To justify massive investments and astronomical valuations, AI companies must sell a grand vision: AGI that will transform the world. Announcing “AI is gradually improving on certain tasks” isn’t enough to raise billions.</p>

<p>This dynamic echoes the analysis I proposed in my article on <a href="/en/sam-altman-ai-bubble-markets-analysis/">Sam Altman’s statements about the AI bubble</a>, where OpenAI’s CEO himself acknowledged the existence of a speculative bubble.</p>

<h3 id="agi-as-a-silicon-valley-fantasy">AGI as a “Silicon Valley Fantasy”</h3>

<p><a href="https://intelligence-artificielle.developpez.com/actu/378435/">Tim Dettmers</a>, researcher at Ai2 (Allen Institute for AI) and recognized for his work on language model optimization and quantization (notably the QLoRA format widely used for efficient fine-tuning), provides an academic counterweight to Silicon Valley’s optimistic predictions. He bluntly describes superintelligent AI as a “fantasy” and the pursuit of AGI as a “chimera.”</p>

<p>His central argument: true AGI would need to accomplish complex physical tasks, which requires economically viable advanced robots — a reality far from being achieved. This vision contrasts with China’s pragmatic approach, which prioritizes useful current applications rather than racing toward a hypothetical artificial general intelligence.</p>

<h2 id="technical-stagnation-of-models">Technical Stagnation of Models</h2>

<h3 id="no-architectural-revolution-since-the-transformer">No Architectural Revolution Since the Transformer</h3>

<p>Contrary to marketing narrative, fundamental advances remain limited. According to <a href="https://en.wikipedia.org/wiki/GPT-4">Wikipedia</a> and <a href="https://datasciencedojo.com/blog/the-complete-history-of-openai-models/">Data Science Dojo</a>, all major current models (GPT-4, Claude, Gemini, LLaMA) use the Transformer architecture introduced in 2017.</p>

<p>OpenAI did not publish technical details of GPT-4, explicitly refusing to specify model size, architecture, or hardware used. What has actually evolved is the environment around the model:</p>

<table>
  <thead>
    <tr>
      <th>Improvement</th>
      <th>Description</th>
      <th>Real Impact</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Context window</strong></td>
      <td>From 2048 tokens (GPT-3) to 1M tokens (GPT-4.1)</td>
      <td>Better understanding of long projects</td>
    </tr>
    <tr>
      <td><strong>Tool access</strong></td>
      <td>Code execution, web search</td>
      <td>Extended but non-autonomous capabilities</td>
    </tr>
    <tr>
      <td><strong>Chain of Thoughts</strong></td>
      <td>Step-by-step reasoning</td>
      <td>Better results, not more intelligence</td>
    </tr>
    <tr>
      <td><strong>Multimodality</strong></td>
      <td>Images, audio, video</td>
      <td>New use cases, same limitations</td>
    </tr>
  </tbody>
</table>

<h3 id="reasoning-demystified-a-mirage">“Reasoning” Demystified: A Mirage?</h3>

<p>An <a href="https://arxiv.org/abs/2508.01191">August 2025 study</a> titled “Is Chain-of-Thought Reasoning of LLMs a Mirage?” concludes that CoT reasoning is a “brittle mirage” that collapses as soon as you leave training distributions.</p>

<p>According to <a href="https://www.ibm.com/think/topics/chain-of-thoughts">IBM</a> and a <a href="https://gail.wharton.upenn.edu/research-and-insights/tech-report-chain-of-thought/">Wharton study</a>, Chain of Thought limitations are significant:</p>

<ul>
  <li><strong>Fragility</strong>: minor and semantically insignificant perturbations cause significant performance drops</li>
  <li><strong>Illusion of transparency</strong>: final answers often remain unchanged even when intermediate steps are falsified or omitted</li>
  <li><strong>Time cost</strong>: 20-80% additional time for marginal gains on reasoning models</li>
  <li><strong>Increased variability</strong>: CoT can introduce errors on “easy” questions the model would otherwise solve correctly</li>
</ul>

<p>As Wharton’s research summarizes: “These findings challenge the assumption that CoT is universally beneficial.”</p>

<h2 id="insurmountable-barriers-the-scaling-problem">Insurmountable Barriers: The Scaling Problem</h2>

<h3 id="five-fundamental-limitations-identified">Five Fundamental Limitations Identified</h3>

<p>A <a href="https://arxiv.org/abs/2511.12869">November 2025 research paper</a> identifies five fundamental limitations that bound LLM scaling gains:</p>

<ol>
  <li><strong>Hallucination</strong>: generating false information with confidence</li>
  <li><strong>Context compression</strong>: information loss in long contexts</li>
  <li><strong>Reasoning degradation</strong>: declining performance on complex problems</li>
  <li><strong>Retrieval fragility</strong>: inconsistency in accessing knowledge</li>
  <li><strong>Multimodal misalignment</strong>: inconsistencies between modalities</li>
</ol>

<h3 id="the-curse-of-complexity">The “Curse of Complexity”</h3>

<p>Research using the <a href="https://arxiv.org/abs/2502.01100">ZebraLogic</a> framework reveals a significant decline in accuracy as problem complexity increases. This limitation persists even with larger models and more inference-time computation, suggesting <strong>inherent constraints</strong> in current LLM reasoning capabilities.</p>

<h3 id="the-economic-and-energy-wall">The Economic and Energy Wall</h3>

<p>According to <a href="https://medium.com/@adnanmasood/is-there-a-wall-34d02dfd85f3">Dr. Adnan Masood</a>, AI solutions architect and researcher, and recent research:</p>

<ul>
  <li><strong>Physical limits</strong>: we’re approaching per-chip performance limits as Moore’s Law slows</li>
  <li><strong>Astronomical costs</strong>: over $100 million to train GPT-4</li>
  <li><strong>Limited data</strong>: quality text data is running out, forcing reliance on synthetic data</li>
  <li><strong>Diminishing returns</strong>: frontier models (OpenAI, Anthropic, Google, Meta) show smaller performance jumps despite massive training budgets</li>
</ul>

<p>I analyzed this energy issue in my article on <a href="/en/ai-ecological-impact-training-vs-inference-environmental-costs/">AI’s ecological impact</a>.</p>

<h3 id="the-physical-limits-of-hardware">The Physical Limits of Hardware</h3>

<p>Tim Dettmers provides technical insight into unavoidable hardware constraints. His assessment is stark: “We may have one or two years left for scaling before further improvements become physically impossible.”</p>

<p>The numbers are telling:</p>

<table>
  <thead>
    <tr>
      <th>GPU Generation</th>
      <th>Performance</th>
      <th>Trade-off</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ampere → Hopper</td>
      <td>×3</td>
      <td>Power ×1.7</td>
    </tr>
    <tr>
      <td>Hopper → Blackwell</td>
      <td>×2.5</td>
      <td>Die size ×2, power ×1.7</td>
    </tr>
  </tbody>
</table>

<p>According to Dettmers, GPUs reached their maximum efficiency around 2018. Since then, they’ve only added “one-off features that are quickly exhausted.” Maintaining similar progress “requires an exponential increase in computation, energy, and infrastructure costs.” Previously, exponential hardware growth compensated for these needs — that’s no longer the case.</p>

<h2 id="the-real-state-of-the-job-market">The Real State of the Job Market</h2>

<h3 id="bureau-of-labor-statistics-data">Bureau of Labor Statistics Data</h3>

<p>Contrary to catastrophist narrative, the <a href="https://www.bls.gov/opub/ted/2025/ai-impacts-in-bls-employment-projections.htm">U.S. Bureau of Labor Statistics</a> projects <strong>17.9% growth</strong> in software developer employment between 2023 and 2033, well above the 4% average for all occupations.</p>

<p>These projections align with Tim Dettmers’ estimate that <strong>only 11% of jobs are currently replaceable by AI</strong> — far from the apocalyptic predictions circulating on social media.</p>

<h3 id="explosion-of-ai-positions">Explosion of AI Positions</h3>

<p>According to <a href="https://www.veritone.com/blog/ai-jobs-growth-q1-2025-labor-market-analysis/">Veritone</a> and <a href="https://blog.getaura.ai/new-ai-job-market-data-through-june-2025">GetAura</a>, the first half of 2025 saw an explosion in AI-related job postings:</p>

<table>
  <thead>
    <tr>
      <th>Period</th>
      <th>AI Job Postings</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January 2025</td>
      <td>66,000</td>
    </tr>
    <tr>
      <td>April 2025</td>
      <td>139,000</td>
    </tr>
    <tr>
      <td>June 2025</td>
      <td>Stabilization (recalibration, not collapse)</td>
    </tr>
  </tbody>
</table>

<p>AI positions now represent <strong>10-12% of all software jobs</strong>, a sign that AI is integrating into the industry rather than replacing it.</p>

<h3 id="rising-salaries">Rising Salaries</h3>

<p>According to <a href="https://spectrum.ieee.org/ai-jobs-in-2025">IEEE Spectrum</a>:</p>

<ul>
  <li><strong>Median AI salary</strong> (Q1 2025): $156,998/year (+0.8% quarter over quarter)</li>
  <li><strong>Top AI researchers</strong>: Meta offering packages of $10-20 million</li>
  <li><strong>Fastest growth</strong>: AI/Machine Learning Engineer (+41.8% year over year)</li>
</ul>

<h3 id="ai-adoption-by-developers">AI Adoption by Developers</h3>

<p>According to the <a href="https://blog.jetbrains.com/research/2025/10/state-of-developer-ecosystem-2025/">JetBrains 2025 report</a>:</p>

<ul>
  <li><strong>85%</strong> of developers regularly use AI tools</li>
  <li><strong>62%</strong> rely on at least one AI coding assistant</li>
  <li><strong>89%</strong> save at least one hour per week thanks to AI</li>
  <li><strong>68%</strong> expect employers to require AI tool proficiency</li>
</ul>

<h3 id="decoding-the-indeed-graph">Decoding the Indeed Graph</h3>

<p>A graph from Indeed showing a drop in tech job postings in the United States regularly circulates to fuel catastrophist narrative. This reading deserves contextualization:</p>

<p><strong>What the graph shows</strong>: an index based on year 2020 = 100.</p>

<p><strong>What it actually means</strong>: the current “drop” simply brings the market back to February 2020 levels, just before the abnormal Covid-19 pandemic spike. The 2020 tech job market was considered robust and healthy.</p>

<h2 id="my-experience-over-a-year-of-augmented-development">My Experience: Over a Year of Augmented Development</h2>

<p>As a developer who has been practicing <strong>AI-augmented development for over a year</strong>, my daily experience confirms the conclusions of the studies cited. I condensed this practice into a <a href="/en/claude-code-getting-started/">20-article series on Claude Code</a>, with a documented concrete project: recreating a complete game in TypeScript.</p>

<p><strong>What over a year of practice taught me:</strong></p>

<ul>
  <li><strong>AI excels</strong> at repetitive tasks, scaffolding, test generation, and documentation</li>
  <li><strong>AI fails</strong> at architecture decisions, business edge cases, and fine-tuning optimization</li>
  <li><strong>Structured workflow</strong> (Explore → Plan → Code → Test) transforms a hit-or-miss tool into an effective partner</li>
  <li><strong>Supervision remains essential</strong>: every generation requires review and validation</li>
</ul>

<p>As I summarize in <a href="/en/claude-code-case-study-prelude/">the final case study</a>: <em>“Claude Code is not a developer replacement, but a <strong>productivity multiplier</strong>.”</em></p>

<p>My example project cost ($120 for 5000 lines of code) illustrates the value proposition — but also the necessity of human expertise to guide, validate, and correct AI at every step.</p>

<h2 id="conclusion-ai-as-a-tool-not-a-replacement">Conclusion: AI as a Tool, Not a Replacement</h2>

<p>Recent data paints a nuanced picture far from alarmist predictions:</p>

<p><strong>What studies show:</strong></p>
<ul>
  <li>AI can <strong>slow down</strong> experienced developers by 19% in certain contexts</li>
  <li>Chain of Thought is a “brittle mirage” that collapses outside training cases</li>
  <li>The developer job market is growing 17.9% over 10 years</li>
  <li>OpenAI is losing billions, fueling a financially motivated AGI narrative</li>
  <li>GPUs reached maximum efficiency around 2018 and hardware physical limits are approaching</li>
  <li>Only 11% of jobs are currently replaceable by AI</li>
</ul>

<p><strong>What this implies:</strong></p>
<ul>
  <li>AI tools are useful but don’t replace human expertise</li>
  <li>The <strong>“human-in-the-loop”</strong> paradigm remains essential for production-quality code</li>
  <li>The profession is evolving toward more architecture and less “boilerplate code”</li>
  <li>Developers mastering AI will have a competitive advantage</li>
</ul>

<p>The <em>human-in-the-loop</em> concept is not a temporary limitation while waiting for more advanced AI — it’s a <strong>structural necessity</strong>. Even the most sophisticated AI systems require human oversight for critical decisions, contextual validation, and final accountability. Developers are becoming <strong>orchestrators</strong> who guide, correct, and validate the AI’s work.</p>

<p>As Tim Dettmers, researcher at Ai2, emphasizes, AGI remains a “Silicon Valley fantasy” — a chimera that contrasts with the pragmatic approach of prioritizing useful current applications. The narrative about imminent developer replacement stems more from marketing and trend-following than from rigorous technical analysis. Wisdom recommends adopting these technologies while maintaining critical thinking, continuing to develop fundamental skills, and not succumbing to panic fueled by misleading demos and financially motivated projections.</p>

<hr />

<h2 id="key-takeaways">Key Takeaways</h2>

<blockquote>
  <p><strong>The 4 key figures from this article:</strong></p>
  <ul>
    <li><strong>-19%</strong>: AI slows down experienced developers (METR study)</li>
    <li><strong>11%</strong>: Share of jobs currently replaceable by AI (Dettmers)</li>
    <li><strong>+17.9%</strong>: Projected developer employment growth 2023-2033 (BLS)</li>
    <li><strong>2018</strong>: Year when GPUs reached maximum efficiency</li>
  </ul>
</blockquote>

<hr />

<h2 id="year-end-review">Year-End Review</h2>

<p>As 2025 draws to a close, the landscape of AI in software development is becoming clearer. Far from the apocalyptic prophecies of early in the year, we now have concrete data to assess the real impact of these technologies.</p>

<p>2025 will have been the year of <strong>demystification</strong>: rigorous studies revealed the limitations of AI tools, the colossal financial losses of industry giants exposed the fragility of their business model, and developers on the ground learned to distinguish media hype from daily reality.</p>

<p>For 2026, my advice remains the same: <strong>learn to use these tools</strong>, but never stop developing your fundamental skills. AI is an excellent assistant — not a replacement.</p>

<p><strong>Happy New Year 2026 to all developers!</strong> May this new year bring you exciting projects, quickly resolved bugs, and serenity in the face of the alarmist predictions that will undoubtedly continue to flourish.</p>

<p><em>What was your experience with AI in 2025? Share your thoughts in the comments or on social media.</em></p>

<hr />

<h2 id="sources">Sources</h2>

<ol>
  <li>
    <p><a href="https://www.youtube.com/watch?v=4-QICRWv8jY">Melvynx - Will AI replace developers?</a> - YouTube</p>
  </li>
  <li>
    <p><a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">METR - Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity</a> - METR</p>
  </li>
  <li>
    <p><a href="https://techcrunch.com/2025/07/11/ai-coding-tools-may-not-speed-up-every-developer-study-shows/">AI coding tools may not speed up every developer</a> - TechCrunch</p>
  </li>
  <li>
    <p><a href="https://www.infoworld.com/article/4020931/ai-coding-tools-can-slow-down-seasoned-developers-by-19.html">AI coding tools can slow down seasoned developers by 19%</a> - InfoWorld</p>
  </li>
  <li>
    <p><a href="https://80000hours.org/2025/03/when-do-experts-expect-agi-to-arrive/">Shrinking AGI timelines: a review of expert forecasts</a> - 80,000 Hours</p>
  </li>
  <li>
    <p><a href="https://research.aimultiple.com/artificial-general-intelligence-singularity-timing/">When Will AGI/Singularity Happen? 8,590 Predictions Analyzed</a> - AIMultiple</p>
  </li>
  <li>
    <p><a href="https://www.cnbc.com/2024/09/27/openai-sees-5-billion-loss-this-year-on-3point7-billion-in-revenue.html">OpenAI sees roughly $5 billion loss this year on $3.7 billion in revenue</a> - CNBC</p>
  </li>
  <li>
    <p><a href="https://www.lesswrong.com/posts/CCQsQnCMWhJcCFY9x/openai-lost-usd5-billion-in-2024-and-its-losses-are">OpenAI lost $5 billion in 2024 (and its losses are increasing)</a> - LessWrong</p>
  </li>
  <li>
    <p><a href="https://arxiv.org/abs/2508.01191">Is Chain-of-Thought Reasoning of LLMs a Mirage?</a> - arXiv</p>
  </li>
  <li>
    <p><a href="https://gail.wharton.upenn.edu/research-and-insights/tech-report-chain-of-thought/">The Decreasing Value of Chain of Thought in Prompting</a> - Wharton</p>
  </li>
  <li>
    <p><a href="https://arxiv.org/abs/2511.12869">On the Fundamental Limits of LLMs at Scale</a> - arXiv</p>
  </li>
  <li>
    <p><a href="https://arxiv.org/abs/2502.01100">ZebraLogic: On the Scaling Limits of LLMs for Logical Reasoning</a> - arXiv</p>
  </li>
  <li>
    <p><a href="https://www.bls.gov/opub/ted/2025/ai-impacts-in-bls-employment-projections.htm">AI impacts in BLS employment projections</a> - Bureau of Labor Statistics</p>
  </li>
  <li>
    <p><a href="https://www.veritone.com/blog/ai-jobs-growth-q1-2025-labor-market-analysis/">AI Jobs on the Rise: Q1 2025 Labor Market Analysis</a> - Veritone</p>
  </li>
  <li>
    <p><a href="https://blog.getaura.ai/new-ai-job-market-data-through-june-2025">New AI Job Market Data (Through June 2025)</a> - GetAura</p>
  </li>
  <li>
    <p><a href="https://spectrum.ieee.org/ai-jobs-in-2025">AI Jobs in 2025: Essential Insights for Software Engineers</a> - IEEE Spectrum</p>
  </li>
  <li>
    <p><a href="https://blog.jetbrains.com/research/2025/10/state-of-developer-ecosystem-2025/">The State of Developer Ecosystem 2025</a> - JetBrains</p>
  </li>
  <li>
    <p><a href="https://en.wikipedia.org/wiki/GPT-4">GPT-4</a> - Wikipedia</p>
  </li>
  <li>
    <p><a href="https://www.ibm.com/think/topics/chain-of-thoughts">What is chain of thought (CoT) prompting?</a> - IBM</p>
  </li>
  <li>
    <p><a href="https://intelligence-artificielle.developpez.com/actu/378435/">Superintelligent AI is a Silicon Valley Fantasy - Tim Dettmers (Ai2)</a> - Developpez.com</p>
  </li>
  <li>
    <p><a href="https://medium.com/@adnanmasood/is-there-a-wall-34d02dfd85f3">Is there a Wall? - Dr. Adnan Masood</a> - Dr. Adnan Masood (AI solutions architect)</p>
  </li>
</ol>
]]></content:encoded>
        <pubDate>Wed, 31 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/will-ai-replace-developers-critical-analysis/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/will-ai-replace-developers-critical-analysis/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/ia-remplacement-developpeurs.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Case Study: Prelude of the Chambered Reborn</title>
        <description>
          
            Real experience report: how I used Claude Code to convert Notch&apos;s game Prelude of the Chambered (Java) to TypeScript in a single evening.
          
        </description>
        <content:encoded><![CDATA[<p>To conclude this series, what better than a concrete experience report? Here’s how I used Claude Code to convert <strong>Prelude of the Chambered</strong>, Notch’s game (Minecraft creator), from Java to TypeScript — <strong>in a single evening</strong>.</p>

<blockquote>
  <p>To discover the project in detail, read my dedicated article: <a href="/en/prelude-of-the-chambered-reborn-typescript-web-port/">Prelude of the Chambered Reborn: Renaissance of a Notch classic</a></p>
</blockquote>

<blockquote>
  <p>Also see my other retro game project in TypeScript: <a href="/en/gbts-typescript-gameboy-development/">GBTS - A GameBoy Emulator</a></p>
</blockquote>

<h2 id="the-challenge">The Challenge</h2>

<h3 id="the-original-project">The Original Project</h3>

<p><strong>Prelude of the Chambered</strong> is a dungeon crawler created by Notch in 48h during Ludum Dare 21 in 2011. The original code is in Java, with a homemade <strong>software raycasting</strong> rendering engine — about 5,000 lines of Java code spread across forty files.</p>

<h3 id="my-goal">My Goal</h3>

<p>Port the game to the modern web with:</p>
<ul>
  <li>TypeScript instead of Java</li>
  <li>Canvas 2D API (software rendering, like the original)</li>
  <li>Vite for building</li>
  <li>Deployable on any browser</li>
</ul>

<p>The challenge: preserve the original raycasting engine and its pixel-by-pixel rendering, without using WebGL or a 3D library.</p>

<p><strong>Without Claude Code</strong>, I would have estimated this project at several weeks of work. With Claude Code, I started one evening after dinner thinking “let’s see how far we get”.</p>

<h2 id="one-evening-one-complete-game">One Evening, One Complete Game</h2>

<h3 id="exploring-the-java-code">Exploring the Java Code</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude

&gt; @java-src/**/*.java Analyze the original game architecture.
&gt; Identify the main components and their responsibilities.
</code></pre></div></div>

<p>In seconds, Claude mapped out the entire project:</p>
<ul>
  <li><strong>Art.java</strong>: Texture and sprite management</li>
  <li><strong>Game.java</strong>: Main game loop</li>
  <li><strong>Level.java</strong>: Level loading via PNG images</li>
  <li><strong>Screen.java</strong>: Software raycasting engine</li>
  <li><strong>Entity.java</strong>: Entity system</li>
</ul>

<h3 id="converting-the-rendering-engine">Converting the Rendering Engine</h3>

<p>The heart of the project: adapting the Java raycasting engine to TypeScript/Canvas 2D.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Analyze @java-src/Screen.java and @java-src/Bitmap.java
&gt; Implement the equivalent in TypeScript with Canvas 2D API.
&gt; Preserve the pixel-by-pixel software rendering.
</code></pre></div></div>

<p>Claude:</p>
<ol>
  <li>Understood Notch’s bitmap rendering system</li>
  <li>Adapted raycasting calculations for TypeScript</li>
  <li>Created a Bitmap class compatible with Canvas 2D</li>
  <li>Preserved software rendering without GPU</li>
</ol>

<h3 id="the-bitmap-level-system">The Bitmap Level System</h3>

<p>Notch’s brilliant architecture: each level is a PNG image where every pixel color defines a game element.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Analyze how Level.java loads levels from images.
&gt; Implement the same logic in TypeScript.
</code></pre></div></div>

<p>Claude perfectly reproduced the system:</p>
<ul>
  <li>White = wall</li>
  <li>Blue = water</li>
  <li>Magenta = ladder</li>
  <li>Red = enemies (with variations based on shade)</li>
  <li>Alpha channel = IDs to link switches and doors</li>
</ul>

<h3 id="entities-and-gameplay">Entities and Gameplay</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Analyze enemies in @java-src/entities/
&gt; and implement them in TypeScript with the same behavior.
</code></pre></div></div>

<p>Claude methodically converted each enemy:</p>
<ul>
  <li><strong>Bat</strong>: Random movement</li>
  <li><strong>Ogre</strong>: Patrol + attack</li>
  <li><strong>Ghost</strong>: Goes through walls</li>
  <li><strong>Eye</strong>: Ranged attack</li>
  <li>Plus boss variants</li>
</ul>

<h3 id="integration-and-debug">Integration and Debug</h3>

<p>Some adjustments were necessary:</p>
<ul>
  <li>Collision fine-tuning</li>
  <li>Adapting <code class="language-plaintext highlighter-rouge">Thread.sleep()</code> to <code class="language-plaintext highlighter-rouge">requestAnimationFrame</code></li>
  <li>Input handling (Java AWT → DOM events)</li>
</ul>

<h3 id="deployment">Deployment</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Configure Vite to build the project and GitHub Actions to deploy.
</code></pre></div></div>

<p>And there you go. Project deployed, playable in the browser.</p>

<h2 id="results">Results</h2>

<h3 id="what-was-accomplished-in-one-evening">What Was Accomplished in One Evening</h3>

<table>
  <thead>
    <tr>
      <th>Element</th>
      <th>Result</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lines of code converted</td>
      <td>~5,000</td>
    </tr>
    <tr>
      <td>TypeScript files created</td>
      <td>~40</td>
    </tr>
    <tr>
      <td>Total time</td>
      <td>One evening</td>
    </tr>
    <tr>
      <td>Working game</td>
      <td>Yes</td>
    </tr>
  </tbody>
</table>

<h3 id="the-final-stack">The Final Stack</h3>

<ul>
  <li><strong>TypeScript</strong>: Strict typing</li>
  <li><strong>Canvas 2D API</strong>: Software rendering, no WebGL</li>
  <li><strong>Vite</strong>: Ultra-fast build with HMR</li>
  <li><strong>GitHub Actions</strong>: Automatic deployment</li>
</ul>

<h3 id="what-claude-did">What Claude Did</h3>

<ul>
  <li>Complete analysis of original Java code</li>
  <li>Raycasting engine conversion</li>
  <li>Bitmap level system adaptation</li>
  <li>Conversion of all entities</li>
  <li>Build and deployment configuration</li>
  <li>Debugging encountered problems</li>
</ul>

<h3 id="what-i-did">What I Did</h3>

<ul>
  <li>Project direction (what to do, in what order)</li>
  <li>Validating Claude’s choices</li>
  <li>Gameplay fine-tuning</li>
  <li>Identifying bugs to fix</li>
  <li>Final code review</li>
</ul>

<h2 id="why-it-worked">Why It Worked</h2>

<h3 id="1-complete-source-code-available">1. Complete Source Code Available</h3>

<p>I had the original Java code. Claude could analyze the existing code rather than guess.</p>

<h3 id="2-precise-references">2. Precise References</h3>

<p><code class="language-plaintext highlighter-rouge">@java-src/Screen.java</code> rather than “the rendering file” — Claude knew exactly what to analyze.</p>

<h3 id="3-faithful-architecture">3. Faithful Architecture</h3>

<p>Rather than reinventing with a modern 3D lib, we preserved the original approach: software raycasting on Canvas 2D. Fewer decisions to make = faster conversion.</p>

<h3 id="4-fast-iterations">4. Fast Iterations</h3>

<p>Component by component, each step validated before the next.</p>

<h2 id="what-this-changes">What This Changes</h2>

<p>Without Claude Code, this project would have taken <strong>several weeks</strong>:</p>
<ul>
  <li>Understanding the raycasting engine: 2-3 days</li>
  <li>Adapting Java → TypeScript calculations: 1 week</li>
  <li>Debugging behavior differences: several days</li>
</ul>

<p>With Claude Code: <strong>one evening</strong>.</p>

<p>It’s not that Claude codes faster — it’s that it eliminates the “understanding” and “mental translation” time between languages.</p>

<h2 id="series-conclusion">Series Conclusion</h2>

<p>In 20 days, we covered:</p>

<ol>
  <li><strong>Installation and first steps</strong></li>
  <li><strong>Secret syntax #@/!</strong></li>
  <li><strong>EPCT Workflow</strong></li>
  <li><strong>Prompt engineering</strong></li>
  <li><strong>Context management</strong></li>
  <li><strong>Git workflows</strong></li>
  <li><strong>Permissions and security</strong></li>
  <li><strong>Custom slash commands</strong></li>
  <li><strong>Subagents</strong></li>
  <li><strong>Skills</strong></li>
  <li><strong>Plugins and marketplace</strong></li>
  <li><strong>Hooks</strong></li>
  <li><strong>MCP</strong></li>
  <li><strong>IDE integration</strong></li>
  <li><strong>CI/CD headless</strong></li>
  <li><strong>Billing and costs</strong></li>
  <li><strong>Troubleshooting</strong></li>
  <li><strong>Status line and terminal</strong></li>
  <li><strong>Tool comparison</strong></li>
  <li><strong>This case study</strong></li>
</ol>

<p>Claude Code is a powerful tool that, when used well, transforms how we develop. It’s not a developer replacement — it’s a <strong>productivity multiplier</strong> that can compress weeks of work into a few hours.</p>

<p>Now it’s your turn!</p>

<hr />

<p><em>Thank you for following this “Master Claude Code in 20 Days” series. <a href="/en/prelude-of-the-chambered-reborn-typescript-web-port/">Discover the Prelude Reborn project</a> — <a href="https://lingelo.github.io/prelude-of-the-chambered-reborn/">Play now</a></em></p>
]]></content:encoded>
        <pubDate>Tue, 30 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-case-study-prelude-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-case-study-prelude-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Claude Code vs Cursor vs GitHub Copilot</title>
        <description>
          
            Detailed comparison of Claude Code, Cursor and GitHub Copilot: features, pricing, use cases and recommendations to choose the right tool.
          
        </description>
        <content:encoded><![CDATA[<p>The AI assistant market for developers is exploding. Claude Code, Cursor, and GitHub Copilot are the three major solutions. Which one to choose? Let’s compare objectively.</p>

<blockquote>
  <p>For broader context on the state of AI in development, see my article <a href="/en/ai-development-between-promises-realities-2025-state/">AI and Development in 2025</a>. And if you’re considering local alternatives, check out <a href="/en/openai-gpt-oss-ollama-proprietary-models-open-source-transition/">OpenAI GPT OSS vs Ollama</a>.</p>
</blockquote>

<h2 id="overview">Overview</h2>

<table>
  <thead>
    <tr>
      <th>Criteria</th>
      <th>Claude Code</th>
      <th>Cursor</th>
      <th>GitHub Copilot</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Type</td>
      <td>CLI + Agent</td>
      <td>Full IDE</td>
      <td>IDE Extension</td>
    </tr>
    <tr>
      <td>AI Model</td>
      <td>Claude (Anthropic)</td>
      <td>Multiple (including Claude)</td>
      <td>GPT-4/Codex</td>
    </tr>
    <tr>
      <td>Price</td>
      <td>$100-200/month (Max)</td>
      <td>$20/month</td>
      <td>$10-19/month</td>
    </tr>
    <tr>
      <td>Platform</td>
      <td>Terminal</td>
      <td>VS Code Fork</td>
      <td>VS Code, JetBrains</td>
    </tr>
  </tbody>
</table>

<h2 id="claude-code">Claude Code</h2>

<h3 id="strengths">Strengths</h3>

<ul>
  <li><strong>Agentic</strong>: Can plan and execute complex tasks end-to-end</li>
  <li><strong>Project context</strong>: CLAUDE.md, rules, hierarchical memory</li>
  <li><strong>Extensible</strong>: Hooks, skills, subagents, MCP</li>
  <li><strong>Terminal-native</strong>: Fast, scriptable, CI/CD integrable</li>
  <li><strong>Autonomy</strong>: Can work on multiple files in sequence</li>
</ul>

<h3 id="weaknesses">Weaknesses</h3>

<ul>
  <li><strong>Learning curve</strong>: #@/! syntax to master</li>
  <li><strong>Price</strong>: More expensive than alternatives</li>
  <li><strong>No integrated IDE</strong>: Requires your separate editor</li>
  <li><strong>Less visual</strong>: No integrated graphical diff</li>
</ul>

<h3 id="ideal-for">Ideal for</h3>

<ul>
  <li>Terminal-first developers</li>
  <li>Complex multi-file projects</li>
  <li>CI/CD automation</li>
  <li>Advanced users seeking power</li>
</ul>

<h2 id="cursor">Cursor</h2>

<h3 id="strengths-1">Strengths</h3>

<ul>
  <li><strong>Full IDE</strong>: VS Code fork with native AI</li>
  <li><strong>Multi-model</strong>: GPT-4, Claude, local models</li>
  <li><strong>Visual</strong>: Integrated diffs, contextual chat</li>
  <li><strong>Composer</strong>: Agent mode for complex tasks</li>
  <li><strong>Accessibility</strong>: Familiar VS Code interface</li>
</ul>

<h3 id="weaknesses-1">Weaknesses</h3>

<ul>
  <li><strong>Locked in</strong>: Must use Cursor as IDE</li>
  <li><strong>Limited terminal</strong>: No pure CLI usage</li>
  <li><strong>Dependency</strong>: Fork that may diverge from VS Code</li>
  <li><strong>Less extensible</strong>: Not as rich plugin system</li>
</ul>

<h3 id="ideal-for-1">Ideal for</h3>

<ul>
  <li>VS Code developers seeking native AI integration</li>
  <li>Teams wanting a unified tool</li>
  <li>Users preferring graphical interface</li>
  <li>Projects where visualization is important</li>
</ul>

<h2 id="github-copilot">GitHub Copilot</h2>

<h3 id="strengths-2">Strengths</h3>

<ul>
  <li><strong>GitHub integration</strong>: Native PRs, Issues, Actions</li>
  <li><strong>Accessible price</strong>: $10/month individual</li>
  <li><strong>Ubiquity</strong>: Available in all major IDEs</li>
  <li><strong>Real-time completion</strong>: Suggestions while typing</li>
  <li><strong>Copilot Chat</strong>: Contextual conversation</li>
</ul>

<h3 id="weaknesses-2">Weaknesses</h3>

<ul>
  <li><strong>Less agentic</strong>: No autonomous planning</li>
  <li><strong>Limited context</strong>: Less suitable for large projects</li>
  <li><strong>Microsoft-dependent</strong>: Tied to Microsoft ecosystem</li>
  <li><strong>Less customizable</strong>: No rules, hooks, etc.</li>
</ul>

<h3 id="ideal-for-2">Ideal for</h3>

<ul>
  <li>AI assistant beginners</li>
  <li>Limited budget</li>
  <li>GitHub-centric projects</li>
  <li>Quick code completion</li>
</ul>

<h2 id="detailed-comparison">Detailed Comparison</h2>

<h3 id="context-understanding">Context Understanding</h3>

<table>
  <thead>
    <tr>
      <th>Aspect</th>
      <th>Claude Code</th>
      <th>Cursor</th>
      <th>Copilot</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Current file</td>
      <td>✅</td>
      <td>✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Entire project</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Project instructions</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Dependencies</td>
      <td>✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Git history</td>
      <td>✅✅</td>
      <td>✅</td>
      <td>✅✅✅</td>
    </tr>
  </tbody>
</table>

<h3 id="agentic-capabilities">Agentic Capabilities</h3>

<table>
  <thead>
    <tr>
      <th>Capability</th>
      <th>Claude Code</th>
      <th>Cursor</th>
      <th>Copilot</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Multi-step planning</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Autonomous execution</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Multi-file modification</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Automatic testing</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>Assisted debugging</td>
      <td>✅✅</td>
      <td>✅✅</td>
      <td>✅</td>
    </tr>
  </tbody>
</table>

<h3 id="customization">Customization</h3>

<table>
  <thead>
    <tr>
      <th>Aspect</th>
      <th>Claude Code</th>
      <th>Cursor</th>
      <th>Copilot</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Custom rules</td>
      <td>✅✅✅</td>
      <td>✅✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Hooks/Automation</td>
      <td>✅✅✅</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Subagents</td>
      <td>✅✅✅</td>
      <td>❌</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>External integrations</td>
      <td>✅✅✅ (MCP)</td>
      <td>✅</td>
      <td>✅ (GitHub)</td>
    </tr>
    <tr>
      <td>Plugins</td>
      <td>✅✅✅</td>
      <td>✅ (VS Code extensions)</td>
      <td>✅</td>
    </tr>
  </tbody>
</table>

<h3 id="pricing-and-licenses">Pricing and Licenses</h3>

<table>
  <thead>
    <tr>
      <th>Plan</th>
      <th>Claude Code</th>
      <th>Cursor</th>
      <th>Copilot</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Free</td>
      <td>Limited (API)</td>
      <td>Limited</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Individual</td>
      <td>$100/month (Max 5x)</td>
      <td>$20/month</td>
      <td>$10/month</td>
    </tr>
    <tr>
      <td>Pro/Business</td>
      <td>$200/month (Max 20x)</td>
      <td>$40/month</td>
      <td>$19/month</td>
    </tr>
    <tr>
      <td>Enterprise</td>
      <td>Custom</td>
      <td>Custom</td>
      <td>$39/month</td>
    </tr>
  </tbody>
</table>

<h2 id="compared-workflows">Compared Workflows</h2>

<h3 id="module-refactoring">Module Refactoring</h3>

<p><strong>Claude Code</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; ultrathink. Refactor the auth module to use JWT.
&gt; Make sure all tests pass.
</code></pre></div></div>
<p>→ Claude plans, modifies files, runs tests, fixes if needed.</p>

<p><strong>Cursor</strong>:</p>
<ol>
  <li>Open Composer</li>
  <li>Describe the refactoring</li>
  <li>Review proposed changes</li>
  <li>Accept/adjust</li>
  <li>Run tests manually</li>
</ol>

<p><strong>Copilot</strong>:</p>
<ol>
  <li>Open Copilot Chat</li>
  <li>Ask for refactoring suggestions</li>
  <li>Apply file by file</li>
  <li>Run tests manually</li>
</ol>

<h3 id="bug-fix">Bug Fix</h3>

<p><strong>Claude Code</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; The test UserService.test.ts fails at line 45.
&gt; Find and fix the bug.
</code></pre></div></div>

<p><strong>Cursor</strong>:</p>
<ol>
  <li>Right-click on error</li>
  <li>“Fix with AI”</li>
  <li>Review suggestion</li>
  <li>Apply</li>
</ol>

<p><strong>Copilot</strong>:</p>
<ol>
  <li>Select problematic code</li>
  <li><code class="language-plaintext highlighter-rouge">/fix</code> in chat</li>
  <li>Apply suggestion</li>
</ol>

<h3 id="new-project">New Project</h3>

<p><strong>Claude Code</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Create a REST API with Express, TypeScript, Prisma.
&gt; Structure according to best practices.
&gt; Add JWT authentication.
</code></pre></div></div>

<p><strong>Cursor</strong>:</p>
<ol>
  <li>Composer mode</li>
  <li>Describe architecture</li>
  <li>Generate file by file</li>
  <li>Adjust as you go</li>
</ol>

<p><strong>Copilot</strong>:</p>
<ol>
  <li>Create files manually</li>
  <li>Use suggestions for content</li>
  <li>Copilot Chat for questions</li>
</ol>

<h2 id="when-to-use-what">When to Use What?</h2>

<h3 id="use-claude-code-if">Use Claude Code if:</h3>

<ul>
  <li>You’re comfortable with terminal</li>
  <li>You work on complex projects</li>
  <li>You want automation (CI/CD, scripts)</li>
  <li>You need AI autonomy</li>
  <li>Budget is not the main constraint</li>
</ul>

<h3 id="use-cursor-if">Use Cursor if:</h3>

<ul>
  <li>You prefer VS Code</li>
  <li>You want an integrated experience</li>
  <li>You work visually (diffs)</li>
  <li>You want to switch models easily</li>
  <li>Moderate budget</li>
</ul>

<h3 id="use-copilot-if">Use Copilot if:</h3>

<ul>
  <li>You’re new to AI</li>
  <li>Limited budget</li>
  <li>You’re in the GitHub ecosystem</li>
  <li>You want real-time suggestions</li>
  <li>You use various IDEs</li>
</ul>

<h2 id="recommended-combination">Recommended Combination</h2>

<p>My personal stack:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>┌─────────────────────────────────────────┐
│ Claude Code (terminal)                  │
│ - Complex tasks                         │
│ - Automation                            │
│ - CI/CD                                 │
├─────────────────────────────────────────┤
│ VS Code + Copilot                       │
│ - Daily editing                         │
│ - Real-time completion                  │
│ - Quick fixes                           │
└─────────────────────────────────────────┘
</code></pre></div></div>

<p>This combination offers:</p>
<ul>
  <li>Claude’s power for heavy tasks</li>
  <li>Copilot’s speed for daily work</li>
  <li>Best of both worlds</li>
</ul>

<h2 id="market-evolution">Market Evolution</h2>

<h3 id="2024-2025-trends">2024-2025 Trends</h3>

<ul>
  <li><strong>More autonomy</strong>: Tools becoming more agentic</li>
  <li><strong>Multi-model</strong>: LLM choice per task</li>
  <li><strong>Integration</strong>: Less friction between tools</li>
  <li><strong>Specialization</strong>: Tools by domain (web, mobile, data)</li>
</ul>

<h3 id="whats-coming">What’s Coming</h3>

<ul>
  <li>Claude Code continues adding agentic features</li>
  <li>Cursor pushes multi-model integration</li>
  <li>Copilot evolves toward more autonomy (Copilot Workspace)</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>There’s no universal “best” tool. The choice depends on:</p>

<ol>
  <li><strong>Your workflow</strong>: Terminal vs GUI</li>
  <li><strong>Your budget</strong>: $10 to $200/month</li>
  <li><strong>Your needs</strong>: Completion vs Full Agent</li>
  <li><strong>Your ecosystem</strong>: GitHub, Anthropic, or neutral</li>
</ol>

<p>My advice: <strong>try all three</strong> with their trial versions, then choose (or combine) according to your style.</p>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 20</strong>, we’ll finish with a <strong>complete case study</strong>: how I used Claude Code to create Prelude of the Chambered Reborn.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-status-line-terminal/">Day 18: Status line and terminal</a></em></p>
]]></content:encoded>
        <pubDate>Mon, 29 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-vs-cursor-vs-copilot-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-vs-cursor-vs-copilot-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Status Line and Terminal Customization</title>
        <description>
          
            Customize Claude Code: status line, vim mode, terminal themes, keyboard shortcuts, and advanced interface configuration.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code runs in your terminal. Did you know you can customize its appearance and behavior? Let’s see how to adapt the interface to your preferences.</p>

<h2 id="the-status-line">The Status Line</h2>

<h3 id="what-is-the-status-line">What is the status line?</h3>

<p>The bar at the bottom of the screen that displays:</p>
<ul>
  <li>Active model</li>
  <li>Tokens used</li>
  <li>Session cost</li>
  <li>Connection status</li>
</ul>

<h3 id="customize-the-status-line">Customize the status line</h3>

<p>Via the <code class="language-plaintext highlighter-rouge">/config</code> command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/config
</code></pre></div></div>

<p>Status line options:</p>
<ul>
  <li><strong>Minimal</strong>: Just the model</li>
  <li><strong>Standard</strong>: Model + tokens</li>
  <li><strong>Detailed</strong>: Everything (model, tokens, cost, latency)</li>
  <li><strong>Hidden</strong>: No status line</li>
</ul>

<h3 id="configuration-in-settings">Configuration in settings</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"statusLine"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"style"</span><span class="p">:</span><span class="w"> </span><span class="s2">"detailed"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showCost"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showTokens"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showModel"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showLatency"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="vim-mode">Vim Mode</h2>

<h3 id="enable-vim-mode">Enable vim mode</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/vim
</code></pre></div></div>

<p>Or at launch:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--vim</span>
</code></pre></div></div>

<h3 id="available-vim-shortcuts">Available vim shortcuts</h3>

<table>
  <thead>
    <tr>
      <th>Mode</th>
      <th>Key</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">i</code></td>
      <td>Insert mode</td>
    </tr>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">v</code></td>
      <td>Visual mode</td>
    </tr>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">dd</code></td>
      <td>Delete line</td>
    </tr>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">yy</code></td>
      <td>Copy line</td>
    </tr>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">p</code></td>
      <td>Paste</td>
    </tr>
    <tr>
      <td>Normal</td>
      <td><code class="language-plaintext highlighter-rouge">/</code></td>
      <td>Search</td>
    </tr>
    <tr>
      <td>Insert</td>
      <td><code class="language-plaintext highlighter-rouge">Esc</code></td>
      <td>Normal mode</td>
    </tr>
  </tbody>
</table>

<h3 id="vim-configuration">Vim configuration</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"editor"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"mode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vim"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"lineNumbers"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"relativNumbers"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="themes-and-colors">Themes and Colors</h2>

<h3 id="built-in-themes">Built-in themes</h3>

<p>Claude Code adapts to your terminal theme. To force a theme:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">CLAUDE_CODE_THEME</span><span class="o">=</span>dark
</code></pre></div></div>

<p>Options:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">dark</code>: Dark background</li>
  <li><code class="language-plaintext highlighter-rouge">light</code>: Light background</li>
  <li><code class="language-plaintext highlighter-rouge">auto</code>: Automatic detection</li>
</ul>

<h3 id="custom-colors">Custom colors</h3>

<p>In your terminal config file (.zshrc, .bashrc):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Claude Code colors</span>
<span class="nb">export </span><span class="nv">CLAUDE_CODE_COLOR_PRIMARY</span><span class="o">=</span><span class="s2">"#00ff00"</span>
<span class="nb">export </span><span class="nv">CLAUDE_CODE_COLOR_SECONDARY</span><span class="o">=</span><span class="s2">"#0066ff"</span>
<span class="nb">export </span><span class="nv">CLAUDE_CODE_COLOR_ERROR</span><span class="o">=</span><span class="s2">"#ff0000"</span>
<span class="nb">export </span><span class="nv">CLAUDE_CODE_COLOR_SUCCESS</span><span class="o">=</span><span class="s2">"#00ff00"</span>
</code></pre></div></div>

<h2 id="keyboard-shortcuts">Keyboard Shortcuts</h2>

<h3 id="default-shortcuts">Default shortcuts</h3>

<table>
  <thead>
    <tr>
      <th>Shortcut</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Enter</code></td>
      <td>Send message</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Shift+Enter</code></td>
      <td>New line</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+C</code></td>
      <td>Cancel/Interrupt</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+L</code></td>
      <td>Clear screen</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Esc Esc</code></td>
      <td>Rewind menu</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Shift+Tab</code></td>
      <td>Accept Edits mode</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">↑</code> / <code class="language-plaintext highlighter-rouge">↓</code></td>
      <td>Prompt history</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Tab</code></td>
      <td>Autocompletion</td>
    </tr>
  </tbody>
</table>

<h3 id="customize-shortcuts">Customize shortcuts</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"keybindings"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"submit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Enter"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"newLine"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Shift+Enter"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"cancel"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Ctrl+C"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"clearScreen"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Ctrl+L"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"rewind"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Esc Esc"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"acceptEdits"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Shift+Tab"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"history.up"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ArrowUp"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"history.down"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ArrowDown"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="autocompletion">Autocompletion</h2>

<h3 id="file-completion">File completion</h3>

<p>Type <code class="language-plaintext highlighter-rouge">@</code> then Tab to see available files:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@sr[Tab]
→ @src/
→ @src/api/
→ @src/components/
</code></pre></div></div>

<h3 id="command-completion">Command completion</h3>

<p>Type <code class="language-plaintext highlighter-rouge">/</code> then Tab:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/co[Tab]
→ /compact
→ /config
→ /cost
</code></pre></div></div>

<h3 id="smart-completion">Smart completion</h3>

<p>Claude Code suggests completions based on:</p>
<ul>
  <li>Current context</li>
  <li>Command history</li>
  <li>Project files</li>
</ul>

<h2 id="advanced-terminal-configuration">Advanced Terminal Configuration</h2>

<h3 id="history-size">History size</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"history"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"maxSize"</span><span class="p">:</span><span class="w"> </span><span class="mi">1000</span><span class="p">,</span><span class="w">
    </span><span class="nl">"saveToDisk"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="scroll-buffer">Scroll buffer</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"terminal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"scrollback"</span><span class="p">:</span><span class="w"> </span><span class="mi">10000</span><span class="p">,</span><span class="w">
    </span><span class="nl">"wordWrap"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="display-format">Display format</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"display"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"codeBlockStyle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bordered"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"syntaxHighlighting"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"lineNumbers"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"diffStyle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"unified"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="shell-integration">Shell Integration</h2>

<h3 id="useful-aliases">Useful aliases</h3>

<p>Add to your <code class="language-plaintext highlighter-rouge">.zshrc</code> or <code class="language-plaintext highlighter-rouge">.bashrc</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Launch Claude Code</span>
<span class="nb">alias </span><span class="nv">cc</span><span class="o">=</span><span class="s1">'claude'</span>

<span class="c"># Claude Code with specific model</span>
<span class="nb">alias </span><span class="nv">ccs</span><span class="o">=</span><span class="s1">'claude --model sonnet'</span>
<span class="nb">alias </span><span class="nv">cco</span><span class="o">=</span><span class="s1">'claude --model opus'</span>
<span class="nb">alias </span><span class="nv">cch</span><span class="o">=</span><span class="s1">'claude --model haiku'</span>

<span class="c"># Continue last session</span>
<span class="nb">alias </span><span class="nv">ccr</span><span class="o">=</span><span class="s1">'claude -c'</span>

<span class="c"># Claude Code in print mode</span>
<span class="nb">alias </span><span class="nv">ccp</span><span class="o">=</span><span class="s1">'claude -p'</span>
</code></pre></div></div>

<h3 id="shell-functions">Shell functions</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Analyze a file with Claude</span>
analyze<span class="o">()</span> <span class="o">{</span>
  <span class="nb">cat</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> | claude <span class="nt">-p</span> <span class="s2">"Analyze this file and identify potential issues"</span>
<span class="o">}</span>

<span class="c"># Generate tests for a file</span>
gentest<span class="o">()</span> <span class="o">{</span>
  claude <span class="nt">-p</span> <span class="s2">"Generate tests for @</span><span class="nv">$1</span><span class="s2">"</span> <span class="nt">--allowedTools</span> Read,Write
<span class="o">}</span>

<span class="c"># Quick review</span>
review<span class="o">()</span> <span class="o">{</span>
  git diff | claude <span class="nt">-p</span> <span class="s2">"Review these changes"</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="terminal-multiplexers">Terminal Multiplexers</h2>

<h3 id="with-tmux">With tmux</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Create a Claude Code session</span>
tmux new-session <span class="nt">-s</span> claude

<span class="c"># In tmux</span>
claude

<span class="c"># Detach: Ctrl+B, D</span>
<span class="c"># Reattach: tmux attach -t claude</span>
</code></pre></div></div>

<h3 id="recommended-tmux-configuration">Recommended tmux configuration</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># ~/.tmux.conf</span>

<span class="c"># Status bar for Claude Code</span>
<span class="nb">set</span> <span class="nt">-g</span> status-right <span class="s1">'#[fg=green]Claude #[fg=white]| #[fg=cyan]%H:%M'</span>

<span class="c"># Adapted colors</span>
<span class="nb">set</span> <span class="nt">-g</span> default-terminal <span class="s2">"screen-256color"</span>
</code></pre></div></div>

<h3 id="with-screen">With screen</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>screen <span class="nt">-S</span> claude
claude
<span class="c"># Detach: Ctrl+A, D</span>
<span class="c"># Reattach: screen -r claude</span>
</code></pre></div></div>

<h2 id="notifications">Notifications</h2>

<h3 id="task-completion-notifications">Task completion notifications</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"notifications"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"onTaskComplete"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"onError"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"sound"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="system-notifications">System notifications</h3>

<p>With libnotify (Linux):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">-p</span> <span class="s2">"Long task"</span> <span class="o">&amp;&amp;</span> notify-send <span class="s2">"Claude finished"</span>
</code></pre></div></div>

<p>With osascript (macOS):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">-p</span> <span class="s2">"Long task"</span> <span class="o">&amp;&amp;</span> osascript <span class="nt">-e</span> <span class="s1">'display notification "Claude finished"'</span>
</code></pre></div></div>

<h2 id="configuration-profiles">Configuration Profiles</h2>

<h3 id="create-profiles">Create profiles</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.claude/
├── profiles/
│   ├── work.json
│   ├── personal.json
│   └── ci.json
└── settings.json
</code></pre></div></div>

<h3 id="work-profile">“work” profile</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sonnet"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"statusLine"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"style"</span><span class="p">:</span><span class="w"> </span><span class="s2">"detailed"</span><span class="w"> </span><span class="p">},</span><span class="w">
  </span><span class="nl">"editor"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"mode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vim"</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="ci-profile">“ci” profile</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"haiku"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"statusLine"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"style"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hidden"</span><span class="w"> </span><span class="p">},</span><span class="w">
  </span><span class="nl">"notifications"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="load-a-profile">Load a profile</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--profile</span> work
</code></pre></div></div>

<h2 id="accessibility">Accessibility</h2>

<h3 id="high-contrast-mode">High contrast mode</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"accessibility"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"highContrast"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"largeText"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
    </span><span class="nl">"screenReaderFriendly"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="disable-animations">Disable animations</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"display"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"animations"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
    </span><span class="nl">"progressIndicator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="complete-configuration-template">Complete Configuration Template</h2>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"statusLine"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"style"</span><span class="p">:</span><span class="w"> </span><span class="s2">"detailed"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showCost"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showTokens"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"showModel"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"editor"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"mode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vim"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"lineNumbers"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"display"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"codeBlockStyle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bordered"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"syntaxHighlighting"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"diffStyle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"unified"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"animations"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"history"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"maxSize"</span><span class="p">:</span><span class="w"> </span><span class="mi">1000</span><span class="p">,</span><span class="w">
    </span><span class="nl">"saveToDisk"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"keybindings"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"submit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Enter"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"newLine"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Shift+Enter"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"cancel"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Ctrl+C"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"notifications"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"onTaskComplete"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"onError"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 19</strong>, we’ll do a <strong>comparison: Claude Code vs Cursor vs GitHub Copilot</strong> - understand each tool’s strengths.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-troubleshooting/">Day 17: Troubleshooting</a></em></p>
]]></content:encoded>
        <pubDate>Sun, 28 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-status-line-terminal-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-status-line-terminal-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Claude Code Troubleshooting</title>
        <description>
          
            Complete Claude Code troubleshooting guide: common errors, connection issues, context limits, and practical solutions.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code is robust, but problems can occur. Here’s a complete guide to diagnose and solve the most common errors.</p>

<h2 id="connection-problems">Connection Problems</h2>

<h3 id="error-api-key-invalid">Error: “API Key invalid”</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Invalid API key
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Verify the key:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="nv">$ANTHROPIC_API_KEY</span>
</code></pre></div>    </div>
  </li>
  <li>Reconfigure:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude config <span class="nb">set </span>apiKey sk-ant-...
</code></pre></div>    </div>
  </li>
  <li>Check permissions on console.anthropic.com</li>
</ol>

<h3 id="error-rate-limit-exceeded">Error: “Rate limit exceeded”</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Rate limit exceeded. Please retry after X seconds.
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Wait for the indicated delay</li>
  <li>Reduce request frequency</li>
  <li>Upgrade to a higher plan (Max 20x)</li>
  <li>Use <code class="language-plaintext highlighter-rouge">/compact</code> to reduce tokens</li>
</ol>

<h3 id="error-connection-timeout">Error: “Connection timeout”</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Request timed out
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Check internet connection</li>
  <li>Check status: status.anthropic.com</li>
  <li>Retry with longer timeout:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--timeout</span> 120000
</code></pre></div>    </div>
  </li>
</ol>

<h2 id="context-problems">Context Problems</h2>

<h3 id="error-context-window-exceeded">Error: “Context window exceeded”</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Maximum context length exceeded
</code></pre></div></div>

<p><strong>Cause</strong>: Conversation + files exceed token limit.</p>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Use <code class="language-plaintext highlighter-rouge">/compact</code> immediately:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/compact
</code></pre></div>    </div>
  </li>
  <li>Start a new session:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/clear
</code></pre></div>    </div>
  </li>
  <li>Limit referenced files:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❌ @src/**/*.ts  (too many files)
✅ @src/api/auth.ts  (specific file)
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="claude-forgets-instructions">Claude “forgets” instructions</h3>

<p><strong>Cause</strong>: Context is saturated and old instructions are truncated.</p>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Add instructions to CLAUDE.md:
    <div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># CLAUDE.md</span>
<span class="gu">## Important rule</span>
Always use early returns
</code></pre></div>    </div>
  </li>
  <li>Repeat critical instructions:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Reminder: use strict TypeScript.
&gt; Now, implement feature X.
</code></pre></div>    </div>
  </li>
  <li>Use <code class="language-plaintext highlighter-rouge">/compact</code> then reformulate</li>
</ol>

<h3 id="file-not-found">File not found</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: File not found: @src/missing.ts
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Verify the path:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ls </span>src/missing.ts
</code></pre></div>    </div>
  </li>
  <li>Use correct relative path:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@./src/missing.ts  (with ./)
@src/missing.ts    (without ./)
</code></pre></div>    </div>
  </li>
  <li>Check read permissions</li>
</ol>

<h2 id="execution-problems">Execution Problems</h2>

<h3 id="bash-command-blocked">Bash command blocked</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Claude is waiting for permission...
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Accept or reject manually</li>
  <li>Add to permissions:
    <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
 </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Bash(npm run:*)"</span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>    </div>
  </li>
  <li>Use Accept Edits mode (Shift+Tab)</li>
</ol>

<h3 id="error-tool-not-available">Error: “Tool not available”</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Tool 'WebFetch' is not available
</code></pre></div></div>

<p><strong>Cause</strong>: Tool is disabled or unavailable.</p>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Check permissions:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/permissions
</code></pre></div>    </div>
  </li>
  <li>
    <p>Enable tool in settings.json</p>
  </li>
  <li>Verify tool exists (some are experimental)</li>
</ol>

<h3 id="infinite-loop">Infinite loop</h3>

<p>Claude continues endlessly on a task.</p>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Interrupt with <code class="language-plaintext highlighter-rouge">Ctrl+C</code></li>
  <li>Use <code class="language-plaintext highlighter-rouge">Esc Esc</code> to go back</li>
  <li>Reformulate with a limit:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Do this task in maximum 3 steps
</code></pre></div>    </div>
  </li>
</ol>

<h2 id="performance-problems">Performance Problems</h2>

<h3 id="very-slow-responses">Very slow responses</h3>

<p><strong>Possible causes</strong>:</p>
<ul>
  <li>Context too large</li>
  <li>High server load</li>
  <li>Slow network connection</li>
</ul>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Reduce context:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/compact
</code></pre></div>    </div>
  </li>
  <li>Limit files:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Analyze only @src/api/auth.ts
</code></pre></div>    </div>
  </li>
  <li>Use a faster model:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--model</span> haiku
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="high-costs">High costs</h3>

<p><strong>Diagnosis</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cost
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">/compact</code> regularly</li>
  <li>Be more precise in prompts</li>
  <li>Avoid massive file reads</li>
  <li>Use Haiku for simple tasks</li>
</ol>

<h2 id="installation-problems">Installation Problems</h2>

<h3 id="npm-install-fails">npm install fails</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install</span> <span class="nt">-g</span> @anthropic-ai/claude-code
<span class="c"># Error: EACCES permission denied</span>
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Use npx:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx @anthropic-ai/claude-code
</code></pre></div>    </div>
  </li>
  <li>Fix npm permissions:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> ~/.npm-global
npm config <span class="nb">set </span>prefix <span class="s1">'~/.npm-global'</span>
<span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span>~/.npm-global/bin:<span class="nv">$PATH</span>
</code></pre></div>    </div>
  </li>
  <li>Use a Node version manager:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nvm use 20
npm <span class="nb">install</span> <span class="nt">-g</span> @anthropic-ai/claude-code
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="incompatible-node-version">Incompatible Node version</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Unsupported Node.js version
</code></pre></div></div>

<p><strong>Solution</strong>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nvm <span class="nb">install </span>18  <span class="c"># or 20</span>
nvm use 18
</code></pre></div></div>

<h2 id="hook-problems">Hook Problems</h2>

<h3 id="hook-doesnt-execute">Hook doesn’t execute</h3>

<p><strong>Checks</strong>:</p>

<ol>
  <li>Hook syntax:
    <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
 </span><span class="nl">"PreToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="w">
   </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Edit"</span><span class="p">,</span><span class="w">
   </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="w">
     </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
     </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"echo 'Hook triggered'"</span><span class="w">
   </span><span class="p">}]</span><span class="w">
 </span><span class="p">}]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>    </div>
  </li>
  <li>Debug logs:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CLAUDE_CODE_DEBUG</span><span class="o">=</span>1 claude
</code></pre></div>    </div>
  </li>
  <li>Script permissions:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">chmod</span> +x ./scripts/hook.sh
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="hook-blocks-claude">Hook blocks Claude</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Hook returned: BLOCK
</code></pre></div></div>

<p><strong>This is intentional</strong> if the hook detects a problem.</p>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Check hook conditions</li>
  <li>Modify the file to satisfy the hook</li>
  <li>Temporarily disable the hook</li>
</ol>

<h2 id="mcp-problems">MCP Problems</h2>

<h3 id="mcp-server-wont-start">MCP server won’t start</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Failed to connect to MCP server
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Verify installation:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx postgres-mcp-server <span class="nt">--version</span>
</code></pre></div>    </div>
  </li>
  <li>Test manually:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx postgres-mcp-server
</code></pre></div>    </div>
  </li>
  <li>Check environment variables:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="nv">$DATABASE_URL</span>
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="mcp-timeout">MCP timeout</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: MCP server timed out
</code></pre></div></div>

<p><strong>Solutions</strong>:</p>

<ol>
  <li>Increase timeout:
    <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"mcpServers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
 </span><span class="nl">"postgres"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
   </span><span class="nl">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="mi">30000</span><span class="w">
 </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>    </div>
  </li>
  <li>Check network connectivity to the service</li>
</ol>

<h2 id="general-diagnosis">General Diagnosis</h2>

<h3 id="debug-mode">Debug mode</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CLAUDE_CODE_DEBUG</span><span class="o">=</span>1 claude
</code></pre></div></div>

<p>Displays detailed logs to identify the problem.</p>

<h3 id="check-configuration">Check configuration</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude config list
</code></pre></div></div>

<h3 id="reset-configuration">Reset configuration</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-rf</span> ~/.claude
claude config <span class="nb">set </span>apiKey sk-ant-...
</code></pre></div></div>

<h3 id="check-logs">Check logs</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> ~/.claude/logs/claude-code.log
</code></pre></div></div>

<h2 id="troubleshooting-checklist">Troubleshooting Checklist</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>□ Internet connection OK?
□ API Key valid?
□ Node.js version compatible (≥18)?
□ Claude Code up to date?
□ File permissions OK?
□ Context not saturated?
□ Hooks configured correctly?
□ MCP servers accessible?
</code></pre></div></div>

<h2 id="getting-help">Getting Help</h2>

<h3 id="official-documentation">Official documentation</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/help
</code></pre></div></div>

<h3 id="community">Community</h3>

<ul>
  <li>GitHub Issues: github.com/anthropics/claude-code/issues</li>
  <li>Anthropic Discord</li>
  <li>Stack Overflow tag <code class="language-plaintext highlighter-rouge">claude-code</code></li>
</ul>

<h3 id="anthropic-support">Anthropic Support</h3>

<p>For Enterprise customers: support.anthropic.com</p>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 18</strong>, we’ll explore the <strong>status line and terminal customization</strong> - configure Claude Code display according to your preferences.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-billing-costs/">Day 16: Billing and costs</a></em></p>
]]></content:encoded>
        <pubDate>Sat, 27 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-troubleshooting-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-troubleshooting-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Claude Code Billing and Cost Optimization</title>
        <description>
          
            Master Claude Code billing: pricing model, /cost command, Max subscriptions, token optimization, and budget best practices.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code is powerful, but it consumes tokens. Understanding billing helps optimize your costs. Let’s see how to monitor and master your budget.</p>

<blockquote>
  <p>Beyond financial cost, don’t forget the <a href="/en/ai-ecological-impact-training-vs-inference-environmental-costs/">ecological impact of AI</a> - every token has a carbon footprint.</p>
</blockquote>

<h2 id="the-pricing-model">The Pricing Model</h2>

<h3 id="rates-by-model-december-2024">Rates by Model (December 2024)</h3>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Input (1M tokens)</th>
      <th>Output (1M tokens)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Claude Sonnet 4</td>
      <td>$3.00</td>
      <td>$15.00</td>
    </tr>
    <tr>
      <td>Claude Opus 4</td>
      <td>$15.00</td>
      <td>$75.00</td>
    </tr>
    <tr>
      <td>Claude Haiku 3.5</td>
      <td>$0.80</td>
      <td>$4.00</td>
    </tr>
  </tbody>
</table>

<h3 id="what-consumes-tokens">What Consumes Tokens</h3>

<table>
  <thead>
    <tr>
      <th>Action</th>
      <th>Tokens consumed</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Your prompt</td>
      <td>Input tokens</td>
    </tr>
    <tr>
      <td>Claude’s response</td>
      <td>Output tokens</td>
    </tr>
    <tr>
      <td>Files read</td>
      <td>Input tokens</td>
    </tr>
    <tr>
      <td>CLAUDE.md context</td>
      <td>Input tokens</td>
    </tr>
    <tr>
      <td>Conversation history</td>
      <td>Input tokens (cumulative)</td>
    </tr>
  </tbody>
</table>

<h2 id="the-cost-command">The /cost Command</h2>

<h3 id="view-session-cost">View Session Cost</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cost
</code></pre></div></div>

<p>Displays:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Session cost: $0.45
Input tokens: 45,000
Output tokens: 5,000
Duration: 45 minutes
</code></pre></div></div>

<h3 id="detailed-analysis">Detailed Analysis</h3>

<p>The cost breaks down as:</p>
<ul>
  <li><strong>Base context</strong>: CLAUDE.md, rules, configuration (~1,000-5,000 tokens)</li>
  <li><strong>Files read</strong>: Variable by size (~100-10,000 tokens per file)</li>
  <li><strong>Conversation</strong>: Cumulative (grows with session)</li>
  <li><strong>Responses</strong>: Variable by complexity</li>
</ul>

<h2 id="claude-subscriptions">Claude Subscriptions</h2>

<h3 id="claude-pro-20month">Claude Pro ($20/month)</h3>

<ul>
  <li>Access to Claude.ai</li>
  <li><strong>Claude Code not included</strong> (uses API)</li>
  <li>Priority usage on web</li>
</ul>

<h3 id="claude-max-100month-or-200month">Claude Max ($100/month or $200/month)</h3>

<p>Includes Claude Code with:</p>

<table>
  <thead>
    <tr>
      <th>Tier</th>
      <th>Price</th>
      <th>Tokens/day</th>
      <th>Ideal for</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Max 5x</td>
      <td>$100/month</td>
      <td>~5M tokens</td>
      <td>Moderate usage</td>
    </tr>
    <tr>
      <td>Max 20x</td>
      <td>$200/month</td>
      <td>~20M tokens</td>
      <td>Heavy usage</td>
    </tr>
  </tbody>
</table>

<h3 id="api-pay-as-you-go">API Pay-as-you-go</h3>

<p>Without Max subscription, you pay via API:</p>
<ul>
  <li>No fixed limit</li>
  <li>Billed on actual usage</li>
  <li>Requires API key</li>
</ul>

<h2 id="typical-consumption">Typical Consumption</h2>

<h3 id="per-task">Per Task</h3>

<table>
  <thead>
    <tr>
      <th>Task</th>
      <th>Estimated tokens</th>
      <th>Sonnet 4 cost</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Simple question</td>
      <td>1,000-2,000</td>
      <td>~$0.01</td>
    </tr>
    <tr>
      <td>Read + analyze file</td>
      <td>5,000-10,000</td>
      <td>~$0.03</td>
    </tr>
    <tr>
      <td>Feature implementation</td>
      <td>20,000-50,000</td>
      <td>~$0.15</td>
    </tr>
    <tr>
      <td>Complete refactoring</td>
      <td>50,000-100,000</td>
      <td>~$0.35</td>
    </tr>
    <tr>
      <td>Long session (2h)</td>
      <td>100,000-200,000</td>
      <td>~$0.70</td>
    </tr>
  </tbody>
</table>

<h3 id="per-day-average-developer">Per Day (Average Developer)</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Morning: Exploration + planning     ~30,000 tokens
Afternoon: Implementation           ~80,000 tokens
Evening: Tests + fixes              ~40,000 tokens
─────────────────────────────────────────────────
Daily total                        ~150,000 tokens
Estimated cost (Sonnet 4)          ~$0.50-1.00
</code></pre></div></div>

<h3 id="anthropic-statistic">Anthropic Statistic</h3>

<blockquote>
  <p>“The average developer uses ~$5-6 per day with Claude Code Max”</p>
</blockquote>

<h2 id="optimizing-your-costs">Optimizing Your Costs</h2>

<h3 id="1-use-compact-regularly">1. Use /compact Regularly</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/compact
</code></pre></div></div>

<p>Reduces conversation history and thus input tokens per prompt.</p>

<p><strong>Rule</strong>: <code class="language-plaintext highlighter-rouge">/compact</code> every 30-45 minutes of active session.</p>

<h3 id="2-be-precise-in-prompts">2. Be Precise in Prompts</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❌ Expensive (broad exploration)
&gt; Look at the code and suggest improvements

✅ Economical (targeted)
&gt; In @src/api/auth.ts, the validateToken function lines 45-60
  can be optimized to avoid redundant DB calls
</code></pre></div></div>

<h3 id="3-use-the-right-commands">3. Use the Right Commands</h3>

<table>
  <thead>
    <tr>
      <th>Situation</th>
      <th>Economical command</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Find a file</td>
      <td><code class="language-plaintext highlighter-rouge">@file.ts</code> instead of exploring</td>
    </tr>
    <tr>
      <td>Limited context</td>
      <td>Mention specific files</td>
    </tr>
    <tr>
      <td>New task</td>
      <td><code class="language-plaintext highlighter-rouge">/clear</code> then new prompt</td>
    </tr>
  </tbody>
</table>

<h3 id="4-choose-the-right-model">4. Choose the Right Model</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># For simple tasks → Haiku (8x cheaper)</span>
claude <span class="nt">--model</span> haiku

<span class="c"># For complex tasks → Sonnet (default)</span>
claude

<span class="c"># For critical tasks → Opus (5x more expensive)</span>
claude <span class="nt">--model</span> opus
</code></pre></div></div>

<h3 id="5-limit-file-reads">5. Limit File Reads</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❌ Expensive
&gt; Read all files in src/ folder and summarize

✅ Economical
&gt; Summarize the architecture based on @src/index.ts and @CLAUDE.md
</code></pre></div></div>

<h2 id="monitoring-your-consumption">Monitoring Your Consumption</h2>

<h3 id="during-session">During Session</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cost
</code></pre></div></div>

<h3 id="cost-history">Cost History</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># View recent usage</span>
claude usage

<span class="c"># Detailed usage</span>
claude usage <span class="nt">--detailed</span>
</code></pre></div></div>

<h3 id="budget-alerts">Budget Alerts</h3>

<p>Configure alerts on the Anthropic console:</p>
<ol>
  <li>Go to console.anthropic.com</li>
  <li>Settings → Billing → Alerts</li>
  <li>Set a threshold (e.g., $50/month)</li>
</ol>

<h2 id="budget-strategies">Budget Strategies</h2>

<h3 id="for-freelancers">For Freelancers</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Recommended monthly budget: $30-50
├── Daily sessions: ~$1-2
├── Occasional peaks: ~$5
└── Safety margin: 20%
</code></pre></div></div>

<h3 id="for-teams">For Teams</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Budget per developer: $100-150/month
├── Claude Max usage ($100-200)
└── OR API with cap
</code></pre></div></div>

<h3 id="for-enterprises">For Enterprises</h3>

<p>Available options:</p>
<ul>
  <li><strong>Claude for Enterprise</strong>: Negotiated rates</li>
  <li><strong>AWS Bedrock</strong>: Billed through AWS</li>
  <li><strong>GCP Vertex AI</strong>: Billed through GCP</li>
</ul>

<h2 id="access-mode-comparison">Access Mode Comparison</h2>

<table>
  <thead>
    <tr>
      <th>Mode</th>
      <th>Monthly cost</th>
      <th>Advantages</th>
      <th>Disadvantages</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>API only</td>
      <td>Variable</td>
      <td>Pay-as-you-go</td>
      <td>No cap</td>
    </tr>
    <tr>
      <td>Max 5x</td>
      <td>$100</td>
      <td>Predictable</td>
      <td>Token limit</td>
    </tr>
    <tr>
      <td>Max 20x</td>
      <td>$200</td>
      <td>Heavy usage</td>
      <td>More expensive</td>
    </tr>
    <tr>
      <td>Enterprise</td>
      <td>Negotiated</td>
      <td>Support, SLA</td>
      <td>Commitment</td>
    </tr>
  </tbody>
</table>

<h2 id="budget-tracking-template">Budget Tracking Template</h2>

<h3 id="daily-journal">Daily Journal</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gu">## 2024-12-31</span>

<span class="gu">### Sessions</span>
<span class="p">-</span> 09:00-11:00: Auth feature ($0.45)
<span class="p">-</span> 14:00-16:00: Tests ($0.30)
<span class="p">-</span> 16:30-17:00: Bugfix ($0.10)

<span class="gu">### Day total: $0.85</span>
<span class="gu">### Week total: $4.20</span>
<span class="gu">### Remaining budget: $25.80</span>
</code></pre></div></div>

<h3 id="tracking-script">Tracking Script</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># track-claude-cost.sh</span>

<span class="nv">DATE</span><span class="o">=</span><span class="si">$(</span><span class="nb">date</span> +%Y-%m-%d<span class="si">)</span>
<span class="nv">COST</span><span class="o">=</span><span class="si">$(</span>claude usage <span class="nt">--today</span> <span class="nt">--json</span> | jq <span class="s1">'.cost'</span><span class="si">)</span>

<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$DATE</span><span class="s2">,</span><span class="nv">$COST</span><span class="s2">"</span> <span class="o">&gt;&gt;</span> ~/claude-costs.csv
</code></pre></div></div>

<h2 id="reduce-costs-without-losing-productivity">Reduce Costs Without Losing Productivity</h2>

<h3 id="1-prepare-before-asking">1. Prepare Before Asking</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Before Claude session
1. Identify relevant files
2. Formulate a precise prompt
3. Gather necessary context

# During session
→ Targeted prompt = fewer tokens = cheaper
</code></pre></div></div>

<h3 id="2-use-smart-caching">2. Use Smart Caching</h3>

<p>Claude caches certain elements:</p>
<ul>
  <li>CLAUDE.md (reloaded once per session)</li>
  <li>Recently read files</li>
  <li>Conversation context</li>
</ul>

<p><strong>Tip</strong>: Keep a session open rather than opening several.</p>

<h3 id="3-task-batching">3. Task Batching</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❌ Expensive (context reloaded each time)
&gt; Add a log here
&gt; And also there
&gt; And here too

✅ Economical (single request)
&gt; Add logs in:
  - @src/api/auth.ts line 45
  - @src/api/users.ts line 30
  - @src/middleware/error.ts line 15
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 17</strong>, we’ll cover <strong>troubleshooting</strong> - solving common problems with Claude Code.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-cicd-headless/">Day 15: CI/CD and headless mode</a></em></p>
]]></content:encoded>
        <pubDate>Fri, 26 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-billing-costs-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-billing-costs-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>CI/CD and Headless Mode with Claude Code</title>
        <description>
          
            Integrate Claude Code into your CI/CD pipelines: headless mode, GitHub Actions, automatic code generation, and production best practices.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code isn’t limited to interactive use. With <strong>headless mode</strong>, you can integrate it into your CI/CD pipelines. Let’s see how to automate intelligently.</p>

<h2 id="headless-mode--p">Headless Mode: -p</h2>

<p>The <code class="language-plaintext highlighter-rouge">-p</code> (or <code class="language-plaintext highlighter-rouge">--print</code>) flag allows running Claude Code without interaction:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">-p</span> <span class="s2">"Explain what this code does"</span> &lt; file.js
</code></pre></div></div>

<p>Claude reads the prompt, executes the task, and returns the result to stdout.</p>

<h3 id="basic-syntax">Basic Syntax</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Simple prompt</span>
claude <span class="nt">-p</span> <span class="s2">"Generate a .gitignore file for Node.js"</span>

<span class="c"># With stdin input</span>
<span class="nb">cat </span>src/utils.ts | claude <span class="nt">-p</span> <span class="s2">"Find potential bugs"</span>

<span class="c"># With files in context</span>
claude <span class="nt">-p</span> <span class="s2">"Refactor @src/api/auth.ts to use async/await"</span>
</code></pre></div></div>

<h3 id="headless-mode-options">Headless Mode Options</h3>

<table>
  <thead>
    <tr>
      <th>Option</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">-p "prompt"</code></td>
      <td>Execute with this prompt</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--output-format json</code></td>
      <td>Structured JSON output</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--output-format text</code></td>
      <td>Text output (default)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--max-turns N</code></td>
      <td>Limit iterations</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">--allowedTools</code></td>
      <td>Restrict tools</td>
    </tr>
  </tbody>
</table>

<h2 id="github-actions-integration">GitHub Actions Integration</h2>

<h3 id="automatic-code-review-workflow">Automatic Code Review Workflow</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .github/workflows/claude-review.yml</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Claude Code Review</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">,</span> <span class="nv">synchronize</span><span class="pi">]</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">review</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Node.js</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-node@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">node-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">20'</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Claude Code</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">npm install -g @anthropic-ai/claude-code</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Get changed files</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">changed</span>
        <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
          <span class="s">echo "files=$(git diff --name-only origin/main...HEAD | tr '\n' ' ')" &gt;&gt; $GITHUB_OUTPUT</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Claude Review</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">ANTHROPIC_API_KEY</span><span class="pi">:</span> <span class="s">$</span>
        <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
          <span class="s">claude -p "Review these modified files and identify potential issues: $" \</span>
            <span class="s">--output-format json &gt; review.json</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post Review Comment</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="pi">|</span>
            <span class="s">const fs = require('fs');</span>
            <span class="s">const review = JSON.parse(fs.readFileSync('review.json', 'utf8'));</span>
            <span class="s">github.rest.issues.createComment({</span>
              <span class="s">issue_number: context.issue.number,</span>
              <span class="s">owner: context.repo.owner,</span>
              <span class="s">repo: context.repo.repo,</span>
              <span class="s">body: `## 🤖 Claude Code Review\n\n${review.result}`</span>
            <span class="s">});</span>
</code></pre></div></div>

<h3 id="test-generation-workflow">Test Generation Workflow</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .github/workflows/claude-tests.yml</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Generate Missing Tests</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="na">file</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">File</span><span class="nv"> </span><span class="s">to</span><span class="nv"> </span><span class="s">generate</span><span class="nv"> </span><span class="s">tests</span><span class="nv"> </span><span class="s">for'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">generate</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Claude Code</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">npm install -g @anthropic-ai/claude-code</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Generate Tests</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">ANTHROPIC_API_KEY</span><span class="pi">:</span> <span class="s">$</span>
        <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
          <span class="s">claude -p "Generate comprehensive tests for @$" \</span>
            <span class="s">--allowedTools Read,Write</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Create PR</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">peter-evans/create-pull-request@v6</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">test:</span><span class="nv"> </span><span class="s">add</span><span class="nv"> </span><span class="s">tests</span><span class="nv"> </span><span class="s">for</span><span class="nv"> </span><span class="s">$"</span>
          <span class="na">body</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Tests</span><span class="nv"> </span><span class="s">automatically</span><span class="nv"> </span><span class="s">generated</span><span class="nv"> </span><span class="s">by</span><span class="nv"> </span><span class="s">Claude</span><span class="nv"> </span><span class="s">Code"</span>
          <span class="na">branch</span><span class="pi">:</span> <span class="s">claude/tests-$</span>
</code></pre></div></div>

<h2 id="gitlab-ci-integration">GitLab CI Integration</h2>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .gitlab-ci.yml</span>
<span class="na">stages</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">review</span>
  <span class="pi">-</span> <span class="s">generate</span>

<span class="na">claude-review</span><span class="pi">:</span>
  <span class="na">stage</span><span class="pi">:</span> <span class="s">review</span>
  <span class="na">image</span><span class="pi">:</span> <span class="s">node:20</span>
  <span class="na">before_script</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">npm install -g @anthropic-ai/claude-code</span>
  <span class="na">script</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="pi">|</span>
      <span class="s">claude -p "Review the code in this MR and list issues" \</span>
        <span class="s">--output-format json &gt; review.json</span>
    <span class="pi">-</span> <span class="s">cat review.json</span>
  <span class="na">artifacts</span><span class="pi">:</span>
    <span class="na">paths</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">review.json</span>
  <span class="na">rules</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">if</span><span class="pi">:</span> <span class="s">$CI_PIPELINE_SOURCE == "merge_request_event"</span>

<span class="na">generate-docs</span><span class="pi">:</span>
  <span class="na">stage</span><span class="pi">:</span> <span class="s">generate</span>
  <span class="na">image</span><span class="pi">:</span> <span class="s">node:20</span>
  <span class="na">before_script</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">npm install -g @anthropic-ai/claude-code</span>
  <span class="na">script</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">claude -p "Generate JSDoc documentation for all src/**/*.ts files without documentation"</span>
  <span class="na">when</span><span class="pi">:</span> <span class="s">manual</span>
</code></pre></div></div>

<h2 id="production-use-cases">Production Use Cases</h2>

<h3 id="1-automatic-code-review">1. Automatic Code Review</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># scripts/review-pr.sh</span>

<span class="nv">PR_FILES</span><span class="o">=</span><span class="si">$(</span>git diff <span class="nt">--name-only</span> origin/main...HEAD<span class="si">)</span>

claude <span class="nt">-p</span> <span class="s2">"
You are a senior reviewer. Analyze these modified files:
</span><span class="nv">$PR_FILES</span><span class="s2">

Look for:
1. Potential bugs
2. Performance issues
3. Security vulnerabilities
4. Convention violations

Format: JSON with severity (high/medium/low)
"</span> <span class="nt">--output-format</span> json
</code></pre></div></div>

<h3 id="2-changelog-generation">2. Changelog Generation</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># scripts/generate-changelog.sh</span>

<span class="nv">LAST_TAG</span><span class="o">=</span><span class="si">$(</span>git describe <span class="nt">--tags</span> <span class="nt">--abbrev</span><span class="o">=</span>0<span class="si">)</span>
<span class="nv">COMMITS</span><span class="o">=</span><span class="si">$(</span>git log <span class="nv">$LAST_TAG</span>..HEAD <span class="nt">--pretty</span><span class="o">=</span>format:<span class="s2">"%s"</span><span class="si">)</span>

claude <span class="nt">-p</span> <span class="s2">"
Generate a changelog from these commits:
</span><span class="nv">$COMMITS</span><span class="s2">

Keep a Changelog format with sections:
- Added
- Changed
- Fixed
- Removed
"</span>
</code></pre></div></div>

<h3 id="3-automatic-code-migration">3. Automatic Code Migration</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># scripts/migrate-to-ts.sh</span>

<span class="k">for </span>file <span class="k">in </span>src/<span class="k">**</span>/<span class="k">*</span>.js<span class="p">;</span> <span class="k">do
  </span>claude <span class="nt">-p</span> <span class="s2">"Convert this JavaScript file to TypeScript with strict types: @</span><span class="nv">$file</span><span class="s2">"</span> <span class="se">\</span>
    <span class="nt">--allowedTools</span> Read,Write
<span class="k">done</span>
</code></pre></div></div>

<h3 id="4-security-audit">4. Security Audit</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .github/workflows/security-audit.yml</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Security Audit</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">schedule</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s1">'</span><span class="s">0</span><span class="nv"> </span><span class="s">2</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">1'</span>  <span class="c1"># Every Monday at 2am</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">audit</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Claude Code</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">npm install -g @anthropic-ai/claude-code</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Security Audit</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">ANTHROPIC_API_KEY</span><span class="pi">:</span> <span class="s">$</span>
        <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
          <span class="s">claude -p "</span>
            <span class="s">Perform a comprehensive security audit:</span>
            <span class="s">1. Scan dependencies for known vulnerabilities</span>
            <span class="s">2. Check for dangerous code patterns</span>
            <span class="s">3. Identify potentially exposed secrets</span>

            <span class="s">Generate a report with priorities.</span>
          <span class="s">" --output-format json &gt; security-report.json</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Upload Report</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">security-report</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">security-report.json</span>
</code></pre></div></div>

<h2 id="permission-control-in-ci">Permission Control in CI</h2>

<h3 id="recommended-strict-mode">Recommended Strict Mode</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">-p</span> <span class="s2">"Generate tests"</span> <span class="se">\</span>
  <span class="nt">--allowedTools</span> Read,Grep,Glob <span class="se">\</span>
  <span class="nt">--dangerously-skip-permissions</span>
</code></pre></div></div>

<p>⚠️ <code class="language-plaintext highlighter-rouge">--dangerously-skip-permissions</code> should only be used in isolated environments (CI containers).</p>

<h3 id="tool-restriction">Tool Restriction</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Read-only</span>
claude <span class="nt">-p</span> <span class="s2">"Analyze this code"</span> <span class="nt">--allowedTools</span> Read,Grep,Glob

<span class="c"># With limited write access</span>
claude <span class="nt">-p</span> <span class="s2">"Fix the bugs"</span> <span class="nt">--allowedTools</span> Read,Write,Edit

<span class="c"># Full access (dangerous)</span>
claude <span class="nt">-p</span> <span class="s2">"Setup the project"</span> <span class="nt">--allowedTools</span> <span class="s2">"*"</span>
</code></pre></div></div>

<h2 id="cost-management-in-ci">Cost Management in CI</h2>

<h3 id="limit-tokens">Limit Tokens</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Limit execution turns</span>
claude <span class="nt">-p</span> <span class="s2">"Quick review"</span> <span class="nt">--max-turns</span> 3

<span class="c"># For simple tasks</span>
claude <span class="nt">-p</span> <span class="s2">"Explain this function"</span> <span class="nt">--max-turns</span> 1
</code></pre></div></div>

<h3 id="cost-estimation">Cost Estimation</h3>

<table>
  <thead>
    <tr>
      <th>Task</th>
      <th>Estimated tokens</th>
      <th>Approximate cost</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Simple code review</td>
      <td>~5,000</td>
      <td>~$0.02</td>
    </tr>
    <tr>
      <td>Test generation</td>
      <td>~15,000</td>
      <td>~$0.05</td>
    </tr>
    <tr>
      <td>Complete refactoring</td>
      <td>~50,000</td>
      <td>~$0.15</td>
    </tr>
    <tr>
      <td>Security audit</td>
      <td>~30,000</td>
      <td>~$0.10</td>
    </tr>
  </tbody>
</table>

<h3 id="daily-budget">Daily Budget</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Example: limit runs per day</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">review</span><span class="pi">:</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">github.event.pull_request.draft == </span><span class="kc">false</span>
    <span class="c1"># Avoid reviewing drafts</span>
</code></pre></div></div>

<h2 id="json-output-format">JSON Output Format</h2>

<h3 id="response-structure">Response Structure</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">-p</span> <span class="s2">"Analyze this code"</span> <span class="nt">--output-format</span> json
</code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Code analysis..."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"cost"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"input_tokens"</span><span class="p">:</span><span class="w"> </span><span class="mi">1234</span><span class="p">,</span><span class="w">
    </span><span class="nl">"output_tokens"</span><span class="p">:</span><span class="w"> </span><span class="mi">567</span><span class="p">,</span><span class="w">
    </span><span class="nl">"total_cost"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.01</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"abc123"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"duration_ms"</span><span class="p">:</span><span class="w"> </span><span class="mi">5432</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="parsing-in-scripts">Parsing in Scripts</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nv">RESULT</span><span class="o">=</span><span class="si">$(</span>claude <span class="nt">-p</span> <span class="s2">"Check for bugs"</span> <span class="nt">--output-format</span> json<span class="si">)</span>

<span class="nv">BUGS</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$RESULT</span> | jq <span class="s1">'.result'</span><span class="si">)</span>
<span class="nv">COST</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$RESULT</span> | jq <span class="s1">'.cost.total_cost'</span><span class="si">)</span>

<span class="nb">echo</span> <span class="s2">"Bugs found: </span><span class="nv">$BUGS</span><span class="s2">"</span>
<span class="nb">echo</span> <span class="s2">"Cost: </span><span class="nv">$COST</span><span class="s2">"</span>
</code></pre></div></div>

<h2 id="cicd-best-practices">CI/CD Best Practices</h2>

<h3 id="1-cache-claude-artifacts">1. Cache Claude Artifacts</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache Claude artifacts</span>
  <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v4</span>
  <span class="na">with</span><span class="pi">:</span>
    <span class="na">path</span><span class="pi">:</span> <span class="s">~/.claude</span>
    <span class="na">key</span><span class="pi">:</span> <span class="s">claude-$-$</span>
</code></pre></div></div>

<h3 id="2-reproducible-environment">2. Reproducible Environment</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Claude environment</span>
  <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
    <span class="s">npm install -g @anthropic-ai/claude-code@latest</span>
    <span class="s">echo "CLAUDE_CODE_USE_BEDROCK=0" &gt;&gt; $GITHUB_ENV</span>
</code></pre></div></div>

<h3 id="3-error-handling">3. Error Handling</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nb">set</span> <span class="nt">-e</span>

<span class="k">if</span> <span class="o">!</span> claude <span class="nt">-p</span> <span class="s2">"Task"</span> <span class="nt">--output-format</span> json <span class="o">&gt;</span> result.json<span class="p">;</span> <span class="k">then
  </span><span class="nb">echo</span> <span class="s2">"Claude failed, falling back to manual review"</span>
  <span class="nb">exit </span>0  <span class="c"># Don't block the pipeline</span>
<span class="k">fi</span>
</code></pre></div></div>

<h3 id="4-detailed-logging">4. Detailed Logging</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Claude with logging</span>
  <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
    <span class="s">claude -p "Task" 2&gt;&amp;1 | tee claude-output.log</span>
  <span class="na">env</span><span class="pi">:</span>
    <span class="na">CLAUDE_CODE_DEBUG</span><span class="pi">:</span> <span class="s2">"</span><span class="s">1"</span>
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 16</strong>, we’ll talk about <strong>billing and cost optimization</strong> - understanding and mastering your Claude Code consumption.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-vscode-jetbrains/">Day 14: VS Code and JetBrains</a></em></p>
]]></content:encoded>
        <pubDate>Thu, 25 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-cicd-headless-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-cicd-headless-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Claude Code in VS Code and JetBrains</title>
        <description>
          
            Integrate Claude Code into VS Code and JetBrains: installation, configuration, features, and comparison with the terminal experience.
          
        </description>
        <content:encoded><![CDATA[<p>So far, we’ve used Claude Code in the terminal. But there are also extensions for <strong>VS Code</strong> and <strong>JetBrains</strong>. Let’s see how to leverage the graphical interface.</p>

<h2 id="two-complementary-approaches">Two Complementary Approaches</h2>

<table>
  <thead>
    <tr>
      <th>Aspect</th>
      <th>Terminal</th>
      <th>IDE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Speed</td>
      <td>⭐⭐⭐</td>
      <td>⭐⭐</td>
    </tr>
    <tr>
      <td>Visualization</td>
      <td>Text only</td>
      <td>Visual diffs</td>
    </tr>
    <tr>
      <td>Integration</td>
      <td>Native shell</td>
      <td>IDE workspace</td>
    </tr>
    <tr>
      <td>Flexibility</td>
      <td>Maximum</td>
      <td>Guided</td>
    </tr>
  </tbody>
</table>

<h2 id="claude-code-for-vs-code">Claude Code for VS Code</h2>

<h3 id="installation">Installation</h3>

<ol>
  <li>Open VS Code</li>
  <li>Extensions (Ctrl+Shift+X)</li>
  <li>Search for “Claude Code”</li>
  <li>Install the official Anthropic extension</li>
</ol>

<p>Or via terminal:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>code <span class="nt">--install-extension</span> anthropic.claude-code
</code></pre></div></div>

<h3 id="configuration">Configuration</h3>

<p>After installation, configure via VS Code settings:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"claude-code.apiKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${env:ANTHROPIC_API_KEY}"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"claude-sonnet-4-20250514"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.autoApprove"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="vs-code-features">VS Code Features</h3>

<h4 id="claude-code-panel">Claude Code Panel</h4>

<p>Accessible via the icon in the sidebar or <code class="language-plaintext highlighter-rouge">Ctrl+Shift+P</code> → “Claude Code: Open Panel”.</p>

<h4 id="available-commands">Available Commands</h4>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>Shortcut</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Open Panel</td>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+Shift+C</code></td>
      <td>Open Claude panel</td>
    </tr>
    <tr>
      <td>Explain Selection</td>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+Shift+E</code></td>
      <td>Explain selected code</td>
    </tr>
    <tr>
      <td>Fix Selection</td>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+Shift+F</code></td>
      <td>Fix selected code</td>
    </tr>
    <tr>
      <td>Generate Tests</td>
      <td><code class="language-plaintext highlighter-rouge">Ctrl+Shift+T</code></td>
      <td>Generate tests</td>
    </tr>
  </tbody>
</table>

<h4 id="inline-suggestions">Inline Suggestions</h4>

<p>Claude can suggest modifications directly in the editor:</p>

<ol>
  <li>Select code</li>
  <li>Right-click → “Ask Claude”</li>
  <li>Describe the desired modification</li>
  <li>View the diff and accept/reject</li>
</ol>

<h3 id="typical-vs-code-workflow">Typical VS Code Workflow</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Open Claude Code panel
2. Describe the task
3. Claude proposes modifications
4. Review the diff in the editor
5. Accept or request adjustments
</code></pre></div></div>

<h2 id="claude-code-for-jetbrains">Claude Code for JetBrains</h2>

<h3 id="supported-ides">Supported IDEs</h3>

<ul>
  <li>IntelliJ IDEA</li>
  <li>PyCharm</li>
  <li>WebStorm</li>
  <li>PhpStorm</li>
  <li>GoLand</li>
  <li>Rider</li>
  <li>And all other JetBrains IDEs</li>
</ul>

<h3 id="installation-1">Installation</h3>

<ol>
  <li>Settings → Plugins</li>
  <li>Marketplace → Search “Claude Code”</li>
  <li>Install and restart IDE</li>
</ol>

<p>Or via the JetBrains Marketplace website.</p>

<h3 id="configuration-1">Configuration</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Settings → Tools → Claude Code
</code></pre></div></div>

<p>Available options:</p>
<ul>
  <li>API Key</li>
  <li>Default model</li>
  <li>Auto-approval level</li>
  <li>VCS integration</li>
</ul>

<h3 id="jetbrains-features">JetBrains Features</h3>

<h4 id="tool-window">Tool Window</h4>

<p>Accessible via View → Tool Windows → Claude Code.</p>

<h4 id="context-actions">Context Actions</h4>

<p>Right-click on code:</p>
<ul>
  <li>“Ask Claude about this”</li>
  <li>“Refactor with Claude”</li>
  <li>“Generate tests with Claude”</li>
  <li>“Add documentation with Claude”</li>
</ul>

<h4 id="vcs-integration">VCS Integration</h4>

<p>Claude Code integrates with JetBrains Git features:</p>
<ul>
  <li>Generated commit messages</li>
  <li>Assisted diff reviews</li>
  <li>PR descriptions</li>
</ul>

<h3 id="smart-inspections">Smart Inspections</h3>

<p>Claude can integrate with JetBrains inspections:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Settings → Editor → Inspections → Claude Code
</code></pre></div></div>

<ul>
  <li>Code smell detection</li>
  <li>Refactoring suggestions</li>
  <li>Security warnings</li>
</ul>

<h2 id="experience-comparison">Experience Comparison</h2>

<h3 id="terminal-the-power">Terminal: The Power</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude

<span class="o">&gt;</span> Refactor the entire auth module to use JWT
<span class="o">&gt;</span> Then create the tests
<span class="o">&gt;</span> And update the documentation

<span class="c"># Claude works on multiple files in sequence</span>
</code></pre></div></div>

<p>Advantages:</p>
<ul>
  <li>Complex commands at once</li>
  <li>Automated workflows</li>
  <li>Scripts and pipes</li>
  <li>Maximum performance</li>
</ul>

<h3 id="ide-the-visualization">IDE: The Visualization</h3>

<p>Advantages:</p>
<ul>
  <li>Side-by-side visual diffs</li>
  <li>Easier code navigation</li>
  <li>Integration with IDE tools</li>
  <li>More intuitive review</li>
</ul>

<h3 id="my-advice">My Advice</h3>

<p>Use <strong>both</strong> depending on the task:</p>

<table>
  <thead>
    <tr>
      <th>Task</th>
      <th>Best choice</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Massive refactoring</td>
      <td>Terminal</td>
    </tr>
    <tr>
      <td>Quick fix</td>
      <td>IDE</td>
    </tr>
    <tr>
      <td>New project</td>
      <td>Terminal</td>
    </tr>
    <tr>
      <td>Code review</td>
      <td>IDE</td>
    </tr>
    <tr>
      <td>Automation</td>
      <td>Terminal</td>
    </tr>
    <tr>
      <td>Code discovery</td>
      <td>IDE</td>
    </tr>
  </tbody>
</table>

<h2 id="synchronization-between-both">Synchronization Between Both</h2>

<h3 id="the-same-claudemd">The Same CLAUDE.md</h3>

<p>Both interfaces read the same <code class="language-plaintext highlighter-rouge">CLAUDE.md</code>:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># CLAUDE.md</span>

<span class="gu">## Conventions</span>
<span class="p">-</span> Strict TypeScript
<span class="p">-</span> Tests with Vitest
<span class="p">-</span> Conventional commits
</code></pre></div></div>

<p>These rules apply whether you use terminal or IDE.</p>

<h3 id="the-same-permissions">The Same Permissions</h3>

<p>The <code class="language-plaintext highlighter-rouge">.claude/settings.json</code> file is shared:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Bash(npm run:*)"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Read(./.env)"</span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="separate-sessions">Separate Sessions</h3>

<p>Each interface has its own sessions. A <code class="language-plaintext highlighter-rouge">/compact</code> in the terminal doesn’t affect the IDE extension.</p>

<h2 id="advanced-ide-features">Advanced IDE Features</h2>

<h3 id="quick-actions-vs-code">Quick Actions (VS Code)</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Ctrl+. on selected code
→ "Claude: Suggest improvement"
→ "Claude: Explain this"
→ "Claude: Find bugs"
</code></pre></div></div>

<h3 id="live-templates-jetbrains">Live Templates (JetBrains)</h3>

<p>Create templates that invoke Claude:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Settings → Editor → Live Templates → + Claude Code
</code></pre></div></div>

<p>Template example:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Abbreviation: cdoc
Description: Generate documentation with Claude
Template text: // $SELECTION$ - TODO: Ask Claude for documentation
</code></pre></div></div>

<h3 id="assisted-debugging">Assisted Debugging</h3>

<p>In both IDEs, Claude can help with debugging:</p>

<ol>
  <li>Place a breakpoint</li>
  <li>Start debugging</li>
  <li>On exception: “Ask Claude why this failed”</li>
  <li>Claude analyzes context and stack trace</li>
</ol>

<h2 id="optimal-configuration">Optimal Configuration</h2>

<h3 id="vs-code-settingsjson">VS Code settings.json</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"claude-code.model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"claude-sonnet-4-20250514"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.autoApprove"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.showInlineHints"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.diffViewMode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sideBySide"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"claude-code.contextSize"</span><span class="p">:</span><span class="w"> </span><span class="s2">"auto"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"editor.inlineSuggest.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="jetbrains-settings">JetBrains settings</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Tools → Claude Code:
  ☑ Show inline suggestions
  ☑ Enable context-aware completions
  ☐ Auto-approve file modifications
  Model: claude-sonnet-4-20250514
  Context window: Auto
</code></pre></div></div>

<h2 id="ide-extension-limitations">IDE Extension Limitations</h2>

<h3 id="compared-to-terminal">Compared to Terminal</h3>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Terminal</th>
      <th>IDE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Custom subagents</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Hooks</td>
      <td>✅</td>
      <td>Partial</td>
    </tr>
    <tr>
      <td>MCP servers</td>
      <td>✅</td>
      <td>Partial</td>
    </tr>
    <tr>
      <td>Skills</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Plugins marketplace</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
    <tr>
      <td>Headless mode</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
  </tbody>
</table>

<h3 id="recommendation">Recommendation</h3>

<p>For <strong>advanced</strong> usage, prefer the terminal. IDE extensions are ideal for:</p>
<ul>
  <li>Quick fixes</li>
  <li>Visual review</li>
  <li>Users less comfortable with terminal</li>
</ul>

<h2 id="recommended-hybrid-workflow">Recommended Hybrid Workflow</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Terminal for complex tasks
   claude
   &gt; Plan and implement the new caching system

2. IDE for review and adjustments
   - Open modified files
   - Review diffs visually
   - Quick fixes with extension

3. Terminal to finalize
   claude
   &gt; Create tests and verify everything passes
</code></pre></div></div>

<h2 id="extension-troubleshooting">Extension Troubleshooting</h2>

<h3 id="vs-code-extension-wont-start">VS Code: Extension Won’t Start</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Verify installation</span>
code <span class="nt">--list-extensions</span> | <span class="nb">grep </span>claude

<span class="c"># Reinstall</span>
code <span class="nt">--uninstall-extension</span> anthropic.claude-code
code <span class="nt">--install-extension</span> anthropic.claude-code
</code></pre></div></div>

<h3 id="jetbrains-performance-issues">JetBrains: Performance Issues</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Help → Diagnostic Tools → Activity Monitor
</code></pre></div></div>

<p>If Claude Code consumes too much:</p>
<ul>
  <li>Reduce context size</li>
  <li>Disable inline suggestions</li>
  <li>Limit scope to open files</li>
</ul>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 15</strong>, we’ll go into production mode with <strong>CI/CD and headless mode</strong> - integrating Claude Code into your automation pipelines.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-mcp-integration/">Day 13: MCP</a></em></p>
]]></content:encoded>
        <pubDate>Wed, 24 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-vscode-jetbrains-en/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-vscode-jetbrains-en/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>MCP: Connecting Claude Code to Your Tools</title>
        <description>
          
            Complete MCP guide in Claude Code: server installation, configuration, OAuth authentication, and practical integrations with your tools.
          
        </description>
        <content:encoded><![CDATA[<p>I’ve already explored the MCP protocol in my article <a href="/en/anthropic-mcp-model-context-protocol-llm-integration/">Model Context Protocol (MCP): Revolution in LLM Integration</a>. Today, we’ll see how to use it concretely in Claude Code.</p>

<h2 id="reminder-what-is-mcp">Reminder: What is MCP?</h2>

<p><strong>Model Context Protocol</strong> is an open standard that allows Claude to connect to external tools:</p>
<ul>
  <li>Databases</li>
  <li>Issue trackers (Jira, GitHub Issues)</li>
  <li>Cloud services</li>
  <li>Internal APIs</li>
</ul>

<p>It’s the <strong>“USB-C of AI”</strong>: a universal interface.</p>

<h2 id="the-three-transport-types">The Three Transport Types</h2>

<table>
  <thead>
    <tr>
      <th>Transport</th>
      <th>Usage</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>HTTP</strong></td>
      <td>Remote servers</td>
      <td>Cloud services</td>
    </tr>
    <tr>
      <td><strong>Stdio</strong></td>
      <td>Local processes</td>
      <td>CLI tools</td>
    </tr>
    <tr>
      <td><strong>SSE</strong></td>
      <td>Legacy (deprecated)</td>
      <td>Old servers</td>
    </tr>
  </tbody>
</table>

<h2 id="installing-an-mcp-server">Installing an MCP Server</h2>

<h3 id="http-server-recommended-for-cloud">HTTP Server (recommended for cloud)</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http github https://mcp.github.com/mcp
</code></pre></div></div>

<p>With authentication:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http secure-api <span class="se">\</span>
  <span class="nt">--header</span> <span class="s2">"Authorization: Bearer </span><span class="nv">$TOKEN</span><span class="s2">"</span> <span class="se">\</span>
  https://api.example.com/mcp
</code></pre></div></div>

<h3 id="stdio-server-local-process">Stdio Server (local process)</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> stdio postgres <span class="se">\</span>
  <span class="nt">--env</span> <span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">"postgres://user:pass@localhost/db"</span> <span class="se">\</span>
  <span class="nt">--</span> npx postgres-mcp-server
</code></pre></div></div>

<h3 id="example-airtable">Example: Airtable</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> stdio airtable <span class="se">\</span>
  <span class="nt">--env</span> <span class="nv">AIRTABLE_API_KEY</span><span class="o">=</span><span class="nv">$AIRTABLE_KEY</span> <span class="se">\</span>
  <span class="nt">--</span> npx <span class="nt">-y</span> airtable-mcp-server
</code></pre></div></div>

<h2 id="the-three-configuration-scopes">The Three Configuration Scopes</h2>

<h3 id="1-local-scope-personal-this-project">1. Local Scope (personal, this project)</h3>

<p>Stored in <code class="language-plaintext highlighter-rouge">~/.claude.json</code>, visible only to you.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--scope</span> <span class="nb">local</span> ...
</code></pre></div></div>

<h3 id="2-project-scope-team-this-repo">2. Project Scope (team, this repo)</h3>

<p>Stored in <code class="language-plaintext highlighter-rouge">.mcp.json</code> at project root, versioned with Git.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--scope</span> project ...
</code></pre></div></div>

<h3 id="3-user-scope-personal-all-projects">3. User Scope (personal, all projects)</h3>

<p>Stored in <code class="language-plaintext highlighter-rouge">~/.claude.json</code>, available everywhere.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--scope</span> user ...
</code></pre></div></div>

<h2 id="managing-mcp-servers">Managing MCP Servers</h2>

<h3 id="list-servers">List Servers</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp list
</code></pre></div></div>

<h3 id="view-details">View Details</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp get github
</code></pre></div></div>

<h3 id="remove-a-server">Remove a Server</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp remove github
</code></pre></div></div>

<h3 id="check-status-in-claude-code">Check Status in Claude Code</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/mcp
</code></pre></div></div>

<h2 id="configuration-in-mcpjson">Configuration in .mcp.json</h2>

<p>To share with the team:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"mcpServers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"github"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"transport"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://mcp.github.com/mcp"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"postgres"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"transport"</span><span class="p">:</span><span class="w"> </span><span class="s2">"stdio"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npx"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"args"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"postgres-mcp-server"</span><span class="p">],</span><span class="w">
      </span><span class="nl">"env"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"DATABASE_URL"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${DATABASE_URL}"</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"jira"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"transport"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://mcp.atlassian.com/jira"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"Authorization"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bearer ${JIRA_TOKEN}"</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="oauth-authentication">OAuth Authentication</h2>

<p>Some MCP servers support OAuth 2.0:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/mcp
</code></pre></div></div>

<p>Then select the server and follow the authentication flow in the browser.</p>

<h2 id="practical-integration-examples">Practical Integration Examples</h2>

<h3 id="github-issues-and-prs">GitHub: Issues and PRs</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http github https://mcp.github.com/mcp
</code></pre></div></div>

<p>Usage:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Create a GitHub issue for the authentication bug
&gt; List open PRs on this repo
&gt; Assign me to PR #42
</code></pre></div></div>

<h3 id="jira-project-management">Jira: Project Management</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http jira <span class="se">\</span>
  <span class="nt">--header</span> <span class="s2">"Authorization: Bearer </span><span class="nv">$JIRA_TOKEN</span><span class="s2">"</span> <span class="se">\</span>
  https://mcp.atlassian.com/jira
</code></pre></div></div>

<p>Usage:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Create a Jira ticket for this feature
&gt; Move ticket PROJ-123 to "In Review"
&gt; What are my assigned tickets?
</code></pre></div></div>

<h3 id="postgresql-database">PostgreSQL: Database</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> stdio postgres <span class="se">\</span>
  <span class="nt">--env</span> <span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">"postgres://..."</span> <span class="se">\</span>
  <span class="nt">--</span> npx postgres-mcp-server
</code></pre></div></div>

<p>Usage:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Show me the users table schema
&gt; Write a query for users inactive for 30 days
&gt; How many records in the orders table?
</code></pre></div></div>

<h3 id="notion-documentation">Notion: Documentation</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http notion https://mcp.notion.com/mcp
</code></pre></div></div>

<p>Usage:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Add this documentation to the "Architecture" page
&gt; Search for last week's meeting notes
</code></pre></div></div>

<h2 id="token-management">Token Management</h2>

<h3 id="mcp-token-limit">MCP Token Limit</h3>

<p>By default, Claude limits MCP responses to <strong>25,000 tokens</strong>.</p>

<p>To increase:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">MAX_MCP_OUTPUT_TOKENS</span><span class="o">=</span>50000
</code></pre></div></div>

<h3 id="warning-at-10000-tokens">Warning at 10,000 Tokens</h3>

<p>Claude warns you if an MCP response exceeds 10,000 tokens.</p>

<h2 id="workflow-with-mcp">Workflow with MCP</h2>

<h3 id="example-feature-from-a-jira-ticket">Example: Feature from a Jira Ticket</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># 1. Read the ticket
&gt; Show me details for ticket PROJ-456

# 2. Claude reads via MCP and understands requirements

# 3. Plan
&gt; ultrathink. Propose an implementation plan

# 4. Implement
&gt; Implement step 1

# 5. Update Jira
&gt; Update ticket PROJ-456 with status "In Progress"
  and add a comment on progress
</code></pre></div></div>

<h3 id="example-debug-with-sentry">Example: Debug with Sentry</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude mcp add <span class="nt">--transport</span> http sentry <span class="se">\</span>
  <span class="nt">--header</span> <span class="s2">"Authorization: Bearer </span><span class="nv">$SENTRY_TOKEN</span><span class="s2">"</span> <span class="se">\</span>
  https://mcp.sentry.io
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; What are the most frequent errors this week?

# Claude analyzes via MCP

&gt; Fix the error "TypeError: Cannot read property 'id' of null"
  appearing in src/api/users.ts
</code></pre></div></div>

<h2 id="mcp-security">MCP Security</h2>

<h3 id="verify-servers">Verify Servers</h3>

<p>Third-party MCP servers may have access to your data. Check:</p>
<ul>
  <li>Server source</li>
  <li>Requested permissions</li>
  <li>Privacy policy</li>
</ul>

<h3 id="environment-variables">Environment Variables</h3>

<p>Never hardcode tokens:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"env"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"API_KEY"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${MY_API_KEY}"</span><span class="w">  </span><span class="err">//</span><span class="w"> </span><span class="err">✅</span><span class="w"> </span><span class="err">Env</span><span class="w"> </span><span class="err">variable</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"env"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"API_KEY"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sk-abc123..."</span><span class="w">   </span><span class="err">//</span><span class="w"> </span><span class="err">❌</span><span class="w"> </span><span class="err">Plain</span><span class="w"> </span><span class="err">token</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="creating-your-own-mcp-server">Creating Your Own MCP Server</h2>

<p>For internal needs, you can create your own MCP server.</p>

<p>Basic structure (TypeScript):</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Server</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@modelcontextprotocol/sdk/server</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">server</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Server</span><span class="p">({</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">my-server</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">version</span><span class="p">:</span> <span class="dl">'</span><span class="s1">1.0.0</span><span class="dl">'</span>
<span class="p">});</span>

<span class="c1">// Define exposed tools</span>
<span class="nx">server</span><span class="p">.</span><span class="nf">setRequestHandler</span><span class="p">(</span><span class="dl">'</span><span class="s1">tools/list</span><span class="dl">'</span><span class="p">,</span> <span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span>
  <span class="na">tools</span><span class="p">:</span> <span class="p">[{</span>
    <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">my_tool</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">description</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Description of my tool</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">inputSchema</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">object</span><span class="dl">'</span><span class="p">,</span>
      <span class="na">properties</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">param1</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">string</span><span class="dl">'</span> <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}]</span>
<span class="p">}));</span>

<span class="c1">// Implement the tool</span>
<span class="nx">server</span><span class="p">.</span><span class="nf">setRequestHandler</span><span class="p">(</span><span class="dl">'</span><span class="s1">tools/call</span><span class="dl">'</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">request</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="nx">name</span><span class="p">,</span> <span class="na">arguments</span><span class="p">:</span> <span class="nx">args</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">params</span><span class="p">;</span>
  <span class="c1">// Tool logic...</span>
  <span class="k">return</span> <span class="p">{</span> <span class="na">result</span><span class="p">:</span> <span class="dl">'</span><span class="s1">...</span><span class="dl">'</span> <span class="p">};</span>
<span class="p">});</span>

<span class="nx">server</span><span class="p">.</span><span class="nf">start</span><span class="p">();</span>
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 14</strong>, we’ll see <strong>Claude Code in VS Code and JetBrains</strong> - IDE integration for a graphical experience.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-hooks/">Day 12: Hooks</a></em></p>
]]></content:encoded>
        <pubDate>Tue, 23 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-mcp-integration/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-mcp-integration/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Hooks: Automating Event Reactions</title>
        <description>
          
            Master Claude Code hooks: 9 event types, configuration, use cases for security, formatting, and automation.
          
        </description>
        <content:encoded><![CDATA[<p>Hooks allow you to execute automatic actions in response to Claude Code events. They’re the bridge between Claude and your development tools. Today, we’ll see how to use and create them.</p>

<h2 id="what-is-a-hook">What is a Hook?</h2>

<p>A hook is an <strong>event handler</strong> that executes when Claude Code does something specific:</p>
<ul>
  <li>Before/after tool execution</li>
  <li>At session start/end</li>
  <li>When user submits a prompt</li>
  <li>etc.</li>
</ul>

<h2 id="the-9-hook-types">The 9 Hook Types</h2>

<table>
  <thead>
    <tr>
      <th>Hook</th>
      <th>Trigger</th>
      <th>Can Block</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SessionStart</code></td>
      <td>Session start</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SessionEnd</code></td>
      <td>Session end</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">PreToolUse</code></td>
      <td>Before tool execution</td>
      <td><strong>Yes</strong></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">PostToolUse</code></td>
      <td>After tool execution</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">UserPromptSubmit</code></td>
      <td>Prompt submission</td>
      <td><strong>Yes</strong></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Notification</code></td>
      <td>Claude notification</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Stop</code></td>
      <td>User stop</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SubagentStop</code></td>
      <td>Subagent end</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">PreCompact</code></td>
      <td>Before context compaction</td>
      <td>No</td>
    </tr>
  </tbody>
</table>

<h2 id="hook-configuration">Hook Configuration</h2>

<h3 id="location">Location</h3>

<p>In <code class="language-plaintext highlighter-rouge">.claude/settings.json</code>:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"HookName"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"optional-pattern"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"path/to/script.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="hook-structure">Hook Structure</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"PostToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Edit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"prettier --write $FILE"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><strong>Explanation:</strong></p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">PostToolUse</code>: Triggers after tool use</li>
  <li><code class="language-plaintext highlighter-rouge">matcher: "Edit"</code>: Only when “Edit” tool is used</li>
  <li><code class="language-plaintext highlighter-rouge">command</code>: The command to execute</li>
</ul>

<h2 id="useful-hook-examples">Useful Hook Examples</h2>

<h3 id="hook-auto-format-after-edit">Hook: Auto-format After Edit</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"PostToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Edit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"prettier --write $EDITED_FILE"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"prettier --write $WRITTEN_FILE"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="hook-git-check-before-exit">Hook: Git Check Before Exit</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"Stop"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/.claude/hooks/git-check.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">git-check.sh</code> script:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Check for uncommitted changes</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nt">-n</span> <span class="si">$(</span>git status <span class="nt">--porcelain</span><span class="si">)</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"⚠️  Warning: uncommitted changes!"</span>
    git status <span class="nt">--short</span>
<span class="k">fi</span>
</code></pre></div></div>

<h3 id="hook-block-dangerous-patterns">Hook: Block Dangerous Patterns</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"PreToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bash"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/.claude/hooks/security-check.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">security-check.sh</code> script:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Read command from stdin</span>
<span class="nb">read</span> <span class="nt">-r</span> <span class="nb">command</span>

<span class="c"># Dangerous patterns</span>
<span class="nv">dangerous_patterns</span><span class="o">=(</span>
    <span class="s2">"rm -rf /"</span>
    <span class="s2">"rm -rf ~"</span>
    <span class="s2">"sudo rm"</span>
    <span class="s2">"&gt; /dev/"</span>
    <span class="s2">"mkfs"</span>
    <span class="s2">"dd if="</span>
    <span class="s2">"chmod 777"</span>
<span class="o">)</span>

<span class="k">for </span>pattern <span class="k">in</span> <span class="s2">"</span><span class="k">${</span><span class="nv">dangerous_patterns</span><span class="p">[@]</span><span class="k">}</span><span class="s2">"</span><span class="p">;</span> <span class="k">do
    if</span> <span class="o">[[</span> <span class="s2">"</span><span class="nv">$command</span><span class="s2">"</span> <span class="o">==</span> <span class="k">*</span><span class="s2">"</span><span class="nv">$pattern</span><span class="s2">"</span><span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"BLOCKED: Dangerous command detected: </span><span class="nv">$pattern</span><span class="s2">"</span>
        <span class="nb">exit </span>1  <span class="c"># Exit 1 = block action</span>
    <span class="k">fi
done

</span><span class="nb">exit </span>0  <span class="c"># Exit 0 = allow</span>
</code></pre></div></div>

<h3 id="hook-log-actions">Hook: Log Actions</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"PostToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/.claude/hooks/log-action.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">log-action.sh</code> script:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Read tool info from stdin (JSON)</span>
<span class="nb">read</span> <span class="nt">-r</span> json

<span class="c"># Extract info with jq</span>
<span class="nv">tool</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$json</span><span class="s2">"</span> | jq <span class="nt">-r</span> <span class="s1">'.tool'</span><span class="si">)</span>
<span class="nv">timestamp</span><span class="o">=</span><span class="si">$(</span><span class="nb">date</span> +<span class="s2">"%Y-%m-%d %H:%M:%S"</span><span class="si">)</span>

<span class="c"># Log</span>
<span class="nb">echo</span> <span class="s2">"[</span><span class="nv">$timestamp</span><span class="s2">] Tool: </span><span class="nv">$tool</span><span class="s2">"</span> <span class="o">&gt;&gt;</span> ~/.claude/logs/actions.log
</code></pre></div></div>

<h3 id="hook-task-completion-notification">Hook: Task Completion Notification</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"Stop"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/.claude/hooks/notify.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">notify.sh</code> script (macOS):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
osascript <span class="nt">-e</span> <span class="s1">'display notification "Claude has finished" with title "Claude Code"'</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">notify.sh</code> script (Linux):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
notify-send <span class="s2">"Claude Code"</span> <span class="s2">"Claude has finished"</span>
</code></pre></div></div>

<h3 id="hook-environment-setup-at-start">Hook: Environment Setup at Start</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"SessionStart"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
        </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/.claude/hooks/session-start.sh"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">session-start.sh</code> script:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Activate Python virtual environment if present</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nt">-f</span> <span class="s2">".venv/bin/activate"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">source</span> .venv/bin/activate
<span class="k">fi</span>

<span class="c"># Load environment variables</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nt">-f</span> <span class="s2">".env.development"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">export</span> <span class="si">$(</span><span class="nb">grep</span> <span class="nt">-v</span> <span class="s1">'^#'</span> .env.development | xargs<span class="si">)</span>
<span class="k">fi</span>

<span class="c"># Check prerequisites</span>
<span class="nb">command</span> <span class="nt">-v</span> node <span class="o">&gt;</span>/dev/null <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"⚠️  Node.js not found"</span>
<span class="nb">command</span> <span class="nt">-v</span> npm <span class="o">&gt;</span>/dev/null <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"⚠️  npm not found"</span>
</code></pre></div></div>

<h2 id="matcher-patterns">Matcher Patterns</h2>

<h3 id="no-matcher-all-events">No Matcher (All Events)</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="match-specific-tool">Match Specific Tool</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bash"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="match-with-regex">Match with Regex</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bash</span><span class="se">\\</span><span class="s2">(npm.*</span><span class="se">\\</span><span class="s2">)"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="available-data">Available Data</h2>

<p>Hooks receive data via <strong>stdin</strong> in JSON format:</p>

<h3 id="pretooluse--posttooluse">PreToolUse / PostToolUse</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tool"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Edit"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"input"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"file_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/file.ts"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"old_string"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"new_string"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"output"</span><span class="p">:</span><span class="w"> </span><span class="s2">"..."</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">Only</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">PostToolUse</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="sessionstart">SessionStart</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"cwd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/project"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"claude-sonnet-4-5-20250929"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"sessionId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"abc123"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="blocking-actions">Blocking Actions</h2>

<p>A <code class="language-plaintext highlighter-rouge">PreToolUse</code> or <code class="language-plaintext highlighter-rouge">UserPromptSubmit</code> hook can <strong>block</strong> the action:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Exit code 0 = allow</span>
<span class="nb">exit </span>0

<span class="c"># Exit code != 0 = block</span>
<span class="nb">exit </span>1
</code></pre></div></div>

<p>Block message:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"BLOCKED: Reason for blocking"</span>
<span class="nb">exit </span>1
</code></pre></div></div>

<h2 id="hook-security">Hook Security</h2>

<h3 id="️-warning">⚠️ Warning</h3>

<p>Hooks execute with <strong>your user permissions</strong>. A malicious hook could:</p>
<ul>
  <li>Read your files</li>
  <li>Exfiltrate data</li>
  <li>Modify your system</li>
</ul>

<h3 id="best-practices">Best Practices</h3>

<ol>
  <li><strong>Check the code</strong> before adding an external hook</li>
  <li><strong>Test in isolation</strong> in a safe environment</li>
  <li><strong>Limit permissions</strong> of scripts</li>
  <li><strong>Regularly audit</strong> installed hooks</li>
</ol>

<h2 id="debugging-hooks">Debugging Hooks</h2>

<h3 id="enable-logs">Enable Logs</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CLAUDE_CODE_DEBUG</span><span class="o">=</span>hooks claude
</code></pre></div></div>

<h3 id="test-script-manually">Test Script Manually</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s1">'{"tool": "Edit", "input": {...}}'</span> | ./my-hook.sh
<span class="nb">echo</span> <span class="nv">$?</span>  <span class="c"># Check exit code</span>
</code></pre></div></div>

<h2 id="recommended-organization">Recommended Organization</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.claude/
├── hooks/
│   ├── security-check.sh
│   ├── git-check.sh
│   ├── log-action.sh
│   ├── notify.sh
│   └── session-start.sh
├── logs/
│   └── actions.log
└── settings.json
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 13</strong>, we’ll see <strong>MCP: Connecting Claude Code to Your Tools</strong> - how to integrate GitHub, Jira, databases, and other external services.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-plugins-marketplace/">Day 11: Plugins and Marketplace</a></em></p>
]]></content:encoded>
        <pubDate>Mon, 22 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-hooks/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-hooks/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Claude Code Plugins and Marketplace</title>
        <description>
          
            Discover the Claude Code plugin marketplace: installation, plugin creation, publishing, and best extensions for developers.
          
        </description>
        <content:encoded><![CDATA[<p>We’ve seen how to create slash commands, subagents, and skills individually. <strong>Plugins</strong> allow you to package them together and share them. Today, we explore the Claude Code plugin ecosystem.</p>

<h2 id="what-is-a-plugin">What is a Plugin?</h2>

<p>A plugin is a <strong>pack</strong> that can contain:</p>
<ul>
  <li>Slash commands</li>
  <li>Subagents</li>
  <li>Skills</li>
  <li>Hooks</li>
  <li>MCP servers</li>
</ul>

<p>All in a standardized structure, easy to install and share.</p>

<h2 id="installing-plugins">Installing Plugins</h2>

<h3 id="via-the-plugin-command">Via the /plugin Command</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install plugin-name
</code></pre></div></div>

<h3 id="from-a-marketplace">From a Marketplace</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install plugin-name@marketplace-name
</code></pre></div></div>

<h3 id="from-a-git-repo">From a Git Repo</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install https://github.com/user/plugin-name
</code></pre></div></div>

<h3 id="from-a-local-folder">From a Local Folder</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install ./my-local-plugin
</code></pre></div></div>

<h2 id="managing-installed-plugins">Managing Installed Plugins</h2>

<h3 id="list-plugins">List Plugins</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin list
</code></pre></div></div>

<h3 id="view-plugin-details">View Plugin Details</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin info plugin-name
</code></pre></div></div>

<h3 id="remove-a-plugin">Remove a Plugin</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin remove plugin-name
</code></pre></div></div>

<h2 id="plugin-structure">Plugin Structure</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-plugin/
├── .claude-plugin/
│   ├── plugin.json         # Metadata (required)
│   └── marketplace.json    # For marketplace publishing
├── commands/               # Slash commands
│   ├── review.md
│   └── deploy.md
├── agents/                 # Subagents
│   └── security-expert.md
├── skills/                 # Skills
│   └── api-tester/
│       └── SKILL.md
├── hooks/                  # Hooks
│   └── pre-commit.json
├── .mcp.json              # MCP servers
└── README.md              # Documentation
</code></pre></div></div>

<h2 id="the-pluginjson-file">The plugin.json File</h2>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my-plugin"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Description of what the plugin does"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Your Name"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"email@example.com"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://your-site.com"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"repository"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/user/my-plugin"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"keywords"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"security"</span><span class="p">,</span><span class="w"> </span><span class="s2">"testing"</span><span class="p">,</span><span class="w"> </span><span class="s2">"automation"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"license"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MIT"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"components"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"commands"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"commands/"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"agents"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"agents/"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"skills"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"skills/"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"hooks/"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"mcpServers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">".mcp.json"</span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="marketplaces">Marketplaces</h2>

<h3 id="concept">Concept</h3>

<p>A marketplace is a plugin <strong>registry</strong>, hosted on GitHub or elsewhere.</p>

<h3 id="adding-a-marketplace">Adding a Marketplace</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin marketplace add owner/repo
</code></pre></div></div>

<p>Or with a Git URL:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin marketplace add https://gitlab.com/team/plugins.git
</code></pre></div></div>

<h3 id="popular-marketplaces">Popular Marketplaces</h3>

<table>
  <thead>
    <tr>
      <th>Marketplace</th>
      <th>Description</th>
      <th>Plugin Count</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Awesome Claude Code</td>
      <td>Community collection</td>
      <td>130+ agents</td>
    </tr>
    <tr>
      <td>Claude Code Plugins Plus</td>
      <td>Production-ready</td>
      <td>185+ skills</td>
    </tr>
    <tr>
      <td>Grey Haven Studio</td>
      <td>Dev, testing, security</td>
      <td>13 plugins</td>
    </tr>
  </tbody>
</table>

<h3 id="marketplace-structure">Marketplace Structure</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my-marketplace"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"owner"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Team"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"team@example.com"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"plugins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"security-suite"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./plugins/security-suite"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Security tools suite"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"testing-tools"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/team/testing-tools"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Automated testing tools"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="creating-your-first-plugin">Creating Your First Plugin</h2>

<h3 id="step-1-create-the-structure">Step 1: Create the Structure</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>my-first-plugin
<span class="nb">cd </span>my-first-plugin
<span class="nb">mkdir</span> <span class="nt">-p</span> .claude-plugin commands agents skills
</code></pre></div></div>

<h3 id="step-2-create-pluginjson">Step 2: Create plugin.json</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my-first-plugin"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My first Claude Code plugin"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Your Name"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"components"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"commands"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"commands/"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"agents"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"agents/"</span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="step-3-add-a-command">Step 3: Add a Command</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">&lt;!-- commands/hello.md --&gt;
---
description: Welcome command
---
</span>
<span class="gh"># /hello</span>

Say hello to the user with their name: $1

Be friendly and offer to help with their project.
</code></pre></div></div>

<h3 id="step-4-add-an-agent">Step 4: Add an Agent</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">&lt;!-- agents/helper.md --&gt;
---
</span>name: helper
description: General development assistant
<span class="gh">tools: Read, Grep, Glob
---
</span>
You are a friendly and competent development assistant.

<span class="gu">## Your Role</span>
Help developers with their technical questions.

<span class="gu">## Style</span>
<span class="p">-</span> Concise but complete answers
<span class="p">-</span> Code examples when relevant
<span class="p">-</span> Always propose alternatives
</code></pre></div></div>

<h3 id="step-5-test-locally">Step 5: Test Locally</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install ./my-first-plugin
/hello Angelo
&gt; @helper How to structure a React project?
</code></pre></div></div>

<h2 id="recommended-plugins">Recommended Plugins</h2>

<h3 id="for-security">For Security</h3>

<p><strong>Security Patterns Plugin</strong></p>
<ul>
  <li>9 automatic security patterns</li>
  <li>XSS, injection, CSRF detection</li>
  <li>Pre-commit hooks for validation</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install security-patterns
</code></pre></div></div>

<h3 id="for-testing">For Testing</h3>

<p><strong>Test Generator Plugin</strong></p>
<ul>
  <li>Automatic test generation</li>
  <li>Vitest, Jest, Mocha support</li>
  <li>Edge case coverage</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install test-generator
</code></pre></div></div>

<h3 id="for-deployment">For Deployment</h3>

<p><strong>Deploy Helper Plugin</strong></p>
<ul>
  <li>Deployment scripts</li>
  <li>CI/CD integration</li>
  <li>Automatic rollback</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install deploy-helper
</code></pre></div></div>

<h3 id="for-documentation">For Documentation</h3>

<p><strong>Doc Generator Plugin</strong></p>
<ul>
  <li>Automatic JSDoc</li>
  <li>README generation</li>
  <li>Changelog management</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install doc-generator
</code></pre></div></div>

<h2 id="publishing-your-plugin">Publishing Your Plugin</h2>

<h3 id="option-1-public-github">Option 1: Public GitHub</h3>

<ol>
  <li>Push your plugin to GitHub</li>
  <li>Users install with:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin install https://github.com/you/your-plugin
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="option-2-team-marketplace">Option 2: Team Marketplace</h3>

<ol>
  <li>Create a marketplace repo:</li>
</ol>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"team-plugins"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"plugins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"your-plugin"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./plugins/your-plugin"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ol>
  <li>Share with the team:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin marketplace add team/team-plugins
/plugin install your-plugin@team-plugins
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="option-3-public-marketplace">Option 3: Public Marketplace</h3>

<p>Submit your plugin to community marketplaces (see their guidelines).</p>

<h2 id="plugin-best-practices">Plugin Best Practices</h2>

<h3 id="1-clear-documentation">1. Clear Documentation</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># My Plugin</span>

<span class="gu">## Installation</span>
<span class="se">\`\`\`</span>
/plugin install my-plugin
<span class="se">\`\`\`</span>

<span class="gu">## Available Commands</span>
<span class="p">-</span> <span class="sb">`/command1`</span> - Description
<span class="p">-</span> <span class="sb">`/command2`</span> - Description

<span class="gu">## Available Agents</span>
<span class="p">-</span> <span class="sb">`@agent1`</span> - Description

<span class="gu">## Configuration</span>
...
</code></pre></div></div>

<h3 id="2-semantic-versioning">2. Semantic Versioning</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.2.3"</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">MAJOR.MINOR.PATCH</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">breaking</span><span class="w"> </span><span class="err">changes</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">new</span><span class="w"> </span><span class="err">features</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">bug</span><span class="w"> </span><span class="err">fixes</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="3-test-your-components">3. Test Your Components</h3>

<p>Before publishing:</p>
<ul>
  <li>Test each command</li>
  <li>Verify agents on multiple cases</li>
  <li>Validate skills activate correctly</li>
</ul>

<h3 id="4-minimal-permissions">4. Minimal Permissions</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"components"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"agents"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="w">
      </span><span class="nl">"tools"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Read"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Grep"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Glob"</span><span class="p">]</span><span class="w">
      </span><span class="err">//</span><span class="w"> </span><span class="err">No</span><span class="w"> </span><span class="err">Write</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">Bash</span><span class="w"> </span><span class="err">if</span><span class="w"> </span><span class="err">not</span><span class="w"> </span><span class="err">needed</span><span class="w">
    </span><span class="p">}]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="plugins-for-teams">Plugins for Teams</h2>

<h3 id="private-marketplace">Private Marketplace</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/settings.json
</code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"extraKnownMarketplaces"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"team-internal"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"github"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"repo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"org/internal-plugins"</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="plugins-shared-via-git">Plugins Shared via Git</h3>

<p>Include the plugin in your repo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>project/
├── .claude/
│   └── plugins/
│       └── our-plugin/
└── src/
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 12</strong>, we’ll start the integration phase with <strong>Hooks</strong>: how to automate actions in response to Claude Code events.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-skills/">Day 10: Skills</a></em></p>
]]></content:encoded>
        <pubDate>Sun, 21 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-plugins-marketplace/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-plugins-marketplace/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Skills: Model-Invoked Automation</title>
        <description>
          
            Master Claude Code Skills: intelligent automation, custom skill creation, difference from slash commands, and best practices.
          
        </description>
        <content:encoded><![CDATA[<p>Yesterday, we saw subagents that you explicitly invoke with <code class="language-plaintext highlighter-rouge">@</code>. Today, we discover <strong>Skills</strong>: capabilities that Claude activates <strong>automatically</strong> based on the context of your request.</p>

<h2 id="the-key-difference-model-invoked">The Key Difference: Model-Invoked</h2>

<table>
  <thead>
    <tr>
      <th>Aspect</th>
      <th>Slash Commands</th>
      <th>Subagents</th>
      <th>Skills</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Invocation</td>
      <td>Explicit (<code class="language-plaintext highlighter-rouge">/command</code>)</td>
      <td>Explicit (<code class="language-plaintext highlighter-rouge">@agent</code>)</td>
      <td><strong>Automatic</strong></td>
    </tr>
    <tr>
      <td>Trigger</td>
      <td>User</td>
      <td>User</td>
      <td><strong>Claude</strong></td>
    </tr>
    <tr>
      <td>Context</td>
      <td>Prompt</td>
      <td>Separate context</td>
      <td>Enrichment</td>
    </tr>
  </tbody>
</table>

<p>Skills are <strong>model-invoked</strong>: Claude decides when to use them based on your request and the skill’s description.</p>

<h2 id="how-skills-work">How Skills Work</h2>

<h3 id="the-process">The Process</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Your request
    ↓
Claude analyzes context
    ↓
Claude reads available skill descriptions
    ↓
If a skill matches → Claude activates it automatically
    ↓
The skill enriches Claude's instructions
</code></pre></div></div>

<h3 id="concrete-example">Concrete Example</h3>

<p>You have a <code class="language-plaintext highlighter-rouge">pdf-expert</code> skill with the description:</p>
<blockquote>
  <p>“Extract text and tables from PDF files. Use when user works with PDFs.”</p>
</blockquote>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; Extract data from the report.pdf file

[Claude detects "PDF" + "extract" → automatically activates pdf-expert]
</code></pre></div></div>

<h2 id="skill-sources">Skill Sources</h2>

<h3 id="1-personal-skills">1. Personal Skills</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.claude/skills/
├── pdf-expert/
│   └── SKILL.md
└── api-tester/
    └── SKILL.md
</code></pre></div></div>

<p>Available in all your projects.</p>

<h3 id="2-project-skills">2. Project Skills</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/skills/
├── deployment/
│   └── SKILL.md
└── migration/
    └── SKILL.md
</code></pre></div></div>

<p>Shared with the team via Git.</p>

<h3 id="3-plugin-skills">3. Plugin Skills</h3>

<p>Installed via Claude Code plugins (see Day 11).</p>

<h2 id="anatomy-of-a-skill">Anatomy of a Skill</h2>

<h3 id="minimal-structure">Minimal Structure</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-skill/
└── SKILL.md
</code></pre></div></div>

<h3 id="complete-structure">Complete Structure</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-skill/
├── SKILL.md           # Instructions (required)
├── reference.md       # Additional documentation
├── scripts/
│   └── helper.py      # Utility scripts
└── templates/
    └── template.txt   # Templates to use
</code></pre></div></div>

<h2 id="the-skillmd-file">The SKILL.md File</h2>

<h3 id="required-frontmatter">Required Frontmatter</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">skill-name</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Clear description of when to use this skill</span>
<span class="nn">---</span>
</code></pre></div></div>

<h3 id="optional-fields">Optional Fields</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">skill-name</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Clear description of when to use this skill</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>    <span class="c1"># Restrict tools</span>
<span class="nn">---</span>
</code></pre></div></div>

<h3 id="naming-rules">Naming Rules</h3>

<table>
  <thead>
    <tr>
      <th>Field</th>
      <th>Rules</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">name</code></td>
      <td>Lowercase letters, numbers, hyphens. Max 64 characters</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">description</code></td>
      <td>Max 1024 characters. Must explain <strong>when</strong> to use</td>
    </tr>
  </tbody>
</table>

<h2 id="skill-examples">Skill Examples</h2>

<h3 id="skill-pdf-expert">Skill: PDF Expert</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">pdf-expert</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Extract text, tables, and metadata from PDF files.</span>
             <span class="s">Use when user asks to analyze, read, or extract</span>
             <span class="s">data from PDF files.</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Bash</span>
<span class="nn">---</span>

<span class="gh"># PDF Expert</span>

<span class="gu">## Capabilities</span>
<span class="p">-</span> Text extraction with pdftotext
<span class="p">-</span> Table extraction with tabula-py
<span class="p">-</span> Metadata reading with pdfinfo

<span class="gu">## Instructions</span>
<span class="p">1.</span> Verify file exists
<span class="p">2.</span> Use pdftotext for raw text
<span class="p">3.</span> Use tabula if tables are detected
<span class="p">4.</span> Format result readably

<span class="gu">## Useful Commands</span>
<span class="p">```</span><span class="nl">bash
</span><span class="c"># Extract text</span>
pdftotext input.pdf -

<span class="c"># PDF info</span>
pdfinfo input.pdf
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
### Skill: API Tester

```markdown
---
name: api-tester
description: Test and debug REST APIs. Use when user wants to test
             endpoints, verify API responses, or debug HTTP
             request problems.
allowed-tools: Read, Bash
---

# API Tester

## Capabilities
- Endpoint testing with curl
- JSON response validation
- Response time measurement
- Authentication testing

## Methodology
1. Identify endpoint to test
2. Build appropriate curl request
3. Analyze response (status, body, headers)
4. Propose fixes if error

## Curl Templates

### GET with auth
```bash
curl -X GET "URL" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json"
</code></pre></div></div>

<h3 id="post-with-body">POST with body</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> POST <span class="s2">"URL"</span> <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
  <span class="nt">-d</span> <span class="s1">'{"key": "value"}'</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
### Skill: Migration Helper

```markdown
---
name: migration-helper
description: Help create and manage database migrations.
             Use when user talks about migrations, schemas,
             or database structure changes.
allowed-tools: Read, Write, Bash(npx prisma:*)
---

# Migration Helper

## Supported Framework
Prisma (detected via prisma/schema.prisma)

## Migration Process
1. Analyze requested change
2. Propose schema modifications
3. Generate migration with `prisma migrate dev`
4. Verify migration is correct

## Best Practices
- Always name migrations descriptively
- Check existing data before destructive migration
- Test on local DB copy first

## Prisma Commands
```bash
# Create migration
npx prisma migrate dev --name description

# See status
npx prisma migrate status

# Reset (caution!)
npx prisma migrate reset
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
### Skill: Security Scanner

```markdown
---
name: security-scanner
description: Scan code for security vulnerabilities.
             Use when user asks for security audit,
             looks for flaws, or wants to secure code.
allowed-tools: Read, Grep, Glob
---

# Security Scanner

## Vulnerabilities Searched

### Injection
- SQL Injection
- NoSQL Injection
- Command Injection
- LDAP Injection

### XSS
- Reflected XSS
- Stored XSS
- DOM-based XSS

### Auth/Session
- Broken Authentication
- Session Fixation
- Insecure Direct Object Reference

### Other
- Sensitive Data Exposure
- Security Misconfiguration
- Insecure Deserialization

## Patterns to Search

```javascript
// SQL Injection
`SELECT * FROM users WHERE id = ${userId}`  // ❌ Dangerous
`SELECT * FROM users WHERE id = ?`          // ✅ Parameterized

// XSS
element.innerHTML = userInput;              // ❌ Dangerous
element.textContent = userInput;            // ✅ Safe

// Command Injection
exec(`ls ${userPath}`);                     // ❌ Dangerous
execFile('ls', [userPath]);                 // ✅ Safer
</code></pre></div></div>

<h2 id="report-format">Report Format</h2>
<p>For each vulnerability found:</p>
<ul>
  <li>File and line</li>
  <li>Vulnerability type</li>
  <li>Severity (Critical/High/Medium/Low)</li>
  <li>Vulnerable code</li>
  <li>Proposed fix
```</li>
</ul>

<h2 id="best-practices-for-descriptions">Best Practices for Descriptions</h2>

<h3 id="-good-description">✅ Good Description</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">description</span><span class="pi">:</span> <span class="s">Extract text and tables from PDF files. Use when</span>
             <span class="s">user asks to analyze, read, parse, or extract</span>
             <span class="s">data from PDF files or documents.</span>
</code></pre></div></div>

<p><strong>Why it’s good:</strong></p>
<ul>
  <li>Explains what the skill does</li>
  <li>Lists triggers (analyze, read, parse, extract)</li>
  <li>Mentions keywords (PDF, documents)</li>
</ul>

<h3 id="-bad-description">❌ Bad Description</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">description</span><span class="pi">:</span> <span class="s">Helps with documents</span>
</code></pre></div></div>

<p><strong>Why it’s bad:</strong></p>
<ul>
  <li>Too vague</li>
  <li>No clear triggers</li>
  <li>Claude won’t know when to activate it</li>
</ul>

<h2 id="restricting-tools">Restricting Tools</h2>

<p>For a read-only skill:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">code-analyzer</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">...</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>
<span class="nn">---</span>
</code></pre></div></div>

<p>Claude won’t be able to modify files when this skill is active.</p>

<h2 id="support-files">Support Files</h2>

<h3 id="reference-files">Reference Files</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-skill/
├── SKILL.md
└── reference.md    # Additional documentation
</code></pre></div></div>

<p>In SKILL.md, reference with:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>See @reference.md for more details.
</code></pre></div></div>

<h3 id="scripts">Scripts</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-skill/
├── SKILL.md
└── scripts/
    └── analyze.py
</code></pre></div></div>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gu">## Use the analysis script</span>
<span class="p">```</span><span class="nl">bash
</span>python scripts/analyze.py <span class="nv">$FILE</span>
</code></pre></div></div>
<p>```</p>

<h2 id="testing-automatic-activation">Testing Automatic Activation</h2>

<h3 id="simple-test">Simple Test</h3>

<ol>
  <li>Create a skill with a clear description</li>
  <li>Make a request that matches</li>
  <li>Verify if Claude uses the skill’s instructions</li>
</ol>

<h3 id="debug">Debug</h3>

<p>If the skill doesn’t activate:</p>
<ul>
  <li>Check that the description is specific enough</li>
  <li>Test with explicit keywords</li>
  <li>Verify SKILL.md syntax</li>
</ul>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 11</strong>, we’ll see <strong>Plugins and the Marketplace</strong>: how to install, create, and share complete packs of commands, agents, skills, and hooks.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-subagents/">Day 9: Subagents</a></em></p>
]]></content:encoded>
        <pubDate>Sat, 20 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-skills/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-skills/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Subagents: Delegating Intelligently</title>
        <description>
          
            Master Claude Code subagents: built-in agents, custom agent creation, context isolation, and efficient task delegation.
          
        </description>
        <content:encoded><![CDATA[<p>Slash commands automate workflows. <strong>Subagents</strong> go further: they’re specialized AI agents with their own context, instructions, and tools. Today, we’ll learn to use and create them.</p>

<h2 id="what-is-a-subagent">What is a Subagent?</h2>

<p>A subagent is a dedicated Claude agent that:</p>
<ul>
  <li>Operates in a <strong>separate context</strong> from the main conversation</li>
  <li>Has its own <strong>system instructions</strong></li>
  <li>Has access to <strong>specific tools</strong></li>
  <li>Can be invoked for specialized tasks</li>
</ul>

<h3 id="subagent-advantages">Subagent Advantages</h3>

<table>
  <thead>
    <tr>
      <th>Advantage</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Isolation</td>
      <td>No pollution of main context</td>
    </tr>
    <tr>
      <td>Specialization</td>
      <td>Instructions optimized for a task</td>
    </tr>
    <tr>
      <td>Reusability</td>
      <td>Shareable across projects</td>
    </tr>
    <tr>
      <td>Control</td>
      <td>Tools limited by need</td>
    </tr>
  </tbody>
</table>

<h2 id="built-in-subagents">Built-in Subagents</h2>

<p>Claude Code includes three default subagents:</p>

<h3 id="explorer">@explorer</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; @explorer Where is the calculateDiscount function defined?
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Characteristic</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Model</td>
      <td>Haiku (fast, economical)</td>
    </tr>
    <tr>
      <td>Mode</td>
      <td>Read-only</td>
    </tr>
    <tr>
      <td>Usage</td>
      <td>Search and exploration</td>
    </tr>
    <tr>
      <td>Tools</td>
      <td>Read, Grep, Glob</td>
    </tr>
  </tbody>
</table>

<p>Ideal for:</p>
<ul>
  <li>Finding definitions</li>
  <li>Understanding architecture</li>
  <li>Locating patterns</li>
</ul>

<h3 id="planner">@planner</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; @planner Propose a plan to migrate from REST to GraphQL
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Characteristic</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Model</td>
      <td>Sonnet</td>
    </tr>
    <tr>
      <td>Mode</td>
      <td>Read-only + reflection</td>
    </tr>
    <tr>
      <td>Usage</td>
      <td>Planning</td>
    </tr>
    <tr>
      <td>Tools</td>
      <td>Read, Grep, Glob</td>
    </tr>
  </tbody>
</table>

<p>Ideal for:</p>
<ul>
  <li>Planning refactoring</li>
  <li>Architecting features</li>
  <li>Evaluating approaches</li>
</ul>

<h3 id="general-purpose">@general-purpose</h3>

<p>General-purpose agent for complex multi-step tasks.</p>

<table>
  <thead>
    <tr>
      <th>Characteristic</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Model</td>
      <td>Sonnet</td>
    </tr>
    <tr>
      <td>Mode</td>
      <td>Read/write</td>
    </tr>
    <tr>
      <td>Usage</td>
      <td>Complex tasks</td>
    </tr>
    <tr>
      <td>Tools</td>
      <td>All</td>
    </tr>
  </tbody>
</table>

<h2 id="creating-a-custom-subagent">Creating a Custom Subagent</h2>

<h3 id="method-1-interactive-interface">Method 1: Interactive Interface</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/agents
</code></pre></div></div>

<p>This command opens an interface to:</p>
<ul>
  <li>View existing agents</li>
  <li>Create new agents</li>
  <li>Modify parameters</li>
</ul>

<h3 id="method-2-markdown-file">Method 2: Markdown File</h3>

<p>Create a file in <code class="language-plaintext highlighter-rouge">.claude/agents/</code>:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">&lt;!-- .claude/agents/security-auditor.md --&gt;
---
</span>name: security-auditor
description: Application security audit expert
tools: Read, Grep, Glob
<span class="gh">model: claude-sonnet-4-5-20250929
---
</span>
You are an application security expert with 15 years of experience.

<span class="gu">## Your Role</span>
Analyze code to identify security vulnerabilities.

<span class="gu">## Methodology</span>
<span class="p">1.</span> Identify entry points (user inputs)
<span class="p">2.</span> Trace data flow
<span class="p">3.</span> Look for dangerous patterns
<span class="p">4.</span> Propose fixes

<span class="gu">## Vulnerabilities to Look For</span>
<span class="p">-</span> SQL Injection
<span class="p">-</span> XSS (Cross-Site Scripting)
<span class="p">-</span> CSRF (Cross-Site Request Forgery)
<span class="p">-</span> Command injection
<span class="p">-</span> Path traversal
<span class="p">-</span> Sensitive data exposure
<span class="p">-</span> Broken authentication/authorization

<span class="gu">## Report Format</span>
For each vulnerability:
<span class="p">-</span> <span class="gs">**File**</span>: file path
<span class="p">-</span> <span class="gs">**Line**</span>: line number
<span class="p">-</span> <span class="gs">**Severity**</span>: Critical / High / Medium / Low
<span class="p">-</span> <span class="gs">**Description**</span>: problem explanation
<span class="p">-</span> <span class="gs">**Impact**</span>: possible consequences
<span class="p">-</span> <span class="gs">**Fix**</span>: corrected code
</code></pre></div></div>

<h3 id="method-3-assisted-generation">Method 3: Assisted Generation</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/agents

&gt; Create an agent specialized in TypeScript code review
</code></pre></div></div>

<p>Claude generates a template you can customize.</p>

<h2 id="agent-file-structure">Agent File Structure</h2>

<h3 id="the-frontmatter">The Frontmatter</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">agent-name</span>           <span class="c1"># Unique identifier (required)</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Description</span>   <span class="c1"># Shown during invocation</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>    <span class="c1"># Authorized tools</span>
<span class="na">model</span><span class="pi">:</span> <span class="s">claude-sonnet-4-5-20250929</span>  <span class="c1"># Or "inherit" to inherit</span>
<span class="nn">---</span>
</code></pre></div></div>

<h3 id="model-options">Model Options</h3>

<table>
  <thead>
    <tr>
      <th>Value</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inherit</code></td>
      <td>Uses main session model</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">claude-sonnet-4-5-20250929</code></td>
      <td>Specific Sonnet</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">claude-3-5-haiku-20241022</code></td>
      <td>Haiku for light tasks</td>
    </tr>
  </tbody>
</table>

<h3 id="the-body-system-prompt">The Body: System Prompt</h3>

<p>Everything after the frontmatter becomes the agent’s <strong>system prompt</strong>.</p>

<h2 id="useful-subagent-examples">Useful Subagent Examples</h2>

<h3 id="code-reviewer-agent">Code Reviewer Agent</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">code-reviewer</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">In-depth code review</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>
<span class="na">model</span><span class="pi">:</span> <span class="s">inherit</span>
<span class="nn">---</span>

You are a senior developer with clean code expertise.

<span class="gu">## Mission</span>
Perform constructive and actionable code reviews.

<span class="gu">## Points to Check</span>
<span class="p">1.</span> <span class="gs">**Readability**</span>: Is the code self-documenting?
<span class="p">2.</span> <span class="gs">**Maintainability**</span>: Easy to modify?
<span class="p">3.</span> <span class="gs">**Performance**</span>: Obvious issues?
<span class="p">4.</span> <span class="gs">**Tests**</span>: Sufficient coverage?
<span class="p">5.</span> <span class="gs">**Security**</span>: Vulnerabilities?

<span class="gu">## Feedback Style</span>
<span class="p">-</span> Constructive and kind
<span class="p">-</span> Always propose an alternative
<span class="p">-</span> Prioritize by importance
<span class="p">-</span> Explain the "why"
</code></pre></div></div>

<h3 id="test-writer-agent">Test Writer Agent</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">test-writer</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Generate comprehensive tests</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Write, Bash(npm test:*)</span>
<span class="na">model</span><span class="pi">:</span> <span class="s">inherit</span>
<span class="nn">---</span>

You specialize in writing tests.

<span class="gu">## Framework</span>
<span class="p">-</span> Vitest for unit tests
<span class="p">-</span> Testing Library for components
<span class="p">-</span> MSW for API mocks

<span class="gu">## Methodology</span>
<span class="p">1.</span> Analyze the code to test
<span class="p">2.</span> Identify cases: nominal, errors, edge cases
<span class="p">3.</span> Write tests with AAA pattern (Arrange-Act-Assert)
<span class="p">4.</span> Verify tests pass

<span class="gu">## Conventions</span>
<span class="p">-</span> One test file per module
<span class="p">-</span> Clear descriptions
<span class="p">-</span> Mocks in __mocks__/
<span class="p">-</span> Factories in tests/factories/
</code></pre></div></div>

<h3 id="documentation-agent">Documentation Agent</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">doc-writer</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Generate technical documentation</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob, Write</span>
<span class="na">model</span><span class="pi">:</span> <span class="s">inherit</span>
<span class="nn">---</span>

You are an experienced technical writer.

<span class="gu">## Mission</span>
Generate clear and complete documentation.

<span class="gu">## Documentation Types</span>
<span class="p">-</span> JSDoc for functions
<span class="p">-</span> README for modules
<span class="p">-</span> ADR for architecture decisions
<span class="p">-</span> Guides for new developers

<span class="gu">## Style</span>
<span class="p">-</span> Concise but complete
<span class="p">-</span> Working code examples
<span class="p">-</span> Consistent structure
<span class="p">-</span> Accessible to juniors
</code></pre></div></div>

<h3 id="refactoring-agent">Refactoring Agent</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">refactor-expert</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Refactoring and clean code expert</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Write, Edit, Bash(npm test:*)</span>
<span class="na">model</span><span class="pi">:</span> <span class="s">claude-sonnet-4-5-20250929</span>
<span class="nn">---</span>

You are a refactoring expert with a cautious approach.

<span class="gu">## Principles</span>
<span class="p">-</span> Small incremental changes
<span class="p">-</span> Green tests before and after
<span class="p">-</span> No behavior change
<span class="p">-</span> One commit per refactoring

<span class="gu">## Patterns to Apply</span>
<span class="p">-</span> Extract Method
<span class="p">-</span> Extract Class
<span class="p">-</span> Replace Conditional with Polymorphism
<span class="p">-</span> Introduce Parameter Object
<span class="p">-</span> Replace Magic Number with Constant

<span class="gu">## Process</span>
<span class="p">1.</span> Understand current code
<span class="p">2.</span> Identify the smell
<span class="p">3.</span> Choose appropriate refactoring
<span class="p">4.</span> Verify tests
<span class="p">5.</span> Apply
<span class="p">6.</span> Re-verify tests
</code></pre></div></div>

<h2 id="invoking-a-subagent">Invoking a Subagent</h2>

<h3 id="basic-syntax">Basic Syntax</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; @agent-name Your request here
</code></pre></div></div>

<h3 id="examples">Examples</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; @security-auditor Analyze src/api/auth.ts for security flaws

&gt; @test-writer Write tests for src/utils/validation.ts

&gt; @refactor-expert The file src/services/user.ts is 500 lines, propose a split
</code></pre></div></div>

<h2 id="agent-scope">Agent Scope</h2>

<h3 id="project-agents">Project Agents</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/agents/
└── my-agent.md
</code></pre></div></div>

<p>Available only in this project.</p>

<h3 id="user-agents">User Agents</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.claude/agents/
└── my-agent.md
</code></pre></div></div>

<p>Available in all your projects.</p>

<h2 id="best-practices">Best Practices</h2>

<h3 id="1-one-agent--one-responsibility">1. One Agent = One Responsibility</h3>

<p>❌ <strong>Bad</strong>: Agent that does review + tests + documentation
✅ <strong>Good</strong>: Three specialized agents</p>

<h3 id="2-precise-instructions">2. Precise Instructions</h3>

<p>The more detailed the system prompt, the better the results.</p>

<h3 id="3-minimal-tools">3. Minimal Tools</h3>

<p>Give only the necessary tools:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Read-only agent</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>

<span class="c1"># Agent with controlled writing</span>
<span class="na">tools</span><span class="pi">:</span> <span class="s">Read, Write, Bash(npm test:*)</span>
</code></pre></div></div>

<h3 id="4-test-your-agents">4. Test Your Agents</h3>

<p>Before sharing with the team, test on multiple use cases.</p>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 10</strong>, we’ll discover <strong>Skills</strong>: capabilities that Claude invokes <strong>automatically</strong> based on context, without you having to call them explicitly.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-custom-slash-commands/">Day 8: Custom Slash Commands</a></em></p>
]]></content:encoded>
        <pubDate>Fri, 19 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-subagents/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-subagents/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Creating Custom Slash Commands</title>
        <description>
          
            Learn to create custom slash commands in Claude Code to automate repetitive tasks and standardize team workflows.
          
        </description>
        <content:encoded><![CDATA[<p>Built-in slash commands are useful, but the real power comes from <strong>custom commands</strong>. Today, we’ll create our own commands to automate recurring workflows.</p>

<h2 id="where-to-store-commands">Where to Store Commands</h2>

<h3 id="project-commands-shared-with-team">Project Commands (Shared with Team)</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/commands/
├── review.md
├── test-file.md
└── deploy.md
</code></pre></div></div>

<p>These commands are versioned with the project and available to the entire team.</p>

<h3 id="personal-commands-cross-project">Personal Commands (Cross-project)</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.claude/commands/
├── morning-standup.md
├── eod-summary.md
└── quick-fix.md
</code></pre></div></div>

<p>These commands are available in all your projects.</p>

<h2 id="anatomy-of-a-slash-command">Anatomy of a Slash Command</h2>

<h3 id="basic-structure">Basic Structure</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Short description shown in /help</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob, Bash</span>
<span class="nn">---</span>

<span class="gh"># /command-name</span>

Instructions for Claude...
</code></pre></div></div>

<h3 id="the-yaml-frontmatter">The YAML Frontmatter</h3>

<table>
  <thead>
    <tr>
      <th>Field</th>
      <th>Description</th>
      <th>Required</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">description</code></td>
      <td>Description in help menu</td>
      <td>No</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">allowed-tools</code></td>
      <td>Tools allowed for this command</td>
      <td>No</td>
    </tr>
  </tbody>
</table>

<h3 id="the-command-body">The Command Body</h3>

<p>Everything after the frontmatter is sent to Claude as a prompt.</p>

<h2 id="available-variables">Available Variables</h2>

<h3 id="arguments">Arguments</h3>

<table>
  <thead>
    <tr>
      <th>Variable</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$ARGUMENTS</code></td>
      <td>All passed arguments</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$1</code></td>
      <td>First argument</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$2</code></td>
      <td>Second argument</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$3</code>, <code class="language-plaintext highlighter-rouge">$4</code>…</td>
      <td>Following arguments</td>
    </tr>
  </tbody>
</table>

<h3 id="example-with-arguments">Example with Arguments</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Run tests for a specific file</span>
<span class="nn">---</span>

<span class="gh"># /test</span>

Run tests for <span class="sb">`$1`</span> and analyze the results.

File to test: $1
Additional options: $2
</code></pre></div></div>

<p>Usage:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/test src/utils/helpers.ts --coverage
</code></pre></div></div>

<h2 id="integrating-dynamic-context">Integrating Dynamic Context</h2>

<h3 id="reference-files-with-">Reference Files with @</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Code review with project conventions</span>
<span class="nn">---</span>

<span class="gh"># /review</span>

Perform a code review of $1 following conventions defined in:
<span class="p">-</span> @CLAUDE.md
<span class="p">-</span> @.eslintrc.js
<span class="p">-</span> @tsconfig.json

File to review: @$1
</code></pre></div></div>

<h3 id="inject-bash-results-with-">Inject Bash Results with !</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Analyze current project state</span>
<span class="nn">---</span>

<span class="gh"># /status</span>

Analyze project state:

<span class="gu">## Git Status</span>
!<span class="sb">`git status --short`</span>

<span class="gu">## Branches</span>
!<span class="sb">`git branch -a`</span>

<span class="gu">## Recent Commits</span>
!<span class="sb">`git log --oneline -10`</span>

<span class="gu">## Tests</span>
!<span class="sb">`npm test 2&gt;&amp;1 | tail -20`</span>

Summarize the state and propose next actions.
</code></pre></div></div>

<h2 id="useful-command-examples">Useful Command Examples</h2>

<h3 id="review---automatic-code-review">/review - Automatic Code Review</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Complete code review of a file</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>
<span class="nn">---</span>

<span class="gh"># /review</span>

Perform a thorough code review of @$1.

<span class="gu">## Review Checklist</span>

<span class="gu">### 1. Security</span>
<span class="p">-</span> [ ] No SQL/XSS injection
<span class="p">-</span> [ ] Input validation
<span class="p">-</span> [ ] Secret handling

<span class="gu">### 2. Performance</span>
<span class="p">-</span> [ ] No N+1 queries
<span class="p">-</span> [ ] Memoization if needed
<span class="p">-</span> [ ] No unnecessary re-renders (React)

<span class="gu">### 3. Maintainability</span>
<span class="p">-</span> [ ] Clear naming
<span class="p">-</span> [ ] Functions &lt; 50 lines
<span class="p">-</span> [ ] No duplicated code

<span class="gu">### 4. Tests</span>
<span class="p">-</span> [ ] Nominal cases covered
<span class="p">-</span> [ ] Error cases covered
<span class="p">-</span> [ ] Edge cases identified

For each issue found, indicate:
<span class="p">-</span> Line concerned
<span class="p">-</span> Severity (critical/medium/low)
<span class="p">-</span> Fix suggestion
</code></pre></div></div>

<h3 id="fix-tests---fix-failing-tests">/fix-tests - Fix Failing Tests</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Analyze and fix failing tests</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Bash, Edit</span>
<span class="nn">---</span>

<span class="gh"># /fix-tests</span>

Tests are failing. Here's the result:

!<span class="sb">`npm test 2&gt;&amp;1`</span>

Analyze errors and propose fixes.
For each failing test:
<span class="p">1.</span> Identify the cause
<span class="p">2.</span> Propose a fix
<span class="p">3.</span> Implement if certain, otherwise ask for confirmation
</code></pre></div></div>

<h3 id="component---create-a-react-component">/component - Create a React Component</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Generate a new React component</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Write</span>
<span class="nn">---</span>

<span class="gh"># /component</span>

Create a new React component named <span class="sb">`$1`</span>.

Structure to create:
</code></pre></div></div>
<p>src/components/$1/
├── $1.tsx           # Main component
├── $1.test.tsx      # Tests
├── $1.styles.ts     # Styles (styled-components)
└── index.ts         # Export</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Use patterns from @src/components/Button/ as reference.

Expected props: $2

The component must:
- Be typed with strict TypeScript
- Have basic render tests
- Follow project conventions
</code></pre></div></div>

<h3 id="pr-description---generate-pr-description">/pr-description - Generate PR Description</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Generate a PR description from commits</span>
<span class="nn">---</span>

<span class="gh"># /pr-description</span>

Generate a Pull Request description based on changes.

<span class="gu">## Commits since main</span>
!<span class="sb">`git log main..HEAD --oneline`</span>

<span class="gu">## Modified files</span>
!<span class="sb">`git diff main --stat`</span>

<span class="gu">## Detailed diff</span>
!<span class="sb">`git diff main`</span>

Generate a PR description with:

<span class="gu">## Summary</span>
[2-3 bullet points describing changes]

<span class="gu">## Changes</span>
[List of modified files with description]

<span class="gu">## Test Plan</span>
[Checklist of tests to perform]

<span class="gu">## Screenshots (if applicable)</span>
[Placeholder if UI modified]
</code></pre></div></div>

<h3 id="morning---morning-standup">/morning - Morning Standup</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Prepare morning standup</span>
<span class="nn">---</span>

<span class="gh"># /morning</span>

Prepare my morning standup.

<span class="gu">## Done yesterday</span>
!<span class="sb">`git log --oneline --since="yesterday" --author="$(git config user.email)"`</span>

<span class="gu">## Work in progress</span>
!<span class="sb">`git status --short`</span>
!<span class="sb">`git stash list`</span>

<span class="gu">## PRs awaiting review</span>
!<span class="sb">`gh pr list --author @me 2&gt;/dev/null || echo "GitHub CLI not available"`</span>

Summarize:
<span class="p">1.</span> What I did yesterday (based on commits)
<span class="p">2.</span> What's in progress (modified files)
<span class="p">3.</span> Potential blockers
</code></pre></div></div>

<h3 id="debug---problem-debugging">/debug - Problem Debugging</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Structured problem debugging</span>
<span class="nn">---</span>

<span class="gh"># /debug</span>

Debug the following problem: $ARGUMENTS

<span class="gu">## Step 1: Understand</span>
<span class="p">-</span> What is the expected behavior?
<span class="p">-</span> What is the current behavior?
<span class="p">-</span> When does the problem appear?

<span class="gu">## Step 2: Reproduce</span>
Propose steps to reproduce the problem.

<span class="gu">## Step 3: Analyze</span>
Analyze the concerned code and identify possible causes.

<span class="gu">## Step 4: Resolve</span>
Propose a solution with necessary changes.

Don't code yet, start with analysis.
</code></pre></div></div>

<h2 id="commands-with-restricted-tools">Commands with Restricted Tools</h2>

<h3 id="read-only-command">Read-only Command</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Analysis without modification</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Grep, Glob</span>
<span class="nn">---</span>

<span class="gh"># /analyze</span>

Analyze the code without making modifications...
</code></pre></div></div>

<h3 id="command-with-limited-bash">Command with Limited Bash</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Run tests only</span>
<span class="na">allowed-tools</span><span class="pi">:</span> <span class="s">Read, Bash(npm test:*)</span>
<span class="nn">---</span>

<span class="gh"># /run-tests</span>

Run tests: !<span class="sb">`npm test`</span>
</code></pre></div></div>

<h2 id="team-command-organization">Team Command Organization</h2>

<h3 id="recommended-structure">Recommended Structure</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/commands/
├── dev/
│   ├── component.md
│   ├── hook.md
│   └── service.md
├── review/
│   ├── security.md
│   ├── performance.md
│   └── full.md
├── git/
│   ├── pr-description.md
│   ├── commit-message.md
│   └── changelog.md
└── debug/
    ├── error.md
    ├── performance.md
    └── memory.md
</code></pre></div></div>

<h3 id="naming-convention">Naming Convention</h3>

<table>
  <thead>
    <tr>
      <th>Prefix</th>
      <th>Usage</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">dev-*</code></td>
      <td>Code creation</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">review-*</code></td>
      <td>Code review</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">git-*</code></td>
      <td>Git operations</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">debug-*</code></td>
      <td>Debugging</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">doc-*</code></td>
      <td>Documentation</td>
    </tr>
  </tbody>
</table>

<h2 id="testing-your-commands">Testing Your Commands</h2>

<h3 id="check-syntax">Check Syntax</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/help
</code></pre></div></div>

<p>Your command should appear with its description.</p>

<h3 id="dry-run-test">Dry-run Test</h3>

<p>Add to your command:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Show what you're going to do before doing it.
</code></pre></div></div>

<h3 id="variable-debugging">Variable Debugging</h3>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DEBUG - Received arguments:
<span class="p">-</span> $ARGUMENTS = "$ARGUMENTS"
<span class="p">-</span> $1 = "$1"
<span class="p">-</span> $2 = "$2"
</code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 9</strong>, we’ll see <strong>subagents</strong>: how to create specialized agents with their own instructions and tools.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-permissions-security/">Day 7: Permissions and Security</a></em></p>
]]></content:encoded>
        <pubDate>Thu, 18 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-custom-slash-commands/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-custom-slash-commands/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
      <item>
        <title>Permissions and Security in Claude Code</title>
        <description>
          
            Master Claude Code&apos;s permission system: allow/ask/deny, secret protection, permission modes, and security best practices.
          
        </description>
        <content:encoded><![CDATA[<p>Claude Code has access to your file system and can execute bash commands. It’s powerful, but requires safeguards. Today, we’ll see how to secure your environment.</p>

<blockquote>
  <p>For deeper context on AI security challenges, see my articles on <a href="/en/llm-jailbreaking-security-analysis-bypass-mechanisms/">LLM jailbreaking</a> and <a href="/en/robust-web-development-nasa-methodologies-critical-applications/">robust development practices inspired by NASA</a>.</p>
</blockquote>

<h2 id="the-default-permission-model">The Default Permission Model</h2>

<p>By default, Claude Code operates in <strong>strict read-only</strong> mode:</p>

<table>
  <thead>
    <tr>
      <th>Action</th>
      <th>Default Permission</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Read files</td>
      <td>✅ Allowed</td>
    </tr>
    <tr>
      <td>Search (Glob, Grep)</td>
      <td>✅ Allowed</td>
    </tr>
    <tr>
      <td>Write/Modify files</td>
      <td>❌ Requires approval</td>
    </tr>
    <tr>
      <td>Execute bash commands</td>
      <td>❌ Requires approval</td>
    </tr>
    <tr>
      <td>Web access (WebFetch)</td>
      <td>❌ Requires approval</td>
    </tr>
  </tbody>
</table>

<h2 id="anatomy-of-the-permission-system">Anatomy of the Permission System</h2>

<h3 id="the-three-levels">The Three Levels</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">],</span><span class="w">   </span><span class="err">//</span><span class="w"> </span><span class="err">Allowed</span><span class="w"> </span><span class="err">without</span><span class="w"> </span><span class="err">asking</span><span class="w">
    </span><span class="nl">"ask"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">],</span><span class="w">     </span><span class="err">//</span><span class="w"> </span><span class="err">Ask</span><span class="w"> </span><span class="err">every</span><span class="w"> </span><span class="err">time</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">]</span><span class="w">     </span><span class="err">//</span><span class="w"> </span><span class="err">Systematically</span><span class="w"> </span><span class="err">refused</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="rule-syntax">Rule Syntax</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(npm run:*)"</span><span class="p">,</span><span class="w">           </span><span class="err">//</span><span class="w"> </span><span class="err">All</span><span class="w"> </span><span class="err">npm</span><span class="w"> </span><span class="err">run</span><span class="w"> </span><span class="err">commands</span><span class="w">
      </span><span class="s2">"Bash(git commit:*)"</span><span class="p">,</span><span class="w">         </span><span class="err">//</span><span class="w"> </span><span class="err">All</span><span class="w"> </span><span class="err">git</span><span class="w"> </span><span class="err">commits</span><span class="w">
      </span><span class="s2">"Read(~/.zshrc)"</span><span class="w">              </span><span class="err">//</span><span class="w"> </span><span class="err">Specific</span><span class="w"> </span><span class="err">file</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"ask"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(git push:*)"</span><span class="w">            </span><span class="err">//</span><span class="w"> </span><span class="err">Ask</span><span class="w"> </span><span class="err">before</span><span class="w"> </span><span class="err">push</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Read(./.env)"</span><span class="p">,</span><span class="w">               </span><span class="err">//</span><span class="w"> </span><span class="err">Block</span><span class="w"> </span><span class="err">.env</span><span class="w">
      </span><span class="s2">"Read(./.env.*)"</span><span class="p">,</span><span class="w">             </span><span class="err">//</span><span class="w"> </span><span class="err">Block</span><span class="w"> </span><span class="err">.env.local</span><span class="p">,</span><span class="w"> </span><span class="err">.env.prod...</span><span class="w">
      </span><span class="s2">"Read(./secrets/**)"</span><span class="p">,</span><span class="w">         </span><span class="err">//</span><span class="w"> </span><span class="err">Block</span><span class="w"> </span><span class="err">entire</span><span class="w"> </span><span class="err">secrets</span><span class="w"> </span><span class="err">folder</span><span class="w">
      </span><span class="s2">"WebFetch"</span><span class="w">                    </span><span class="err">//</span><span class="w"> </span><span class="err">Block</span><span class="w"> </span><span class="err">web</span><span class="w"> </span><span class="err">requests</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="tools-and-their-permissions">Tools and Their Permissions</h2>

<h3 id="tools-without-required-permission">Tools Without Required Permission</h3>

<table>
  <thead>
    <tr>
      <th>Tool</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Read</code></td>
      <td>Read file contents</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Glob</code></td>
      <td>Search files by pattern</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Grep</code></td>
      <td>Search within file contents</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">AskUserQuestion</code></td>
      <td>Ask user a question</td>
    </tr>
  </tbody>
</table>

<h3 id="tools-requiring-permission">Tools Requiring Permission</h3>

<table>
  <thead>
    <tr>
      <th>Tool</th>
      <th>Description</th>
      <th>Risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Write</code></td>
      <td>Create/overwrite files</td>
      <td>Medium</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Edit</code></td>
      <td>Modify existing files</td>
      <td>Medium</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Bash</code></td>
      <td>Execute shell commands</td>
      <td><strong>High</strong></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WebFetch</code></td>
      <td>Download web content</td>
      <td>Medium</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WebSearch</code></td>
      <td>Perform web searches</td>
      <td>Low</td>
    </tr>
  </tbody>
</table>

<h2 id="configuring-permissions">Configuring Permissions</h2>

<h3 id="method-1-via-permissions-command">Method 1: Via /permissions Command</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/permissions
</code></pre></div></div>

<p>Interactive interface to manage permissions.</p>

<h3 id="method-2-in-settingsjson">Method 2: In settings.json</h3>

<p>File <code class="language-plaintext highlighter-rouge">.claude/settings.json</code>:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(npm:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(yarn:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(pnpm:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git add:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git commit:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git status)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git diff:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git log:*)"</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Read(./.env)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./.env.*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./secrets/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./config/credentials.*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(rm -rf:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(sudo:*)"</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="method-3-always-allow-during-session">Method 3: “Always Allow” During Session</h3>

<p>When Claude requests permission, you can choose:</p>
<ul>
  <li><strong>Allow once</strong>: Allow this time</li>
  <li><strong>Always allow</strong>: Allow for this session and future ones</li>
</ul>

<h2 id="protecting-sensitive-files">Protecting Sensitive Files</h2>

<h3 id="recommended-protection-template">Recommended Protection Template</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Read(./.env)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./.env.*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./secrets/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./**/*credentials*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./**/*secret*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./**/apikey*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./config/production.*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./.git/config)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(~/.ssh/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(~/.aws/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(~/.kube/**)"</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="commonly-sensitive-files">Commonly Sensitive Files</h3>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Examples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Environment variables</td>
      <td><code class="language-plaintext highlighter-rouge">.env</code>, <code class="language-plaintext highlighter-rouge">.env.local</code>, <code class="language-plaintext highlighter-rouge">.env.production</code></td>
    </tr>
    <tr>
      <td>Credentials</td>
      <td><code class="language-plaintext highlighter-rouge">credentials.json</code>, <code class="language-plaintext highlighter-rouge">serviceAccount.json</code></td>
    </tr>
    <tr>
      <td>SSH keys</td>
      <td><code class="language-plaintext highlighter-rouge">~/.ssh/id_rsa</code>, <code class="language-plaintext highlighter-rouge">~/.ssh/config</code></td>
    </tr>
    <tr>
      <td>Cloud configs</td>
      <td><code class="language-plaintext highlighter-rouge">~/.aws/credentials</code>, <code class="language-plaintext highlighter-rouge">~/.kube/config</code></td>
    </tr>
    <tr>
      <td>Git secrets</td>
      <td><code class="language-plaintext highlighter-rouge">.git/config</code> (may contain tokens)</td>
    </tr>
  </tbody>
</table>

<h2 id="permission-modes">Permission Modes</h2>

<h3 id="mode-1-individual-approval-default">Mode 1: Individual Approval (Default)</h3>

<p>Each sensitive action requires confirmation:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Claude wants to execute: npm install lodash
[Allow once] [Always allow] [Deny]
</code></pre></div></div>

<h3 id="mode-2-accept-edits">Mode 2: Accept Edits</h3>

<p>Automatically accepts file modifications but asks for bash commands:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Shift+Tab → Accept Edits mode
</code></pre></div></div>

<h3 id="mode-3-yolo-dangerous">Mode 3: YOLO (Dangerous)</h3>

<p>⚠️ <strong>Not recommended in production</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claude <span class="nt">--dangerously-skip-permissions</span>
</code></pre></div></div>

<p>All actions are automatically approved. Use only:</p>
<ul>
  <li>In isolated environments (containers)</li>
  <li>For controlled automated scripts</li>
  <li>Never on your main development machine</li>
</ul>

<h2 id="risky-bash-commands">Risky Bash Commands</h2>

<h3 id="recommended-blocklist">Recommended Blocklist</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(rm -rf:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(rm -r:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(sudo:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(chmod 777:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(curl|sh)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(wget|sh)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(&gt; /dev:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(mkfs:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(dd:*)"</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="automatic-detection">Automatic Detection</h3>

<p>Claude Code automatically detects suspicious patterns:</p>
<ul>
  <li>Command injection</li>
  <li>Pipes to shells</li>
  <li>Dangerous redirections</li>
</ul>

<p>Even if a command is in <code class="language-plaintext highlighter-rouge">allow</code>, suspicious patterns trigger a request.</p>

<h2 id="permissions-for-teams">Permissions for Teams</h2>

<h3 id="shared-claudesettingsjson-file">Shared .claude/settings.json File</h3>

<p>Commit this file to your repo for consistent team permissions:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(npm run:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm test:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git:*)"</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Read(./.env*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm publish:*)"</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="enterprise-permissions">Enterprise Permissions</h3>

<p>For organizations, global policies can be defined:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Enterprise Policy (highest priority)
    │
    ├─ deny: Read(./secrets/**)
    ├─ deny: Bash(curl:*)
    └─ deny: WebFetch
</code></pre></div></div>

<p>These rules cannot be overridden by users.</p>

<h2 id="audit-and-monitoring">Audit and Monitoring</h2>

<h3 id="action-logs">Action Logs</h3>

<p>Claude Code can log all actions for audit:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CLAUDE_CODE_ENABLE_TELEMETRY</span><span class="o">=</span>1 claude
</code></pre></div></div>

<h3 id="available-metrics">Available Metrics</h3>

<ul>
  <li>Bash commands executed</li>
  <li>Files modified</li>
  <li>Tokens consumed</li>
  <li>Errors and denials</li>
</ul>

<h2 id="security-best-practices">Security Best Practices</h2>

<h3 id="1-principle-of-least-privilege">1. Principle of Least Privilege</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="err">//</span><span class="w"> </span><span class="err">Only</span><span class="w"> </span><span class="err">what's</span><span class="w"> </span><span class="err">necessary</span><span class="w">
      </span><span class="s2">"Bash(npm run dev)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm run test)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm run lint)"</span><span class="w">
    </span><span class="p">]</span><span class="w">
    </span><span class="err">//</span><span class="w"> </span><span class="err">Everything</span><span class="w"> </span><span class="err">else</span><span class="w"> </span><span class="err">requires</span><span class="w"> </span><span class="err">approval</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="2-systematic-review">2. Systematic Review</h3>

<p>Before approving a bash command:</p>
<ul>
  <li>Read the complete command</li>
  <li>Check the arguments</li>
  <li>Be wary of pipes and redirections</li>
</ul>

<h3 id="3-isolated-environments-for-experimentation">3. Isolated Environments for Experimentation</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Use Docker for risky tests</span>
docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">-v</span> <span class="si">$(</span><span class="nb">pwd</span><span class="si">)</span>:/app node:18 bash
</code></pre></div></div>

<h3 id="4-hook-verification">4. Hook Verification</h3>

<p>Claude Code hooks have access to environment credentials. Before adding a hook:</p>
<ul>
  <li>Check the source code</li>
  <li>Test in an isolated environment</li>
</ul>

<h3 id="5-secret-rotation">5. Secret Rotation</h3>

<p>If you suspect exposure:</p>
<ol>
  <li>Immediately revoke tokens/keys</li>
  <li>Audit Claude Code logs</li>
  <li>Generate new secrets</li>
</ol>

<h2 id="secure-configuration-template">Secure Configuration Template</h2>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"allow"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(npm run:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(yarn:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git add:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git commit:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git status)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git diff:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git log:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git branch:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git checkout:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(ls:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(cat:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(head:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(tail:*)"</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"ask"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Bash(git push:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(git merge:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm install:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(npm uninstall:*)"</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"deny"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="s2">"Read(./.env)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./.env.*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./secrets/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./**/*credential*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(./**/*secret*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(~/.ssh/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Read(~/.aws/**)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(rm -rf:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(sudo:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Bash(chmod 777:*)"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"WebFetch"</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="whats-coming-tomorrow">What’s Coming Tomorrow</h2>

<p>In <strong>Day 8</strong>, we’ll start the customization phase with <strong>creating custom slash commands</strong> to automate your recurring workflows.</p>

<hr />

<p><em>This article is part of the “Master Claude Code in 20 Days” series. <a href="/en/claude-code-git-workflows/">Day 6: Git Workflows</a></em></p>
]]></content:encoded>
        <pubDate>Wed, 17 Dec 2025 00:00:00 +0100</pubDate>
        <link>https://angelo-lima.fr/en/claude-code-permissions-security/</link>
        <guid isPermaLink="true">https://angelo-lima.fr/en/claude-code-permissions-security/</guid>
        
        <dc:creator>Angelo Lima</dc:creator>
        
        
          
          <category>IA</category>
          
          <category>Développement</category>
          
          <category>Sécurité</category>
          
        
        
        <enclosure url="https://angelo-lima.fr/assets/img/claude-code.webp" type="image/png" length="0" />
        
      </item>
    
  </channel>
</rss>