Skip to content

DSCODE

A macOS terminal coding agent built on DeepSeek Harness, carrying its own pinned harness profile, a terminal package it patches at build time, and a session layer — sessions that message each other, Ultra sub-agents, reviewed approvals, scheduled runs.

Screenshot of DSCODE
Editor screenshot, 30 Sep 2026DSCODE ↗

What it is

A terminal coding agent for macOS, built on DeepSeek Harness. Its premise is that sessions on one machine should be able to see each other: a session can read another’s transcript, hand over work with dscode send <session-id> --steer "review the change in parser.ts and reply", ask a side question through /btw in a read-only child that never touches the main conversation, or let /delegate <task> plan a task on a board and run the ready parts as child agents in isolated git worktrees. Approvals go to an independent reviewer by default (/permission auto-review) inside a workspace-write sandbox. Install with npm install -g @toddzheng024/dscode, then cd /path/to/project and run dscode; the first launch installs a pinned preset from the DSH Plugin Hub, and /login stores a DeepSeek API key in ~/.dscode/credentials.yaml with 0600 permissions. Homebrew (brew tap qiz029/tap && brew trust qiz029/tap && brew install dscode), a one-line installer and a source checkout are also supported. It needs macOS 14+, Node 22.19+ or 24+, Git and Chrome; dscode exec "prompt" runs a turn from a script.

Who built itThe repository lists exactly one contributor, the account qiz029, and all 123 commits are linked to it — authored as todd.zheng from toddzheng024@gmail.com. The MIT licence names Todd Zheng, and the package publishes under the npm scope @toddzheng024. This is a one-person project in the plain sense: no second contributor, no bot account, and no other public record of the builder in the material this record was written from.

How it is put together

The parts · 6

The shape is a distribution wrapped around somebody else’s runtime, and most of the structure follows from that. DeepSeek Harness supplies the agent runtime and the plugin host; DSCODE supplies three layers on top. A launcher and two packages install and pin the whole thing — the command package, a bundle carrying the plugins and a modified terminal, and a Hub profile with integrity hashes. A vendored terminal lives in packages/tui because the interface needed changes a plugin cannot make, and it is modified by generating modules from patch descriptions at build time rather than by editing vendored sources, which buys a repeatable install and costs a documented merge procedure for every upstream release. Everything else is plugins: a persistent shell, worktree-isolated child agents, an independent reviewer for approvals, a mailbox and a bridge that let separate sessions on one machine see and message each other, triggers with a durable scheduler, session metrics, memory and email. One session runtime is shared by the TUI, the CLI and scripts, so a session started in the terminal can be read, steered and messaged from another process without taking its write lock.

packages/tui/
The vendored terminal: 79 files, 1,338 KB, the second-largest directory in the tree. Its src/app.ts is 382,157 bytes — the largest code file here — followed by src/index.ts (120,925), src/render/projection.ts (105,398), src/kernel-panels.ts (68,255), src/provider-settings.ts (37,703) and src/render/status.ts (37,350), with two 32 KB locale files (locales/en.ts 32,615, locales/zh.ts 32,201) and the build-time patch description cordis.patch.yml (11,484).
plugins/
Twenty-eight plugin directories, led by triggers (26 files, 157 KB, cli.mjs 30,629), the session bridge (7 files, 70 KB, mailbox.mjs 20,129, communication.mjs 14,606, server.mjs 11,799), OpenRouter (5 files, 54 KB, wire.mjs 24,178), the TUI tools (9 files, 53 KB), session metrics (8 files, 43 KB), Grok (7 files, 42 KB), OpenCode Go (9 files, 41 KB), the dscode plugin itself (2 files, 41 KB, index.mjs 26,993 and board.mjs 14,492) and email (10 files, 40 KB).
docs/ and docs/releases/
Twenty-five documents and 333 KB, most of them user guides the README indexes in both languages, plus 38 release notes and 140 KB. The largest are CHANGELOG.md (80,835), tui-commands.md (26,963), triggers.md (24,958), session-messaging-design.md (23,238), verification.md (19,130) and the distribution guides; AGENTS.md (3,649) states the release rules and which documents are guides and which are design records.
tests/ and eval/
Seventy-six test files and 684 KB against the shipped code, with session-metrics.test.mjs (33,995), code-review.test.mjs (29,844), opencode-go.test.mjs (29,184), openrouter.test.mjs (28,388) and dscode.test.mjs (22,228) the largest; then eval/compaction (24 files, 711 KB, fixtures of 212,244 and 162,078 bytes), eval/continuation (36 files, 99 KB, including twenty small check scripts and cases-20.json at 25,802) and eval/deepswe (10 files, 62 KB).
research/
Seven notes, 118 KB, in Chinese, kept apart from docs/ — which AGENTS.md rules must be English: a context-compaction survey (30,762), two migration notes for taking over the vendored dsh-code (25,484 and 14,319), a four-way system-prompt comparison (22,905), a complexity-metric design (12,663), a workload assessment for replacing the terminal in-house (7,558) and a code review of its own v0.7.8 (7,389).
scripts/, Makefile and install.sh
Fifty-one scripts and 287 KB of build and verification plumbing: patch-runtime.mjs (23,335) heads six patch-*.mjs files, and the rest are probes and verifiers (verify-hub.mjs 13,018, verify-login-runtime.mjs 12,818, dscode-probe.mjs 14,456). install.sh is 11,166 bytes, the Makefile 5,899, and the release workflow under .github/workflows/release.yml 5,486.

Choices, and what they beat

  • Generate the terminal’s modifications at build time from patch descriptions over rewriting the vendored sources in place

    The README states it as a promise to the user: the bundle generates its modified modules at build time and never rewrites third-party sources on a user’s machine. The cost is written down too — docs/vendored-tui-upgrade.md (5,058 bytes) exists to carry a new upstream dsh-code release, and its stated limit is what only a smoke test catches.

  • Sessions on one machine that can see and message each other over agents working alone

    The README argues the case in one line — most coding agents work alone, and this one is built on the opposite assumption. The boundaries are written into the design record rather than left implicit: the first version is limited to the same machine, the same state directory and a loaded root session, sending to an unloaded session returns target_unavailable, and every chain is capped at a depth of 3, 8 new messages, one final reply, one hour, a 64,000-byte body and 100 unclaimed notes, with a refusal rather than a silent drop when a limit is hit.

  • Approvals reviewed by an independent model from the user’s instruction over deciding them from a rule table, or turning confirmations off

    The README states the alternative it rejected: an independent reviewer decides from your instruction rather than from a rule table. The defaults are ordinary — a workspace-write sandbox, /permission ask to hand decisions back — and the limits are drawn explicitly: Ultra adds no permissions and Computer Use keeps human authorisation.

  • One event ingress instead of a hook per scenario over a set of per-scenario hooks

    The design record calls it "an ingress, not a set of hooks": every way of waking the agent — cron, delay, file change, poll, CI job — is reduced to something posting one event, which is why there is one entry point and one payload grammar and why a new source costs a definition field rather than a code path. The same record lists what the choice gives up: it is not an automatic retry engine, it does not claim exactly-once external effects, and no notifier consumes the run log yet.

  • A release is a four-part checklist over a version bump on its own

    AGENTS.md opens with the rule that a release is not just a version bump: the notes file, the package.json version, the changelog entry and both READMEs ship in the same change, and the release tool refuses rather than publish without the notes. Twenty releases inside nine days is what that process, written down and enforced, looks like.

Read fromREADME.md (28,788 characters, read in full), AGENTS.md (3,647 characters), docs/triggers-design.md (7,448 characters), the first 12,000 characters of docs/session-messaging-design.md (23,169 in total), the README’s dependency and distribution tables, and the complete 515-file tree with sizes together with the two-level directory summary.

Build log

5 stages
  1. 01

    Fourteen days, and twenty releases in the last nine of them

    The repository was created on 2026-09-11 at 09:40:02Z and its first commit arrived 59 seconds later — "Add DSCODE coding harness and npm Hub distribution". Its last commit, on 2026-09-25, is "Release 0.7.32: OpenCode Go account login and footer usage". Between those two points sit 123 commits, all of them in September 2026, and all from the same account. The releases are not spread across that fortnight: the first, v0.7.13, was published on 2026-09-17 and the last, v0.7.32, on 2026-09-25, so all twenty landed inside the final nine days, with at least one on every one of those days — four on 2026-09-18, four on 2026-09-19 and four on 2026-09-22 — and the closest pair, v0.7.26 and v0.7.27, twenty-six minutes apart. The release rules are the other half of the explanation: AGENTS.md makes a release a checklist rather than a version bump, with the notes file, a matching package.json version, a changelog entry and both READMEs shipping in the same change, and make attach refusing outright rather than publish without docs/releases/<version>.md. The tree carries 38 such files, from 0.2.0 to 0.7.32, against 20 tags and 20 releases — a gap the materials do not explain. Dates here are the API’s UTC timestamps.

  2. 02

    What those nine days of releases were actually about

    The README’s "What’s new" section covers the last nine releases, and read end to end it is three threads rather than nine features. The first is work that runs with nobody watching: 0.7.24 lets an event start a session, with definitions in <state>/triggers/ and <workspace>/.dsh/triggers/, an event carrying only data under a required eventId, and trigger install writing a launchd LaunchAgent; 0.7.26 adds fresh and persistent session modes, durable cron and delay jobs and supervised script sources. The second is provider sign-in: 0.7.29 adds /account, which signs the DeepSeek route in through the system browser with a loopback callback, so a signed-in machine needs no DEEPSEEK_API_KEY; 0.7.31 brings OpenCode Go into /provider with its DeepSeek, GLM, Kimi, MiMo, LongCat, Hy and Space Bunny models; 0.7.32 replaces that route’s console API key with /opencode login and puts the subscription’s five-hour, weekly and monthly caps into the footer. The third is repair of the composition the whole project sits on: 0.7.27 fixes fresh Hub installation failing after the Harness composition generated an empty cordis.yml, and 0.7.28 moves the runtime from 0.1.5-rc.2 to 0.1.7-alpha.2 while renaming the permission preset auto to auto-review, because DSH now reserves auto for its own integration. Feature releases and repair releases are interleaved, and the repair releases are the small ones: a broken installer, a renamed flag, an upstream version bump.

  3. 03

    A shell grown on a plugin host, and the price of the terminal

    DeepSeek Harness is the host, and the README describes the ordinary path on it: the first launch installs a pinned complete preset from the DSH Plugin Hub with no manual plugin assembly, and the launcher checks installed bundles and Harness dependencies against the recommended combination, printing one consolidated warning instead of editing dependencies or downgrading. Most of what DSCODE adds follows that model — 28 directories under plugins/, from plugins/triggers (26 files, 157 KB, its cli.mjs alone 30,629 bytes) down to one-file plugins like plugins/ultra/policy.mjs (6,114 bytes). The terminal is where the project leaves the plugin model: packages/tui is a vendored, modified copy of the interface, 79 files and 1,338 KB, and its own src/app.ts is 382,157 bytes, the largest code file in the tree. How it is carried is stated in the README: the bundle generates its modified modules at build time and never rewrites third-party sources on a user’s machine. That is why there is a cordis.patch.yml of 11,484 bytes inside the terminal package and another under config/, six scripts/patch-*.mjs files (the largest, patch-runtime.mjs, 23,335 bytes), and a whole document, docs/vendored-tui-upgrade.md (5,058 bytes), about taking a new upstream dsh-code release — a document whose stated limit is what only a smoke test catches. The tree is 515 files, and the largest directory in it by bytes is not code at all but assets/: two files, 3,504 KB, almost all of it the 3,585,589-byte demo GIF.

  4. 04

    One contributor, 123 commits, and a directory of Chinese research notes

    Every one of the 123 commits is linked to the same GitHub account, qiz029, authored as todd.zheng from toddzheng024@gmail.com, and the contributor list has exactly one entry: qiz029 with 123 commits. What the history also records is how much of the work was done with a model in the loop — 43 of the 123 commits carry a co-author trailer, 26 for "Claude Fable 5.1", 14 for "Claude Opus 5 (1M context)", two for "Claude Opus 5.5" and one for "Claude Opus 5.5 (1M context)". The project’s own notes on building it are not in docs/, which AGENTS.md rules must be English; they are in research/, seven documents and 118 KB, written in Chinese, and their subjects are the project’s own problems: taking over the vendored terminal (dsh-code-vendor-接管-迁移笔记.md, 25,484 bytes, and dsh-code-1.2.0-迁移笔记.md, 14,319), whether to replace that terminal in-house (7,558 bytes), a comparison of four system prompts (22,905), a survey of context compaction (30,762), a design for complexity metrics an agent can maintain (12,663), and a code review of its own v0.7.8 listing optimisations and potential bugs (7,389). Beside them sits eval/: 711 KB under eval/compaction for context-compaction evaluation, carried by fixtures of 212,244 and 162,078 bytes, and 36 files under eval/continuation with twenty small check scripts.

  5. 05

    What broke, and what the design records admit does not work

    The repository carries 1,009 stars, one fork and no issues and no pull requests at all, so the record of what went wrong lives in the tree rather than in bug reports. Some of it is in the release notes: 0.7.27 exists because the Harness composition generated an empty cordis.yml and fresh Hub installation failed; 0.7.28 broke its own users by renaming a permission preset, because DSH took the name auto; and 0.7.29 carries the admission that the host-plane workflow engine had to be disabled again after an upstream rename silently voided the patch that disabled it — a patch that stopped applying with nothing catching it. AGENTS.md adds two more: a publish job that dies after about thirty seconds at the credential check is usually a version conflict on npm rather than a missing secret, and a version already on npm from a different build cannot be re-tagged, so the version has to be bumped and a new tag cut; and make release, make verify and npm run doctor cannot run inside a dscode session, because the nested sandbox is refused, so the release gate has to be run from an ordinary terminal. The design records keep their own limits in writing: the trigger mechanism is "not an automatic retry engine", nothing consumes its runs.jsonl yet and the notifier transport is "undecided on purpose"; the agent-to-agent messaging design fixes a strict cancellation boundary at "before the claim", bounds every chain at a depth of 3, 8 new messages, one final reply, one hour, a 64,000-byte body, 100 unclaimed notes and 1 MiB per session, and says outright that it does not treat the same OS user as a security boundary, and that resisting a deliberate bypass needs sandbox isolation which the first version does not promise.

Adjacent records

All records →