Browse Source

feat(inspector): add the development mount overlay and demo script

imccyu 1 month ago
parent
commit
15572ddb22

+ 6 - 0
.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# 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 .agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.md
+2026-08-27-inspector-development-mount.md: 0e5f0af52306ebb553e4fb911696cfc3fae087ee
+2026-08-27-inspector-development-mount.zh.md: 252e52692df2ad983e6da9ee9640c5ae6603f20f

+ 30 - 0
.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.md

@@ -0,0 +1,30 @@
+# Agent Note: Inspector development mount
+
+Status: implemented
+
+English | [中文](2026-08-27-inspector-development-mount.zh.md)
+
+## Problem
+
+`@deepseek-ai/dsh-experimental-inspector` is a private package no published dsh installation carries, yet development launches need to mount it into the shipped Web composition on demand. A row in a shipped bundle patch cannot express this: `verify-cordis-config` requires every named row of a bundle patch to resolve from that bundle's own `dependencies` — disabled rows included — and a published manifest must not depend on an unpublished package.
+
+## Decision
+
+The inspector package owns a development overlay, `packages/experimental/inspector/cordis.patch.yml`, holding a single `insert` of the `experimental-inspector` row. A launch selects it through the generic overlay flag; `pnpm run demo:inspector` is the shorthand for `pnpm dsh web --patch ./packages/experimental/inspector/cordis.patch.yml`.
+
+The overlay contributes only the row; the row's module resolves from the profile plane at entry import:
+
+- A source launch (`pnpm dsh`, tsx) resolves the workspace package through the tsconfig `paths` facade and needs no installation.
+- A built launch (`node apps/cli/lib/bin.js`) needs the package importable from the profile first: `dsh plugin --profile web add link:<absolute package path>`, once per profile. `link:` keeps dependency resolution inside the real package directory; `file:` re-installs the package's `workspace:^` dependencies in the profile and fails with `ERR_PNPM_WORKSPACE_PKG_NOT_FOUND`.
+
+A launch whose profile cannot import the package fails loud at entry import (`Cannot find package '@deepseek-ai/dsh-experimental-inspector' imported from <profile dir>`); nothing is skipped silently.
+
+## Consequences
+
+Published packages carry no trace of the inspector: no manifest entry, no composition row, no launcher flag. Mounting stays a per-launch choice — the same service without the overlay never loads the package — and every layer the launch composes is declared in a config file. The cost is launch-mode asymmetry: a built launch needs the one-time profile `link:` install, and the overlay must be named on every invocation, which `pnpm run demo:inspector` absorbs for the common case.
+
+## Alternatives considered
+
+- A `disabled: !!js` row in the shipped web-app patch: the dependency gate and npm publication both force the private package into the published manifest.
+- A `--inspector` launcher flag mounting the package as an extra bundle layer: the launcher owns neither app flags nor plugin package names.
+- An optional `peerDependencies` entry on `dsh-web-app` plus a dynamic `ctx.loader.create` from its glue plugin: it writes a never-published name into a published manifest and mounts a row no config layer declares.

+ 30 - 0
.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.zh.md

@@ -0,0 +1,30 @@
+# Agent Note:Inspector 开发挂载
+
+Status: implemented
+
+[English](2026-08-27-inspector-development-mount.md) | 中文
+
+## Problem
+
+`@deepseek-ai/dsh-experimental-inspector` 是任何已发布 dsh 安装都不携带的 private 包,但开发启动需要按需把它挂进随货 Web 组合。随货 bundle patch 里的一行表达不了这件事:`verify-cordis-config` 要求 bundle patch 中每个具名行都能从该 bundle 自己的 `dependencies` 解析——disabled 行也不豁免——而已发布的 manifest 不得依赖未发布的包。
+
+## Decision
+
+inspector 包自有一份开发 overlay,`packages/experimental/inspector/cordis.patch.yml`,只含一个 `insert` 的 `experimental-inspector` 行。启动通过通用 overlay flag 选它;`pnpm run demo:inspector` 是 `pnpm dsh web --patch ./packages/experimental/inspector/cordis.patch.yml` 的简写。
+
+overlay 只贡献这一行;行的模块在 entry import 时从 profile 平面解析:
+
+- 源码启动(`pnpm dsh`,tsx)经 tsconfig `paths` 门面解析 workspace 包,无需任何安装。
+- built 启动(`node apps/cli/lib/bin.js`)需先让包可从 profile import:`dsh plugin --profile web add link:<包目录绝对路径>`,每个 profile 一次。`link:` 让依赖解析留在真实包目录内;`file:` 会在 profile 里重装该包的 `workspace:^` 依赖并以 `ERR_PNPM_WORKSPACE_PKG_NOT_FOUND` 失败。
+
+profile 无法 import 该包的启动会在 entry import 处响亮失败(`Cannot find package '@deepseek-ai/dsh-experimental-inspector' imported from <profile dir>`);不存在静默跳过。
+
+## Consequences
+
+已发布的包不携带 inspector 的任何痕迹:没有 manifest 条目、没有组合行、没有 launcher flag。挂载保持按次启动选择——不带 overlay 的同一服务永远不会加载该包——且启动组合的每一层都由 config 文件声明。代价是启动方式不对称:built 启动需要一次性 profile `link:` 安装,且每次调用都要点名 overlay,常见场景由 `pnpm run demo:inspector` 吸收。
+
+## Alternatives considered
+
+- 随货 web-app patch 里放 `disabled: !!js` 行:依赖门禁与 npm 发布都会把 private 包逼进已发布 manifest。
+- `--inspector` launcher flag 把包挂成额外 bundle 层:launcher 既不拥有 app flag 也不拥有插件包名。
+- `dsh-web-app` 上加 optional `peerDependencies` 并由其 glue 插件动态 `ctx.loader.create`:向已发布 manifest 写入永不发布的名字,且挂载的行不在任何 config 层声明。

+ 1 - 0
package.json

@@ -147,6 +147,7 @@
     "release:publish": "tsx scripts/release/publish.ts",
     "dsh": "node --import tsx/esm apps/cli/src/bin.ts",
     "demo:code-mode": "node scripts/demo-code-mode.mjs",
+    "demo:inspector": "pnpm dsh web --patch ./packages/experimental/inspector/cordis.patch.yml",
     "mock:llm": "node --import tsx packages/test-support/llm-mock-server/src/bin.ts",
     "dev:web": "tsx scripts/dev-web.ts --poll",
     "postinstall": "node scripts/install-lefthook.mjs"

+ 13 - 0
packages/experimental/inspector/cordis.patch.yml

@@ -0,0 +1,13 @@
+# Development overlay for the experimental inspector: mount it per launch with
+#   pnpm run demo:inspector        (pnpm dsh web --patch ./packages/experimental/inspector/cordis.patch.yml)
+# A source launch resolves this workspace package through the tsconfig paths
+# facade and needs no installation. A built launch additionally needs the
+# package importable from the profile:
+#   dsh plugin --profile web add link:<absolute path to this package directory>
+# (`link:`, not `file:` — `file:` re-installs the workspace:^ dependencies
+# inside the profile and fails). The package is private and ships with no
+# published dsh installation; a missing package fails loud at entry import.
+
+- insert:
+    - id: experimental-inspector
+      name: '@deepseek-ai/dsh-experimental-inspector'