Merge remote-tracking branch 'origin/master' into worktree/pr1018-todo-retarget-20260731

# Conflicts:
#	apps/cli/README.i18n.yaml
#	packages/ui/tui/README.i18n.yaml
This commit is contained in:
Tianyi Cui
2026-07-31 19:23:34 +08:00
53 changed files with 1113 additions and 150 deletions

View File

@@ -25,9 +25,9 @@ The Web and headless surfaces boot `base.cordis.yml` plus `web.cordis.yml`, then
The shipped TUI and Web compositions register the native DeepSeek adapter plus pi-ai OpenAI and Anthropic profiles. Credentials and endpoint overrides come from the provider-standard `DEEPSEEK_API_KEY` / `DEEPSEEK_BASE_URL`, `OPENAI_API_KEY` / `OPENAI_BASE_URL`, and `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL` pairs in the boot's layered environment.
The Web/headless composition also registers only `web_search`. Search uses DeepSeek's Anthropic-compatible Messages endpoint, resolves the same `DEEPSEEK_API_KEY` reference for every call, and accepts the separate `DEEPSEEK_SEARCH_BASE_URL` endpoint override; each search is an auxiliary model request with its own latency and token cost. `web_fetch` remains disabled and the composition mounts no default fetch provider, so deployments that need arbitrary page retrieval must opt in through an overlay. The TUI composition does not mount Web tools by default. The deployment decision and its security boundary live in the [default Web search Agent Note](../../.agents/notes/implemented/feature/2026-07-31-web-default-search.md).
Every surface also registers `web_search` and only `web_search`. Search uses DeepSeek's Anthropic-compatible Messages endpoint, resolves the same `DEEPSEEK_API_KEY` reference for every call, and accepts the separate `DEEPSEEK_SEARCH_BASE_URL` endpoint override; each search is an auxiliary model request with its own latency and token cost. `web_fetch` remains disabled and the composition mounts no default fetch provider, so deployments that need arbitrary page retrieval must opt in through an overlay. The deployment decision and its security boundary live in the [default Web search Agent Note](../../.agents/notes/implemented/feature/2026-07-31-web-default-search.md).
`DSH_TOOLS_MODE` selects the tool presentation mode for the whole Web/headless process: `native` (the schema default when unset), `code` (the `run_code`-only Code Mode wire), or `both`; any other value fails loud at boot through the `dsh-tools` config schema. It is a TEMPORARY seam — process-wide because Loader composition is static — and is removed once the web UI owns per-session tool-mode selection; the TUI surface ignores it (its config tree pins its own mode).
`DSH_TOOLS_MODE` selects the tool presentation mode for the whole Web/headless process: `native` (the schema default when unset), `code` (the `run_code`-only Code Mode wire), or `both`; any other value fails loud at boot through the `dsh-tools` config schema. It is a TEMPORARY seam — process-wide because Loader composition is static — and is removed once the web UI owns per-session tool-mode selection; the TUI surface ignores it and pins `native`.
[`core-web.cordis.yml`](config/core-web.cordis.yml) is an opt-in `dsh web --config` overlay that keeps the shipped Web host, browser, Workspace, persistence, and permission composition while reducing the default native model surface to owner-scoped persistent `bash` and `str_replace_editor`. The PTY backend and editor consume the existing Web sandbox and filesystem providers. An open persistent shell prevents changing that session's permission mode until the shell closes, so a shell created under wider access cannot survive a downgrade. `DSH_TOOLS_MODE` still controls native/Code Mode presentation for the resulting two-tool registry.
@@ -39,6 +39,23 @@ pnpm run dsh web --config apps/cli/config/core-web.cordis.yml
Every `dsh` surface — TUI, Web, and headless — reports session telemetry by default (the row lives in the shared `base.cordis.yml`): every session-log event streams as OTLP/HTTP log records to `https://harness-telemetry.deepseeksvc.com/v1/logs` on a 10-second batch cadence. `DSH_TELEMETRY_OTLP_URL` points the exporter at a different collector; setting `DSH_TELEMETRY_DISABLED` to ANY non-empty value — including `0` or `false` — disables the row before it loads (a privacy switch prefers off-by-mistake over on-by-mistake). No redaction rule is mounted in this composition yet: exported records are the raw captured copy, including message text, tool arguments and results, and the session's working-directory path. The deployment rulings live in the [web-telemetry-default-mount Agent Note](../../.agents/notes/implemented/feature/2026-07-31-web-telemetry-default-mount.md).
MCP servers are not a shipped default, because a default would have to name one: `@deepseek-ai/dsh-mcp-client` mounts exactly one server per row and spawns it as a child process, outside `ctx.bash` and so outside the sandbox policy. The package is a runtime dependency of this CLI, so an installed `dsh` can mount your own servers from `$DSH_HOME/config.yaml` or a `--config` overlay without a source checkout:
```yaml
- insert:
- id: mcp-github
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: github
transport: stdio
command: npx
args: ['-y', '@modelcontextprotocol/server-github']
env:
GITHUB_TOKEN: !!js process.env.GITHUB_TOKEN
```
The model then sees `mcp__github__*`. See the [mcp-client README](../../packages/mcp/mcp-client/README.md) for the Streamable HTTP transport and the full field table.
## Install (developer machine)
Symlink the source-running launcher onto your PATH; it resolves the checkout through its own real path, so code changes apply on the next launch with no build step: