Просмотр исходного кода

docs(plugin-manager): make the README examples self-contained

The two `ts` fences declare their inputs and import what they use, so the
doc-typecheck gate compiles them against the workspace API instead of
failing on the names the surrounding prose supplied.
Yichen Jiang 4 недель назад
Родитель
Сommit
8a0aeccccc

+ 2 - 2
packages/boot/plugin-manager/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 packages/boot/plugin-manager/README.md
-README.md: 07eee8b2b95d5d3a1860d12b1bc804a5f0a3fde2
-README.zh.md: e20bd584257ee75b74b187a0c61bb4c358377a94
+README.md: c488373c22b696d3dfe605335cc11d8b942cc75a
+README.zh.md: 4cdfa4c90b6f5fc91c1a29255b09bdda566f588d

+ 17 - 0
packages/boot/plugin-manager/README.md

@@ -30,6 +30,12 @@ English | [中文](README.zh.md)
 Build a `PluginInstaller` from the profile directory, the install anchor (the dsh app's `package.json`), a `loadProfile` that answers the profile's composed layers, the tooling bounds, and a sink for pnpm's output; then `add(spec)` or `remove(name)`:
 
 ```ts
+import { loadProfile } from '@deepseek-ai/dsh-app-boot'
+import { PluginInstaller } from '@deepseek-ai/dsh-plugin-manager'
+
+declare const profileDir: string
+declare const installAnchor: string
+
 const installer = new PluginInstaller({
   profileDir, profileName: 'web', installAnchor,
   loadProfile: () => loadProfile('dsh', 'web', installAnchor, undefined, { userLayer: false }),
@@ -37,6 +43,7 @@ const installer = new PluginInstaller({
   installLog: (chunk) => process.stdout.write(chunk.text),
 })
 const outcome = await installer.add('@acme/dsh-sql-tool')
+console.log(outcome.installed, outcome.removed)
 ```
 
 `add` takes a pnpm spec — a registry name, a `github:` or git URL, a tarball, an absolute path — runs `pnpm add`, records what pnpm wrote to `dependencies`, and probes every new package. A successful `pnpm add` is not yet an installed plugin: a package that declares neither a bundle nor a plugin module, or a bundle whose row id a composed layer already owns, is removed again with `pnpm remove` and listed under `removed` with the reason; a package the probe refused stays installed for a view to explain. New bundles are left disabled and listed under `installedOnly`, so the caller decides whether to enable them — the CLI always does, the Web host only when asked. A non-zero exit, a spawn failure, or the timeout fails the call with `plugins/install-failed` and the tail of the log, and the profile manifest is restored to what it was before the run.
@@ -46,12 +53,22 @@ const outcome = await installer.add('@acme/dsh-sql-tool')
 Build a `PluginManager` over the Cordis context and readers for what it needs per call — the profile runtime, the preset roster's layers, and the running-agent count — so a composition that gains or lacks one of them is answered at call time rather than at mount:
 
 ```ts
+import type { Context } from '@deepseek-ai/cordis'
+import type {} from '@deepseek-ai/dsh-agent'
+import type {} from '@deepseek-ai/dsh-agent-presets'
+import type {} from '@deepseek-ai/dsh-app-boot'
+import { PluginManager, type PluginToolingConfig } from '@deepseek-ai/dsh-plugin-manager'
+
+declare const ctx: Context
+declare const config: PluginToolingConfig
+
 const manager = new PluginManager(ctx, {
   config,
   runtime: () => ctx.get('profileRuntime'),
   presets: () => ctx.get('agentPresets'),
   runningAgents: () => (ctx.get('agents')?.list() ?? []).filter(agent => agent.status === 'running').length,
 })
+console.log(await manager.list())
 ```
 
 `list` returns one view per package the profile knows: its template and installed bundles and every other installed dependency. A view carries the manifest facts (name, version, title, description, `engines.dsh`), what the package is (`bundle`, `plugin`, or `library`), who supplied it (`builtin` or `external`), when its rows mount (`boot` or `runtime`), whether it is installed and enabled, and a folded `status`: `running`, `partial`, or `failed` for an enabled bundle by how many of its rows are active; `disabled` for an installed bundle outside the layer list; `not-enableable` when the probe refused it, with the reason; `restart-required` when the manifest and the live tree disagree on a profile that applies changes at its next start; `plain` for a library or plugin module, which is added to a composition rather than enabled. Rows come from the live tree while the bundle is composed — phase, disabled-by, and the recorded failure of an isolated row — and from the probe record otherwise, under the ids their patches declare. `addable` lists the modules the package declares in `dsh.plugins`, each with its default config and the probe's verdict.

+ 17 - 0
packages/boot/plugin-manager/README.zh.md

@@ -30,6 +30,12 @@ kind: "package-reference"
 用 profile 目录、安装锚点(dsh 应用的 `package.json`)、一个回答 profile 已组合层列表的 `loadProfile`、工具边界,以及 pnpm 输出的去处构造 `PluginInstaller`,然后 `add(spec)` 或 `remove(name)`:
 
 ```ts
+import { loadProfile } from '@deepseek-ai/dsh-app-boot'
+import { PluginInstaller } from '@deepseek-ai/dsh-plugin-manager'
+
+declare const profileDir: string
+declare const installAnchor: string
+
 const installer = new PluginInstaller({
   profileDir, profileName: 'web', installAnchor,
   loadProfile: () => loadProfile('dsh', 'web', installAnchor, undefined, { userLayer: false }),
@@ -37,6 +43,7 @@ const installer = new PluginInstaller({
   installLog: (chunk) => process.stdout.write(chunk.text),
 })
 const outcome = await installer.add('@acme/dsh-sql-tool')
+console.log(outcome.installed, outcome.removed)
 ```
 
 `add` 接受一个 pnpm spec——registry 名字、`github:` 或 git URL、tarball、绝对路径——运行 `pnpm add`,记录 pnpm 写进 `dependencies` 的内容,并探测每个新包。`pnpm add` 成功还不等于装好了插件:既不声明组合包也不声明插件模块的包,或者某个行 id 已被已组合层占有的组合包,会再以 `pnpm remove` 移除并连同原因列在 `removed` 里;探针拒绝的包保留在原处,留给视图说明。新组合包保持停用并列在 `installedOnly` 里,由调用方决定是否启用——CLI 一律启用,Web 宿主只在被要求时启用。非零退出、spawn 失败或超时都以 `plugins/install-failed` 与日志尾部让调用失败,并把 profile manifest 恢复到运行前的样子。
@@ -46,12 +53,22 @@ const outcome = await installer.add('@acme/dsh-sql-tool')
 在 Cordis 上下文之上构造 `PluginManager`,并交给它按调用读取所需之物的读取器——profile runtime、preset roster 的层、运行中的 agent 数——这样一个后来才有或始终没有其中之一的组合在调用时得到回答,而不是在挂载时:
 
 ```ts
+import type { Context } from '@deepseek-ai/cordis'
+import type {} from '@deepseek-ai/dsh-agent'
+import type {} from '@deepseek-ai/dsh-agent-presets'
+import type {} from '@deepseek-ai/dsh-app-boot'
+import { PluginManager, type PluginToolingConfig } from '@deepseek-ai/dsh-plugin-manager'
+
+declare const ctx: Context
+declare const config: PluginToolingConfig
+
 const manager = new PluginManager(ctx, {
   config,
   runtime: () => ctx.get('profileRuntime'),
   presets: () => ctx.get('agentPresets'),
   runningAgents: () => (ctx.get('agents')?.list() ?? []).filter(agent => agent.status === 'running').length,
 })
+console.log(await manager.list())
 ```
 
 `list` 为 profile 知道的每个包返回一份视图:模板组合包与已安装的组合包,以及其他每个已安装的依赖。视图携带 manifest 事实(名字、版本、标题、描述、`engines.dsh`),这个包是什么(`bundle`、`plugin` 或 `library`),谁提供它(`builtin` 或 `external`),它的行何时挂载(`boot` 或 `runtime`),是否已安装与已启用,以及折叠出的 `status`:已启用的组合包按活跃行的多少是 `running`、`partial` 或 `failed`;已安装但不在层列表中的组合包是 `disabled`;探针拒绝时是 `not-enableable` 并附原因;在启动时才应用变更的 profile 上 manifest 与在线树不一致时是 `restart-required`;库或插件模块是 `plain`,它们被添加进组合而不是被启用。组合包已组合时行来自在线树——阶段、被谁停用,以及隔离行记录的失败——否则来自探针记录,id 保持各自 patch 声明的样子。`addable` 列出包在 `dsh.plugins` 里声明的模块,各自带默认配置与探针的判定。