npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcd0luo/celes-center-session-bridge

v0.2.8

Published

dsh: cross-session messaging for the Celes dispatch center — address another session by id or name, deliver as its next user turn; queued bridge messages are merged in place (formatted append) instead of piling up turns

Readme

@mcd0luo/celes-center-session-bridge

DSH 调度中心的跨会话通信插件(Celes 系列),同时提供 空闲 agent 释放(W287 内存治本): 包装 agents.resume 收口登记所有 resume 路径(bridge 投递即唤醒 / watchdog session.prompt / api-session-controller resolveOrResume)返回的 AgentHandle,agent 转 idle 后 TTL 到期经官方 AgentHandle.dispose() 卸载(会话日志保留磁盘,可再次 resume);另有周期 reaper 兜底扫描。 机制与安全门详见 lib/idle-release.js。注入服务:sessions / agents / sessionPersistence / webServer / tools / settings(agentPresets / sessionQuery 可选)。

能力

1. Agent 工具 session_send_message

任意会话内的 AI 直接调用,向目标会话投递消息:

  • 目标可用「会话地址」(session id)或「会话命名」(对话标题 / 项目 / 工作区名);
  • 按命名指定时先解析到唯一地址再投递,命中多个时返回候选清单供你改用地址;
  • 排队消息合并:目标 inbox 已有本插件排队未消费消息时,格式化原位追加而非堆积多轮;
  • 目标离线(parked)时「投递即唤醒」:agents.resume 加载后 steer(W255 单飞 / W270/W282 setup 兼容)。

2. HTTP API(挂在 dsh web 进程的 webServer 上,127.0.0.1 监听)

| 方法 | 路径 | 用途 | |---|---|---| | GET | /celes-center/bridge/health | 健康检查 | | GET | /celes-center/bridge/sessions | 列出全部会话(地址/标题/项目/在线/running) | | GET | /celes-center/bridge/memory-state | W287 空闲 agent 释放健康面(免认证只读):agents 总数/running/tracked/累计释放/失败计数/最近释放 | | POST | /celes-center/bridge/send | 投递消息 {target, content, from?} | | POST | /celes-center/bridge/set-model | 切换会话模型 {id, provider?, model?, reasoningEffort?} | | POST | /celes-center/bridge/archive /unarchive /set-title /group-consolidate | 会话运维(归档/反归档/改名/分组整合) |

3. W287 空闲 agent 释放

  • 配置:IDLE_RELEASE_TTL_MS(默认 900000ms=15min,0=关闭)、IDLE_RELEASE_SWEEP_MS (默认 300000ms=5min,0=关闭周期扫描)、auditPort(默认 3180,释放审计回写端口); 可被环境变量 IDLE_RELEASE_TTL_MS / IDLE_RELEASE_SWEEP_MS 覆盖(settings 表单同源默认)。
  • 投递后释放:deliver 的 resume-steer 路径在 agent/status 回 idle 后启动 TTL 计时;期间新投递 (/send 命中 live)/新 turn(running 事件)取消计时;到期且仍非 running → 释放。
  • 通用兜底 reaper:周期扫描登记表,覆盖漏发 agent/status 事件的常驻 agent(watchdog/follow 加载)。
  • 安全边界:绝不释放 running;绝不释放 TTL 内有活动/排队工作的;失败静默+计数(memory-state 可查)。
  • 审计:每次释放 POST /celes-center/audit/append(server-ops 类目,sessionId+驻留时长+原因)。

配置

| 字段 | 默认 | 说明 | |---|---|---| | routePrefix | /celes-center/bridge | HTTP 路由前缀 | | token | "" | 共享访问令牌(空 = 仅信任本机回环) | | projcachePath | /opt/dsh/storages/session_projcache.json | 会话标题投影缓存 | | workspacesPath | /opt/dsh/storages/workspace.json | 工作区注册文件 | | groupRoots | [] | 分组整合根目录(空 = 关闭) | | mergeQueued | true | 排队消息原位合并优化 | | IDLE_RELEASE_TTL_MS | 900000 | 空闲 agent 释放 TTL(毫秒;0=关闭) | | IDLE_RELEASE_SWEEP_MS | 300000 | 兜底 reaper 周期(毫秒;0=关闭) | | auditPort | 3180 | 释放审计回写端口 |

兼容性(DSH 0.1.2/0.1.3 破坏性变更适配)

0.1.2 起 Session.events 形态收紧:snapshotEvents(fromSeq?, toSeqExclusive?) / eventAt(seq) / seq 替代;0.1.3 起 persistence.list() 返回 [{header, revision, sizeBytes}]、inspect()/服务级 append() 移除(改 open(id,"read"|"write") 句柄)。本插件的双向兼容策略(见 lib/events-adapt.js):

  • live Session:优先 session.snapshotEvents()(0.1.2-rc.1+),无此方法时回退 session.events (0.1.1-rc.2 及更早),升级窗口期两个核心版本均可运行。

  • persistence.inspect() / loadStored() 返回的检查对象(SessionInspection / StoredPrefix): 均为纯数据对象 { meta, inheritedEventCount, events } —— 不是 Session,没有 snapshotEvents(), events 字段在两个版本都保留,故沿用 inspection.events;适配层保留 snapshotEvents 兜底分支防御收紧。

  • 0.1.3 resume 不再携带 preset 挂载:投递唤醒路径补 setup(preset 投影/持久化 header 回退), 工具面不坍缩(W270 §5.3-1 / W282)。

  • W287 空闲释放基于 0.1.3 语义:AgentHandle.dispose() 停止 loop、await 退出、卸载 scoped world、 关闭会话写句柄、从 agents/sessions 注册表摘除;磁盘日志保留 → agents.resume 可再次加载。 0.1.1 宿主无该语义(无 dispose 句柄)时本功能自动降级为只跟踪不释放(track 空 handle,日志提示)。

  • W289 标题兜底缓存失效制改造:无标题离线会话的标题来自日志整读(大文件可 ~秒级), 旧「固定 60s TTL」每 ~60s 强制全量重读 → ~62s 周期 ~10s 同步冷重建窗口(W286 P0 归因)。 现改为按持久化索引失效 + stale-while-revalidate:persistence.list() 行 {header, revision, sizeBytes}(0.1.3 契约;revision=dev:ino:size:mtimeNs:ctimeNs) 与缓存 token 对比——文件未变 → 缓存永续;文件变化 → 先回旧值 + 后台异步刷新 (singleflight 去重),请求路径不阻塞;仅首次无缓存值同步取(冷启动一次性)。 实现见 lib/title-cache.js(TitleCache.frameEval 按目录帧原子求值)。

W780(0.2.7)修复:resume 取错事件字段——已归档 worker 会话「投递成功但什么都没发生」

  • 症状:向已归档(parked)worker 会话发消息,session_send_message / POST /send 返回 {ok:true, delivery:{via:"resume-steer", live:true}},但目标会话毫无动静——日志里每轮唤醒都是 turn/start → step/start → step/end → turn/end,reason.kind=error, message = agent "…" has no provider/model: set AgentOptions.provider and AgentOptions.model, 1 个空步、0 token、0 工具调用。消息确实投进去了、turn 也确实开了,只是 agent 没有模型配置,第一步就抛错。
  • 根因:inspectStored()(lib/index.js)把 handle.read() 的返回值当数组用。 DSH 0.1.5 的 jsonl 后端(dsh-session-persistence-jsonl/lib/index.js 的 read()/readPrimed()/readCurrent())返回的是事件切片包装对象 {eventState, events}, 不是数组;且 persistence.inspect 在该后端上不存在,所以每次都走这段 fallback。 于是 inspectionEvents() 的 Array.isArray(inspection?.events) 判假 → undefined → resume 分支的 agentOptions 提取整块被跳过 → agentOptions = {} → agents.resume({resumeSessionId, agentOptions:{}}) 恢复出的 agent 无 provider/model。
  • 影响面:不止 resume 的模型配置,同一读链上的三处一并失效——离线标题兜底 (titleFallback,无标题离线会话标题丢失)、离线投递 POST /send(误报「无存储日志,无法离线投递」)、 离线 POST /set-title(同样 404)。test/inspect-stored-read-shape.test.js 用例 e 固定了该回归。
  • 修复:新增 eventsOfReadResult() 解包——数组直接返回,{events:[…]} 取 .events, 其余(undefined/非数组)一律 [],绝不外泄包装对象;meta 仍取 handle.header, finally { handle.close() } 与 read() 抛错向上抛的语义均保持不变。双形态兼容(0.1.5 包装对象 + 旧版裸数组)。
  • 证据:真实被唤醒会话日志 session-b5bbe03e-… 的 request/header 事件确实带 {"config":{"provider":"celestea","model":"deepseek-flash","reasoningEffort":"high",…}} ——修复后这条提取路径能取到正确值。
  • 自证伪:把 eventsOfReadResult() 调用回退成裸 handle.read(),test/inspect-stored-read-shape.test.js 7 例中 3 例必红(a/d/e;agentOptions 变为 {provider:undefined,model:undefined})。

单测:npm test(node:test,零依赖)——test/events-adapt.test.js(事件适配)、 test/apply-flow.test.js(投递/目录/模型链路)、test/idle-release.test.js (W287:TTL 计时/取消、idle 才释放、running 绝不释放、reaper 扫描、审计/计数、apply 集成含 memory-state)、 test/title-cache.test.js(W289:文件未变缓存永续 / 文件变化异步刷新且先回旧值 / 并发刷新去重 / 冷启动同步;apply 集成含响应形状回归)、 test/inspect-stored-read-shape.test.js(W780:handle.read() 包装对象/裸数组双形态解包、 inspect 优先契约、read() 抛错向上抛、resume agentOptions 端到端提取、离线投递不再误报无日志)。

MIT