Skip to content

Workflows tab (replace Later): v0.1 UI 壳 for ~/.openclaw/cron/jobs.json #115

Description

@SymbolStar

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 壳)

  1. icon rail:web/index.html 里第 68 行的 data-view="later" 按钮,把 icon 从 🔖 换成 ⏰,label 从 Later 换成 Workflows,去掉 is-dim,加 data-enabled="1"顺序、其他 tab 全不动
  2. 新增 view shell #workflows-view,加对应 CSS。
  3. 新增数据层:读 ~/.openclaw/cron/jobs.json + ~/.openclaw/cron/runs/* 的一层 normalize(见下)。
  4. 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 段:

  1. 左栏 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
  2. 主区顶部 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 高亮)
  3. 主表格 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 映射成 failedskipped 归入 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 各一张。

  • icon rail 除 Later 位外其他 tab 图标、顺序、间距、.is-dim 状态与 v0.2-final 前保持完全一致
  • Workflows 位显示 ⏰ + Workflows label,选中态样式与其他 tab 一致
  • Health strip 单位全部 X runs,小标题 Run activity · today 存在
  • 表格 6 列,无第 7 列
  • Schedule 单元格 hover 出 cron raw tooltip
  • Failed 行有左侧 3px 红 accent bar,无红底
  • Running / ok / disabled 行任何 accent bar
  • Disabled 行 opacity: .6
  • Run Now 按钮点击后行状态在 12s 内更新为 running / 完成状态
  • Dark mode:所有色都走 semantic token,grep web/style.css (workflows 相关段) 应该 0 个 hex 字面值
  • 26 个真实 job 全部能渲染出来,schedule 人话覆盖 17 条 cron(未覆盖的 fallback 显示 raw 不崩)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions