<?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/">
  <channel>
    <title>DEV Community: aicoding-guide</title>
    <description>The latest articles on DEV Community by aicoding-guide (@aicoding-guide).</description>
    <link>https://dev.to/aicoding-guide</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4119600%2F36237543-8d98-41c3-b6a3-c8202a09085f.png</url>
      <title>DEV Community: aicoding-guide</title>
      <link>https://dev.to/aicoding-guide</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aicoding-guide"/>
    <language>en</language>
    <item>
      <title>Gemini CLI v0.64 fixes the CPU hang on @ inside code and headless folder trust</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Tue, 20 Oct 2026 19:18:57 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/gemini-cli-v064-fixes-the-cpu-hang-on-inside-code-and-headless-folder-trust-3n8d</link>
      <guid>https://dev.to/aicoding-guide/gemini-cli-v064-fixes-the-cpu-hang-on-inside-code-and-headless-folder-trust-3n8d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/gemini-cli-update-0-64/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gemini CLI v0.64.0 adds no features. All 17 entries under "What's Changed" are fixes, refactors or release chores.&lt;/p&gt;

&lt;p&gt;Two of them matter a great deal, though: a hang where &lt;strong&gt;piping code containing &lt;code&gt;@&lt;/code&gt; into &lt;code&gt;-p&lt;/code&gt; pins the CPU at 100%&lt;/strong&gt;, and a headless mode that &lt;strong&gt;treated untrusted folders as trusted&lt;/strong&gt;. If the first sounds familiar, that alone is a reason to upgrade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What this article covers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why input like &lt;code&gt;@scope/pkg&lt;/code&gt; hung the CLI, and the workaround that worked&lt;/li&gt;
&lt;li&gt;How headless folder trust diverged from the actual trust decision&lt;/li&gt;
&lt;li&gt;File writes and state persistence becoming atomic&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Piping code with @ pinned the CPU at 100%
&lt;/h2&gt;

&lt;p&gt;The fix is PR #29557 (Issue #29434). The symptom: piping code into &lt;code&gt;-p&lt;/code&gt; on stdin made the CLI stop before it sent anything to the model. In the reporter's words, "The node process sits at ~100% CPU (state RN) indefinitely."&lt;/p&gt;

&lt;p&gt;The trigger is input where an &lt;code&gt;@&lt;/code&gt;-prefixed token is immediately followed by a double quote, with more quoted strings after it. In practice that means a scoped npm import.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@scope/pkg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./local&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The symptoms were:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Behaviour&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;Nothing at all, not even an error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--output-format stream-json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only the &lt;code&gt;init&lt;/code&gt; event appears, then it stops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signals&lt;/td&gt;
&lt;td&gt;SIGINT and SIGTERM are ignored; only SIGKILL stops it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Versions reproduced&lt;/td&gt;
&lt;td&gt;The reporter names v0.59.0 and v0.60.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The reporter attributes the cause to the &lt;code&gt;@&lt;/code&gt;-path regex matching across multiple quoted spans, so the result falls back to a glob whose large brace expansion minimatch then processes synchronously. That is the reporter's analysis; the fix itself is described only as stopping the CPU hang and quote swallowing caused by &lt;code&gt;@&lt;/code&gt; inside code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A workaround if you cannot upgrade yet&lt;/strong&gt;&lt;br&gt;
The reporter writes that escaping every &lt;code&gt;@&lt;/code&gt; in the piped text avoids the hang. If a CI job pipes source code into &lt;code&gt;gemini -p&lt;/code&gt;, add that preprocessing step until you can upgrade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Headless treated untrusted folders as trusted
&lt;/h2&gt;

&lt;p&gt;This is PR #29528 (Issue #29031). In headless mode (&lt;code&gt;-p&lt;/code&gt;), the internal folder trust handling always passed the state through as trusted. The result was a mismatch: the warning said the folder was untrusted while the application-level check said it was trusted.&lt;/p&gt;

&lt;p&gt;Folder trust exists to stop a project you have not vetted from loading its own configuration. According to the documentation, an untrusted folder disables all of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The project's &lt;code&gt;.gemini/settings.json&lt;/code&gt; is not loaded&lt;/li&gt;
&lt;li&gt;The project's &lt;code&gt;.env&lt;/code&gt; files are not loaded&lt;/li&gt;
&lt;li&gt;Extensions cannot be installed, updated or uninstalled&lt;/li&gt;
&lt;li&gt;Tool auto-acceptance is disabled, so every tool prompts&lt;/li&gt;
&lt;li&gt;Automatic memory loading from directories in local settings is disabled&lt;/li&gt;
&lt;li&gt;MCP servers are not connected&lt;/li&gt;
&lt;li&gt;Custom &lt;code&gt;.toml&lt;/code&gt; commands are not loaded, both project and user ones&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So while the mismatch lasted, an untrusted folder's settings, hooks and MCP servers could still take effect in a headless run. If your CI relies on this feature, that is a reason to upgrade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The docs disagree on the default&lt;/strong&gt;&lt;br&gt;
The settings table gives &lt;code&gt;security.folderTrust.enabled&lt;/code&gt; a default of &lt;code&gt;true&lt;/code&gt;. The Trusted Folders page says "The Trusted Folders feature is &lt;strong&gt;disabled by default&lt;/strong&gt;." Both live on &lt;code&gt;main&lt;/code&gt; in the same repository (checked 2026-10-21). Open &lt;code&gt;/permissions&lt;/code&gt; to see which applies in your own setup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To turn it on explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"folderTrust"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decisions are stored in &lt;code&gt;~/.gemini/trustedFolders.json&lt;/code&gt;. Running headless against an untrusted folder exits with &lt;code&gt;FatalUntrustedWorkspaceError&lt;/code&gt;, so a CI job that must proceed uses the &lt;code&gt;--skip-trust&lt;/code&gt; flag or &lt;code&gt;GEMINI_CLI_TRUST_WORKSPACE=true&lt;/code&gt;. For MCP configuration, see &lt;a href="https://aicoding-guide.com/en/posts/gemini-cli-mcp/" rel="noopener noreferrer"&gt;Setting up MCP servers in Gemini CLI&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writes and state persistence became atomic
&lt;/h2&gt;

&lt;p&gt;Three fixes address data corruption:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;th&gt;What changed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PR #29499&lt;/td&gt;
&lt;td&gt;File tool operations are serialised and writes are atomic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR #29558&lt;/td&gt;
&lt;td&gt;State persistence is atomic, with recovery from a backup when the state is corrupt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR #29568&lt;/td&gt;
&lt;td&gt;Conversation recording uses append-only delta patching with bounded history windowing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These cover parallel file operations clobbering each other, and a state file left corrupt when the process dies mid-save. They matter most in long-running sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Windows and interaction fixes
&lt;/h2&gt;

&lt;p&gt;Four more that show up in daily use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows ConPTY now forwards the IME cursor position&lt;/strong&gt; (PR #29560), fixing misplaced cursors while composing text in an IME&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ctrl+C emergency abort now reaches the cancellation handler&lt;/strong&gt; during active operations (PR #29586)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@file:line&lt;/code&gt; references and a ghost-text wrap hang&lt;/strong&gt; are fixed (PR #29581)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enter and Spacebar reliably confirm selection list options&lt;/strong&gt; (PR #29502)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond those, updating an extension on Windows now retries directory removal through file-locking errors (PR #29540), scroll position is preserved (PR #29520), and ACP resolves sessions by exact ID (PR #29580). For the previous release, see &lt;a href="https://aicoding-guide.com/en/posts/gemini-cli-update-0-63/" rel="noopener noreferrer"&gt;Gemini CLI v0.63 fixes the diff cannot spawn error&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;v0.64.0 adds no features; all 17 "What's Changed" entries are fixes, refactors or release chores&lt;/li&gt;
&lt;li&gt;Piping code containing &lt;code&gt;@scope/pkg&lt;/code&gt; into &lt;code&gt;-p&lt;/code&gt; no longer pins the CPU at 100%, a state only SIGKILL could end&lt;/li&gt;
&lt;li&gt;Headless mode no longer treats an untrusted folder as trusted&lt;/li&gt;
&lt;li&gt;File writes and state persistence are atomic, with backup recovery for corrupt state&lt;/li&gt;
&lt;li&gt;The official docs give &lt;code&gt;security.folderTrust.enabled&lt;/code&gt; both a &lt;code&gt;true&lt;/code&gt; default and "disabled by default"&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gemini</category>
      <category>updates</category>
      <category>foldertrust</category>
      <category>headless</category>
    </item>
    <item>
      <title>Codex CLI v0.163 turns Daybreak back on by default and makes /config searchable</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Sun, 18 Oct 2026 19:19:07 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/codex-cli-v0163-turns-daybreak-back-on-by-default-and-makes-config-searchable-3kag</link>
      <guid>https://dev.to/aicoding-guide/codex-cli-v0163-turns-daybreak-back-on-by-default-and-makes-config-searchable-3kag</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/codex-update-0-163/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Codex CLI v0.163.0 reverses a change that shipped five days earlier: &lt;strong&gt;Daybreak is on by default again&lt;/strong&gt;. Alongside it come a searchable settings panel, mid-turn steering, and three security fixes in the network proxy.&lt;/p&gt;

&lt;p&gt;Two things are worth acting on. If you had explicitly disabled Daybreak, check its current state. If you restrict network access in the sandbox, upgrade to 0.163.0.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What this article covers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Daybreak is the default again for eligible accounts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt; searches across categories, and you can steer a response mid-turn&lt;/li&gt;
&lt;li&gt;The three fixes that landed in the network proxy&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Daybreak is the default again
&lt;/h2&gt;

&lt;p&gt;The release notes say "Daybreak is enabled by default for eligible accounts." In v0.161.0 it required &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak=true&lt;/code&gt;, and &lt;code&gt;daybreak=true&lt;/code&gt; alone was not enough. That requirement lasted five days.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# What v0.161.0 and v0.162.0 required&lt;/span&gt;
&lt;span class="nn"&gt;[features]&lt;/span&gt;
&lt;span class="py"&gt;cli_daybreak&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From v0.163.0, an eligible account does not need this. &lt;code&gt;codex exec&lt;/code&gt; can also use Daybreak with an OpenAI API key now.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do not treat this setting as settled&lt;/strong&gt;&lt;br&gt;
The same setting has moved twice in five days, and the release notes do not define what makes an account "eligible". If &lt;code&gt;cli_daybreak&lt;/code&gt; is written into a runbook or a shared &lt;code&gt;config.toml&lt;/code&gt;, verify the real behaviour after upgrading. &lt;a href="https://aicoding-guide.com/en/posts/codex-update-0-161/" rel="noopener noreferrer"&gt;What changed in Codex CLI v0.161 and v0.162&lt;/a&gt; covers how it worked before.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  /config and mid-turn control
&lt;/h2&gt;

&lt;p&gt;How you find settings, and what happens when you interrupt, both changed.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Searches preferences across categories. Supported changes apply in place, and ones needing a restart are marked as such&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Follow-ups mid-response&lt;/td&gt;
&lt;td&gt;Send a follow-up while Codex is responding to steer it immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interrupting a turn&lt;/td&gt;
&lt;td&gt;Also stops running Code Mode cells and nested tool calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leader key in &lt;code&gt;/keymap&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The default is &lt;code&gt;Ctrl+X&lt;/code&gt;. Voice mute moved to &lt;code&gt;F9&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/daemon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restarts a managed background server, warning about work that may be interrupted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/side&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A temporary side chat. It persists across thread switches, and prompt answers go back to the originating thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel read-only tools&lt;/td&gt;
&lt;td&gt;Independent reads such as skills, memories and conversation history run in parallel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;/config, /keymap and /daemon are not in the official list&lt;/strong&gt;&lt;br&gt;
As of 2026-10-19 the official slash command reference has no entry for &lt;code&gt;/config&lt;/code&gt;, &lt;code&gt;/keymap&lt;/code&gt; or &lt;code&gt;/daemon&lt;/code&gt;. They appear only in the release notes. The reference does list &lt;code&gt;/approve&lt;/code&gt;, &lt;code&gt;/compact&lt;/code&gt;, &lt;code&gt;/model&lt;/code&gt;, &lt;code&gt;/plan&lt;/code&gt;, &lt;code&gt;/review&lt;/code&gt;, &lt;code&gt;/side&lt;/code&gt;, &lt;code&gt;/status&lt;/code&gt; and &lt;code&gt;/worktree&lt;/code&gt;, among others, and describes &lt;code&gt;/side&lt;/code&gt; as "Start a temporary side chat without interrupting the main chat."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The network proxy and the sandbox
&lt;/h2&gt;

&lt;p&gt;Three security fixes landed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The network proxy now checks permission &lt;strong&gt;before a DNS lookup&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It rejects duplicate &lt;code&gt;Host&lt;/code&gt; headers&lt;/li&gt;
&lt;li&gt;Credential aliases can no longer bypass the inspection hooks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first matters most in practice. Previously name resolution could run ahead of the permission decision, so even a connection you blocked could leak to your DNS server which host was about to be contacted. Resuming a saved thread now also restores its permission and network approvals.&lt;/p&gt;

&lt;p&gt;On the documentation side, the Linux sandbox section was updated. The official sandboxing page says that on Linux and WSL2 you install &lt;code&gt;bubblewrap&lt;/code&gt; with your package manager first, that Codex uses the first &lt;code&gt;bwrap&lt;/code&gt; executable it finds on &lt;code&gt;PATH&lt;/code&gt;, and that without one it falls back to a bundled helper which "requires support for unprivileged user namespace creation". Codex shows a startup warning when &lt;code&gt;bwrap&lt;/code&gt; is missing or the helper cannot create the namespace.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;bubblewrap (bwrap)&lt;/strong&gt;: a Linux sandboxing tool that isolates processes using namespaces without needing privileges. Codex uses it to limit where commands can write and what they can reach over the network.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The release notes say the Linux sandbox documentation now also explains seccomp, but as of 2026-10-19 no mention of seccomp could be found on the official sandboxing page. For how approvals and the sandbox interact, see &lt;a href="https://aicoding-guide.com/en/posts/codex-approval-sandbox/" rel="noopener noreferrer"&gt;Combining approval_policy and sandbox_mode in Codex&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bundled zsh is gone
&lt;/h2&gt;

&lt;p&gt;Codex no longer bundles a patched &lt;code&gt;zsh&lt;/code&gt; and uses its standard shell executor instead. Configurations that use the retired shell flags get a migration notice.&lt;/p&gt;

&lt;p&gt;The names of those flags could not be confirmed in the official configuration reference, so if the notice appears, follow what the message itself says. For the structure of the configuration file as a whole, see &lt;a href="https://aicoding-guide.com/en/posts/codex-config-toml/" rel="noopener noreferrer"&gt;Configuring Codex with config.toml&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two smaller items: the Linux and macOS release binaries are smaller because symbols are stripped from the packaged copies, and &lt;code&gt;codex exec&lt;/code&gt; no longer repeats file diffs after unrelated commands. Clipboard paste handling on Windows and WSL was also fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;v0.163.0 makes Daybreak the default for eligible accounts; &lt;code&gt;cli_daybreak&lt;/code&gt; is no longer needed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt; searches settings across categories and marks changes that need a restart&lt;/li&gt;
&lt;li&gt;You can send a follow-up mid-response, and interrupting also stops Code Mode cells&lt;/li&gt;
&lt;li&gt;The network proxy checks permission before a DNS lookup and rejects duplicate &lt;code&gt;Host&lt;/code&gt; headers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt;, &lt;code&gt;/keymap&lt;/code&gt;, &lt;code&gt;/daemon&lt;/code&gt; and the retired shell flag names could not be confirmed in the official docs&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codex</category>
      <category>codexcli</category>
      <category>updates</category>
      <category>daybreak</category>
    </item>
    <item>
      <title>This week in Claude Code, Codex and Gemini CLI (week of October 18, 2026)</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Sat, 17 Oct 2026 19:13:13 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/this-week-in-claude-code-codex-and-gemini-cli-week-of-october-18-2026-e6d</link>
      <guid>https://dev.to/aicoding-guide/this-week-in-claude-code-codex-and-gemini-cli-week-of-october-18-2026-e6d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/weekly-2026-10-18/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The change with the widest reach this week is &lt;strong&gt;idle compaction&lt;/strong&gt; in Claude Code. Leave a long conversation sitting and it now gets summarised on its own.&lt;/p&gt;

&lt;p&gt;On the Codex side, &lt;strong&gt;Daybreak is enabled by default again&lt;/strong&gt; — a setting that only became an explicit opt-in five days earlier in v0.161.0. It has flipped twice in under a week.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
This week in brief&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code compacts idle conversations automatically (&lt;code&gt;idleCompaction&lt;/code&gt; turns it off)&lt;/li&gt;
&lt;li&gt;Codex 0.163.0 made Daybreak the default for eligible accounts again&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE_CODE_DISABLE_FILE_MENTIONS&lt;/code&gt; and &lt;code&gt;CLAUDE_CODE_AUTO_MODE_MODEL&lt;/code&gt; were added&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Claude Code
&lt;/h2&gt;

&lt;p&gt;Four releases this week, 2.1.299 through 2.1.302.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idle compaction arrived (2.1.299, 2.1.302)
&lt;/h3&gt;

&lt;p&gt;The CHANGELOG wording is: "Added idle compaction in the terminal: a 200K+ token conversation left idle for about 54 minutes is compacted before its one-hour prompt cache expires, so your next message doesn't reprocess it all."&lt;/p&gt;

&lt;p&gt;The motivation is cost. Leave a conversation above 200K tokens idle for roughly 54 minutes and it is summarised before the one-hour prompt cache expires, so your next message does not pay to reprocess everything. The prompt caching documentation also notes that Claude Code may compact when idle, and that &lt;code&gt;idleCompaction&lt;/code&gt; disables it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"idleCompaction": false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Turns off automatic idle compaction (v2.1.290+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes the 200K token threshold (v2.1.290+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Idle compaction&lt;/code&gt; row in &lt;code&gt;/config&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Toggles it from the UI (added in v2.1.302)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Know what compaction drops before you leave it on&lt;/strong&gt;&lt;br&gt;
Compaction replaces the conversation layer with a summary. &lt;code&gt;CLAUDE.md&lt;/code&gt; itself is re-read from disk, but the contents of files that Claude read because &lt;code&gt;CLAUDE.md&lt;/code&gt; told it to are folded into the summary. &lt;a href="https://aicoding-guide.com/en/posts/claude-code-context-compact/" rel="noopener noreferrer"&gt;Context management with /compact and /clear&lt;/a&gt; covers the difference. If your workflow depends on what is in the window, turn it off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  New environment variables (2.1.299, 2.1.301, 2.1.302)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_DISABLE_FILE_MENTIONS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude gets the &lt;strong&gt;paths&lt;/strong&gt; of &lt;code&gt;@&lt;/code&gt; file mentions rather than their contents, and reads them with its own file tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_AUTO_MODE_MODEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Chooses the model the client-side auto mode classifier uses. It does not change server-side auto mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;In unattended retry mode, exits instead of waiting out a usage limit whose reset is too far off&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;CLAUDE_CODE_DISABLE_FILE_MENTIONS&lt;/code&gt; is the useful one if &lt;code&gt;@&lt;/code&gt;-mentioning a large file keeps filling your context in one shot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security fixes (2.1.301, 2.1.302)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Read tool loaded an image file of any size — or a pipe or device named like an image — entirely into memory. Image sources over &lt;strong&gt;128 MB are now refused&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Quitting removed a worktree made by a &lt;code&gt;WorktreeCreate&lt;/code&gt; hook without asking, even when it might hold unpushed commits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Telemetry
&lt;/h3&gt;

&lt;p&gt;The OpenTelemetry &lt;code&gt;api_request&lt;/code&gt; event now splits cache writes by lifetime with &lt;code&gt;cache_creation_5m_tokens&lt;/code&gt; and &lt;code&gt;cache_creation_1h_tokens&lt;/code&gt;. The &lt;code&gt;tool_decision&lt;/code&gt; event gained &lt;code&gt;classifier_verdict&lt;/code&gt;, &lt;code&gt;permission_mode&lt;/code&gt; and &lt;code&gt;classifier_category&lt;/code&gt;, so you can tell an auto mode classifier decision apart from one made by a permission rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Daybreak is the default again (0.163.0)
&lt;/h3&gt;

&lt;p&gt;The release notes say "Daybreak is enabled by default for eligible accounts." In v0.161.0 it required &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak=true&lt;/code&gt;, and &lt;code&gt;daybreak=true&lt;/code&gt; alone was not enough (&lt;a href="https://aicoding-guide.com/en/posts/codex-update-0-161/" rel="noopener noreferrer"&gt;What changed in Codex CLI v0.161 and v0.162&lt;/a&gt;). Five days and a reversal later, this is not a setting to treat as settled.&lt;/p&gt;

&lt;h3&gt;
  
  
  /config and steering (0.163.0)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/config&lt;/code&gt;&lt;/strong&gt;: search preferences across categories, change supported ones in place, and see which changes need a restart&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow-ups mid-response&lt;/strong&gt;: send a follow-up while Codex is responding to steer it immediately. Interrupting a turn also stops running Code Mode cells and nested tool calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leader key in &lt;code&gt;/keymap&lt;/code&gt;&lt;/strong&gt;: the default is &lt;code&gt;Ctrl+X&lt;/code&gt;. Voice mute moved to &lt;code&gt;F9&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel read-only tools&lt;/strong&gt;: independent reads such as skills, memories and conversation history now run in parallel&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Network and sandbox (0.163.0)
&lt;/h3&gt;

&lt;p&gt;Three proxy fixes landed: the network proxy now &lt;strong&gt;checks permission before a DNS lookup&lt;/strong&gt;, rejects duplicate &lt;code&gt;Host&lt;/code&gt; headers, and prevents credential aliases from bypassing inspection hooks. Resuming a saved thread now restores its permission and network approvals too.&lt;/p&gt;

&lt;p&gt;One operational change: Codex no longer bundles a patched &lt;code&gt;zsh&lt;/code&gt; and uses its standard shell executor instead. Configurations using the retired shell flags get a migration notice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gemini CLI
&lt;/h2&gt;

&lt;p&gt;v0.64.0 is fixes only. The notable ones: a CPU hang and swallowed quotes when &lt;code&gt;@&lt;/code&gt; appears in code, file tool operations serialised with atomic writes, and atomic state persistence with recovery from a backup when the file is corrupt. On Windows, ConPTY now forwards the IME cursor position.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check now
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Decide how you feel about idle compaction. If you do not want conversations summarised unprompted, turn it off in &lt;code&gt;/config&lt;/code&gt; or with &lt;code&gt;"idleCompaction": false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If you had explicitly disabled Daybreak in Codex, check its current state — the default moved&lt;/li&gt;
&lt;li&gt;Upgrade Claude Code to 2.1.302 or later if the Read tool image issue matters to you&lt;/li&gt;
&lt;li&gt;Upgrade Codex to 0.163.0 if you restrict network access in the sandbox, for the pre-DNS permission check&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code now compacts idle conversations: 200K+ tokens left for about 54 minutes&lt;/li&gt;
&lt;li&gt;Turn it off with &lt;code&gt;"idleCompaction": false&lt;/code&gt;, tune it with &lt;code&gt;CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS&lt;/code&gt;, toggle it in &lt;code&gt;/config&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE_CODE_DISABLE_FILE_MENTIONS&lt;/code&gt; passes &lt;code&gt;@&lt;/code&gt; mentions as paths instead of contents&lt;/li&gt;
&lt;li&gt;Codex 0.163.0 made Daybreak the default again for eligible accounts, reversing v0.161.0&lt;/li&gt;
&lt;li&gt;Gemini CLI v0.64.0 is fixes only&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>weeklydigest</category>
      <category>updates</category>
      <category>claudecode</category>
      <category>codex</category>
    </item>
    <item>
      <title>Claude Code on Windows, native or WSL, and what trips people up</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Fri, 16 Oct 2026 19:22:28 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/claude-code-on-windows-native-or-wsl-and-what-trips-people-up-3em3</link>
      <guid>https://dev.to/aicoding-guide/claude-code-on-windows-native-or-wsl-and-what-trips-people-up-3em3</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/claude-code-windows-setup/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude Code started out aimed at macOS and Linux, with Windows users pointed at WSL. There is now a &lt;strong&gt;native Windows build&lt;/strong&gt; you can run straight from PowerShell. Which one to choose comes down to one question: &lt;strong&gt;do you need sandboxing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article compares the two, gives the install steps for each, and collects the things that actually trip people up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native versus WSL, and the sandboxing difference that decides it&lt;/li&gt;
&lt;li&gt;Install steps for each, and whether Git for Windows matters&lt;/li&gt;
&lt;li&gt;The gotchas: hooks, paths, encoding and line endings&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Native versus WSL 2
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Native Windows&lt;/th&gt;
&lt;th&gt;WSL 2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runs on&lt;/td&gt;
&lt;td&gt;Windows directly&lt;/td&gt;
&lt;td&gt;Linux inside WSL (Ubuntu, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requires&lt;/td&gt;
&lt;td&gt;Nothing; Git for Windows is optional&lt;/td&gt;
&lt;td&gt;WSL 2 enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sandboxing&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Not supported&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Supported&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shell tool&lt;/td&gt;
&lt;td&gt;Git Bash when Git for Windows is installed, otherwise the PowerShell tool&lt;/td&gt;
&lt;td&gt;bash / zsh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where projects live&lt;/td&gt;
&lt;td&gt;Windows drives (&lt;code&gt;C:\...&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Inside WSL (&lt;code&gt;/home/...&lt;/code&gt;) is recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux tooling such as Docker&lt;/td&gt;
&lt;td&gt;Needs a Windows build&lt;/td&gt;
&lt;td&gt;Linux builds work as-is&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suits&lt;/td&gt;
&lt;td&gt;Windows-native development (.NET, Node)&lt;/td&gt;
&lt;td&gt;Linux toolchains, or sandboxed command execution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;WSL 1 is the third option, for when WSL 2 is unavailable; like native Windows, it does not support sandboxing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Touching Windows files from WSL is slow&lt;/strong&gt;&lt;br&gt;
Working on a project under &lt;code&gt;/mnt/c/...&lt;/code&gt; from WSL makes file I/O dramatically slower. If you choose WSL, keep the project inside WSL, under &lt;code&gt;~/projects/&lt;/code&gt; for example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Installing the native build
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Git for Windows (optional)
&lt;/h3&gt;

&lt;p&gt;The documentation calls Git for Windows optional. With it, Git Bash backs the &lt;a href="https://code.claude.com/docs/en/tools-reference" rel="noopener noreferrer"&gt;Bash tool&lt;/a&gt;; without it, Claude Code runs shell commands through the PowerShell tool. If your hooks and scripts assume bash, install it. The defaults from &lt;a href="https://git-scm.com/download/win" rel="noopener noreferrer"&gt;Git for Windows&lt;/a&gt; are fine.&lt;/p&gt;

&lt;p&gt;With Git for Windows installed, the PowerShell tool is available alongside Bash: on by default for claude.ai and Console accounts, and enabled with &lt;code&gt;CLAUDE_CODE_USE_POWERSHELL_TOOL=1&lt;/code&gt; in Amazon Bedrock, Google Cloud's Agent Platform and Microsoft Foundry sessions. Set it to &lt;code&gt;0&lt;/code&gt; to turn the tool off.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Install Claude Code
&lt;/h3&gt;

&lt;p&gt;Open PowerShell and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://claude.ai/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In CMD the command is different — your prompt shows &lt;code&gt;PS C:\&lt;/code&gt; in PowerShell and &lt;code&gt;C:\&lt;/code&gt; without the &lt;code&gt;PS&lt;/code&gt; in CMD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="nb"&gt;curl&lt;/span&gt; &lt;span class="na"&gt;-fsSL &lt;/span&gt;&lt;span class="kd"&gt;https&lt;/span&gt;://claude.ai/install.cmd &lt;span class="na"&gt;-o &lt;/span&gt;&lt;span class="kd"&gt;install&lt;/span&gt;.cmd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kd"&gt;install&lt;/span&gt;.cmd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;del&lt;/span&gt; &lt;span class="kd"&gt;install&lt;/span&gt;.cmd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WinGet works too, but a WinGet install does not auto-update, so run &lt;code&gt;winget upgrade Anthropic.ClaudeCode&lt;/code&gt; periodically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;winget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Anthropic.ClaudeCode&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The npm package is another option and needs Node.js 22 or later. You do not need to run the installer as Administrator.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Start it and check
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\path\to\project&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first run prompts you to log in. &lt;code&gt;claude doctor&lt;/code&gt; reports installation health and settings-file validation errors without starting a session.&lt;/p&gt;

&lt;p&gt;If Claude Code cannot find Git Bash, point at it in your settings file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CLAUDE_CODE_GIT_BASH_PATH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Program Files&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Git&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;bin&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;bash.exe"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing in WSL
&lt;/h2&gt;

&lt;p&gt;Sandboxed command execution requires WSL 2; WSL 1 does not support it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;wsl --install&lt;/code&gt; in an elevated PowerShell and restart. Ubuntu is installed by default.&lt;/li&gt;
&lt;li&gt;Open the Ubuntu terminal and install Node.js if you plan to use the npm package (nvm is the easy route).&lt;/li&gt;
&lt;li&gt;Install with the Linux command — you run it inside the WSL terminal, not from PowerShell or CMD:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For VS Code, install the WSL extension, open a folder inside WSL, and install the Claude Code extension into WSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  What trips people up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hooks and scripts run through Git Bash
&lt;/h3&gt;

&lt;p&gt;With Git for Windows installed, the Bash tool uses Git Bash, so PowerShell cmdlets are not available directly. Invoke PowerShell explicitly instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PostToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Edit|Write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"powershell -NoProfile -File .claude/hooks/format.ps1"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For hook basics, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-hooks-lint-format/" rel="noopener noreferrer"&gt;Run lint and format on save with Claude Code hooks&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing paths
&lt;/h3&gt;

&lt;p&gt;In permission patterns and &lt;code&gt;CLAUDE.md&lt;/code&gt;, forward slashes (&lt;code&gt;src/**&lt;/code&gt;) work on Windows too. Avoid backslashes, which need escaping inside JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encoding
&lt;/h3&gt;

&lt;p&gt;If command output comes back garbled, set PowerShell's output encoding to UTF-8:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;OutputEncoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Text.Encoding&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Line endings
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;CLAUDE.md&lt;/code&gt; or hook script saved with CRLF by a Windows editor can fail under Git Bash when a stray &lt;code&gt;\r&lt;/code&gt; ends up in the script. Set &lt;code&gt;*.sh text eol=lf&lt;/code&gt; in &lt;code&gt;.gitattributes&lt;/code&gt; and save scripts with LF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install natively from PowerShell with &lt;code&gt;irm https://claude.ai/install.ps1 | iex&lt;/code&gt;; Git for Windows is optional, and without it the PowerShell tool runs commands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandboxing means WSL 2.&lt;/strong&gt; Native Windows and WSL 1 do not support it. Keep projects inside WSL when you go that route&lt;/li&gt;
&lt;li&gt;Write hooks and scripts for Git Bash, and keep line endings at LF&lt;/li&gt;
&lt;li&gt;Fix garbled output with UTF-8 output encoding, and use forward slashes in paths&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claudecode</category>
      <category>windows</category>
      <category>wsl</category>
      <category>setup</category>
    </item>
    <item>
      <title>Run Claude Code in GitHub Actions with claude-code-action</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Fri, 16 Oct 2026 19:22:27 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/run-claude-code-in-github-actions-with-claude-code-action-323o</link>
      <guid>https://dev.to/aicoding-guide/run-claude-code-in-github-actions-with-claude-code-action-323o</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/claude-code-github-actions/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Comment "&lt;a class="mentioned-user" href="https://dev.to/claude"&gt;@claude&lt;/a&gt; fix this bug" on an issue and have Claude Code implement the fix and open a pull request. Have a review appear automatically when a PR opens. Both come from the official &lt;strong&gt;claude-code-action&lt;/strong&gt;, configured with workflow files in your repository.&lt;/p&gt;

&lt;p&gt;This article covers setup, the two basic configurations — mention response and automated review — and how to limit permissions and cost.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up with &lt;code&gt;/install-github-app&lt;/code&gt;, and which authentication secret to use&lt;/li&gt;
&lt;li&gt;The workflow that responds to &lt;code&gt;@claude&lt;/code&gt; mentions&lt;/li&gt;
&lt;li&gt;The automated review workflow, who can trigger runs, and how to cap cost&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting up
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;/install-github-app&lt;/code&gt; from Claude Code inside the repository. It installs the Claude GitHub App, sets up the authentication secret, and pushes a branch with the workflow files, opening a pull request for you to create. You need admin access to the repository, and the GitHub CLI installed and authenticated with &lt;code&gt;gh auth login&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Register the authentication secret. Use &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; for a Claude API key from the Claude Console, or &lt;code&gt;CLAUDE_CODE_OAUTH_TOKEN&lt;/code&gt; for a subscription token generated with &lt;code&gt;claude setup-token&lt;/code&gt;. In the workflow, pass them to &lt;code&gt;anthropic_api_key&lt;/code&gt; and &lt;code&gt;claude_code_oauth_token&lt;/code&gt; respectively.&lt;/li&gt;
&lt;li&gt;Create and merge the pull request. &lt;code&gt;@claude&lt;/code&gt; then works in the repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;/install-github-app&lt;/code&gt; only works with github.com repositories; on a gitlab.com or bitbucket.org remote it prints a notice and exits. For manual setup, install the &lt;a href="https://github.com/apps/claude" rel="noopener noreferrer"&gt;Claude GitHub App&lt;/a&gt; yourself, add the secret, and copy &lt;code&gt;examples/claude.yml&lt;/code&gt; into &lt;code&gt;.github/workflows/&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;The GitHub App and &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;&lt;/strong&gt;: by default the action authenticates as the Claude GitHub App. If you pass &lt;code&gt;github_token: ${{ secrets.GITHUB_TOKEN }}&lt;/code&gt; instead, GitHub won't trigger workflows on the commits Claude makes — the documented fix for "CI not running on Claude's commits" is to remove that line.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuration 1: respond to &lt;a class="mentioned-user" href="https://dev.to/claude"&gt;@claude&lt;/a&gt; mentions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Claude Code&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;issue_comment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request_review_comment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;claude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;contains(github.event.comment.body, '@claude')&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;issues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropics/claude-code-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;anthropic_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;id-token: write&lt;/code&gt; is required for the action's default GitHub App authentication, and &lt;code&gt;actions: read&lt;/code&gt; lets Claude read CI results on PRs. With no &lt;code&gt;prompt&lt;/code&gt; input, the action runs in &lt;strong&gt;interactive mode&lt;/strong&gt; and waits for the trigger phrase — &lt;code&gt;@claude&lt;/code&gt; by default, changeable with &lt;code&gt;trigger_phrase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Requests that work well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On an issue: "&lt;a class="mentioned-user" href="https://dev.to/claude"&gt;@claude&lt;/a&gt; reproduce this and open a PR with a fix"&lt;/li&gt;
&lt;li&gt;On a review comment: "&lt;a class="mentioned-user" href="https://dev.to/claude"&gt;@claude&lt;/a&gt; add error handling to this function"&lt;/li&gt;
&lt;li&gt;On a PR: "&lt;a class="mentioned-user" href="https://dev.to/claude"&gt;@claude&lt;/a&gt; add tests for what this change affects"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration 2: review automatically when a PR opens
&lt;/h2&gt;

&lt;p&gt;Supplying a &lt;code&gt;prompt&lt;/code&gt; input puts the action in &lt;strong&gt;automation mode&lt;/strong&gt;, which runs without waiting for a mention. The configuration the documentation now shows calls the &lt;code&gt;code-review&lt;/code&gt; plugin's skill rather than a free-text prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Code Review&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ready_for_review&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;issues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropics/claude-code-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;anthropic_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;plugin_marketplaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/anthropics/claude-code.git"&lt;/span&gt;
          &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code-review@claude-code-plugins"&lt;/span&gt;
          &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/code-review:code-review&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--comment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;github.repository&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}/pull/${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;github.event.pull_request.number&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
          &lt;span class="na"&gt;claude_args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--allowedTools&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"mcp__github_inline_comment__create_inline_comment"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Without --comment, nothing is posted&lt;/strong&gt;&lt;br&gt;
In automation mode, "By default, results appear in the workflow run log rather than a comment." &lt;code&gt;--comment&lt;/code&gt; is what makes Claude post on the pull request. Keep the &lt;code&gt;claude_args&lt;/code&gt; line too: even though the skill's own &lt;code&gt;allowed-tools&lt;/code&gt; frontmatter names the same tool, the action starts the inline-comment MCP server only when &lt;code&gt;--allowedTools&lt;/code&gt; in &lt;code&gt;claude_args&lt;/code&gt; names it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With a free-text &lt;code&gt;prompt&lt;/code&gt; you have to grant the tools yourself: "For a plain-text prompt, Claude has no shell or GitHub API access until you grant the tools the prompt needs" — through &lt;code&gt;--allowedTools&lt;/code&gt; in &lt;code&gt;claude_args&lt;/code&gt;, or a &lt;code&gt;permissions.allow&lt;/code&gt; rule in the &lt;code&gt;settings&lt;/code&gt; input.&lt;/p&gt;

&lt;p&gt;Claude skips draft and closed pull requests, ones it judges not to need review, and ones that already carry a comment from Claude.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limiting permissions and cost
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;How&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keep outsiders from triggering runs&lt;/td&gt;
&lt;td&gt;Already checked by the action (see below). Narrow further with an &lt;code&gt;if:&lt;/code&gt; on &lt;code&gt;github.event.comment.author_association&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minimize write access&lt;/td&gt;
&lt;td&gt;Give the review workflow &lt;code&gt;contents: read&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restrict the tools&lt;/td&gt;
&lt;td&gt;Pass &lt;code&gt;--allowedTools&lt;/code&gt; in &lt;code&gt;claude_args&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cap the work per run&lt;/td&gt;
&lt;td&gt;Pass &lt;code&gt;--max-turns&lt;/code&gt;, and set a workflow-level timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforce your project's rules&lt;/td&gt;
&lt;td&gt;Put them in the repository's &lt;code&gt;CLAUDE.md&lt;/code&gt;, which the action reads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Who can trigger a run is checked by the action itself&lt;/strong&gt;: two checks run before Claude starts, and the run fails if either rejects it. &lt;strong&gt;Write access&lt;/strong&gt; — on issue and pull request events the triggering user must have write access to the repository; to allow specific users without it, set &lt;code&gt;allowed_non_write_users&lt;/code&gt; and pass your own &lt;code&gt;github_token&lt;/code&gt;. &lt;strong&gt;Human actor&lt;/strong&gt; — a bot actor is rejected unless listed in &lt;code&gt;allowed_bots&lt;/code&gt;, which keeps bots from triggering Claude in a loop. That check also applies to scheduled runs, which GitHub attributes to a repository user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secrets and pull requests from forks&lt;/strong&gt;&lt;br&gt;
On public repositories, GitHub withholds secrets from runs triggered by fork pull requests, so a review workflow runs only on pull requests from branches in the same repository. Before reaching for &lt;code&gt;pull_request_target&lt;/code&gt; to change that, understand that it runs the fork's code with your secrets available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How this relates to CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;Claude inside the action reads the repository's &lt;code&gt;CLAUDE.md&lt;/code&gt; the same as it does locally — the documentation lists "Define project standards in CLAUDE.md" as a best practice, and notes that Claude reads it on every run, so keeping it concise also keeps cost down. Review criteria and prohibitions belong there rather than in the workflow's &lt;code&gt;prompt&lt;/code&gt;, so you maintain one copy (&lt;a href="https://aicoding-guide.com/en/posts/claude-md-how-to-write/" rel="noopener noreferrer"&gt;How to write CLAUDE.md&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For a lighter setup that calls &lt;code&gt;claude -p&lt;/code&gt; directly instead of using the official action, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-headless-ci/" rel="noopener noreferrer"&gt;Run Claude Code headless in CI&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt; installs the app and workflows; register &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; or &lt;code&gt;CLAUDE_CODE_OAUTH_TOKEN&lt;/code&gt; as the secret&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;prompt&lt;/code&gt; means interactive mode and the &lt;code&gt;@claude&lt;/code&gt; trigger; a &lt;code&gt;prompt&lt;/code&gt; means automation mode&lt;/li&gt;
&lt;li&gt;In automation mode results go to the run log unless you pass &lt;code&gt;--comment&lt;/code&gt; and name the inline-comment tool in &lt;code&gt;claude_args&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Write access and a human-actor check already gate who can trigger runs; &lt;code&gt;allowed_bots&lt;/code&gt; and &lt;code&gt;allowed_non_write_users&lt;/code&gt; adjust them&lt;/li&gt;
&lt;li&gt;Keep review criteria in &lt;code&gt;CLAUDE.md&lt;/code&gt;, and cap cost with &lt;code&gt;--max-turns&lt;/code&gt;, a smaller model, and workflow timeouts&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claudecode</category>
      <category>githubactions</category>
      <category>ci</category>
      <category>automation</category>
    </item>
    <item>
      <title>Review debt in the AI era cannot be repaid by reading more</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Thu, 15 Oct 2026 19:17:36 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/review-debt-in-the-ai-era-cannot-be-repaid-by-reading-more-4gkd</link>
      <guid>https://dev.to/aicoding-guide/review-debt-in-the-ai-era-cannot-be-repaid-by-reading-more-4gkd</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/essay-review-debt/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Review debt cannot be repaid by reading more. It can only be repaid by shrinking the unit you ship, by letting machines fail what they can, or by making the risky thing impossible in the first place.&lt;/p&gt;

&lt;p&gt;The first thing an AI coding tool breaks is the balance between writing and reading. Generation gets several times faster; the rate at which a person reads a diff and judges whether it is right does not. What piles up in that gap is review debt.&lt;/p&gt;

&lt;p&gt;Everything below rests on the Claude Code documentation as fetched on 2026-10-16.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why adding reviewers does not close the gap&lt;/li&gt;
&lt;li&gt;Three ways to repay the debt, and the mechanism behind each&lt;/li&gt;
&lt;li&gt;When the argument fails&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Headcount does not catch up
&lt;/h2&gt;

&lt;p&gt;Start with the direction parallelism pushes. On agent teams the documentation says: "Agent teams use approximately 7x more tokens than standard sessions when teammates run in plan mode." Tokens stand in for output volume: raise the parallelism and the pile grows faster than the number of people reviewing it.&lt;/p&gt;

&lt;p&gt;Adding reviewers has its own ceiling. You can add readers; you cannot reduce the context each change requires. Readers who don't share that context add variance in judgment, not throughput.&lt;/p&gt;

&lt;p&gt;What has to change is not the supply of reading but the &lt;strong&gt;demand for it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  One: shrink the unit you ship
&lt;/h2&gt;

&lt;p&gt;Agree on direction before the diff gets large, rather than reading it afterwards. This is why the documentation recommends plan mode: "Claude explores the codebase and proposes an approach for your approval, preventing expensive re-work when the initial direction is wrong."&lt;/p&gt;

&lt;p&gt;What the human reads there is an approach, not code. The reading shrinks by an order of magnitude, and so does what you throw away when it's wrong (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-plan-mode/" rel="noopener noreferrer"&gt;Claude Code plan mode&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A second move: &lt;strong&gt;keep things out of the diff entirely&lt;/strong&gt;. Exploration produces no code but fills your context. The docs put it plainly — "Delegate the exploration so only the findings come back" and "The subagent reads files in its own context window and reports a summary" (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-subagents/" rel="noopener noreferrer"&gt;Create subagents in Claude Code&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Two: let the machine fail it first
&lt;/h2&gt;

&lt;p&gt;Before a person reads, let the machine reject what it can — the review-stage version of the previous essay's point that &lt;a href="https://aicoding-guide.com/en/posts/essay-tests-as-fixed-point/" rel="noopener noreferrer"&gt;only what can fail is a fixed point&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The tools now ship this idea themselves. The auto mode description reads: "In auto mode, a second model, the classifier, reviews actions instead of you." &lt;strong&gt;Instead of you.&lt;/strong&gt; Part of review has already moved from humans to machines.&lt;/p&gt;

&lt;p&gt;Hooks do the same job. In v2.1.295, command and HTTP hooks gained &lt;code&gt;onFailure: "block"&lt;/code&gt;: a hook that can't start, times out or exits unexpectedly now blocks rather than letting the action through. A broken check no longer waves things past, which is what makes a machine pass trustworthy before the human one (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-hooks-lint-format/" rel="noopener noreferrer"&gt;Run lint and format on save with Claude Code hooks&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Where nobody is watching, this layer &lt;em&gt;is&lt;/em&gt; the review (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-headless-ci/" rel="noopener noreferrer"&gt;Run Claude Code headless in CI&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Three: make it not happen
&lt;/h2&gt;

&lt;p&gt;The third route removes the thing to review: an action that never ran needs no reviewing.&lt;/p&gt;

&lt;p&gt;What does the work here is permissions, not requests to the model: "Permission rules are enforced by Claude Code, not by the model," and instructions in your prompt or &lt;code&gt;CLAUDE.md&lt;/code&gt; shape "what Claude tries to do" but not "what Claude Code allows."&lt;/p&gt;

&lt;p&gt;In practice, convert the comments you keep writing in review into deny or ask rules. "Never touch the production config" and "always stop before a push" are more reliable as one rule each than as a comment every time, and once written they leave the review queue (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-settings-json-permissions/" rel="noopener noreferrer"&gt;Design permissions in Claude Code's settings.json&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Objections and limits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Some mistakes no machine catches.&lt;/strong&gt; Design soundness, a misread domain, a wrong specification — none of these fail a test, a hook or a classifier. The auto mode docs note that "Explicit ask rules still force a prompt", assuming a human stays in the loop by design. Machine review narrows what a person looks at; it does not replace them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shrinking each change hides the whole.&lt;/strong&gt; The smaller the diff, the easier it is to miss that the design is drifting. That is why the first route is "agree the approach before splitting", not "split". Skip the agreement and the debt moves into the design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can only constrain known risks.&lt;/strong&gt; A deny rule names a danger you already thought of. A new category gets caught in review the first time, always. Permission design fixes the &lt;em&gt;output&lt;/em&gt; of review, not its input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some work doesn't carry this debt.&lt;/strong&gt; Throwaway prototypes and scripts with no external effect — there, repaying review debt costs more than it returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Output scales with parallelism; the context each change needs does not, so more reviewers never catch up&lt;/li&gt;
&lt;li&gt;Route one: agree the approach before the diff grows — plan mode's documented rationale&lt;/li&gt;
&lt;li&gt;Route two: let machines fail it. The auto mode classifier reviews "instead of you"&lt;/li&gt;
&lt;li&gt;Route three: constrain with permissions. An action that never ran is never reviewed&lt;/li&gt;
&lt;li&gt;The limits: design errors fail nothing, small diffs hide drift, and you can only constrain known risks&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aicoding</category>
      <category>codereview</category>
      <category>permissions</category>
      <category>hooks</category>
    </item>
    <item>
      <title>Getting started with Claude Code, from install to your first hour</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Tue, 13 Oct 2026 19:16:42 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/getting-started-with-claude-code-from-install-to-your-first-hour-2ooi</link>
      <guid>https://dev.to/aicoding-guide/getting-started-with-claude-code-from-install-to-your-first-hour-2ooi</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/claude-code-getting-started/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two things trip people up on a first install of Claude Code: which install method to pick, and what to check once it is in.&lt;/p&gt;

&lt;p&gt;The short answer: pick the install method by &lt;strong&gt;whether it auto-updates&lt;/strong&gt;. Only the native installer and npm update themselves; Homebrew, WinGet and the Linux package managers are manual. Then verify with &lt;code&gt;claude --version&lt;/code&gt; and &lt;code&gt;claude doctor&lt;/code&gt; before starting your first session.&lt;/p&gt;

&lt;p&gt;Everything below comes from the official documentation as fetched on 2026-10-14. For what Claude Code &lt;em&gt;is&lt;/em&gt;, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-what-is/" rel="noopener noreferrer"&gt;What Claude Code is&lt;/a&gt;; this page goes in the order you actually type things.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The system requirements and which plans include Claude Code&lt;/li&gt;
&lt;li&gt;How to choose an install method (it comes down to auto-updates)&lt;/li&gt;
&lt;li&gt;Your first session, and what to touch in the first hour&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Requirements and the plans that include it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;macOS 13.0+, Windows 10 1809+ or Windows Server 2019+, Ubuntu 20.04+, Debian 10+, Alpine Linux 3.19+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware&lt;/td&gt;
&lt;td&gt;4 GB+ RAM, x64 or ARM64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shell&lt;/td&gt;
&lt;td&gt;Bash, Zsh, PowerShell or CMD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;An internet connection is required&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The free plan does not include it&lt;/strong&gt;&lt;br&gt;
Claude Code requires a Pro, Max, Team, Enterprise or Claude Console account. The documentation is explicit: "The free claude.ai plan does not include Claude Code access." Amazon Bedrock, Google Cloud's Agent Platform and Microsoft Foundry also work. For what each plan costs, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-pricing-plans/" rel="noopener noreferrer"&gt;Claude Code pricing and plans&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Choose an install method by its update behavior
&lt;/h2&gt;

&lt;p&gt;This is the first fork in the road. &lt;strong&gt;Only the native installer and npm update themselves.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Auto-updates&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native (recommended)&lt;/td&gt;
&lt;td&gt;`curl -fsSL &lt;a href="https://claude.ai/install.sh" rel="noopener noreferrer"&gt;https://claude.ai/install.sh&lt;/a&gt; \&lt;/td&gt;
&lt;td&gt;bash`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homebrew&lt;/td&gt;
&lt;td&gt;&lt;code&gt;brew install --cask claude-code&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WinGet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;winget install Anthropic.ClaudeCode&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apt / dnf / apk&lt;/td&gt;
&lt;td&gt;Register the repository, then install&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On macOS, Linux and WSL the native install is one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows the command depends on your shell. Your prompt shows &lt;code&gt;PS C:\&lt;/code&gt; in PowerShell and &lt;code&gt;C:\&lt;/code&gt; without the &lt;code&gt;PS&lt;/code&gt; in CMD.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://claude.ai/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="nb"&gt;curl&lt;/span&gt; &lt;span class="na"&gt;-fsSL &lt;/span&gt;&lt;span class="kd"&gt;https&lt;/span&gt;://claude.ai/install.cmd &lt;span class="na"&gt;-o &lt;/span&gt;&lt;span class="kd"&gt;install&lt;/span&gt;.cmd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kd"&gt;install&lt;/span&gt;.cmd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;del&lt;/span&gt; &lt;span class="kd"&gt;install&lt;/span&gt;.cmd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The install command shows no progress while it downloads. When it finishes, &lt;strong&gt;open a new terminal window&lt;/strong&gt; before checking.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Release channel&lt;/strong&gt;: the &lt;code&gt;autoUpdatesChannel&lt;/code&gt; setting takes &lt;code&gt;"latest"&lt;/code&gt; (the default — new versions as they ship) or &lt;code&gt;"stable"&lt;/code&gt; (typically about a week old, skipping releases with major regressions). Homebrew picks by cask name instead: &lt;code&gt;claude-code&lt;/code&gt; is stable and &lt;code&gt;claude-code@latest&lt;/code&gt; is latest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The npm package needs Node.js 22 or later. Do not use &lt;code&gt;sudo npm install -g&lt;/code&gt; — the documentation warns it leads to permission issues and security risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify, then start your first session
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A working installation prints a version number such as &lt;code&gt;2.1.211 (Claude Code)&lt;/code&gt;. If you get &lt;code&gt;command not found&lt;/code&gt;, the install directory is not on your PATH yet.&lt;/p&gt;

&lt;p&gt;For a fuller check, &lt;code&gt;claude doctor&lt;/code&gt; prints read-only installation and settings diagnostics without starting a session: install health, settings-file validation errors, and warnings with suggested fixes. It also reports the result of the most recent update attempt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start it in the project you want to work in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/your/project
claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first run prompts you to log in through your browser. If you have set &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; and you approve the key when Claude Code asks whether to use it, the login prompt is skipped. Once you are logged in, the credentials are stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to decide on Windows
&lt;/h2&gt;

&lt;p&gt;Windows gives you native or WSL, and the difference that matters most is &lt;strong&gt;whether sandboxing is available&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Sandboxing&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native Windows&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Windows-native projects and tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WSL 2&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Linux toolchains, or sandboxed command execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WSL 1&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;If WSL 2 is unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On native Windows, &lt;a href="https://git-scm.com/downloads/win" rel="noopener noreferrer"&gt;Git for Windows&lt;/a&gt; is optional but worth having: it provides Git Bash, which backs the Bash tool. Without it, Claude Code runs shell commands through the PowerShell tool. If Git Bash cannot be found, point at it in settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CLAUDE_CODE_GIT_BASH_PATH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Program Files&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Git&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;bin&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;bash.exe"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The first hour
&lt;/h2&gt;

&lt;p&gt;Once a session is open, work through these in order.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the permission mode.&lt;/strong&gt; It shows in the status bar. With v2.1.283 or later, terminal and VS Code sessions start in &lt;code&gt;auto&lt;/code&gt; on every plan. &lt;code&gt;Shift+Tab&lt;/code&gt; cycles modes at any time. The six modes are compared in &lt;a href="https://aicoding-guide.com/en/posts/claude-code-default-mode/" rel="noopener noreferrer"&gt;Claude Code permission modes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Have it explain the project.&lt;/strong&gt; Just ask &lt;code&gt;what does this project do?&lt;/code&gt; — Claude reads the files it needs, so you don't add context by hand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a CLAUDE.md.&lt;/strong&gt; &lt;code&gt;/init&lt;/code&gt; scaffolds one for the project. For what to put in it, see &lt;a href="https://aicoding-guide.com/en/posts/claude-md-how-to-write/" rel="noopener noreferrer"&gt;How to write CLAUDE.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send one small change.&lt;/strong&gt; Something like &lt;code&gt;add a hello world function to the main file&lt;/code&gt;, to see the approval flow once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write a single deny rule.&lt;/strong&gt; Before widening the automation, put what must not be touched into &lt;code&gt;permissions.deny&lt;/code&gt; in &lt;code&gt;.claude/settings.json&lt;/code&gt; — see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-settings-json-permissions/" rel="noopener noreferrer"&gt;Design permissions in Claude Code's settings.json&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look at your usage.&lt;/strong&gt; &lt;code&gt;/usage&lt;/code&gt; shows how much of your plan you are consuming; &lt;a href="https://aicoding-guide.com/en/posts/claude-code-cost-usage/" rel="noopener noreferrer"&gt;Check Claude Code usage and cost&lt;/a&gt; covers the rest&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The commands worth memorizing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start interactive mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude "task"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start with an initial prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude -p "query"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run one query, then exit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude -c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue the most recent conversation in this directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude -r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resume a previous conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show available commands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clear conversation history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Switch accounts or re-authenticate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Requirements: macOS 13.0+, Windows 10 1809+, Ubuntu 20.04+ and similar, with 4 GB+ RAM&lt;/li&gt;
&lt;li&gt;The free claude.ai plan does not include Claude Code; you need Pro, Max, Team, Enterprise, Console or a cloud provider&lt;/li&gt;
&lt;li&gt;Pick the install method by auto-update behavior: native and npm update themselves, Homebrew, WinGet, apt, dnf and apk do not&lt;/li&gt;
&lt;li&gt;Verify with &lt;code&gt;claude --version&lt;/code&gt;, and read &lt;code&gt;claude doctor&lt;/code&gt; when something is off&lt;/li&gt;
&lt;li&gt;On Windows, sandboxing means WSL 2; native Windows and WSL 1 do not support it&lt;/li&gt;
&lt;li&gt;In the first hour: check the permission mode, run &lt;code&gt;/init&lt;/code&gt;, send one small change, then write a deny rule&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claudecode</category>
      <category>install</category>
      <category>gettingstarted</category>
      <category>setup</category>
    </item>
    <item>
      <title>Codex CLI v0.161 and v0.162 changes, and GPT-6.1 Sol becoming the default model</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Sun, 11 Oct 2026 19:13:42 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/codex-cli-v0161-and-v0162-changes-and-gpt-61-sol-becoming-the-default-model-502m</link>
      <guid>https://dev.to/aicoding-guide/codex-cli-v0161-and-v0162-changes-and-gpt-61-sol-becoming-the-default-model-502m</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/codex-update-0-161/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Codex CLI v0.161.0 and v0.162.0 carry two changes that reach into your configuration: &lt;strong&gt;the default model was swapped&lt;/strong&gt; and &lt;strong&gt;the way Daybreak is enabled changed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Two things are worth checking because of them: whether you pin a model in &lt;code&gt;config.toml&lt;/code&gt;, and whether you have added the &lt;code&gt;cli_daybreak&lt;/code&gt; opt-in if you use Daybreak.&lt;/p&gt;

&lt;p&gt;Setting keys below are only the ones confirmed against the official configuration reference as fetched on 2026-10-12; anything unconfirmed is marked as such.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where GPT-6.1 Sol became the default, and how to pin a model yourself&lt;/li&gt;
&lt;li&gt;That Daybreak now requires an explicit opt-in&lt;/li&gt;
&lt;li&gt;The approval and sandbox changes, and where the worktree tools stand&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  GPT-6.1 Sol is the new default model
&lt;/h2&gt;

&lt;p&gt;The v0.161.0 release notes read "GPT-6.1 Sol is now the default model in the bundled and Amazon Bedrock catalogs." What is stated as default is &lt;strong&gt;the bundled catalog and the Amazon Bedrock catalog&lt;/strong&gt;; other setups are not addressed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;model&lt;/code&gt; row in the configuration reference now uses &lt;code&gt;gpt-6.1-sol&lt;/code&gt; as its example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;model&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Model to use (e.g., &lt;code&gt;gpt-6.1-sol&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To pin it instead of taking the default, put it at the top level of &lt;code&gt;~/.codex/config.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"gpt-6.1-sol"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Check availability on your account first&lt;/strong&gt;&lt;br&gt;
The reference says to "Set &lt;code&gt;model&lt;/code&gt; to one available to your signed-in account or workspace," and tells you to check GPT-6.1 Sol availability before using that example value. If your organization's workspace doesn't offer it, writing it into &lt;code&gt;model&lt;/code&gt; won't make it work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Amazon Bedrock also gained multi-agent V2 and Ultra reasoning support. For setting reasoning depth, see &lt;a href="https://aicoding-guide.com/en/posts/codex-reasoning-effort/" rel="noopener noreferrer"&gt;Change the reasoning effort in Codex&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Daybreak needs an explicit opt-in
&lt;/h2&gt;

&lt;p&gt;This is the change most likely to break an existing setup. The release notes read: "Daybreak is opt-in through &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak=true&lt;/code&gt;; &lt;code&gt;daybreak=true&lt;/code&gt; alone is insufficient."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# v0.161.0 and later. daybreak = true on its own does nothing&lt;/span&gt;
&lt;span class="nn"&gt;[features]&lt;/span&gt;
&lt;span class="py"&gt;cli_daybreak&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default the controls and indicators are hidden and &lt;code&gt;/daybreak&lt;/code&gt; is unavailable — and automatic Cyber routing is omitted even for saved Daybreak threads. Saved preferences themselves remain intact, so adding &lt;code&gt;cli_daybreak&lt;/code&gt; restores the previous state. &lt;code&gt;codex exec --cyber-access-program&lt;/code&gt; was also added for choosing a Cyber access program per turn; that override stays available with &lt;code&gt;cli_daybreak&lt;/code&gt; disabled.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;features.cli_daybreak is not in the configuration reference&lt;/strong&gt;&lt;br&gt;
As of 2026-10-12 there is no &lt;code&gt;cli_daybreak&lt;/code&gt; row in the official reference's &lt;code&gt;features.*&lt;/code&gt; table. The key name appears only in the release notes. The rows that &lt;em&gt;are&lt;/em&gt; listed include &lt;code&gt;features.apps&lt;/code&gt;, &lt;code&gt;features.hooks&lt;/code&gt;, &lt;code&gt;features.memories&lt;/code&gt;, &lt;code&gt;features.multi_agent&lt;/code&gt; and &lt;code&gt;features.network_proxy&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For &lt;code&gt;config.toml&lt;/code&gt; as a whole, see &lt;a href="https://aicoding-guide.com/en/posts/codex-config-toml/" rel="noopener noreferrer"&gt;What you can configure in Codex's config.toml&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approval and sandbox changes
&lt;/h2&gt;

&lt;p&gt;Permissions got fixes in both releases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Approved escalation&lt;/strong&gt;: approved filesystem escalation can now grant broader write access while preserving denied reads and network restrictions. Background tasks retain their originating turn's permissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux sandbox&lt;/strong&gt;: startup with multiple denied files is fixed, and writable sandbox-construction executables are now rejected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ripgrep config&lt;/strong&gt;: ripgrep configuration no longer weakens deny-glob masks. Paths you were protecting with a deny rule may have been visible to search, so this is worth upgrading for if you exclude sensitive files in the sandbox&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: elevated terminal sessions can start using an embedded server, and ordinary drive-letter file access is restored on Windows 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the approval policy and sandbox settings themselves, see &lt;a href="https://aicoding-guide.com/en/posts/codex-approval-sandbox/" rel="noopener noreferrer"&gt;Codex approval policy and sandbox settings&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Worktree tools, the TUI, and the rest
&lt;/h2&gt;

&lt;p&gt;In v0.162.0, &lt;strong&gt;when the worktrees feature is enabled&lt;/strong&gt;, there are tools for creating and listing managed Git worktrees from trusted local projects. The key that enables that feature could not be confirmed in the official configuration reference.&lt;/p&gt;

&lt;p&gt;In the TUI: &lt;code&gt;/copy&lt;/code&gt; navigates and copies transcript blocks, &lt;code&gt;Ctrl+Insert&lt;/code&gt; copies a selection, mouse-wheel speed is tunable (the release notes name &lt;code&gt;tui.mouse_scroll_speed&lt;/code&gt;, which likewise does not appear in the reference's &lt;code&gt;tui.*&lt;/code&gt; table), and URLs are clickable in approval headers, questions, MCP prompts, warnings and banners, including across wrapped lines.&lt;/p&gt;

&lt;p&gt;The rest, as it touches configuration and operations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.160.1&lt;/td&gt;
&lt;td&gt;Preserves &lt;code&gt;SYSTEMROOT&lt;/code&gt;, &lt;code&gt;TEMP&lt;/code&gt; and &lt;code&gt;TMP&lt;/code&gt; when launching remote stdio MCP servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.161.0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/mcp login &amp;lt;name&amp;gt;&lt;/code&gt; signs in to an MCP server from an active session&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.162.0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;apply_patch&lt;/code&gt; preserves existing CRLF line endings without an opt-in; Windows releases ship a signed PowerShell installer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.162.1&lt;/td&gt;
&lt;td&gt;Fixes a TUI crash on multi-line asynchronous questions, and startup failures from feature-setting differences between a running background server and CLI defaults&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For adding MCP servers, see &lt;a href="https://aicoding-guide.com/en/posts/codex-mcp-setup/" rel="noopener noreferrer"&gt;Set up MCP servers in Codex&lt;/a&gt;; for the previous release, &lt;a href="https://aicoding-guide.com/en/posts/codex-update-0-160/" rel="noopener noreferrer"&gt;Codex CLI v0.160 changes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;v0.161.0 makes GPT-6.1 Sol the default in the bundled and Amazon Bedrock catalogs; confirm separately that your account can use it&lt;/li&gt;
&lt;li&gt;To pin a model, set &lt;code&gt;model = "gpt-6.1-sol"&lt;/code&gt; at the top level of &lt;code&gt;config.toml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Daybreak needs &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak = true&lt;/code&gt;; &lt;code&gt;daybreak = true&lt;/code&gt; alone does nothing&lt;/li&gt;
&lt;li&gt;ripgrep configuration no longer weakens deny-glob masks — worth upgrading for if the sandbox excludes sensitive files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;features.cli_daybreak&lt;/code&gt;, the worktrees feature flag and &lt;code&gt;tui.mouse_scroll_speed&lt;/code&gt; are all absent from the official configuration reference's tables&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codex</category>
      <category>codexcli</category>
      <category>updates</category>
      <category>gpt61sol</category>
    </item>
    <item>
      <title>Claude Code permissions by example, auto-allow npm scripts, confirm git push, block force push</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Sat, 10 Oct 2026 23:16:31 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/claude-code-permissions-by-example-auto-allow-npm-scripts-confirm-git-push-block-force-push-4blb</link>
      <guid>https://dev.to/aicoding-guide/claude-code-permissions-by-example-auto-allow-npm-scripts-confirm-git-push-block-force-push-4blb</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/claude-code-permissions-examples/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you let Claude Code drive, you usually want three lines drawn. Scripts you wrote yourself, such as &lt;code&gt;npm run lint&lt;/code&gt; and &lt;code&gt;npm run test&lt;/code&gt;, should run without a prompt. &lt;code&gt;git push&lt;/code&gt; reaches the remote, so you want one last look right before it. &lt;code&gt;git push --force&lt;/code&gt; should never run at all.&lt;/p&gt;

&lt;p&gt;All three fit in a single &lt;code&gt;permissions&lt;/code&gt; block in &lt;code&gt;settings.json&lt;/code&gt;, using the three layers allow, ask and deny. This article shows the finished configuration first, then explains each layer and the places people trip.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A complete settings.json that combines allow, ask and deny&lt;/li&gt;
&lt;li&gt;What the &lt;code&gt;:*&lt;/code&gt; prefix match means, and how to keep install commands out of an allow rule&lt;/li&gt;
&lt;li&gt;Why ask outranks allow, and why "don't ask again" still prompts&lt;/li&gt;
&lt;li&gt;How to cover every spelling of a force push (&lt;code&gt;-f&lt;/code&gt;, &lt;code&gt;--force-with-lease&lt;/code&gt;, reordered options) with deny&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The finished configuration
&lt;/h2&gt;

&lt;p&gt;Put this in the project's &lt;code&gt;.claude/settings.json&lt;/code&gt;. It is written to be shared with a team.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm run:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm test)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx tsc:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx vitest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx eslint:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx prettier:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git status)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git diff:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git log:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git add:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git commit:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm i:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm uninstall:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push --force:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push -f:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push --force-with-lease:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push * --force:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, scripts and the read-only Git commands plus commits run silently, &lt;code&gt;git push&lt;/code&gt; and &lt;code&gt;npm install&lt;/code&gt; open a dialog, and a force push is refused.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Rule precedence&lt;/strong&gt;: rules are evaluated deny, then ask, then allow, and the first match in that order decides. Specificity does not change the order. An allow rule for &lt;code&gt;Bash(git:*)&lt;/code&gt; does not stop an ask rule for &lt;code&gt;Bash(git push:*)&lt;/code&gt; from prompting, and a deny match is refused in every permission mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Auto-allow npm scripts (allow)
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;Bash(npm run:*)&lt;/code&gt;, &lt;code&gt;:*&lt;/code&gt; is a prefix match: "starts with &lt;code&gt;npm run&lt;/code&gt;, anything may follow." It matches arguments too, such as &lt;code&gt;npm run test -- --watch&lt;/code&gt;. &lt;code&gt;npm install&lt;/code&gt; begins differently, so it is not swept in. Put the &lt;code&gt;*&lt;/code&gt; after the subcommand; a rule with the &lt;code&gt;*&lt;/code&gt; before it, like &lt;code&gt;Bash(npm * test)&lt;/code&gt;, triggers a startup warning.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx&lt;/code&gt; can run any package, so the example allows only the ones you use rather than the whole program. Do not put &lt;code&gt;Bash(npx:*)&lt;/code&gt; in ask: ask is evaluated before allow, so the &lt;code&gt;npx tsc&lt;/code&gt; you just allowed would start prompting too. Leaving it out means "the ones I allowed run silently, any other &lt;code&gt;npx&lt;/code&gt; follows the default behavior."&lt;/p&gt;

&lt;h3&gt;
  
  
  Patterns per package manager
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Running scripts&lt;/th&gt;
&lt;th&gt;Install commands (ask)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(npm run:*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(npm install:*)&lt;/code&gt;, &lt;code&gt;Bash(npm i:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pnpm&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(pnpm run:*)&lt;/code&gt;, &lt;code&gt;Bash(pnpm test)&lt;/code&gt;, &lt;code&gt;Bash(pnpm lint)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(pnpm add:*)&lt;/code&gt;, &lt;code&gt;Bash(pnpm install:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(yarn run:*)&lt;/code&gt;, &lt;code&gt;Bash(yarn test)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(yarn add:*)&lt;/code&gt;, &lt;code&gt;Bash(yarn install)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bun&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(bun run:*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(bun add:*)&lt;/code&gt;, &lt;code&gt;Bash(bun install:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;pnpm and yarn let you drop &lt;code&gt;run&lt;/code&gt;, as in &lt;code&gt;pnpm lint&lt;/code&gt;, so either list the scripts you use or allow the whole program and stop the install commands with ask rules. Because ask is evaluated first, that combination is safe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm:*)"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm add:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm remove:*)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For a Python project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pytest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(python -m pytest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(ruff:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(mypy:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(uv run:*)"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pip install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(uv add:*)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Confirm every git push (ask)
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;ask&lt;/code&gt; rule means "prompt me even if an allow rule matches." Automate the read-only Git commands and commits with allow, put &lt;code&gt;Bash(git push:*)&lt;/code&gt; in ask, and only the push stops.&lt;/p&gt;

&lt;p&gt;The dialog at push time offers these options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Allow once&lt;/td&gt;
&lt;td&gt;Runs this one call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Don't ask again&lt;/td&gt;
&lt;td&gt;Appends an allow rule to &lt;code&gt;settings.local.json&lt;/code&gt;, but you are still prompted next time while the ask rule remains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deny&lt;/td&gt;
&lt;td&gt;Does not run, and lets you tell Claude why&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That "don't ask again" leaves the ask rule in place is intended. It keeps you from undoing "I always review pushes" with one keystroke. To stop the prompts, remove the ask line from the settings file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-allowing one branch only
&lt;/h3&gt;

&lt;p&gt;If pushes to your own working branches should go through, scope both the allow and the ask rule by branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push origin feature/*:*)"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push origin main:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git push origin develop:*)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This depends on Claude spelling the command as &lt;code&gt;git push origin feature/xxx&lt;/code&gt;. A bare &lt;code&gt;git push&lt;/code&gt; matches neither rule and falls through to your &lt;code&gt;defaultMode&lt;/code&gt;. If you value reliability over convenience, skip the branch scoping and keep one "always confirm pushes" rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Block force push (deny)
&lt;/h2&gt;

&lt;p&gt;Deny is evaluated before ask and allow, and it applies in every permission mode, including &lt;code&gt;bypassPermissions&lt;/code&gt;, where allow rules have no effect. A deny in the project's &lt;code&gt;settings.json&lt;/code&gt; cannot be undone by an allow in someone's &lt;code&gt;settings.local.json&lt;/code&gt;, which is why team-wide prohibitions belong here.&lt;/p&gt;

&lt;p&gt;Bash rules match the command text, so each spelling needs its own line:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Pattern that matches it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push --force origin main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(git push --force:*)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push -f origin main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(git push -f:*)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push origin main --force&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(git push * --force:*)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push --force-with-lease&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(git push --force-with-lease:*)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;--force-with-lease&lt;/code&gt; is safer than a bare &lt;code&gt;--force&lt;/code&gt;, but it still overwrites the remote. If your team allows it, move that one line into ask.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A deny rule is a safety net, not a wall&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd repo &amp;amp;&amp;amp; git push --force&lt;/code&gt;, or a push buried in a shell script, does not start with the text your rule matches. For a branch that genuinely must not be rewritten, set branch protection on the remote (GitHub's "do not allow force pushes") and treat the deny rule as a way to reduce local accidents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same approach covers other commands that destroy work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(git reset --hard:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git checkout -- .:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(git clean -f:*)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verify it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Save the settings and restart Claude Code.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;/permissions&lt;/code&gt; and check that each list shows the lines you wrote and the file each came from.&lt;/li&gt;
&lt;li&gt;Say "run the tests." If &lt;code&gt;npm run test&lt;/code&gt; goes without a prompt, allow works.&lt;/li&gt;
&lt;li&gt;Say "add lodash." If &lt;code&gt;npm install lodash&lt;/code&gt; prompts, ask works.&lt;/li&gt;
&lt;li&gt;Say "commit this and push it." The commit should go through and a dialog should appear right before the push.&lt;/li&gt;
&lt;li&gt;Ask Claude to run &lt;code&gt;git push --force origin test-branch&lt;/code&gt;. It should be refused.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Related settings
&lt;/h2&gt;

&lt;p&gt;How &lt;code&gt;settings.json&lt;/code&gt; and &lt;code&gt;settings.local.json&lt;/code&gt; divide the work, how the scopes override each other and how to pick a &lt;code&gt;defaultMode&lt;/code&gt; are covered in the parent article, &lt;a href="https://aicoding-guide.com/en/posts/claude-code-settings-json-permissions/" rel="noopener noreferrer"&gt;Claude Code permissions in settings.json and settings.local.json&lt;/a&gt;. For the file-oriented version of the same mechanism, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-deny-read-env/" rel="noopener noreferrer"&gt;Stop Claude Code reading your .env&lt;/a&gt;. Once scripts run unattended, a hook that lints after every edit keeps quality up: &lt;a href="https://aicoding-guide.com/en/posts/claude-code-hooks-lint-format/" rel="noopener noreferrer"&gt;Run lint and format automatically with Claude Code hooks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Rules are evaluated deny, then ask, then allow, and the first match decides&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Bash(npm run:*)&lt;/code&gt; allows every npm script in one rule; &lt;code&gt;npm install&lt;/code&gt; is a different prefix. When allowing a whole program such as pnpm or npx, stop the install commands with ask&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Bash(git push:*)&lt;/code&gt; in ask forces a prompt right before every push, and "don't ask again" does not remove it&lt;/li&gt;
&lt;li&gt;Deny &lt;code&gt;--force&lt;/code&gt;, &lt;code&gt;-f&lt;/code&gt;, &lt;code&gt;--force-with-lease&lt;/code&gt; and the reordered form separately. Deny applies in every mode and cannot be undone by personal settings&lt;/li&gt;
&lt;li&gt;Pair the deny rules with branch protection on the remote for anything you cannot lose&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claudecode</category>
      <category>permissions</category>
      <category>allow</category>
      <category>ask</category>
    </item>
    <item>
      <title>This week in Claude Code, Codex and Gemini CLI (week of October 11, 2026)</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Sat, 10 Oct 2026 19:13:13 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/this-week-in-claude-code-codex-and-gemini-cli-week-of-october-11-2026-2k6d</link>
      <guid>https://dev.to/aicoding-guide/this-week-in-claude-code-codex-and-gemini-cli-week-of-october-11-2026-2k6d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/weekly-2026-10-11/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The change with the widest reach this week is &lt;strong&gt;Claude Haiku 5.5&lt;/strong&gt;. It is now the default Haiku model on the Anthropic API, with a 1M-token context, and short prompts cost a tenth of what Haiku 4.5 did. On the Codex side, the &lt;strong&gt;default model is now GPT-6.1 Sol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Claude Code also landed several fixes for permission rules that were being skipped. If you lean on the sandbox or on hooks to make permission decisions, this is a week to update early.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
This week's highlights&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Haiku 5.5 is the default Haiku on the API (1M context, $0.10 / $0.50)&lt;/li&gt;
&lt;li&gt;Claude Code fixed Bash deny and ask rules being skipped, and a permission bypass for UNC-path file reads&lt;/li&gt;
&lt;li&gt;Codex's default model is GPT-6.1 Sol, and Daybreak now needs an explicit opt-in&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Claude Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Claude Haiku 5.5 arrives (2.1.293)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;claude-haiku-5-5&lt;/code&gt; was added and is now the default Haiku model on the Anthropic API. The CHANGELOG reads "1M context, $0.10/$0.50 per Mtok ($0.50/$2.50 for prompts over 100K)", and the official pricing page fetched on 2026-10-11 has the same split.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Input (per Mtok)&lt;/th&gt;
&lt;th&gt;Output (per Mtok)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 5.5 (prompts up to 100K)&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 5.5 (prompts over 100K)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$2.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 4.5&lt;/td&gt;
&lt;td&gt;$1&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A tenth of Haiku 4.5 on short prompts — but the rate is 5x higher once you pass 100,000 tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Several permission rules were being skipped (2.1.289, 2.1.292)
&lt;/h3&gt;

&lt;p&gt;A cluster of fixes landed for the category "the thing you thought your settings blocked went through anyway."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the sandbox auto-allows commands, a Bash command with an &lt;strong&gt;environment-variable prefix&lt;/strong&gt; such as &lt;code&gt;TZ="$HOME" rm -rf build&lt;/code&gt; did not match deny or ask rules. The same held for a bare variable assignment before the command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Read&lt;/code&gt; deny rules did not apply to files @-mentioned or selected in the IDE through a symlink&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: PreToolUse hook approvals and auto mode bypassed the permission prompt for file reads from network (UNC) paths&lt;/li&gt;
&lt;li&gt;A notebook or PDF read on macOS and Windows could return a file outside what was approved, through a link swapped in mid-read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Designing deny rules is covered in &lt;a href="https://aicoding-guide.com/en/posts/claude-code-settings-json-permissions/" rel="noopener noreferrer"&gt;Design permissions in Claude Code's settings.json&lt;/a&gt; — though this week is also a run of examples showing that having written the rule is not itself the guarantee.&lt;/p&gt;

&lt;h3&gt;
  
  
  onFailure blocks the action when a hook fails (2.1.295)
&lt;/h3&gt;

&lt;p&gt;Command and HTTP hooks take &lt;code&gt;onFailure: "block"&lt;/code&gt;. A hook that can't start, times out, or exits with an unexpected code now &lt;strong&gt;blocks&lt;/strong&gt; the action instead of letting it through.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PreToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bash .claude/hooks/check.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"onFailure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use hooks as enforcement rather than as a request, a broken hook used to mean the action sailed past. 2.1.294 also fixed &lt;code&gt;prompt&lt;/code&gt; and &lt;code&gt;agent&lt;/code&gt; hooks written as instructions allowing what they should block.&lt;/p&gt;

&lt;h3&gt;
  
  
  New settings around subagents (2.1.290, 2.1.292, 2.1.296)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What was added&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;effort&lt;/code&gt; on the Agent tool&lt;/td&gt;
&lt;td&gt;Runs a subagent at the effort level you ask for&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;autoCompactWindow&lt;/code&gt; in subagent frontmatter&lt;/td&gt;
&lt;td&gt;Lets a subagent auto-compact earlier than the main conversation (also in &lt;code&gt;--agents&lt;/code&gt; definitions)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs every workflow agent on one model while other subagents keep theirs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;allow_large&lt;/code&gt; on the Read tool&lt;/td&gt;
&lt;td&gt;Reads a text file past the usual size limits in one call&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href="https://aicoding-guide.com/en/posts/claude-code-subagents/" rel="noopener noreferrer"&gt;Create subagents in Claude Code&lt;/a&gt; for the rest. &lt;code&gt;CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS&lt;/code&gt; and &lt;code&gt;..._MAX_DELAY_MS&lt;/code&gt; were also added, to lengthen the backoff when retrying an overloaded (529) request.&lt;/p&gt;

&lt;p&gt;2.1.290 additionally fixed WebFetch silently dropping page text past 100,000 characters; it now says how much was unread and takes an &lt;code&gt;offset&lt;/code&gt; to read on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The default model is now GPT-6.1 Sol (0.161.0)
&lt;/h3&gt;

&lt;p&gt;The release notes read "GPT-6.1 Sol is now the default model in the bundled and Amazon Bedrock catalogs." What is stated as default is &lt;strong&gt;the bundled catalog and the Amazon Bedrock catalog&lt;/strong&gt;; other setups are not addressed. &lt;code&gt;/mcp login &amp;lt;name&amp;gt;&lt;/code&gt; also arrived, for signing in to MCP servers from an active terminal session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daybreak needs an explicit opt-in (0.161.0)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;daybreak=true&lt;/code&gt; on its own is not enough. You need &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak=true&lt;/code&gt;. By default the controls and indicators are hidden and &lt;code&gt;/daybreak&lt;/code&gt; is unavailable; saved preferences themselves remain intact. For writing &lt;code&gt;config.toml&lt;/code&gt;, see &lt;a href="https://aicoding-guide.com/en/posts/codex-config-toml/" rel="noopener noreferrer"&gt;What you can configure in Codex's config.toml&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Worktree tools and TUI changes (0.162.0)
&lt;/h3&gt;

&lt;p&gt;With the worktrees feature enabled, there are now &lt;strong&gt;tools for creating and listing managed Git worktrees&lt;/strong&gt; from trusted local projects. &lt;code&gt;apply_patch&lt;/code&gt; preserves existing CRLF line endings without an opt-in. In the TUI, &lt;code&gt;/copy&lt;/code&gt; navigates and copies transcript blocks, and &lt;code&gt;tui.mouse_scroll_speed&lt;/code&gt; tunes mouse-wheel scrolling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sandbox fixes (0.161.0, 0.162.0)
&lt;/h3&gt;

&lt;p&gt;Approved filesystem escalation can now grant broader write access while preserving denied reads and network restrictions, and background tasks retain their originating turn's permissions. 0.162.0 fixed Linux sandbox startup with multiple denied files and stopped &lt;strong&gt;ripgrep configuration from weakening deny-glob masks&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gemini CLI
&lt;/h2&gt;

&lt;p&gt;v0.63.0 is 15 fixes with no new features and no new setting keys. The two that matter: the removal of what caused &lt;code&gt;cannot spawn : No such file or directory&lt;/code&gt; during diffs (Gemini CLI was overriding Git's &lt;code&gt;diff.external&lt;/code&gt; with an empty string), and the fix for a negative &lt;code&gt;tools.truncateToolOutputThreshold&lt;/code&gt; roughly doubling output instead of disabling truncation. Details in &lt;a href="https://aicoding-guide.com/en/posts/gemini-cli-update-0-63/" rel="noopener noreferrer"&gt;Gemini CLI v0.63 changes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check now
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Move Claude Code to 2.1.296 or later — every permission-bypass fix this week is in that range&lt;/li&gt;
&lt;li&gt;If you rely on Bash deny or ask rules under sandbox auto-allow, test a command with an environment-variable prefix and confirm it still stops&lt;/li&gt;
&lt;li&gt;If you use hooks as enforcement, add &lt;code&gt;onFailure: "block"&lt;/code&gt; to them&lt;/li&gt;
&lt;li&gt;Review the model id where you use Haiku and move to &lt;code&gt;claude-haiku-5-5&lt;/code&gt;, noting the 5x rate above 100,000 tokens&lt;/li&gt;
&lt;li&gt;If you were using Daybreak in Codex, switch to &lt;code&gt;--enable cli_daybreak&lt;/code&gt; or &lt;code&gt;features.cli_daybreak=true&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Haiku 5.5 is the default Haiku on the API: 1M context, $0.10 / $0.50 up to 100K tokens&lt;/li&gt;
&lt;li&gt;Claude Code 2.1.289 to 2.1.292 concentrate the fixes for skipped permission rules; the UNC-path read is marked Security&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onFailure: "block"&lt;/code&gt; stops the action when a hook itself fails&lt;/li&gt;
&lt;li&gt;Codex defaults to GPT-6.1 Sol in the bundled and Bedrock catalogs, and Daybreak needs the &lt;code&gt;cli_daybreak&lt;/code&gt; opt-in&lt;/li&gt;
&lt;li&gt;Gemini CLI v0.63.0 is fixes only&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>weeklydigest</category>
      <category>updates</category>
      <category>claudecode</category>
      <category>codex</category>
    </item>
    <item>
      <title>Auto-allow npm scripts in Claude Code without allowing npm install</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Fri, 09 Oct 2026 19:22:46 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/auto-allow-npm-scripts-in-claude-code-without-allowing-npm-install-1od0</link>
      <guid>https://dev.to/aicoding-guide/auto-allow-npm-scripts-in-claude-code-without-allowing-npm-install-1od0</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/claude-code-allow-npm-scripts/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A confirmation dialog on every &lt;code&gt;npm run lint&lt;/code&gt;, &lt;code&gt;npm run test&lt;/code&gt; and &lt;code&gt;npm run build&lt;/code&gt; is the single biggest drag on working with Claude Code. The scripts in your &lt;code&gt;package.json&lt;/code&gt; are commands you wrote yourself, so there is no reason not to allow them as a group.&lt;/p&gt;

&lt;p&gt;In short: put &lt;code&gt;Bash(npm run:*)&lt;/code&gt; in &lt;code&gt;allow&lt;/code&gt; and every npm script stops prompting. &lt;code&gt;npm install&lt;/code&gt; is a different prefix, so it is not swept in by accident.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patterns that allow scripts for npm, pnpm, yarn and npx&lt;/li&gt;
&lt;li&gt;What &lt;code&gt;:*&lt;/code&gt; means, and how to keep install commands out of the rule&lt;/li&gt;
&lt;li&gt;The equivalent for Python projects (pytest, ruff)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The setting
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm run:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm test)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx tsc:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx vitest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx eslint:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npx prettier:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm i:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(npm uninstall:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx&lt;/code&gt; can run any package, so this allows only the ones you use rather than the whole program. Note that &lt;code&gt;npx&lt;/code&gt; is deliberately &lt;em&gt;not&lt;/em&gt; in &lt;code&gt;ask&lt;/code&gt;: an ask rule prompts even when a more specific allow rule also matches, so &lt;code&gt;Bash(npx:*)&lt;/code&gt; in &lt;code&gt;ask&lt;/code&gt; would start prompting for the &lt;code&gt;npx tsc&lt;/code&gt; you just allowed. Leaving it out means "the ones I allowed run silently, any other &lt;code&gt;npx&lt;/code&gt; follows the default behavior" — a prompt in Manual mode.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;What &lt;code&gt;:*&lt;/code&gt; means&lt;/strong&gt;: &lt;code&gt;Bash(npm run:*)&lt;/code&gt; is a prefix match — "starts with &lt;code&gt;npm run&lt;/code&gt;, anything may follow." It matches arguments too, such as &lt;code&gt;npm run test -- --watch&lt;/code&gt;. Put the &lt;code&gt;*&lt;/code&gt; after the subcommand; a rule with a &lt;code&gt;*&lt;/code&gt; before it, like &lt;code&gt;Bash(npm * test)&lt;/code&gt;, triggers a startup warning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Patterns per package manager
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Running scripts&lt;/th&gt;
&lt;th&gt;Install commands (ask)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(npm run:*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(npm install:*)&lt;/code&gt;, &lt;code&gt;Bash(npm i:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pnpm&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(pnpm run:*)&lt;/code&gt;, &lt;code&gt;Bash(pnpm test)&lt;/code&gt;, &lt;code&gt;Bash(pnpm lint)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(pnpm add:*)&lt;/code&gt;, &lt;code&gt;Bash(pnpm install:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(yarn run:*)&lt;/code&gt;, &lt;code&gt;Bash(yarn test)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(yarn add:*)&lt;/code&gt;, &lt;code&gt;Bash(yarn install)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bun&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bash(bun run:*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bash(bun add:*)&lt;/code&gt;, &lt;code&gt;Bash(bun install:*)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;pnpm and yarn let you drop &lt;code&gt;run&lt;/code&gt;, as in &lt;code&gt;pnpm lint&lt;/code&gt;, so either list the scripts you use individually or allow the whole program and stop the install commands with ask rules. Because ask is evaluated before allow, that combination is safe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm:*)"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm add:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pnpm remove:*)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  For a Python project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pytest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(python -m pytest:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(ruff:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(mypy:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(uv run:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(pip install:*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(uv add:*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verify it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Save the setting and restart Claude Code.&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;/permissions&lt;/code&gt; and check the allow list.&lt;/li&gt;
&lt;li&gt;Say "run the tests." If &lt;code&gt;npm run test&lt;/code&gt; goes without a prompt, it works.&lt;/li&gt;
&lt;li&gt;Say "add lodash." If &lt;code&gt;npm install lodash&lt;/code&gt; prompts, the ask rules work too.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Related settings
&lt;/h2&gt;

&lt;p&gt;Once the scripts run unattended, a hook that always lints after an edit keeps quality up as you widen the automation — see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-hooks-lint-format/" rel="noopener noreferrer"&gt;Run lint and format on save with Claude Code hooks&lt;/a&gt;. For the overall design, see the parent article, &lt;a href="https://aicoding-guide.com/en/posts/claude-code-settings-json-permissions/" rel="noopener noreferrer"&gt;Design permissions in Claude Code's settings.json&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Bash(npm run:*)&lt;/code&gt; allows every npm script in one rule, and &lt;code&gt;npm install&lt;/code&gt; is a different prefix so it stays out&lt;/li&gt;
&lt;li&gt;When allowing a whole program such as &lt;code&gt;pnpm&lt;/code&gt; or &lt;code&gt;npx&lt;/code&gt;, stop the install commands with ask rules — ask is evaluated before allow&lt;/li&gt;
&lt;li&gt;For Python, allow &lt;code&gt;pytest&lt;/code&gt;, &lt;code&gt;ruff&lt;/code&gt; and &lt;code&gt;uv run&lt;/code&gt;, and put &lt;code&gt;pip install&lt;/code&gt; in ask&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claudecode</category>
      <category>permissions</category>
      <category>npm</category>
      <category>pnpm</category>
    </item>
    <item>
      <title>Make a coding agent write the failing test before the implementation</title>
      <dc:creator>aicoding-guide</dc:creator>
      <pubDate>Fri, 09 Oct 2026 19:22:45 +0000</pubDate>
      <link>https://dev.to/aicoding-guide/make-a-coding-agent-write-the-failing-test-before-the-implementation-57c1</link>
      <guid>https://dev.to/aicoding-guide/make-a-coding-agent-write-the-failing-test-before-the-implementation-57c1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aicoding-guide.com/en/posts/ai-coding-test-first-workflow/" rel="noopener noreferrer"&gt;https://aicoding-guide.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ask a coding agent to "implement this feature" and the implementation arrives fast, but the verification often ends at "it should work." The most effective fix is to &lt;strong&gt;make it write a failing test first, confirm the failure, and only then implement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An agent with a concrete goal — "make this test pass" — can iterate on its own. This article covers the prompts that work across all three tools, and the tool-specific ways to enforce the rule rather than request it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;&lt;br&gt;
What you will learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The four steps of the workflow and the prompt for each&lt;/li&gt;
&lt;li&gt;What to put in your context file (CLAUDE.md / AGENTS.md / GEMINI.md)&lt;/li&gt;
&lt;li&gt;How to stop the agent from editing the tests, and what to do when it goes wrong&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The four steps
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;th&gt;What to tell the agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Write the test&lt;/td&gt;
&lt;td&gt;A failing test derived from the spec&lt;/td&gt;
&lt;td&gt;Say "don't write the implementation yet"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Confirm the failure&lt;/td&gt;
&lt;td&gt;Run it and see it fail&lt;/td&gt;
&lt;td&gt;Have it confirm the failure is "not implemented"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Implement&lt;/td&gt;
&lt;td&gt;Change the implementation until the test passes&lt;/td&gt;
&lt;td&gt;Say "don't change the test"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Tidy up&lt;/td&gt;
&lt;td&gt;Remove duplication, improve names, add cases&lt;/td&gt;
&lt;td&gt;Have it confirm tests still pass afterwards&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important part is that steps 1 and 3 are &lt;strong&gt;separate instructions&lt;/strong&gt;. Roll them into one ("write tests and implement it") and the agent tends to write the implementation first and back-fill a test that fits it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: tests only
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I want a calculateTotal function in `src/lib/pricing.ts` that returns the discounted
total from a quantity and a unit price.
Spec:
- 5% off at 10 or more, 10% off at 100 or more
- Throw if the quantity is 0 or less
- Round fractions down

First, write only the tests for this spec in `src/lib/pricing.test.ts`.
Do not write the implementation yet. Once the tests are written, run
`pnpm test pricing`, confirm they all fail because the function does not exist,
and report back.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Steps 2–3: implement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement calculateTotal so every test in pricing.test.ts passes.
Do not modify the test file. If you think a test is wrong, report why
without changing it.
Run `pnpm test pricing` afterwards and paste the result.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: tidy up
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the implementation and the tests, and clean up duplication or unclear names.
Add boundary cases if any are missing (9, 10, 99, 100).
Finally run `pnpm test pricing` and `pnpm lint` and report the results.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Boundary cases&lt;/strong&gt;: tests at the points where the spec changes behavior (10, 100) and just either side of them (9, 11). Agents tend to test "representative" values only, so asking for boundaries explicitly pays off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Put it in the context file
&lt;/h2&gt;

&lt;p&gt;If repeating the instructions gets tiring, write the workflow into your context file. The same text works for all three tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## How to implement (test first)&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; For a new feature or a fix, write a failing test first and run it to confirm the failure
&lt;span class="p"&gt;2.&lt;/span&gt; Implement until the test passes. Do not change the test file while implementing
&lt;span class="p"&gt;3.&lt;/span&gt; If you judge a test to be wrong, report why without changing it and wait for instructions
&lt;span class="p"&gt;4.&lt;/span&gt; Include the test command you ran and its result (passed / failed counts) in your report
&lt;span class="p"&gt;5.&lt;/span&gt; If there is no test setup, propose setting one up first
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For keeping one copy of that text across the three files, see &lt;a href="https://aicoding-guide.com/en/posts/context-files-comparison/" rel="noopener noreferrer"&gt;CLAUDE.md, AGENTS.md and GEMINI.md differ only in how they load&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code: enforce it with a hook
&lt;/h2&gt;

&lt;p&gt;In Claude Code you can make this a mechanism rather than a request. The documentation is explicit that a context file is "context, not enforced configuration" and points at a &lt;code&gt;PreToolUse&lt;/code&gt; hook to block an action regardless of what Claude decides.&lt;/p&gt;

&lt;p&gt;A hook that blocks edits to test files during the implementation phase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# .claude/hooks/protect-tests.sh&lt;/span&gt;
&lt;span class="c"&gt;# Only blocks test-file edits when PROTECT_TESTS=1&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PROTECT_TESTS&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;0&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.tool_input.file_path // empty'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;*&lt;/span&gt;.test.&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;.spec.&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;/__tests__/&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Test files can't be changed during the implementation phase: &lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;. If a test is wrong, report why."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;exit &lt;/span&gt;2 &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;
&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PreToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Edit|Write|NotebookEdit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bash .claude/hooks/protect-tests.sh"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit code 2 on &lt;code&gt;PreToolUse&lt;/code&gt; blocks the tool call, so starting with &lt;code&gt;PROTECT_TESTS=1 claude&lt;/code&gt; makes tampering with the tests physically impossible rather than merely discouraged. For hook basics, see &lt;a href="https://aicoding-guide.com/en/posts/claude-code-hooks-lint-format/" rel="noopener noreferrer"&gt;Run lint and format on save with Claude Code hooks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix the procedure in a skill&lt;/strong&gt;: writing the four steps into a &lt;code&gt;/tdd &amp;lt;spec&amp;gt;&lt;/code&gt; slash command keeps every run on the same track (&lt;a href="https://aicoding-guide.com/en/posts/claude-code-custom-slash-commands/" rel="noopener noreferrer"&gt;Create your own slash commands&lt;/a&gt;). Delegating the test run to a &lt;a href="https://aicoding-guide.com/en/posts/claude-code-subagents/" rel="noopener noreferrer"&gt;subagent&lt;/a&gt; keeps long test output out of your main context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex and Gemini CLI
&lt;/h2&gt;

&lt;p&gt;Neither has an equivalent of hooks, so you run this on instructions plus inspection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Codex&lt;/strong&gt;: keep the implementation phase on &lt;code&gt;--sandbox workspace-write&lt;/code&gt;, and check with &lt;code&gt;/diff&lt;/code&gt; that the test files are unchanged before you approve. Put the workflow in &lt;code&gt;AGENTS.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini CLI&lt;/strong&gt;: turn checkpointing on, and if a test file was modified, roll back with &lt;code&gt;/restore&lt;/code&gt;. Put the workflow in &lt;code&gt;GEMINI.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When it goes wrong
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;It writes the implementation during the test step&lt;/td&gt;
&lt;td&gt;Repeat "don't write the implementation yet" at the end of the prompt too. In Claude Code, use plan mode to get a plan only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;It loosens the test when it won't pass&lt;/td&gt;
&lt;td&gt;State "don't change the test" and block it with a hook&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The tests are all mocks and prove nothing&lt;/td&gt;
&lt;td&gt;Say "mock external dependencies if you must, but never mock the logic of the function under test"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The test run takes too long&lt;/td&gt;
&lt;td&gt;Put a narrowing command in the prompt (&lt;code&gt;pnpm test pricing&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make "write the test" and "implement" separate instructions, with a confirmed failure in between&lt;/li&gt;
&lt;li&gt;State "don't change the test file" and "include test results in your report" every time, or put them in your context file&lt;/li&gt;
&lt;li&gt;Claude Code can block test-file edits with a &lt;code&gt;PreToolUse&lt;/code&gt; hook and fix the procedure in a skill&lt;/li&gt;
&lt;li&gt;With Codex and Gemini CLI, use &lt;code&gt;/diff&lt;/code&gt; or checkpointing to check the tests weren't tampered with&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testdriven</category>
      <category>workflow</category>
      <category>claudecode</category>
      <category>codex</category>
    </item>
  </channel>
</rss>
