Third-party plugins cannot expose Web settings sections (WEB_SETTINGS_NAMESPACES allowlist) #903
Replies: 3 comments
English
中文
|
EnglishThanks for the independent confirmation — we just verified every call site against the shipped
The half-updated profile failure mode is exactly as you describe: pnpm completes, then reconcile throws We fully support the minimal fix ( Separately — the main topic of this discussion (a first-class 中文感谢独立复现确认——我们在发行版 dsh 0.1.0-rc.6 上逐点核对了调用位置,全部属实( 另外主帖的 |
|
提案我完全支持(另外两个帖子在要同一件事:#1877 和 #3114,后者已经写成了带 API 设计的完整 RFC)。我想说的是你们正在出货的那个变通方案——它有几个风险,而且有一条更安全的路今天就能走。 那个自愈式改写宿主文件的做法,风险比看上去大
我理解为什么会走到这一步,也认同你自己的判断("这正是一等公民
顺带一个具体的坑(另一个帖子刚踩过):改写 一条不碰宿主文件的路白名单挡住的是 settings 的数据面( 所以把两半拆开:
我们(一个仓库外的第三方插件)在 DSH Web 里的管理页就是这么落地的,跑在真 DSH loop 上: 代价照说(我们付了):丢掉 关于 BOM 那条"Bonus"@StarsMilky 补的调用点和你的复核已经很完整了。我只想说这条不该当 bonus:你们描述的失败形态是半更新的 profile(pnpm 成功了、reconcile 抛了、依赖写进了 一个让用户的配置停在中间状态的崩溃,比设置页少一个 section 严重。 建议把它单独开一帖,标题直接写后果("BOM in a plugin manifest leaves a half-updated profile after 一件对 RFC 有用的事#3114 那份 RFC 最缺的是"有真实消费者"。这一族现在被卡住的插件已经能列成表了:
六个用途完全不同的插件撞同一堵墙,其中一个已经被逼到改写宿主文件。这份名单贴到 #3114 去比留在各自帖里有用。 边界与利益相关我们不修 DSH 自家组件——apiproxy、settings seam 都在 DSH 里。上面第一节是风险提示、第二节是绕法不是修复。 利益相关:我维护 pi2dsh(Pi 生态兼容层)。这条不推销: |
Uh oh!
There was an error while loading. Please reload this page.
Third-party plugins cannot expose Web settings sections (
WEB_SETTINGS_NAMESPACESallowlist)TL;DR: the Web settings client only serves namespaces hard-coded in
dsh-host-apiproxy'sWEB_SETTINGS_NAMESPACESallowlist. Any namespace registered by a third-party plugin throughinstallSettingsSection/settings.register()answerssettings-not-exposedon stock installs, even though it is fully registered host-side. A first-classexposeflag onsettings.register()would fix this cleanly.Where
@deepseek-ai/dsh-host-apiproxy/lib/index.js:exposedNamespaces()= configurable model providers + this allowlist + product namespaces. The code comment next to the list already acknowledges the design gap:Impact
We maintain three third-party plugins (
dsh-tool-vision,dsh-soul-md,dsh-tdai-memory) that register settings-backed configuration (secret API keys, model endpoints, persona paths). On any stock install:settings.describefilters their namespaces out → the Web settings page shows "settings namespace is not available"settings.update/mutaterefuses withsettings-not-exposedThe only workarounds today are editing
dsh-host-apiproxy/lib/index.jsby hand (lost on everydshupdate) or giving up the settings UI entirely. Meanwhile the harness marketing is literally "Everything is a Plugin" — the settings surface is the one seam where third-party plugins are second-class.Proposed fix (opt-in exposure)
settings.register(ns, schema, options)gains anexposeoption (defaultfalse), andinstallSettingsSectionpassesexpose: true— or add an explicitinstallSettingsSection(..., { expose: true })hook flag.dsh-host-apiproxy'sexposedNamespaces()collectsexposednamespaces from the live settings registry instead of a hard-coded array.This keeps the "decision made by the registering plugin" model the comment asks for, without a change to this package for every new plugin.
Bonus (small):
JSON.parsechokes on UTF-8 BOMdsh-client-modulesanddsh-app-bootread pluginpackage.jsonwith bareJSON.parse(readFileSync(..., "utf8")). A UTF-8 BOM (easy to produce with editors on Windows) throwsUnexpected token '\uFEFF'and crashesdsh webat boot /dsh pluginreconcile. A defensiveJSON.parse(text.replace(/^\uFEFF/, ""))would make the harness robust to editor defaults.Our current workaround (shipping today)
Our plugins locate the
dsh-host-apiproxyfile through the host process module cache and idempotently insert their namespace into the allowlist at startup (self-healing afterdshupdates). It works, but it is exactly the kind of hack a first-classexposeflag would make unnecessary — and it edits files under the user'sdshinstallation, which is not something plugin authors should have to do.Happy to contribute a PR if pull requests are accepted; we just couldn't file an issue since issues are disabled on this repo, so posting here per the repo's feedback channel.
All reactions