<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: jesse-vincent</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/jesse-vincent.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2025-10-10T23:57:19+00:00</updated><author><name>Simon Willison</name></author><entry><title>simonw/claude-skills</title><link href="https://simonwillison.net/2025/Oct/10/claude-skills/#atom-tag" rel="alternate"/><published>2025-10-10T23:57:19+00:00</published><updated>2025-10-10T23:57:19+00:00</updated><id>https://simonwillison.net/2025/Oct/10/claude-skills/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/simonw/claude-skills"&gt;simonw/claude-skills&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
One of the tips I picked up from &lt;a href="https://blog.fsck.com/2025/10/09/superpowers/"&gt;Jesse Vincent's Claude Code Superpowers post&lt;/a&gt; (&lt;a href="https://simonwillison.net/2025/Oct/10/superpowers/"&gt;previously&lt;/a&gt;) was this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Skills are what give your agents Superpowers.&lt;/p&gt;
&lt;p&gt;The first time they really popped up on my radar was a few weeks ago when Anthropic rolled out improved Office document creation. When the feature rolled out, I went poking around a bit -- I asked Claude to tell me all about its new skills. And it was &lt;a href="https://claude.ai/share/0fe5a9c0-4e5a-42a1-9df7-c5b7636dad92"&gt;only too happy to dish&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In that transcript Jesse asks how the skill system works and Claude replies:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Looking at the skills system, here's how it works:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Current Skills&lt;/strong&gt; (in &lt;code&gt;/mnt/skills/public/&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;docx&lt;/strong&gt; - Word document handling&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pdf&lt;/strong&gt; - PDF processing and form filling&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pptx&lt;/strong&gt; - PowerPoint presentations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;xlsx&lt;/strong&gt; - Excel spreadsheets&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;This looks like it's part of Claude's brand new Code Interpreter feature! I &lt;a href="https://simonwillison.net/2025/Sep/9/claude-code-interpreter/"&gt;wrote about that extensively&lt;/a&gt; last month, but I missed that there was a &lt;code&gt;/mnt/skills/public/&lt;/code&gt; folder full of fascinating implementation details.&lt;/p&gt;
&lt;p&gt;So I fired up a fresh Claude instance (fun fact: Code Interpreter also works in the Claude iOS app now, which it didn't when they first launched) and prompted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Create a zip file of everything in your /mnt/skills folder&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This worked, and gave me a &lt;code&gt;.zip&lt;/code&gt; to download. You can &lt;a href="https://claude.ai/new?q=Create%20a%20zip%20file%20of%20everything%20in%20your%20%2Fmnt%2Fskills%20folder"&gt;run the prompt yourself here&lt;/a&gt;, though you'll need to &lt;a href="https://simonwillison.net/2025/Sep/9/claude-code-interpreter/#switching-it-on-in-settings-features"&gt;enable the new feature first&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I've pushed the contents of that zip to my &lt;a href="https://github.com/simonw/claude-skills"&gt;new simonw/claude-skills GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So now you can see the prompts Anthropic wrote to enable the creation and manipulation of the following files in their Claude consumer applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/simonw/claude-skills/blob/initial/mnt/skills/public/pdf/SKILL.md"&gt;pdf&lt;/a&gt; - PDF files&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/simonw/claude-skills/blob/initial/mnt/skills/public/docx/SKILL.md"&gt;docx&lt;/a&gt; - Microsoft Word&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/simonw/claude-skills/blob/initial/mnt/skills/public/pptx/SKILL.md"&gt;pptx&lt;/a&gt; - Microsoft PowerPoint decks&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/simonw/claude-skills/blob/initial/mnt/skills/public/xlsx/SKILL.md"&gt;xlsx&lt;/a&gt; - Microsoft Excel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In each case the prompts spell out detailed instructions for manipulating those file types using Python, using libraries that come pre-installed on Claude's containers.&lt;/p&gt;
&lt;p&gt;Skills are more than just prompts though: the repository also includes dozens of pre-written Python scripts for performing common operations.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/simonw/claude-skills/blob/initial/mnt/skills/public/pdf/scripts/fill_fillable_fields.py"&gt;pdf/scripts/fill_fillable_fields.py&lt;/a&gt; for example is a custom CLI tool that uses &lt;a href="https://pypi.org/project/pypdf/"&gt;pypdf&lt;/a&gt; to find and then fill in a bunch of PDF form fields, specified as JSON, then render out the resulting combined PDF.&lt;/p&gt;
&lt;p&gt;This is a really sophisticated set of tools for document manipulation, and I love that Anthropic have made those visible - presumably deliberately - to users of Claude who know how to ask for them.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/pdf"&gt;pdf&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/prompt-engineering"&gt;prompt-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthropic"&gt;anthropic&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude"&gt;claude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/code-interpreter"&gt;code-interpreter&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jesse-vincent"&gt;jesse-vincent&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/skills"&gt;skills&lt;/a&gt;&lt;/p&gt;



</summary><category term="pdf"/><category term="python"/><category term="ai"/><category term="prompt-engineering"/><category term="generative-ai"/><category term="llms"/><category term="anthropic"/><category term="claude"/><category term="code-interpreter"/><category term="jesse-vincent"/><category term="skills"/></entry><entry><title>Superpowers: How I'm using coding agents in October 2025</title><link href="https://simonwillison.net/2025/Oct/10/superpowers/#atom-tag" rel="alternate"/><published>2025-10-10T23:30:14+00:00</published><updated>2025-10-10T23:30:14+00:00</updated><id>https://simonwillison.net/2025/Oct/10/superpowers/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.fsck.com/2025/10/09/superpowers/"&gt;Superpowers: How I&amp;#x27;m using coding agents in October 2025&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
A follow-up to Jesse Vincent's post &lt;a href="https://blog.fsck.com/2025/10/05/how-im-using-coding-agents-in-september-2025/"&gt;about September&lt;/a&gt;, but this is a really significant piece in its own right.&lt;/p&gt;
&lt;p&gt;Jesse is one of the most creative users of coding agents (Claude Code in particular) that I know. He's put a great amount of work into evolving an effective process for working with them, encourage red/green TDD (watch the test fail first), planning steps, self-updating memory notes and even implementing a &lt;a href="https://blog.fsck.com/2025/05/28/dear-diary-the-user-asked-me-if-im-alive/"&gt;feelings journal&lt;/a&gt; ("I feel engaged and curious about this project" - Claude).&lt;/p&gt;
&lt;p&gt;Claude Code &lt;a href="https://www.anthropic.com/news/claude-code-plugins"&gt;just launched plugins&lt;/a&gt;, and Jesse is celebrating by wrapping up a whole host of his accumulated tricks as a new plugin called &lt;a href="https://github.com/obra/superpowers"&gt;Superpowers&lt;/a&gt;. You can add it to your Claude Code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There's a lot in here! It's worth spending some time &lt;a href="https://github.com/obra/superpowers"&gt;browsing the repository&lt;/a&gt; - here's just one fun example, in &lt;a href="https://github.com/obra/superpowers/blob/main/skills/debugging/root-cause-tracing/SKILL.md"&gt;skills/debugging/root-cause-tracing/SKILL.md&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;---
name: Root Cause Tracing
description: Systematically trace bugs backward through call stack to find original trigger
when_to_use: Bug appears deep in call stack but you need to find where it originates
version: 1.0.0
languages: all
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bugs often manifest deep in the call stack (git init in wrong directory, file created in wrong location, database opened with wrong path). Your instinct is to fix where the error appears, but that's treating a symptom.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Core principle:&lt;/strong&gt; Trace backward through the call chain until you find the original trigger, then fix at the source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to Use&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;digraph when_to_use {
    "Bug appears deep in stack?" [shape=diamond];
    "Can trace backwards?" [shape=diamond];
    "Fix at symptom point" [shape=box];
    "Trace to original trigger" [shape=box];
    "BETTER: Also add defense-in-depth" [shape=box];

    "Bug appears deep in stack?" -&amp;gt; "Can trace backwards?" [label="yes"];
    "Can trace backwards?" -&amp;gt; "Trace to original trigger" [label="yes"];
    "Can trace backwards?" -&amp;gt; "Fix at symptom point" [label="no - dead end"];
    "Trace to original trigger" -&amp;gt; "BETTER: Also add defense-in-depth";
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[...]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one is particularly fun because it then includes a &lt;a href="https://en.wikipedia.org/wiki/DOT_(graph_description_language)"&gt;Graphviz DOT graph&lt;/a&gt; illustrating the process - it turns out Claude can interpret those as workflow instructions just fine, and Jesse has been &lt;a href="https://blog.fsck.com/2025/09/29/using-graphviz-for-claudemd/"&gt;wildly experimenting with them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I &lt;a href="https://claude.ai/share/2b78a93e-cdc3-4b1d-9b02-457eb62140a5"&gt;vibe-coded up&lt;/a&gt; a quick URL-based DOT visualizer, &lt;a href="https://tools.simonwillison.net/dot#digraph%20when_to_use%20%7B%0A%20%20%20%20%22Bug%20appears%20deep%20in%20stack%3F%22%20%5Bshape%3Ddiamond%5D%3B%0A%20%20%20%20%22Can%20trace%20backwards%3F%22%20%5Bshape%3Ddiamond%5D%3B%0A%20%20%20%20%22Fix%20at%20symptom%20point%22%20%5Bshape%3Dbox%5D%3B%0A%20%20%20%20%22Trace%20to%20original%20trigger%22%20%5Bshape%3Dbox%5D%3B%0A%20%20%20%20%22BETTER%3A%20Also%20add%20defense-in-depth%22%20%5Bshape%3Dbox%5D%3B%0A%0A%20%20%20%20%22Bug%20appears%20deep%20in%20stack%3F%22%20-%3E%20%22Can%20trace%20backwards%3F%22%20%5Blabel%3D%22yes%22%5D%3B%0A%20%20%20%20%22Can%20trace%20backwards%3F%22%20-%3E%20%22Trace%20to%20original%20trigger%22%20%5Blabel%3D%22yes%22%5D%3B%0A%20%20%20%20%22Can%20trace%20backwards%3F%22%20-%3E%20%22Fix%20at%20symptom%20point%22%20%5Blabel%3D%22no%20-%20dead%20end%22%5D%3B%0A%20%20%20%20%22Trace%20to%20original%20trigger%22%20-%3E%20%22BETTER%3A%20Also%20add%20defense-in-depth%22%3B%0A%7D"&gt;here's that one rendered&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The above DOT rendered as an image" src="https://static.simonwillison.net/static/2025/jesse-dot.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;There is &lt;em&gt;so much&lt;/em&gt; to learn about putting these tools to work in the most effective way possible. Jesse is way ahead of the curve, so it's absolutely worth spending some time exploring what he's shared so far.&lt;/p&gt;
&lt;p&gt;And if you're worried about filling up your context with a bunch of extra stuff, here's &lt;a href="https://bsky.app/profile/s.ly/post/3m2srmkergc2p"&gt;a reassuring note from Jesse&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The core of it is VERY token light. It pulls in one doc of fewer than 2k tokens. As it needs bits of the process, it runs a shell script to search for them.  The long end to end chat for the planning and implementation process for that todo list app was 100k tokens.&lt;/p&gt;
&lt;p&gt;It uses subagents to manage token-heavy stuff, including all the actual implementation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Jesse's post also tipped me off about Claude's &lt;code&gt;/mnt/skills/public&lt;/code&gt; folder, see &lt;a href="https://simonwillison.net/2025/Oct/10/claude-skills/"&gt;my notes here&lt;/a&gt;.)


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/plugins"&gt;plugins&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/prompt-engineering"&gt;prompt-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthropic"&gt;anthropic&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude"&gt;claude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/coding-agents"&gt;coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude-code"&gt;claude-code&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sub-agents"&gt;sub-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jesse-vincent"&gt;jesse-vincent&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/skills"&gt;skills&lt;/a&gt;&lt;/p&gt;



</summary><category term="plugins"/><category term="ai"/><category term="prompt-engineering"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="anthropic"/><category term="claude"/><category term="vibe-coding"/><category term="coding-agents"/><category term="claude-code"/><category term="sub-agents"/><category term="jesse-vincent"/><category term="skills"/></entry><entry><title>Embracing the parallel coding agent lifestyle</title><link href="https://simonwillison.net/2025/Oct/5/parallel-coding-agents/#atom-tag" rel="alternate"/><published>2025-10-05T12:06:55+00:00</published><updated>2025-10-05T12:06:55+00:00</updated><id>https://simonwillison.net/2025/Oct/5/parallel-coding-agents/#atom-tag</id><summary type="html">
    &lt;p&gt;For a while now I've been hearing from engineers who run multiple coding agents at once - firing up several Claude Code or Codex CLI instances at the same time, sometimes in the same repo, sometimes against multiple checkouts or &lt;a href="https://docs.claude.com/en/docs/claude-code/common-workflows#run-parallel-claude-code-sessions-with-git-worktrees"&gt;git worktrees&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was pretty skeptical about this at first. AI-generated code needs to be reviewed, which means the natural bottleneck on all of this is how fast I can review the results. It's tough keeping up with just a single LLM given how fast they can churn things out, where's the benefit from running more than one at a time if it just leaves me further behind?&lt;/p&gt;
&lt;p&gt;Despite my misgivings, over the past few weeks I've noticed myself quietly starting to embrace the parallel coding agent lifestyle.&lt;/p&gt;
&lt;p&gt;I can only focus on reviewing and landing one significant change at a time, but I'm finding an increasing number of tasks that can still be fired off in parallel without adding too much cognitive overhead to my primary work.&lt;/p&gt;
&lt;p&gt;Here are some patterns I've found for applying parallel agents effectively.&lt;/p&gt;
&lt;h4 id="research-poc"&gt;Research for proof of concepts&lt;/h4&gt;
&lt;p&gt;The first category of tasks I've been applying this pattern to is &lt;strong&gt;research&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Research tasks answer questions or provide recommendations without making modifications to a project that you plan to keep.&lt;/p&gt;
&lt;p&gt;A lot of software projects start with a proof of concept. Can &lt;a href="https://yjs.dev"&gt;Yjs&lt;/a&gt; be used to implement a simple collaborative note writing tool with a Python backend? The &lt;a href="https://github.com/y-crdt/pycrdt"&gt;libraries exist&lt;/a&gt;, but do they work when you wire them together?&lt;/p&gt;
&lt;p&gt;Today's coding agents can build a proof of concept with new libraries and resolve those kinds of basic questions. Libraries too new to be in the training data? Doesn't matter: tell them to checkout the repos for those new dependencies and read the code to figure out how to use them.&lt;/p&gt;
&lt;h4 id="how-does-that-work-again"&gt;How does that work again?&lt;/h4&gt;
&lt;p&gt;If you need a reminder about how a portion of your existing system works, modern "reasoning" LLMs can provide a detailed, actionable answer in just a minute or two.&lt;/p&gt;
&lt;p&gt;It doesn't matter how large your codebase is: coding agents are extremely effective with tools like grep and can follow codepaths through dozens of different files if they need to.&lt;/p&gt;
&lt;p&gt;Ask them to make notes on where your signed cookies are set and read, or how your application uses subprocesses and threads, or which aspects of your JSON API aren't yet covered by your documentation.&lt;/p&gt;
&lt;p&gt;These LLM-generated explanations are worth stashing away somewhere, because they can make excellent context to paste into further prompts in the future.&lt;/p&gt;
&lt;h4 id="small-maintenance-tasks"&gt;Small maintenance tasks&lt;/h4&gt;
&lt;p&gt;Now we're moving on to code edits that we intend to keep, albeit with &lt;em&gt;very&lt;/em&gt; low-stakes. It turns out there are a lot of problems that really just require a little bit of extra cognitive overhead which can be outsourced to a bot.&lt;/p&gt;
&lt;p&gt;Warnings are a great example. Is your test suite spitting out a warning that something you are using is deprecated? Chuck that at a bot - tell it to run the test suite and figure out how to fix the warning. No need to take a break from what you're doing to resolve minor irritations like that.&lt;/p&gt;
&lt;p&gt;There is a definite knack to spotting opportunities like this. As always, the best way to develop that instinct is to try things - any small maintenance task is something that's worth trying with a coding agent. You can learn from both their successes &lt;em&gt;and&lt;/em&gt; their failures.&lt;/p&gt;
&lt;h4 id="carefully-specified-and-directed-actual-work"&gt;Carefully specified and directed actual work&lt;/h4&gt;
&lt;p&gt;Reviewing code that lands on your desk out of nowhere is a &lt;em&gt;lot&lt;/em&gt; of work. First you have to derive the goals of the new implementation: what's it trying to achieve? Is this something the project needs? Is the approach taken the best for this current project, given other future planned changes? A lot of big questions before you can even start digging into the details of the code.&lt;/p&gt;
&lt;p&gt;Code that started from your own specification is a lot less effort to review. If you already decided what to solve, picked the approach and worked out a detailed specification for the work itself, confirming it was built to your needs can take a lot less time.&lt;/p&gt;
&lt;p&gt;I described my &lt;a href="https://simonwillison.net/2025/Mar/11/using-llms-for-code/#tell-them-exactly-what-to-do"&gt;more authoritarian approach&lt;/a&gt; to prompting models for code back in March. If I tell them &lt;em&gt;exactly&lt;/em&gt; how to build something the work needed to review the resulting changes is a whole lot less taxing.&lt;/p&gt;
&lt;h4 id="how-i-m-using-these-tools-today"&gt;How I'm using these tools today&lt;/h4&gt;
&lt;p&gt;My daily drivers are currently &lt;a href="https://www.claude.com/product/claude-code"&gt;Claude Code&lt;/a&gt; (on Sonnet 4.5), &lt;a href="https://github.com/openai/codex"&gt;Codex CLI&lt;/a&gt; (on GPT-5-Codex), and &lt;a href="https://chatgpt.com/codex"&gt;Codex Cloud&lt;/a&gt; (for asynchronous tasks, frequently launched from my phone.)&lt;/p&gt;
&lt;p&gt;I'm also dabbling with &lt;a href="https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent"&gt;GitHub Copilot Coding Agent&lt;/a&gt; (the agent baked into the &lt;a href="https://github.com"&gt;GitHub.com&lt;/a&gt; web interface in various places) and &lt;a href="https://jules.google"&gt;Google Jules&lt;/a&gt;, Google's currently-free alternative to Codex Cloud.&lt;/p&gt;
&lt;p&gt;I'm still settling into patterns that work for me. I imagine I'll be iterating on my processes for a long time to come, especially as the landscape of coding agents continues to evolve.&lt;/p&gt;
&lt;p&gt;I frequently have multiple terminal windows open running different coding agents in different directories. These are currently a mixture of Claude Code and Codex CLI, running in &lt;a href="https://simonwillison.net/2025/Sep/30/designing-agentic-loops/#the-joy-of-yolo-mode"&gt;YOLO mode&lt;/a&gt; (no approvals) for tasks where I'm confident malicious instructions can't sneak into the context.&lt;/p&gt;
&lt;p&gt;(I need to start habitually running my local agents in Docker containers to further limit the blast radius if something goes wrong.)&lt;/p&gt;
&lt;p&gt;I haven't adopted git worktrees yet: if I want to run two agents in isolation against the same repo I do a fresh checkout, often into &lt;code&gt;/tmp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For riskier tasks I'm currently using asynchronous coding agents - usually Codex Cloud - so if anything goes wrong the worst that can happen is my source code getting leaked (since &lt;a href="https://simonwillison.net/2025/Jun/3/codex-agent-internet-access/"&gt;I allow it to have network access&lt;/a&gt; while running). Most of what I work on is open source anyway so that's not a big concern for me.&lt;/p&gt;
&lt;p&gt;I occasionally use &lt;a href="https://github.com/features/codespaces"&gt;GitHub Codespaces&lt;/a&gt; to run VS Code's agent mode, which is surprisingly effective and runs directly in my browser. This is particularly great for workshops and demos since it works for anyone with GitHub account, no extra API key necessary.&lt;/p&gt;
&lt;h4 id="please-share-your-patterns-that-work"&gt;Please share your patterns that work&lt;/h4&gt;
&lt;p&gt;This category of coding agent software is still really new, and the models have only really got good enough to drive them effectively in the past few months - Claude 4 and GPT-5 in particular.&lt;/p&gt;
&lt;p&gt;I plan to write more as I figure out the ways of using them that are most effective. I encourage other practitioners to do the same!&lt;/p&gt;
&lt;h4 id="recommended-reading"&gt;Recommended reading&lt;/h4&gt;
&lt;p&gt;Jesse Vincent wrote &lt;a href="https://blog.fsck.com/2025/10/05/how-im-using-coding-agents-in-september-2025/"&gt;How I'm using coding agents in September, 2025&lt;/a&gt; which describes his workflow for parallel agents in detail, including having an architect agent iterate on a plan which is then reviewed and implemented by fresh instances of Claude Code.&lt;/p&gt;
&lt;p&gt;In &lt;a href="https://sketch.dev/blog/seven-prompting-habits"&gt;The 7 Prompting Habits of Highly Effective Engineers&lt;/a&gt; Josh Bleecher Snyder describes several patterns for this kind of work. I particularly like this one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Send out a scout&lt;/strong&gt;. Hand the AI agent a task just to find out where the sticky bits are, so you don’t have to make those mistakes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I've tried this a few times with good results: give the agent a genuinely difficult task against a large codebase, with no intention of actually landing its code, just to get ideas from which files it modifies and how it approaches the problem.&lt;/p&gt;
&lt;p&gt;Peter Steinberger's &lt;a href="https://steipete.me/posts/just-talk-to-it"&gt;Just Talk To It - the no-bs Way of Agentic Engineering&lt;/a&gt; provides a very detailed description of his current process built around Codex CLI.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-agents"&gt;ai-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/coding-agents"&gt;coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude-code"&gt;claude-code&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async-coding-agents"&gt;async-coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jules"&gt;jules&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/codex-cli"&gt;codex-cli&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/parallel-agents"&gt;parallel-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jesse-vincent"&gt;jesse-vincent&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/peter-steinberger"&gt;peter-steinberger&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/agentic-engineering"&gt;agentic-engineering&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="ai-agents"/><category term="coding-agents"/><category term="claude-code"/><category term="async-coding-agents"/><category term="jules"/><category term="codex-cli"/><category term="parallel-agents"/><category term="jesse-vincent"/><category term="peter-steinberger"/><category term="agentic-engineering"/></entry><entry><title>Trying to end the pandemic a little earlier with VaccinateCA</title><link href="https://simonwillison.net/2021/Feb/28/vaccinateca/#atom-tag" rel="alternate"/><published>2021-02-28T05:40:28+00:00</published><updated>2021-02-28T05:40:28+00:00</updated><id>https://simonwillison.net/2021/Feb/28/vaccinateca/#atom-tag</id><summary type="html">
    &lt;p&gt;This week I got involved with the &lt;a href="https://www.vaccinateca.com/"&gt;VaccinateCA&lt;/a&gt; effort. We are trying to end the pandemic a little earlier, by building the most accurate database possible of vaccination locations and availability in California.&lt;/p&gt;

&lt;h4&gt;VaccinateCA&lt;/h4&gt;
&lt;p&gt;I’ve been following this project for a while through Twitter, mainly via &lt;a href="https://twitter.com/patio11"&gt;Patrick McKenzie&lt;/a&gt; - here’s &lt;a href="https://twitter.com/patio11/status/1351942635682816002"&gt;his tweet&lt;/a&gt; about the project from January 20th.&lt;/p&gt;

&lt;blockquote class="twitter-tweet"&gt;&lt;p lang="en" dir="ltr"&gt;&lt;a href="https://t.co/JrD5mb4TAN"&gt;https://t.co/JrD5mb4TAN&lt;/a&gt; calls medical professionals daily to ask who they could vaccinate and how to get in line. We publish this, covering the entire state of California, to help more people get their vaccines faster. Please tell your friends and networks.&lt;/p&gt;- Patrick McKenzie (@patio11) &lt;a href="https://twitter.com/patio11/status/1351942635682816002?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;The core idea is one of those things that sounds obviously correct the moment you hear it. The Covid vaccination roll-out is decentralized and pretty chaotic. VaccinateCA figured out that the best way to figure out where the vaccine is available is to call the places that are distributing it - pharmacies, hospitals, clinics - as often as possible and ask if they have any in stock, who is eligible for the shot and how people can sign up for an appointment.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.vaccinateca.com/what-weve-learned-so-far/"&gt;What We've Learned (So Far)&lt;/a&gt; by Patrick talks about lessons learned in the first 42 days of the project.&lt;/p&gt;
&lt;p&gt;There are three public-facing components to VaccinateCA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.vaccinateca.com/"&gt;www.vaccinateca.com&lt;/a&gt; is a website to help you find available vaccines near you.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;help.vaccinateca&lt;/code&gt; is the web app used by volunteers who make calls - it provides a script and buttons to submit information gleaned from the call. If you’re interested in volunteering there’s &lt;a href="https://www.vaccinateca.com/about-us"&gt;information on the website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;api.vaccinateca&lt;/code&gt; is the public API, which is &lt;a href="https://docs.vaccinateca.com/reference"&gt;documented here&lt;/a&gt; and is also used by the end-user facing website. It provides a full dump of collected location data, plus information on county policies and large-scale providers (pharmacy chains, health care providers).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The system currently mostly runs on &lt;a href="https://airtable.com/"&gt;Airtable&lt;/a&gt;, and takes advantage of pretty much every feature of that platform.&lt;/p&gt;
&lt;h4&gt;Why I got involved&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://twitter.com/obra"&gt;Jesse Vincent&lt;/a&gt; convinced me to get involved. It turns out to be a perfect fit for both my interests and my skills and experience.&lt;/p&gt;
&lt;p&gt;I’ve built crowdsourcing platforms before - for &lt;a href="https://simonwillison.net/2009/Dec/20/crowdsourcing/"&gt;MP’s expense reports at the Guardian&lt;/a&gt;, and then for conference and event listings with our startup, Lanyrd.&lt;/p&gt;
&lt;p&gt;VaccinateCA is a very data-heavy organization: the key goal is to build a comprehensive database of vaccine locations and availability. My background in data journalism and the last three years I’ve spent working on &lt;a href="https://datasette.io/"&gt;Datasette&lt;/a&gt; have given me a wealth of relevant experience here.&lt;/p&gt;
&lt;p&gt;And finally… VaccinateCA are quickly running up against the limits of what you can sensibly do with Airtable - especially given Airtable’s hard limit at 100,000 records. They need to port critical tables to a custom PostgreSQL database, while maintaining as much as possible the agility that Airtable has enabled for them.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt; is a great fit for this kind of challenge, and I know quite a bit about both Django and using Django to quickly build robust, scalable and maintainable applications!&lt;/p&gt;
&lt;p&gt;So I spent this week starting a Django replacement for the Airtable backend used by the volunteer calling application. I hope to get to feature parity (at least as an API backend that the application can write to) in the next few days, to demonstrate that a switch-over is both possible and a good idea.&lt;/p&gt;
&lt;h4&gt;What about Datasette?&lt;/h4&gt;
&lt;p&gt;On Monday I spun up a Datasette instance at &lt;a href="https://vaccinateca.datasette.io/"&gt;vaccinateca.datasette.io&lt;/a&gt; (&lt;a href="https://github.com/simonw/vaccinate-ca-datasette/"&gt;underlying repository&lt;/a&gt;) against data from the public VaccinateCA API. The map visualization of &lt;a href="https://vaccinateca.datasette.io/vaccinateca/locations?_facet=Affiliation&amp;amp;_facet=Latest+report+yes%3F&amp;amp;_facet_array=Availability+Info"&gt;all of the locations&lt;/a&gt; instantly proved useful in helping spot locations that had incorrectly been located with latitudes and longitudes outside of California.&lt;/p&gt;
&lt;p&gt;I hope to use Datasette for a variety of tasks like this, but it shouldn’t be the core of the solution. VaccinateCA is the perfect example of a problem that needs to be solved with &lt;a href="http://boringtechnology.club/"&gt;Boring Technology&lt;/a&gt; - it needs to Just Work, and time that could be spent learning exciting new technologies needs to be spent building what’s needed as quickly, robustly and risk-free as possible.&lt;/p&gt;
&lt;p&gt;That said, I’m already starting to experiment with the new &lt;a href="https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.JSONField"&gt;JSONField&lt;/a&gt; introduced in Django 3.1 - I’m hoping that a few JSON columns can help compensate for the lack of flexibility compared to Airtable, which makes it ridiculously easy for anyone to add additional columns.&lt;/p&gt;
&lt;p&gt;(To be fair JSONField has been a feature of the Django PostgreSQL Django extension since &lt;a href="https://docs.djangoproject.com/en/3.1/releases/1.9/"&gt;version 1.9 in 2015&lt;/a&gt; so it’s just about made it into the boring technology bucket by now.)&lt;/p&gt;
&lt;h4&gt;Also this week&lt;/h4&gt;
&lt;p&gt;Working on VaccinateCA has given me a chance to use some of my tools in new and interesting ways, so I got to ship a bunch of small fixes, detailed in &lt;a href="#releases-2021-feb-27"&gt;Releases this week&lt;/a&gt; below.&lt;/p&gt;
&lt;p&gt;On Friday I gave a talk at &lt;a href="https://speakeasyjs.com/"&gt;Speakeasy JS&lt;/a&gt;, "the JavaScript meetup for &lt;g-emoji class="g-emoji" alias="lab_coat" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f97c.png"&gt;🥼&lt;/g-emoji&gt; mad science, &lt;g-emoji class="g-emoji" alias="mage_man" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f9d9-2642.png"&gt;🧙‍♂️&lt;/g-emoji&gt; hacking, and &lt;g-emoji class="g-emoji" alias="test_tube" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f9ea.png"&gt;🧪&lt;/g-emoji&gt; experiments" about why "SQL in your client-side JavaScript is a great idea". The video for that &lt;a href="https://www.youtube.com/watch?v=JyOYqJGrWak"&gt;is on YouTube&lt;/a&gt; and I plan to provide a full write-up soon.&lt;/p&gt;
&lt;p&gt;I also recorded a five minute lightning talk about &lt;a href="https://simonwillison.net/2020/Oct/9/git-scraping/"&gt;Git Scraping&lt;/a&gt; for next week's &lt;a href="https://www.ire.org/training/conferences/nicar-2021/"&gt;NICAR 2021&lt;/a&gt; data journalism conference.&lt;/p&gt;
&lt;p&gt;I also made a few small cosmetic upgrades to the way tags are displayed on my blog - they now show with a rounded border and purple background, and include a count of items published with that tag. My &lt;a href="https://simonwillison.net/tags/"&gt;tags page&lt;/a&gt; is one example of where I've now applied this style.&lt;/p&gt;
&lt;h4&gt;TIL this week&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://til.simonwillison.net/til/til/sphinx_sphinx-ext-extlinks.md"&gt;Using sphinx.ext.extlinks for issue links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://til.simonwillison.net/til/til/postgresql_show-schema.md"&gt;Show the SQL schema for a PostgreSQL database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://til.simonwillison.net/til/til/github-actions_postgresq-service-container.md"&gt;Running tests against PostgreSQL in a service container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://til.simonwillison.net/til/til/django_extra-read-only-admin-information.md"&gt;Adding extra read-only information to a Django admin change page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://til.simonwillison.net/til/til/postgresql_read-only-postgresql-user.md"&gt;Granting a PostgreSQL user read-only access to some tables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="releases-2021-feb-27"&gt;Releases this week&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/flatten-single-item-arrays"&gt;flatten-single-item-arrays&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/flatten-single-item-arrays/releases/tag/0.1"&gt;0.1&lt;/a&gt; - 2021-02-25
&lt;br /&gt;Given a JSON list of objects, flatten any keys which always contain single item arrays to just a single value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/datasette-auth-github"&gt;datasette-auth-github&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/datasette-auth-github/releases/tag/0.13.1"&gt;0.13.1&lt;/a&gt; - (&lt;a href="https://github.com/simonw/datasette-auth-github/releases"&gt;25 releases total&lt;/a&gt;) - 2021-02-25
&lt;br /&gt;Datasette plugin that authenticates users against GitHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/datasette-block"&gt;datasette-block&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/datasette-block/releases/tag/0.1.1"&gt;0.1.1&lt;/a&gt; - (&lt;a href="https://github.com/simonw/datasette-block/releases"&gt;2 releases total&lt;/a&gt;) - 2021-02-25
&lt;br /&gt;Block all access to specific path prefixes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/github-contents"&gt;github-contents&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/github-contents/releases/tag/0.2"&gt;0.2&lt;/a&gt; - 2021-02-24
&lt;br /&gt;Python class for reading and writing data to a GitHub repository&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/csv-diff"&gt;csv-diff&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/csv-diff/releases/tag/1.1"&gt;1.1&lt;/a&gt; - (&lt;a href="https://github.com/simonw/csv-diff/releases"&gt;9 releases total&lt;/a&gt;) - 2021-02-23
&lt;br /&gt;Python CLI tool and library for diffing CSV and JSON files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/sqlite-transform"&gt;sqlite-transform&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/sqlite-transform/releases/tag/0.4"&gt;0.4&lt;/a&gt; - (&lt;a href="https://github.com/simonw/sqlite-transform/releases"&gt;5 releases total&lt;/a&gt;) - 2021-02-22
&lt;br /&gt;Tool for running transformations on columns in a SQLite database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/airtable-export"&gt;airtable-export&lt;/a&gt;&lt;/strong&gt;: &lt;a href="https://github.com/simonw/airtable-export/releases/tag/0.5"&gt;0.5&lt;/a&gt; - (&lt;a href="https://github.com/simonw/airtable-export/releases"&gt;7 releases total&lt;/a&gt;) - 2021-02-22
&lt;br /&gt;Export Airtable data to YAML, JSON or SQLite files on disk&lt;/li&gt;
&lt;/ul&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/crowdsourcing"&gt;crowdsourcing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/postgresql"&gt;postgresql&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/patrick-mckenzie"&gt;patrick-mckenzie&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette"&gt;datasette&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/weeknotes"&gt;weeknotes&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/covid19"&gt;covid19&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vaccinate-ca"&gt;vaccinate-ca&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/personal-news"&gt;personal-news&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jesse-vincent"&gt;jesse-vincent&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="crowdsourcing"/><category term="django"/><category term="postgresql"/><category term="patrick-mckenzie"/><category term="datasette"/><category term="weeknotes"/><category term="covid19"/><category term="vaccinate-ca"/><category term="personal-news"/><category term="jesse-vincent"/></entry></feed>