🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

红绿灯状态灯 eustace030616-hub/traffic-light

DeepSeek Harness
eustace030616-hub32 天前有提交已提供中文文档扫描:含敏感能力

在窗口上方显示会话状态与余额的红绿灯

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/4 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add eustace030616-hub/traffic-light
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]—
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
数据截至 2026/10/04·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 32 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 6 处,展示前 6 条)
  • 读取本地文件
    lib/index.js:464
    asked = statSync(refreshPath, { throwIfNoEntry: false })?.mtimeMs ?? 0
  • 读取本地文件
    lib/index.js:479
    if (!existsSync(RENDERER)) {
  • 执行外部命令来自配置/变量
    lib/index.js:484
    light = spawn(RENDERER, ['--state-file', statePath, ...lightArgs], { stdio: 'ignore' })
  • 写入本地文件
    lib/state.js:80
    mkdirSync(dirname(statePath), { recursive: true })
  • 写入本地文件
    lib/state.js:82
    writeFileSync(temporary, `${JSON.stringify(doc)}\n`, 'utf8')
  • 写入本地文件
    lib/state.js:83
    renameSync(temporary, statePath)
扫描于 2026/11/5(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 显示会话状态
  • 显示余额
  • 窗口上方红绿灯

一个 DSH 插件加一个 macOS 小灯守护进程:插件把每个会话的回合状态写进一个 JSON 文件,守护进程在任意窗口上方用红绿灯画出来。

README

由 DeepSeek 最新模型翻译生成
traffic light 一个 DSH 插件,外加一个 macOS 指示灯守护进程。 插件把每个会话正在做什么写进一个小 JSON 文件;守护进程读这个文件,在每个窗口上方画出一盏红绿灯。两个进程,一份文档,中间没有 socket。 - 插件。 lib/ —— 一个 DSH 插件,从插件页面安装。 - 守护进程。 mac/ —— DSHLight.app,通用架构,ad-hoc 签名。它只读,从不写。 安装 插件 —— 把下面这行粘进 DSH 的插件页面(侧边栏 → Plugins),然后重启 DSH: github:eustace030616-hub/traffic-light 守护进程 —— 不用装:它就在同一个包里,插件会把它启动。
展开完整文档(README 剩余 1 节)
traffic light

一个 DSH 插件,外加一个 macOS 指示灯守护进程。 插件把每个会话正在做什么写进一个小 JSON 文件;守护进程读这个文件,在每个窗口上方画出一盏红绿灯。两个进程,一份文档,中间没有 socket。

- 插件。 lib/ —— 一个 DSH 插件,从插件页面安装。
- 守护进程。 mac/ —— DSHLight.app,通用架构,ad-hoc 签名。它只读,从不写。

安装

插件 —— 把下面这行粘进 DSH 的插件页面(侧边栏 → Plugins),然后重启 DSH:

github:eustace030616-hub/traffic-light

守护进程 —— 不用装:它就在同一个包里,插件会把它启动。想单独运行,克隆仓库并打开随附的 bundle:

git clone https://github.com/eustace030616-hub/traffic-light.git ~/traffic-light
open ~/traffic-light/bin/DSHLight.app

用法

| 你看到 | 它表示 |
| 暗的 | 休息(idle):没有待处理的事,这不是故障 |
| 黄色,常亮 | 有会话正在干活(working) |
| 黄色,脉动 | 有会话卡在你这里(asking)—— 1.3 s 内从 30% 到 100% |
| 绿色 | 一轮结束了,你还没看(waiting) |
| 红色 | 数据源本身不可信 —— 丢了、读不了或过期了 |
| 红色,脉动 | 余额低于阈值,或者服务商不肯接这次调用 |

| 你做什么 | 它做什么 |
| 双击 | 在 DSH 和你来时的应用之间切换 |
| 单击 | 在灯旁边立刻说明这盏灯什么意思 —— 它往上飘,一秒左右后消失,句子越长留得越久 |
| 右键 | 打开列表:Appearance、Account、Quit the light |
| 拖动 | 吸附到更近的那条屏幕边缘,高度随你放下的位置 |

DSH 在前台时,绿色会自己消掉,因为待在这里正是这条提醒想要的结果。

Appearance ▸ Account ▸
Size ●━━━━━━━━━━ 20 pt CNY 12.62
Gap ●━━━━━━━━━━ 8 pt ─────────────
Rest ●━━━━━━━━━━ 28% Top up now
Lit ●━━━━━━━━━━ 85% updated 2m ago
─────────────
Reset to default

滑块拖动时即时生效,并且会被记住;Reset to default 恢复 20 / 8 / 28% / 85%。账户部分每种有余额的货币占一行,下面跟着平台自己的充值页面。点一下货币那一行 —— ↻ 就是提示 —— 去要一份最新余额。列表保持打开,答案回来时数字就地改写。

数据怎么流动

一个文件,一个方向:

DSH Desktop the daemon (DSHLight)
agent/pre-step a prompt was accepted reads the document every 0.25 s
agent/turn-stopping the ordinary turn end never fetches, holds no credential
agent/status idle | running
approval/request blocked on you
user-questions/… blocked on you │ ▲ ▼ │ lib/index.js — 每次变更写一份文档,每 2 秒重新打一次时间戳(心跳)│ │ │ ▼ │ ~/Library/Application Support/dsh-status/state.json ┘ 先写入临时文件,再重命名到位

守护进程唯一的写入,用于按需获取余额:点击某条货币行 → touch <statePath>.refresh → 下一次心跳时返回

- 多个会话,一盏灯。 每个根会话都在 meta.sessions 里;守护进程按 blocked > unread finish > working > rest 聚合。
- 多个 harness:暂不支持。 每个发布者都会写整份文档,所以两个发布者会互相覆盖,而守护进程是单例(flock),只读一个路径。要改的话,得先改成每个路径一把锁。
- 其他任何遵守契约的东西: 你自己写文档,保持 updatedAt 新鲜,用 --state-file PATH 让守护进程指向它。守护进程里不用改任何代码。

文档

~/Library/Application Support/dsh-status/state.json —— cat 它,或者用 DSHLight --print 跟踪它。

{ "version": 1, "state": "working", "sessionId": "session-1a2b3c4d", "title": null,
"updatedAt": 1790000000000, "changedAt": 1790000000000, "heartbeatMs": 2000,
"reason": "prompt", "meta": { "cwd": "/Users/you/project" } }

| 字段 | 含义 |
| version | 契约版本。只有破坏性变更才会升。 |
| state | idle \| working \| waiting \| asking。 |
| sessionId | 正在上报的会话,或 null。 |
| title | 会话标题 —— 目前始终是 null(见 Known gaps)。 |
| updatedAt | 最后一次收到发布者消息的时间。即使什么都没变,也会每 heartbeatMs 重新打一次时间戳 —— 这正是过期判断能生效的原因,也是它绝不能当成变更时间读取的原因。 |
| changedAt | 最后一次确认此状态的时间。心跳不会动它,所以确认时该比对的是它,而不是 updatedAt。 |
| heartbeatMs | 发布者的节奏,这样守护进程就不必硬编码过期规则。 |
| reason | 哪个事件写了这份文档:init、session-start、prompt、turn-end、agent-idle、agent-running、approval、question、answered、dispose。仅用于调试。 |
| meta | 扩展通道:只增不改,未知键必须忽略。 |
| meta.sessions | 发布者监视的每个会话:{ id, state, reason, changedAt }。 |
| meta.account | { fetchedAt, intervalMs, isAvailable, balances: [{ currency, total, granted, toppedUp }] },查询失败时则是一个 reason。数字都是字符串;绝不含凭据。 |

新信息都放进 meta,键只增不改,读取方遇到从未见过的状态时保持静默而不是报警 —— 所以新增状态或键不会让旧版本虚惊一场。

什么会让灯变化

| 转换 | 触发条件 |
| → idle | 插件加载、会话即将开始、dispose |
| → working | 带消息的 agent/pre-step,或 agent/status: running |
| → waiting | agent/turn-stopping,或 agent/status: idle |
| → asking | approval/request 或 user-questions/request,一直计数到最后一个得到答复 |
| ignored | 子代理上的上述任何一项;提问计入其父会话 |

只有智能体的状态能覆盖所有结束方式:你停止的一轮会被中止,turn-stopping 永远不会为它派发——这就是为什么以前停止的会话会一直亮黄灯,直到 DSH 重启。

配置

每个键都是可选的,且手工校验;不可用的值会回退到默认值(lib/config.js)。

| 键 | 默认值 | 说明 |
| statePath | ~/Library/Application Support/dsh-status/state.json | 必须是绝对路径 |
| heartbeatMs | 2000 | 下限为 250 |
| launch | true | 挂载时启动守护进程,dispose 时停止 |
| lightArgs | [] | 额外的守护进程参数,例如浏览器托管的 DSH 用 --open / --ack-app |
| balance | true | 本包发出的唯一请求 |
| balanceMs | 300000 | 下限为 60000 |

守护进程

npm test # 65 checks — no DSH, no network, no key
npm run ship # rebuild bin/ from the Swift (npm test fails if it drifts)
./mac/build.sh --run # follow the light in a terminal
open build/DSHLight.app # draw it by hand
pkill -f DSHLight # stop it

| 参数 | 作用 |
| --state-file PATH | 读取哪个文档(默认:已发布的路径) |
| --print | 在终端里跟随,而不是绘制窗口 |
| --interval SECONDS | 轮询间隔,默认 0.25 |
| --open PATH | 双击打开什么,默认 /Applications/DSH Desktop.app |
| --ack-app BUNDLE-ID | 另一个应用,它返回即视为绿灯结束;可重复 |
| --no-ack | 保持绿灯直到下一个提示词,而不是返回时结束 |
| --level floating\|status\|screensaver | 窗口层级,默认 screensaver |
| --size POINTS | 本次运行的透镜尺寸,覆盖尺寸滑块 |
| --low-balance POINTS | 余额降到多少时灯变红并呼吸,默认 8,以金额最大的币种计;0 表示关闭 |

值得了解:

- 主体是菜单自身材质的一半强度,加一层 0.15 的黑色蒙版,圆角取自其窄边;透镜周围的环是浅灰色,绝不是黑色。
- 菜单栏的 22 点始终预留,从不跟随:visibleFrame 在两种栏状态下都报告整个屏幕,而贴着菜单栏会产生一个迟滞的灯,与菜单栏重叠。
- 红色从不表示智能体。 不可信的订阅源是红色常亮;余额耗尽是红色呼吸;完全读不到的账户是列表里一行暗色,绝不是透镜。
- 守护进程不持有密钥,也不抓取任何东西;每个账户数字都来自发布者,而它只写一个刷新请求。
- 每个用户一盏灯 —— 进程存活期间独占一个 flock。
- 双击恢复的是应用,不是窗口或标签页 —— 公开 API 能触及的范围就到这里。
- 不需要 Apple 账号:临时签名,包管理器安装不会设置隔离标志。

密钥

- API key 在请求时通过 harness 的凭据接缝解析 —— inject 是唯一可行的路径 —— 并在一次请求期间存活于一个局部变量。没有任何地方存储它,轮换后的 key 无需重启即可抵达下一个请求。
- 失败时返回的是错误码,绝不是服务商的消息:DeepSeek 自己的 401 会回显被拒 key 的一部分,所以只有在应答正常时才读取响应体。
- key 绝不会进入已发布的文档、日志行或子进程的参数,守护进程则完全没有凭据。测试注入一个金丝雀值,并断言它不出现在任何地方。
- 开发时也是同一条规则:绝不打印凭据。描述凭据时只说它存在、来源和长度;万一泄露,用 ctx.credentials.set(ref, …) 轮换。

已知缺口

- title 始终是 null:会话标题明明存在,但哪个访问器能暴露它尚未确认,猜错比 null 更糟。

MIT —— 见 LICENSE。
预览分享卡片长什么样 ↓eustace030616-hub/traffic-light
分享 · DeepSeek Harness Hub
eustace030616-hub/traffic-light

在窗口上方显示会话状态与余额的红绿灯

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部