AI AgentAI Coding

Claude Code's Mods: Taking Half a Step Toward DSH, Stopping Right on the Line

On August 13, 2026, DeepSeek open-sourced its coding agent harness, DSH (DeepSeek Harness, GitHub repository). At the time, I did an in-depth analysis of DSH, noting its core difference from traditional coding agents: plugins run directly inside the host framework’s process, and even the most critical main control loop itself is a hot-swappable plugin. The entire lifecycle mechanism built into the framework was designed around this replaceable control loop.

On October 1, 2026, Anthropic announced mods, a new feature for Claude Code, on its official blog. After reading the official technical documentation, I noticed that for the first time, Claude Code allows third-party code to run inside its own process. Comparing the design trade-offs of the two reveals that what Claude Code designed—and where it chose to stop—falls right along the dividing line I drew two months ago in my in-depth DSH analysis.

Claude Code Lets Third-Party Code Run Inside Its Own Process for the First Time

Starting with Claude Code client v2.1.287, Anthropic officially introduced the mods mechanism. In Anthropic’s official blog post on mods, mods refer to small TypeScript or JavaScript functions that run inside the Claude Code process. They can rewrite prompts, intercept tool calls, approve execution permissions, and even take over and render the terminal interface.

Before this, all Claude Code extensions lived out-of-process: skills are Markdown files that inject instruction context, settings hooks are scripts, HTTP requests, or prompts triggered externally, and MCP servers are separate external processes. The official comparison table states plainly that mods are the only extension format capable of directly rendering and modifying the user interface.

Mods are event-driven. Claude Code triggers events whenever a user submits a prompt, uses a tool, requests authorization, or renders the interface. Mod handlers can intervene before an event occurs, capture results after it completes, replace the event entirely, or wrap around it.

With these hook points, mods reach places previous extension mechanisms could never touch. They can rewrite prompt content before it reaches the model, intercept and retry tool calls, and redact secrets before output is returned. On the interface side, they can adjust how tools are displayed, replace loading spinners, customize confirmation dialogs, or open up dedicated display areas and interactive panels above the prompt input. Mods can also register slash commands that consume no model turns and can be invoked instantly even mid-generation. Multiple hooks within the same mod can share in-memory state through module-level variables—one function counts while another displays. When multiple mods attach to the same event, they execute in load order: the first loaded receives the event first and gets the return result last. Users can even have Claude write a TypeScript mod on the spot and hot-reload it into effect.

In Anthropic’s official example mods repository, token-weather draws a real-time context window usage forecast above the prompt input, while blast-radius intercepts dangerous commands on detection and pops up an assessment panel with proceed and cancel buttons.

Once the mechanism was in place, the host itself began moving built-in features outward. In v2.1.287, the official team split the built-in /diff command into a standalone mod that users can toggle off or replace. The official documentation states explicitly that more built-in features will migrate to mods in the future, slimming the host down into a compact foundation that loads capabilities on demand. This version also bundles You should know, which uses an out-of-band side agent to flag information you might have missed during an operation.

But when code runs inside the same process, security boundaries weaken considerably. Mods have no sandbox. They share identical privileges with the current terminal: reading and writing files, making network requests, accessing environment secrets, and approving tool calls. While enterprise environments provide static validation commands and pre-loaded security mods, letting third-party code run inside the main process remains an inherently high-trust act.

Two Plugin Worldviews

Customization mechanisms in mainstream coding agents currently fall into two primary patterns. In the first, plugins are merely files and configurations; the host program reads these configurations and launches corresponding processes externally. This is a declarative customization mechanism. In the second, plugins load into the host process as code modules, carrying their own state to do their work. This is an imperative customization mechanism.

The standard-bearers of the declarative approach are Codex and early Claude Code. Here, plugins are simply static files and configuration manifests on disk: Markdown instructions, MCP launch commands, or rules triggering shell scripts. The host reads the configuration and spins up an independent process outside. Isolation is clean, but plugins cannot reach host internals; if you want to tweak context compression or scheduling logic, your only option is modifying the host source code and recompiling.

The imperative route is exemplified by DSH, open-sourced in August. Plugins run directly in the host process as code modules with their own lifecycles and in-memory state, living and dying alongside the host. When a module loads, it registers capabilities within the process; other plugins declare dependencies, and the underlying framework wires them together automatically.

Yet the engineering cost of an imperative architecture is steep. Resident stateful code makes hot-swapping complex: unloading easily leaves dangling references, and no one cleans up open connections or background tasks for you. To support this model, DSH introduced a heavy lifecycle framework dedicated to tracking side effects, tearing down resources, and broadcasting notifications when dependencies shift.

From this perspective, Claude Code’s mods crossed the process boundary and stepped onto the imperative side: they can execute logic directly inside the host using TypeScript, share state, and hot-reload. But compared to DSH’s full-blown service registration and dependency wiring system, Claude Code chose only the leanest subset of the imperative route: event handlers. It provides no capability registry or dependency wiring; multiple mods simply respond to events sequentially in load order.

Declarative and imperative plugin worldviews are compared across process boundaries, execution models, and control capabilities.

Which Half-Step It Took, and Which It Didn’t

Placing the engineering implementations of Anthropic and DSH side by side makes the half-step taken—and the half-step avoided—immediately obvious. The half-step taken is bringing code into the host process, gaining the ability to intercept and rewrite key events, alongside session-time hot-reloading and intra-module state retention.

The half-step it didn’t take sits right at the critical juncture of the system architecture. To clarify terms first: the agent loop refers to the main loop code where a coding agent sends a request to the model, awaits a response, executes tools, and loops again each turn. Claude Code provides no capability registration mechanism, dependency topology wiring, or transactional hot-swap rollback. The more crucial boundary lies in the main loop: according to existing official technical documentation, mods offer no interface to replace the agent loop. This is a judgment based on the documentation as it stands, but the architectural boundary is distinct.

Claude Code mods expose in-process event hooks, but according to public documentation, the main control loop provides no interface for replacement.

This brings us back to the metaphor from my August DSH analysis: a whole plate of dumplings and that dish of vinegar. In DSH, the entire lifecycle framework—side-effect revocation, dependency change notifications, and transactional protection for hot updates—serves one radical goal: turning the agent loop itself into an ordinary, hot-swappable plugin. DSH’s agent loop provides the loop service inside its core package, declaring dependencies on system prompts and toolsets. To swap a single-agent loop for a multi-agent coordination loop, you only need to write a plugin implementing the same interface and replace it in the configuration. The framework automatically unloads the old loop, cleans up listeners, and smoothly spins up the new control flow once dependencies are in place.

That complex runtime framework is the whole plate of dumplings; making the main loop hot-swappable at any moment is the dish of vinegar they actually wanted to dip them in. In truth, DSH wrapped a whole plate of dumplings just for this dish of vinegar. The dependency notification and rollback designs are entirely byproducts built so the host wouldn’t crash when swapping out the control loop.

By contrast, in Codex’s open-source repository, you can see its main loop, run_turn(), hardcoded directly in the core using Rust. External hooks can only make light adjustments at preset checkpoints; they cannot reshape the control flow skeleton at runtime, whether to turn serial tool execution into parallel runs or assemble multiple agents at the loop level.

Current Claude Code mods offer a different approach: they build a lightweight, pragmatic event interception mechanism, but judging by public documentation, they left that dish of vinegar completely untouched. They achieved high usability for event interception and UI customization, yet kept the main loop firmly inside the core, pointing nowhere near control-flow self-evolution.

Is This Borrowing?

The similar evolution of both systems along the in-process versus out-of-process axis naturally invites the question: is this borrowing? Having looked at the public timeline and design trade-offs, I lean toward no.

On the public timeline, DSH was open-sourced on August 13, 2026, while Anthropic released mods on October 1, 2026. Tracing Anthropic’s public design trail backward, the earliest trace is the mods design issue #91870 opened in the claude-code repository on September 3, 2026, titled “Mods - make Claude 10x more extensible”; a week later, the team noted in the issue that function hooks would be shipping on the scale of weeks. In other words, the earliest verifiable public design starting point came three weeks after DSH was released. The exact date when the CLAUDE_CODE_ENABLE_FUNCTION_HOOKS environment variable used for early testing first appeared left no verifiable record, so it cannot determine precedence. The honest conclusion is that their design cadences were very close; whether Anthropic’s design process was influenced by DSH cannot be determined from public evidence alone, and neither can claim clear precedence.

More critical than the timeline are the design trade-offs. If Anthropic had set out to copy DSH, it wouldn’t have discarded DSH’s most defining hallmarks: the capability registry, the dependency injection framework, and the replaceable agent loop. Instead, mods concentrated on direct, day-to-day ergonomics: rendering status interfaces, adding shortcut commands, and intercepting high-risk operations. Someone copying homework wouldn’t copy just half of it, much less pick the most ordinary half.

Both were moving in the same direction because they hit the exact same engineering wall. The deeper customization goes, the less declarative external configuration suffices: fine-tuning prompts, intercepting tool chains, and redrawing terminal interfaces all require code to enter the host’s process space. Facing the same constraints, each team arrived at its own answer. Who influenced whom chronologically remains unclear, and there is no design lineage; rather, a single engineering problem produced two distinct solutions. A self-calibration is worth noting here: in-process versus out-of-process is merely a coarse-grained classification axis. Both systems landing on the imperative side is largely because the axis itself is broad; one cannot use this to infer concrete design inheritance between the two.

What This Means for You

These two approaches cater to different audiences.

For developers using Claude Code day-to-day, mods are genuinely useful customization tools. When writing production code, we rarely need dynamic dependency injection or a replacement for the underlying main loop; what we usually want are concrete enhancements: watching context consumption above the prompt (like token-weather), catching high-risk commands with an assessment panel before they execute (like blast-radius), or binding a local operation to a slash command. Mods handle all of these. By contrast, DSH’s lifecycle mechanisms are virtually irrelevant in everyday engineering.

For harness explorers watching architectural evolution, Claude Code demonstrates a clear modular trajectory. Splitting /diff into a standalone mod and shipping You should know as a built-in mod signals an evolution away from monoliths toward a lean core with on-demand loading. This direction comes close to a composable architecture, though it still lacks a complete lifecycle governance mechanism for hot-swapping the main loop.

This raises an open question: when will Anthropic open up agent loop customization? The inflection point will likely arrive where model capability meets practical demand. When models can routinely author dozens of lines of tool functions and hundreds of lines of main loop code pushing the limits of frontier model capability—and when users genuinely need to switch scheduling strategies dynamically per task—only then does such a heavy architecture earn its keep. Until then, that dish of vinegar prepared for dynamic control loop replacement remains something only DeepSeek has ready.