diff --git a/apps/cli/README.i18n.yaml b/apps/cli/README.i18n.yaml index 3b54366fab..7e4aacef29 100644 --- a/apps/cli/README.i18n.yaml +++ b/apps/cli/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/README.md -README.md: 25f201a082961db9cd4760334d2ab07a13deab89 -README.zh.md: f288bf61b77e5fe5cfdafafdc1fdfbf9f5669582 +README.md: 2bc36cce6205a4bfc3ba1d7ee15f0e0b2feab215 +README.zh.md: 0e0771658cecb4bee0f3eadd0639ad531e64ea3c diff --git a/apps/cli/README.md b/apps/cli/README.md index 25f201a082..2bc36cce62 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -18,7 +18,7 @@ The TUI surface: `dsh upgrade` is a guided fresh-session entry over the default TUI surface: it mints a fresh session in the invoking directory and seeds its first turn with the bundled `dsh-upgrade` skill, exactly as if the user typed `/skill:`. The launcher passes the skill name on the boot context ([`INITIAL_SKILL_KEY`](../../packages/ui/tui/README.md)), which the TUI auto-invokes once the chat is live. Both take no options — `--config`, `-p`, and `--resume` fail loud — and seed only on this first launch, so a later `dsh --resume ` of the session is an ordinary TUI session with no re-injection. -The Web and headless surfaces boot `base.cordis.yml` plus `web.cordis.yml`; `dsh web --config ` adds an overlay after the web surface defaults. Both surfaces otherwise share the same composition: both treat the invoking directory as the default project and Workspace root, create named Workspaces beneath that root unless `--workspace-root ` overrides it, load applicable `AGENTS.md`/`CLAUDE.md` instructions into each agent-loop request prefix with a 65,536-byte render budget, and opt into first-message model titles. Headless differs only in listening on an OS-assigned port (parallel `dsh -p` runs never collide; the stderr-printed URL opens the live session in a browser). Both need the frontend dist and client bundles built (`pnpm run build && pnpm run build:web`). +The Web and headless surfaces boot `base.cordis.yml` plus `web.cordis.yml`, then apply `$DSH_HOME/config.yaml`; an explicit `--config ` replaces that personal overlay. Both surfaces otherwise share the same composition: both treat the invoking directory as the default project and Workspace root, create named Workspaces beneath that root unless `--workspace-root ` overrides it, load applicable `AGENTS.md`/`CLAUDE.md` instructions into each agent-loop request prefix with a 65,536-byte render budget, and opt into first-message model titles. Headless differs only in listening on an OS-assigned port (parallel `dsh -p` runs never collide; the stderr-printed URL opens the live session in a browser). Both need the frontend dist and client bundles built (`pnpm run build && pnpm run build:web`). 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. diff --git a/apps/cli/README.zh.md b/apps/cli/README.zh.md index f288bf61b7..0e0771658c 100644 --- a/apps/cli/README.zh.md +++ b/apps/cli/README.zh.md @@ -18,7 +18,7 @@ TUI 界面: `dsh upgrade` 是默认 TUI 界面之上的引导式全新会话入口:它在调用目录中创建一个全新会话,并以内置 `dsh-upgrade` skill 播种其首轮,效果等同于用户手动键入 `/skill:`。启动器将 skill 名称提供到启动上下文([`INITIAL_SKILL_KEY`](../../packages/ui/tui/README.md)),TUI 在聊天就绪后自动调用它。两者都不接受任何选项——`--config`、`-p`、`--resume` 都会明确报错——且仅在首次启动时播种,因此之后 `dsh --resume ` 恢复该会话时是普通 TUI 会话,不会重复注入。 -Web 和无头界面启动 `base.cordis.yml` 与 `web.cordis.yml`;`dsh web --config ` 会在 Web 界面默认值之后追加一个覆盖。除此之外,两者共享同一套组合:两者都将调用目录视为默认项目和 Workspace 根目录,除非通过 `--workspace-root ` 覆盖,否则会在该根目录下创建具名 Workspace;它们会把适用的 `AGENTS.md`/`CLAUDE.md` 指令加载到每个 agent-loop 请求前缀中,渲染预算为 65,536 字节,并选用首条消息模型标题。无头界面唯一的差异是监听操作系统分配的端口(并行 `dsh -p` 运行绝不冲突;stderr 打印的 URL 会在浏览器中打开实时会话)。两者都需要先构建前端 dist 和客户端 bundle(`pnpm run build && pnpm run build:web`)。 +Web 和无头界面启动 `base.cordis.yml` 与 `web.cordis.yml`,随后应用 `$DSH_HOME/config.yaml`;显式的 `--config ` 会替代该个人覆盖。除此之外,两者共享同一套组合:两者都将调用目录视为默认项目和 Workspace 根目录,除非通过 `--workspace-root ` 覆盖,否则会在该根目录下创建具名 Workspace;它们会把适用的 `AGENTS.md`/`CLAUDE.md` 指令加载到每个 agent-loop 请求前缀中,渲染预算为 65,536 字节,并选用首条消息模型标题。无头界面唯一的差异是监听操作系统分配的端口(并行 `dsh -p` 运行绝不冲突;stderr 打印的 URL 会在浏览器中打开实时会话)。两者都需要先构建前端 dist 和客户端 bundle(`pnpm run build && pnpm run build:web`)。 已交付的 TUI 和 Web 组合会注册原生 DeepSeek 适配器,以及 pi-ai 的 OpenAI 和 Anthropic 提供方配置。凭据和端点覆盖来自启动分层环境中的提供方标准变量对:`DEEPSEEK_API_KEY` / `DEEPSEEK_BASE_URL`、`OPENAI_API_KEY` / `OPENAI_BASE_URL` 和 `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`。 diff --git a/apps/cli/src/app-cli-entry.ts b/apps/cli/src/app-cli-entry.ts index ab86f1f77f..9f258257b7 100644 --- a/apps/cli/src/app-cli-entry.ts +++ b/apps/cli/src/app-cli-entry.ts @@ -17,7 +17,7 @@ import type { FiberState } from 'cordis' import Loader from '@cordisjs/plugin-loader' import Include, { type PatchOptions } from '@cordisjs/plugin-include' import yaml from 'js-yaml' -import { assertEntriesLoaded, installFailLoud, loadEnv, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' +import { assertEntriesLoaded, installFailLoud, loadEnv, loadOverlayPatches, loadPersonalPatches } from '@deepseek-ai/dsh-app-boot' import { resolveDshHome, resolveSessionsRoot } from '@deepseek-ai/dsh-paths' // Empty type import carries the httpServer Context merge for the port read below. import type {} from '@deepseek-ai/dsh-host-webserver' @@ -110,9 +110,9 @@ export interface AppCLIEntryOptions { */ overlayPath: string /** - * Optional extra overlay applied after {@link overlayPath} and before this - * entry's own profile/flag patches — the `--config` escape for demos and - * tests that need a row this surface does not ship. + * Optional explicit overlay applied after {@link overlayPath} and before + * this entry's own profile/flag patches. When absent, the personal + * `$DSH_HOME/config.yaml` overlay is applied instead. */ extraOverlayPath?: string /** Whether to append the HMR row (the whole prod/dev difference; web surface only). */ @@ -243,7 +243,7 @@ export class AppCLIEntry { const patches = [ ...loadOverlayPatches('dsh', this.options.overlayPath), ...this.options.extraOverlayPath === undefined - ? [] + ? loadPersonalPatches('dsh') ?? [] : loadOverlayPatches('dsh', this.options.extraOverlayPath), ...this.patches, ] diff --git a/apps/cli/src/web.ts b/apps/cli/src/web.ts index d6e0c159d4..af97d82af3 100644 --- a/apps/cli/src/web.ts +++ b/apps/cli/src/web.ts @@ -27,7 +27,8 @@ const LOOPBACK_HOST = '127.0.0.1' * @param workspaceRoot - parent directory for name-created workspaces, or `undefined` for the gateway's cwd fallback. * @param trustedHosts - extra authorities for the /api browser-trust fence, or `undefined` for the derived LAN literals alone. * @param config - an overlay of loader patches applied over the shipped web - * composition, or `undefined` for none; already parsed from `--config`. + * composition instead of `$DSH_HOME/config.yaml`, or `undefined` to use the + * personal overlay; already parsed from `--config`. */ export async function runWeb( host: string | undefined,