dsh-loopx-plugin
loopx-project/loopxLoopX——面向长周期 Agent 的提供商中立、本地优先状态内核与控制平面:在 DeepSeek Harness 执行层之上持久化 Goal、Todo、门禁、证据、配额、恢复与交接状态;插件负责引导安装 CLI 与技能、准入有界的同会话续跑,并为精确绑定的工作循环提供本地 GoalBar。
常驻宿主的定时引擎,带 Web 任务面板与 timer_agent 工具:按 cron 计划触发真实 Agent 会话,可固定已有会话保持上下文连续,也可在指定项目目录新开会话。
中文 | English
一个 DeepSeek Harness (DSH) Web GUI 插件:调研 NousResearch/hermes-agent 的 cron 系统后,按其「定时器 ↔ Agent 协同」思路实现的 host 常驻定时任务引擎——dsh web 服务启动即生效,GUI 页面关闭也照常触发。

到点(5 段 cron)通过真实 agent 会话执行你写好的 prompt:
对话中可直接用 timer_agent 工具管理任务(create / list / update / pause / resume / remove / run);Web GUI 侧边栏「定时任务」面板管理同一批任务——一个台账,三个入口(工具 / WebUI / 文件)。
命令 + 参数(可选工作目录、超时),不经过 AI、不消耗额度;stdout/stderr 尾部(≤16k 字符)与退出码随执行记录入账。适合自包含的脚本(下载、导出、续期等)[!WARNING] 普通任务会在你的机器上以当前用户权限执行任意命令,没有任何沙箱或白名单。 任何能新建/编辑任务的人(你自己、能调用
timer_agent工具的 agent 会话、能访问回环 API 的本机进程)都能让任意程序定时运行。请只填入你审查过的、无人值守安全的命令;不要把该插件暴露给不可信环境;任务台账jobs.json可被篡改即等价于本机任意代码执行。谨慎使用。
┌─ dsh web 宿主进程 ────────────────────────────────┐
│ 60s ticker(常驻,GUI 关闭也运行) │
│ ├─ HostJobStore ~/.dsh/timer-agent/jobs.json │
│ │ (原子写,损坏降级不崩溃) │
│ ├─ TimerRunner at-most-once:先顺延 nextRunAt │
│ │ 再触发;运行中跳过;错过即跳过 │
│ │ ├─ agents.resume(钉住会话) │
│ │ └─ agents.create + workspaceRegistry │
│ │ (新会话挂到正确项目) │
│ ├─ timer_agent 工具(模型可调用) │
│ └─ /api/dsh-timer-agent/* 路由(仅回环) │
└────────────────────────┬──────────────────────────┘
│ HTTP 轮询镜像(5s)
┌─ 浏览器半边(薄)────────┴──────────────────────────┐
│ 侧边栏入口 + 任务面板(React) │
│ 可折叠项目/会话树 · cron 预设 · 执行历史 │
└───────────────────────────────────────────────────┘
执行结算通过 session/event(turn/end 的 reason.kind)判定成功/失败,失败原因精确写入台账。
* / */n / a-b / 逗号列表)+ 预设下拉(每天 09:00 / 每小时 / 每 10 分钟 / 每周一 09:00,新建与编辑页均有)timer_agent 直接创建与管理定时任务plugin:timer-agent 播报段,agent 知晓本插件能力与协作方式适配 dsh 0.2.0-rc.2(自 v0.7.0 的 dsh 0.1.5-rc.2 跨两个 minor 升级,两处破坏性变化):
SettingsProvider.installSection 运行时注册,换为 SettingsForms——插件配置改由 cordis loader 按导出的 Config schema 声明式注入(值写在 profile patch 的插件行上,改动即重载插件 fiber),client 端配置表单由 SettingsForms 自动生成。本插件删除 installSection 注册与 settings 注入,enabled/announceToAgent 语义不变@deepseek-ai/schemastery fork 收紧到 ~3.18.4(3.18.3/4 引入 Mode/SchemaOutput 类型体系),与原版 schemastery 同名声明合并后 typecheck 冲突。插件改用 fork 与宿主同源(运行时行为不变,宿主对 schema 本就鸭子类型调用)settings 移除后为四项)、webServer 路由、systemPrompt.section、tools.register、session/event/turn/end、client 端 slots/sessions 注入与 /plugins/<id>/client.js 服务路径;dsh.compatibility.dshReleases 声明更新为 0.2.0-rc.2@deepseek-ai/dsh-* 对齐 0.2.0-rc.2)cancel 决策与 projectContent 投影;system-prompt 新增 interpolate 选项与 TOOL_COMPUTER_USE/MCP_SERVERS 段位;ui-settings 新增 settings.launcher slot 与 configForms(原 settingsScope 改名)向下兼容:任务台账格式无变化,v0.7.0 及更早的 ~/.dsh/timer-agent/jobs.json 升级即用。真机验证:隔离 DSH_HOME 分别起 dsh web 0.2.0-rc.2 与 0.1.5-rc.2,插件均正常挂载、/api/dsh-timer-agent/jobs 200、台账零副作用;更旧版本 dsh 请用 v0.7.0。
适配 dsh 0.1.5-rc.2(自 v0.6.0 的 dsh 0.1.2-rc.1 跨四个 minor 升级,宿主插件面 API 几乎全部稳定,仅两处破坏性变化):
agents 的 cancel(cause):宿主把自由文本 cause 换成了稳定意图枚举(user/parent/hook/disposed)。本插件的超时取消迁移为 { kind: 'hook', reason: … }(无人到场的自动取消并携带原因)sessionPersistence.inspect 被移除。钉住会话恢复时的预设重建改走 sessionQuery.readSession(完整事件流,agent-preset/selected 仍生效);宿主未挂 sessionQuery 时回退 sessionPersistence.stat 读 headersession/event/turn/end、agentDefaultModel/llm/agentPresets、followup 消息形状)经逐一核对全部不变;dsh.compatibility.dshReleases 声明更新为 0.1.5-rc.2schemastery(宿主运行时对 schema 仅做鸭子类型调用,分叉包无影响)向下兼容:任务台账格式无变化,v0.6.0 及更早的 ~/.dsh/timer-agent/jobs.json 升级即用;仅在 dsh ≥ 0.1.5 上验证,旧版 dsh 请用 v0.6.0。
变更
nextRunAt):cron / 固定间隔只用于计算它,到期即触发runAt 创建 / timer_agent 的 run_at 参数):触发一次即归档;手动执行同样消耗executions 最后一条的 startedAt,回退 lastTriggeredAt)重算,错过不补跑nextRunAt / 工具 next_run_at);Cron 严格按表达式,拒绝手改向下兼容
dsh plugin --profile web add link:<本目录绝对路径>
安装后重启 dsh web,侧边栏出现「定时任务」入口即生效(浏览器侧改动强刷 Ctrl+F5 即可)。
| Option | Type | Default | Description |
|---|---|---|---|
| enabled | boolean | true | Master switch: ticker + tool + routes. Set false to disable the engine without uninstalling. |
| announceToAgent | boolean | true | Inject a system-prompt section announcing the plugin's capabilities to the agent. |
timer_agentManage the scheduled jobs the host ticker owns (the same rows the web GUI「定时任务」panel renders).
Parameters:
action (string, required): create / list / update / pause / resume / archive / restart / remove / runjob_id (string): job id, required for all actions except create/list (get ids from list; never guess)prompt (string): for create — the full self-contained prompt the scheduled run executes; for update — replacement; for run — transient context for that single fireschedule (string): 5-field cron, e.g. 0 9 * * *; required for createname (string): short human titleworkdir (string): absolute project directory the run's session works in (empty = default workspace)session (string): pin an existing session id — every run continues that conversationReturns: { kind, job?, jobs?, error? } — summarized job row(s) or a structured error message.
pnpm install
pnpm run build # lib/index.js(host) + lib/client.js(浏览器,CSS 已内联)
pnpm run typecheck
pnpm test # 49 项行为级 E2E(fake host faces,无需 dsh 运行时)
pnpm run smoke-test # 静态结构冒烟(23 项)
E2E 覆盖:cron 解析与下次运行计算(本地时间语义)、台账原子写与损坏降级、at-most-once 调度触发、钉住会话 resume、turn/end 成功/失败结算(含失败原因入账)、运行中拒绝重复触发、禁用调度不触发、手动触发通道、workdir 传递、timer_agent 工具全动作(含非法参数拒绝)、HTTP 路由 CRUD + run + 回环/同源防线 + 非法输入 400。
| hermes-agent | 本插件 |
|---|---|
| gateway 进程内 60s ticker | dsh web 宿主进程内 60s ticker |
| 触发即新 AIAgent(platform=cron) 会话 | agents.create/resume 真实 dsh 会话 |
| ~/.hermes/cron/jobs.json 台账 | ~/.dsh/timer-agent/jobs.json(原子写) |
| at-most-once(先推进 next_run_at) | 先顺延 nextRunAt 再触发 |
| claim 去重 + 心跳 | 运行中跳过 + 5s 手动触发快通道 |
| deliver 回投/指定平台续跑 | 钉住会话 / workdir 新会话 / 默认空间 |
| cron_hint → notepad → script 组装 prompt | 自包含 prompt(无人在场,不可提问) |
| turn/end reason.kind=error 结算 | 同款 session/event 结算 |
兼容范围(声明于 package.json):
0.2.0-rc.2(dsh.compatibility.dshReleases 精确声明 compatible;其他版本未验证,视为 unknown)>=22(engines.node;仓库内测试依赖 Node 22+ 的 type-stripping 能力)依赖:
@deepseek-ai/schemastery(配置 schema 校验,与宿主同源的分叉包),随包安装,无 install/postinstall/prepare 生命周期脚本@deepseek-ai/* 与 react 均为 peerDependencies,由 dsh 宿主提供,插件不禁用、不替换、不重复安装任何官方组件lib/ 直接随源码入库权限披露(源码静态扫描可见的四类信号,均为插件功能所需):
~/.dsh/timer-agent/jobs.json 的原子读写(store);不触碰 dsh 核心目录与其他 Profile 文件command 型任务通过 spawn 执行任务作者填写的命令(cwd 可指定 workdir,继承宿主 process.env);prompt 型任务通过 dsh session API 执行,不直接起 shell/api/dsh-timer-agent/* 路由 + 宿主经 dsh client 调用本地 dsh 服务;不连任何外部服务process.env(dsh 凭据经环境变量传递给 CLI);插件自身不读取、不记录、不持久化任何凭据或密钥失败边界:服务进程停止即不触发(错过即跳过);台账损坏时降级为空表并备份原文件;运行中到点跳过本次;手动触发与 ticker 触发经同一 at-most-once 通道,不会重复执行。
源码版本锚:v0.8.0 发布于 tag v0.8.0。
dsh web 服务进程存活(服务停了自然不触发;重启后只跑已顺延到期的任务,错过即跳过)