Files
deepseek-harness/apps/cli
Turtle 03e70034e6 refactor(agent-preset): consolidate creator skills into dsh-doc (#6633)
* feat(release): publish package source, declaration maps, and documentation

Every release member publishes its TypeScript source and the declaration
maps that resolve into it, and @deepseek-ai/dsh publishes the repository
Markdown documentation staged from docs/ at prepack time.

The ./src/* export most members already declared now resolves for an
installed consumer, and a consumer editor follows a declaration to the
implementation. Bundled JavaScript maps stay unpublished; the vendored
family and the Desktop runtime file policy are unchanged.

Rationale: .agents/notes/implemented/process/2026-10-08-published-source-and-docs.md

* feat(release): publish JavaScript maps and compress bundles

Every emitted JavaScript map ships beside the bundle it describes, and the
workspace build and the client preset compress bundles without mangling
identifiers.

The documentation payload now mirrors the website publication manifest and
is removed again by `postpack`; Desktop and the Python executable exclude
the published source, documentation, and maps; `clean` removes a staged
copy. Typert's publication contract gains the Remote declaration map.

* fix(release): keep node bundles readable for the worker image

The browser worker image lowers `yield*` only as a whole statement and
rewrites `for await` loops by their source layout, so compressed node-side
entries either fail that lowering or lower to unparseable code. Only the
browser bundles keep compression, which removes about a third of their text.

The bundle-purity assertion now matches the module-loader call regardless of
the quote style compression picks, and the release-pack fixture exercises
the installed package's new documentation requirement.

* feat(release): publish the whole documentation tree

`@deepseek-ai/dsh` copies `docs/` in full instead of the website's page
set: the maintainer documents, the generated migration records, the
translation guidelines, and the `*.i18n.yaml` consistency records ship
with the installed package, so the documentation's own links resolve
without a checkout.

* feat(release): publish the upgrade guides with the documentation

The staged documentation keeps the website's page set and adds every
`docs/upgrade-guide/` document, which is what an installed reader consults
when a released change breaks something. The rest of the maintainer tree
stays out.

* feat(agent-preset): ship plugin artwork skill with creator mode

* docs(skills): clarify artwork icon lookup and official review steps

* refactor(agent-preset): fold plugin artwork into cordis plugin development

* feat(agent-preset): require detail documents for creator bundles

* test(release): expect source and maps in master's new payload cases

* refactor(agent-preset): consolidate creator skills into dsh-doc

* feat(release): keep installed docs and source readable in Desktop

Desktop keeps the published src/ and docs/ trees inside app.asar, and
every model shell call receives DSH_INSTALL_DIR and DSH_NODE_EXECUTABLE
so an agent can read them through Electron's Node mode. Staging also
generates docs/upgrade-guide/README.md, an index of the upgrade guides
grouped by the release they upgrade from.

Minified client bundles print string literals with backticks: the
worker image packer now recognizes those chunk requests, client license
banners are prepended after minification so their text survives, and
the affected artifact tests accept either quote.

* docs(agent-preset): add dsh-doc install, upgrade, and fallback guidance

* docs(agent-preset): align dsh-doc archive reads and upgrade start versions

* docs(agent-preset): bound dsh-doc upgrade index reads and test documented commands

* test(desktop): read archived docs through the Windows PowerShell form

Regenerate the config catalog for the shifted shell-env source line.

* docs(upgrade-guide): correct dsh-doc session verification step

* test(agent-preset): use a block body for dsh-doc fixture cleanup

* test(desktop): wait for the GUI-subsystem Electron process from PowerShell

* docs(agent-preset): read the running DSH version from the installation

* build(release): publish source and maps from the message-quotes package

* docs(agent-preset): document the verified PowerShell runtime invocation

* docs(agent-preset): keep PowerShell runtime output streams and exit code

* docs(tool-cordis): describe the shipped dsh-doc skill

* docs(skills): load configuration guidance separately

* fix(skills): declare shared template details in every locale

* fix(skills): verify dsh-doc guidance through recorded sessions

* test(skills): retain current runtime reminder in dsh-doc replay

* test(snapshot): refresh terminal panel runtime context
2026-11-05 17:53:22 +08:00
..
2026-11-03 12:51:08 +08:00

@deepseek-ai/dsh

English | 中文

The dsh command is the sole supported Node application launcher: profiles are ordered stacks of plugin-bundle patch layers under the user's own overrides. SDK and ACP are profiles, not separate public bins. The Python runtime wheel packages this same command; the SDK defaults to sdk, and the minimal example selects sdk-minimal. src/args.ts owns the command grammar, and src/bin.ts loads only the selected runner. Invalid commands, options from another mode, and fatal configuration or boot failures exit nonzero.

Entry modes

Command Purpose
dsh <name> / dsh --profile <name> Boot the named profile under $DSH_HOME/profiles/<name>.
dsh --profile <name> --from-default-profile <template> Replace a custom profile with a fresh copy of a shipped template, then boot it.
dsh --profile acp Serve automation clients over ACP stdio until disconnect.
dsh --profile headless "job" Run one fresh persisted session, print the final answer, and exit.
dsh --profile sdk Serve SDK clients over JSON-RPC stdio until shutdown or disconnect.
dsh --profile sdk-minimal Serve SDK clients with the standalone minimal agent tree.
dsh web Boot the Web profile.
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, headless, sdk, sdk-minimal, and acp profiles auto-initialize on first use from shipped templates. Create or reset another profile at a non-shipped name with --from-default-profile, or initialize a base-backed profile through dsh plugin. The desktop name is reserved for the Electron-owned profile, so the CLI rejects boot and config-dump requests for it. The npm CLI also rejects its plugin-management requests; the Desktop-installed command can manage the initialized Desktop profile using that installation’s runtime.

App arguments

The launcher parses only its own flags and hands everything after them to the booted profile, where any injected app plugin may parse the shared immutable snapshot (dsh-cmdline). The first token the launcher does not recognize starts the app's arguments:

dsh --profile web --port 8080       # --port belongs to the web app
dsh --profile tui --resume <id>     # example, assuming the tui profile is installed; --resume belongs to the terminal app
dsh --profile headless "run the tests"
dsh --profile web --help            # the web app's flags, not the launcher's
dsh --help                          # the launcher's own help

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). dsh-hmr, when enabled in YAML, watches the profile manifest and both profile and home patch files, then recomposes all layers through one serialized reload. Without HMR, changes apply on restart. Edits arriving during watcher registration use the same nonfatal reload reporting as later edits. Plugin Manager shares package operations and the profile write lock with dsh plugin; package updates retain disabled bundle selections. CLI package commands inherit authentication variables and terminal descriptors, including interactive build approval; service calls retain their scrubbed environment and captured diagnostics.

Installation and profile startup enforce the declared engines.dsh range, or DSH peer ranges when it is absent, against the same runtime version shown by dsh --version. Incompatible plugins require an explicitly acknowledged exact-version exemption. The plugin manager's compatibility reference documents version-exemptions, allow-version, revoke-version, persistence, and risks.

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

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, @deepseek-ai/dsh-sdk-app, @deepseek-ai/dsh-sdk-minimal, @deepseek-ai/dsh-acp-app), 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. --dump-config-schema imports the composed tree's declared plugin schemas and prints JSON Schema for entries and patches instead of configuration values; read the schema-dump safety and scope before inspecting untrusted plugins.

The CLI behavior reference owns exact layer precedence, flags, shutdown behavior, deployment defaults, and source execution. The startup and reload failure table compares optional and required plugin failures with configuration HMR.

Optional overlays

config/examples/ ships opt-in overlays for GitHub review webhooks, memory MCP servers, and runtime Cordis tools. They are never part of a default profile; the user guides and developer practice guides own setup and safety instructions.

Installed payload

The published tarball carries the bundled runtime under lib/, the TypeScript under src/, the declaration and JavaScript maps beside the files they describe, and the documentation under docs/. Only prepack stages docs/, and postpack removes that copy again, so a reader of the working tree sees whatever the checkout holds.

docs/ holds the documentation website's pages plus every upgrade guide, with the assets those pages reference. docs/upgrade-guide/README.md is generated during staging: it groups the guides by the release each v<T> directory upgrades from and lists each guide's title, English and Chinese descriptions, and relative paths. The Desktop application carries the same docs/ and src/ inside its app.asar. The generated persistence-changes/ records, the i18n/ guidelines, and the *.i18n.yaml consistency records are not published. Its pages keep the repository's relative links, so a link into ../packages/** or into the omitted persistence-changes/ records resolves only in a checkout.

Development

Production runs require built package and frontend artifacts. From the repository root, run pnpm run build separately, then use pnpm dsh <args...> to run the TypeScript entry and forward every argument; the source-execution reference owns the module-resolution contract.

The @deepseek-ai/dsh/profile-boot export provides the shared profile lifecycle to the Desktop host. A resolved application profile supplies its own installation anchor for runtime package resolution while retaining the Harness home patch, proxy environment, telemetry switch, patch reload, and bounded shutdown.

Packaged installations call the same runCli() entry with their package-manager executable. The Desktop carrier also enables plugin operations for its initialized profile; npm launches omit these options. Installation-owned package environments apply only to plugin package operations; the invoking directory, ordinary profile selection, and agent-shell PATH retain their CLI meanings.

The Web failure matrix runs the built CLI through startup failures and native configuration HMR with awaitWriteFinish enabled in test:expected. It verifies authenticated HTTP responses, diagnostics, recovery, process exits, and disposal without model API calls; the startup acceptance also covers the shipped required Web dependencies and port conflicts.