From 681d0b997380dcee68f23dcaf378ea58ac81104f Mon Sep 17 00:00:00 2001 From: xiaoan17 Date: Fri, 30 Oct 2026 13:32:25 +0800 Subject: [PATCH 01/21] feat(dashboard): denser workspace with stage bar and run band MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - one-line Goal rows with short labels; full title moves to tooltip/drawer - collapse the six-cell vitals strip into a Plan → Run → Accept stage bar - wire status run history into a home run band (28 most recent runs) - single-row task toolbar with one filter control; inline empty lanes - desktop notifications become a sidebar bell instead of a settings block - quiet the capability nav, inline scope hints, drop stray help icons - dedupe the Delivery & evidence title; clamp drawer goal titles Signed-off-by: xiaoan17 --- .../dashboard/smoke/home-route-smoke.ts | 4 + .../personal-workspace/channel-header.tsx | 4 +- .../personal-workspace/context-drawer.tsx | 13 ++- .../personal-workspace/delivery-review.tsx | 6 +- .../personal-workspace/goal-display.ts | 16 +++ .../personal-workspace/goal-loopx-mode.css | 5 + .../personal-workspace/goal-masthead.css | 24 +++- .../personal-workspace/goal-masthead.tsx | 75 +++++------- .../personal-workspace/goal-overview.tsx | 15 +-- .../personal-workspace/goal-research-mode.css | 7 ++ .../personal-workspace/goal-sidebar.tsx | 22 +++- .../personal-workspace/goal-tasks-view.tsx | 27 +++-- .../goal-workspace-work.tsx | 2 +- .../personal-workspace/manager-brief.tsx | 60 +++++++--- .../personal-workspace-model.ts | 11 ++ .../personal-workspace-page.tsx | 51 ++++---- .../personal-workspace/personal-workspace.css | 109 ++++++++++++++---- .../workspace-settings-page.tsx | 20 +--- apps/presentation/dashboard/src/router.tsx | 27 ++++- .../dashboard/src/views/dashboard-page.tsx | 22 +++- examples/dashboard-home-browser-smoke.mjs | 37 ++++++ 21 files changed, 387 insertions(+), 170 deletions(-) create mode 100644 apps/presentation/dashboard/src/features/personal-workspace/goal-display.ts diff --git a/apps/presentation/dashboard/smoke/home-route-smoke.ts b/apps/presentation/dashboard/smoke/home-route-smoke.ts index 72bdc21d3d..21f48302ef 100644 --- a/apps/presentation/dashboard/smoke/home-route-smoke.ts +++ b/apps/presentation/dashboard/smoke/home-route-smoke.ts @@ -32,6 +32,10 @@ const designSource = readFileSync("design.md", "utf8"); excludes(routerSource, 'view: z.enum(["ops", "share"])', "legacy dual-view routing removed"); excludes(routerSource, 'chatRoute', "legacy standalone chat route removed"); +includes(routerSource, 'path: "/design/local-dashboard"', "temporary local dashboard design route"); +includes(routerSource, "", "shared dashboard route adapter"); +excludes(dashboardSource, "dashboardRoute.useSearch()", "dashboard search is provided by its route adapter"); +excludes(dashboardSource, "dashboardRoute.useNavigate()", "dashboard navigation is provided by its route adapter"); includes(dashboardSource, 'data-testid="personal-goal-home"', "personal workspace route"); includes(dashboardSource, "{t(selectedGoal.loadState === "error" ? "startup.goalError" : "startup.goalLoading")}

: null} {selectedGoal ? ( + <>
- {researchControl} {runtimeControl}
+ {researchControl ?
{researchControl}
: null} + ) : !scopeUnavailable ? ( -

{goal.title}

{onOpenDetails ? : null}
+

{goalShortLabel(goal)}

{onOpenDetails ? : null}
{context.length ?

{context.join(" · ")}

: null} ); @@ -196,55 +197,31 @@ export function GoalVitals({ goal, items, onFocusRegion, userTodos, digest: shar const lastTime = last ? relativeTime(last.at, locale) : null; const stateLabel = finishing ? t("vitals.stopping") : t(activity.labelKey as WorkspaceMessageKey); + const stages = locale === "zh-CN" ? ["计划", "执行", "验收"] : ["Plan", "Run", "Accept"]; + const stageIndex = goal.state === "已完成" ? 3 + : (work.classes.running_observed > 0 || work.open > 0 || goal.execution?.kind === "running") ? 1 + : goal.acceptanceObservation ? 2 : 0; + const waitingOn = needs.availability === "ok" && needs.blocking + ? (locale === "zh-CN" ? "等你决定" : "Waiting on you") + : work.classes.running_observed ? (locale === "zh-CN" ? "Agent 执行中" : "Agent running") : null; + return ( -
- onFocusRegion("overview")} sub={finishing ? t("vitals.turnFinishing") : activity.alsoKey ? t(activity.alsoKey as WorkspaceMessageKey, {host: goalHostSurfaces(goal).map(hostSurfaceLabel).join(" / ")}) : undefined} - help={stateSub ?

{stateSub}

: undefined} - tone={finishing ? "stopped" : activity.tone} valueKey={`${goal.goalId}:${stateLabel}`}> - - {stateLabel} -
- onFocusRegion("tasks")} valueKey={`${goal.goalId}:${work.done}:${work.total}:${work.open}`} - sub={workSub} - help={work.done === null || work.coverage !== "complete" ? -

{t("vitals.scope")}

{work.coverage !== "complete" ?

{t("vitals.workCoverageUnknown")}

: null} - {work.done === null ?

{t("vitals.workDoneUnknown")}

: null} -

{work.projectedOpen !== null ? t("vitals.workPartial", {listed: work.listedOpen, projected: work.projectedOpen}) : `${work.listedOpen} ${locale === "zh-CN" ? "项已列出" : "listed"}`}

-
: undefined} - extra={<> - {work.total !== null && ribbonTotal > 0 ? {ribbonOrder.map((name) => work.classes[name] - ? : null)} : null} - }> - {work.total === null ? work.open : {work.done}/{work.total}} -
- onFocusRegion("attention")} valueKey={`${goal.goalId}:${needs.availability}:${needs.availability === "ok" ? needs.blocking : ""}`} - tone={needs.availability === "ok" && needs.blocking !== null && needs.blocking > 0 ? "danger" : needs.availability === "ok" ? "recede" : undefined} - help={needs.availability !== "ok" || needs.coverage !== "complete" ?

{needs.availability === "ok" ? t("vitals.needsYouPartial", {count: needs.listed}) : t("vitals.unavailable")}

: undefined} - sub={needs.availability !== "ok" ? null : [ - needs.oldestWaitingSince ? t("vitals.needsYouOldest", { time: relativeTime(needs.oldestWaitingSince, locale) ?? "" }) : null, - needs.optional ? t("vitals.needsYouOptional", { count: needs.optional }) : null, - ].filter(Boolean).join(" · ")}> - {needs.availability !== "ok" ? t("vitals.unavailable") : needs.blocking === null ? "—" : needsEmpty ? t("vitals.needsYouNone") - : <>{needs.blocking > 0 ? : null}{needs.blocking}} -
- onFocusRegion("usage")} sub={digest.usage.agentTimeMs === null ? undefined : windowLabel} - help={digest.usage.agentTimeMs === null ?

{t("vitals.notMeasured")}

: undefined} - empty={digest.usage.agentTimeMs === null} - valueKey={`${goal.goalId}:${digest.usage.window}:${digest.usage.agentTimeMs}`}> - {digest.usage.agentTimeMs === null ? t("vitals.notMeasured") : formatDurationMs(digest.usage.agentTimeMs)} -
- onFocusRegion("usage")} sub={digest.usage.costUsd === null ? undefined : windowLabel} - help={digest.usage.costUsd === null ?

{t("vitals.notMeasured")}

: undefined} - empty={digest.usage.costUsd === null} - valueKey={`${goal.goalId}:${digest.usage.window}:${digest.usage.costUsd}`}> - {digest.usage.costUsd === null ? t("vitals.notMeasured") : formatCostUsd(digest.usage.costUsd)} -
- onFocusRegion("overview")} - sub={last ? last.actor || t("vitals.turn") : undefined} - help={!last ?

{t("vitals.noActivity")}

: undefined} empty={!last} - tone={last ? undefined : "recede"}> - {last && lastTime ? lastTime : t("vitals.noActivity")} -
+
+
    + {stages.map((label, index) => ( +
  1. + +
  2. + ))} +
+
+