π File detail
components/tasks/taskStatusUtils.tsx
π§© .tsxπ 107 linesπΎ 13,548 bytesπ text
β Back to All Filesπ― Use case
This file lives under βcomponents/β, which covers shared React UI pieces. On the API surface it exposes isTerminalStatus, getTaskStatusIcon, getTaskStatusColor, describeTeammateActivity, and shouldHideTasksFooter β mainly functions, hooks, or classes. Dependencies touch figures and src. What the file header says: Shared utilities for displaying task status across different task types.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Shared utilities for displaying task status across different task types.
π€ Exports (heuristic)
isTerminalStatusgetTaskStatusIcongetTaskStatusColordescribeTeammateActivityshouldHideTasksFooter
π External import roots
Package roots from from "β¦" (relative paths omitted).
figuressrc
π₯οΈ Source preview
/**
* Shared utilities for displaying task status across different task types.
*/
import figures from 'figures';
import type { TaskStatus } from 'src/Task.js';
import type { InProcessTeammateTaskState } from 'src/tasks/InProcessTeammateTask/types.js';
import { isPanelAgentTask } from 'src/tasks/LocalAgentTask/LocalAgentTask.js';
import { isBackgroundTask, type TaskState } from 'src/tasks/types.js';
import type { DeepImmutable } from 'src/types/utils.js';
import { summarizeRecentActivities } from 'src/utils/collapseReadSearch.js';
/**
* Returns true if the given task status represents a terminal (finished) state.
*/
export function isTerminalStatus(status: TaskStatus): boolean {
return status === 'completed' || status === 'failed' || status === 'killed';
}
/**
* Returns the appropriate icon for a task based on status and state flags.
*/
export function getTaskStatusIcon(status: TaskStatus, options?: {
isIdle?: boolean;
awaitingApproval?: boolean;
hasError?: boolean;
shutdownRequested?: boolean;
}): string {
const {
isIdle,
awaitingApproval,
hasError,
shutdownRequested
} = options ?? {};
if (hasError) return figures.cross;
if (awaitingApproval) return figures.questionMarkPrefix;
if (shutdownRequested) return figures.warning;
if (status === 'running') {
if (isIdle) return figures.ellipsis;
return figures.play;
}
if (status === 'completed') return figures.tick;
if (status === 'failed' || status === 'killed') return figures.cross;
return figures.bullet;
}
/**
* Returns the appropriate semantic color for a task based on status and state flags.
*/
export function getTaskStatusColor(status: TaskStatus, options?: {
isIdle?: boolean;
awaitingApproval?: boolean;
hasError?: boolean;
shutdownRequested?: boolean;
}): 'success' | 'error' | 'warning' | 'background' {
const {
isIdle,
awaitingApproval,
hasError,
shutdownRequested
} = options ?? {};
if (hasError) return 'error';
if (awaitingApproval) return 'warning';
if (shutdownRequested) return 'warning';
if (isIdle) return 'background';
if (status === 'completed') return 'success';
if (status === 'failed') return 'error';
if (status === 'killed') return 'warning';
return 'background';
}
/**
* Derives a human-readable activity string for an in-process teammate,
* accounting for shutdown/approval/idle states and falling back through
* recent-activity summary β last activity description β 'working'.
*/
export function describeTeammateActivity(t: DeepImmutable<InProcessTeammateTaskState>): string {
if (t.shutdownRequested) return 'stopping';
if (t.awaitingPlanApproval) return 'awaiting approval';
if (t.isIdle) return 'idle';
return (t.progress?.recentActivities && summarizeRecentActivities(t.progress.recentActivities)) ?? t.progress?.lastActivity?.activityDescription ?? 'working';
}
/**
* Returns true when BackgroundTaskStatus would render nothing because the
* spinner tree is active and every visible background task is an in-process
* teammate (teammates are shown in the spinner tree instead).
*
* Uses the same task filtering as BackgroundTaskStatus: `isBackgroundTask()`
* plus exclusion of panel-managed agent tasks for ants (those are shown
* by CoordinatorTaskPanel).
*/
export function shouldHideTasksFooter(tasks: {
[taskId: string]: TaskState;
}, showSpinnerTree: boolean): boolean {
if (!showSpinnerTree) return false;
let hasVisibleTask = false;
for (const t of Object.values(tasks) as TaskState[]) {
if (!isBackgroundTask(t) || "external" === 'ant' && isPanelAgentTask(t)) {
continue;
}
hasVisibleTask = true;
if (t.type !== 'in_process_teammate') return false;
}
return hasVisibleTask;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiVGFza1N0YXR1cyIsIkluUHJvY2Vzc1RlYW1tYXRlVGFza1N0YXRlIiwiaXNQYW5lbEFnZW50VGFzayIsImlzQmFja2dyb3VuZFRhc2siLCJUYXNrU3RhdGUiLCJEZWVwSW1tdXRhYmxlIiwic3VtbWFyaXplUmVjZW50QWN0aXZpdGllcyIsImlzVGVybWluYWxTdGF0dXMiLCJzdGF0dXMiLCJnZXRUYXNrU3RhdHVzSWNvbiIsIm9wdGlvbnMiLCJpc0lkbGUiLCJhd2FpdGluZ0FwcHJvdmFsIiwiaGFzRXJyb3IiLCJzaHV0ZG93blJlcXVlc3RlZCIsImNyb3NzIiwicXVlc3Rpb25NYXJrUHJlZml4Iiwid2FybmluZyIsImVsbGlwc2lzIiwicGxheSIsInRpY2siLCJidWxsZXQiLCJnZXRUYXNrU3RhdHVzQ29sb3IiLCJkZXNjcmliZVRlYW1tYXRlQWN0aXZpdHkiLCJ0IiwiYXdhaXRpbmdQbGFuQXBwcm92YWwiLCJwcm9ncmVzcyIsInJlY2VudEFjdGl2aXRpZXMiLCJsYXN0QWN0aXZpdHkiLCJhY3Rpdml0eURlc2NyaXB0aW9uIiwic2hvdWxkSGlkZVRhc2tzRm9vdGVyIiwidGFza3MiLCJ0YXNrSWQiLCJzaG93U3Bpbm5lclRyZWUiLCJoYXNWaXNpYmxlVGFzayIsIk9iamVjdCIsInZhbHVlcyIsInR5cGUiXSwic291cmNlcyI6WyJ0YXNrU3RhdHVzVXRpbHMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2hhcmVkIHV0aWxpdGllcyBmb3IgZGlzcGxheWluZyB0YXNrIHN0YXR1cyBhY3Jvc3MgZGlmZmVyZW50IHRhc2sgdHlwZXMuXG4gKi9cblxuaW1wb3J0IGZpZ3VyZXMgZnJvbSAnZmlndXJlcydcbmltcG9ydCB0eXBlIHsgVGFza1N0YXR1cyB9IGZyb20gJ3NyYy9UYXNrLmpzJ1xuaW1wb3J0IHR5cGUgeyBJblByb2Nlc3NUZWFtbWF0ZVRhc2tTdGF0ZSB9IGZyb20gJ3NyYy90YXNrcy9JblByb2Nlc3NUZWFtbWF0ZVRhc2svdHlwZXMuanMnXG5pbXBvcnQgeyBpc1BhbmVsQWdlbnRUYXNrIH0gZnJvbSAnc3JjL3Rhc2tzL0xvY2FsQWdlbnRUYXNrL0xvY2FsQWdlbnRUYXNrLmpzJ1xuaW1wb3J0IHsgaXNCYWNrZ3JvdW5kVGFzaywgdHlwZSBUYXNrU3RhdGUgfSBmcm9tICdzcmMvdGFza3MvdHlwZXMuanMnXG5pbXBvcnQgdHlwZSB7IERlZXBJbW11dGFibGUgfSBmcm9tICdzcmMvdHlwZXMvdXRpbHMuanMnXG5pbXBvcnQgeyBzdW1tYXJpemVSZWNlbnRBY3Rpdml0aWVzIH0gZnJvbSAnc3JjL3V0aWxzL2NvbGxhcHNlUmVhZFNlYXJjaC5qcydcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHRhc2sgc3RhdHVzIHJlcHJlc2VudHMgYSB0ZXJtaW5hbCAoZmluaXNoZWQpIHN0YXRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUZXJtaW5hbFN0YXR1cyhzdGF0dXM6IFRhc2tTdGF0dXMpOiBib29sZWFuIHtcbiAgcmV0dXJuIHN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcgfHwgc3RhdHVzID09PSAnZmFpbGVkJyB8fCBzdGF0dXMgPT09ICdraWxsZWQnXG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYXBwcm9wcmlhdGUgaWNvbiBmb3IgYSB0YXNrIGJhc2VkIG9uIHN0YXR1cyBhbmQgc3RhdGUgZmxhZ3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUYXNrU3RhdHVzSWNvbihcbiAgc3RhdHVzOiBUYXNrU3RhdHVzLFxuICBvcHRpb25zPzoge1xuICAgIGlzSWRsZT86IGJvb2xlYW5cbiAgICBhd2FpdGluZ0FwcHJvdmFsPzogYm9vbGVhblxuICAgIGhhc0Vycm9yPzogYm9vbGVhblxuICAgIHNodXRkb3duUmVxdWVzdGVkPzogYm9vbGVhblxuICB9LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgeyBpc0lkbGUsIGF3YWl0aW5nQXBwcm92YWwsIGhhc0Vycm9yLCBzaHV0ZG93blJlcXVlc3RlZCB9ID1cbiAgICBvcHRpb25zID8/IHt9XG5cbiAgaWYgKGhhc0Vycm9yKSByZXR1cm4gZmlndXJlcy5jcm9zc1xuICBpZiAoYXdhaXRpbmdBcHByb3ZhbCkgcmV0dXJuIGZpZ3VyZXMucXVlc3Rpb25NYXJrUHJlZml4XG4gIGlmIChzaHV0ZG93blJlcXVlc3RlZCkgcmV0dXJuIGZpZ3VyZXMud2FybmluZ1xuXG4gIGlmIChzdGF0dXMgPT09ICdydW5uaW5nJykge1xuICAgIGlmIChpc0lkbGUpIHJldHVybiBmaWd1cmVzLmVsbGlwc2lzXG4gICAgcmV0dXJuIGZpZ3VyZXMucGxheVxuICB9XG4gIGlmIChzdGF0dXMgPT09ICdjb21wbGV0ZWQnKSByZXR1cm4gZmlndXJlcy50aWNrXG4gIGlmIChzdGF0dXMgPT09ICdmYWlsZWQnIHx8IHN0YXR1cyA9PT0gJ2tpbGxlZCcpIHJldHVybiBmaWd1cmVzLmNyb3NzXG4gIHJldHVybiBmaWd1cmVzLmJ1bGxldFxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGFwcHJvcHJpYXRlIHNlbWFudGljIGNvbG9yIGZvciBhIHRhc2sgYmFzZWQgb24gc3RhdHVzIGFuZCBzdGF0ZSBmbGFncy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRhc2tTdGF0dXNDb2xvcihcbiAgc3RhdHVzOiBUYXNrU3RhdHVzLFxuICBvcHRpb25zPzoge1xuICAgIGlzSWRsZT86IGJvb2xlYW5cbiAgICBhd2FpdGluZ0FwcHJvdmFsPzogYm9vbGVhblxuICAgIGhhc0Vycm9yPzogYm9vbGVhblxuICAgIHNodXRkb3duUmVxdWVzdGVkPzogYm9vbGVhblxuICB9LFxuKTogJ3N1Y2Nlc3MnIHwgJ2Vycm9yJyB8ICd3YXJuaW5nJyB8ICdiYWNrZ3JvdW5kJyB7XG4gIGNvbnN0IHsgaXNJZGxlLCBhd2FpdGluZ0FwcHJvdmFsLCBoYXNFcnJvciwgc2h1dGRvd25SZXF1ZXN0ZWQgfSA9XG4gICAgb3B0aW9ucyA/PyB7fVxuXG4gIGlmIChoYXNFcnJvcikgcmV0dXJuICdlcnJvcidcbiAgaWYgKGF3YWl0aW5nQXBwcm92YWwpIHJldHVybiAnd2FybmluZydcbiAgaWYgKHNodXRkb3duUmVxdWVzdGVkKSByZXR1cm4gJ3dhcm5pbmcnXG4gIGlmIChpc0lkbGUpIHJldHVybiAnYmFja2dyb3VuZCdcblxuICBpZiAoc3RhdHVzID09PSAnY29tcGxldGVkJykgcmV0dXJuICdzdWNjZXNzJ1xuICBpZiAoc3RhdHVzID09PSAnZmFpbGVkJykgcmV0dXJuICdlcnJvcidcbiAgaWYgKHN0YXR1cyA9PT0gJ2tpbGxlZCcpIHJldHVybiAnd2FybmluZydcbiAgcmV0dXJuICdiYWNrZ3JvdW5kJ1xufVxuXG4vKipcbiAqIERlcml2ZXMgYSBodW1hbi1yZWFkYWJsZSBhY3Rpdml0eSBzdHJpbmcgZm9yIGFuIGluLXByb2Nlc3MgdGVhbW1hdGUsXG4gKiBhY2NvdW50aW5nIGZvciBzaHV0ZG93bi9hcHByb3ZhbC9pZGxlIHN0YXRlcyBhbmQgZmFsbGluZyBiYWNrIHRocm91Z2hcbiAqIHJlY2VudC1hY3Rpdml0eSBzdW1tYXJ5IOKGkiBsYXN0IGFjdGl2aXR5IGRlc2NyaXB0aW9uIOKGkiAnd29ya2luZycuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXNjcmliZVRlYW1tYXRlQWN0aXZpdHkoXG4gIHQ6IERlZXBJbW11dGFibGU8SW5Qcm9jZXNzVGVhbW1hdGVUYXNrU3RhdGU+LFxuKTogc3RyaW5nIHtcbiAgaWYgKHQuc2h1dGRvd25SZXF1ZXN0ZWQpIHJldHVybiAnc3RvcHBpbmcnXG4gIGlmICh0LmF3YWl0aW5nUGxhbkFwcHJvdmFsKSByZXR1cm4gJ2F3YWl0aW5nIGFwcHJvdmFsJ1xuICBpZiAodC5pc0lkbGUpIHJldHVybiAnaWRsZSdcbiAgcmV0dXJuIChcbiAgICAodC5wcm9ncmVzcz8ucmVjZW50QWN0aXZpdGllcyAmJlxuICAgICAgc3VtbWFyaXplUmVjZW50QWN0aXZpdGllcyh0LnByb2dyZXNzLnJlY2VudEFjdGl2aXRpZXMpKSA/P1xuICAgIHQucHJvZ3Jlc3M/Lmxhc3RBY3Rpdml0eT8uYWN0aXZpdHlEZXNjcmlwdGlvbiA/P1xuICAgICd3b3JraW5nJ1xuICApXG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIHdoZW4gQmFja2dyb3VuZFRhc2tTdGF0dXMgd291bGQgcmVuZGVyIG5vdGhpbmcgYmVjYXVzZSB0aGVcbiAqIHNwaW5uZXIgdHJlZSBpcyBhY3RpdmUgYW5kIGV2ZXJ5IHZpc2libGUgYmFja2dyb3VuZCB0YXNrIGlzIGFuIGluLXByb2Nlc3NcbiAqIHRlYW1tYXRlICh0ZWFtbWF0ZXMgYXJlIHNob3duIGluIHRoZSBzcGlubmVyIHRyZWUgaW5zdGVhZCkuXG4gKlxuICogVXNlcyB0aGUgc2FtZSB0YXNrIGZpbHRlcmluZyBhcyBCYWNrZ3JvdW5kVGFza1N0YXR1czogYGlzQmFja2dyb3VuZFRhc2soKWBcbiAqIHBsdXMgZXhjbHVzaW9uIG9mIHBhbmVsLW1hbmFnZWQgYWdlbnQgdGFza3MgZm9yIGFudHMgKHRob3NlIGFyZSBzaG93blxuICogYnkgQ29vcmRpbmF0b3JUYXNrUGFuZWwpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2hvdWxkSGlkZVRhc2tzRm9vdGVyKFxuICB0YXNrczogeyBbdGFza0lkOiBzdHJpbmddOiBUYXNrU3RhdGUgfSxcbiAgc2hvd1NwaW5uZXJUcmVlOiBib29sZWFuLFxuKTogYm9vbGVhbiB7XG4gIGlmICghc2hvd1NwaW5uZXJUcmVlKSByZXR1cm4gZmFsc2VcbiAgbGV0IGhhc1Zpc2libGVUYXNrID0gZmFsc2VcbiAgZm9yIChjb25zdCB0IG9mIE9iamVjdC52YWx1ZXModGFza3MpIGFzIFRhc2tTdGF0ZVtdKSB7XG4gICAgaWYgKFxuICAgICAgIWlzQmFja2dyb3VuZFRhc2sodCkgfHxcbiAgICAgIChcImV4dGVybmFsXCIgPT09ICdhbnQnICYmIGlzUGFuZWxBZ2VudFRhc2sodCkpXG4gICAgKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBoYXNWaXNpYmxlVGFzayA9IHRydWVcbiAgICBpZiAodC50eXBlICE9PSAnaW5fcHJvY2Vzc190ZWFtbWF0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