refactor(cli)!: complete app-owned profile startup

This commit is contained in:
Turtle
2026-08-09 18:23:25 +08:00
parent 7e3a82eacc
commit d4ccfbd80f
97 changed files with 260 additions and 224 deletions

View File

@@ -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 docs/user/develop/basic/publish.md
publish.md: c81e53d75ecccd31c9051f33252854dbe156c566
publish.zh.md: c5a15be00bea838eb534dbf608c29d3832c2c0e1
publish.md: 04520b0fb7d30c716e3c87761bd38f0c25824739
publish.zh.md: 7b0e0141dc0522bb5ec356aa8cba1618c9517f09

View File

@@ -118,9 +118,19 @@ A bundle that defines a runnable app marks its startup row through the injection
inject: [cmdlineArgs]
```
That row calls `runStartup` from [`@deepseek-ai/dsh-cmdline`](../../../../packages/ui/cmdline/README.md) with the app's own commander program. The launcher hands it every argument after the launcher flags, so app-specific flags need no launcher change. Loader mounts the composition once, waits for each row's injections, and only then evaluates that row's `!!js` config against its injected context.
That row calls `runStartup` from [`@deepseek-ai/dsh-cmdline`](../../../../packages/boot/cmdline/README.md) with the app's own commander program. The launcher hands it every argument after the launcher flags, so app-specific flags need no launcher change. Loader mounts the composition once, waits for each row's injections, and only then evaluates that row's `!!js` config against its injected context.
Rows configured by those arguments inject the startup service and read it from their own `!!js` options, with the deployment value beside it as the fallback. On `--help`, the service is not provided, so those rows never activate. An app layered over another app disables the lower startup row, because one composition has one command-line owner.
Rows configured by those arguments inject the startup service and read it from their own `!!js` options, with the deployment value beside it as the fallback:
```yaml
- id: my-app
name: '@example/my-app'
inject: [myAppStartup]
config:
port: !!js ctx.myAppStartup.port ?? 8080
```
On `--help`, the service is not provided, so those rows never activate. An app layered over another app disables the lower startup row, because one composition has one command-line owner.
## Installing from GitHub: the build-script catch

View File

@@ -118,9 +118,19 @@ dsh --profile demo
inject: [cmdlineArgs]
```
该行使用应用自己的 commander program 调用 [`@deepseek-ai/dsh-cmdline`](../../../../packages/ui/cmdline/README.md) 中的 `runStartup`。启动器把自身 flag 之后的所有参数交给它,因此添加应用专属 flag 无需修改启动器。Loader 只挂载一次组合,等待每一行的注入,再基于其已注入的上下文求值该行的 `!!js` 配置。
该行使用应用自己的 commander program 调用 [`@deepseek-ai/dsh-cmdline`](../../../../packages/boot/cmdline/README.md) 中的 `runStartup`。启动器把自身 flag 之后的所有参数交给它,因此添加应用专属 flag 无需修改启动器。Loader 只挂载一次组合,等待每一行的注入,再基于其已注入的上下文求值该行的 `!!js` 配置。
受这些参数配置的行会注入启动服务,并在自己的 `!!js` 选项中读取它,同时把部署取值写在旁边作为回退。遇到 `--help` 时,该服务不会被提供,所以这些行不会激活。叠加在另一应用之上的应用会禁用下层启动行,因为一套组合只能有一个命令行所有者。
受这些参数配置的行会注入启动服务,并在自己的 `!!js` 选项中读取它,同时把部署取值写在旁边作为回退
```yaml
- id: my-app
name: '@example/my-app'
inject: [myAppStartup]
config:
port: !!js ctx.myAppStartup.port ?? 8080
```
遇到 `--help` 时,该服务不会被提供,所以这些行不会激活。叠加在另一应用之上的应用会禁用下层启动行,因为一套组合只能有一个命令行所有者。
## 从 GitHub 安装:构建脚本这道坎

View File

@@ -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 docs/user/guide/quickstart.md
quickstart.md: 6a0b292ce12b32b7993b7de56b35f1df2e7a7153
quickstart.zh.md: 008245f136e28630c7e8368eeec536e11112a885
quickstart.md: 8e883efd470fef329a7308f1017cab0b7afcdd67
quickstart.zh.md: e0e3f4e4754bca588831b6d204f77d1c97a140b3

View File

@@ -36,10 +36,10 @@ DEEPSEEK_API_KEY=sk-your-key-here
Run a non-interactive task and print its final answer:
```sh
pnpm run dsh run "summarize the architecture of this workspace"
pnpm run dsh --profile headless "summarize the architecture of this workspace"
```
`dsh run` creates and persists a fresh session, prints the final assistant answer, and exits. It starts no Web server or listening port, and a successful run leaves stderr empty.
`dsh --profile headless` creates and persists a fresh session, prints the final assistant answer, and exits. It starts no Web server or listening port, and a successful run leaves stderr empty.
## Step 3: use the Web UI
@@ -53,7 +53,7 @@ Open `http://127.0.0.1:3080`. The agent can read and write files, run commands,
## What happened
`dsh run` boots the `headless` profile: [`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) and [`dsh-headless`](../../../packages/bundle/headless/cordis.patch.yml) compose over an empty root, then the runner drives the core Agent and Session services directly. `dsh web` instead composes `dsh-base` with [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml), which owns the Host, HTTP, and browser layers. Both read the same default DeepSeek model route from `dsh-base`.
`dsh --profile headless` boots the `headless` profile: [`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) and [`dsh-headless`](../../../packages/bundle/headless/cordis.patch.yml) compose over an empty root, then the runner drives the core Agent and Session services directly. `dsh web` instead composes `dsh-base` with [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml), which owns the Host, HTTP, and browser layers. Both read the same default DeepSeek model route from `dsh-base`.
## Next steps

View File

@@ -36,10 +36,10 @@ DEEPSEEK_API_KEY=sk-your-key-here
运行一个非交互式任务并打印最终回答:
```sh
pnpm run dsh run "summarize the architecture of this workspace"
pnpm run dsh --profile headless "summarize the architecture of this workspace"
```
`dsh run` 创建并持久化一个新会话,打印最终助手回答,然后退出。它不会启动 Web 服务器或监听端口;成功运行时 stderr 为空。
`dsh --profile headless` 创建并持久化一个新会话,打印最终助手回答,然后退出。它不会启动 Web 服务器或监听端口;成功运行时 stderr 为空。
## 第三步:使用 Web UI
@@ -53,7 +53,7 @@ pnpm run dsh web
## 运行原理
`dsh run` 启动 `headless` profile[`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) 和 [`dsh-headless`](../../../packages/bundle/headless/cordis.patch.yml) 在空根之上组合,随后 runner 直接驱动 core Agent 与 Session 服务。`dsh web` 则由 `dsh-base` 与 [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml) 组合,后者拥有 Host、HTTP 与浏览器层。二者都从 `dsh-base` 读取同一个默认 DeepSeek 模型路由。
`dsh --profile headless` 启动 `headless` profile[`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) 和 [`dsh-headless`](../../../packages/bundle/headless/cordis.patch.yml) 在空根之上组合,随后 runner 直接驱动 core Agent 与 Session 服务。`dsh web` 则由 `dsh-base` 与 [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml) 组合,后者拥有 Host、HTTP 与浏览器层。二者都从 `dsh-base` 读取同一个默认 DeepSeek 模型路由。
## 下一步