mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
feat: enhance CLI stream viewer with active execution synchronization and improved tab UI
This commit is contained in:
@@ -206,21 +206,35 @@
|
||||
/* ===== Tab Bar ===== */
|
||||
.cli-stream-tabs {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 2px;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
background: hsl(var(--muted) / 0.2);
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scrollbar-width: thin;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Show scrollbar on hover for better UX */
|
||||
.cli-stream-tabs::-webkit-scrollbar {
|
||||
height: 4px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.cli-stream-tabs::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.cli-stream-tabs::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--border));
|
||||
border-radius: 2px;
|
||||
border-radius: 3px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.cli-stream-tabs::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(var(--muted-foreground) / 0.5);
|
||||
}
|
||||
|
||||
.cli-stream-tab {
|
||||
@@ -235,6 +249,7 @@
|
||||
color: hsl(var(--muted-foreground));
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,82 @@ let searchFilter = ''; // Search filter for output content
|
||||
|
||||
const MAX_OUTPUT_LINES = 5000; // Prevent memory issues
|
||||
|
||||
// ===== State Synchronization =====
|
||||
/**
|
||||
* Sync active executions from server
|
||||
* Called on initialization to recover state when view is opened mid-execution
|
||||
*/
|
||||
async function syncActiveExecutions() {
|
||||
// Only sync in server mode
|
||||
if (!window.SERVER_MODE) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/cli/active');
|
||||
if (!response.ok) return;
|
||||
|
||||
const { executions } = await response.json();
|
||||
if (!executions || executions.length === 0) return;
|
||||
|
||||
executions.forEach(exec => {
|
||||
// Skip if already tracked (avoid overwriting live data)
|
||||
if (cliStreamExecutions[exec.id]) return;
|
||||
|
||||
// Rebuild execution state
|
||||
cliStreamExecutions[exec.id] = {
|
||||
tool: exec.tool || 'cli',
|
||||
mode: exec.mode || 'analysis',
|
||||
output: [],
|
||||
status: exec.status || 'running',
|
||||
startTime: exec.startTime || Date.now(),
|
||||
endTime: null
|
||||
};
|
||||
|
||||
// Add system start message
|
||||
cliStreamExecutions[exec.id].output.push({
|
||||
type: 'system',
|
||||
content: `[${new Date(exec.startTime).toLocaleTimeString()}] CLI execution started: ${exec.tool} (${exec.mode} mode)`,
|
||||
timestamp: exec.startTime
|
||||
});
|
||||
|
||||
// Fill historical output (limit to last MAX_OUTPUT_LINES)
|
||||
if (exec.output) {
|
||||
const lines = exec.output.split('\n');
|
||||
const startIndex = Math.max(0, lines.length - MAX_OUTPUT_LINES + 1);
|
||||
lines.slice(startIndex).forEach(line => {
|
||||
if (line.trim()) {
|
||||
cliStreamExecutions[exec.id].output.push({
|
||||
type: 'stdout',
|
||||
content: line,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Update UI if we recovered any executions
|
||||
if (executions.length > 0) {
|
||||
// Set active tab to first running execution
|
||||
const runningExec = executions.find(e => e.status === 'running');
|
||||
if (runningExec && !activeStreamTab) {
|
||||
activeStreamTab = runningExec.id;
|
||||
}
|
||||
|
||||
renderStreamTabs();
|
||||
updateStreamBadge();
|
||||
|
||||
// If viewer is open, render content
|
||||
if (isCliStreamViewerOpen) {
|
||||
renderStreamContent(activeStreamTab);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[CLI Stream] Synced ${executions.length} active execution(s)`);
|
||||
} catch (e) {
|
||||
console.error('[CLI Stream] Sync failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Initialization =====
|
||||
function initCliStreamViewer() {
|
||||
// Initialize keyboard shortcuts
|
||||
@@ -39,6 +115,9 @@ function initCliStreamViewer() {
|
||||
if (content) {
|
||||
content.addEventListener('scroll', handleStreamContentScroll);
|
||||
}
|
||||
|
||||
// Sync active executions from server (recover state for mid-execution joins)
|
||||
syncActiveExecutions();
|
||||
}
|
||||
|
||||
// ===== Panel Control =====
|
||||
|
||||
Reference in New Issue
Block a user