chore: update component exports and fix merge artifacts
- Export new preview components - Remove unused imports from upstream merge - Update .gitignore patterns - Clean up TypeScript errors from merge conflicts
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -23,3 +23,5 @@ dist-ssr
|
|||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
temp_lib/
|
temp_lib/
|
||||||
|
|
||||||
|
.cursor/
|
@@ -217,7 +217,7 @@ function App() {
|
|||||||
|
|
||||||
case "projects":
|
case "projects":
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 flex items-center justify-center p-4 overflow-y-auto">
|
<div className="flex h-full items-center justify-center p-4 overflow-y-auto">
|
||||||
<div className="w-full max-w-2xl">
|
<div className="w-full max-w-2xl">
|
||||||
{/* Header with back button */}
|
{/* Header with back button */}
|
||||||
<motion.div
|
<motion.div
|
||||||
|
@@ -298,7 +298,7 @@ export const CCAgents: React.FC<CCAgentsProps> = ({ onBack, className }) => {
|
|||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
exit={{ opacity: 0, y: -20 }}
|
exit={{ opacity: 0, y: -20 }}
|
||||||
transition={{ duration: 0.2 }}
|
transition={{ duration: 0.2 }}
|
||||||
className="space-y-8"
|
className="pt-6 space-y-8"
|
||||||
>
|
>
|
||||||
{/* Agents Grid */}
|
{/* Agents Grid */}
|
||||||
<div>
|
<div>
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
ChevronDown,
|
ChevronRight,
|
||||||
ChevronRight,
|
Loader2,
|
||||||
Loader2,
|
CheckCircle2,
|
||||||
CheckCircle2,
|
|
||||||
AlertCircle,
|
AlertCircle,
|
||||||
Terminal,
|
Terminal,
|
||||||
FileText,
|
FileText,
|
||||||
@@ -96,8 +95,7 @@ function getToolDescription(toolCall: ToolCall): string {
|
|||||||
export const CollapsibleToolResult: React.FC<CollapsibleToolResultProps> = ({
|
export const CollapsibleToolResult: React.FC<CollapsibleToolResultProps> = ({
|
||||||
toolCall,
|
toolCall,
|
||||||
toolResult,
|
toolResult,
|
||||||
className,
|
className
|
||||||
children
|
|
||||||
}) => {
|
}) => {
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
const isPending = !toolResult;
|
const isPending = !toolResult;
|
||||||
|
@@ -50,6 +50,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
import * as Diff from 'diff';
|
import * as Diff from 'diff';
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { detectLinks, makeLinksClickable } from "@/lib/linkDetector";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widget for TodoWrite tool - displays a beautiful TODO list
|
* Widget for TodoWrite tool - displays a beautiful TODO list
|
||||||
@@ -1139,33 +1140,57 @@ export const CommandWidget: React.FC<{
|
|||||||
*/
|
*/
|
||||||
export const CommandOutputWidget: React.FC<{
|
export const CommandOutputWidget: React.FC<{
|
||||||
output: string;
|
output: string;
|
||||||
}> = ({ output }) => {
|
onLinkDetected?: (url: string) => void;
|
||||||
|
}> = ({ output, onLinkDetected }) => {
|
||||||
|
// Check for links on mount and when output changes
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (output && onLinkDetected) {
|
||||||
|
const links = detectLinks(output);
|
||||||
|
if (links.length > 0) {
|
||||||
|
// Notify about the first detected link
|
||||||
|
onLinkDetected(links[0].fullUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [output, onLinkDetected]);
|
||||||
|
|
||||||
// Parse ANSI codes for basic styling
|
// Parse ANSI codes for basic styling
|
||||||
const parseAnsiToReact = (text: string) => {
|
const parseAnsiToReact = (text: string) => {
|
||||||
// Simple ANSI parsing - handles bold (\u001b[1m) and reset (\u001b[22m)
|
// Simple ANSI parsing - handles bold (\u001b[1m) and reset (\u001b[22m)
|
||||||
const parts = text.split(/(\u001b\[\d+m)/);
|
const parts = text.split(/(\u001b\[\d+m)/);
|
||||||
let isBold = false;
|
let isBold = false;
|
||||||
|
const elements: React.ReactNode[] = [];
|
||||||
|
|
||||||
return parts.map((part, idx) => {
|
parts.forEach((part, idx) => {
|
||||||
if (part === '\u001b[1m') {
|
if (part === '\u001b[1m') {
|
||||||
isBold = true;
|
isBold = true;
|
||||||
return null;
|
return;
|
||||||
} else if (part === '\u001b[22m') {
|
} else if (part === '\u001b[22m') {
|
||||||
isBold = false;
|
isBold = false;
|
||||||
return null;
|
return;
|
||||||
} else if (part.match(/\u001b\[\d+m/)) {
|
} else if (part.match(/\u001b\[\d+m/)) {
|
||||||
// Ignore other ANSI codes for now
|
// Ignore other ANSI codes for now
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!part) return null;
|
if (!part) return;
|
||||||
|
|
||||||
return (
|
// Make links clickable within this part
|
||||||
<span key={idx} className={isBold ? 'font-bold' : ''}>
|
const linkElements = makeLinksClickable(part, (url) => {
|
||||||
{part}
|
onLinkDetected?.(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isBold) {
|
||||||
|
elements.push(
|
||||||
|
<span key={idx} className="font-bold">
|
||||||
|
{linkElements}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
elements.push(...linkElements);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
Reference in New Issue
Block a user