Workflows tab (replace Later)
替换现有 icon rail 里的 🔖 Later → ⏰ Workflows,用于可视化管理 ~/.openclaw/cron/jobs.json 里现有的 26 个定时任务。v0.1 = UI 壳,不改 cron runtime,不改 jobs.json 存储结构。
Design owner: @designer (dora) · Review: @judy · Scope: FE only.
Design 交付
- Mock (final): workflows-v0.2-final.html(本 issue 提交前 designer 会 PR 进
docs/design/workflows/)
- 1440 主档截图:见附件 v0.2-final-1440.png
- 本地绝对路径(现场备份):
/Users/symbolstar/.openclaw/workspace-designer/products/openforge-workflows/mock-v0.2-final.html
/Users/symbolstar/.openclaw/workspace-designer/products/openforge-workflows/v0.2-final-1440.png
范围(v0.1 = UI 壳)
改:
- icon rail:
web/index.html 里第 68 行的 data-view="later" 按钮,把 icon 从 🔖 换成 ⏰,label 从 Later 换成 Workflows,去掉 is-dim,加 data-enabled="1"。顺序、其他 tab 全不动。
- 新增 view shell
#workflows-view,加对应 CSS。
- 新增数据层:读
~/.openclaw/cron/jobs.json + ~/.openclaw/cron/runs/* 的一层 normalize(见下)。
- Run Now 按钮 → 调用现有
cron 工具的 run action(走 OpenClaw MCP,不是 REST)。
不改:
~/.openclaw/cron/jobs.json schema / 存储位置
- cron runtime(多 step DAG 是 v0.2 的事,v0.1 一个 job = 一行)
- Later 相关代码可留可删,本次只是把入口换成 Workflows;如果后面有人要 Later 再另开 tab
Layout 规格
docs/design/workflows/mock-v0.2-final.html 是权威参考,dev 直接照抄 CSS token(复用 web/style.css 里已有的 --surface-* / --ok / --danger / --warn / --brand-blue* 语义 token,禁止在 workflows view 里新增 hex literal)。
主结构 3 段:
-
左栏 workflow list(沿用 channel-list 组件类):
- Header:
Workflows · 26 · 22 on
- Section 1:
Failing today · N — 出问题的置顶
- Section 2:
Running now · M
- Section 3:
All workflows · X
- 每行 = 状态圆点 (ok/warn/err/off 4 色) + job name + agent badge
-
主区顶部 health strip(在 filter bar 上方):
- 小标题
Run activity · today
- 4 张卡片,单位全部用
X runs(不要 job/runs 混用):
- Succeeded ·
N runs · sub: avg Xs · p95 Xm Ys
- Failed ·
N runs · sub: 列前 2 个失败 job name+时间
- Running ·
N run(s) · sub: 显示当前 running job + elapsed
- Upcoming · next 6h ·
N runs · sub: 下一次时间+job name
- 卡片可点 → filter 表格 + 高亮左栏对应 section(点 Failed 卡→ 表格 filter=failed,左栏 Failing section 高亮)
-
主表格 6 列(Toggle / Name / Schedule / Last run / Next / Actions):
- Toggle 列无表头(图形语义足够)
- Name 列:主行 = job name(
--text 常规粗);副行 = agent badge + sessionTarget · delivery 描述
- Schedule 列:主行人话(
每天 08:00),第二行 tz(Asia/Shanghai);hover 时在下方浮出原 cron 表达式 tooltip(0 8 * * *)
- Last run 列:pill (状态+recency,
× failed · 8h ago / ✓ ok · 15m ago / ● running · started HH:MM) + 第二行 duration 或 result detail (exit 1 · duration 42s / elapsed 4m 12s / 2 commits pushed · duration 28s)
- Next 列:人话 (
明天 08:00) + relative (in 15h)
- Actions 列:
▶ Run now / 📋 Logs / ✎ Edit;running 态时首位换 ⏹ Cancel;一次性过期任务多一个 🗑 Delete
视觉规则(关键)
- 失败行 accent bar:左侧 3px
var(--danger),通过 box-shadow: inset 3px 0 0 var(--danger) 加在第一格。只有 failed 行加,running / ok / disabled 都不加——bar 是"需要处理"的专用信号,语义纯粹。
- 失败行不加红底(26 行里 2 行红底会拉整个表变"事故现场")。
- Disabled 行
opacity: .6,沉底。
- Portal / dark mode 纪律:workflows view 里所有颜色必须走 semantic token;不能出现 hex 字面值,不能
var(--host-*, fallback) 依赖继承(参考 MEMORY.md 里 xiaof / icon-rail / activity-chip 三次同类踩坑)。
数据 normalize 规格
jobs.json 字段现状(26 条 job 摸底结果):
schedule.kind: 只见过 cron (17) 和 at (9);every UI 预留但 no-op 即可。
sessionTarget: 三态 —— isolated (18) / current (1) / session:<长串> (7)。
delivery.mode: announce (20) / none (6)。
agentId: 8 个不同 agent(sentry / main / sherry / miki / kb / milk / xiaoba / bugfix)。
Normalize 层(TypeScript 建议签名):
type NormalizedJob = {
id: string;
name: string;
agent: string;
enabled: boolean;
schedule: {
kind: 'cron' | 'at' | 'every';
human: string; // "每天 08:00" | "工作日 09:00" | "一次性 · 已过期"
tz: string; // "Asia/Shanghai"
raw: string; // "0 8 * * *",hover tooltip 用
nextRunAt: number | null; // ms since epoch, null if past one-shot
nextRunHuman: string; // "明天 08:00 · in 15h 15m"
};
target: {
kind: 'isolated' | 'current' | 'session';
label: string; // "isolated" | "current" | "session:agent:miki:main"
labelShort: string; // "session:…miki:main"(表格里 truncate 用)
};
delivery: { mode: 'announce' | 'none'; to?: string };
lastRun?: {
status: 'ok' | 'failed' | 'running';
startedAt: number;
endedAt?: number;
durationMs?: number;
exitCode?: number;
resultDetail?: string; // "2 commits pushed" / "timeout" / "exit 1"
};
};
cron → 人话 规则(覆盖现有 17 条):
0 H * * * → 每天 HH:00
M H * * * → 每天 HH:MM
M H * * 1-5 → 工作日 HH:MM
M H * * 6,0 → 周末 HH:MM
- 其他 → fallback 显示 raw(不要抛错)
- 用
cron-parser 库算 next fire,配合 job.schedule.tz 转本地时间
at → 人话 规则:
- 未来 →
一次性 · YYYY-MM-DD HH:MM
- 已过 →
一次性 · 已过期,行整体 opacity: .6,Actions 里补 ↻ Re-enable 和 🗑 Delete
sessionTarget 展示:
isolated → 直接显示 "isolated"
current → 显示 "current"
session:<长串> → 列表页截断成 session:…<最后一段>,详情页展全
Run Now 走 cron run
按 judy 判断,零成本:
// UI 层:调 OpenClaw MCP tool
await openclaw.call('cron', { action: 'run', jobId, runMode: 'force' });
一次性调用,不要 poll。cron 工具返回后刷新一下该行的 lastRun 数据。
注意:cron 工具 runs action 拿到的 run 历史条目,status 字段有 ok / error / running / skipped;normalize 层把 error 映射成 failed,skipped 归入 disabled 显示。
Refresh 策略
- 页面开着时每 30s poll 一次
cron list + 每个 job 的 cron runs (top 1)
- 点 Refresh 按钮立即拉一次
- Run Now 触发后 3s / 6s / 12s 各 poll 一次拿到最新状态(避免用户点了没反馈)
验收 checklist
真机截图必测视口 1024 / 1280 / 1440(MEMORY.md 记录的三档基准);每档 dark + light 各一张。
v0.2 backlog(不在本 issue)
- 多 step DAG(要动 cron runtime + jobs.json schema)
- Runs tab 里的时间轴 + 分步耗时(xresearch 拆成 4 step)
- Step 编辑器(agentTurn / shell / http / wait)
- Workflow 之间的依赖 / trigger chain
- 失败重跑策略、审计日志
cc @judy (可读性 review 通过) · design owner @designer
Workflows tab (replace Later)
替换现有 icon rail 里的 🔖 Later → ⏰ Workflows,用于可视化管理
~/.openclaw/cron/jobs.json里现有的 26 个定时任务。v0.1 = UI 壳,不改 cron runtime,不改 jobs.json 存储结构。Design owner: @designer (dora) · Review: @judy · Scope: FE only.
Design 交付
docs/design/workflows/)/Users/symbolstar/.openclaw/workspace-designer/products/openforge-workflows/mock-v0.2-final.html/Users/symbolstar/.openclaw/workspace-designer/products/openforge-workflows/v0.2-final-1440.png范围(v0.1 = UI 壳)
改:
web/index.html里第 68 行的data-view="later"按钮,把 icon 从 🔖 换成 ⏰,label 从Later换成Workflows,去掉is-dim,加data-enabled="1"。顺序、其他 tab 全不动。#workflows-view,加对应 CSS。~/.openclaw/cron/jobs.json+~/.openclaw/cron/runs/*的一层 normalize(见下)。cron工具的runaction(走 OpenClaw MCP,不是 REST)。不改:
~/.openclaw/cron/jobs.jsonschema / 存储位置Layout 规格
docs/design/workflows/mock-v0.2-final.html是权威参考,dev 直接照抄 CSS token(复用web/style.css里已有的--surface-*/--ok/--danger/--warn/--brand-blue*语义 token,禁止在 workflows view 里新增 hex literal)。主结构 3 段:
左栏 workflow list(沿用 channel-list 组件类):
Workflows · 26 · 22 onFailing today · N— 出问题的置顶Running now · MAll workflows · X主区顶部 health strip(在 filter bar 上方):
Run activity · todayX runs(不要 job/runs 混用):N runs· sub:avg Xs · p95 Xm YsN runs· sub: 列前 2 个失败 job name+时间N run(s)· sub: 显示当前 running job + elapsedN runs· sub: 下一次时间+job name主表格 6 列(Toggle / Name / Schedule / Last run / Next / Actions):
--text常规粗);副行 = agent badge +sessionTarget · delivery描述每天 08:00),第二行 tz(Asia/Shanghai);hover 时在下方浮出原 cron 表达式 tooltip(0 8 * * *)× failed · 8h ago/✓ ok · 15m ago/● running · started HH:MM) + 第二行 duration 或 result detail (exit 1 · duration 42s/elapsed 4m 12s/2 commits pushed · duration 28s)明天 08:00) + relative (in 15h)▶ Run now/📋 Logs/✎ Edit;running 态时首位换⏹ Cancel;一次性过期任务多一个🗑 Delete视觉规则(关键)
var(--danger),通过box-shadow: inset 3px 0 0 var(--danger)加在第一格。只有 failed 行加,running / ok / disabled 都不加——bar 是"需要处理"的专用信号,语义纯粹。opacity: .6,沉底。var(--host-*, fallback)依赖继承(参考 MEMORY.md 里 xiaof / icon-rail / activity-chip 三次同类踩坑)。数据 normalize 规格
jobs.json字段现状(26 条 job 摸底结果):schedule.kind: 只见过cron(17) 和at(9);everyUI 预留但 no-op 即可。sessionTarget: 三态 ——isolated(18) /current(1) /session:<长串>(7)。delivery.mode:announce(20) /none(6)。agentId: 8 个不同 agent(sentry / main / sherry / miki / kb / milk / xiaoba / bugfix)。Normalize 层(TypeScript 建议签名):
cron → 人话 规则(覆盖现有 17 条):
0 H * * *→每天 HH:00M H * * *→每天 HH:MMM H * * 1-5→工作日 HH:MMM H * * 6,0→周末 HH:MMcron-parser库算 next fire,配合 job.schedule.tz 转本地时间at → 人话 规则:
一次性 · YYYY-MM-DD HH:MM一次性 · 已过期,行整体opacity: .6,Actions 里补↻ Re-enable和🗑 DeletesessionTarget 展示:
isolated→ 直接显示 "isolated"current→ 显示 "current"session:<长串>→ 列表页截断成session:…<最后一段>,详情页展全Run Now 走
cron run按 judy 判断,零成本:
一次性调用,不要 poll。cron 工具返回后刷新一下该行的 lastRun 数据。
注意:
cron工具runsaction 拿到的 run 历史条目,status字段有ok/error/running/skipped;normalize 层把error映射成failed,skipped归入 disabled 显示。Refresh 策略
cron list+ 每个 job 的cron runs(top 1)验收 checklist
真机截图必测视口 1024 / 1280 / 1440(MEMORY.md 记录的三档基准);每档 dark + light 各一张。
.is-dim状态与 v0.2-final 前保持完全一致Workflowslabel,选中态样式与其他 tab 一致X runs,小标题Run activity · today存在opacity: .6web/style.css(workflows 相关段) 应该 0 个 hex 字面值v0.2 backlog(不在本 issue)
cc @judy (可读性 review 通过) · design owner @designer