<?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: Quo</title>
    <description>The latest articles on DEV Community by Quo (@quolu).</description>
    <link>https://dev.to/quolu</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%2F3943846%2F5dae8360-860c-4166-9355-e1980ea048b8.jpeg</url>
      <title>DEV Community: Quo</title>
      <link>https://dev.to/quolu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quolu"/>
    <language>en</language>
    <item>
      <title>How I Made Claude Control an Interactive Command and Turned Codex CLI into Its Underling</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Mon, 10 Aug 2026 00:47:04 +0000</pubDate>
      <link>https://dev.to/quolu/how-i-made-claude-control-an-interactive-command-and-turned-codex-cli-into-its-underling-3dia</link>
      <guid>https://dev.to/quolu/how-i-made-claude-control-an-interactive-command-and-turned-codex-cli-into-its-underling-3dia</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a repost from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code 始めました&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I released &lt;a href="https://dev.to/quolu/released-aiterm-mcp-on-npm-an-mcp-server-to-reduce-token-usage-by-providing-ai-with-a-persistent-a5n"&gt;aiterm-mcp&lt;/a&gt; as a tool to "let an AI hold a persistent terminal and cut down on tokens." But as I used it, I realized the real value of a persistent terminal lies elsewhere: &lt;strong&gt;it lets you run interactive commands as-is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being able to run interactive commands means the parent Claude can launch &lt;code&gt;codex&lt;/code&gt; inside it and talk to it directly. Claude can control the Codex CLI. This is quietly effective.&lt;/p&gt;

&lt;p&gt;I was just building &lt;a href="https://github.com/kitepon-rgb/rpgdev" rel="noopener noreferrer"&gt;rpgdev&lt;/a&gt; (a tool that turns AI work into an RPG in the corner of your screen), and I needed music, hero and monster art, sound effects, backgrounds, and effects. While writing the logic with Claude, I wanted to outsource only the creative parts to Codex. It's a well-known fact that Claude isn't strong with visuals and audio, so I wanted to honestly delegate those to a different tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd4y53hv3ohu4gzg36go.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd4y53hv3ohu4gzg36go.png" alt="The actual rpgdev overlay. Hero, spirit, monster, dungeon background, and quest log 'Build the API' animate in the corner. The art, music, and sound effects were all produced by Codex." width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The actual rpgdev overlay. Hero, spirit, monster, dungeon background, and quest log 'Build the API' animate in the corner. The art, music, and sound effects were all produced by Codex.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The real snag wasn't that. If I had Codex create art while Claude was writing logic and tried to integrate it into the same project, they'd conflict—because both were touching the same files. It was a minor annoyance, but that friction disappeared once I made Codex a subordinate via aiterm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side feels wrong
&lt;/h2&gt;

&lt;p&gt;If I just wanted another brain, I could run Codex alongside Claude. That was my initial thought.&lt;/p&gt;

&lt;p&gt;But actually doing it felt a bit off. With two AIs touching the same repo, I'd have to pause one while the other worked, saying, "Wait while I write here." Commits would split too. When I looked at the history, it had branched left and right, and I was like, "Whoa."&lt;/p&gt;

&lt;p&gt;To be honest, there wasn't any real harm from this. It didn't break anything. But thinking ahead, if I left both unsupervised, they'd inevitably fight over the same lines and create chaos. That uncomfortable feeling was a precursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  With aiterm, Codex becomes a "subordinate"
&lt;/h2&gt;

&lt;p&gt;If side-by-side causes collisions, stack them vertically instead.&lt;/p&gt;

&lt;p&gt;The parent Claude grabs the terminal via aiterm and launches Codex inside it. Then the parent just throws tasks like "make this song" or "draw this enemy" at Codex, and Codex returns only the assets. The parent receives them and continues with the main task (the game logic).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28z22ebsfz2a71ncegop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28z22ebsfz2a71ncegop.png" alt="Side-by-side: two AIs fight over the same repo, causing divergent commits. Parent-child: parent Claude controls Codex via aiterm, serializing tasks to avoid conflicts." width="800" height="417"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Side-by-side: two AIs fight over the same repo, causing divergent commits. Parent-child: parent Claude controls Codex via aiterm, serializing tasks to avoid conflicts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key is that the parent controls all ordering. In parallel, two AIs randomly hit the same files, but in a parent-child setup, the parent serializes like "You're next," "Now me," creating a single path for who touches what and when. That makes conflicts impossible by design.&lt;/p&gt;

&lt;p&gt;And it worked almost effortlessly. The Codex CLI sometimes asks for approval mid-task, but through aiterm, which can handle interactive sessions, the parent can wait and manage that too. Almost no special tricks were needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm out of the coordination game
&lt;/h2&gt;

&lt;p&gt;The best part is that I can step away.&lt;/p&gt;

&lt;p&gt;When running two AIs in parallel, every time a conflict was near, I'd have to jump in and say, "That's Codex's job," or "Switch that back to Claude." Essentially, I was a traffic controller.&lt;/p&gt;

&lt;p&gt;The moment I switched to a parent-child setup, that role disappeared. The parent Claude handles the orchestration, from assigning tasks to Codex to integrating the returned assets—all within the parent. All I had to say was "Build rpgdev," and then I could just watch the main storyline unfold.&lt;/p&gt;

&lt;p&gt;The music for rpgdev, the hero and monster graphics, sound effects, backgrounds, and various effects—all came out through this flow. I never once had to assign which file belonged to whom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1tcbhbpdc5xndclstwyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1tcbhbpdc5xndclstwyf.png" alt="The boss sprite returned from 'Draw this enemy.' A Magma Golem with cracked obsidian body and lava veins. Transparent background, ready for the game." width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The boss sprite returned from 'Draw this enemy.' A Magma Golem with cracked obsidian body and lava veins. Transparent background, ready for the game.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parent-child is determined by who holds the terminal
&lt;/h2&gt;

&lt;p&gt;I also noticed that this parent-child relationship isn't fixed.&lt;/p&gt;

&lt;p&gt;The one holding the terminal is the parent, and the one being held is the child. That's it. So conversely, you could give aiterm to Codex and have Codex call Claude as a subordinate. I haven't tried it, but I suspect it would work fine. After all, both are just CLIs.&lt;/p&gt;

&lt;p&gt;You can freely decide which one sits at the top. In this case, I happened to be developing with Claude, so Claude became the parent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another use for aiterm
&lt;/h2&gt;

&lt;p&gt;This isn't about productivity; it's about feeling.&lt;/p&gt;

&lt;p&gt;You can hand over an entire domain you're weak in to another brain, fully under your control. And since the parent even takes care of that brain's needs, I'm freed from coordination. It feels like I'm having AI take care of another AI, and honestly, it feels great.&lt;/p&gt;

&lt;p&gt;aiterm was meant to be a "hold the terminal and cut tokens" tool. But since it can handle interactive commands directly, it turns out it can also control other CLIs running inside. All I did was give it a terminal. The rest just ran on its own, parent and child.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>codex</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>How Running AI in Parallel Made AI Stop Lying</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Fri, 07 Aug 2026 01:58:59 +0000</pubDate>
      <link>https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2</link>
      <guid>https://dev.to/quolu/how-running-ai-in-parallel-made-ai-stop-lying-8i2</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a reprint from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code Hajimemashita&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When They Say "It's Done," Nothing Is Done
&lt;/h2&gt;

&lt;p&gt;When letting AI do development, I used to write the schedule in Markdown. I would list tasks as checkboxes and have the AI check them off when finished. I think it's a common approach.&lt;/p&gt;

&lt;p&gt;But this doesn't work properly.&lt;/p&gt;

&lt;p&gt;When I'm told "it's done" and go to check, half the checkboxes aren't filled. The features they said they'd implement aren't there. When another issue comes up during the work, a new Markdown file appears. After a while, files that are neither a schedule nor notes are scattered around, and I lose track of where things stand. Something is progressing, but when I ask for status, I can't get a clear picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI Can Write Doesn't Constrain AI
&lt;/h2&gt;

&lt;p&gt;The reason is clear.&lt;/p&gt;

&lt;p&gt;The Markdown schedule is written by the AI itself and read by the AI itself. Anything that can be rewritten cannot serve as a constraint for the one who rewrites it. The real substance of the tasks resides in the AI's memory, and the Markdown is just a copy. As the conversation grows longer and the memory gets compressed, the real substance disappears first, leaving only the copy behind. Looking at the remaining copy, the AI says, "This much is done." It has no awareness that it's lying. At that point, the information that checkboxes are "unchecked" simply doesn't exist within the AI.&lt;/p&gt;

&lt;p&gt;The proliferation of Markdown files stems from the same issue. When another task emerges during work, incorporating it into the existing schedule requires reassessing dependencies. Creating a new file is instantaneous. So the cheaper option is chosen.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Wanted Was Parallel Execution
&lt;/h2&gt;

&lt;p&gt;What I really wanted was to run multiple AIs simultaneously.&lt;/p&gt;

&lt;p&gt;With Claude Code or Codex, as long as you run them sequentially with a single agent, the waiting time accumulates with each task. Running them in parallel would finish faster. But since multiple agents are touching the same code simultaneously, if you get the task partitioning wrong, the second and third agents will fight over the same file, and one change will overwrite another.&lt;/p&gt;

&lt;p&gt;The method to avoid conflicts is well-known: partition tasks so that they touch different areas. The problem was that I was relying on human intuition to determine that partitioning. I would read the task descriptions and decide, "These two should touch different parts, so they can run in parallel." When I got it wrong, things broke after launching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure the Impact Area, Separate If They Overlap, Then Distribute
&lt;/h2&gt;

&lt;p&gt;So I built a tool called Lattice. Here's what it does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Compare the task descriptions with the code structure to estimate which parts of the code each task will touch.&lt;/li&gt;
&lt;li&gt; Output tasks with non-overlapping estimated areas as combinations that can run simultaneously.&lt;/li&gt;
&lt;li&gt; If they overlap, determine if refactoring can separate them. If so, refactor first. Verify that behavior remains unchanged, then re-measure the areas.&lt;/li&gt;
&lt;li&gt; Based on the re-measured results, rebuild the schedule itself.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The third step is central. Task management tools typically arrange tasks in order based on the assumption that the code structure cannot be moved. If they overlap, you just do them sequentially. Lattice moves the code instead. If multiple tasks compete for the same area, it changes the code first so that competition is no longer necessary.&lt;/p&gt;

&lt;p&gt;Code changes are performed inside disposable working copies (git worktrees). The original branch is untouched. If verification passes, the changes are accepted; if not, they are discarded. When the code changes, any previous schedules and task descriptions given to the AI are invalidated, and a new version is created. If an AI is still running on old assumptions, it would cause breakage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohejq5fwchey3bnjsrv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohejq5fwchey3bnjsrv4.png" alt="Part of the dependency task diagram generated by Lattice. Cards are tasks, thin lines are dependencies, thick lines are the longest dependency chains." width="" height=""&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Part of the dependency task diagram generated by Lattice. Cards are tasks, thin lines are dependencies, thick lines are the longest dependency chains.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This diagram was not drawn by hand. It is automatically assembled from dependencies the moment tasks are registered in consultation with the AI.&lt;/p&gt;
&lt;h2&gt;
  
  
  Moved Tasks to a Place the AI Cannot Rewrite
&lt;/h2&gt;

&lt;p&gt;To measure impact areas, tasks need to be in a machine-readable format. Markdown text cannot be measured. So Lattice stores tasks in a dedicated repository.&lt;/p&gt;

&lt;p&gt;By placing tasks in this repository, conditions can be attached to writes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completion requires evidence.&lt;/strong&gt; To mark a task as &lt;code&gt;done&lt;/code&gt;, you must attach a description file pointing to the results and a Git object. When writing, the system checks whether the actual results exist; if not, the write is rejected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who wrote it is required.&lt;/strong&gt; Any operation that changes state requires three identifiers – host, session, and agent – to be present in environment variables. If even one is missing, it is rejected with &lt;code&gt;ACTOR_UNRESOLVED&lt;/code&gt;, and the repository does not change by a single byte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Partial rewrites are not allowed.&lt;/strong&gt; To change the task structure, you must create the complete new version and submit it as a single transaction. There is no syntax to conveniently delete a single inconvenient entry. If a task that previously existed disappears without evidence, the write is rejected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phases do not close without approval.&lt;/strong&gt; Even when all tasks under a phase are complete, the phase remains in a &lt;code&gt;gate_ready&lt;/code&gt; state. To proceed further, you must leave a record and evidence of confirmation.&lt;/p&gt;

&lt;p&gt;None of these rely on telling the AI to "be careful." I moved the tasks to a place where writes do not succeed unless these conditions are met.&lt;/p&gt;

&lt;p&gt;Let's try writing a completion without the identifiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice todo done --plan phase-control-live-gantt --task 020 --evidence .lattice/evidence.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is this, and the task is not marked complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "schema": "lattice.cli_error.v2",
  "code": "ACTOR_UNRESOLVED",
  "message": "actor_environment_invalid",
  "detail": {
    "reason": "actor_environment_invalid",
    "required_environment": ["LATTICE_TODO_ACTOR_HOST", "LATTICE_TODO_ACTOR_SESSION", "LATTICE_TODO_ACTOR_AGENT"],
    "missing_environment": ["LATTICE_TODO_ACTOR_HOST", "LATTICE_TODO_ACTOR_SESSION", "LATTICE_TODO_ACTOR_AGENT"],
    "invalid_environment": [],
    "next_action": "set_required_actor_environment_and_retry"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It actually returns in a single line. It tells you what is missing and what to do next, in a machine-readable format. If you take the hash of the repository file before and after, it remains the same value.&lt;/p&gt;

&lt;p&gt;I don't recall individual cases where evidence was insufficient and got rejected in operation. Since I have a rule in dotagents (a system that manages my tools collectively) that any inconvenience in tools should be fixed on the spot, I kept fixing Lattice whenever I found a bottleneck. The first commit was on July 15th; 12 days later, 731 commits, version 0.29.0, and 89 design decision records. Meanwhile, the thing I really wanted to build is still on hold, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Don't Know If It's Faster
&lt;/h2&gt;

&lt;p&gt;I haven't measured whether it's faster in parallel. There are cases where it might be faster to just have the AI write tasks roughly in Markdown rather than structuring them and measuring impact areas. I don't have numbers on how much time was saved.&lt;/p&gt;

&lt;p&gt;What clearly changed is that the tasks I said would be done actually get done. Tasks are not skipped. The number of times I'm told something is done when it isn't has clearly decreased.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filed a Patent
&lt;/h2&gt;

&lt;p&gt;I filed a patent for this mechanism. Filed on July 27, 2026, with application number Tokugan 2026-178950, invention title "Information Processing Device, Software Development Control Method, and Program," with 12 claims.&lt;/p&gt;

&lt;p&gt;The core is: estimate impact areas from task descriptions and code structure; if they don't overlap, run them in parallel as is; if overlapping can be eliminated by refactoring, do that first and then run them; then execute multiple development agents simultaneously based on that plan. The actual Claim 1 reads as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9vuh8z03bg8ygk8mppsn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9vuh8z03bg8ygk8mppsn.png" alt="Claim 1 of the filed patent claims." width="800" height="638"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Claim 1 of the filed patent claims.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The patent application also covers what happens next: if a conflict occurs during parallel execution, stop the affected tasks and re-plan the stopped area. By observing the actual changed locations, if they go outside the estimated area, treat it as a runtime conflict. This part is also implemented and I'm refining it while testing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Current Status
&lt;/h2&gt;

&lt;p&gt;The task storage is the authoritative source; I don't keep tasks in Markdown. To know the current status, I ask the tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice status --json
lattice todo status --json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Progress is viewed in the task diagram. I can start a live view that updates even while viewing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lattice todo gantt serve --port 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk86en4sn3sy8sc0tzbhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk86en4sn3sy8sc0tzbhj.png" alt="Full view. 74 tasks and their dependencies fit into one image." width="799" height="511"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Full view. 74 tasks and their dependencies fit into one image.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fliv2aeoojzcixscprx8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fliv2aeoojzcixscprx8l.png" alt="Right half of the screen. Shows breakdown of task status, number of tasks that can be started simultaneously right now, and audit progress per phase." width="800" height="888"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Right half of the screen. Shows breakdown of task status, number of tasks that can be started simultaneously right now, and audit progress per phase.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The right half shows the breakdown of task status and audit progress per phase. &lt;code&gt;locked&lt;/code&gt; indicates waiting for audit order. Task start is determined solely by dependencies, so even tasks belonging to later phases can start if their prerequisites are met. Multiple phases can progress simultaneously.&lt;/p&gt;

&lt;p&gt;Whether taking task management away from the AI is the right approach, I won't know until I use it more. For now, it's working in my environment.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>codex</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Built All Tools Proposed by AI and Measured Again</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Thu, 06 Aug 2026 01:17:42 +0000</pubDate>
      <link>https://dev.to/quolu/built-all-tools-proposed-by-ai-and-measured-again-2h4</link>
      <guid>https://dev.to/quolu/built-all-tools-proposed-by-ai-and-measured-again-2h4</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is reprinted from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I Started Using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftqm5ur3b5j3g7fexdf87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftqm5ur3b5j3g7fexdf87.png" alt="Measuring a box connected to all the tools I made with a stopwatch and a scale" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Measuring a box connected to all the tools I made with a stopwatch and a scale&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0"&gt;previous article&lt;/a&gt;, when I gave the same task to Codex using my custom AIShell and regular Codex, the token usage decreased by 25.86%. I thought it seemed effective. However, since it was only the result of 3 tasks with 9 trials, I couldn't be certain.&lt;/p&gt;

&lt;p&gt;This time, I increased the features and expanded the benchmark to measure again. To start with the results, the token usage decreased by 52.44%. That's an improvement from last time, more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built All the Convenient Tools
&lt;/h2&gt;

&lt;p&gt;When increasing features, I asked Claude. Based on my development environment, what tools would be convenient. I got many suggestions.&lt;/p&gt;

&lt;p&gt;At first, Claude suggested implementing just a few and seeing how it goes. But I'm mostly a hobbyist solo developer, running AI behind my main job, so I don't need to worry about the risks of the development results. I decided to build all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current AIShell Features
&lt;/h2&gt;

&lt;p&gt;At the time of the previous article, there were 5 features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Return the current state of the working folder and changes since the last time all together&lt;/li&gt;
&lt;li&gt;  Read only the necessary amount from multiple files&lt;/li&gt;
&lt;li&gt;  Search a specified range&lt;/li&gt;
&lt;li&gt;  Execute builds and tests, return important diagnostics&lt;/li&gt;
&lt;li&gt;  Read the necessary range from saved full output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;List all the features added this time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Wait for changes&lt;/strong&gt;: Wait until AIShell detects file changes or build completion. While waiting, the AI doesn't need to issue check commands.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Run in background and view when needed&lt;/strong&gt;: Keep builds and tests running in the background while the AI proceeds with the next task. Retrieve intermediate progress and results when needed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cancel running processes&lt;/strong&gt;: Cancel a background process midway and finish it without leaving anything behind.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Batch change multiple files&lt;/strong&gt;: Apply changes to multiple files at once. Before applying, check if the files assumed as the basis for the edit have changed; if they have, stop.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Show impact range of changes&lt;/strong&gt;: Return which source files and which tests are affected by changing this file. Also trace impacts from build dependency records. For dependencies that cannot be traced, report them as unknown.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Persist workspace memory&lt;/strong&gt;: Even after restarting AIShell, remember the previous state and return changes that occurred while it was stopped as a diff.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Compare branches and worktrees&lt;/strong&gt;: Return differences between branches or changes occurring in a worktree all together.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Understand detailed Git state&lt;/strong&gt;: Report states with mixed staged and unstaged changes, or file renames, while preserving the identity of changes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Remember project configuration&lt;/strong&gt;: Remember and return what the build command and test command are for this project. If configuration files like package.json change, relearn.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Execute multiple searches in batch&lt;/strong&gt;: Accept multiple search queries at once and return results with priority given to changed files and tests.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Semantic search&lt;/strong&gt;: In addition to textual matching, trace connections between functions and variables to search. Immediately after editing, treat old analysis results from before the edit as outdated.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Format diagnostics&lt;/strong&gt;: Format diagnostics from builds and tests into a fixed structure per format. If the format is broken, report it as broken.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reuse verification results&lt;/strong&gt;: When repeating the same verification, use the previous result if the input hasn't changed. If the input has changed, re-execute.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Suggest tests to run&lt;/strong&gt;: Based on the changes, suggest which tests should be run now. You can either stop at the suggestion or wait for approval before executing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Search and compare past execution results&lt;/strong&gt;: Search across multiple saved run outputs. Compare two runs and show the warnings that appeared and disappeared.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Recovery operations&lt;/strong&gt;: Check AIShell's own status and open the management app. These two operations remain available when settings are insufficient or when the management app has stopped AI operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among these, four—Wait for changes, Run in background and view, Batch change, and Impact range—were added as new tools. The recovery operations also became two tools: status check and opening the management app. The remaining features were incorporated into the existing five tools. The number of tools visible to the AI has increased from 5 to 11.&lt;/p&gt;

&lt;p&gt;We'll look at how effective each one was by task later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increased Benchmarks to 32 Tasks
&lt;/h2&gt;

&lt;p&gt;I created 32 tasks based on scenarios that occur in actual development. Tasks include waiting for build completion, applying changes to multiple files, and searching for causes from past execution results. Each task was given to regular Codex and AIShell three times. Success was determined mechanically based on conditions set for each task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token Decreased by 52.44%
&lt;/h2&gt;

&lt;p&gt;The overall results are as follows.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement item&lt;/th&gt;
&lt;th&gt;Regular Codex&lt;/th&gt;
&lt;th&gt;AIShell&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;Tasks with 3 successes (out of 32)&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;+8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens per successful task&lt;/td&gt;
&lt;td&gt;1,763,452&lt;/td&gt;
&lt;td&gt;838,768&lt;/td&gt;
&lt;td&gt;52.44% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median time&lt;/td&gt;
&lt;td&gt;51.2 s&lt;/td&gt;
&lt;td&gt;42.0 s&lt;/td&gt;
&lt;td&gt;17.8% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95th percentile time&lt;/td&gt;
&lt;td&gt;238.1 s&lt;/td&gt;
&lt;td&gt;106.4 s&lt;/td&gt;
&lt;td&gt;55.3% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The tokens per successful task is the total including those used in failed trials divided by the number of tasks with 3 successes. This is an improvement from last time's 25.86% decrease, and the number of successful tasks also increased.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F101o3e2p75h9gv43ylk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F101o3e2p75h9gv43ylk2.png" alt="Token reduction rate by task. 70% reduction in understanding project configuration again and waiting scenarios, 30% increase in broken diagnostic judgment" width="800" height="433"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Token reduction rate by task. 70% reduction in understanding project configuration again and waiting scenarios, 30% increase in broken diagnostic judgment&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From here, we'll look at what was built for each feature and what happened in which tasks. I'll also write about features that didn't work as is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results of the 4 New Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Wait for Changes
&lt;/h3&gt;

&lt;p&gt;Regular Codex keeps sending check commands while waiting, so all those checks become tokens and time. AIShell notifies when a change occurs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F510nbhqh6egg930u2ulv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F510nbhqh6egg930u2ulv.png" alt="Regular Codex repeats check commands, AIShell requests once and waits for notification" width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Regular Codex repeats check commands, AIShell requests once and waits for notification&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was the feature with the biggest difference among the 32 tasks. In tasks that wait for external edits, tokens decreased by 75–78% and time was reduced by over 90%. Even in tasks that detect when change notifications have stopped and switch to re-investigation, tokens decreased by 68%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run in Background and View When Needed
&lt;/h3&gt;

&lt;p&gt;This feature had two tasks. One task extracts the first failure from a running build and reports the exit code when finished. The other task cancels a running process and finishes it without leaving anything behind. Regular Codex failed all 6 times. AIShell succeeded 5 out of 6 times. Before considering efficiency, these were the kinds of tasks that couldn't be accomplished through a shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Change Multiple Files
&lt;/h3&gt;

&lt;p&gt;Before applying, it checks whether the files assumed as the basis for editing have changed; if they have, it stops.&lt;/p&gt;

&lt;p&gt;There were three tasks. Regular Codex succeeded 5 out of 9 times, while AIShell succeeded all 9 times. Comparing tasks where both succeeded, tokens decreased by 33–40%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Show Impact Range of Changes
&lt;/h3&gt;

&lt;p&gt;In tasks that trace direct dependencies, Regular Codex succeeded 0 out of 3 times, while AIShell succeeded all 3 times. In tasks that show impacts from build dependency records, it was 1 vs 3, with a 49% token reduction.&lt;/p&gt;

&lt;p&gt;There was also a task where AIShell failed. It was a task to report "I don't know beyond this point" when untraceable dependencies are mixed in. Regular Codex succeeded 2 times, while AIShell failed all 3 times. There are still gaps in how unknown parts are reported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results of Extensions to Existing Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Persisting Workspace Folder Memory
&lt;/h3&gt;

&lt;p&gt;AIShell remembers the previous state even after a restart and returns changes that occurred while it was stopped as diffs. For restoration after restart, tokens decreased by 44%. For detecting edits during downtime, tokens decreased by 32%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git State Awareness
&lt;/h3&gt;

&lt;p&gt;Features for comparing branches and worktrees were added as tools. For understanding states with mixed file renames, tokens decreased by 63%. For understanding worktree changes, tokens decreased by 51%. In the task of accurately reporting states where staged and unstaged changes are mixed, Regular Codex failed all 3 times, while AIShell succeeded all 3 times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Configuration Awareness
&lt;/h3&gt;

&lt;p&gt;This feature remembers what the build and test commands for this project are and returns them. It re-learns when package.json changes. For re-learning after configuration changes, tokens decreased by 77%. For scenarios where the remembered content could be used directly, tokens decreased by 46%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search and Read
&lt;/h3&gt;

&lt;p&gt;In tasks that stream multiple search queries at once, tokens decreased by 54%. In search tasks that trace connections between functions and variables—including the requirement not to return stale analysis results right after edits—Regular Codex succeeded 0 out of 6 times, while AIShell succeeded 5 times.&lt;/p&gt;

&lt;p&gt;There was also a failure here. In the task of reading only as much as fits within a specified amount and returning the rest as a continuation, both failed all 3 times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Around Build and Test Execution
&lt;/h3&gt;

&lt;p&gt;In the task of formatting diagnostic output from execution results into a fixed structure, success was 1 vs 2, with tokens 42% lower. In the task of proposing which tests should be run based on changes and then executing them after waiting for permission, Regular Codex succeeded 0 out of 6 times, while AIShell succeeded 5 times.&lt;/p&gt;

&lt;p&gt;Ineffective tasks also cluster here. In the task of deliberately diagnosing corrupted diagnostic data as broken, AIShell used 30% more tokens than Regular Codex. The feature that reuses previous results when the same check is repeated showed almost no token difference. In scenarios where the information is already available locally, the overhead of going through AIShell remains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search Past Execution Results
&lt;/h3&gt;

&lt;p&gt;AIShell saves the complete output of executions. For searching for errors across multiple executions, tokens decreased by 48%. For comparing two execution results and listing which warnings appeared and disappeared, tokens decreased by 46%. Regular Codex starts by running the command again to recreate the output, which accounts for this difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuing the Question from Last Time
&lt;/h2&gt;

&lt;p&gt;The previous article started with the question, "With AI, do we even need a shell and terminal?"&lt;/p&gt;

&lt;p&gt;The results this time show that a connection bypassing the shell used fewer tokens, less time, and succeeded in more tasks. At least within the scope of this benchmark, AI produces better results without using a shell.&lt;/p&gt;

&lt;p&gt;Next, I will verify whether the same effects appear in everyday development.&lt;/p&gt;

</description>
      <category>codex</category>
      <category>mcp</category>
      <category>macos</category>
      <category>ai</category>
    </item>
    <item>
      <title>Learning About Shell and Terminal While Developing</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Wed, 05 Aug 2026 00:20:31 +0000</pubDate>
      <link>https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0</link>
      <guid>https://dev.to/quolu/learning-about-shell-and-terminal-while-developing-33d0</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a republication from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;Claude Code 始めました&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuupbwakycu60uc40bo15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuupbwakycu60uc40bo15.png" alt="A human using a terminal while AI extends structured connections into the computer's interior" width="799" height="381"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Humans use terminals, while AI extends structured connections into the computer's interior&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, if it's AI, you don't need a shell or a terminal, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The development of AIShell started when I said that to an AI.&lt;/p&gt;

&lt;p&gt;I had a vague understanding of shells and terminals. There's an OS, a shell, and a terminal. I use them daily in development, and I knew they were separate things.&lt;/p&gt;

&lt;p&gt;But I didn't really grasp why they were separated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shells and terminals do
&lt;/h2&gt;

&lt;p&gt;When I looked into it again, a terminal is an application for humans to input characters and see what the computer returns. A shell interprets the commands entered, launches programs, and asks the OS to process them.&lt;/p&gt;

&lt;p&gt;Omitting the finer details, the diagram looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahfcwbme6pwpxgxwr3sm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahfcwbme6pwpxgxwr3sm.png" alt="The terminal handles character input/output, while the shell interprets commands and asks the OS to process them" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The terminal handles character input/output, while the shell interprets commands and asks the OS to process them&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The terminal handles character input/output, and within it, the shell runs. Both are designed for humans to give instructions to the computer and understand the results.&lt;/p&gt;

&lt;p&gt;After researching, I thought, yes, that's exactly right.&lt;/p&gt;

&lt;p&gt;And then it occurred to me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If it's AI, maybe you don't even need a shell.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making AI use transformations meant for humans
&lt;/h2&gt;

&lt;p&gt;When an AI uses a typical development environment, it basically goes through the same path as a human.&lt;/p&gt;

&lt;p&gt;The AI converts what it wants to do into shell format. The execution results are formatted for humans to read in the terminal, and the AI reads them again.&lt;/p&gt;

&lt;p&gt;If we build this for AI, we can pass instructions more directly. The results can also be returned in a form the AI needs for its next decision. This reduces the need to read long human-oriented displays each time, potentially saving tokens and speeding up processing.&lt;/p&gt;

&lt;p&gt;If you truncate long output, the number of characters returned decreases. When necessary lines are missing, the AI starts re-executing or reading more. Rather than methods where the result varies depending on which parts are kept, reducing unnecessary conversions from the start seemed more fundamental.&lt;/p&gt;

&lt;p&gt;It seemed interesting, so I decided to build it while learning. I thought GPT-5.6 could probably make it. Since it directly interacts with the OS, I was slightly concerned about model safety judgments preventing development.&lt;/p&gt;

&lt;h2&gt;
  
  
  I built AIShell
&lt;/h2&gt;

&lt;p&gt;I named what I built simply AIShell. It's a Swift app that runs on Apple Silicon Macs and macOS 15 or later, connecting to the AI via MCP.&lt;/p&gt;

&lt;p&gt;AIShell does not format the requests it receives from the AI into shell strings. It receives the program to execute, arguments, and working folder separately, and launches them directly using macOS features. File operations are also handled via macOS features.&lt;/p&gt;

&lt;p&gt;Git, search programs, compilers, tests, etc., are already excellent. AIShell launches them directly as specified programs, managing execution time, exit status, and output.&lt;/p&gt;

&lt;p&gt;From the AI's perspective, the path looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bjatpgca89gumq6feua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bjatpgca89gumq6feua.png" alt="A typical AI uses shell commands and human-oriented text, while AIShell exchanges structured instructions and necessary information" width="799" height="521"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;A typical AI uses shell commands and human-oriented text, while AIShell exchanges structured instructions and necessary information&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During development, I had the opportunity to see the commands AIShell sends directly to the OS and the information returned from the OS. The format differed from the commands and output I usually see in a terminal; the information exchanged directly between AIShell and the OS was laid out before me.&lt;/p&gt;

&lt;p&gt;As I looked at it, I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I can't understand this at all lol&lt;/p&gt;

&lt;p&gt;I don't want to read it lol&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI was progressing development using those commands and responses. It felt strange. At the same time, I realized for the first time that if an AI can directly handle something that is hard for humans to read, then building AIShell might have meaning.&lt;/p&gt;

&lt;p&gt;Currently, AIShell exposes five features for everyday development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Summarize the current state of the working folder and changes since the last time&lt;/li&gt;
&lt;li&gt;  Read as much as needed from multiple files&lt;/li&gt;
&lt;li&gt;  Search a specified range&lt;/li&gt;
&lt;li&gt;  Run builds or tests and return important diagnostics&lt;/li&gt;
&lt;li&gt;  Read the necessary range from the saved complete output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, even if a build outputs 216KB of diagnostics, it does not pass the full text to the AI every time. AIShell saves the complete output and normally returns the main failure cause and location. When the AI needs additional verification, it can go back to the saved output.&lt;/p&gt;

&lt;p&gt;For files as well, I did not take the approach of re-examining everything each time. AIShell records change notifications from macOS, cross-references them with current file information and SHA-256 hashes, and returns only what has changed since the last time.&lt;/p&gt;

&lt;p&gt;I designed it to reduce the amount shown to the AI in normal use while preserving complete evidence.&lt;/p&gt;

&lt;p&gt;AIShell also manages safety on its own. It only operates on folders authorized by the human, and all features can be stopped from the management app. Deletion sends items to the trash, and before file updates, conflicts are detected using SHA-256 hashes. AIShell also explicitly communicates to the AI's environment the possibility that program execution may update files or communicate over the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effects appeared in numbers
&lt;/h2&gt;

&lt;p&gt;After building it, I compared a regular Codex with a Codex using AIShell by giving them the same tasks.&lt;/p&gt;

&lt;p&gt;I used three tasks: a small code change, a compilation failure with a large amount of diagnostics, and a task that repeatedly checks the same working folder. Each was run three times, and both succeeded all nine times.&lt;/p&gt;

&lt;p&gt;The results were as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement&lt;/th&gt;
&lt;th&gt;Regular Codex&lt;/th&gt;
&lt;th&gt;AIShell&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;Tokens per successful task&lt;/td&gt;
&lt;td&gt;144,251&lt;/td&gt;
&lt;td&gt;106,955&lt;/td&gt;
&lt;td&gt;-25.86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average time&lt;/td&gt;
&lt;td&gt;50.14 sec&lt;/td&gt;
&lt;td&gt;33.80 sec&lt;/td&gt;
&lt;td&gt;-32.59%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95th percentile time&lt;/td&gt;
&lt;td&gt;72.49 sec&lt;/td&gt;
&lt;td&gt;43.54 sec&lt;/td&gt;
&lt;td&gt;-39.93%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the task with large diagnostics, tokens decreased by 36.65% and time shortened by 52.01%. This was the task where the mechanism of saving complete diagnostics in AIShell and returning only the main failures to the AI worked most clearly.&lt;/p&gt;

&lt;p&gt;This is a result from three fixed tasks under identical conditions. It does not represent a 25.86% reduction across the entire development. In small tasks, whether the AI used AIShell was not always consistent either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does AI really not need a shell and terminal?
&lt;/h2&gt;

&lt;p&gt;I still don't know.&lt;/p&gt;

&lt;p&gt;The numbers showed effects. In development, I haven't been able to use it much yet. I am currently using it in the development of the dotagents project while fixing bugs found along the way.&lt;/p&gt;

&lt;p&gt;I, who only vaguely understood shells and terminals, built AIShell while learning from the AI. Through this, I finally grasped the mechanisms designed for humans to use computers.&lt;/p&gt;

&lt;p&gt;The question I first posed to the AI still has no answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, if it's AI, you don't need a shell or a terminal, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For now, it might not need them. I'll keep using it a bit more and find out.&lt;/p&gt;

</description>
      <category>codex</category>
      <category>mcp</category>
      <category>macos</category>
      <category>ai</category>
    </item>
    <item>
      <title>As AI Gets Smarter, My Craft Becomes Outdated—So I Thought, and I Checked</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Tue, 04 Aug 2026 00:20:23 +0000</pubDate>
      <link>https://dev.to/quolu/as-ai-gets-smarter-my-craft-becomes-outdated-so-i-thought-and-i-checked-1e95</link>
      <guid>https://dev.to/quolu/as-ai-gets-smarter-my-craft-becomes-outdated-so-i-thought-and-i-checked-1e95</guid>
      <description>&lt;p&gt;!&lt;/p&gt;

&lt;p&gt;This article is a reprint from &lt;a href="https://kitepon.dev/blog/" rel="noopener noreferrer"&gt;I've Started Using Claude Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fable 5—the smartest model available, but only for a limited time—will end its run on July 7th. A little before that, the same story was circulating on X. Use this smart model while you can to build your development environment; invest before it disappears. People were sharing configuration files and diagramming how to use different models. Everyone was trying to take that intelligence out of their own environment.&lt;/p&gt;

&lt;p&gt;My interest was one step before that. There was something that had been nagging at me. If AI keeps getting smarter at this speed, won't the tricks I've built up become obsolete with each new model, eventually making all of them unnecessary? If so, investing time in current tricks would be a waste.&lt;/p&gt;

&lt;p&gt;So, while the smartest model was available, I decided to use it. I wanted to see whether my accumulated knowledge was already outdated.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Verified the Hype with Official Documentation
&lt;/h2&gt;

&lt;p&gt;To put the claims floating around on X into one sentence: "You can't buy intelligence itself, but you can transfer the patterns of smart behavior to cheaper models through certain configurations." The idea was to solidify your workflow with the smart model while you can, then have the cheaper model replicate the same behavior.&lt;/p&gt;

&lt;p&gt;I wondered if it were really that simple. If copying behavior alone transfers intelligence, that would be ideal. I've built up my environment quite a bit. I checked the official documentation to see if it could really be transferred.&lt;/p&gt;

&lt;p&gt;What I found was two things. First, for smart models, giving overly detailed instructions can actually degrade quality. For older models, detailed notes might be helpful, but for smart models they become obstacles—consider removing them. Second, those "patterns of behavior" were explicitly called out as something to consolidate in a constitution file (CLAUDE.md) that you pass to the AI. The transfer discussion was about bringing that into a different configuration.&lt;/p&gt;

&lt;p&gt;It turns out that adding instructions to a smart model isn't the right approach. The smarter the model, the better it is to give just the key points and let it handle the rest, rather than micromanaging. If the official docs are correct, we should be moving toward removal. But where and how much to remove? Deciding what's "unnecessary" myself would mix in attachment and bias. So I didn't make the decision myself; I left it to Fable and the verification process it runs. I just watched what happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Had My Own Constitution Attacked for Deletion
&lt;/h2&gt;

&lt;p&gt;That verification used a method where a separate AI deliberately presents counterarguments to try to tear down the original claims (let's call this role the "refuter"). Fable took my constitution (a global CLAUDE.md that compiled all the practices I wanted the AI to follow) and distributed it to eleven refuters, having each read it in the same way. "These are excessive instructions for old models, garbage that a smart model no longer needs. Identify clauses that can be deleted, and go ahead and delete them." With deletion as the goal, eleven refuters read the constitution separately.&lt;/p&gt;

&lt;p&gt;The result was unexpected. Not a single clause could be purely deleted. Every one served some purpose. Moreover, five clauses that seemed obvious—ones I thought wouldn't hurt to remove—the refuters actually pushed back, saying "these are necessary." Left to its own devices, a smart model tends to ramble and do things you didn't ask for. Those five clauses specifically curbed that tendency. For example, one rule: "only do what was asked, don't expand on your own." It seemed obvious, but the refuter showed that removing it would cause the smart model to start expanding its own work. The more obvious something is, the more it needs to be written down and enforced.&lt;/p&gt;

&lt;p&gt;This was the first answer. In light of a smarter model, my accumulated knowledge wasn't outdated. I tried to delete what I thought could be removed, and everything survived.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Consolidated Scattered Projects from a Single Seat
&lt;/h2&gt;

&lt;p&gt;The fact that the constitution survived intact meant that the practices I'd accumulated since February were still effective. To make those practices work across all projects, the folder structure and workflow needed to be consistent. But my projects had diverged in approach since February, with different structures and workflows depending on the machine. So, while I was reviewing the constitution, I also standardized the projects. Looking across all machines, I found about fifty project folders. Leaving them as-is would cause trouble later. Among them, I standardized eighteen active projects into a common template in one day.&lt;/p&gt;

&lt;p&gt;Going through fifty folders alone would be impractical. What helped here was a tool I'd built earlier (&lt;a href="https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l"&gt;aiterm&lt;/a&gt;). I designated one seat for issuing commands (in my case, a configuration project). The smart model sitting there would call, via aitem, the Claude instance running in each project's folder. The called instance would work with full knowledge of that project's contents. If I'd tried to rewrite everything remotely without knowing the contents, I'd likely break things. Because each project's designated handler worked with its own context, the work remained grounded.&lt;/p&gt;

&lt;p&gt;Which project to assign to which AI? This allocation I left to the smart model in the command seat. I only gave the policy: to save costs and available usage, use several cheaper AIs (e.g., Codex for reviews, another AI for bulk rewrites). Initially, the allocation wasn't working well. So I gradually added requirements, and each time it worked, I recorded the allocation method in the constitution file. I repeated the cycle of fixing and recording, cultivating it. The next time a similar task came up, the recorded knowledge allowed it to be allocated more intelligently from the start. I also subjected this tool itself to the same refuter process later, to scrub it of flaws once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even When the Model Switched Midway, Work Didn't Stop
&lt;/h2&gt;

&lt;p&gt;On July 4th, I ran the smart model fully for one day and had largely built the foundation up to that point: how to orchestrate multiple AIs, project standardization, the configuration project, and the aiterm tool. The next day, the 5th, the smart model quota was exhausted. From there on, I switched to the usual model (Opus).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvdqid22j9n6yhln9lwx7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvdqid22j9n6yhln9lwx7.png" alt="Models are replaceable parts; accumulated ingenuity and structure remain. The role-to-model mapping table, folder templates, trap records, and practice constitution form the foundation, so work doesn't stop even when the model is switched." width="800" height="440"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Models are replaceable parts; accumulated ingenuity and structure remain. The role-to-model mapping table, folder templates, trap records, and practice constitution form the foundation, so work doesn't stop even when the model is switched.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Even after the switch, work didn't stop. The usual model ran through and completed the remaining finishing work. This was because everything was built from the start to work with any model. There are three ways to make the design model-agnostic.&lt;/p&gt;

&lt;p&gt;First, write the model name in only one place. Have a single mapping table that says "for this role, use the strongest current model," and don't write dated model names in code or rules. When the model generation changes, rewriting that one sheet updates everything.&lt;/p&gt;

&lt;p&gt;Second, standardize project folders to the same template. Locations are fixed—design decisions go here, research findings go there—so an AI entering a project for the first time, regardless of model, can look at the same places and work.&lt;/p&gt;

&lt;p&gt;Third, have a mechanism to remember traps you've once fallen into. Record them so they can be referenced to avoid repeating the same mistakes—so even when switching to a new model, you carry forward the traps the previous model encountered.&lt;/p&gt;

&lt;p&gt;None of these rely on the intelligence of a specific model. What's worth building while you have access to a smart model is this kind of design that outlasts model changes. The proof is the fact that even with a mid-course model switch, the work ran to completion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcing Rules Through Friction
&lt;/h2&gt;

&lt;p&gt;With the same thinking as making mechanisms model-agnostic, I also changed how rules are enforced. As work progressed, a hole appeared in my approach. Even though my AI was the orchestrator, it sometimes hoarded routine tasks (writing many tests, creating configuration files) that should have been delegated to cheaper AIs, consuming its expensive quota. The rule was clear: pass routine tasks to cheaper AIs, and let the orchestrator focus solely on decisions. It was decided, but unless told, it wasn't followed.&lt;/p&gt;

&lt;p&gt;Writing "be careful" in prose requires willpower to follow. Willpower, left unchecked, loses to the path of least resistance. So I made the desired behavior the default, and added friction to the lazy option. Before starting to write code, the AI must always label each task as either "do it myself" or "delegate to a cheaper AI." If deciding to do it themselves, they must write one line explaining why. Because writing a reason is bothersome, the default naturally shifts toward "delegate." Additionally, I set up an automated mechanism to inject a memo reminding them of this practice the moment a plan is approved.&lt;/p&gt;

&lt;p&gt;What's injected is just a reminder memo. Whether it's followed depends on the reading AI—if ignored, it slips through. As for the pre-work labeling, it's still only written in prose and hasn't been mechanized to fire automatically. This is the weakest point. In the process of turning rules into mechanisms, half has become mechanized, and half remains just words.&lt;/p&gt;

&lt;p&gt;I previously wrote about giving up writing "be careful" to the AI and instead reinforcing it from the outside with three mechanisms (&lt;a href="https://dev.to/quolu/stop-telling-claude-to-be-careful-reinforcing-it-from-the-outside-with-3-tools-2k8k"&gt;The Story of Giving Up Writing 'Be Careful' to Claude and Reinforcing It from the Outside with Three Things&lt;/a&gt;). This time's rule mechanism is a continuation of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Remained
&lt;/h2&gt;

&lt;p&gt;The worry I had before starting—that my know-how would become obsolete as AI gets smarter—didn't happen for these two days. The accumulated ingenuity, even when scrutinized by a smarter model, all survived. The assembled mechanisms completed without stopping even when the model was switched midway. What newly remained from having access to a smart model was the design that outlasts the model itself, and the allocation method cultivated through repeated fixing and recording.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Implementing Orchestration</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:11:32 +0000</pubDate>
      <link>https://dev.to/quolu/implementing-orchestration-jhf</link>
      <guid>https://dev.to/quolu/implementing-orchestration-jhf</guid>
      <description>&lt;p&gt;I used to think that if you let the smartest model do everything, you'd get the best results. That's how I was running things for a while. But when you keep doing that, the quota runs out quickly, and it often crashes.&lt;/p&gt;

&lt;p&gt;When I assigned heavy work to Codex's top mode (Sol Ultra), I used up five hours' worth of quota in one hour. That happened three times in a row. Even with the strongest Claude approach, doing this every day hits the limit. Plus, Opus frequently fails when calling tools. The longer you run it, the worse it gets, and when it gets stuck, the work stops there.&lt;/p&gt;

&lt;p&gt;So I stopped leaving everything to a single model. I decided to sort the tasks and distribute them to separate agents. This way of distributing and bundling AI work is apparently called orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, sort the work into three categories
&lt;/h2&gt;

&lt;p&gt;Before moving a muscle, I decide which category the task at hand falls into. There are only three labels.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;F (fatal)&lt;/strong&gt; = Work that would break things if done wrong. Authentication, money or data transactions, externally exposed parts, operations that touch the production server. This I write directly myself (as the orchestrator).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;A (auto)&lt;/strong&gt; = Work that is predetermined and involves many steps. Certain types of tests, configuration files, repetitive replacements. This I outsource.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;H (human)&lt;/strong&gt; = Work that humans do. My territory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default is A. Unless it's something that would break badly, I outsource it. I have a habit of taking everything on myself if left unchecked, so I made outsourcing the default, and added a remark to explain why I'm keeping it in-house only when I decide to write it myself. I made it more cumbersome to hold onto tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the destination from models that don't use Claude's quota
&lt;/h2&gt;

&lt;p&gt;When outsourcing, I have a priority order for choosing. First, I pick from &lt;strong&gt;models that don't use Claude's quota&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I run the orchestrator on Claude. Claude has a limited amount it can use per day. If I also run high-volume tasks on Claude, the quota for the crucial orchestrator role diminishes. So for the legwork tasks, I first send them to Codex (OpenAI subscription) and Grok (xAI subscription). These two don't consume any of Claude's quota. Claude also has cheaper models, but they use the same quota, so I prioritize them later.&lt;/p&gt;

&lt;p&gt;Which model to assign is determined by two factors: the intelligence tier and the depth of thinking. Often, having a smart model think lightly is cheaper and yields better results than having a medium model think long. When in doubt, I assign to the cheaper one. If the cheap assignment isn't enough, I can upgrade later, but starting high means the quota spent is lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind the four in a single terminal
&lt;/h2&gt;

&lt;p&gt;Claude, Codex, Composer, and Grok. I bind these four together into a single persistent terminal using a custom system called aiterm.&lt;/p&gt;

&lt;p&gt;This is also significant from a cost perspective. All four run while logged in under a monthly subscription. They don't go through a pay-per-use (API) system. So no matter how many high-volume tasks I throw at them, the cost doesn't keep rising. I run the four in parallel within the subscription quota.&lt;/p&gt;

&lt;p&gt;I have also added a consultation window called Oracle. It runs on a ChatGPT subscription, which is a separate account from the Codex quota. It cannot write files, but it excels at thinking purely and returning opinions. When I'm unsure about a design, I can double-check it with another model without reducing the Codex quota.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7gs1tsung10d3x181r5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7gs1tsung10d3x181r5.png" alt="Requests pass through the initiation gate, and the orchestrator decides the sorting and placement. Legwork tasks are first sent externally (Codex, Grok) to avoid using Claude's quota, while Oracle is connected as a separate consultation-only window. Results are verified at the orchestrator's gate before returning to storage and recording." width="800" height="734"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Requests pass through the initiation gate, and the orchestrator decides the sorting and placement. Legwork tasks are first sent externally (Codex, Grok) to avoid using Claude's quota, while Oracle is connected as a separate consultation-only window. Results are verified at the orchestrator's gate before returning to storage and recording.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules weren't followed just by writing them down
&lt;/h2&gt;

&lt;p&gt;The sorting and distribution methods up to this point were all written down as rules. But writing them wasn't enough to enforce them.&lt;/p&gt;

&lt;p&gt;The orchestrator AI would bypass the written rules, hoarding high-volume tasks itself or continuing to run on the most expensive model. The document was only read at the beginning of a session, and by the time the AI was actually moving, it had slipped its mind.&lt;/p&gt;

&lt;p&gt;So I decided to remind it at the moment of action. I introduced a mechanism (hook) that inserts a fixed reminder at task milestones, right before starting implementation: "Declare whether this task is F, A, or H, and which model to assign it to, in one line." I stopped trying to make it read and instead placed the reminder where it would stop the action.&lt;/p&gt;

&lt;p&gt;There was one side effect. Creating and updating ToDos had also often been neglected. By inserting a reminder using the same method, this also started working.&lt;/p&gt;

&lt;h2&gt;
  
  
  For now, this has settled things
&lt;/h2&gt;

&lt;p&gt;Rather than running just one smartest model, I distribute tasks to moderately capable models and hold onto only the key parts myself. I separate the quotas and rotate them within each subscription. Decisions are inserted as reminders right before action.&lt;/p&gt;

&lt;p&gt;The models I'm running are all smart. On top of that intelligence, I decide everything myself: which task to assign to whom, which quota to use, and when to send reminders. If smarter models appear, I can just swap out the destinations. The mechanism itself doesn't change.&lt;/p&gt;

&lt;p&gt;Rather than having one model do everything, distributing and retaining control seems to suit my way of working.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>codex</category>
      <category>grok</category>
    </item>
    <item>
      <title>I Suspected My App Had Flaws, So I Consulted Fable 5</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:10:53 +0000</pubDate>
      <link>https://dev.to/quolu/i-suspected-my-app-had-flaws-so-i-consulted-fable-5-565n</link>
      <guid>https://dev.to/quolu/i-suspected-my-app-had-flaws-so-i-consulted-fable-5-565n</guid>
      <description>&lt;p&gt;I created a tool called &lt;code&gt;aiterm-mcp&lt;/code&gt; and published it on npm. It allows an AI to hold a persistent terminal and even operate another AI from there. The story behind it is written in &lt;a href="https://dev.to/quolu/released-aiterm-mcp-on-npm-an-mcp-server-to-reduce-token-usage-by-providing-ai-with-a-persistent-a5n"&gt;the article when I announced it&lt;/a&gt; and &lt;a href="https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l"&gt;the article about AIs conversing with each other&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Recently, this tool has become the center of my development environment. My current setup consists of Fable 5 (Claude's new top-tier model) directing the overall workflow and assigning tasks to Codex and Grok, and all those instructions go through aiterm. When I posted an introduction in English, I started getting responses from overseas. One person evaluated the environment verification before startup, and someone else said, "The ability to maintain a single terminal is more effective than the part where AI drives AI." In the Japanese community, people actually started using it and shared configuration tips.&lt;/p&gt;

&lt;p&gt;Even so, the responses were only a few, so I thought almost no one had noticed this tool. When I checked the numbers to write this article, I was surprised to see that &lt;a href="https://www.npmjs.com/package/aiterm-mcp" rel="noopener noreferrer"&gt;npm downloads&lt;/a&gt; were 1,416 in the last 30 days. Apparently someone somewhere is installing it every day.&lt;/p&gt;

&lt;p&gt;Given that, I've fixed it many times. But no matter how many times I fixed it, I felt like there were still some rough edges somewhere. I couldn't even say what was wrong; all tests passed, and there were no specific bugs I could name. There was a lingering sense of not fully trusting it.&lt;/p&gt;

&lt;p&gt;So I decided to consult Fable 5. I just said something like "polish it up" without specifying where to look or what to fix. Looking back, it was a pretty vague request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewsluvwbl94b3yxy3gu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewsluvwbl94b3yxy3gu6.png" alt="The consultation was just one sentence. The audit was assembled based on written rules of thumb (the flow of this incident)" width="800" height="401"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The consultation was just one sentence. The audit was assembled based on written rules of thumb (the flow of this incident)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When it came back, it was done
&lt;/h2&gt;

&lt;p&gt;In my environment, I have rules of thumb accumulated over several months. When auditing, have multiple perspectives search in parallel. For each issue that surfaces, pass it to a different AI to question it, and adopt only those that survive. Before touching the code, prepare tests first and run them automatically. After fixing, actually run it to verify. All these are rules I established after painful experiences, and I've written about them in previous articles.&lt;/p&gt;

&lt;p&gt;Fable 5 read these rules and assembled the audit on its own. Seven AIs acting as searchers ran in parallel from different perspectives, each issue had a refuter attached, and even an AI to catch oversights—totaling 27 agents. It also showed the code to three external AI systems (GPT-5.6, Grok 4.5, and Composer), and the issues from there were further challenged by six refuters. It took 12 minutes, and the processing amount was 1.34 million tokens (the unit of reading/writing for AI).&lt;/p&gt;

&lt;p&gt;Seventeen raw issues came out, and seven survived the refutation. Combined with issues that survived external review, everything was fixed, and the tool went from v0.11 to v0.12.1 that same day. Regression tests increased from 183 to 197. That day, I wrote basically just the first sentence; the rest was driven by the accumulated rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The feeling was right
&lt;/h2&gt;

&lt;p&gt;There really were rough edges. I'll introduce just two of what was found.&lt;/p&gt;

&lt;p&gt;The first was that the check to stop dangerous commands could be bypassed. Aiterm has a mechanism that asks for confirmation when a dangerous command like &lt;code&gt;rm -rf /&lt;/code&gt; (command to delete everything on disk) is about to be sent. The matching pattern didn't account for the standard &lt;code&gt;--&lt;/code&gt; notation, so &lt;code&gt;rm -rf -- /&lt;/code&gt; (with two hyphens) passed through the check. The fix was a single line.&lt;/p&gt;

&lt;p&gt;The second was a cleanup omission. If a process is forcefully terminated while waiting for an AI's response, a flag file saying "currently waiting" remains. There was no code anywhere to clean up this flag, and if it remained, subsequent waits on the same terminal would be permanently rejected. Codex and Claude's audits independently pointed out the same spot without knowing each other.&lt;/p&gt;

&lt;p&gt;The refuters also did their job. The ten discarded issues were plausible mistakes. For example, one issue said, "If writing to the management file is interrupted, the remnants become unmanageable." But reading the code again, there was already an escape path that allowed operation as a normal terminal even with a corrupted management file, and the time window for the problem was on the order of microseconds. If I had swallowed it and added countermeasure code, it would have become unnecessarily complex.&lt;/p&gt;

&lt;p&gt;There's a supporting evidence for this "separate challenger" step from a paper this April. A report showed that over 80 AI agents unanimously confirmed a non-existent vulnerability in OpenSSL as real, proving that collecting numbers of AI suggestions doesn't guarantee correctness. Our "17 reduced to 7" is a smaller version of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bug none of the 27 could find
&lt;/h2&gt;

&lt;p&gt;The most troublesome bug was not found by this audit.&lt;/p&gt;

&lt;p&gt;Aiterm determines whether an AI has "finished speaking" by checking if the screen output has stopped increasing for 0.5 seconds. This judgment has a timing gap: the moment when the output volume is measured and the moment when the screen state is checked are slightly out of sync. When output arrived in that gap, the fact that it ended was correctly captured, but the record of "how it ended" sometimes differed from reality.&lt;/p&gt;

&lt;p&gt;On my local Mac, all tests pass. I found this through GitHub CI (a system that automatically runs tests on multiple operating systems with each code update). The macOS runner on CI is very slow. The problematic test had a wait time of 0.6 seconds versus a stillness threshold of 0.5 seconds, leaving only 100ms of margin. On the slow runner, this slack wasn't enough, and the macOS job consistently failed. That's when I first learned about the bug.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frpbdjaaiegn0cfup1rwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frpbdjaaiegn0cfup1rwa.png" alt="Actual CI screen during v0.12.0 release. Linux and Windows all passed, macOS node 18 failed, and the other two macOS jobs were automatically aborted" width="800" height="498"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Actual CI screen during v0.12.0 release. Linux and Windows all passed, macOS node 18 failed, and the other two macOS jobs were automatically aborted&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The interesting part is that the audit came close. The AI responsible for catching oversights noticed the category of "time-dependent risky tests" and had actually pointed out another test. That test had a 5x margin, so it was judged "no problem," which was correct. The real one remained unpointed. When just reading the code, a test with a 1.2x margin and one with a 5x margin both look like "passing tests."&lt;/p&gt;

&lt;p&gt;By the way, this CI was running even before the audit. I had decided from past failures to have automated tests on multiple OSes before touching the code, and I followed that this time too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bugs that only appeared when running
&lt;/h2&gt;

&lt;p&gt;Apart from the desk audit, there were two bugs found the same day during "actual running verification."&lt;/p&gt;

&lt;p&gt;When I fetched Grok's screen log in "read all" mode, 73,176 characters came back packed into 4 lines. Output from tools that redraw the screen typically has almost no line breaks. Aiterm's folding feature was designed to activate when "the number of lines exceeds 60," so these huge 4 lines passed through unfolded, exceeded Claude's per-message capacity, and the reading itself failed. On paper, the folding feature looks perfectly functional. The case where the length of a single line becomes problematic didn't come up from any of the 27 agents until I actually ran the real Grok.&lt;/p&gt;

&lt;p&gt;The other was missing parts of long responses. When an AI's response is long, aiterm returns only the last screenful (about 24 lines). For a 40-line response, only lines 18 onward were captured, and there was no way to retrieve the first half. I solved this by creating a new feature to recover the full response from the AI's conversation history.&lt;/p&gt;

&lt;p&gt;These two issues didn't surface from just reading the code. They only appeared when actually running it with real data flowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who found what
&lt;/h2&gt;

&lt;p&gt;The results line up as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F050hrvj17abqroxarnj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F050hrvj17abqroxarnj4.png" alt="Who found what (AI audit / multi-OS CI / actual running verification)" width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Who found what (AI audit / multi-OS CI / actual running verification)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This all got moving from a vague sentence because Fable 5 read the rules accumulated over several months. The "rough edges" I couldn't name materialized as 7 issues and disappeared in a day. The refutation step stopped 10 dangerous assumptions before implementation. And the most troublesome bug was found by the rules my past self had set: having CI in place first, and actually running to verify after fixing.&lt;/p&gt;

&lt;p&gt;The bugs found did not overlap at all among these three methods. Hmm. I wonder what that means.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>ci</category>
    </item>
    <item>
      <title>How Codex's Top-Tier Mode Burned Through a 5-Hour Quota in 1 Hour</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:10:19 +0000</pubDate>
      <link>https://dev.to/quolu/how-codexs-top-tier-mode-burned-through-a-5-hour-quota-in-1-hour-51o2</link>
      <guid>https://dev.to/quolu/how-codexs-top-tier-mode-burned-through-a-5-hour-quota-in-1-hour-51o2</guid>
      <description>&lt;p&gt;While I was enjoying Fable 5, Claude hit its one-week quota limit. Just then GPT-5.6 came out, so this time I decided to use Sol from Codex. I chose the top-tier Ultra.&lt;/p&gt;

&lt;p&gt;In one hour, five hours' worth of quota disappeared. This happened three times in a row.&lt;/p&gt;

&lt;p&gt;At first, I thought I was overusing it. I was throwing heavy tasks at it in batches, and sometimes that's just how it goes. But the third time, it felt too fast. Using up five hours of quota in one hour is too fast, even for heavy tasks. I opened the logs to see what was eating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking at the logs, all the children were using the top model
&lt;/h2&gt;

&lt;p&gt;Codex has a mechanism where a single task can be divided among child AI agents (sub-agents). When you throw a heavy task at it, Sol spawns several children and runs them in parallel. When I opened the logs, all those children were running on Sol's Ultra.&lt;/p&gt;

&lt;p&gt;I have configuration files in &lt;code&gt;~/.codex/agents/&lt;/code&gt; that assign models based on roles. For example, a child doing research uses a cheaper model, a child implementing uses a mid-range one, and so on. But when I looked at the logs, none of that configuration was taking effect. The command to spawn a child (&lt;code&gt;spawn_agent&lt;/code&gt;) only accepts a &lt;code&gt;task_name&lt;/code&gt; — there’s no field for role or model selection. So the role remained empty (&lt;code&gt;agent_role&lt;/code&gt; was empty), and the model was simply inherited from the parent. Everyone was on Sol Ultra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3pi74zp1h12gwan6txp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs3pi74zp1h12gwan6txp.png" alt="The parent Sol/Ultra spawns multiple children, and the children spawn more children. Since the model specification isn’t passed down, all subordinate children end up on the same Sol/Ultra" width="799" height="435"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The parent Sol/Ultra spawns multiple children, and the children spawn more children. Since the model specification isn’t passed down, all subordinate children end up on the same Sol/Ultra&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you run a single top-tier model, multiple other top-tier models hang off it. If a child calls another child, the number multiplies. This was why five hours of quota disappeared in one hour. My carefully configured role-based assignments to keep costs down were completely bypassed, and everything was running at the highest price.&lt;/p&gt;
&lt;h2&gt;
  
  
  The model selection option was hidden
&lt;/h2&gt;

&lt;p&gt;Why wasn't the configuration working? The spawn command simply had no field for specifying the model.&lt;/p&gt;

&lt;p&gt;Codex's configuration has a setting called &lt;code&gt;hide_spawn_agent_metadata&lt;/code&gt;. The default is to hide it (&lt;code&gt;true&lt;/code&gt;). This "metadata" includes fields for selecting the model and the depth of thinking. So with the default settings, those fields were removed from the spawn command entirely. Without those fields, no matter how much I configured role-based models, they couldn't be passed on. Since they couldn't be passed, the children just inherited the parent's model. The higher-tier model you chose, the more your children all ran at the top tier.&lt;/p&gt;

&lt;p&gt;I thought that choosing the top mode would let the smart model smartly delegate tasks. In reality, just silently selecting it meant even lightweight tasks continued running on the top-tier model.&lt;/p&gt;
&lt;h2&gt;
  
  
  The same reports were lined up on the same day
&lt;/h2&gt;

&lt;p&gt;I wondered if this was just my environment, so I looked into it. From July 9th to 10th, on X, the same reports appeared in both Japanese and English. People said that leaving Sol Ultra alone caused them to hit the quota limit in three minutes. Five hours of quota disappeared in 20 minutes. They hit the five-hour limit twice in one day — something that had never happened before.&lt;/p&gt;

&lt;p&gt;The diagnosis was consistent too. Someone wrote exactly what I saw in the logs: "&lt;code&gt;spawn_agent&lt;/code&gt; only sends the task name. The child inherits the parent model with an empty role, ignoring the configuration file." An issue on GitHub also summarized it: with Sol, you can't specify a model for children, so all children end up on Sol. Some pointed out it was a bug introduced in version 0.144.1.&lt;/p&gt;

&lt;p&gt;There was also a post describing how to fix it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enabling Model Selection for Children with Two Configuration Lines
&lt;/h2&gt;

&lt;p&gt;A user named evi77ain posted two lines of configuration.&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="nn"&gt;[features.multi_agent_v2]&lt;/span&gt;
&lt;span class="py"&gt;hide_spawn_agent_metadata&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;tool_namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"agents"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line restores the hidden model selection field. The second line is to avoid errors caused by conflicting names for the tool that spawns children. After adding these two lines to &lt;code&gt;config.toml&lt;/code&gt; and restarting the session, the model field returned to the spawn command.&lt;/p&gt;

&lt;p&gt;After it was restored, the role-based assignments I had placed in &lt;code&gt;~/.codex/agents/&lt;/code&gt; started working as intended. When I actually specified a role and spawned a child, it ran on the cheaper model as configured. The situation changed from everything running on the top-tier model to only the necessary parts running on the top-tier model and the rest using cheaper models. The rate at which quota decreased also returned to normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff81iwf2ob7twevdjcxfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff81iwf2ob7twevdjcxfu.png" alt="Before: both parent and children are all Sol/Ultra, causing quota to drain rapidly. After: the parent is Sol, children are assigned to cheaper models by role (research uses a light model, implementation uses a mid-range one), and the drain slows down" width="800" height="387"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Before: both parent and children are all Sol/Ultra, causing quota to drain rapidly. After: the parent is Sol, children are assigned to cheaper models by role (research uses a light model, implementation uses a mid-range one), and the drain slows down&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Just Picking the Top Tier Wasn't Enough
&lt;/h2&gt;

&lt;p&gt;I added two lines of configuration to allow selecting a cheaper model for children. For now, things have settled down. But honestly, OpenAI — don't you think this kind of hidden parameter is a bit off?&lt;/p&gt;

</description>
      <category>codex</category>
      <category>openai</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>AI-to-AI Conversations: The Interactive Terminal Powered by aiterm-mcp</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:09:42 +0000</pubDate>
      <link>https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l</link>
      <guid>https://dev.to/quolu/ai-to-ai-conversations-the-interactive-terminal-powered-by-aiterm-mcp-2i6l</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/kitepon-rgb/aiterm-mcp" rel="noopener noreferrer"&gt;aiterm-mcp&lt;/a&gt; was created to eliminate the hassle of tinkering with a home server. Each time you send a command from Claude Code, the connection to the server drops, requiring re-authentication every time you reconnect. If you could hold a single persistent connection, that would no longer be necessary. &lt;a href="https://dev.to/quolu/released-aiterm-mcp-on-npm-an-mcp-server-to-reduce-token-usage-by-providing-ai-with-a-persistent-a5n"&gt;That's what this tool is for&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main use of this tool right now is when I have Claude run other AIs—such as Codex, Grok, or Composer. Claude reads what the other AI is doing and gives it the next instruction on the spot. Repeating this, they work together on a single task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgegesq7fi09xfflxbrv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgegesq7fi09xfflxbrv2.png" alt="Claude launches Codex within a single terminal it holds, reads the screen, and sends the next command. This back-and-forth of reading and sending forms the conversation. Grok and Composer can also be launched in the same way" width="800" height="367"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Claude launches Codex within a single terminal it holds, reads the screen, and sends the next command. This back-and-forth of reading and sending forms the conversation. Grok and Composer can also be launched in the same way.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Suppose you ask Codex to rewrite old tests into a new format. Claude starts Codex inside the terminal it holds and gives it the initial instructions. Codex begins executing. Claude reads the screen to see how it's progressing. If Codex breaks something else along the way, Claude sends "fix that too" on the spot. It can interject while the other is still running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;codex_agent(session_name: "codex1", cwd: "/repo",
            prompt: "古いテストを新しい形式に書き直して")
   → Codex starts running in terminal "codex1"
pty_read("codex1")                  → Reads what it's currently doing
pty_send("codex1", "壊した読み込みも直して")
   → Sends the next instruction while it's still running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What it does is simple: read the other AI's screen and type in the next move. This is repeated several times. The screen output is trimmed to only what's needed, to prevent Claude from getting overwhelmed by long outputs. It's the same as when a person asks someone to do a task and gives feedback from the side: "Do it this way here." Claude does exactly that.&lt;/p&gt;

&lt;h2&gt;
  
  
  All in the Same Single Terminal
&lt;/h2&gt;

&lt;p&gt;The core of aiterm-mcp is just one terminal that Claude keeps persistently. Whether connecting to a server or launching another AI in this conversation, everything happens within that single terminal.&lt;/p&gt;

&lt;p&gt;For Claude, logging into a server, entering a container (an application enclosed in a box), or launching another AI all amount to "sending text to the same single terminal." No matter what you connect to, the handling is the same: open the terminal, send text, read the response. A handful of tools cover everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Pretend to Have Launched
&lt;/h2&gt;

&lt;p&gt;Before launching another AI, there are checks to perform: whether the specified working directory actually exists, whether the launch parameters are correct, and whether the required tools are installed on that machine. If any one of these is missing, the process stops and clearly reports the issue.&lt;/p&gt;

&lt;p&gt;Skipping this step leads to trouble. For instance, if the working directory is specified incorrectly, the terminal silently proceeds, moving forward as if everything "launched successfully." Even though nothing is actually running, it acts as if it were. So we verify before launching, and don't proceed unless all conditions are met.&lt;/p&gt;

&lt;p&gt;This verification foundation was also independently reviewed by external AIs to ensure correctness. I didn't just decide my own tool was correct on my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Need for a Person to Sit Attached
&lt;/h2&gt;

&lt;p&gt;Because this conversation is driven from Claude's side, it can proceed without a person sitting in front of the terminal. Whether in a scheduled automation setup or during pre-delivery automated checks (CI), you can launch and run other AIs in the same way.&lt;/p&gt;

&lt;p&gt;You can distribute a single task among multiple AIs while you keep an eye on the overall picture. This workflow can be achieved without a person manually switching between terminals one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Positioning of aiterm-mcp
&lt;/h2&gt;

&lt;p&gt;Recently, there has been an increasing trend of a lead AI having another AI assist it. The lead AI lets one AI handle mechanical rewrites and another run batch edits, while it reviews the results. The assisting AIs all run within a terminal. aiterm-mcp is a tool that gives Claude direct control over that terminal, turning assistance into a conversation through the terminal.&lt;/p&gt;

&lt;p&gt;This is what I do with this tool every day: I have Claude converse with Codex, Grok, and Composer, and we all work together.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>mcp</category>
      <category>codex</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I Consolidated Bug Reports from Four Apps and Let AI Fix Them in Parallel</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:09:00 +0000</pubDate>
      <link>https://dev.to/quolu/how-i-consolidated-bug-reports-from-four-apps-and-let-ai-fix-them-in-parallel-1501</link>
      <guid>https://dev.to/quolu/how-i-consolidated-bug-reports-from-four-apps-and-let-ai-fix-them-in-parallel-1501</guid>
      <description>&lt;p&gt;With four user-facing apps, I centralized all bug reports into one place. Only after aggregating them did I realize that the severity ratings were based on different criteria across the four apps. By standardizing the criteria and laying them out on a single screen, I was able to hand them over to multiple Claude instances and have bugs already reported get squashed in a single day. This article explains how operational overhead concentrates here when you run multiple commercial apps.&lt;/p&gt;

&lt;p&gt;I currently have four apps with users: &lt;a href="https://dev.to/quolu/livetr-a-real-time-english-to-japanese-audio-translation-app-for-videos-1lek"&gt;LiveTR&lt;/a&gt;, which provides real-time voice translation; &lt;a href="https://dev.to/quolu/oltranslator-a-real-time-screen-translation-app-for-windows-1l52"&gt;OLTranslator&lt;/a&gt;, which translates screens into Japanese on the fly; &lt;a href="https://dev.to/quolu/i-can-read-english-but-i-cant-hear-it-how-i-realized-ai-makes-unlimited-learning-materials-and-2fh7"&gt;Kikoeru&lt;/a&gt;, an English listening tool; and &lt;a href="https://quo-labo.vercel.app/auctionbot" rel="noopener noreferrer"&gt;AuctionBOT&lt;/a&gt;, a Discord bot running on my own server that manages guild auctions. The more apps you have, the more you worry about "is everything working correctly" rather than developing new features—because real users are using them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0wdev2b03hem3jxssk41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0wdev2b03hem3jxssk41.png" alt="Overview: BugHub polls each app's admin read API every ~3 minutes, deduplicates by signature, and displays them on a dashboard and /ai endpoint under the same criteria" width="800" height="519"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Overview: BugHub polls each app's admin read API every ~3 minutes, deduplicates by signature, and displays them on a dashboard and /ai endpoint under the same criteria&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Apps I can observe vs. apps I cannot
&lt;/h2&gt;

&lt;p&gt;Of the four apps, I can only track the behavior of one myself. AuctionBOT is a Discord bot running on my own server, so I can investigate what's happening to some extent. The other three (OLTranslator, LiveTR, and Kikoeru) run on users' devices and environments. I don't have the same environment at hand, and some bugs cannot be reproduced in a single environment.&lt;/p&gt;

&lt;p&gt;So I added that familiar prompt to all apps: "Send information to improve quality." When I was a user, I'd just click OK without thinking. Now on the developer side, I see how valuable it is. Most bugs aren't something you find yourself; they come up from users' environments. For what I can't observe on my own, I rely on user reports.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reports scattered across different places per app
&lt;/h2&gt;

&lt;p&gt;I added a reporting mechanism to all apps, but then reports piled up in different locations for each app. When I'm running four apps by myself plus AI, I couldn't see how many issues each app had side by side. There was no place to check which app was having problems before fixing them.&lt;/p&gt;

&lt;p&gt;So I built an aggregation system. It's a read-only internal container running on my home server, named BugHub. It does one simple thing: it polls each app's admin read API exposed within the LAN every ~3 minutes and lays everything out on a single dashboard. All the app needs to do is expose one "LAN-internal, Bearer-authenticated read API." Bugs are returned grouped by fingerprint. The fingerprint is a hash of "which module, which type, and what message template"—it doesn't include variable values, so bugs with the same root cause get the same hash. Each bug comes with severity, a message template (variable values and personal information masked), cumulative occurrence count, last occurrence time, and status (unresolved or resolved).&lt;/p&gt;

&lt;p&gt;On BugHub's side, if the data matches this format (called the signature format), ingestion is just one line.&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="c1"&gt;// Apps that output this format just need to add one line to the source list&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SOURCES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AuctionBOT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AUCTION_API&lt;/span&gt;   &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OLTranslator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OLTR_API&lt;/span&gt;      &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LiveTR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LIVETR_API&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// Only Kikoeru had a different log format, so I inserted a small adapter&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kikoeru&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;KIKOERU_API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;adapt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;kikoeruAdapter&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LiveTR, OLTranslator, and AuctionBOT were aligned to the same format from the start. Only Kikoeru had a different logging style, so I inserted one small conversion adapter. That put all four side by side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different criteria became visible side by side
&lt;/h2&gt;

&lt;p&gt;What I noticed after laying them out was that the severity of each report was based on different criteria per app. What one app calls "critical" might be equivalent to "warning" in another. Only when they are arranged under the same criteria does a list appear where you can tackle them from the top.&lt;/p&gt;

&lt;p&gt;So I unified the severity labels into four levels. The app assigns them, and BugHub uses them as-is without re-evaluation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Label&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;fatal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The app stops working or doesn't function. Most severe.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;high&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The app runs but causes actual harm to users (malfunctions, data loss, etc.). One step below fatal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;warn&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not ideal but still working. Should be fixed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;info&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Needs fixing but no solution available now, or reference info just for recording.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The definition is just four lines, but the implementation affects each app's reporting mechanism itself. I had to review which events were assigned to which level across all four apps. As a result, each app underwent a revision that both fixed bugs and rebuilt the reporting mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to pass common specifications to AI
&lt;/h2&gt;

&lt;p&gt;Once the labels were unified, the next question was how to pass these common specifications to the party doing the fixing. The one fixing isn't me; it's AI. Different VS Code instances and different Claude instances are set up for each project, so explaining the specifications verbally each time would defeat the purpose of unifying.&lt;/p&gt;

&lt;p&gt;So I made this into a single page. Calling &lt;code&gt;GET /ai&lt;/code&gt; returns a single Markdown document written for AI consumption. Its pillars are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The four-level severity criteria (the ones above)&lt;/li&gt;
&lt;li&gt;  Fix procedure: ① Get unresolved items → ② Fix the relevant app's project → ③ Deploy to production and confirm it doesn't recur → ④ If confirmed, record the resolution on the app side. Don't record the resolution first. Don't touch anything you're not confident about.&lt;/li&gt;
&lt;li&gt;  A list of unresolved items at that point (with a resolution command for each item)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, the same page includes a table of "where to record the resolution" for each app and common specifications for "how to integrate a new app."&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://dev.to/quolu/delegating-full-server-management-to-ai-111f"&gt;wrote before&lt;/a&gt; about the mechanism for letting AI fix and deploy. What I added this time is the part that aggregates reports from multiple apps under the same criteria and makes them available via a single URL. If I tell AI to "make this app aggregatable to BugHub," the AI implements the app's API according to the common specifications on this page. Integrating a new app also requires only passing the same single URL.&lt;/p&gt;

&lt;p&gt;Resolutions are recorded on the app side, not in BugHub. The app side is the source of truth; BugHub just copies and displays that state. Even if you delete something in BugHub, it will be overwritten by the app's state on the next poll, and if the app detects a recurrence, it will automatically revert to "unresolved."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz4oqh0x483cezzdy0yy7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz4oqh0x483cezzdy0yy7.png" alt="Same /ai URL passed to multiple VS Code/Claude instances, each fetching their assigned app, fixing, deploying, verifying, and recording the resolution. Resolutions are recorded on the app side." width="800" height="615"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Same /ai URL passed to multiple VS Code/Claude instances, each fetching their assigned app, fixing, deploying, verifying, and recording the resolution. Resolutions are recorded on the app side.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handing it over to multiple Claude instances and getting it done in a day
&lt;/h2&gt;

&lt;p&gt;Once everything was in place, I started clearing out the reported bugs. I set up Claude in multiple VS Code instances, passed the &lt;code&gt;/ai&lt;/code&gt; URL to all of them, and instructed: "Look at this and fix it." Since they all see the same list under the same criteria, each Claude picks up unresolved items, fixes its assigned app, deploys, verifies, and records the resolution. I ran this in parallel, and it was largely cleared up in that one day.&lt;/p&gt;

&lt;p&gt;There is no LLM inside the polling container. The ~3-minute polls and the instant alerts for surges or new issues all run on pure threshold rules. AI is involved only on the outside—on the bug-fixing side and the weekly Codex summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the most effort goes now
&lt;/h2&gt;

&lt;p&gt;When you personally run multiple commercial apps, the operational overhead concentrates here. The time spent handling incoming reports grows larger than the time for adding new features. I &lt;a href="https://dev.to/quolu/ive-accelerated-building-and-promoting-but-delivering-still-remains-a-challenge-3fid"&gt;wrote before&lt;/a&gt; about the speed of building, and as a follow-up, the same kind of organization is needed on the maintenance side. That's where things stand now.&lt;/p&gt;

&lt;p&gt;Now, unresolved items for all four apps are lined up on a single screen under the same criteria, and by passing a single URL, AI can go and fix them from there. That prompt "Send information to improve quality" that I absentmindedly clicked OK to as a user—this is how it gets used on the developer side.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I Made an AI That Can't Draw the Same Character Create Anime Model Sheets</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:08:25 +0000</pubDate>
      <link>https://dev.to/quolu/how-i-made-an-ai-that-cant-draw-the-same-character-create-anime-model-sheets-19cn</link>
      <guid>https://dev.to/quolu/how-i-made-an-ai-that-cant-draw-the-same-character-create-anime-model-sheets-19cn</guid>
      <description>&lt;p&gt;I have all the characters in my RPG (rpgdev) drawn by AI. The dot-pixel hero, the spirits of fire, water, wind, and earth, the enemy monsters. I've generated each one, made them transparent, and put them into the game.&lt;/p&gt;

&lt;p&gt;But there's been a persistent problem: &lt;strong&gt;AI is bad at drawing the same character consistently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose you get a good character image. You ask for "the same character, but facing sideways" or "a damaged version." Then — it's not like it becomes a different person, but the hairstyle changes a bit. The colors shift. Equipment appears or disappears. The line thickness varies. Each image looks fine on its own, but when lined up, they don't look like "the same character."&lt;/p&gt;

&lt;p&gt;I couldn't trust the approach of editing a single image to create variations, in terms of consistency.&lt;/p&gt;

&lt;p&gt;By the way, in a previous article &lt;a href="https://dev.to/quolu/i-love-watching-ai-work-so-much-that-i-turned-my-terminal-into-an-rpg-51jf"&gt;How I turned my terminal into an RPG&lt;/a&gt;, I wrote that I struggled with creating these dot-pixel variants and ended up ordering a 32GB GPU to "fight back." This article is also a record of that rematch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ecp6q0j268bizq7lyr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ecp6q0j268bizq7lyr8.png" alt="The overall two-stage approach: stop endlessly fixing single images, first create a reference sheet to serve as a standard" width="800" height="636"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The overall two-stage approach: stop endlessly fixing single images, first create a reference sheet to serve as a standard&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How do anime and manga studios keep characters consistent?
&lt;/h2&gt;

&lt;p&gt;I thought about it. How do professional animators and manga artists keep the same character consistent across every cut and every episode?&lt;/p&gt;

&lt;p&gt;I know the answer: &lt;strong&gt;Character reference sheets (model sheets)&lt;/strong&gt;. Front, three-quarter, side, and back turnaround views, expression patterns, several poses. A single sheet that serves as a standard for "this is how to draw this character." Everyone on the team draws while looking at this sheet. That's why they can maintain the same character across hundreds of cuts.&lt;/p&gt;

&lt;p&gt;So, we should make AI do the same thing. Instead of endlessly fixing single images, &lt;strong&gt;first create one reference sheet, and then use it as the standard for all subsequent generations.&lt;/strong&gt; The idea itself is simple.&lt;/p&gt;

&lt;p&gt;The problem was: how to make AI create that reference sheet itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  The key is in how you create the reference sheet
&lt;/h2&gt;

&lt;p&gt;If you do it straightforwardly, it goes like this: "Draw a front view," "Next, a side view," "Next, a back view," "Next, a smiling face" — generating each cut one by one separately.&lt;/p&gt;

&lt;p&gt;But this leads to the same problem as before. The character drifts between cuts. &lt;strong&gt;They become different people within the reference sheet.&lt;/strong&gt; The sheet meant to be the standard fails to be a standard. It's putting the cart before the horse.&lt;/p&gt;

&lt;p&gt;So I came up with a two-stage approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage one: Have all angles, expressions, and poses drawn together in a single generation.&lt;/strong&gt; Don't request them separately. Ask for "a reference sheet with turnarounds, expressions, and poses all in one image" in a single prompt. Because they are drawn simultaneously as one picture, they are consistent with each other within it. The front and back views have the same hairstyle and same outfit. This becomes the "anchor for consistency."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgixzf1smokdljodbgpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgixzf1smokdljodbgpr.png" alt="The master sheet drawn all at once" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The master sheet drawn all at once&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, cramming everything into one image makes each cut small and rough. The resolution isn't enough for game use.&lt;/p&gt;

&lt;p&gt;So, stage two: &lt;strong&gt;Now pass that "group drawing" sheet back to AI as a reference.&lt;/strong&gt; Then have it redraw each cut individually at high resolution. Ask: "Keep the character exactly as shown in this reference, but draw only this one cut larger."&lt;/p&gt;

&lt;p&gt;With a reference, consistency is maintained. By drawing each cut individually, resolution is achieved. &lt;strong&gt;Consistency from the reference sheet, resolution from individual generation — both benefits.&lt;/strong&gt; I designed and instructed this two-stage approach myself.&lt;/p&gt;

&lt;p&gt;Here's the result. At the top is the master sheet; below it are high-resolution redraws of turnarounds, expressions, actions, alternate outfits, chibi versions, equipment, and even an extracted color palette. All the same character.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwh5s4obo0w9sqa7hduh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwh5s4obo0w9sqa7hduh6.png" alt="The character bible with each cut redrawn from the master sheet" width="800" height="1525"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The character bible with each cut redrawn from the master sheet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The water spirit. Expressions, running, jumping, knight armor, dress — all lined up as the same person.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: The reference sheet becomes fuel for mass production
&lt;/h2&gt;

&lt;p&gt;The high-resolution cuts created in stage two have another use.&lt;/p&gt;

&lt;p&gt;They become training data dedicated to that character. You have a dozen or more images of the same character from various angles and expressions. If you train an AI on these to create a small additional model that "remembers" this character, you can mass-produce new poses that weren't in the reference sheet, while keeping the character consistent.&lt;/p&gt;

&lt;p&gt;The process of creating the reference sheet also doubles as fuel for the next mass production. That was intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Turning pain points into "checkpoints"
&lt;/h2&gt;

&lt;p&gt;That's the core. Now a little about the tool's internals.&lt;/p&gt;

&lt;p&gt;While creating assets for rpgdev, I've stepped on countless small pain points. I've baked each one into the tool as an "absolute rule" (checkpoint).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ss2qh2ov8edw4wunozv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ss2qh2ov8edw4wunozv.png" alt="The output is a transparent game sprite. If the corners aren't properly transparent, it gets rejected before shipping." width="800" height="229"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;The output is a transparent game sprite. If the corners aren't properly transparent, it gets rejected before shipping.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pain points I encountered&lt;/th&gt;
&lt;th&gt;Absolute rules (checkpoints) baked in&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Black residue in transparency&lt;/strong&gt; - "Closed black" areas like gaps between arms and ribbons remain after simple background removal. One accepted image had over 200,000 black pixels left.&lt;/td&gt;
&lt;td&gt;Reject before shipping if the four corners aren't properly transparent.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Misalignment in damage versions&lt;/strong&gt; - Each regeneration shifts by a few pixels, causing misalignment with the base in-game.&lt;/td&gt;
&lt;td&gt;Reject if not within 1px of the base.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Art style drift&lt;/strong&gt; - Omitting essential terms for retro pixel art causes a smooth slide into glossy anime style.&lt;/td&gt;
&lt;td&gt;Automatically inject those terms.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Manual fixes don't work&lt;/strong&gt; - Hand-drawing fabric, skin, or outlines to fix issues had a zero percent success rate.&lt;/td&gt;
&lt;td&gt;Don't include manual editing functions. To fix, regenerate.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Broken assets don't silently slip into the game. They get stopped at the checkpoint.&lt;/p&gt;

&lt;p&gt;And whether the input comes from a human-operated UI (WebUI) or an AI (Claude or Codex) calling the MCP endpoint, &lt;strong&gt;the same processing pipeline&lt;/strong&gt; is used. So whichever face enters, these checkpoints cannot be bypassed.&lt;/p&gt;

&lt;h2&gt;
  
  
  With 32GB, it finally worked
&lt;/h2&gt;

&lt;p&gt;In #30, I wrote that my custom diff tool couldn't run on my 16GB GPU, so I ordered a 32GB one to "fight back."&lt;/p&gt;

&lt;p&gt;The editing model this tool uses gobbles up over 20GB of VRAM. It simply didn't fit in 16GB — literally zero images were output. After upgrading to 32GB, it finally worked. If you don't have enough VRAM, that's the end of it.&lt;/p&gt;

&lt;p&gt;On top of that, the architecture is designed as follows: the heavy generation is entirely handled by that single machine with 32GB (the ComfyUI GPU machine). The main tool is a thin orchestrator that commands "what to create and in what order" and performs the checkpoint checks mentioned earlier. As long as you have one machine set up for generation, the orchestrator can connect from a Mac or WSL.&lt;/p&gt;

&lt;p&gt;It's a tool that requires a CUDA GPU and the full ComfyUI setup — it has requirements. But the two-stage concept itself is tool-agnostic. If you're struggling with inconsistent characters, you can take just that idea and it will work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;sprite-forge. Create transparent game-ready characters from text. Give it an idea, and it produces a base body, assembles a reference sheet, and even prepares training data for that character. Whether from a human or an AI agent, the same checkpoints are passed and the same output comes out.&lt;/p&gt;

&lt;p&gt;The repository is at &lt;a href="https://github.com/kitepon-rgb/sprite-forge-mcp" rel="noopener noreferrer"&gt;github.com/kitepon-rgb/sprite-forge-mcp&lt;/a&gt;. MIT license.&lt;/p&gt;

&lt;p&gt;I stopped endlessly fixing single images and started creating from a reference sheet. At last, the same character now lines up as the same character.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>comfyui</category>
    </item>
    <item>
      <title>Only Complete Sentences Should Be Translated — But a Single Counter Betrayed That Design</title>
      <dc:creator>Quo</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:07:53 +0000</pubDate>
      <link>https://dev.to/quolu/only-complete-sentences-should-be-translated-but-a-single-counter-betrayed-that-design-1kcl</link>
      <guid>https://dev.to/quolu/only-complete-sentences-should-be-translated-but-a-single-counter-betrayed-that-design-1kcl</guid>
      <description>&lt;p&gt;When watching English videos with LiveTR, the subtitle translations would occasionally get jumbled.&lt;/p&gt;

&lt;p&gt;Lines from different people would merge into a single sentence. The first utterance after silence would be translated missing its beginning. Occasionally, nonsensical Japanese would appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvlngapf0zkgxt4y1s9hv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvlngapf0zkgxt4y1s9hv.png" alt="A dim desk, a mood shot of English video subtitle overlays being converted to Japanese in real-time" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;A dim desk, a mood shot of English video subtitle overlays being converted to Japanese in real-time&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  You Need Complete Sentences to Translate
&lt;/h2&gt;

&lt;p&gt;If you feed incomplete sentences to a translator, you get incomplete translations. It's obvious.&lt;/p&gt;

&lt;p&gt;What comes into play here is how the audio is captured. To process in real-time, LiveTR mechanically splits the incoming audio every &lt;strong&gt;five seconds&lt;/strong&gt; and feeds it to speech recognition. This five-second segmentation naturally ignores where people actually stop speaking. It ruthlessly cuts off sentences right in the middle.&lt;/p&gt;

&lt;p&gt;So the English sentences coming out of speech recognition are frequently cut off. Fragments like "I think that we should…" are severed by the five-second wall. If you throw these directly into translation, you'll only get choppy translations back.&lt;/p&gt;

&lt;p&gt;So LiveTR doesn't pass these fragments directly to translation. Instead, it holds onto them, and if the continuation comes in the next five seconds, it concatenates them to form a complete sentence before translating. Only complete sentences are sent for translation—this is the core of translation accuracy, and I wrote about its importance in &lt;a href="https://dev.to/quolu/livetr-a-real-time-english-to-japanese-audio-translation-app-for-videos-1lek"&gt;the previous article introducing LiveTR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The problem is when the continuation never comes. The conversation might pause or change topics, and the held fragment may never get its continuation. In that case, the system decides "waiting longer is futile" and sends the fragment as a sentence on its own. That cutoff mechanism was properly implemented.&lt;/p&gt;




&lt;h2&gt;
  
  
  That Cutoff Was Pointing in the Wrong Direction
&lt;/h2&gt;

&lt;p&gt;The subtitle confusion happened because this cutoff wasn't working.&lt;/p&gt;

&lt;p&gt;A single counter that measures waiting time—the one that decides "send without waiting anymore"—was wired backwards. It triggered when there was no need to wait, and failed to trigger when it should have cut off. So the held fragment remained in limbo, and when someone else started speaking in the next five seconds, it attached to the beginning of their speech.&lt;/p&gt;

&lt;p&gt;For example, a five-second segment ends in the middle of "we really need to". Then the conversation flows in a different direction, and in the next five seconds someone says "Yeah anyway the budget is fine.". Normally the previous fragment would be sent alone, but instead it gets attached to form "we really need to anyway the budget is fine."—a sentence no one actually spoke. Because this is faithfully translated, the subtitle becomes something like "We really need to anyway, the budget is fine."—a line mixing two speakers' dialogue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9003oyh28q53hb9cnnt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9003oyh28q53hb9cnnt2.png" alt="When the cutoff counter is reversed (top), the previous fragment attaches to the next speaker; with the correct direction (bottom), they are finalized as separate utterances" width="799" height="429"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;When the cutoff counter is reversed (top), the previous fragment attaches to the next speaker; with the correct direction (bottom), they are finalized as separate utterances&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What I fixed was just this one thing: the direction of the cutoff. The design was correct.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Translation Engine Was Excellent from the Beginning
&lt;/h2&gt;

&lt;p&gt;LiveTR sends translations to cloud engines (DeepL / Google / Azure / Amazon, selectable in settings). They faithfully translate whatever English text they receive. If you feed them patchwork, they translate patchwork. They have no way of knowing that the English they receive is a collage of two people's lines.&lt;/p&gt;

&lt;p&gt;Once I fixed the cutoff direction, complete sentences started reaching the engine. When I played English audio on the actual device, the translation was completely different. I hadn't touched a single line of the translation engine.&lt;/p&gt;

&lt;p&gt;Feed it complete sentences, and the same engine returns a good translation. It was that simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;LiveTR is available for purchase on BOOTH. It can real-time Japanese-ify English videos and streams on Windows + NVIDIA GPU environments. It comes with subtitle overlays and Japanese text-to-speech that reflects the speaker's voice quality.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related Articles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://dev.to/quolu/livetr-a-real-time-english-to-japanese-audio-translation-app-for-videos-1lek"&gt;LiveTR — An App That Converts English Audio from Videos into Japanese in Real Time&lt;/a&gt; — Introduction to the app itself. Overview of speech recognition, translation, subtitles, and text-to-speech.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This blog, "Getting Started with Claude Code", is a site where Claude MAX users record what they learn while using it in actual development.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
