mirror of
https://github.com/hansjone/dsh-ops-cron.git
synced 2026-10-09 03:03:18 +08:00
Initial commit: scheduled tasks plugin for DeepSeek Harness
Sidebar jobs under New Session, isolated run history, cron/at schedules, and model-facing cron_* tools.
This commit is contained in:
commit
ef8ff6e10d
22 changed files with 5711 additions and 0 deletions
205
docs/NOTES.md
Normal file
205
docs/NOTES.md
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
# dsh-cron-tasks 经验记录
|
||||
|
||||
日期:2026-08-23 — 2026-08-24
|
||||
包名:`@dsh-external/dsh-cron-tasks`
|
||||
Loader id:`dsh-cron-tasks`
|
||||
源码:本仓库
|
||||
运行时副本:`~/.dsh/plugins/dsh-cron-tasks`(`file:` 接入 web + desktop)
|
||||
产品契约:`docs/PRD.md`
|
||||
|
||||
这次会话把定时任务从「能调度」推到「能打开历史对话、能被 AI 创建、能当普通工作区会话继续聊」。下面只记本轮踩过的坑和已经定下来的产品语义。
|
||||
|
||||
---
|
||||
|
||||
## 产品(一句话)
|
||||
|
||||
到点后 Harness **新开一条 root Session** 跑事先写好的提示词,记录进侧栏「定时任务」历史。这类 Session **不得淹没日常工作区列表**。
|
||||
|
||||
这不是官方 `@deepseek-ai/dsh-schedule`(同会话 reminder),也不是 OS `crontab`。
|
||||
|
||||
三个面都要有:
|
||||
|
||||
1. 侧栏「新会话」正下方入口(不是 footer)
|
||||
2. 设置 → 插件配置里的调度策略
|
||||
3. 历史记录:点开就是原生对话
|
||||
|
||||
重叠 skip、漏跑 skip、Host 没跑就不触发。
|
||||
|
||||
---
|
||||
|
||||
## 形态
|
||||
|
||||
| 半边 | 入口 | 职责 |
|
||||
|---|---|---|
|
||||
| Host | `lib/index.js` + `lib/host.js` | 定时器、CRUD、fire、归档/揭示、工具、skill、同源 API |
|
||||
| Client | `lib/client.js`(`window.__ModuleLoader__` factory) | 侧栏入口、任务列表、编辑器、隐藏原生 cron 行、打开会话、fork 提升 |
|
||||
|
||||
`package.json` 必须同时有 `dsh.bundle.patch` 和 `dsh.client`(`platform: web`,`immediately: true`)。Host **不要** import `@deepseek-ai/*`,也不要把它写进 `dependencies`。工具用纯 `ToolDefinition`,不要 `defineTool`。
|
||||
|
||||
Client `inject` 只写 `slots` / `locale` / `settingsScope`。静态 `inject: ['sessions']` 会在 boot 死锁;`sessions` / `workspaces` 用 `ctx.inject` 可选 + `internal/service`。
|
||||
|
||||
---
|
||||
|
||||
## 本机加载(file:)
|
||||
|
||||
```sh
|
||||
# 拷到运行时后再 file: 安装(不要 link:)
|
||||
dsh plugin --profile web add file:$HOME/.dsh/plugins/dsh-cron-tasks
|
||||
dsh plugin --profile desktop add file:$HOME/.dsh/plugins/dsh-cron-tasks
|
||||
```
|
||||
|
||||
改代码后必须再拷:
|
||||
|
||||
1. `~/.dsh/plugins/dsh-cron-tasks`
|
||||
2. `~/.dsh/profiles/web/node_modules/@dsh-external/dsh-cron-tasks`
|
||||
3. `~/.dsh/profiles/desktop/node_modules/@dsh-external/dsh-cron-tasks`
|
||||
|
||||
`file:` 是拷贝。只改仓库,profile 里的副本不会自己变。改 Host / bundle 后用户自己重启 `dsh web`;Desktop 和 web 互不影响。
|
||||
|
||||
验收:
|
||||
|
||||
- `dsh --profile web --dump-config` 能看到 `id: dsh-cron-tasks`
|
||||
- `cd packages/dsh-cron-tasks && node --test test/*.test.js`
|
||||
- curl 本机加 `--noproxy '*'`
|
||||
|
||||
---
|
||||
|
||||
## 运行会话怎么藏、怎么打开
|
||||
|
||||
v1 用 `workspaceRegistry.archiveSession` 从工作区列表拿掉。归档当前会话会把选中清掉,所以 v2 打开历史时必须先 **unarchive** 再 `sessions.open`。
|
||||
|
||||
工作区里再用标题前缀 `定时任务 · ` 把原生行藏掉(`hideNativeCronRows`)。藏标题 ≠ 删日志。
|
||||
|
||||
打开历史的坑:
|
||||
|
||||
- `sessions.open` 要求 id 已在 summaries 里;归档中的 id 会抛,catch 后看起来像「点了还停在原来的工作区会话」
|
||||
- 要等 unarchive 反映到 `archivedSessionIds`,必要时 `sessions.refresh`,再 `open`,确认 `list.current === sessionId`
|
||||
- `ctx.get('sessions')` 在未 inject 时可能抛,必须 `tryGet` / `faces.sessions`
|
||||
|
||||
`POST /dsh-cron-tasks/runs/:id/open` 负责 reveal;client 再 open。离开定时任务模式时 `POST /conceal` 把**已知运行会话**再归档。fork 出来的子会话不在这份名单里,不要误归档。
|
||||
|
||||
---
|
||||
|
||||
## 执行失败 `{{model}}` 没有值
|
||||
|
||||
`agents.create` 不自动带上「新会话」用的默认模型。Persona 模板插 `{{model}}`,空值会让整轮装配失败。
|
||||
|
||||
修法:`ctx.get('agentDefaultModel').currentSelection()`,create 时写入 `agentOptions`,并在 agent ctx 上监听 `system-prompt/assemble` 和 `agent/request` 填 `provider` / `model`。没有选中模型要响亮失败,不要默默跑。
|
||||
|
||||
---
|
||||
|
||||
## 模型怎么建任务(不要塞 system-reminder)
|
||||
|
||||
一开始在每条会话塞 `<system-reminder>` 讲定时任务,不合理。改成:
|
||||
|
||||
- runtime skill `scheduled-tasks`(**必须** `source: 'runtime'`,否则 skill_load 报 `source must be a string`)
|
||||
- 工具:`cron_create` / `cron_list` / `cron_pause` / `cron_resume` / `cron_delete`
|
||||
|
||||
MiniMax 锚定会话常驻工具只有 `bash` / `str_replace_editor` / `skill_search` / `skill_load` / `dev_tool_search`。cron 工具不在 resident set 里,模型会先去跑 `crontab -l`。skill 必须写明:先 `skill_search`「定时任务」,再 `skill_load scheduled-tasks`,**禁止 crontab / /etc/cron\***。
|
||||
|
||||
session.jsonl 对照过:没 load skill 时模型当 OS cron 用;load 成功后才会调 `cron_*`。
|
||||
|
||||
---
|
||||
|
||||
## 日程字段:模型会叠着传
|
||||
|
||||
session.jsonl 5:「一分钟后」一次性任务。模型第一次:
|
||||
|
||||
```json
|
||||
{ "at": "00:33", "hour": 0, "minute": 33 }
|
||||
```
|
||||
|
||||
插件按互斥报 `pass only one of expr, at, or hour/minute`,错误后缀还说「请传 hour+minute」,模型第二次变成 `expr` + `hour`。第三次才成功,时间已经漂了。
|
||||
|
||||
定下来的优先级(多余字段忽略,不要报错):
|
||||
|
||||
1. `after_minutes` / `in_minutes`(「一分钟后」用这个,不要自己算钟面)
|
||||
2. `hour` + `minute`(今晚几点;**hour=0 是午夜**,不能当 falsy 丢掉)
|
||||
3. `at`
|
||||
4. `expr` / `cron`
|
||||
|
||||
过去的一次性 `at` 仍然拒绝。`datetime-local` 必须按任务时区编解码,禁止对 UTC ISO 做 `slice`(否则 11:13 会显示成 15:13 或 23:13)。
|
||||
|
||||
skill 里写清当前本地时间;不要让模型猜日历(曾经把 2026-08-23 写成 2026-05-14)。
|
||||
|
||||
---
|
||||
|
||||
## 调度器:一次性和漏跑
|
||||
|
||||
5 字段 cron + IANA(默认 `Asia/Shanghai`)。
|
||||
|
||||
一次性 `at` 触发后必须把 `nextRunAt` **写成 `null`**。用 `??` 回退会把 due 时间填回去,每 15s tick 再跳一次。判断完成用 `nextRunAt === null`,不要用 `??`。`Object.hasOwn` 才能持久化 null。
|
||||
|
||||
漏跑:Host 宕机不回放积压。skip 要去重,避免 misfire skip 刷屏。
|
||||
|
||||
暂停:列表可停可恢复;立即运行(播放图标)即使暂停也允许。
|
||||
|
||||
---
|
||||
|
||||
## 「在新对话中分支」
|
||||
|
||||
官方:`sessions.fork({ sessionId, atSeq, increaseTitle: true })` 然后 `open(childId)`。子会话复制历史,标题变成 `定时任务 · 晨报 (1)`。
|
||||
|
||||
看起来像刷新,因为:
|
||||
|
||||
- 内容几乎一样
|
||||
- 标题仍带前缀,被 `hideNativeCronRows` 藏掉
|
||||
- 侧栏还停在定时任务模式
|
||||
- 父会话未进任何工作区 `sessionIds`,官方 `forkWorkspace` 不 attach 子会话
|
||||
|
||||
合理语义:
|
||||
|
||||
| | 原运行会话 | 分支子会话 |
|
||||
|---|---|---|
|
||||
| 角色 | 历史原件 | 普通可继续聊的对话 |
|
||||
| 列表 | 继续藏 | 出现在工作区或未分组 |
|
||||
| 标题 | `定时任务 · …` | 去掉前缀,如 `晨报 (1)` |
|
||||
| 之后 | 仍可从历史打开 | 切走还能在左边找到 |
|
||||
|
||||
插件要:认出 parent 是已知 run → 改标题 → `POST /sessions/:id/adopt` → 退出定时任务模式。不要把子会话写进历史。
|
||||
|
||||
### 工作区绑定
|
||||
|
||||
官方 `attachSession` 要求 **header.cwd === workspace.path**。cwd 对不上就不能挂到别人的项目。
|
||||
|
||||
- 任务没填 cwd 时,新运行用**最近工作区路径**并 attach,再 archive(槽位还在,列表不显示)。之后 fork 会继承该工作区。
|
||||
- 已存在的、cwd 仍是 `~/.dsh/cron-tasks/workspace` 的子会话,只能出现在**未分组**。
|
||||
- `hideNativeCronRows` **禁止**在分组收起(DOM 里没有 session 行)时把整组「未分组」`display:none`。切走找不到会话,多半是这个。
|
||||
|
||||
AI 在工作区会话里建任务:`cron_create` 若没传 cwd,用 `exec.agent.session.header.cwd`。手动新建:下拉已有工作区,或「自定义路径」。
|
||||
|
||||
---
|
||||
|
||||
## UI
|
||||
|
||||
列表视觉对齐工作区(运行时偷 hashed class + `--dsw-*`)。任务当分组,运行当行。点任务出编辑器,点运行打开原生会话。
|
||||
|
||||
- 加号是新建任务;运行用播放图标
|
||||
- 可搜索、可暂停
|
||||
- 工作目录:工作区下拉 / 自定义 / 留空=最近工作区
|
||||
|
||||
不要用 CSS 把输入框圆角削平(那是额度条子的教训,这里侧栏 overlay 用 `data-dsh-ct-mode`)。
|
||||
|
||||
---
|
||||
|
||||
## 排错顺序
|
||||
|
||||
1. 启动日志 `[dsh-cron-tasks]`
|
||||
2. `--dump-config` 有没有 row
|
||||
3. profile `node_modules/@dsh-external/dsh-cron-tasks` 是不是旧副本
|
||||
4. `~/.dsh/cron-tasks/store.json`(`nextRunAt: null` 是否被写回)
|
||||
5. 模型路径:session.jsonl 里有没有 `skill_load scheduled-tasks`、`cron_create` 参数是否叠字段
|
||||
6. 打开会话失败:是否还在 `archivedSessionIds`、summaries 里有没有这个 id
|
||||
7. 分支后找不到:标题前缀、未分组被整组隐藏、cwd 与工作区路径不一致
|
||||
|
||||
---
|
||||
|
||||
## 明确不要做
|
||||
|
||||
- 改 DSH 本体;发 npm / 用本机 GitHub PAT
|
||||
- `link:` 安装
|
||||
- 每条会话塞定时任务 `<system-reminder>`
|
||||
- 把 `@deepseek-ai/*` 当 runtime 依赖
|
||||
- 补跑漏掉的 cron 节拍
|
||||
- 把 fork 子会话再归档进历史
|
||||
- 互斥报错逼模型重试日程字段(直接按优先级吞)
|
||||
182
docs/PRD.md
Normal file
182
docs/PRD.md
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
# 定时任务(dsh-cron-tasks)产品需求文档
|
||||
|
||||
**产品名**:定时任务
|
||||
**包名**:`@dsh-external/dsh-cron-tasks`
|
||||
**Loader id**:`dsh-cron-tasks`
|
||||
**版本**:v2
|
||||
**状态**:v1 已交付调度与隔离。v2 补齐结果可见、侧栏融入工作区列表、原生会话继续聊、工作目录与超时。
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题与定位
|
||||
|
||||
用户需要一种**与当前对话无关**的定时工作方式:到点后 Harness 新开一个 root Session,用事先写好的完整提示词跑一轮 Agent,然后把这次运行记进「定时任务历史」。这类 Session **不得出现在左侧工作区/会话列表**,以免把日常工作区淹没。
|
||||
|
||||
这与官方 `@deepseek-ai/dsh-schedule` 不同:官方 Schedule 是**同一会话内的 reminder**(`after_seconds` / `at` / `every_seconds`),回到原来的 live Session 做 follow-up。本插件解决的是「按计划独立跑完一件事,并留下可回看的历史」。
|
||||
|
||||
调度器住在 DSH Host 进程里。Host 未运行时任务不会触发;这是预期行为,不是缺陷。错过的节拍**不补跑成写入风暴**。
|
||||
|
||||
---
|
||||
|
||||
## 2. 三个产品面(v1 必须全部落地)
|
||||
|
||||
以下三个面按目标原文命名,缺一不可。
|
||||
|
||||
### 2.1 左侧侧边栏「新会话」按钮正下方的「定时任务」入口
|
||||
|
||||
- 在左侧侧边栏 **「新会话」按钮正下方** 放置可点击控件,文案为 **「定时任务」**。
|
||||
- 展开态:图标 + 「定时任务」,视觉对齐原生「新会话」(高度、圆角、`--dsw-*` token)。
|
||||
- 收缩轨(56px rail):只显示约 18px 图标,位置仍紧挨「新会话」下方。
|
||||
- **不**把该入口放到 `sidebar.footer.action`(Settings 旁)作为唯一入口。官方没有「新会话正下方」的一等 slot,v1 用受控的客户端注入插在「新会话」按钮之后、工作区列表之前。
|
||||
- 点击后打开任务视图:当前任务列表(名称、日程、启用状态、下次运行、上次结果)+ **定时任务历史**。任务的创建 / 列表 / 暂停恢复 / 删除 / 立即运行都在这个视图里完成。
|
||||
|
||||
### 2.2 设置页「插件配置」里的定时任务设置
|
||||
|
||||
- 在 **设置 → 插件 → 插件配置** 中出现本插件卡片。
|
||||
- 卡片只承载**插件级策略**,不是任务电子表格:
|
||||
- 启用调度器
|
||||
- 默认时区(IANA,例如 `Asia/Shanghai`)
|
||||
- 历史保留条数
|
||||
- 重叠策略(v1:跳过)
|
||||
- 漏跑(misfire)策略(v1:跳过,不回放积压)
|
||||
- 单条任务的编辑器在侧栏「定时任务」视图,不把任务表塞进设置卡片。
|
||||
|
||||
### 2.3 定时任务历史
|
||||
|
||||
- 每一次触发(到点或「立即运行」)留下一条历史:job id、run id、计划时间、实际时间、终态、结果 Session id、短错误或摘要。
|
||||
- 运行产生的 Session **不出现在工作区列表**;日志保留,可从历史记录打开/对照 Session id。
|
||||
- 「从工作区隐藏」≠ 删除日志。
|
||||
|
||||
---
|
||||
|
||||
## 3. 市面插件取舍
|
||||
|
||||
对照当前市场上的 DSH 定时/调度插件,明确 **Keep(吸收)** 与 **Drop(明确不做)**。本插件是独立实现,不 fork 任何现有仓库。
|
||||
|
||||
| 插件 | 形态摘要 | Keep | Drop |
|
||||
|---|---|---|---|
|
||||
| **chicheng-cron**(534119219) | 侧栏「新会话」正下方「定时任务」入口;cron 跑 shell/python/node/Skill/Agent;推送;可归档会话 | **入口位置**(新会话正下方,展开/收缩对齐原生);Agent 任务到点执行;执行历史;Host 关闭不补跑 | Shell / Python / Node 脚本执行;Skill 注入;chicheng-push / messaging-core 推送;移动端专项适配 |
|
||||
| **dsh-automation**(titanwings) | 全新 root Session 跑独立任务;可审计历史;IANA 时区;重叠 skip;Host 宕机只 catch 最近一次、不回放 backlog;可选 archive 跑出来的 Session | **每次触发 = 新 root Session**(不是当前聊天 follow-up);durable 历史(queued/running/终态 + session id + 摘要/错误);**overlap skip**;**misfire 不写风暴**;archive 隐藏工作区列表、日志保留;提示词必须自包含 | 模型侧 `automation_*` 工具;RRULE 友好表单(v1 用 cron/`at` 即可);权限预设只读/可写双模式与 capability allowlist 的完整沙箱产品化;对话 Tab 作为主入口 |
|
||||
| **cronjob-dsh-plugin**(peng-huiyang) | 设置页「定时任务」;专用会话;cron 5/6/7 + IANA;`cron_*` 工具;触发文本当不可信内容 | **设置页可配置**(我们把策略放进「插件配置」);**不可信提示词包裹**;错过周期不补跑 | 把任务表放进设置页当唯一 UI;复用同一条「专用会话」反复 follow-up(v1 每次新开会话);模型工具 `cron_create/list/delete` |
|
||||
| **dsh-cron**(omdsh-dev 等社区条目) | 定时调度,向已有智能体会话注入消息或触发后续操作 | 「到点做事」这一产品意图 | 往**当前/已有会话**注入消息(那是官方 Schedule 的赛道) |
|
||||
| **dsh-schedule-tasks**(uluckystar / MyDSH) | 5 段 cron;`sidebar.footer.action` + 浮层;第一版动作是 shell / 站内 notify | 5 段 cron + 本地时区;列表展示下次触发/上次结果;启停/删除/手动触发 | **Footer-only 入口**(不满足「新会话下方」);shell 与站内 notify 作为主动作;不唤起 Agent 会话 |
|
||||
| **官方 dsh-schedule**(`@deepseek-ai/dsh-schedule`) | 会话内 reminder:`after_seconds` / `at` / `every_seconds` ≥ 300s;回到原 live Session;无日历/cron | 与官方分工:**不替换**它。同会话「十分钟后回来」继续用官方 | 日历/cron(官方 v1 也不做);外部通知;本插件不提供 same-chat reminder |
|
||||
| 其他参考(非 v1 对标必须,但影响取舍) | | | |
|
||||
| dsh-plugin-automations(Sev7een) | 设置页;准点 / 谷时段;一次或每天 | 设置页策略分离 | 谷时段/峰谷计价窗口 |
|
||||
| dsh-scheduler(yangyongzhen) | YAML jobs;shell / webhook;Server酱/钉钉/飞书 | cron + `at` 二选一 | webhook、IM 推送、YAML-only 配置 |
|
||||
| dsh-routines(Jesse-njx) | cron prompt;overlap / missed-run / timeout 安全默认 | overlap + missed-run 安全默认 | 把摘要推到外部「你已经在的地方」 |
|
||||
| dsh-plugin-scheduled-tasks(Ceelog / @opendsh) | 按项目、新 headless session、一次/间隔/cron、持久历史 | 新 session + 持久历史 | 模型对话内创建任务(v1 不做) |
|
||||
| dsh-sleep-send | 输入框右侧定时发送当前草稿 | — | localStorage、改当前输入框、补发过期草稿 |
|
||||
| dsh-aura-scheduler | 系统主动开口、价值网络 | — | 心跳/传感器/Off-peak 主动打扰 |
|
||||
|
||||
**取舍一句话**:吸收 chicheng-cron 的入口位置、dsh-automation 的「新 Session + 历史 + 隐藏工作区 + 安全调度语义」、cronjob 的设置页策略、不可信提示词与 `cron_*` 工具;拒绝脚本/推送/footer-only/同会话 reminder/OS daemon。
|
||||
|
||||
---
|
||||
|
||||
## 4. v1 功能需求
|
||||
|
||||
### 4.1 任务模型
|
||||
|
||||
一条任务是**自包含**的:
|
||||
|
||||
| 字段 | 要求 |
|
||||
|---|---|
|
||||
| 名称 | 非空短名,用于列表与历史 |
|
||||
| 提示词 | 非空;到点原样交给新 Session。必须写得让新会话能独立理解,不依赖创建时的聊天上下文 |
|
||||
| 日程 | 至少两种:一次性 `at`(ISO 8601 时间点)与循环 **5 字段 cron**(分 时 日 月 周) |
|
||||
| 时区 | IANA,默认取插件配置里的默认时区 |
|
||||
| 启用 | 可暂停 / 恢复 |
|
||||
|
||||
人可以:**创建、列表、暂停/恢复、删除、立即运行**。
|
||||
|
||||
### 4.2 调度语义
|
||||
|
||||
- 循环任务用 5 字段 cron,在指定 IANA 时区的墙上时钟求下次触发。
|
||||
- 一次性 `at` 到点触发一次,之后不再调度。
|
||||
- 非法 cron / 非法时区 / 空提示词在保存时失败,不写入。
|
||||
- Host 重启后从磁盘恢复任务表,按**当前时刻**重算下次触发。
|
||||
- **漏跑**:Host 宕机期间错过的节拍 **不回放积压**(at-most-once / skip)。v1 不把 N 次错过写成 N 条 queued。
|
||||
- **重叠**:同一任务若已有 `running` 或 `queued` 的 run,到期记录为 `skipped`(原因 overlap),不并行开第二场。
|
||||
- 调度器只在 DSH Host 进程内存活。没有 OS crontab、没有独立 daemon。
|
||||
|
||||
### 4.3 触发路径
|
||||
|
||||
到点或「立即运行」时:
|
||||
|
||||
1. 由 Host 创建 **新的 root Session**(不是当前聊天的 follow-up)。
|
||||
2. 将包裹后的提示词作为 `source.kind = plugin` 的用户消息入队(**不伪装成人手输入**)。
|
||||
3. 提示词外层标明「这是定时任务下发的不可信内容」。
|
||||
4. 将该 Session **从工作区/侧栏会话列表隐藏**(调用 `workspaceRegistry.archiveSession` 或等价归档;失败则不得声称满足本条)。日志保留。
|
||||
5. 追加一条 **定时任务历史**。
|
||||
|
||||
终态至少包括:`queued` / `running` / `succeeded` / `failed` / `skipped`。崩溃恢复时,未完成的 `queued`/`running` 记为失败(host interrupted),不偷偷重跑。
|
||||
|
||||
### 4.4 工作区隔离
|
||||
|
||||
- 运行 Session **不得**出现在普通工作区列表。
|
||||
- 插件维护「这些 session id 是定时任务运行」的集合;工作区可见投影排除它们。
|
||||
- 历史里能看到 session id 与短摘要;v1 不依赖官方 unarchive(当前 Harness 可能没有解档 API)。
|
||||
|
||||
### 4.5 UI
|
||||
|
||||
- 「定时任务」入口:见 §2.1。
|
||||
- 任务视图:列表 + 新建/编辑表单(名称、提示词、cron 或 `at`、时区、启用)+ 立即运行 + 历史。
|
||||
- 插件配置卡片:见 §2.2。
|
||||
- 样式只用 `--dsw-*` token,不引入第二套组件库,组件内不碰 `ctx`。
|
||||
|
||||
### 4.6 安装形态
|
||||
|
||||
可 `dsh plugin add file:…` 的 Host+Client 包:
|
||||
|
||||
- `package.json` 声明 `dsh.bundle.patch` 与 `dsh.client.platform: web`
|
||||
- `cordis.patch.yml` 唯一 `id: dsh-cron-tasks`
|
||||
- Host `lib/index.js` 的 `apply(ctx)`
|
||||
- Client `lib/client.js`(`window.__ModuleLoader__`)
|
||||
- **不**把 `@deepseek-ai/*` 放进 `dependencies`
|
||||
|
||||
交付:拷到 `~/.dsh/plugins/dsh-cron-tasks`,web 与 desktop 均 `add file:$HOME/.dsh/plugins/dsh-cron-tasks`,改 bundle 后重启 profile。
|
||||
|
||||
---
|
||||
|
||||
## 5. 非目标(v1 明确不做)
|
||||
|
||||
- Shell / Python / Node 脚本任务、webhook、Server酱 / 钉钉 / 飞书 / 其它 push(chicheng-cron / dsh-scheduler / dsh-schedule-tasks 第一版那条路)。
|
||||
- 替换官方 `@deepseek-ai/dsh-schedule` 的同会话 `at` / `after_seconds` reminder。
|
||||
- OS daemon,或 Host 没在跑时仍触发;错过节拍的 catch-up backlog。
|
||||
- 发布到 npm / GitHub;`link:` 安装;使用本机 GitHub PAT。
|
||||
- 自然语言解析 cron(仍由模型自己把口语转成 5 段 cron / ISO `at`,插件只收结构化参数)。
|
||||
- 谷时段 / 峰谷计价窗口、多 Host 抢锁、无人值守 `danger-full-access`。
|
||||
- 把任何现有插件 copy/fork 当交付物。
|
||||
- 6 字段秒级 cron、RRULE、自然语言建任务、邮件 SMS。
|
||||
|
||||
---
|
||||
|
||||
## 6. 后续阶段(不阻塞 v1)
|
||||
|
||||
- 打开历史 Session 的一等 UI(取决于官方 unarchive / 按 id 打开能力)。
|
||||
- 超时取消、并发上限、工作区绑定与权限预设。
|
||||
- 可选通知(且默认关闭)。
|
||||
|
||||
---
|
||||
|
||||
## 7. v2 产品补充
|
||||
|
||||
- 历史行展示**最后一条助手回复**(如「测试成功」),不只是 `Turn finished`。
|
||||
- 点击「定时任务」后,**工作区列表区域**换成任务列表(分组=任务,行=运行记录),增删改查/立即运行都在这里,视觉对齐原生 session/project 行。
|
||||
- 点任务:右侧主栏是编辑页(提示词、cron、工作目录、超时)。
|
||||
- 点运行记录:右侧打开**原生 DSH 会话**(`sessions.open`),可以继续聊。因此 v2 **不再归档**这些会话(归档会把当前选中会话清掉);普通工作区里用标题前缀「定时任务 ·」把它们藏起来。
|
||||
- 任务可配 **工作目录** 与 **超时**,便于拉网页写文件、出图等长任务。
|
||||
|
||||
## 8. 模型工具
|
||||
|
||||
- 与侧栏手动新建共用同一份任务表。
|
||||
- 工具:`cron_create`、`cron_list`、`cron_pause`、`cron_resume`、`cron_delete`。
|
||||
- 口语日程由模型转成 5 段 cron 或 ISO `at`;插件不做自然语言解析。
|
||||
- 这不是官方同会话 reminder(`schedule_create`)。
|
||||
|
||||
## 9. 风险与约束
|
||||
|
||||
- **隐藏 Session** 依赖当前 Harness 的 `workspaceRegistry.archiveSession`。若归档调用失败,不得把 Session 留在普通列表却宣称验收通过。
|
||||
- **入口位置**:无官方「新会话下方」slot;注入必须紧挨该按钮。仅 footer 不满足需求。
|
||||
- **Host 必须在跑**。写进本 PRD 与 README,避免被当成 bug。
|
||||
- 提示词按不可信内容包裹,降低提示注入把定时通道变成越权入口的风险。
|
||||
Loading…
Add table
Add a link
Reference in a new issue