Command Line
dsh is the single entry-point command — almost everything starts with a dsh.
The official zero-install entry point is npx @deepseek-ai/dsh ..., requiring Node.js ^22.19.0 or >=24.0.0. Inside the official source checkout, use pnpm dsh .... The rest of this page uses dsh ... for either available entry point.
1. Basic Usage
dsh --profile web # Start the web profile (equivalent to dsh web)
dsh web # Web UI (alias for --profile web)
dsh --profile headless "run the tests" # One-off task; exits after it completes
dsh plugin ... # Manage profile plugin dependencies
The
dsh runsubcommand has been removed; one-off tasks now use--profile headless <task>.
2. launcher flags (launcher layer)
These are consumed by dsh before being passed to the app:
--profile <name> Select $DSH_HOME/profiles/<name> (auto-initialized on first use)
--patch <path> Stack an additional overlay patch (takes precedence over the profile layer)
--dump-config Print the composition tree and exit
--dump-default-config Print only the bundle layer (no user layer / --patch)
dsh --profile web --dump-config # Inspect the web profile's full composition
dsh --profile tui --patch ./extra.yml # Start with a custom patch
Two key mechanisms:
- The launcher only eats its own flags; everything else is passed through to the app as-is. The first token the launcher does not recognize begins the "inner arguments", which flow verbatim into the config tree: for example,
dsh --profile tui --resume abchas inner arguments['--resume', 'abc'](where--resumeis a flag of the TUI app itself). - Flag position is significant: launcher flags must come before the app arguments; a
--patchplaced after an app flag belongs to the app. The launcher consumes one--; to pass a literal--through to the app, write-- --. --help/--versionare parsed and printed by the app itself, not handled centrally by the launcher.
3. Web subcommand
dsh web --port 8080 # Specify a port (0 = random)
dsh web --host 0.0.0.0 # Allow LAN access
dsh web --trusted-host <host> # Trusted host
dsh web --dump-config # Print the config tree and exit
- The Web UI listens on
127.0.0.1:3080by default - The workspace is selected with a directory picker inside the Web UI (not a CLI flag)
- Dev HMR: in the source directory,
pnpm run dev:webrebuilds the client assets anddsh webpolls for hot updates automatically
4. headless one-off tasks
--profile headless runs a one-off task: the task text is the rest of the command line, submitted as an ordinary user message, and after it finishes the last non-empty assistant text is written to stdout before exiting.
dsh --profile headless "run pnpm test, summarize the failures into a list"
dsh --profile headless "review the auth logic in src/server.ts and give 3 actionable suggestions"
dsh --profile headless "use glob to list all call sites still using the old API" > /tmp/out.txt
Behavior notes:
- Exit code:
turn/endiscompleted→0, otherwise1. - On success stderr is empty; on error the error code and message are written to stderr.
- Submits only one task, with no interactive follow-up UI; listens on no ports (no Host/Web/browser attached).
- It is a "run-and-exit" form friendly to CI/scripts, suitable for putting into a shell, cron, or Makefile.
5. Plugin management
# Install a bundle plugin (git source on one line)
dsh plugin --profile web add "github:dsh-external/<repo>#main"
# Local directory development
dsh plugin --profile web add link:/path/to/plugin
# Remove / inspect dependencies
dsh plugin --profile web remove <package>
dsh plugin --profile web why <package>
pluginforwards its arguments verbatim to pnpm, executed in the profile directory; it only accepts sources pnpm recognizes (pure git sources,link:, etc.). The&path:subpath is a format of the repository plugin mechanism itself; to install a monorepo sub-package use the repository source in the plugin panel, notdsh plugin add. After installing a bundle, restartdsh webfor it to take effect (repository plugins apply immediately).
6. Inspecting configuration
dsh web --dump-config # Composed config tree (with layer-source comments)
dsh web --dump-default-config # Bundle layer only
--dump-config is the authoritative tool for diagnosing "which layer overrode what" (see Boot and Configuration).
7. Environment variables
| Variable | Purpose |
|---|---|
DSH_HOME | Overrides the home directory (default ~/.dsh) |
DSH_TELEMETRY_DISABLED | Any non-empty value disables telemetry |
DSH_TELEMETRY_OTLP_URL | Overrides the telemetry reporting endpoint |
DSH_PERMISSION_MODE | Permission preset override |
DSH_TOOLS_MODE | Tool mounting mode |
DEEPSEEK_API_KEY etc. | provider credentials (can also live in .env) |
See Environment Variables for the full list.
8. Common command scenarios
| What you want | Command |
|---|---|
| Run a web session | dsh web |
| Run a one-off task | dsh --profile headless "task" |
| Save the result of a one-off task | dsh --profile headless "task" > /tmp/out.txt |
| Start with app-layer flags | dsh --profile tui --resume abc |
| Inspect the current composition | dsh web --dump-config |
| Bundle layer only | dsh web --dump-default-config |
| Install a plugin | dsh plugin --profile web add "github:..." |
| Install a plugin from a local directory | dsh plugin --profile web add link:/path/to/plugin |
| Start with a custom patch | dsh --profile tui --patch ./extra.yml |
Next steps
- Configuration: profile / patch / settings
- Plugins: full overview of plugin management
- Quickstart: get your first session running