{"schemaVersion":"1.0","publication":{"slug":"pivot-claude-code","name":"Claude Code Review","description":"Workflows, releases, and field notes for Anthropic's coding agent.","audience":"Developers and teams adopting Claude Code.","geography":null},"edition":{"id":"889c44f5-a065-4e45-906f-92dd8a56015d","date":"2026-10-28","status":"locked","createdAt":"2026-10-27T16:33:14.306Z","storyCount":6,"newsletterSubject":"Self-hosted runners stay reserved longer, CLI adds Tasks and Elicitations, Scripts answer multiple choice prompts"},"updatedAt":"2026-10-27T16:31:21.326Z","stories":[{"id":"2589f703-30fc-4ffd-871c-eeeeeadbc8d2","title":"Self-hosted Claude Code runners can stay reserved until background work finishes","dek":"Two flags added in Claude Code's 2.1.311 release, --hold-idle-file and --max-hold-min, let a self-hosted runner, the computer you supply to run jobs instead of Anthropic's cloud, wait before freeing its slot when a session's background processes are still running.","bodyMd":"Claude Code's 2.1.311 release added two flags to the self-hosted-runner command: `--hold-idle-file` and `--max-hold-min`. Together they stop a runner from reclaiming a slot the instant Claude's own turn ends, if the session left something still running on the host. The changelog entry for 2.1.311 carries an October 21 date, but that date sits awkwardly against the rest of the evidence: the agent SDK's parity release for 2.1.311 wasn't published until October 26, and the intervening versions 2.1.308 and 2.1.309 both carry a later date, October 22, despite being lower version numbers. The exact ship date for 2.1.311 is unclear from the record Anthropic has published so far.\n\nThe problem they fix is specific to self-hosted runners, the machines a team supplies to run Claude Code jobs instead of using Anthropic's own cloud infrastructure. A session can finish its work and go idle while a dev server, a long test suite, or some other background process it kicked off keeps going. Without a way to signal that, a runner would free the slot anyway, leaving that process orphaned or killed outright.\n\nThe fix is a hold mechanism. Point `--hold-idle-file` at a file your host updates while it still needs the session; as long as that file keeps changing, Claude Code leaves the slot alone. `--max-hold-min` sets an upper bound on the wait, so a process that never finishes, or a host that stops updating the file, doesn't tie up a runner slot forever.\n\nThe flags land in a run of releases, 2.1.305 through 2.1.311, that also tightened sandbox behavior. Version 2.1.309 fixed sandboxed Bash commands on macOS and Linux that had been running the shell's startup files outside the sandbox before each command, and closed a symlink trick that let a sandboxed command bypass a macOS `denyWrite` rule by reaching the real path through a linked folder. The same version stopped sandboxed commands and auto-accepted edits from modifying the MCP config file passed in with `--mcp-config`.\n\nElsewhere in the run, 2.1.307 added `/claude-api api-version`, which moves a project's Claude API calls to a named API version, 2026-10-21 in this case, instead of letting them drift onto whatever version ships next. A summary of the 2.1.310 changelog also describes a Monitor tool for plugin monitors added across Bedrock, Vertex, and Foundry, though Anthropic's own release notes for that version were not supplied to confirm the description directly.\n\nThe idle-hold flags only apply to self-hosted-runner sessions, not jobs run on Anthropic's own cloud infrastructure, so teams running Claude Code entirely through Anthropic's hosted service won't see them.","status":"published","storyType":"news","category":"Release","clusterKey":"claude-code-2-1-3xx-releases","slug":"self-hosted-claude-code-runners-can-stay-reserved-until-background-work-2589f7","url":"https://claudecodereview.ai/a/self-hosted-claude-code-runners-can-stay-reserved-until-background-work-2589f7/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/2589f703-30fc-4ffd-871c-eeeeeadbc8d2","role":"lead","position":0,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/self-hosted-claude-code-runners-can-stay-reserved-until-background-work-2589f7/aa7b495fb948a61d-57d264137cbd9225/web_hero.webp","imageAlt":"A row of seven slots with one slot at the end held open by a mechanical latch to prevent it from closing.","createdAt":"2026-10-27T16:09:43.614Z","updatedAt":"2026-10-27T16:31:21.326Z","sources":[{"role":"primary","title":"2.1.311","url":"https://code.claude.com/docs/en/changelog#2-1-311","sourceName":"Claude Code changelog","author":"Claude Code changelog","publishedAt":"2026-10-26T22:02:28Z"},{"role":"supporting","title":"Claude Code 2.1.311 adds idle holds for self-hosted runners and fixes background-agent handling - OpenTools","url":"https://opentools.ai/news/claude-code-2-1-311-self-hosted-idle-holds-background-mcp-lifecycle","sourceName":"\"when:7d \"Claude Code\" Anthropic\" - Google News","author":"\"when:7d \"Claude Code\" Anthropic\" - Google News","publishedAt":"2026-10-27T11:00:28Z"},{"role":"supporting","title":"Claude Agent SDK for TypeScript v0.3.311","url":"https://github.com/anthropics/claude-agent-sdk-typescript/releases/tag/v0.3.311","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-26T21:51:29Z"},{"role":"supporting","title":"Claude Code 2.1.310 adds a Monitor tool (per changelog summary)","url":"https://x.com/ekcheungai/status/2114360380080136318","sourceName":"EK","author":"EK","publishedAt":"2026-10-25T14:16:12Z"},{"role":"supporting","title":"Claude Code v2.1.309","url":"https://github.com/anthropics/claude-code/releases/tag/v2.1.309","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-22T22:18:57Z"},{"role":"supporting","title":"Claude Agent SDK for TypeScript v0.3.309","url":"https://github.com/anthropics/claude-agent-sdk-typescript/releases/tag/v0.3.309","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-22T22:18:33Z"},{"role":"supporting","title":"Claude Code v2.1.308","url":"https://github.com/anthropics/claude-code/releases/tag/v2.1.308","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-22T04:34:55Z"},{"role":"supporting","title":"Claude Agent SDK for TypeScript v0.3.307","url":"https://github.com/anthropics/claude-agent-sdk-typescript/releases/tag/v0.3.307","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-21T22:17:12Z"},{"role":"supporting","title":"Claude Code v2.1.307","url":"https://github.com/anthropics/claude-code/releases/tag/v2.1.307","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-21T22:17:02Z"},{"role":"supporting","title":"Claude Code v2.1.306","url":"https://github.com/anthropics/claude-code/releases/tag/v2.1.306","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-21T03:16:31Z"},{"role":"supporting","title":"Claude Code v2.1.305","url":"https://github.com/anthropics/claude-code/releases/tag/v2.1.305","sourceName":"Anthropic","author":"Anthropic","publishedAt":"2026-10-20T20:46:50Z"}]},{"id":"4a86b09d-a21d-42b8-84f6-a9a13ae0e779","title":"Claude Code CLI adds Tasks and Elicitations for MCP server plugins","dek":"Anthropic says the two capabilities are live in the Claude Code CLI as of October 23 and rolling out to more Claude products soon; documentation titles suggest Tasks lets a server hand back a long-running job without blocking and Elicitations lets it pause to ask for a missing detail, though the announcement does not confirm this behavior.","bodyMd":"Anthropic shipped two additions to the Model Context Protocol (MCP) inside the Claude Code CLI on October 23: Tasks and Elicitations, according to a post from ClaudeDevs, the company's developer account for Claude Code. Anthropic says both capabilities are rolling out to more of its Claude products soon, without naming which ones or when.\n\nThe post does not explain what either feature does. Anthropic links to two specific sections of its MCP documentation: one titled \"MCP tasks for server authors,\" and another titled \"Respond to MCP elicitation requests.\" Those titles suggest Tasks may let a server hand back a long-running job without blocking the session, and Elicitations may let a server pause a tool call to ask for a missing detail, but the announcement itself does not confirm this behavior.\n\nFor plugin builders, Anthropic points server authors to its MCP documentation at code.claude.com/docs/en/mcp, under sections named for task authoring and elicitation requests, without detailing the underlying behavior in the announcement itself.","status":"published","storyType":"news","category":"Release","clusterKey":"tasks-and-elicitations-cli","slug":"claude-code-cli-adds-tasks-and-elicitations-for-mcp-server-plugins-4a86b0","url":"https://claudecodereview.ai/a/claude-code-cli-adds-tasks-and-elicitations-for-mcp-server-plugins-4a86b0/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/4a86b09d-a21d-42b8-84f6-a9a13ae0e779","role":"item","position":1,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/claude-code-cli-adds-tasks-and-elicitations-for-mcp-server-plugins-4a86b0/f1f978d8f7a6f078-70090ccaf9b6f6e8/web_hero.webp","imageAlt":"A diagram shows a single line splitting into two separate paths, with one branch ending in an open line and the other ending in a hook shape.","createdAt":"2026-10-27T15:49:14.630Z","updatedAt":"2026-10-27T16:01:11.024Z","sources":[{"role":"primary","title":"Tasks and Elicitations are available today in the Claude Code CLI, rolling out to more Claude products soon. Building pl","url":"https://x.com/ClaudeDevs/status/2113698007892070527","sourceName":"@ClaudeDevs","author":"ClaudeDevs","publishedAt":"2026-10-23T18:24:10Z"}]},{"id":"5129e0e9-f938-4d45-a05a-ca923526628d","title":"Let a script answer Claude Code's multiple-choice questions while you're away","dek":"A hook is a small script that runs automatically when something happens in Claude Code, and a PermissionRequest hook can pick the answer to a question Claude Code asks mid-run, so a session you aren't watching keeps going instead of waiting at the terminal.","bodyMd":"When Claude Code needs a decision, it uses the AskUserQuestion tool to show a multiple-choice prompt (\"Which framework?\", \"Keep the old API or replace it?\"). If you are away from the terminal, the run stops there.\n\nA hook is a small script you set up that runs automatically when something happens in Claude Code, such as it asking you a question. A PermissionRequest hook can answer this prompt for you in an interactive session, so you don't have to be there to click. The hooks docs already describe the same trick for `-p` mode through a PreToolUse hook. The interactive-session version was tested on Claude Code 2.1.283.\n\n**What the hook receives.** On stdin, the hook gets JSON with `hook_event_name` set to `PermissionRequest`, `tool_name` set to `AskUserQuestion`, and a `tool_input` holding a `questions` array. Each question has its text, a `header`, a list of `options` (each with a `label` and `description`) and a `multiSelect` flag.\n\n**What it must return.**\n\n1. Copy `tool_input`.\n2. Add an `answers` object that maps each question's text to the chosen option label. For multi-select questions, separate labels with commas.\n3. Return it as `updatedInput` with `behavior: \"allow\"`:\n\n```json\n{\n  \"hookSpecificOutput\": {\n    \"hookEventName\": \"PermissionRequest\",\n    \"decision\": {\n      \"behavior\": \"allow\",\n      \"updatedInput\": {\n        \"questions\": [ ...same as input... ],\n        \"answers\": { \"Which color do you want?\": \"Blue\" }\n      }\n    }\n  }\n}\n```\n\nClaude Code then prints \"User answered Claude's questions\", notes \"Allowed by PermissionRequest hook\", and continues with \"Blue\". No terminal prompt appears.\n\n**A minimal test hook.** This shell script answers every question with its last option and is meant for testing only:\n\n```sh\n#!/bin/sh\npython3 -c '\nimport json, sys\nd = json.load(sys.stdin)\nif d.get(\"tool_name\") != \"AskUserQuestion\": sys.exit(0)\nti = d[\"tool_input\"]\nti[\"answers\"] = {q[\"question\"]: q[\"options\"][-1][\"label\"] for q in ti.get(\"questions\", [])}\nprint(json.dumps({\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"behavior\": \"allow\", \"updatedInput\": ti}}}))\n'\n```\n\nRegister it under `hooks.PermissionRequest` in a settings file, then start a session with `claude --settings test-settings.json`. For any other tool the script exits without a decision, so the normal permission prompt still shows.\n\n**When to use it.** Reach for it when you are away from the terminal, since the session otherwise waits for an answer. The same pattern lets a hook forward the question elsewhere, such as a phone. Lidnight, a menu bar app that keeps a Mac awake while Claude Code and Codex work, does this in version 1.7.79: the options appear on an end-to-end encrypted phone status page and in the menu bar, and the tapped choice goes back through the hook. Answering in the terminal still works, and whichever answer comes first wins.\n\n**Two limits.** Returning `allow` alone does not answer the question: the question stays open and the session keeps waiting, even if an approval app reports \"allowed\". And the hook blocks until it returns, so a hook that waits for a remote answer has to give up before the hook timeout so the terminal prompt still works.","status":"published","storyType":"tip","category":"Workflow","clusterKey":"permissionrequest-hook-auto-answer-questions","slug":"let-a-script-answer-claude-code-s-multiple-choice-questions-while-you-re-5129e0","url":"https://claudecodereview.ai/a/let-a-script-answer-claude-code-s-multiple-choice-questions-while-you-re-5129e0/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/5129e0e9-f938-4d45-a05a-ca923526628d","role":"item","position":2,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/let-a-script-answer-claude-code-s-multiple-choice-questions-while-you-re-5129e0/6c3da40532a7f34f-5616b56093fe06b6/web_hero.webp","imageAlt":"A diagram showing four branching paths, where three end in smaller blocks and one funnels into a single, larger block at the end.","createdAt":"2026-10-22T00:08:20.647Z","updatedAt":"2026-10-22T01:01:42.256Z","sources":[{"role":"primary","title":"Answer Claude Code's Questions Automatically From Hooks or Your Phone","url":"https://dev.to/dawonlee/you-can-answer-claude-codes-askuserquestion-from-a-hook-and-from-your-phone-1ddn","sourceName":"Dawon Lee","author":"Dawon Lee","publishedAt":"2026-10-21T11:26:55Z"}]},{"id":"1b821132-4d74-4b9e-9645-09582b011ae7","title":"Test a rule that blocks risky commands against your own session history before trusting it","dek":"Claude Code saves every shell command it has run, so you can replay them through a rule that stops it pushing code changes straight into your project's main, live version (what \"pushing to main\" means), without running anything, and see which commands it would wrongly allow or stop. The title's \"rule\" is a small safety check that automatically stops Claude Code from running certain commands, and you can test it on past commands first.","bodyMd":"Claude Code keeps each session's history on your machine, and every Bash call in it records the exact command and the folder it ran in. That history is a ready-made test set for a PreToolUse hook (a script that checks each command before Claude runs it and can refuse it). Replay the old commands through the script's decision logic, with nothing executed, and you see what it would have allowed or blocked.\n\nThe developer of rules-guard, a Claude Code plugin that blocks direct pushes to protected branches, describes the problem. A first version of the hook looked for the word \"staging\" near a push and blocked the command. Counting afterward showed it had blocked 33 commands, and 27 of them should have gone through. Most were `gh pr create --base staging`, the very move the agent was supposed to make instead of pushing. Unit tests only covered cases the developer had already thought of. The history covered the rest.\n\n**How to run the replay**\n\n1. Extract every tool call the guard sees: command, working directory and tool name.\n2. Run the guard's decision function on each one, with anything that touches the machine stubbed out.\n3. Save the decision and the rule that fired for each call.\n4. Diff against the last run. Every changed line is either a bug or a decision you meant to make.\n\nThe developer's replay over 10,851 real commands found 15 that should be blocked (direct pushes to a protected branch and plain force pushes). The rewritten guard blocked all 15 and nothing else: zero missed blocks, zero wrong blocks.\n\n**When to rerun it**\n\nRerun after every new rule, refactor or message tweak, since any of them can change a decision you did not mean to touch. After rewriting all the block messages, the developer's replay over 11,628 calls showed the wording changed on every block and no allow or block decision changed.\n\n**Write the block message for the agent**\n\nIn the first version the reason printed to stdout, so the agent saw only \"No stderr output\" and had nothing to act on. The rewritten messages share one shape: a first line naming the tool, rule and category, then Problem, Where and Fix lines, with an optional \"Ask the user\" line. The categories are fix-and-retry, use-instead, env-setup and held (stop and ask the user). The developer says that since the switch the agent follows the Fix line, and a blocked push turns into a branch and a pull request.\n\n**Try rules-guard**\n\nIt is MIT licensed and has no network calls:\n\n`/plugin marketplace add AbdAlrahmanAlQaroot/claude-code-mods`\n\n`/plugin install rules-guard@claude-code-mods`\n\nProtected-branch pushes, plain force pushes and production kubectl/AWS calls are blocked by default. The stricter personal rules (AI attribution lines, PR description format, new code comments, test files in commits) are optional and off by default.\n\nKeep the rule in your instructions file too: it explains the reason and shapes what the agent tries first. The hook enforces it when a long session makes pushing look helpful.","status":"published","storyType":"tip","category":"Workflow","clusterKey":"replay-session-commands-against-guard-rule","slug":"test-a-rule-that-blocks-risky-commands-against-your-own-session-history-1b8211","url":"https://claudecodereview.ai/a/test-a-rule-that-blocks-risky-commands-against-your-own-session-history-1b8211/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/1b821132-4d74-4b9e-9645-09582b011ae7","role":"item","position":3,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/test-a-rule-that-blocks-risky-commands-against-your-own-session-history-1b8211/3949f54abd6c172e-d269974a42fce35c/web_hero.webp","imageAlt":"A wide set of over 11,000 bars funneling into one path, with 15 specific bars highlighted in clay-orange to represent blocked commands.","createdAt":"2026-10-22T00:12:41.199Z","updatedAt":"2026-10-22T01:01:21.310Z","sources":[{"role":"primary","title":"Test AI Agent Guardrails by Replaying Thousands of Real Commands","url":"https://dev.to/abd_alrahmanqaroot_9c569/replay-your-history-before-you-trust-an-agent-guardrail-1fb6","sourceName":"Abd Alrahman Qaroot","author":"Abd Alrahman Qaroot","publishedAt":"2026-10-21T09:30:20Z"}]},{"id":"46361140-13f0-4004-ab18-21a1d6ccd38b","title":"Swap slogans for specific lines in CLAUDE.md so Claude has less to guess","dek":"Vague rules like \"keep everything clean\" give the agent nothing to act on, and since Claude keeps loading the file while it works on your project, the fix is short, concrete instructions.","bodyMd":"Instructions such as \"write high-quality code,\" \"follow best practices,\" \"make the UI beautiful\" or \"keep everything clean\" sound reasonable but tell Claude nothing it can act on. The same goes for \"make the landing page premium.\" Rewrite each one into something Claude can follow: \"use large product imagery, generous spacing, and restrained controls on storefront pages.\"\n\n**Rewrite vague lines as specifics**\n\nThe wording matters. The more specific the line, the less Claude has to guess. Swaps worth making in your CLAUDE.md or AGENTS.md:\n\n- Instead of \"format the code properly,\" write \"use two space indentation.\"\n- Instead of \"test your work,\" write \"run `pnpm test` before finishing the task.\"\n- Instead of \"keep the API code organized,\" write \"API handlers live in source API handlers.\"\n\n**Keep the file short**\n\nEvery line in CLAUDE.md or AGENTS.md draws on an attention budget. Claude keeps loading the file while it works, and as more information enters the context window, more things compete for its attention. Don't put something there because Claude might need it one day. Put in what Claude should know every time it works on the project.\n\nThat rules out pasting your whole project structure or large API documentation into the file. The common guidance is to stay well under 200 lines, but 200 is not a target: if everything useful fits in 30 or 40 lines, that is better.","status":"published","storyType":"tip","category":"Workflow","clusterKey":"claude-md-instruction-adherence","slug":"swap-slogans-for-specific-lines-in-claude-md-so-claude-has-less-to-guess-463611","url":"https://claudecodereview.ai/a/swap-slogans-for-specific-lines-in-claude-md-so-claude-has-less-to-guess-463611/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/46361140-13f0-4004-ab18-21a1d6ccd38b","role":"item","position":4,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/swap-slogans-for-specific-lines-in-claude-md-so-claude-has-less-to-guess-463611/e60abf334c1f5283-7d88f5fb5cc190b9/web_hero.webp","imageAlt":"A tall stack of papers being condensed into a smaller, more focused pile of sheets to represent replacing vague instructions with specific, actionable lines.","createdAt":"2026-10-26T17:42:34.180Z","updatedAt":"2026-10-27T13:34:31.022Z","sources":[{"role":"primary","title":"Claude Code 101: Why Claude Ignores Your Instructions","url":"https://www.youtube.com/watch?v=Ef0HP55XXiM","sourceName":"JavaScript Mastery","author":"JavaScript Mastery","publishedAt":"2026-10-26T10:52:52Z"},{"role":"supporting","title":"Claude Code 101: You’re Using CLAUDE.md WRONG! 🚨","url":"https://www.youtube.com/watch?v=u83xtdl0q-M","sourceName":"JavaScript Mastery","author":"JavaScript Mastery","publishedAt":"2026-10-23T10:41:20Z"}]},{"id":"87db736e-3da3-4393-b881-f9836195970e","title":"Turn a vague \"make it more fun\" into an overnight Ultracode run","dek":"Battle Drones, a browser real-time strategy game (you build bases and command units live, not in turns), was built over 12 iterations and 321 agent commits, and its write-up shows Ultracode runs alongside long, specific and time-boxed prompts.","bodyMd":"Battle Drones is a Command & Conquer style real-time strategy game, where players build bases and command units live rather than in turns, and it runs in a mobile or desktop browser. It came out of 12 major iterations and 321 commits by coding agents, mainly Claude Code. Its write-up was published 2026-10-20 and links the key prompts and transcripts for each version.\n\nUltracode is the mode in Claude Code (here, Claude Code for Web) that runs dynamic workflows. The docs describe one as \"A dynamic workflow is a JavaScript script that orchestrates many subagents at once.\" The project's v4 used it with Claude Opus 5.5 and a prompt typed on a phone: \"This game isn't fun enough yet. Make it a LOT more fun.\" The run started in the evening and returned a playable build late the next morning.\n\nPart of that time went to testing. According to the write-up, the agent ran more than a thousand simulated playtest sessions and used the results to rebalance units, add new ones and introduce features. Its own release notes cite 1,200 AI-vs-AI matches on Normal: games still undecided after 25 minutes fell from 14% to 0.9%, and wins by a side that had been 800+ scrap behind rose from 24% to 46%. Earlier versions looked like a game but were not fun to play.\n\nA second overnight run ported the game to three.js with 3D models of every building, vehicle and landscape. Claude constructed the models entirely in TypeScript code. Opus also wrote the soundtrack in code: the project contains no audio files, and the music gets more intense as fighting breaks out.\n\nThe write-up also shows other prompt styles. For the Archipelago map, the author's longest prompt set out the strategic incentive: island uplinks reachable only by infantry flown in on a Condor aircraft. It told the agent to research and critique the design first, and to build only after the changes were agreed. The resulting tropical map has seven island uplinks. A brainstorm-first conversation produced the Goliath mech. A time-boxed prompt (\"You have 45 minutes to build this!\") produced the random map generator, picked to use the 25% of a weekly allowance left before a reset.\n\nMultiplayer was built from a single starting prompt. Pointing Claude Code at an earlier audio-pong experiment and asking for a Battle Drones version led Opus to build a Radio Probe tool to measure bandwidth between two devices, then a full audio modem system. When the high-pitched sound caused headaches, a prompt for a stateless WebSockets relay on Fly.io produced online multiplayer. The author estimates it costs no more than $2.19 a month on a single shared-cpu-1x instance.\n\nThe write-up notes that replay and multiplayer benefit from a deterministic simulation engine, one that produces identical results on every device. In this project, Claude had to swap in custom versions of Math.sin() and Math.cos() because Chrome and Safari returned slightly different numbers, which desynchronized replays. The write-up also says Ultracode \"burns tokens like there's no tomorrow\", though it can also solve complex problems from a single prompt.","status":"published","storyType":"news","category":"Workflow","clusterKey":"battle-drones-rts-built-with-claude-code","slug":"turn-a-vague-make-it-more-fun-into-an-overnight-ultracode-run-87db73","url":"https://claudecodereview.ai/a/turn-a-vague-make-it-more-fun-into-an-overnight-ultracode-run-87db73/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/87db736e-3da3-4393-b881-f9836195970e","role":"item","position":5,"imageStatus":"ready","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/turn-a-vague-make-it-more-fun-into-an-overnight-ultracode-run-87db73/2e38a3e306a08f4a-7315914013a20eb8/web_hero.webp","imageAlt":"A wide funnel compresses 321 small scattered blocks into a single, large, clean monolith representing a finished game build.","createdAt":"2026-10-27T02:51:35.165Z","updatedAt":"2026-10-27T13:31:54.686Z","sources":[{"role":"primary","title":"Simon Willison Ships Battle Drones, a Full 3D RTS Game Built Entirely With Claude Code","url":"https://simonwillison.net/2026/Oct/20/battledrones","sourceName":"Simon Willison's Weblog","author":"Simon Willison's Weblog","publishedAt":"2026-10-20T19:34:19Z"},{"url":"https://x.com/simonw/status/2112630778068881543","title":null,"sourceName":"x.com","author":"Simon Willison","publishedAt":"2026-10-20T19:43:22.000Z","role":"supporting"}]}],"tips":[{"id":"a1514f8d-452e-45f5-a72a-2b9592d638e2","title":"Which Claude Code project files to commit, and what goes in CLAUDE.md versus .claude","dek":"Anthropic's docs contrast CLAUDE.md, the instructions file Claude reads every session, with skills, which load only when called or relevant; the hidden .claude folder holds the rest of the project's Claude Code configuration.","bodyMd":"Claude Code's docs say what each project file does and when it loads, and that decides where an instruction belongs. The clearest contrast is between `CLAUDE.md`, the instructions file Claude reads at the start of every session, and skills, which load only when you call them or when they are relevant. Here is the layout, drawn from Anthropic's pages on memory, the `.claude` directory, skills, subagents, MCP and settings (read October 25, 2026).\n\n**CLAUDE.md: what every session needs.** Put build and test commands, naming conventions, project layout and \"always do X\" rules in `CLAUDE.md` at the repo root or in `.claude/CLAUDE.md`. Keep it under 200 lines: longer files use more context and Claude follows them less reliably. Write checkable instructions (\"Run `npm test` before committing\", not \"Test your changes\"). Run `/init` to draft one from your codebase and `/context` to confirm it loaded. Anthropic's trigger for adding a line: Claude made the same mistake twice, a code review caught something it should have known, or you retyped the same correction.\n\nCLAUDE.md is context, not enforcement. If something must happen every time, such as blocking edits to `.env`, use a hook in settings.\n\n**Everything else under `.claude`**\n\n`.claude` is the hidden project folder that holds Claude Code's configuration, skills, agents and rules.\n\n- `.claude/rules/*.md`: topic-specific instructions. A rule with `paths` frontmatter (for example `\"src/api/**/*.ts\"`) loads only when Claude reads or edits a matching file. A rule without `paths` loads at launch, with the same priority as `.claude/CLAUDE.md`. `@path` imports in CLAUDE.md still load with it, so they don't save context. Path-scoped rules do.\n- `.claude/skills/<name>/SKILL.md`: workflows and long checklists that load when called or relevant. The folder name becomes a command such as `/deploy`.\n- `.claude/agents/<name>.md`: subagents with their own system prompt, tools and optional model. They run in a separate context window and return a summary, which suits tasks that read dozens of files.\n- `.claude/settings.json`: team permissions, hooks, plugins and environment variables.\n- `.mcp.json` at the repo root: project MCP servers, added with `claude mcp add --scope project`. Each person is asked to approve them before use. Use `${API_KEY}` or `${VAR:-default}` placeholders so keys expand from each person's environment.\n\n**What to commit.** `CLAUDE.md` (or `.claude/CLAUDE.md`), `.claude/rules/`, `.claude/skills/`, `.claude/agents/`, `.claude/settings.json`, and `.mcp.json` with placeholders.\n\n**What to keep out of git.** `CLAUDE.local.md` (add it to `.gitignore`) and `.claude/settings.local.json`, which holds personal overrides and wins over the team file. Claude Code creates the latter when you pick \"Yes, and don't ask again\" on a permission prompt and adds it to your global git excludes. If you create it by hand, ignore it yourself. Files in `~/.claude` and auto memory under `~/.claude/projects/` never enter the repo.\n\n**If the repo also serves other agents.** By default Claude Code reads `AGENTS.md` only when no `CLAUDE.md`, `.claude/CLAUDE.md` or `CLAUDE.local.md` exists in the working directory or above. Adding a `CLAUDE.local.md` therefore makes Claude stop reading `AGENTS.md` for you. To keep one shared file, put `@AGENTS.md` on the first line of `CLAUDE.md` and add Claude-only notes below. Alternatively, set **Project instructions** in `/config` to `claude-md-and-agents-md` to read both. Reading `AGENTS.md` directly needs Claude Code v2.1.277 or later, so use the import on older installs.\n\nAnything under `.agents/` is not read as instructions, and the skills docs list only `.claude/skills` locations. Cursor documents reading `.claude/skills`, which makes it the one skills path both tools document.","category":"Workflow","slug":"which-claude-code-project-files-to-commit-and-what-goes-in-claude-md-ver-a1514f","url":"https://claudecodereview.ai/a/which-claude-code-project-files-to-commit-and-what-goes-in-claude-md-ver-a1514f/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/a1514f8d-452e-45f5-a72a-2b9592d638e2","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/which-claude-code-project-files-to-commit-and-what-goes-in-claude-md-ver-a1514f/88eda2ba5e65f4bd-18af441a6d0bd9f4/web_hero.webp","imageAlt":"A tall rectangular prism stands taller than a group of small, varied blocks, representing the distinction between core instructions and modular project configuration.","createdAt":"2026-10-30T03:33:49.533Z"},{"id":"012d35b5-2133-4478-8cb3-f1e7957e1fbe","title":"Keep long sessions from filling up on tool output with the Context Mode plugin","dek":"Context Mode routes raw MCP output into a sandbox and tracks session events in SQLite, which its README says keeps far less raw output from heavy browser, GitHub and log tools in your context.","bodyMd":"Context Mode is an MCP server plus a set of hooks that keeps raw tool output out of the chat. According to its README, a Playwright snapshot costs 56 KB, twenty GitHub issues cost 59 KB and one access log is 45 KB. After about 30 minutes of work, roughly 40% of a Claude Code context can be gone, and after compaction the agent can lose track of which files it was editing. Context Mode keeps the raw output in a sandbox so only a small result reaches the conversation. It also records session events in SQLite so work survives compaction.\n\n## Set it up\n\nYou need Claude Code v1.0.33 or newer (`claude --version`). If `/plugin` is not recognized, update with `brew upgrade claude-code` or `npm update -g @anthropic-ai/claude-code`.\n\n1. **Install.** Inside Claude Code run `/plugin marketplace add mksglu/context-mode`, then `/plugin install context-mode@context-mode`. Restart Claude Code or run `/reload-plugins`.\n2. **Verify.** Run `/context-mode:ctx-doctor`. Every check should show `[x]`. It validates runtimes, hooks, FTS5 and plugin registration. Fix anything red first, because the routing hooks are what make the savings automatic.\n3. **Let the model write code instead of reading files.** Routing is automatic: a SessionStart hook injects instructions at runtime, so nothing is written into your project. The README's example replaces 47 `Read()` calls (700 KB) with one `ctx_execute()` script that prints only line counts (3.6 KB). The README quotes 315 KB shrinking to 5.4 KB for sandboxed output. Those are the project's own numbers, so measure yours.\n4. **Measure.** `/context-mode:ctx-stats` shows a per-tool breakdown, tokens consumed and the savings ratio. For a live meter, add this to `~/.claude/settings.json` and restart:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"context-mode statusline\"\n  }\n}\n```\n\n5. **Index docs you keep re-reading.** `/context-mode:ctx-index` loads a local file or directory into a persistent FTS5 knowledge base. `/context-mode:ctx-search` then returns only the relevant passages through BM25 search. `/context-mode:ctx-purge` permanently deletes everything indexed.\n\n## Try it without the plugin\n\n`claude mcp add context-mode -- npx -y context-mode` adds only the MCP server. You get all 11 tools but no automatic routing or slash commands, so the model is not nudged away from raw Bash, Read and WebFetch and savings are smaller. It works as a low-commitment test.\n\n## When it is worth it\n\nThe plugin targets long sessions that lean on browser, GitHub or log-heavy MCP tools and keep hitting compaction. For short sessions, the write-up says the overhead is not worth it.\n\nOne caution from the README: if you do not start with `--continue`, previous session data is deleted immediately, so a fresh session is a clean slate. After a compaction, Context Mode indexes the recorded events (file edits, git operations, tasks, errors, decisions) and retrieves only what is relevant rather than replaying the history.","category":"Workflow","slug":"keep-long-sessions-from-filling-up-on-tool-output-with-the-context-mode-012d35","url":"https://claudecodereview.ai/a/keep-long-sessions-from-filling-up-on-tool-output-with-the-context-mode-012d35/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/012d35b5-2133-4478-8cb3-f1e7957e1fbe","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/keep-long-sessions-from-filling-up-on-tool-output-with-the-context-mode-012d35/64ab7afaa95425f6-2859cb9dfee6cb92/web_hero.webp","imageAlt":"A funneling graphic showing forty-seven rectangular blocks passing through a narrow aperture into one single, small cube.","createdAt":"2026-10-30T03:31:19.263Z"},{"id":"a3b34cbb-9e00-4643-bdea-82b6d27706e5","title":"Shrink test logs and JSON output before they hit your token bill","dek":"Headroom, an open-source local proxy (a program on your machine that sits between Claude Code and the model), compresses logs and tool output, including JSON and token-heavy text, before it is sent, and one command wraps your sessions.","bodyMd":"Test runs, build logs, large JSON (the structured data format many tools print) and long diffs go back to the model on every step, and you pay for those tokens each time. Tokens are the units of text the model bills by. Headroom is an open-source tool that sits between Claude Code and the model and compresses that material first. Its README gives one example: a log that costs 10,144 tokens shrinks to 1,260 while the same fatal error is still found.\n\nCompression runs on your machine. Headroom routes each piece of content to a fitting compressor (one for JSON, one that understands code structure, a text model for prose) and caches the originals locally. The model gets a `headroom_retrieve` tool to pull back the full text when it needs it. Headroom flags content that would break your provider's prompt cache but does not rewrite your prompts.\n\n## Setup\n\n1. Install the CLI with `uv tool install --python 3.13 \"headroom-ai[all]\"` or `pip install \"headroom-ai[all]\"`. The npm package (`npm install headroom-ai`) is the TypeScript SDK only and has no CLI.\n2. Run `headroom wrap claude`. It starts a local proxy (a program on your machine that sits between Claude Code and the model), installs the Serena MCP server for semantic code navigation (registered for the wrapped project only) and launches Claude Code routed through Headroom. Launch Claude Code this way each session. To back out, run `headroom unwrap claude`.\n3. Check it works: `headroom doctor` confirms routing, `headroom perf` shows compression stats, and `headroom dashboard` shows live savings while the proxy is running. Run `doctor` first.\n4. If you would rather not wrap anything, run `headroom proxy --port 8787` and point your tools at it. Anything that can set an API base URL can use it, including your own scripts.\n5. Optionally, run `headroom learn`. It mines failed sessions and writes corrections to `CLAUDE.local.md` (gitignored) by default, or to `CLAUDE.md` or `AGENTS.md` if you choose. Review what it proposes before committing it to a shared file.\n\n## When it pays off\n\nLong sessions on a large repo, usage limits you keep hitting, or per-token billing are the cases where a quick trial makes sense. Sessions heavy on test runs, build logs and large JSON compress well. A session of short prompts will not move much.\n\n## Caveats\n\nThe 10,144 to 1,260 figure is the README's own example, not a benchmark of your repo, so measure with `headroom perf` on real sessions. Headroom also adds a local proxy to your setup, one more moving part when something breaks. The same `wrap` command works for Codex, Cursor, Aider, Cline, Goose and OpenHands.","category":"Workflow","slug":"shrink-test-logs-and-json-output-before-they-hit-your-token-bill-a3b34c","url":"https://claudecodereview.ai/a/shrink-test-logs-and-json-output-before-they-hit-your-token-bill-a3b34c/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/a3b34cbb-9e00-4643-bdea-82b6d27706e5","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/shrink-test-logs-and-json-output-before-they-hit-your-token-bill-a3b34c/5aa2e890dcb437f0-544c3236601d11e5/web_hero.webp","imageAlt":"A wide funnel feeds three types of data blocks into a single narrow tube, where a clay-orange filter section represents compressed data output.","createdAt":"2026-10-29T21:58:29.261Z"},{"id":"bbbd9b99-2dd4-4c09-9d14-30e77a90254a","title":"Catch file changes a PostToolUse hook misses with a Stop hook that asks git","dek":"In a scripted test, a PostToolUse hook matching Edit|MultiEdit|Write saw 3 of 7 file changes, while a Stop hook running git status saw all 7.","bodyMd":"In a scripted test, a PostToolUse hook matched on `Edit|MultiEdit|Write` saw only the changes made through Claude's file tools. On Claude Code 2.1.312, it caught 3 of 7 changes. The four it missed were made through Bash: `sed -i`, a `>` redirect, `rm` and `git mv`. A Stop hook that runs `git status` listed all seven, including the delete and the rename.\n\nA quick gloss on the terms: a hook is a script Claude Code runs automatically at set points. A PostToolUse hook runs after each tool call, and a Stop hook runs when Claude finishes. Git is the version-control tool that tracks uncommitted changes in a repo, and `git status` lists them.\n\nThe test used a scripted fake model (a local server standing in for the Messages API) that issued a fixed list of tool calls against the real Claude Code binary, so no API key was needed. A real model picks its own routes, and seven routes are a sample, not a census.\n\n**Add the git-backed Stop hook**\n\n1. Create `.claude/stop-check.sh`:\n\n```\ngit status --porcelain -uall > .git/hk-status\ngrep -q '\"stop_hook_active\":true' && exit 0\n[ -s .git/hk-status ] || exit 0\ncat .git/hk-status >&2\nexit 2\n```\n\n2. Register it in `.claude/settings.json` as a `Stop` hook with the command `cd \"$CLAUDE_PROJECT_DIR\" && sh .claude/stop-check.sh`.\n\nThe `cd` matters because hooks run in Claude's current directory, which moves when Claude runs `cd`. Exit code 2 tells Claude Code not to stop yet and passes stderr to the model, so Claude sees the list of changed files before it finishes. The `stop_hook_active` check lets the second stop through, so the hook can't loop. In the test, this cost one extra model call and delivered all seven status lines.\n\n**Why adding Bash to the matcher doesn't fix it**\n\nMatching `Edit|Write|Bash` makes the hook fire on the four Bash changes. But those payloads hold the command string, with no `file_path` and no patch. To learn which files `rm` or `git mv` touched, the hook would have to parse shell.\n\n**New files arrive with an empty patch**\n\nA file created with Write reports `type=create` and `structuredPatch=[]`; the text sits in `tool_response.content`. A hook that reviews `structuredPatch` sees nothing for new files, so read `content` when `type` is `create`.\n\n**Worth using when** a review loop depends on knowing what Claude changed. Keep PostToolUse for instant per-edit checks, since Stop only runs when Claude finishes.\n\n**Limits**\n- Git skips gitignored files, files outside the repo, and anything Claude commits itself.\n- The hook also lists your own uncommitted work.\n- `MultiEdit` did not appear in the request Claude Code 2.1.312 sent the model, so it widens nothing.\n- `NotebookEdit` appears as a deferred tool and the usual matcher doesn't name it; its payload wasn't tested.\n- PostToolUse behavior in subagents wasn't tested.","category":"Workflow","slug":"catch-file-changes-a-posttooluse-hook-misses-with-a-stop-hook-that-asks-bbbd9b","url":"https://claudecodereview.ai/a/catch-file-changes-a-posttooluse-hook-misses-with-a-stop-hook-that-asks-bbbd9b/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/bbbd9b99-2dd4-4c09-9d14-30e77a90254a","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/catch-file-changes-a-posttooluse-hook-misses-with-a-stop-hook-that-asks-bbbd9b/77803526806d849e-d986ba588b19e4b0/web_hero.webp","imageAlt":"A diagram shows seven file blocks being caught by a container versus a sieve that only catches three.","createdAt":"2026-10-29T21:56:56.756Z"},{"id":"8d01e30d-2c9d-4811-9baa-5d6f7de00bfd","title":"See every waiting session, subagent and Codex run that Agent View leaves off its list","dek":"Agent View only lists background sessions, so a JSON command, a Notification hook or ccdeck, a free, open-source dashboard that runs on your machine and shows Claude Code and Codex sessions, has to cover the rest.","bodyMd":"Agent View, opened with `claude agents`, is one screen for background sessions. Anthropic's documentation says interactive sessions open in other terminals don't appear until you background them, and that subagents and teammates a session spawns aren't listed as separate rows. Codex isn't listed either. The feature is in research preview, and a row shows only the session's name, current activity and age: no spend or quota.\n\nTwo terms used below: a subagent is a helper session that a main Claude Code session spawns. Codex is a separate coding-agent CLI that has its own `codex agents` dashboard and writes rollout files under `~/.codex/sessions`.\n\nThree ways to see the rest:\n\n1. **Poll `claude agents --json`.** In Claude Code 2.1.312 the command prints active sessions, interactive and background, as a JSON array. Each entry has a `kind` and, while its process is alive, a `status` of `busy`, `waiting` or `idle`. A waiting session adds `waitingFor`, such as `permission prompt` or `input needed`. Filter it with jq: `claude agents --json | jq '.[] | select(.status == \"waiting\")'`. It lists sessions, not subagents, and it is a snapshot, so poll it to keep it current.\n\n2. **Add a `Notification` hook** to `~/.claude/settings.json`. It applies to every session that reads that file, whichever terminal started it. Match `permission_prompt|idle_prompt` and have the hook command append one line per wait to a log, for example with `jq -c` writing to `~/.claude/waiting.log`. Notification hooks can't block or modify notifications, so this only observes.\n\n3. **Run a dashboard.** ccdeck, a free, open-source dashboard, starts with `npx ccdeck`. Its first run adds a hook to `~/.claude/settings.json`, so sessions from any terminal report to it. Each subagent gets its own card joined to its session, and Codex CLI sessions appear on the same canvas, read from the rollout files under `~/.codex/sessions`. The topbar names Claude Code sessions stopped on a prompt or question, with how long each has waited. It also shows estimated spend per session. `ccdeck sessions` prints the waiting list in a terminal.\n\nFor subagents without a dashboard, hooks from settings files also run inside subagents. Tool events such as `PreToolUse` carry `agent_id` and `agent_type` when a subagent made the call, and `SubagentStart` and `SubagentStop` mark each one's life.\n\n**When to use which.** Dispatch and reply in Agent View. Poll the JSON if all you need is who is waiting in any terminal. Add a hook or dashboard when you want subagents, Codex or spend alongside.\n\n**Limits.** ccdeck can't reply, start or attach to sessions, because its hook is a one-way forwarder. It keeps nothing while no deck is running. Its waiting list covers Claude Code only, and the tool name beside a wait is its inference. Codex logs record no approval request, so a running Codex session shows \"approvals not visible\". Because the hook only observes, it doesn't change what Agent View does, and background sessions read user settings, so they report too.","category":"Workflow","slug":"see-every-waiting-session-subagent-and-codex-run-that-agent-view-leaves-8d01e3","url":"https://claudecodereview.ai/a/see-every-waiting-session-subagent-and-codex-run-that-agent-view-leaves-8d01e3/","relayUrl":"https://relaygrid.com/publications/pivot-claude-code/stories/8d01e30d-2c9d-4811-9baa-5d6f7de00bfd","imageUrl":"https://media.pivotnews.ai/brands/claude-code-review/articles/see-every-waiting-session-subagent-and-codex-run-that-agent-view-leaves-8d01e3/00195507b7b60ff9-5f4c5c671f925426/web_hero.webp","imageAlt":"A diagram shows rectangular session strips, square subagent tiles, and circular coding-agent discs being connected by a single line into a unified cluster.","createdAt":"2026-10-29T21:52:06.001Z"}]}