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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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