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

AI 番茄钟 dragonheartcra/dsh-pomodoro-ai

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

让管家会话的 AI 帮你拆任务、排番茄并到点提醒

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · tool
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件发起外部网络请求
查看扫描证据(共 25 处,展示前 21 条)
  • 读取本地文件
    lib/index.js:106
    const st = statSync(file)
  • 读取本地文件
    lib/index.js:109
    const value = JSON.parse(readFileSync(file, 'utf8'))
  • 读取本地文件
    lib/index.js:129
    localTracks = readdirSync(dirs.musicDir)
  • 读取本地文件
    lib/index.js:417
    stat = statSync(filePath)
  • 读取本地文件
    lib/index.js:441
    return createReadStream(filePath, { start, end }).pipe(res)
  • 读取本地文件
    lib/index.js:444
    return createReadStream(filePath).pipe(res)
  • 写入本地文件
    lib/index.js:559
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/index.js:563
    appendFileSync(probeFile, JSON.stringify({ t: Date.now(), kind, build: BUILD, ...data }) + '\n')
  • 发起网络请求
    lib/client.js:59
    fetch(API + "/probe", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload) }).catch(() => {});
  • 发起网络请求
    lib/client.js:507
    fetch(API + "/state", { cache: "no-store" })
  • 发起网络请求
    lib/client.js:610
    fetch(API + "/command", {
  • 发起网络请求
    lib/client.js:621
    fetch(API + "/command", {
  • 发起网络请求
    lib/client.js:648
    fetch(API + "/flow/data")
  • 写入本地文件
    lib/store.js:184
    mkdirSync(dir, { recursive: true })
  • 读取本地文件
    lib/store.js:204
    if (!existsSync(stateFile)) return freshState(now(), config)
  • 读取本地文件
    lib/store.js:205
    const raw = JSON.parse(readFileSync(stateFile, 'utf8'))
  • 读取本地文件
    lib/store.js:234
    if (!existsSync(eventsFile)) return []
  • 读取本地文件
    lib/store.js:235
    const lines = readFileSync(eventsFile, 'utf8').split('\n')
  • 写入本地文件
    lib/store.js:255
    writeFileSync(tmp, JSON.stringify(state, null, 2) + '\n', 'utf8')
  • 写入本地文件
    lib/store.js:256
    renameSync(tmp, stateFile)
  • 写入本地文件
    lib/store.js:264
    appendFileSync(eventsFile, JSON.stringify(event) + '\n', 'utf8')
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • AI拆解任务
  • AI排番茄钟
  • 到点提醒

DeepSeek Harness 的 AI 番茄钟插件:一个全局时钟、按会话隔离工具、窗口内悬浮组件、FlowTunes 环境音。

README

由 DeepSeek 最新模型翻译生成
dsh-pomodoro-ai DeepSeek Harness(DSH)的 AI 番茄钟插件。 一个全局唯一的钟 + 一个会话级的「管家」+ 一个 DSH 窗口内的浮层部件。 你把任务丢给管家会话的 AI,它帮你拆解、估番茄数、排期、启动计时;到点它主动来找你。 其他会话连番茄钟工具都看不见——你在别的项目里干活时,不会有第二个 AI 来碰你的钟。 它解决什么问题 - 你不想手动管计时器:跟 AI 说「帮我拆一下今天的活」,它登记计划、算番茄数、启动第一个番茄,你直接去干活。 - 你同时开很多会话跑不同项目:番茄钟只属于你指定的那一个会话。其他会话的请求里连工具 schema 都不出现(顺带省 token),硬调也只会拿到 UNKNOWN_TOOL。 - 你要如实记录:暂停发生在哪一刻、暂停了多久、关机期间哪一段走完了(无法核实会明确标注),全部进事件流;统计按本地自然日聚合。 - 你不想被"提醒"绑架:阶段结束默认只通知一次,且投递到管家会话——AI 会带着权威状态(实际时长、暂停次数与时间点)来找你,而不是一个空响铃。 特性 | 能力 | 说明 | | AI 工具面 | pomodoro_plan / start / control / status / noise 五个工具,只对管家会话可见 | | 轮次模型 | 专注 → 短休 → …
展开完整文档(README 剩余 1 节)
dsh-pomodoro-ai

DeepSeek Harness(DSH)的 AI 番茄钟插件。

一个全局唯一的钟 + 一个会话级的「管家」+ 一个 DSH 窗口内的浮层部件。
你把任务丢给管家会话的 AI,它帮你拆解、估番茄数、排期、启动计时;到点它主动来找你。
其他会话连番茄钟工具都看不见——你在别的项目里干活时,不会有第二个 AI 来碰你的钟。

它解决什么问题

- 你不想手动管计时器:跟 AI 说「帮我拆一下今天的活」,它登记计划、算番茄数、启动第一个番茄,你直接去干活。
- 你同时开很多会话跑不同项目:番茄钟只属于你指定的那一个会话。其他会话的请求里连工具 schema 都不出现(顺带省 token),硬调也只会拿到 UNKNOWN_TOOL。
- 你要如实记录:暂停发生在哪一刻、暂停了多久、关机期间哪一段走完了(无法核实会明确标注),全部进事件流;统计按本地自然日聚合。
- 你不想被"提醒"绑架:阶段结束默认只通知一次,且投递到管家会话——AI 会带着权威状态(实际时长、暂停次数与时间点)来找你,而不是一个空响铃。

特性

| 能力 | 说明 |
| AI 工具面 | pomodoro_plan / start / control / status / noise 五个工具,只对管家会话可见 |
| 轮次模型 | 专注 → 短休 → … → 长休(每 N 轮),长短休可各自关闭 |
| 浮层部件 | DSH 窗口内可拖动浮层;展开态含计划/声音/周统计三个折叠面板;迷你态只有一个会"烧短"的圆环 + 时间 + focus/relax 小字 |
| 背景音 | FlowTunes 环境音多路叠加(每路独立音量)+ 音乐频道顺序播放 / 本地文件夹 |
| 提示音 | 专注 / 短休 / 长休结束三种提示音 + 可选滴答声 |
| 周统计 | 近 7 天柱状图 + 今日汇总,按本地自然日切分 |
| 到点主动开口 | 通过官方 @deepseek-ai/dsh-schedule 把提醒投递为该会话的后续回合 |
| 不丢计时 | 绝对 deadlineAt 推进:刷新页面、关掉窗口都不影响;重启后按剩余时间重新武装提醒 |
| 状态迁移 | state.json 版本化迁移(当前 v3),旧版本无损升级 |

安装

1) 装插件(官方 CLI,走 GitHub)
dsh plugin --profile desktop add github:dragonheartcra/dsh-pomodoro-ai

2) 给 profile 补一条官方持久提醒服务(阶段结束通知靠它)编辑 ~/.dsh/profiles/desktop/cordis.patch.yml,追加:
- insert:
- id: schedule
name: '@deepseek-ai/dsh-schedule'

重启 DSH(或启用官方 HMR 免重启),右下角就会出现浮层。

本包没有构建步骤、没有运行时依赖:lib/.js 直接就是成品,require 只有 react。

用法

1. 指定一个会话当「管家」

在你想管理番茄钟的那个会话里输入:

/pomodoro 接管 # 让当前会话成为管家(其他会话立刻看不见工具) /pomodoro 释放 # 解除 /pomodoro # 看状态:谁是管家、挂载在哪、计时到哪了

别名 /pomo。(命令名必须是 ASCII——官方注册表限制 ^[a-z][a-z0-9_-]$。)

2. 跟管家会话的 AI 说话

帮我拆一下今天的活,然后开始第一个番茄现在这个番茄还剩多久?我今天一共专注了多久?
把专注时长改成 45 分钟,每 2 轮长休放点雨声和篝火,音量小一点

3. 浮层

- 展开态:环 + 时间 + 阶段;下面四个按钮(暂停/继续、跳过、重置、停止);三个折叠面板(计划、声音、近 7 天);底部今日统计。
- 迷你态:只有一个圆——环随时间"烧短",中间是时间,下面一行小字 focus / relax(短休与长休都是 relax,靠环的颜色区分)。点一下展开,拖动可搬位置。
- 头部有「配色」按钮:自动 / 墨白 / 深色 / 浅色四套自带调色板。

会话隔离(管家会话)

为什么:DSH 里同时跑很多项目,只有一个会话该管番茄钟。全局注册工具的代价是三重的——每个会话的请求都带 5 个工具 schema(白付 token)、任何会话都能 pomodoro_start 抢走绑定、任何会话都能操作全局唯一的那只钟。

做法:工具不全局注册,只注册进「管家会话」的 agent scope。

| 层 | 位置 | 说明 |
| 时钟 / 状态 / 事件流 / HTTP 路由 / 浮层数据源 | 全局 | 一次只能专注一件事,单例是正确语义 |
| 到点提醒 | 全局,投递给管家会话 | reminderTarget = manager ?? watch |
| 5 个工具 | 管家会话的 agent.ctx | 其他会话不可见 |
| 指定管家 | 人类命令 /pomodoro 接管 | invocation.agent 就是当前会话 |

官方依据(cordis_inspect_query 查到的精确契约):

- tools.register():"Register globally or in the calling agent scope"
- tools.schemas(scope?) / get(name, scope?):"the viewing scope (the agent)"
- tools.execute():「隐形工具会报 UNKNOWN_TOOL」
- 事件 agent/created(serial):「为每个智能体初始化做准备」 → 会话重开时自动重新挂载
- 命令 handler(invocation):invocation.agent = 输入该命令的会话

三道闸:

1. assertToolSchema —— 注册前校验(空 parameters 会被上游 400 拒绝,并挂掉全站所有会话,有前科)
2. register 进管家 scope
3. 注册后回读隔离校验:该 scope 里工具齐全(5/5)且全局视图里一个都没有;任一不满足就整体回滚

外加每个工具 execute 里的第二道闸(非管家会话直接拒绝),以及 15 秒一轮的对账器兜底(防止「启动时服务未就绪」或「事件没等到」导致工具没挂上)。

架构

lib/store.js 纯逻辑内核:状态机 / 轮次 / 持久化 / 统计 / 事件流。零 DSH 依赖 → node 直接单测 lib/index.js host 半:HTTP 路由 + 1s tick + 5 个工具(只挂进管家 scope)+ 到点通知工具与路由抽成工厂(createTools / createApiHandler / createFlowLoader)→ 脱离 DSH 可测 lib/client.js client 半:shell.overlay 浮层 + 音频引擎(手写 bundle,无构建步骤) tools/ 三套测试(227 项断言,全部脱离 DSH 可跑)

权威在 host:浮层只渲染 + 发命令,倒计时用 host 给的绝对 deadlineAt 本地推算——轮询抖动或页面卡顿都不会让显示与 host 漂移。

数据落在哪

$DSH_HOME/pomodoro/
├── state.json 权威状态(版本化,当前 v3) ├── events.jsonl 追加式事件流(每次阶段变化 / 暂停 / 恢复 / 离线结算 / 配置变更) └── probe.jsonl 诊断探针(host 装配指纹、客户端上报、提醒武装/消费记录)

events.jsonl 每条都带来源:ai / widget / human / system——所以「谁在什么时候做了什么」是可查的。

配置

用 pomodoro_control 的 action=config 改,或直接写 state.json:

| 字段 | 默认 | 说明 |
| focusMin | 25 | 专注时长(分钟) |
| shortBreakMin | 5 | 短休时长 |
| longBreakMin | 15 | 长休时长 |
| roundsPerCycle | 4 | 每几个番茄进长休 |
| shortBreaksEnabled | true | 关掉则跳过短休 |
| longBreaksEnabled | true | 关掉则用短休顶替长休 |
| autoBreak | true | 专注结束是否自动进休息 |
| autoNextFocus | false | 休息结束是否自动开始下一段(默认停住等你) |
| notifyOnPhaseEnd | true | 阶段结束是否通知 |
| cueVolume | 0.7 | 提示音音量 |
| tickDuringWork / tickDuringBreak | false | 滴答声 |
| flowDataDir / loopIconsDir / cueDir / musicDir | 空 | 音源目录,见下 |

静态资源(插件不含任何第三方资产)

环境音清单/图标/提示音需要你自己提供,三种方式任选:

1. 环境变量 POMODORO_STATIC 指向你的 static 目录(期望其下有 flowtunes/、loop-icons/、audio/)
2. 把文件放进 $DSH_HOME/pomodoro/{flowtunes,loop-icons,audio}
3. 用 config.set 显式指定四个目录

缺了不影响计时:环境音/图标/提示音各自降级(路由 404、界面提示缺哪些文件)。

- flowtunes/:channels.json、catalog.json、ambient.json
- loop-icons/:<环境音 id>.svg
- audio/:alert-work.mp3、alert-short-break.mp3、alert-long-break.mp3、tick.mp3
- musicDir:本地音乐文件夹(host 流式提供,支持 Range)

环境音/音乐的音频本身从 FlowTunes 公共桶运行时流式播放(loop-audio-v3 / track-audio-v3),仓库里不含任何音频文件。

HTTP 路由

| 路由 | 说明 |
| GET /pomodoro-ai/api/health | 健康检查(build、pid、是否拿到 schedule、目录) |
| GET /pomodoro-ai/api/state | 权威状态快照(浮层就靠它) |
| POST /pomodoro-ai/api/command | 命令入口(浮层用;{action, payload, source}) |
| GET /pomodoro-ai/api/events?limit=N | 最近事件 |
| GET /pomodoro-ai/api/flow/data | 频道 + 曲目目录 + 环境音清单 + 本地曲目 + URL 模板 |
| GET /pomodoro-ai/api/flow/icon/<id> | 环境音图标(SVG) |
| GET /pomodoro-ai/api/cue/<name> | 提示音(支持 Range) |
| GET /pomodoro-ai/api/audio/<file> | 本地音乐(支持 Range) |

测试

npm test # 227 项断言,全部脱离 DSH
node tools/smoke.mjs # 内核:轮次周期 / 暂停 / 离线结算 / 持久化 / 统计 / 背景音 / 迁移 / 管家
node tools/host-smoke.mjs # 工具 schema 与行为 / 管家隔离 / 全部路由 / Range / 路径穿越
node tools/client-check.mjs # 在 node 里模拟 __ModuleLoader__ 与 React,把浮层真渲染一遍

三套都只用 node:*,不需要浏览器、不需要 DSH。host-smoke 里有一节「真实音源目录」,设了 POMODORO_STATIC 才会跑(验证你的数据文件与提示音真的能被读到)。

为什么这么设计:DSH 官方装配会缓存 ESM,改 host 代码原本必须重启。能提前验证的测试价值极高——上面这些坑几乎每一个都是靠"能脱离宿主跑"才被抓到的。

工程笔记(踩过的坑,都留了回归测试)

- 工具 schema 是全局的:parameters: {} 会被上游 400 拒绝,挂掉所有会话。现在有三道闸 + 注册前校验。
- CSS 变量"存在但为空":var(--x, fallback) 遇到空值会判定整条声明无效、不会用回退值。
我们曾因此得到一个"白底白字"的按钮。结论:凡是"文字压在什么颜色上"的地方,对比度必须自己保证,不能托付给主题 token。
- 热重载会留下孤儿音频:旧 bundle 启动的 /Web Audio 节点没有句柄指向它,会一直响且停不掉,只能刷新页面。现在所有发声节点登记进 window 上的注册表,新 bundle 载入的第一件事就是回收上一版。
- 加载顺序:profile patch 层比 bundle 层后装配,所以插件 apply 时可能还拿不到某些服务(schedule、agents)。所有跨服务调用都做了"等就绪 / 对账器兜底"。
- 两端契约不一致:浮层发 addLoop: "rain"、内核只认 {id, volume} → 静默失败。
现在内核兼容两种形状,并且有一条测试直接扫客户端源码的调用形状。
- serial 事件的监听器抛错会让会话创建失败:agent/created 的监听器全部 try/catch 吞掉并记 probe。

已知边界

- HTTP 路由在 localhost 上没有鉴权:任何有 shell 权限的会话理论上都能 curl /command 绕过工具闸门。
这是已知且接受的取舍(单机本地工具的合理上限);要收紧可以用 webServer.tapIndex 注入随机 token。
- 环境音/音乐需要联网(FlowTunes 公共桶)。数据与图标属于该服务的授权范围,不在本仓库内,请自行确认你的使用方式。
- 浮层在所有会话可见(它是全局那只钟的显示器);工具隔离才是"其他会话感知不到"的部分。

致谢

- 轮次模型与音量模型移植自 elegant-pomodoro(MIT),后者又源自 Pomotroid(MIT, © 2018 Christopher Murphy)。
- 到点通知基于官方 @deepseek-ai/dsh-schedule。
- 环境音/音乐数据来自 FlowTunes 的公开接口,未随本仓库分发。

许可

MIT © 2026 dragonheartcra
预览分享卡片长什么样 ↓dragonheartcra/dsh-pomodoro-ai
分享 · DeepSeek Harness Hub
dragonheartcra/dsh-pomodoro-ai

让管家会话的 AI 帮你拆任务、排番茄并到点提醒

这是你的仓库?认领条目

回到顶部