From 568e8091c176822ec4f1f8ba8357e40e9e30a62c Mon Sep 17 00:00:00 2001 From: kris Date: Sun, 29 Mar 2026 22:51:02 +0800 Subject: [PATCH] feat: highlight problem main agent runs --- web/storyforge-web-v4/assets/app.js | 9 ++++++++- web/storyforge-web-v4/tests/workbench-pages.test.mjs | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index 83fb17d..5fdc7b2 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -985,10 +985,12 @@ function renderOneLinerRunsHtml() { const pendingRunCount = safeArray(runs).filter((item) => item.run_status === "needs_confirmation").length; const activeRunCount = safeArray(runs).filter((item) => ["queued", "running", "blocked"].includes(item.run_status)).length; const completedRunCount = safeArray(runs).filter((item) => item.run_status === "done").length; - const filterKey = String(appState.onelinerRunFilter || "").trim() || (activeRunCount || pendingRunCount ? "focus" : "done"); + const problemRunCount = safeArray(runs).filter((item) => ["blocked", "failed", "cancelled"].includes(item.run_status)).length; + const filterKey = String(appState.onelinerRunFilter || "").trim() || (activeRunCount || pendingRunCount ? "focus" : completedRunCount ? "done" : "problems"); const runFilterPredicates = { focus: (item) => ["needs_confirmation", "queued", "running", "blocked"].includes(item.run_status), done: (item) => item.run_status === "done", + problems: (item) => ["blocked", "failed", "cancelled"].includes(item.run_status), all: () => true }; const filteredRuns = safeArray(runs).filter(runFilterPredicates[filterKey] || runFilterPredicates.focus); @@ -1035,10 +1037,12 @@ function renderOneLinerRunsHtml() { 待确认 ${escapeHtml(formatNumber(pendingRunCount))} 执行中 ${escapeHtml(formatNumber(activeRunCount))} 已完成 ${escapeHtml(formatNumber(completedRunCount))} + 异常 ${escapeHtml(formatNumber(problemRunCount))}
重点运行 已完成 + 异常运行 全部
${runs.length > 1 ? ` @@ -1057,6 +1061,9 @@ function renderOneLinerRunsHtml() { `).join("")} + ${!filteredRuns.length ? ` +
当前筛选下还没有对应运行,已临时显示全部任务。
+ ` : ""} ` : ""}
diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index abcc707..9e12604 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -311,12 +311,15 @@ test("oneliner runtime shows grouped run health summary above the current run ca assert.match(runtime, /待确认/); assert.match(runtime, /执行中/); assert.match(runtime, /已完成/); + assert.match(runtime, /异常/); assert.match(runtime, /最近完成/); assert.match(runtime, /recentCompletedRuns/); assert.match(runtime, /select-oneliner-run-filter/); assert.match(runtime, /重点运行/); assert.match(runtime, /已完成/); + assert.match(runtime, /异常运行/); assert.match(runtime, /全部/); + assert.match(runtime, /problemRunCount/); assert.match(runtime, /safeArray\(runs\)\.filter\(\(item\) => item\.run_status === "needs_confirmation"\)\.length/); });