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:
catlog22
2026-02-13 21:46:28 +08:00
parent d750290f84
commit 25e27286b4
21 changed files with 692 additions and 498 deletions

View File

@@ -11,9 +11,7 @@ import {
Play,
CheckCircle,
XCircle,
Clock,
Terminal,
Loader2,
} from 'lucide-react';
import { Card } from '@/components/ui/Card';
import { Badge } from '@/components/ui/Badge';
@@ -23,50 +21,9 @@ import {
selectExecutionStats,
useTerminalPanelStore,
} from '@/stores';
import type { QueueExecution, QueueExecutionStatus } from '@/stores/queueExecutionStore';
import type { QueueExecution } from '@/stores/queueExecutionStore';
import { cn } from '@/lib/utils';
// ========== Helpers ==========
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';
}
}
function statusIcon(status: QueueExecutionStatus) {
switch (status) {
case 'running':
return <Loader2 className="w-3.5 h-3.5 animate-spin" />;
case 'completed':
return <CheckCircle className="w-3.5 h-3.5" />;
case 'failed':
return <XCircle className="w-3.5 h-3.5" />;
case 'pending':
default:
return <Clock className="w-3.5 h-3.5" />;
}
}
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`;
}
import { statusIcon, statusBadgeVariant, formatRelativeTime } from '@/lib/execution-display-utils';
// ========== Empty State ==========

View File

@@ -38,6 +38,7 @@ import {
} from '@/components/shared/CliExecutionSettings';
import { buildQueueItemContext } from '@/lib/queue-prompt';
import { useQueueExecutionStore, type QueueExecution } from '@/stores/queueExecutionStore';
import type { Flow } from '@/types/flow';
// ---------------------------------------------------------------------------
// Types
@@ -70,7 +71,7 @@ export function QueueItemExecutor({ item, className }: QueueItemExecutorProps) {
// Resolve the parent issue for context building
const { issues } = useIssues();
const issue = useMemo(
() => issues.find((i) => i.id === item.issue_id) as any,
() => issues.find((i) => i.id === item.issue_id),
[issues, item.issue_id]
);
@@ -203,13 +204,13 @@ export function QueueItemExecutor({ item, className }: QueueItemExecutorProps) {
throw new Error('Failed to create flow');
}
// Hydrate Orchestrator stores
const flowDto = created.data as any;
// Hydrate Orchestrator stores -- convert OrchestratorFlowDto to Flow
const flowDto = created.data;
const parsedVersion = parseInt(String(flowDto.version ?? '1'), 10);
const flowForStore = {
const flowForStore: Flow = {
...flowDto,
version: Number.isFinite(parsedVersion) ? parsedVersion : 1,
} as any;
} as Flow;
useFlowStore.getState().setCurrentFlow(flowForStore);
// Execute the flow