2nd dokployH
Find a file
Yichen Jiang 8d06b2d576 feat(agent-presets): make the default preset a user setting
`config.default` becomes the composition base of an `agent-presets` settings
namespace, so the user document layers over the deployment's engineering
default and a person can change which preset new sessions get without a
restart.

The value is read per resolution rather than snapshotted: a hot-reloaded
document takes effect on the next session created, and every running session
stays on the preset it was composed from — which is the same rule the
session-header guard enforces from the other side.

`resolve()` read `config.default` directly, which would have made the whole
setting inert; it now goes through `defaultId` like every other caller.

The write-protection test is rewritten against a temp profile root. It was
passing vacuously: the un-overridden Loader REWRITES the composition it read —
stamping `disabled: true` onto the self-disposing row — so the committed
fixture had been mutated by the very run that proved the bug, and every later
run compared against the damaged file and passed. Building the preset in a
temp directory makes the assertion immune to its own failure mode, and it now
fails with a visible `+ disabled: true` when the override is removed.

Review follow-ups on this layer. The exported schema is
`AgentPresetSettingsSchema`, symmetric with the `AgentPresetSettings`
interface it resolves and self-describing at an import site. The `session.create`
JSDoc promised "the deployment's default preset" for an omitted `agentPreset`,
which this layer makes false — it now names the effective default. The
constructor records why it does not use `installSettingsSection`: that helper
re-judges what a consumer DERIVED across attach and detach, and nothing here is
derived. The provider-unload test disposes the fiber `ctx.plugin()` handed back
instead of reaching into `ctx.reflect.store`, and the write-protection wait says
why slack is the right shape for an absence assertion.

The real composition covers the layering too. `apps/cli` boots the shipped
`cordis.yml`, stores `agent-presets.default`, and asserts an unnamed session
composes from it — the package suite proves the layering against a hand-built
context, this proves the roster and the settings provider are wired to each
other. That test also pins the settings row at a temp file: it defaulted to
`$DSH_HOME/settings.yaml`, so a developer's own stored default decided the
outcome of a file whose whole point is that only the shipped root does.

The Agent Note records the per-resolution read and its correspondence with the
session header, and the vacuous-test finding above.
2026-08-07 00:36:54 +08:00
.agents feat(agent-presets): make the default preset a user setting 2026-08-07 00:36:54 +08:00
.claude docs: accuracy sweep, architecture restructure, two ADRs, review skill 2026-06-13 22:05:34 +08:00
.github chore: enable Issue management automation 2026-08-03 19:53:36 +08:00
apps feat(agent-presets): make the default preset a user setting 2026-08-07 00:36:54 +08:00
assets docs: make the top-level README product-first 2026-07-23 00:15:44 +08:00
bin feat(cli): enable Node environment proxy in launcher 2026-07-30 16:53:35 +08:00
docs feat(agent-presets): make the default preset a user setting 2026-08-07 00:36:54 +08:00
examples fix(web): correct the preset-layer contracts review found stale 2026-08-07 00:35:30 +08:00
native docs: rescan rebased documentation hierarchy 2026-08-05 16:16:57 +08:00
packages feat(agent-presets): make the default preset a user setting 2026-08-07 00:36:54 +08:00
patches cleanup: remove TUI package and legacy dsh entrypoints 2026-08-04 13:20:28 +08:00
python feat(app-boot): register cordis:group beside cordis:include 2026-08-07 00:34:19 +08:00
scripts feat(agent-presets): compose each session's agent from a preset cordis.yml 2026-08-06 21:03:18 +08:00
skills docs: rescan rebased documentation hierarchy 2026-08-05 16:16:57 +08:00
vendor fix: retire leftovers of the removed $DSH_HOME/config.yaml personal overlay 2026-08-06 17:28:58 +08:00
website docs: tutorial for packaging and installing a plugin bundle 2026-08-06 17:28:40 +08:00
.editorconfig Declare LF and final-newline conventions in .editorconfig 2026-07-15 16:09:12 +08:00
.gitattributes Merge remote-tracking branch 'origin/master' into fix/web-transcript-projection 2026-07-31 17:17:00 +08:00
.gitignore Merge commit 'refs/codex/pr885/master-20260730' into worktree/retarget-pr885-20260729 2026-07-30 01:18:28 +08:00
.gitlab-ci.yml python: derive release version from repository 2026-07-13 17:49:01 +08:00
.jscpd.json chore(lint): bring .tsx files into the eslint, lefthook, and jscpd lanes 2026-07-27 21:42:08 +08:00
.oxlintrc.json Merge commit 'refs/codex/pr885/master-20260730' into worktree/retarget-pr885-20260729 2026-07-30 01:18:28 +08:00
AGENTS.md feat(bundle): ship dsh-base, dsh-web-app, and dsh-headless profile bundles 2026-08-06 04:40:11 +08:00
CLAUDE.md Initialize repo with README, AGENTS.md, and CLAUDE.md symlink 2026-06-10 22:58:56 +08:00
eslint.format.config.mjs Merge commit 'refs/codex/pr885/master-20260730' into worktree/retarget-pr885-20260729 2026-07-30 01:18:28 +08:00
knip.json Merge remote-tracking branch 'origin/master' into feat/profile-plugin-management 2026-08-06 06:55:42 +08:00
lefthook.yml docs: close the remaining silent-omission paths in the notices generator 2026-07-30 10:28:16 -07:00
LICENSE Initialize repo with README, AGENTS.md, and CLAUDE.md symlink 2026-06-10 22:58:56 +08:00
package.json ci: print exact uncovered locations when the coverage gate fails 2026-08-06 03:18:17 +08:00
pnpm-lock.yaml feat(agent-presets): make the default preset a user setting 2026-08-07 00:36:54 +08:00
pnpm-workspace.yaml pkg: upgrade node-addon 2026-08-05 01:11:49 +08:00
pytest.ini Merge remote-tracking branch 'origin/master' into codex/trim-ai-prose 2026-07-14 00:40:36 +08:00
README.i18n.yaml docs: profile scheme across guides, notes, and generated catalogs; Agent Note 2026-08-06 06:29:06 +08:00
README.md docs: profile scheme across guides, notes, and generated catalogs; Agent Note 2026-08-06 06:29:06 +08:00
README.zh.md docs: profile scheme across guides, notes, and generated catalogs; Agent Note 2026-08-06 06:29:06 +08:00
THIRD_PARTY_NOTICES.md Merge remote-tracking branch 'origin/master' into feat/md-incre-2 2026-08-06 14:37:56 +08:00
tsconfig.base.client.json refactor(tsconfig): single root solution graph over host/client aggregates 2026-07-23 03:59:05 +08:00
tsconfig.base.json feat(agent-presets): compose each session's agent from a preset cordis.yml 2026-08-06 21:03:18 +08:00
tsconfig.client.json docs(client): correct checkpoint pin contract 2026-07-31 09:29:19 +08:00
tsconfig.host.json feat(persona): make the agent persona a composable row 2026-08-07 00:35:30 +08:00
tsconfig.json refactor(tsconfig): single root solution graph over host/client aggregates 2026-07-23 03:59:05 +08:00
tsdown.config.ts refactor(tsconfig): single root solution graph over host/client aggregates 2026-07-23 03:59:05 +08:00
vitest.config.ts ci: print exact uncovered locations when the coverage gate fails 2026-08-06 03:18:17 +08:00
vitest.e2e.config.ts fix(test): isolate jsdom storage on Node 26 2026-07-30 21:49:33 +08:00
vitest.shared.ts fix(test): isolate jsdom storage on Node 26 2026-07-30 21:49:33 +08:00
vitest.snapshot.config.ts Merge pull request #1369 from deepseek-harness/codex/remove-dsh-tui-entrypoint 2026-08-04 14:11:37 +08:00
vitest.web-stress.config.ts test(web): add opt-in reasoning chunk stress lane 2026-08-04 14:37:31 +08:00
vitest.web.config.ts fix(test): isolate jsdom storage on Node 26 2026-07-30 21:49:33 +08:00
vitest.web.perf.config.ts test: add opt-in web performance scenario 2026-08-04 14:23:34 +08:00

DeepSeek Harness

English | 中文

DeepSeek Harness (dsh) is an open-source coding agent built on the DeepSeek Harness SDK.

It uses an architecture where everything is a plugin.

Internal testing notice

DeepSeek Harness is under internal testing. Features and interfaces may change.

The internal build uploads all Session Logs by default to help diagnose reported problems. Set DSH_TELEMETRY_DISABLED=1 to disable telemetry. Send feedback through the internal WeChat group.

Install

Clone the repository, then run the installer:

git clone <repo-url>
cd deepseek-harness
scripts/install.sh

The installer requires git and Node ^22.19 || >=24, offers to install pnpm when it is missing, prompts for a DeepSeek API key, builds the required repository artifacts, and launches the Web UI.

The default active checkout is ~/.dsh/source/current, and the launcher is linked into ~/.local/bin. Re-run the installer to update. scripts/install.sh owns alternate locations, update mechanics, and recovery options.

Use DeepSeek Harness

Web UI

For the recommended local interface, choose Web UI when the installer finishes. To start it later, or after updating the active checkout, build the repository and run:

(cd ~/.dsh/source/current && pnpm run build)
dsh web

The path above is the installer's default. If you set DSH_SOURCE or DSH_CURRENT, or reused an existing checkout, replace ~/.dsh/source/current with that checkout path; see scripts/install.sh for details. The Web UI is served at http://127.0.0.1:3080 by default.

Profiles

dsh boots profiles — ordered stacks of plugin-bundle patch layers under your own overrides in $DSH_HOME/profiles/<name>:

dsh --profile web                       # the browser UI (same as: dsh web)
dsh plugin --profile tui add <package>  # install a plugin into a custom profile
dsh --profile tui                       # boot it

The CLI contract describes profile layout, layer semantics, and config dump commands.

Headless

Run one task, print the final answer, and exit:

dsh --profile headless "summarize this workspace"

Automation and SDKs

From a source checkout with DEEPSEEK_API_KEY in the environment or its root .env, start the ACP automation server:

pnpm run demo:acp

The Python SDK drives a bundled JSON-RPC runtime. The examples cover the runnable headless, ACP, JSON-RPC, Code Mode, and self-referential compositions.

Why DeepSeek Harness

Built-in capabilities cover file reading, editing, and search; shell and persistent PTY execution; reusable skills; task tracking, goals, plans, todos, and background tasks; subagents and workflows; sandboxing and approvals; settings and credentials; persistent, resumable, forkable, and queryable sessions; LSP and web access; context compaction; and telemetry. Each composition selects the subset appropriate to its surface. The Web UI includes Plan Mode.

  • Everything is a plugin. Models, tools, policies, storage, context management, and interfaces are composable Cordis plugins, so deployments can extend or replace behavior without forking the agent loop. See the architecture for the underlying design.
  • Runs are reconstructable. Anything visible to the model is logged in the authoritative session stream; persistence, resume/fork/query, replay, telemetry, and UIs derive from the same events. See the session-log architecture.
  • Code Mode (opt-in). It exposes a run_code tool and a generated TypeScript SDK; only program output re-enters model context. See Code Mode.
  • Self-referential Cordis tools are opt-in. They let the agent inspect its live runtime and mount or unmount plugins while it runs. See the Cordis tools.

Community

Follow DeepSeek Harness on Twitter for project updates.

Development

Start with the development guide and read the architecture before changing packages.

For agents, follow AGENTS.md.

DeepSeek Harness is currently in internal testing.

License

BSD 3-Clause

Third-party dependencies and their licenses are disclosed in THIRD_PARTY_NOTICES.md.