Back to home

gameswu

dsh-notifacation-frame

dsh通知消息统一管理框架

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-notifacation-frame

DSH 通知框架:统一管理通知事件,允许派生插件注册自己的通知项,并在设置页为每个通知项提供配置卡片。内置了会话任务完成、agent 提问、进程崩溃与若干报错事件的通知实现。

功能

  • 统一通知事件管理:所有通知项(内置 + 派生插件)走同一注册表、同一配置模型、同一投递管线(通道分发 + 历史环形缓冲)。
  • 设置页配置卡片:Settings → 通知 页为每个通知项渲染一张卡片——启用开关、通道复选(网页内提示 / 系统通知 / 日志)、由字段元数据驱动的派生插件配置项、测试按钮、最近通知历史。修改热生效,无需重启。
  • 派生插件支持:派生插件只需 inject: ['notificationFrame'] 并调用 ctx.notificationFrame.register(definition)definition.fields 声明的配置项由框架解析、校验、补默认后经 env.config 传入,配置修改时框架自动重激活(先 dispose 旧 setup,再以新配置重跑)。详见 派生插件开发指南examples/dsh-notif-demo
  • 页内 toast + 系统通知 + 日志:host 经 WebSocket 推送通知到浏览器(右上角 toast 栈,点击可跳转会话);Windows / Linux / macOS 系统通知尽力而为(带冷却防刷屏);可选通知日志文件。

内置通知项

通知项事件默认通道默认状态
session-complete会话 agent 完成任务(agent/status running→idle,可只通知顶层会话)web
ask-user-questionagent 调用询问问题工具(tools/result,工具名过滤,正文可带问题)web + system
process-crashdsh 进程意外中止(uncaughtException / unhandledRejection / 非零退出码)system + log
agent-erroragent 的 step/turn 报错(agent/errorweb + log
agent-loop-config-start-failed声明式 agent 启动失败web + system
tool-error工具调用失败(tools/result isError,可按名单排除噪声工具)web(工具失败通常由模型自愈,按需开启)
dsh-updatedsh 包新版本检查(npm registry dist-tags 对比本机安装版本,启动 + 每 24h 周期)web + system

报错事件的选择理由:agent/erroragent-loop/config-start-failed 直接影响任务成败,默认通知;tool-error 高频且模型通常自动重试,默认关闭;agent/request-error(单次请求失败、会重试)过于嘈杂,不接入。

安装

# 1. 构建插件模块
cd dsh-notifacation-frame
pnpm install
pnpm run build          # 产出 lib/index.js(插件入口)+ lib/*.d.ts + lib/client.js(浏览器 bundle)

# 2. 将包装入目标 profile(以 web 为例)——一步完成,无需手改任何配置:
#    dsh plugin 是 pnpm 转发器:安装后自动把声明了 dsh.bundle 的依赖登记进
#    profile 的 dsh.profile.bundles,启动时按 bundle 顺序合并包自带的
#    cordis.patch.yml(挂载行就在本仓库根目录的 cordis.patch.yml 里)
dsh plugin --profile web add "file:$(pwd)"

# 3. 重启 DSH 生效(启动日志出现 [dsh-notifacation-frame] notification framework active)

profile 自己的 cordis.patch.yml覆盖层,不是挂载行——只有当你需要覆盖 框架级配置(如 logFile)时才在里面按 id 重述该行:

- id: notifacation-frame
  config:
    logFile: /path/to/notifications.log

卸载:dsh plugin --profile web remove dsh-notifacation-frame(bundles 登记同步移除)。

配置

配置项位置默认说明
各通知项开关 / 通道 / 派生字段Settings → 通知 页卡片见内置表热生效,写入用户设置层
logFile组合行 config''通知日志文件('' = 仅控制台)
historyLimit组合行 config100内存历史环形缓冲长度
systemCooldownMs组合行 config5000系统通知冷却(防刷屏)
systemTimeoutMs组合行 config8000系统通知气泡展示时长
webSocketPath组合行 config/notification-frame/wshost→client 推送路径

组合行 config.* 是框架级 base 层;各通知项的用户配置存在 settings 命名空间 dsh-notifacation-frame{ items: { [id]: { enabled, channels, options } } }), 设置卡片经 Host 的 fenced JSON 路由 /notification-frame/api 读写(与 dsh-plugin-vscode-sidebar 的 /sidebar/api 同款通道:POST + {ok, value|error} 信封,信任栅栏与 /api 网关同源)。

派生插件(一分钟上手)

// 派生插件 host/plugin.ts
import type { NotifierDefinition } from 'dsh-notifacation-frame'

export const name = 'my-notifier'
export const inject = ['notificationFrame'] as string[]

const myItem: NotifierDefinition = {
  id: 'my-event',
  title: '我的事件',
  description: '某个事件发生时提醒我。',
  severity: 'info',
  channels: ['web', 'system', 'log'],
  defaultChannels: ['web'],
  fields: [
    { key: 'minValue', label: '最小阈值', type: 'number', default: 10, min: 0, max: 100 },
    { key: 'greet', label: '问候语', type: 'string', default: 'hello' },
    { key: 'mode', label: '模式', type: 'select', options: [{ value: 'a', label: 'A' }, { value: 'b', label: 'B' }], default: 'a' },
  ],
  setup(env) {
    // env.config = { minValue, greet, mode } —— 已解析/校验/补默认,直接使用
    const ctx = env.ctx as MyCtx
    return ctx.on('some/event', (payload) => {
      env.notify({ title: 'Something happened', body: 'value=' + payload.v })
    })
  },
}

export function apply(ctx: MyCtx): void {
  ctx.effect(() => ctx.notificationFrame.register(myItem))
}

fields 就是派生插件的配置项:设置卡片自动渲染对应控件,用户修改后框架用新配置重跑 setup(热生效)。完整的解析规则、数据类型、生命周期与示例见 docs/derived-plugins.mdexamples/dsh-notif-demo

项目结构

dsh-notifacation-frame/
├── package.json            # main = lib/index.js;dsh.client = web bundle
├── tsconfig.build.json     # 宿主声明构建(tsc:lib/*.js + lib/*.d.ts,标准装饰器语义)
├── tsdown.config.ts        # 客户端打包(lib/client.js + *.svg?raw 虚拟模块内联)
├── cordis.patch.yml        # bundle 挂载层(插入框架行)
├── assets/
│   └── icons/              # 图标资源(bell-outline-16.svg 等,随包发布)
├── src/
│   ├── index.ts            # 宿主打包入口(再导出 host/plugin.js 的类型与运行时面)
│   ├── shared.ts           # 线缆模型:类型 + 派生配置解析(同构,纯函数)
│   ├── host/
│   │   ├── plugin.ts       # 入口:Config / settings 命名空间 / fenced JSON API / WS 推送
│   │   ├── registry.ts     # 通知注册表(注册、配置热生效、投递过滤、历史)
│   │   ├── channels.ts     # 通道中枢(web 广播 / log 文件 / 系统通知)
│   │   ├── builtins.ts     # 7 个内置通知项
│   │   ├── update-check.ts # dsh 新版本检查(semver 比较 + registry dist-tags)
│   │   ├── wire.ts         # JSON API 线缆助手({ok, value|error} 信封,fenced 路由用)
│   │   ├── trust-fence.ts  # WS/API 信任栅栏(回环 / --trusted-host)
│   │   └── types.ts        # 宿主结构类型 + ctx.notificationFrame 增广
│   └── client/
│       └── entry.ts        # 设置页卡片(settings.section)+ toast 栈(shell.overlay)+ WS 客户端
├── examples/
│   └── dsh-notif-demo/     # 派生插件完整示例(可独立安装)
├── docs/
│   └── derived-plugins.md  # 派生插件开发与配置解析指南
└── tests/                  # vitest:解析契约 / 注册表 / 通道 / 内置项行为 / 入口集成

构建管线与 dsh-plugin-vscode-sidebar 同源:宿主 JS 由 tsc 产出(lib/ 下 与 .d.ts 并排,@Remote 装饰器按标准语义编译),客户端由 tsdown 打包为 module-loader closure。

开发

pnpm install
pnpm run typecheck  # 严格模式类型检查(含示例 workspace)
pnpm run build      # 编译宿主 + 客户端 bundle
pnpm run test       # vitest(58 个用例:配置解析、注册表热生效、通道、内置项、入口集成)

文档

许可证

MIT © 2026 gameswu