deepseek-harness/apps/cli
Yichen Jiang 5ed79887fb fix(web): correct the preset-layer contracts review found stale
None of these change behavior; each said something that was not true.

`SessionCwdConflict`'s doc block had been left stranded above the
`AgentPresetConflict` inserted under it, so one class carried a comment
about the other and the second carried none.

The roster comment named a `.system` directory that does not exist; the
shipped root is `config/agent-presets/`, and `system` is the trust its
entries carry.

The real-composition test attributed the disabled `api-gateway` row to
"side effects outside this process" alongside the port and the exporter.
It is disabled for a different reason — the api-proxy cannot mount in
this layer at all — and hiding that behind the same phrase would leave a
later layer unable to tell whether the line can come out.

One test claimed to refuse an adoption while asserting only that the
header records the preset; it now says what it checks.

`PERSONA_SECTION`/`PERSONA_ORDER` existed twice, once in the registry
that declares the slot and once restated in the row that replaces it —
a drift that would land a preset's persona beside the deployment's
instead of shadowing it. The registry exports them now.

The preset conflict message read "already runs agent preset undefined"
for a session that records none, which is the shape a deployment with no
roster produces; it names that case instead, with the regression that
reaches it through the gateway.

Finally, `PresetTree.write()` drops the `loader/config-update` the
inherited method emits — recorded on the override, since a future
edit-while-running flow needs its own persistence path.
2026-08-07 00:35:30 +08:00
..
config fix(web): compose a forked session, and give the shell realm its provider 2026-08-07 00:35:30 +08:00
reference refactor(cli)!: namespace the profile and bundle manifests under dsh.profile and dsh.bundle 2026-08-06 17:28:30 +08:00
src feat(web): move the agent plane behind per-session presets 2026-08-07 00:35:30 +08:00
tests fix(web): correct the preset-layer contracts review found stale 2026-08-07 00:35:30 +08:00
composition.md feat(cli)!: dsh boots profiles; plugin subcommand manages them via pnpm 2026-08-06 06:29:06 +08:00
package.json fix: address ds-review-bot round — insert-aliasing clones, settlement gates, closure module fallback 2026-08-06 09:27:44 +08:00
README.i18n.yaml refactor(cli)!: namespace the profile and bundle manifests under dsh.profile and dsh.bundle 2026-08-06 17:28:30 +08:00
README.md refactor(cli)!: namespace the profile and bundle manifests under dsh.profile and dsh.bundle 2026-08-06 17:28:30 +08:00
README.zh.md refactor(cli)!: namespace the profile and bundle manifests under dsh.profile and dsh.bundle 2026-08-06 17:28:30 +08:00
tsconfig.json feat(cli)!: dsh boots profiles; plugin subcommand manages them via pnpm 2026-08-06 06:29:06 +08:00
tsdown.config.ts cleanup: remove TUI package and legacy dsh entrypoints 2026-08-04 13:20:28 +08:00

@deepseek-ai/dsh

English | 中文

The dsh command is the product launcher for profiles: ordered stacks of plugin-bundle patch layers under the user's own overrides. src/args.ts owns the command grammar, and src/bin.ts loads only the selected runner. Invalid commands, options from another mode, configuration errors, and boot failures exit nonzero.

Entry modes

Command Purpose
dsh --profile <name> Boot the named profile under $DSH_HOME/profiles/<name>.
dsh --profile headless "task" Run one fresh persisted session, print the final answer, and exit.
dsh web Alias of --profile web with the Web flag family (--host, --port, --dev, ...).
dsh plugin --profile <name> <pnpm args> Manage a profile's plugins by forwarding to pnpm in the profile directory.

The invoking directory is the default workspace root. The web and headless profiles auto-initialize on first use from shipped templates; any other profile must be created through dsh plugin.

Profiles

A profile directory holds a package.json (out-of-tree plugin dependencies plus the profile manifest dsh.profile with its ordered bundles list) and a cordis.patch.yml (the user's own patch layer, hot-reloaded on long-lived surfaces). The tree composes over an empty root: each bundle's patch in dsh.profile.bundles order, then the profile's cordis.patch.yml, then the home-level $DSH_HOME/cordis.patch.yml, then --patch overlays, then flag patches. Bundles named in dsh.profile.bundles resolve from the dsh installation first (@deepseek-ai/dsh-base, @deepseek-ai/dsh-web-app, @deepseek-ai/dsh-headless), then from the profile's own node_modules, where pnpm installs out-of-tree plugins. Use --dump-default-config and --dump-config to inspect the composed tree without booting it.

The CLI behavior reference owns exact layer precedence, flags, shutdown behavior, deployment defaults, and the source launcher.

Development

Production runs require built package and frontend artifacts. From a checkout, pnpm run dsh runs the TypeScript entry and forwards arguments; the source-launcher reference describes the PATH symlink and module-resolution contract.