diff --git a/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.i18n.yaml new file mode 100644 index 0000000000..1403e3a7e6 --- /dev/null +++ b/.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 diff --git a/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.md b/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.md new file mode 100644 index 0000000000..0e5f0af523 --- /dev/null +++ b/.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:`, 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 `); 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. diff --git a/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.zh.md b/.agents/notes/implemented/architecture/2026-08-27-inspector-development-mount.zh.md new file mode 100644 index 0000000000..252e52692d --- /dev/null +++ b/.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 `);不存在静默跳过。 + +## 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 层声明。 diff --git a/package.json b/package.json index bec66ae4c9..c9394768b2 100644 --- a/package.json +++ b/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" diff --git a/packages/experimental/inspector/cordis.patch.yml b/packages/experimental/inspector/cordis.patch.yml new file mode 100644 index 0000000000..56da3b95df --- /dev/null +++ b/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: +# (`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'