feat: unify CLI output handling and enhance theme variables

- Updated `CliStreamMonitorNew`, `CliStreamMonitorLegacy`, and `CliViewerPage` components to prioritize `unitContent` from payloads, falling back to `data` when necessary.
- Enhanced `colorGenerator` to include legacy variables for compatibility with shadcn/ui.
- Refactored orchestrator index to unify node exports under a single module.
- Improved `appStore` to clear both new and legacy CSS variables when applying themes.
- Added new options to CLI execution for raw and final output modes, improving programmatic output handling.
- Enhanced `cli-output-converter` to normalize cumulative delta frames and avoid duplication in streaming outputs.
- Introduced a new unified workflow specification for prompt template-based workflows, replacing the previous multi-type node system.
- Added tests for CLI final output handling and streaming output converter to ensure correct behavior in various scenarios.
This commit is contained in:
catlog22
2026-02-04 22:57:41 +08:00
parent 4ee165119b
commit de989aa038
12 changed files with 899 additions and 107 deletions

View File

@@ -250,7 +250,7 @@ export function CliStreamMonitorNew({ isOpen, onClose }: CliStreamMonitorNewProp
invalidateActive();
} else if (type === 'CLI_OUTPUT') {
const p = payload as CliStreamOutputPayload;
const unitContent = p.unit?.content;
const unitContent = p.unit?.content ?? p.data;
const unitType = p.unit?.type || p.chunkType;
let content: string;
@@ -267,7 +267,7 @@ export function CliStreamMonitorNew({ isOpen, onClose }: CliStreamMonitorNewProp
content = JSON.stringify(unitContent);
}
} else {
content = typeof p.data === 'string' ? p.data : JSON.stringify(p.data);
content = typeof unitContent === 'string' ? unitContent : JSON.stringify(unitContent);
}
const lines = content.split('\n');

View File

@@ -257,7 +257,7 @@ export function CliStreamMonitor({ isOpen, onClose }: CliStreamMonitorProps) {
invalidateActive();
} else if (type === 'CLI_OUTPUT') {
const p = payload as CliStreamOutputPayload;
const unitContent = p.unit?.content;
const unitContent = p.unit?.content ?? p.data;
const unitType = p.unit?.type || p.chunkType;
let content: string;
@@ -274,7 +274,7 @@ export function CliStreamMonitor({ isOpen, onClose }: CliStreamMonitorProps) {
content = JSON.stringify(unitContent);
}
} else {
content = typeof p.data === 'string' ? p.data : JSON.stringify(p.data);
content = typeof unitContent === 'string' ? unitContent : JSON.stringify(unitContent);
}
const lines = content.split('\n');

View File

@@ -98,6 +98,25 @@ export function generateThemeFromHue(
vars['--active'] = `${normalizedHue} 15% 90%`;
vars['--focus'] = `${normalizedHue} 70% 60%`;
// Legacy variables for shadcn/ui compatibility
vars['--background'] = vars['--bg'];
vars['--foreground'] = vars['--text'];
vars['--card'] = vars['--surface'];
vars['--card-foreground'] = vars['--text'];
vars['--primary-foreground'] = `0 0% 100%`;
vars['--secondary-foreground'] = `0 0% 100%`;
vars['--accent-foreground'] = `0 0% 100%`;
vars['--destructive-foreground'] = `0 0% 100%`;
vars['--muted-foreground'] = vars['--text-secondary'];
vars['--sidebar-background'] = `${normalizedHue} 30% 97%`;
vars['--sidebar-foreground'] = vars['--text'];
vars['--input'] = vars['--border'];
vars['--ring'] = vars['--accent'];
vars['--indigo'] = `239 65% 60%`;
vars['--indigo-light'] = `239 65% 92%`;
vars['--orange'] = `25 90% 55%`;
vars['--orange-light'] = `25 90% 92%`;
} else {
// Dark mode: Medium saturation, low lightness backgrounds
vars['--bg'] = `${normalizedHue} 20% 10%`;
@@ -163,6 +182,25 @@ export function generateThemeFromHue(
vars['--hover'] = `${normalizedHue} 18% 16%`;
vars['--active'] = `${normalizedHue} 20% 20%`;
vars['--focus'] = `${normalizedHue} 70% 60%`;
// Legacy variables for shadcn/ui compatibility
vars['--background'] = vars['--bg'];
vars['--foreground'] = vars['--text'];
vars['--card'] = vars['--surface'];
vars['--card-foreground'] = vars['--text'];
vars['--primary-foreground'] = `${normalizedHue} 30% 10%`;
vars['--secondary-foreground'] = `0 0% 100%`;
vars['--accent-foreground'] = `${normalizedHue} 30% 10%`;
vars['--destructive-foreground'] = `0 0% 100%`;
vars['--muted-foreground'] = vars['--text-secondary'];
vars['--sidebar-background'] = `${normalizedHue} 25% 12%`;
vars['--sidebar-foreground'] = vars['--text'];
vars['--input'] = vars['--border'];
vars['--ring'] = vars['--accent'];
vars['--indigo'] = `239 60% 55%`;
vars['--indigo-light'] = `239 40% 20%`;
vars['--orange'] = `25 85% 50%`;
vars['--orange-light'] = `25 50% 20%`;
}
return vars;

View File

@@ -232,7 +232,7 @@ export function CliViewerPage() {
invalidateActive();
} else if (type === 'CLI_OUTPUT') {
const p = payload as CliStreamOutputPayload;
const unitContent = p.unit?.content;
const unitContent = p.unit?.content ?? p.data;
const unitType = p.unit?.type || p.chunkType;
let content: string;
@@ -249,7 +249,7 @@ export function CliViewerPage() {
content = JSON.stringify(unitContent);
}
} else {
content = typeof p.data === 'string' ? p.data : JSON.stringify(p.data);
content = typeof unitContent === 'string' ? unitContent : JSON.stringify(unitContent);
}
const lines = content.split('\n');

View File

@@ -8,8 +8,5 @@ export { NodePalette } from './NodePalette';
export { PropertyPanel } from './PropertyPanel';
export { FlowToolbar } from './FlowToolbar';
// Node components
export { SlashCommandNode } from './nodes/SlashCommandNode';
export { FileOperationNode } from './nodes/FileOperationNode';
export { ConditionalNode } from './nodes/ConditionalNode';
export { ParallelNode } from './nodes/ParallelNode';
// Node components (unified system)
export { NodeWrapper, PromptTemplateNode, nodeTypes } from './nodes';

View File

@@ -51,8 +51,9 @@ const applyThemeToDocument = (
document.documentElement.classList.remove('light', 'dark');
document.documentElement.classList.add(resolvedTheme);
// Clear custom CSS variables list
// Clear custom CSS variables list (includes both new and legacy variables)
const customVars = [
// New theme system variables
'--bg', '--bg-secondary', '--surface', '--surface-hover',
'--border', '--border-hover', '--text', '--text-secondary',
'--text-tertiary', '--text-disabled', '--accent', '--accent-hover',
@@ -63,7 +64,13 @@ const applyThemeToDocument = (
'--warning', '--warning-light', '--warning-text', '--error',
'--error-light', '--error-text', '--info', '--info-light',
'--info-text', '--destructive', '--destructive-hover', '--destructive-light',
'--hover', '--active', '--focus'
'--hover', '--active', '--focus',
// Legacy shadcn/ui compatibility variables
'--background', '--foreground', '--card', '--card-foreground',
'--primary-foreground', '--secondary-foreground', '--accent-foreground',
'--destructive-foreground', '--muted-foreground', '--sidebar-background',
'--sidebar-foreground', '--input', '--ring', '--indigo', '--indigo-light',
'--orange', '--orange-light'
];
// Apply custom theme or preset theme