Repository navigation
Replies: 1 comment
|
机制你说对了,只有一处归属要挪一下:「没有 optional」不是 loader 缺的,是 cordis 缺的;而「只警告不失败」这一半,其实已经有现成开关,只是没打开。 1.
Inject.resolve(fiber.entry!.options.inject, fiber.inject)它只是把 2. 「只警告」是可配置的,缺的是把这些 id 传进去
if (requiredIds.includes(failure.entry.options.id)) return true
// An entry waiting for a service starts once a provider appears.
if (failure.outcome.kind === 'pending') return false顺序是关键: 所以最小的修法不是给 loader 加超时,而是:把这些 preset 的 id 加进启动时传给 3. 但直接变 fatal 未必是用户想要的 把
这两条都不需要动 cordis。真要支持「optional 依赖」,那才是他说的那个 API 级改动。 4. 关于责任归属
|
Uh oh!
There was an error while loading. Please reload this page.
name: Bug
about: 记录现有预期行为的失效
type: Bug
Summary
第三方 bundle 可以通过自己的
dsh.bundle.patch.yml用inject字段给 Loader 的核心条目加上硬依赖,而 Loader 没有 optional / 超时 / 降级机制。依赖一旦消失,被注入的条目永远停在FIBER_PENDING。由于
preset-standard等行不在全局 required list 里,dsh 会照常启动、只打一条 warning。用户看到的是「能开机、UI 能用、文件也能读,但新建会话必失败」——故障被降级成了一条几乎没人会读的警告。现成复现:
billion-context插件的 bundle patch(dsh.bundle.patch.yml:23-30)往preset-standard/preset-ptc/preset-minimal/preset-cordis四行注入biliBasicCompactionPolicy;禁用该插件后 dsh 永久无法新建会话,且没有任何恢复路径。Reproduction
package.json→dsh.profile.bundles里包含billion-contextcordis.patch.yml追加- id: bili-native+disabled: true)Current behavior
~/.dsh/logs/desktop-next.log:UI 点新建会话:
根因链:
vendor/loader/src/index.ts:134—Inject.resolve(fiber.entry!.options.inject, fiber.inject),条目级 inject 完全来自entry.options.injectvendor/cordis/src/registry.ts:71-72—Inject.resolve(null)直接 return;数组形式inject: [a]里每一项仍必填(registry.ts:73-76只把 intercept config 置 null)vendor/cordis/src/fiber.ts:611-623—_refresh只要 inject 里任一键未解析就置epoch = INACTIVEpackages/boot/app-boot/lib/index.js:3942—const missing = Object.keys(fiber.inject).filter(s => fiber.ctx.get(s) === undefined)→outcome.kind = "pending"packages/boot/app-boot/lib/index.js:4005-4008— 只有全局 required list 里的不活跃条目才拒绝启动,其余仅 warningEntryOptions只有id / name / config / group / disabled / inject(vendor/loader/src/config/entry.ts:10-23),没有任何 optionalInject / optional / required: false 之类的表达。结果就是第三方 bundle 可以为 dsh 的核心条目制造不可逆的硬依赖。用户侧唯一可用的绕过是写 home 层 patch(
~/.dsh/cordis.patch.yml,层序见packages/boot/app-boot/src/profile-context.ts:73-80,home 层在 profile 层之后所以能赢):inject: null能生效是因为applyEntryPatches(vendor/include/src/index.ts:120-123)是顶层键整体替换而非深合并。Expected behavior
至少满足其一:
Environment
desktop(含@deepseek-ai/dsh-web-app预设)English summary
A third-party bundle can turn a core Loader entry's service dependency into a hard requirement via
inject, and the Loader has no optional / timeout / degrade path. Once the provider disappears the entry staysFIBER_PENDINGforever. Becausepreset-standardand friends are not in the global required list, dsh still boots and only emits a warning — so the user gets a working UI that cannot create a single session.Reproducer:
billion-context'sdsh.bundle.patch.yml:23-30injectsbiliBasicCompactionPolicyintopreset-standard/preset-ptc/preset-minimal/preset-cordis. Disable the plugin and dsh can never create a session again.Chain:
vendor/loader/src/index.ts:134→vendor/cordis/src/registry.ts:71-76(every array item is still required) →vendor/cordis/src/fiber.ts:611-623(any unresolved key ⇒INACTIVE) →app-boot/lib/index.js:3942(pending) →:4005-4008(only the global required list fails startup).EntryOptionshas no way to express an optional dependency.All reactions