Replies: 1 comment
|
在 rc.7( 1. 三处源码全部属实:
2. 为什么"只注入常驻服务的插件存活"是必然: 你的观察与 loader 的 3. 家族汇聚——这是 reconcile 家族的触发类 #4:
4. 修复方向(任选其一,都有现成落点):
5. 连带提示: 你的运行时注入探针(进程内验证 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Title
Third-party bundle plugins are silently disabled ~3s after boot — HMR recompose picks up disabled=true written onto the shared bundle insert objectsEnvironment
~/.dsh/profiles/web, plugins installed viadsh plugin addand manualdsh.profile.bundlesentriesSymptom
Any third-party bundle plugin (a package declaring
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }whose patch inserts its own row via- insert: [{ id, name }]) activates at boot, then ~3 seconds later is silently disabled:entry.options.disabledbecomestrue(raw value),entry.fiberis destroyed — verified via injected probe in the live process.配置状态: 已停用with no Cordis status column (no fiber)./api/usageStats/queryreturns 404 fordsh-spend).dsh --dump-configshows the entry without anydisabledfield — configuration layer is clean.injectlists only always-present services (settings,loader); every plugin injectingagents/sessions/webServergets disabled.Root cause (confirmed from source + runtime injection)
applyEntryPatches(vendor/include/src/index.ts) pushes theinsertentries by object reference into the composed tree (data.push(...insert)).cordis-plugin-loader/src/index.ts, "case 7") writesfiber.entry.options.disabled = truedirectly on that shared object when a fiber is disposed by loader behavior.watchUserPatchestriggersinternal/update; the Include plugin recomposes viaapplyPatches(this.data, config.patches). The same patch objects (including the now-mutated insert rows) are applied again, so every previously-disposed third-party row comes backdisabled: true.internal/updateevents carry identical patch lists (50 entries), yet the first compose leavesdsh-at-fileclean and the second compose yieldsdisabled: true. Runtime probe at t+3s shows all third-party entriesdisabled=true, fiber=Nexcept the one that was never disposed.apps/cli/src/profile-boot.tsalready documents this hazard ("the boot application must not mutate the objects later reloads recompose from") and clones for boot, but the mutation path through the loader's dispose hook still reaches the shared insert objects, and the HMR recompose re-applies them.Impact
Every third-party bundle plugin silently loses host services and client UI shortly after boot. No error is printed (disabled is a valid state).
dsh-doctorreports nothing actionable. Users are left with plugins that "installed but do nothing."Workaround (verified)
Add explicit
disabled: falseoverrides for every third-party row in the profile's own patch layer (~/.dsh/profiles/<name>/cordis.patch.yml):The profile layer applies after bundle layers on every recompose, so it wins over the polluted value. Verified: all 22 third-party plugins stay
ACTIVE(fiber state 2) and their client manifests appear.Suggested fix
entry.optionsin place for shared insert rows — either clone the row before writingdisabled, or drop the mutation entirely (the HMRapplyPatchesalready recomposes from the layer list).datainsideapplyEntryPatches(currentlystructuredClone(data)only clones the previous tree, not the inserted objects coming frompatches).All reactions