Files
orcs-code/src/components/tasks/taskStatusUtils.tsx
Anandan 462a985d7e Remove embedded source map directives from tracked sources (#329)
Inline base64 source maps had been checked into tracked src files. This strips those comments from the repository without changing runtime behavior or adding ongoing guardrails, per the requested one-time cleanup scope.

Constraint: Keep this change limited to tracked source cleanup only
Rejected: Add CI/source verification guard | user requested one-time cleanup only
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If these directives reappear, fix the producing transform instead of reintroducing repo-side cleanup code
Tested: rg -n "sourceMappingURL" ., bun run smoke, bun run verify:privacy, bun run test:provider, npm run test:provider-recommendation
Not-tested: bun run typecheck (repository has many pre-existing unrelated failures)

Co-authored-by: anandh8x <test@example.com>
2026-04-04 21:19:27 +08:00

107 lines
3.7 KiB
TypeScript

/**
* 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;
}