Skip to content

Commit 15528c0

Browse files
committed
feat: humanize diagnostics and verify gateway runtime
1 parent 271ae12 commit 15528c0

15 files changed

Lines changed: 607 additions & 60 deletions

AGENTS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ bun run dev -- db check # 检查数据库完整性与业务统计
5555
-`0005` 起 migration 必须遵循 expand/contract 并保持 N-1 二进制兼容:只允许新增表、非唯一索引,以及可空或带默认值的新增列。删除、重命名、收紧约束和数据改写必须延后到旧版本不再是自动回滚目标后执行;测试会拒绝破坏该约束的 SQL。
5656
- Gateway 用 SQLite `BEGIN IMMEDIATE` + `gateway_lock` 保证单实例;进程身份必须同时识别直接 Gateway 入口与公开的 `supertask gateway`/CLI 入口。Dashboard 默认只监听 `127.0.0.1:4680`
5757
- Gateway 必须先完成恢复收敛、Scheduler 初始化和 Dashboard 绑定,最后才启动 Worker,并把包版本与 `gateway_lock.ready_at` 一起写入;PM2 `online` 不能单独作为就绪依据,进程 PID、版本和运行作用域必须匹配新鲜 ready 锁。
58-
- PM2 替换已有 Gateway 前必须先用保存的运行环境验证管理命令可执行;若新旧进程无法共用同一可回滚的 PM2 管理路径,必须在删除旧进程前失败关闭。
58+
- PM2 替换已有 Gateway 前必须先用保存的运行环境验证管理命令可执行,并用目标 Gateway 环境真实执行 `opencode --version`;若 OpenCode 不可执行,或新旧进程无法共用同一可回滚的 PM2 管理路径,必须在删除旧进程前失败关闭。
5959
- PM2 替换、数据库维护、卸载与 macOS supervisor 检查必须先共用 `PM2_HOME/supertask-gateway.manage.sqlite` canonical SQLite 事务锁;兼容旧 custom lock 时还必须从 PM2 dump/运行环境和 LaunchAgent 恢复全部旧路径,并按固定顺序同时持有,不能因后续 CLI 缺少旧环境变量而绕过旧 supervisor。已安装 LaunchAgent 的 `PM2_HOME` 与当前 CLI 不同必须在任何修改前失败关闭,避免两个 PM2 daemon 争用同一 Gateway。不得恢复 PID/stale 文件锁。PM2 kill timeout 不得低于 Worker shutdown grace 加 15 秒,`stop/delete` 命令 timeout 不得低于实际 kill timeout 加 5 秒,管理锁必须持有到命令返回;显式低值必须在删除旧进程前失败关闭。
6060
- macOS supervisor 只有在 `jlist` 成功且确认 Gateway 缺失、同时 `dump.pm2` 明确包含 Gateway 时才可 `resurrect`;状态未知、`errored``stopped` 和卸载后的空 dump 都不得触发重启。卸载必须停止并移除项目 LaunchAgent。
61-
- `/health` 必须分别反映 Worker、Scheduler、Watchdog 和历史清理的活跃度与连续失败;`supertask doctor` 还要解析 OpenCode 最终配置,要求唯一的精确插件版本,核对对应缓存、全局 CLI、PM2 实际 Gateway 入口包和 ready 锁版本,并验证 macOS LaunchAgent 与 PM2 dump 可恢复性。浮动 `@latest`/`@next` 入口或任一组件版本不一致必须失败。升级成功替换插件和 Gateway 后必须检测全局 CLI 的 npm/Bun 安装来源并同步精确版本;无法确认时返回明确的部分失败和人工命令。PM2 自动替换/恢复必须保留既有 Bun 路径、完整运行环境和数据库作用域。用户显式执行 `install` / `upgrade` 时,目标 Gateway 可从当前终端刷新 OpenCode、XDG 与 Provider 执行环境,但必须固定旧 `HOME``PATH``PM2_HOME`、全部 `SUPERTASK_*`、Bun 路径、cwd 和数据库/配置作用域;失败回滚必须使用未修改的完整旧环境。
61+
- `/health` 必须分别反映 Worker、Scheduler、Watchdog 和历史清理的活跃度与连续失败;`supertask doctor` 要分别验证当前终端和 PM2 保存的 Gateway 环境中的 OpenCode,再解析最终配置,要求唯一的精确插件版本,核对对应缓存、全局 CLI、PM2 实际 Gateway 入口包和 ready 锁版本,并验证 macOS LaunchAgent 与 PM2 dump 可恢复性。`doctor --smoke` 必须经真实数据库队列和 Gateway 执行 OpenCode、验证输出标记,普通 `doctor` 不得调用模型。浮动 `@latest`/`@next` 入口或任一组件版本不一致必须失败。升级成功替换插件和 Gateway 后必须检测全局 CLI 的 npm/Bun 安装来源并同步精确版本;无法确认时返回明确的部分失败和人工命令。PM2 自动替换/恢复必须保留既有 Bun 路径、完整运行环境和数据库作用域。用户显式执行 `install` / `upgrade` 时,目标 Gateway 可从当前终端刷新 OpenCode、XDG 与 Provider 执行环境,但必须固定旧 `HOME`、`PATH`、`PM2_HOME`、全部 `SUPERTASK_*`、Bun 路径、cwd 和数据库/配置作用域;失败回滚必须使用未修改的完整旧环境。
6262
- 数据库检查、备份、清空和恢复统一经过 `DatabaseMaintenanceService`;CLI 清空/恢复必须显式确认并拒绝运行中任务,且只可自动停启 PID 与当前数据库新鲜 ready 锁一致的 PM2 Gateway;前台或无法确认归属的进程必须拒绝误杀。清空/恢复前必须自动创建校验通过的安全备份;清空必须动态删除全部业务表数据(包括 N+1 expand-only 表),通过延迟外键检查支持循环依赖,并保留 `gateway_lock` 与 migration 元数据。恢复来源必须从已打开的 SQLite 连接生成包含已提交 WAL 页的一致快照,并拒绝当前数据库的符号链接/硬链接别名。恢复必须动态校验 source/live 业务表和可写列:source-only 未知表/列在删除前失败关闭,共有未来列完整复制,live-only 列只允许可空/默认值且 live-only 新表必须清空,避免 N/N-1 形成混合时间点;随后在当前连接的排他事务内原位替换,不得关闭连接后 rename 换库。默认在操作失败时也恢复原 Gateway 状态,`--keep-stopped` 除外。
6363
- Dashboard 清空只能豁免当前 Gateway PID,仍必须服务端确认、拒绝运行中任务并在同一事务内先备份后动态删除全部业务表;不得恢复为路由内直接 `DELETE` 的实现。
6464
- Dashboard 的浏览器写请求必须通过同源检查,数据库字符串进入 HTML 前必须调用 `esc`;API 的 ID、状态和配置不得直接断言类型。
@@ -88,6 +88,7 @@ bun run dev -- db check # 检查数据库完整性与业务统计
8888
- Dashboard 项目目录必须可从本机文件夹浏览器选择;选定后必须以该 `cwd` 执行配置的 OpenCode `agent list``models`。新任务只显示 primary/all Agent,不得把 subagent 或旧 `supertask-runner` 作为可直接运行选项;编辑时允许保留不在当前列表中的历史值。时长控件必须先提供常用预设,数字+单位只作为自定义退路。
8989
- 普通任务编辑必须经 `TaskService` 同时服务 Dashboard 与 CLI,只允许 `pending/failed/dead_letter`,且不得修改 `cwd/dependsOn`;运行中和完成/取消终态拒绝修改。降低失败任务重试预算导致现有次数超限时必须立即收敛到 `dead_letter`
9090
- Dashboard 继续会话命令必须按 run ID 从服务端读取并校验 Session ID 后生成,不得把完整 Session ID 直接写入 HTML 或未经校验拼接成终端命令。
91+
- Dashboard 的任务、定时任务和执行详情必须默认使用人类可读标签和格式;原始 JSON/JSONL 只作为折叠的二级排障入口。执行日志必须在所点击的 run 附近展开,不得统一堆到页面末尾。
9192
- Worker 必须在新 run 日志中保存真实 executable、参数数组和 `cwd` 的结构化元数据;Dashboard 只能从该元数据生成可复制命令,不得根据任务当前值猜测历史执行命令。
9293
- `cron/recurring` 达到 `maxInstances` 时必须推进下一触发点,`delayed` 保持等待;到期模板扫描必须有界。不可恢复依赖应在状态事件中递归收敛,下游链不得在每个 Worker poll 全局扫描。
9394

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
All notable user-facing changes are recorded here. This project follows semantic versioning while it is in the `0.x` development series.
44

5+
## [0.1.36] - 2026-07-18
6+
7+
### Added
8+
9+
- `supertask doctor --smoke` now queues a real Gateway-managed OpenCode task and verifies its exact response. Agent, model, project directory, and timeout are selectable; ordinary `doctor` remains free of model calls.
10+
- Task, scheduled-task, and run details now open as labeled, human-readable summaries. Raw JSON remains available in a collapsed troubleshooting section and can still be copied.
11+
12+
### Fixed
13+
14+
- PM2 install, upgrade, and stale-Gateway replacement now execute `opencode --version` using the exact target Gateway environment before stopping the old process. A broken saved `PATH`, executable, or cwd fails closed without disrupting the working Gateway.
15+
- `supertask doctor` now diagnoses terminal OpenCode and PM2/Gateway OpenCode separately, preventing a successful interactive shell check from hiding a broken daemon environment.
16+
- Execution logs now expand directly beneath the run that was clicked instead of appearing at the bottom of the page.
17+
18+
[0.1.36]: https://github.com/vbgate/opencode-supertask/compare/v0.1.35...v0.1.36
19+
520
## [0.1.35] - 2026-07-18
621

722
### Added

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ supertask uninstall # stop and remove from pm2
128128
supertask gateway # start Gateway in foreground
129129
supertask ui # open Web Dashboard in browser
130130
supertask config # show current config
131-
supertask doctor [--json] # end-to-end runtime diagnostics
131+
supertask doctor [--json] # static end-to-end runtime diagnostics
132+
supertask doctor --smoke [--smoke-agent build] [--smoke-model provider/model]
133+
# queue one real Gateway/OpenCode verification task
132134
supertask upgrade # pin latest plugin version and replace Gateway
133135

134136
# Task management
@@ -239,13 +241,13 @@ http://localhost:4680 — 4 pages:
239241

240242
The responsive Dashboard supports Chinese and English plus system, light, and dark themes. Language is stored in a same-site cookie, while theme preference stays in browser local storage; both survive refreshes without changing Gateway configuration.
241243

242-
Health endpoint: `GET http://localhost:4680/health` returns 200 only after Gateway startup completes and its internal loops remain active without an unrecovered loop failure. `supertask doctor` also checks OpenCode, SQLite, PM2 readiness, Dashboard health, log rotation, and on macOS the loaded LaunchAgent plus its recoverable PM2 dump. It requires the effective OpenCode plugin configuration to use one exact version, verifies that exact cache package, and compares it with the global CLI, actual PM2 Gateway entry, and ready-lock version; floating `@latest`/`@next` paths or any component version mismatch fail diagnostics.
244+
Health endpoint: `GET http://localhost:4680/health` returns 200 only after Gateway startup completes and its internal loops remain active without an unrecovered loop failure. `supertask doctor` checks OpenCode separately in the invoking terminal and in PM2's saved Gateway environment, then checks SQLite, PM2 readiness, Dashboard health, log rotation, and on macOS the loaded LaunchAgent plus its recoverable PM2 dump. It requires the effective OpenCode plugin configuration to use one exact version, verifies that exact cache package, and compares it with the global CLI, actual PM2 Gateway entry, and ready-lock version; floating `@latest`/`@next` paths or any component version mismatch fail diagnostics. Add `--smoke` only when a real model call is desired; it queues a normal high-priority task and verifies the exact marker returned by OpenCode.
243245

244246
| Page | Features |
245247
|------|----------|
246-
| Task Queue | Browse a project folder, load its runnable Agents/models, see running/queued/error counts, create or edit prioritized tasks, retry, cancel, guarded delete, and copy a validated `opencode --session …` command |
248+
| Task Queue | Browse a project folder, load its runnable Agents/models, see running/queued/error counts, create or edit prioritized tasks, open human-readable details, retry, cancel, guarded delete, and copy a validated `opencode --session …` command |
247249
| Scheduled Tasks | Create and edit model, Agent, prompt, project directory, schedule, retries, and timeout with common duration presets; Run now always queues a task |
248-
| Execution Logs | Structured Agent output, errors, tools, exact reproducible command, raw OpenCode JSONL, and session tracking |
250+
| Execution Logs | Structured Agent output, errors, tools, and exact reproducible command expanded directly beneath the selected run; raw OpenCode JSONL remains a secondary troubleshooting view |
249251
| System Status | Config editor with saved/active state, PM2-backed save-and-restart, concurrency monitor, and backup-first transactional database clear |
250252

251253
## Data
@@ -324,6 +326,7 @@ SUPERTASK_LANG=zh-CN supertask doctor
324326
```bash
325327
# Gateway 与诊断
326328
supertask install | uninstall | gateway | ui | doctor
329+
supertask doctor --smoke --smoke-agent build --smoke-model openai/gpt-5
327330

328331
# 普通任务
329332
supertask add | edit | list | get | status | retry | cancel | delete

docs/architecture.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ pending / running / failed ──cancel──> cancelled
137137
|---|---|---|---|
138138
| 执行模型 | Worker 直接运行目标 Agent | 少一层 LLM、状态写入者明确、PID 更可控 | 需要独立远程执行协议时 |
139139
| 进程守护 | PM2 可选,前台模式始终可用 | 守护不应成为开发和插件加载的硬依赖 | 有统一容器或 OS 服务管理平台时 |
140-
| Gateway 执行环境 | 自动恢复沿用旧环境;显式安装/升级刷新 OpenCode/XDG/Provider 环境,但固定 PM2、Bun、数据库与配置身份 | 自定义 Agent 应与发起安装/升级的可用终端一致,同时不能让环境刷新误切数据库或 PM2 daemon | 引入独立密钥/执行环境管理器时 |
140+
| Gateway 执行环境 | 自动恢复沿用旧环境;显式安装/升级刷新 OpenCode/XDG/Provider 环境,但固定 PM2、Bun、数据库与配置身份;替换前用目标环境预检 OpenCode | 自定义 Agent 应与发起安装/升级的可用终端一致,同时不能让环境刷新误切数据库或 PM2 daemon;坏环境不会先停掉健康 Gateway | 引入独立密钥/执行环境管理器时 |
141141
| PM2 生命周期互斥 | 先持有 `PM2_HOME` 下的 canonical SQLite `BEGIN IMMEDIATE` 锁,再按固定顺序持有从当前环境、dump/运行环境和 LaunchAgent 恢复的旧 custom 锁;LaunchAgent 与当前 CLI 的 `PM2_HOME` 不同则在修改前失败关闭;`stop/delete` 持锁等待至少 kill timeout + 5 秒 | 崩溃自动释放,避免绕过旧 supervisor、启动第二个 PM2 daemon、PID 复用、stale-unlink ABA 或 PM2 尚未结束时提前进入下一临界区 | 迁移到单一外部服务管理器时 |
142142
| 持久化 | SQLite WAL | 零服务依赖,适合单机队列 | 多机消费、高写入并发或 HA 时 |
143143
| migration 回滚 | N/N-1 expand/contract 兼容 | PM2 可在新版未 ready 时安全恢复旧二进制 | 引入数据库版本化快照回滚协议时 |
144144
| 配置错误 | 校验失败并拒绝启动 | 避免错误配置被默认值掩盖 | 不改变;可增加更友好的诊断 |
145145
| 调度补偿 | 不回放全部错过周期 | 避免恢复时瞬间制造积压 | 业务明确要求补账并定义上限时 |
146146
| 数据库维护 | Service 统一数据安全;CLI 编排匹配当前 ready 锁的 PM2 Gateway 自动停启 | 避免各入口实现不完整的危险 SQL,并防止维护命令误停另一套实例 | 存储迁移到外部数据库时重做维护协议 |
147-
| Dashboard | 嵌入 Gateway,仅监听 loopback | 少一个常驻进程,默认不暴露网络面 | 需要公网/团队访问时拆分并加鉴权 |
147+
| Dashboard | 嵌入 Gateway,仅监听 loopback;详情默认语义化,原始 JSON/JSONL 退到折叠排障入口 | 少一个常驻进程,默认不暴露网络面,同时不把数据库结构直接当作人类界面 | 需要公网/团队访问时拆分并加鉴权 |
148148

149149
## 安全边界
150150

@@ -156,7 +156,7 @@ Dashboard 只绑定 `127.0.0.1`,浏览器写请求检查 `Sec-Fetch-Site` 和
156156

157157
以下是当前源码行为,不应由文档掩盖:
158158

159-
- `/health` 检查 ready 锁、Worker/Scheduler/Watchdog/历史清理活跃时间和连续失败,并保留最近错误;`supertask doctor` 还解析 OpenCode 最终插件配置,要求精确版本并核对对应缓存、全局 CLI、PM2 实际 Gateway 入口包和 ready 锁版本,同时验证 macOS LaunchAgent 的程序路径、加载状态和 PM2 dump 可恢复性。浮动 `@latest`/`@next` 入口或任一组件版本不一致都失败关闭。macOS supervisor 只恢复 dump 中明确存在但 `jlist` 确认缺失的 Gateway,不会把状态未知或 `errored` 当作恢复信号。显式 `supertask install` 会配置 `pm2-logrotate`,但仍没有指标导出和告警集成。
159+
- `/health` 检查 ready 锁、Worker/Scheduler/Watchdog/历史清理活跃时间和连续失败,并保留最近错误;`supertask doctor` 分别验证终端与 PM2 保存环境中的 OpenCode,再解析最终插件配置,要求精确版本并核对对应缓存、全局 CLI、PM2 实际 Gateway 入口包和 ready 锁版本,同时验证 macOS LaunchAgent 的程序路径、加载状态和 PM2 dump 可恢复性`doctor --smoke` 进一步提交真实队列任务验证完整执行链。浮动 `@latest`/`@next` 入口或任一组件版本不一致都失败关闭。macOS supervisor 只恢复 dump 中明确存在但 `jlist` 确认缺失的 Gateway,不会把状态未知或 `errored` 当作恢复信号。显式 `supertask install` 会配置 `pm2-logrotate`,但仍没有指标导出和告警集成。
160160
- 单实例锁、任务抢占和状态更新足以覆盖当前单机模型,但不提供分布式租约和 exactly-once 保证。
161161

162162
这些限制一旦成为真实故障来源,应先写复现测试,再调整实现与本文档。

0 commit comments

Comments
 (0)