mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
feat(docs): add full documentation generation phase and related documentation generation phase
- Implement Phase 4: Full Documentation Generation with multi-layered strategy and tool fallback. - Introduce Phase 5: Related Documentation Generation for incremental updates based on git changes. - Create new utility components for displaying execution status in the terminal panel. - Add helper functions for rendering execution status icons and formatting relative time. - Establish a recent paths configuration for improved path resolution.
This commit is contained in:
65
ccw/frontend/src/lib/execution-display-utils.ts
Normal file
65
ccw/frontend/src/lib/execution-display-utils.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
// ========================================
|
||||
// Execution Display Utilities
|
||||
// ========================================
|
||||
// Shared helpers for rendering queue execution status across
|
||||
// ExecutionPanel and QueueExecutionListView components.
|
||||
|
||||
import type { ReactElement } from 'react';
|
||||
import { createElement } from 'react';
|
||||
import {
|
||||
Loader2,
|
||||
CheckCircle,
|
||||
XCircle,
|
||||
Clock,
|
||||
} from 'lucide-react';
|
||||
import type { QueueExecutionStatus } from '@/stores/queueExecutionStore';
|
||||
|
||||
/**
|
||||
* Map execution status to Badge variant.
|
||||
*/
|
||||
export function statusBadgeVariant(status: QueueExecutionStatus): 'info' | 'success' | 'destructive' | 'secondary' {
|
||||
switch (status) {
|
||||
case 'running':
|
||||
return 'info';
|
||||
case 'completed':
|
||||
return 'success';
|
||||
case 'failed':
|
||||
return 'destructive';
|
||||
case 'pending':
|
||||
default:
|
||||
return 'secondary';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map execution status to a small icon element.
|
||||
*/
|
||||
export function statusIcon(status: QueueExecutionStatus): ReactElement {
|
||||
const base = 'w-3.5 h-3.5';
|
||||
switch (status) {
|
||||
case 'running':
|
||||
return createElement(Loader2, { className: `${base} animate-spin text-info` });
|
||||
case 'completed':
|
||||
return createElement(CheckCircle, { className: `${base} text-success` });
|
||||
case 'failed':
|
||||
return createElement(XCircle, { className: `${base} text-destructive` });
|
||||
case 'pending':
|
||||
default:
|
||||
return createElement(Clock, { className: `${base} text-muted-foreground` });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an ISO date string as a human-readable relative time.
|
||||
*/
|
||||
export function formatRelativeTime(isoString: string): string {
|
||||
const diff = Date.now() - new Date(isoString).getTime();
|
||||
const seconds = Math.floor(diff / 1000);
|
||||
if (seconds < 60) return `${seconds}s ago`;
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
if (minutes < 60) return `${minutes}m ago`;
|
||||
const hours = Math.floor(minutes / 60);
|
||||
if (hours < 24) return `${hours}h ago`;
|
||||
const days = Math.floor(hours / 24);
|
||||
return `${days}d ago`;
|
||||
}
|
||||
@@ -7,6 +7,34 @@
|
||||
|
||||
import type { QueueItem } from '@/lib/api';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Minimal interfaces for the issue data consumed by buildQueueItemContext.
|
||||
// The backend may return solution.tasks[] which is not part of the core
|
||||
// IssueSolution interface, so we define a local superset here.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** A lightweight task entry nested inside a solution from the backend. */
|
||||
interface SolutionTask {
|
||||
id: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/** Solution shape as consumed by the prompt builder (superset of IssueSolution). */
|
||||
interface PromptSolution {
|
||||
id: string;
|
||||
description?: string;
|
||||
approach?: string;
|
||||
tasks?: SolutionTask[];
|
||||
}
|
||||
|
||||
/** Minimal issue shape consumed by the prompt builder. */
|
||||
export interface QueueItemIssue {
|
||||
title?: string;
|
||||
context?: string;
|
||||
solutions?: PromptSolution[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a context string for executing a queue item.
|
||||
*
|
||||
@@ -18,7 +46,7 @@ import type { QueueItem } from '@/lib/api';
|
||||
*/
|
||||
export function buildQueueItemContext(
|
||||
item: QueueItem,
|
||||
issue: any | undefined
|
||||
issue: QueueItemIssue | undefined
|
||||
): string {
|
||||
const lines: string[] = [];
|
||||
|
||||
@@ -38,7 +66,7 @@ export function buildQueueItemContext(
|
||||
}
|
||||
|
||||
const solution = Array.isArray(issue.solutions)
|
||||
? issue.solutions.find((s: any) => s?.id === item.solution_id)
|
||||
? issue.solutions.find((s) => s?.id === item.solution_id)
|
||||
: undefined;
|
||||
|
||||
if (solution) {
|
||||
@@ -54,7 +82,7 @@ export function buildQueueItemContext(
|
||||
// Include matched task from solution.tasks when available
|
||||
const tasks = Array.isArray(solution.tasks) ? solution.tasks : [];
|
||||
const task = item.task_id
|
||||
? tasks.find((t: any) => t?.id === item.task_id)
|
||||
? tasks.find((t) => t?.id === item.task_id)
|
||||
: undefined;
|
||||
if (task) {
|
||||
lines.push('');
|
||||
|
||||
Reference in New Issue
Block a user