Repository navigation
v2.0.2
A preference-load crash that made the plugin — and its companion monitors — silently disappear.
settings.describe() was called with .then(...) unconditionally, but that one name has
two implementations: the typert WIRE form returns a Promise, while the DIRECT form —
SettingsController.describe() in @deepseek-ai/dsh-api-settings-controller — is
synchronous and returns the view object itself, and can throw instead
(settings service is absent: mount @deepseek-ai/dsh-settings).
The resulting TypeError: settings.describe(...).then is not a function is raised
synchronously, so it escaped before the .catch at the end of the loader's chain.
Because it lands inside apply(), it aborted the rest of apply: ctx.provide('quickControl', …),
every switch registration and the panel mount all sit downstream of the preference load. The plugin
therefore still read as loaded while nothing of it was on screen — with only
[dock-flash] apply failed: TypeError: … in the console. That is the reported "the plugin was
registered and then silently disappeared".
Both call sites now normalize through _describeAsync(), which accepts a Promise, a plain view, or a
throw, so the loader's existing .catch records a named reason instead of killing the plugin. The same
defect was fixed in all four companions (dsh-flash-ctx-mon 0.1.3, dsh-flash-mem-mon 0.1.2,
dsh-flash-net-mon 0.1.1, dsh-flash-proxy 0.1.2), where apply() is async with no internal catch —
there the throw rejected apply and failed the Cordis fiber, so those plugins never activated at all.
pnpm run check:overlay section 23 exercises both shapes (a synchronous view and a throwing provider) and
asserts that apply() still reaches ctx.provide('quickControl', …), that the synchronous view is
parsed and adopted rather than merely tolerated, and that a refusal is recorded instead of swallowed.
All five assertions fail against the unfixed build, reproducing the reported error verbatim.
204 assertions pass, 0 fail.
Patch: no published surface changed — no switch added, renamed or removed, no field, type or route touched.