全部插件

DSH / BUNDLE / CLIENT-UI

@vertixara/dsh-prompt-manager

v0.4.1elfmingh / dsh-prompt-managerc827f0dbdb

可安装组合包UI 与客户端插件社区 · Topic 自动分析Web UI

概览

@vertixara/dsh-prompt-manager

DeepSeek Harness 的分层提示词管理器:全局、工作区、会话级提示词档案,内置段落与上下文的禁用/覆盖,子代理作用域,以及完整的 Web 管理界面。

README / ZH

插件文档

目录摘要

DeepSeek Harness 的分层提示词管理器:全局、工作区、会话级提示词档案,内置段落与上下文的禁用/覆盖,子代理作用域,以及完整的 Web 管理界面。

dsh.pub 核对固定版本的组合包契约、运行时事实与分发语义;完整 README 请查看源仓库。

在 GitHub 阅读完整 README

LIMITATIONS

已知限制

- **界面语言跟随 DSH 的界面语言,并且在切换时立即生效。** 取值顺序是宿主 locale 服务(`ctx.locale.getLocale().active`)→ `<html lang>` → `navigator.language`。前两个都同步可读,第三条只是兜底 —— 用系统语言判断是错的,系统中文 + DSH 英文时会判成中文。侧边栏和会话页签的标题由宿主渲染,它本来就订阅了 `ctx.locale`、语言一变就重新调 `label()`,所以插件里的 `t()` 也必须现场读,不能缓存。另有少量文案来自 Host 侧(工具返回值、`prompt_manager` 的 action 结果),这些也跟随界面语言,通过请求上的 `?lang=` 传过去。 - 静态注册的条目改不到已经在运行的 agent,只能靠重建会话 - 后注入只能追加,要撤掉已注入的内容必须用 override disable - `required: true` 的 context 被移除后是否恢复,由框架决定 - 工具描述只读:改它需要动 `assembly.tools`,风险过高,未开放 - 面板显示的 tools 数量取决于目标会话是否产生过装配 - `complete` 段落会在 waterfall 之后被框架还原,对它做改写无效(当前环境未观测到) ### 存储与并发 · Storage and concurrency - **同一个存储文件只允许一个写入进程。** 插件用「临时文件 + rename」保证单进程内的原子替换, 并让全部读写事务走同一条队列,但**没有**跨进程互斥。同时跑两个 DSH 实例并指向同一个 `prompt-manager.json`,两边会互相覆盖。需要多进程时请各自用不同的 `storeFile`。 - **排队有期限。** 写入要排队;等了 10 秒还没轮到的请求会明确失败(`WRITE_QUEUE_TIMEOUT`), 而不是无限期挂着。已经开始执行的事务不受这个期限约束,会正常跑完。 - **读不到配置时拒绝修改。** 存储文件读取失败时,界面仍会展示最后一次成功读到的内容, 但所有修改动作会被拒绝(`STORE_UNREADABLE`)—— 否则会拿旧内容整份写回,把磁盘上 可能还完好的数据覆盖掉。 - **`.tmp` 文件需要手工清理。** 保存是先写 `<storeFile>.<pid>-<ts>-<nonce>.tmp` 再 rename。 rename 失败时这份临时文件会被**故意保留**(它是唯一一份完整可用的内容)。确认自己 不需要之后,手工删掉即可;插件不会自动清理,因为无法可靠判断某个临时文件是否还属于 一个正在进行的事务。 - **`.corrupt-*` 是抢救记录。** 首次加载时如果存储文件无法解析,它会被改名成 `<storeFile>.corrupt-<时间戳>` 留证据。确认内容没用了再手工删。 - 写入使用 `flush: true` 请求把内容刷到存储设备,降低掉电后留下空文件或半截文件的可能。 这**不是**断电保证:目录项的持久化取决于操作系统与文件系统。 **English:** - **The panel language follows DSH's UI language and switches live.** Resolution order is the host locale service (`ctx.locale.getLocale().active`), then `<html lang>`, then `navigator.language`. The first two are synchronously readable; the third is only a fallback — judging by system language is wrong, since a Chinese system with DSH set to English resolves to Chinese. The sidebar and conversation-tab titles are rendered by the host, which already subscribes to `ctx.locale` and re-invokes `label()` on every switch, so the plugin's `t()` must read live rather than cache. A few strings come from the host side (tool return values and `prompt_manager` action results); those follow the UI language too, carried on the request as `?lang=`. - Static entries cannot reach an agent that is already running; only rebuilding the session helps - Post-hoc injection can only append; removing injected content requires an override `disable` - Whether a `required: true` context comes back after removal is up to the framework - Tool descriptions are read-only: changing them means mutating `assembly.tools`, which is too risky and stays closed - The tool count shown in the panel depends on whether that session has ever assembled - The `complete` section is restored by the framework after the waterfall, so rewriting it has no effect (not observed in this environment) - **One writer process per store file.** Atomic replacement is guaranteed within a single process, and every read/write transaction shares one queue, but there is **no** cross-process lock. Two DSH instances pointed at the same `prompt-manager.json` will overwrite each other; give each its own `storeFile`. - **Queuing is bounded.** A write that has not started within 10 s fails with `WRITE_QUEUE_TIMEOUT` instead of hanging. A transaction that has already started is never cut off. - **Unreadable store refuses writes.** When the store cannot be read, the UI keeps showing the last successfully loaded content but every mutating action is rejected with `STORE_UNREADABLE` — otherwise the stale copy would be written back over data that may still be intact. - **`.tmp` files need manual cleanup.** Saves write `<storeFile>.<pid>-<ts>-<nonce>.tmp` and then rename. A failed rename deliberately keeps that file (it is the only complete copy). Delete it by hand once you are sure it is not needed; the plugin does not auto-prune, because it cannot reliably tell whether a temp file still belongs to a running transaction. - **`.corrupt-*` files are rescue evidence.** An unparseable store is renamed to `<storeFile>.corrupt-<timestamp>` on first load. De