diff --git a/src/client/components/memberBoard.tsx b/src/client/components/memberBoard.tsx
index a734082..3e495e3 100644
--- a/src/client/components/memberBoard.tsx
+++ b/src/client/components/memberBoard.tsx
@@ -47,19 +47,18 @@ export function memberStyle(hue: string): CSSProperties {
return { '--lc-member-hue': hue } as CSSProperties
}
-/** The run's activity figures a surface carries: consumption, duration, then steps — with the
- * occupancy figure beside them for the task rows that show it. */
-export function runMetaOf(node: AgentNode, t: ViewKit['t'], fmt: ViewKit['fmt']): { bits: string[]; pct: number | null } {
+/** The run's activity figures a surface carries: consumption, duration, then steps. */
+export function runMetaOf(node: AgentNode, t: ViewKit['t'], fmt: ViewKit['fmt']): string[] {
const bits: string[] = []
if (node.head !== null && node.head.tokens > 0) bits.push(fmt(node.head.tokens))
if (node.durationMs !== null) bits.push(fmtDurationCompact(node.durationMs))
if (node.requests > 0) bits.push(t('agents.steps', { n: node.requests }))
- return { bits, pct: node.head !== null ? node.head.pct : null }
+ return bits
}
/** The run's activity line above a card's foot — the graph cards' own meta readout. */
function memberMeta(node: AgentNode, t: ViewKit['t'], fmt: ViewKit['fmt']): ReactElement | null {
- const { bits } = runMetaOf(node, t, fmt)
+ const bits = runMetaOf(node, t, fmt)
if (bits.length === 0) return null
return (
diff --git a/src/client/components/taskBoard.tsx b/src/client/components/taskBoard.tsx
index e0c3d62..207846b 100644
--- a/src/client/components/taskBoard.tsx
+++ b/src/client/components/taskBoard.tsx
@@ -13,7 +13,7 @@
import { memo, useEffect, useMemo, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type MouseEvent, type ReactElement } from 'react'
import { IconChecklistOutlineRegular, IconUserOutlineRegular, IconUsersOutlineRegular, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'
import type { AgentForest, AgentNode } from '../agentTree'
-import { familyHue, pressureColorOf } from '../agentTree'
+import { familyHue } from '../agentTree'
import { fmtTime } from '../format'
import { familyOthersOf, memberIdByName, type FleetTeam, type FleetTeamTask } from '../fleetTeam'
import type { FleetDetail } from '../../shared/types'
@@ -252,8 +252,6 @@ export function TaskBoard(props: TaskBoardProps): ReactElement {
return out
}, [team, agentNodes, ownerVisible, needle, status, props.ownerFilter])
- const doneCount = rows.filter(row => row.status === 'completed').length
- const activeCount = rows.filter(row => row.status === 'in_progress').length
const visibleCount = groups.reduce((n, group) => n + group.rows.length, 0)
const toggleOpen = (id: string): void => {
@@ -355,7 +353,7 @@ export function TaskBoard(props: TaskBoardProps): ReactElement {
const renderAgentRow = (row: WorkRow, hue: string): ReactElement => {
const node = row.node as AgentNode
- const { bits, pct } = runMetaOf(node, t, fmt)
+ const bits = runMetaOf(node, t, fmt)
// The delegation's briefing prompt is the task's description; the opened row adds the
// subagent's final report-back. Both render as Markdown, clamped to two lines when closed.
const prompt = props.detailOf(node.id)?.detail?.initialPrompt
@@ -391,10 +389,9 @@ export function TaskBoard(props: TaskBoardProps): ReactElement {
) : null}
- {bits.length > 0 || pct !== null ? (
+ {bits.length > 0 ? (
{bits.join(' · ')}
- {pct !== null ? {pct}% : null}
) : null}
@@ -536,18 +533,6 @@ export function TaskBoard(props: TaskBoardProps): ReactElement {
) : null}
- {rows.length > 0 ? (
-
-
-
-
-
- {t('fleet.tasks.progress', { done: doneCount, total: rows.length })}
- {activeCount > 0 ? ` · ${t('fleet.tasks.active', { n: activeCount })}` : ''}
-
-
- ) : null}
-
{showToolbar ? (
{
assert.ok(text(board).includes(DICT_EN['fleet.board.others']))
assert.equal(queryAll(board, '.lc-member-card').length, 4)
assert.ok(text(query(m.container, '.lc-tasks')).includes('schema parsing'))
- // The task board's completion bar: team task-1 in flight, the w2 delegation settled.
- assert.ok(text(query(m.container, '.lc-tasks-progress')).includes('1/2 done'))
// The comms panel opens collapsed.
assert.ok(text(query(m.container, '.lc-comms')).includes('Scan 3 sessions'))
// The network card stands alone: the boards beside it carry the agent detail.
diff --git a/tests/client/components/taskBoard.spec.ts b/tests/client/components/taskBoard.spec.ts
index eaf10d2..011fdfd 100644
--- a/tests/client/components/taskBoard.spec.ts
+++ b/tests/client/components/taskBoard.spec.ts
@@ -104,7 +104,6 @@ describe('TaskBoard — the owner-grouped board', () => {
const scout = query(m.container, '[data-task="s1"]')
assert.ok(text(scout).includes('in progress'))
assert.ok(text(scout).includes('800 · 42s · 5 steps'))
- assert.ok(text(scout).includes('80%'))
assert.ok(query(scout, '.lc-team-task-subject').className.includes('lc-team-task-subject-clamp'))
assert.ok(query(scout, '.lc-team-task-head .lc-member-icon') !== null, 'the row wears the agent hue')
// The settled delegation reads done; the idler reads pending without a meta line.
@@ -349,25 +348,6 @@ describe('TaskBoard — the team task DAG', () => {
})
describe('TaskBoard — the toolbar and guidance states', () => {
- test('the head carries the completion bar over every row', async () => {
- const m = await mount(h(TaskBoard, propsOf()))
- const progress = query(m.container, '.lc-tasks-progress')
- // Team task-1 plus the settled s2 are done, of eight rows.
- assert.ok(text(progress).includes('2/8 done'))
- assert.ok(text(progress).includes('2 in progress'))
- assert.equal(query(progress, '.lc-tasks-progress-track i')?.style.width, '25%')
- await m.unmount()
-
- // No in-flight work: the active count drops out of the text.
- const calm = teamOf()
- calm.tasks[1] = { ...calm.tasks[1], status: 'completed' }
- const calmForest: AgentForest = { ...FOREST, nodes: [FOREST.nodes[0], { ...FOREST.nodes[1], running: false, completed: true }, FOREST.nodes[2], FOREST.nodes[3]] }
- const m2 = await mount(h(TaskBoard, propsOf({ team: calm, forest: calmForest })))
- assert.ok(text(query(m2.container, '.lc-tasks-progress')).includes('4/8 done'))
- assert.ok(!text(query(m2.container, '.lc-tasks-progress')).includes('in progress'))
- await m2.unmount()
- })
-
test('the status filter counts and narrows across both kinds', async () => {
const m = await mount(h(TaskBoard, propsOf()))
const filters = queryAll(m.container, '.lc-fleet-filters .lc-gran-btn')
@@ -401,12 +381,10 @@ describe('TaskBoard — the toolbar and guidance states', () => {
const m = await mount(h(TaskBoard, propsOf({ team: null, forest: { nodes: [nodeOf('root', { isCurrent: true, depth: 0 })], edges: [], overflow: 0, solo: true } })))
assert.ok(text(m.container).includes(DICT_EN['fleet.tasks.noTeam']))
assert.equal(queryAll(m.container, '.lc-team-task').length, 0)
- assert.equal(queryAll(m.container, '.lc-tasks-progress').length, 0)
await m.unmount()
const empty = await mount(h(TaskBoard, propsOf({ team: teamOf({ tasks: [] }), forest: null })))
assert.ok(text(empty.container).includes(DICT_EN['fleet.team.empty']))
- assert.equal(queryAll(empty.container, '.lc-tasks-progress').length, 0, 'no bar without tasks')
await empty.unmount()
})
})