@townco/ui 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/hooks/index.d.ts +1 -0
- package/dist/core/hooks/index.js +1 -0
- package/dist/core/hooks/use-chat-messages.d.ts +50 -11
- package/dist/core/hooks/use-chat-session.d.ts +5 -5
- package/dist/core/hooks/use-tool-calls.d.ts +52 -0
- package/dist/core/hooks/use-tool-calls.js +61 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/lib/logger.d.ts +24 -0
- package/dist/core/lib/logger.js +108 -0
- package/dist/core/schemas/chat.d.ts +166 -83
- package/dist/core/schemas/chat.js +27 -27
- package/dist/core/schemas/index.d.ts +1 -0
- package/dist/core/schemas/index.js +1 -0
- package/dist/core/schemas/tool-call.d.ts +174 -0
- package/dist/core/schemas/tool-call.js +130 -0
- package/dist/core/store/chat-store.d.ts +28 -28
- package/dist/core/store/chat-store.js +123 -59
- package/dist/gui/components/ChatLayout.js +11 -10
- package/dist/gui/components/MessageContent.js +4 -1
- package/dist/gui/components/ToolCall.d.ts +8 -0
- package/dist/gui/components/ToolCall.js +100 -0
- package/dist/gui/components/ToolCallList.d.ts +9 -0
- package/dist/gui/components/ToolCallList.js +22 -0
- package/dist/gui/components/index.d.ts +2 -0
- package/dist/gui/components/index.js +2 -0
- package/dist/gui/components/resizable.d.ts +7 -0
- package/dist/gui/components/resizable.js +7 -0
- package/dist/sdk/schemas/session.d.ts +390 -220
- package/dist/sdk/schemas/session.js +74 -29
- package/dist/sdk/transports/http.js +705 -472
- package/dist/sdk/transports/stdio.js +187 -32
- package/dist/tui/components/ChatView.js +19 -51
- package/dist/tui/components/MessageList.d.ts +2 -4
- package/dist/tui/components/MessageList.js +13 -37
- package/dist/tui/components/ToolCall.d.ts +9 -0
- package/dist/tui/components/ToolCall.js +41 -0
- package/dist/tui/components/ToolCallList.d.ts +8 -0
- package/dist/tui/components/ToolCallList.js +17 -0
- package/dist/tui/components/index.d.ts +2 -0
- package/dist/tui/components/index.js +2 -0
- package/package.json +4 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { ArrowDown } from "lucide-react";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from "./resizable.js";
|
|
5
6
|
import { Toaster } from "./Sonner.js";
|
|
6
7
|
const ChatLayoutContext = React.createContext(undefined);
|
|
7
8
|
const useChatLayoutContext = () => {
|
|
@@ -22,7 +23,7 @@ const ChatLayoutRoot = React.forwardRef(({ defaultSidebarOpen = false, defaultPa
|
|
|
22
23
|
setPanelSize,
|
|
23
24
|
activeTab,
|
|
24
25
|
setActiveTab,
|
|
25
|
-
}, children: _jsx("div", { ref: ref, className: cn("flex h-screen flex-row bg-background text-foreground", className), ...props, children: children }) }));
|
|
26
|
+
}, children: _jsx("div", { ref: ref, className: cn("flex h-screen flex-row bg-background text-foreground", className), ...props, children: _jsx(ResizablePanelGroup, { direction: "horizontal", className: "flex-1", children: children }) }) }));
|
|
26
27
|
});
|
|
27
28
|
ChatLayoutRoot.displayName = "ChatLayout.Root";
|
|
28
29
|
const ChatLayoutHeader = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
@@ -30,7 +31,7 @@ const ChatLayoutHeader = React.forwardRef(({ className, children, ...props }, re
|
|
|
30
31
|
});
|
|
31
32
|
ChatLayoutHeader.displayName = "ChatLayout.Header";
|
|
32
33
|
const ChatLayoutMain = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
33
|
-
return (_jsx("div", { ref: ref, className: cn("flex flex-1 flex-col overflow-hidden", className), ...props, children: children }));
|
|
34
|
+
return (_jsx(ResizablePanel, { defaultSize: 75, minSize: 50, children: _jsx("div", { ref: ref, className: cn("flex flex-1 flex-col overflow-hidden h-full", className), ...props, children: children }) }));
|
|
34
35
|
});
|
|
35
36
|
ChatLayoutMain.displayName = "ChatLayout.Main";
|
|
36
37
|
const ChatLayoutBody = React.forwardRef(({ showToaster = true, className, children, ...props }, ref) => {
|
|
@@ -90,13 +91,13 @@ const ChatLayoutAside = React.forwardRef(({ breakpoint = "lg", className, childr
|
|
|
90
91
|
// Hidden state - don't render
|
|
91
92
|
if (panelSize === "hidden")
|
|
92
93
|
return null;
|
|
93
|
-
return (_jsx("div", { ref: ref, className: cn(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
return (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 25, minSize: 15, maxSize: 50, children: _jsx("div", { ref: ref, className: cn(
|
|
95
|
+
// Hidden by default, visible at breakpoint
|
|
96
|
+
"hidden h-full border-l border-border bg-card overflow-y-auto transition-all duration-300",
|
|
97
|
+
// Breakpoint visibility
|
|
98
|
+
breakpoint === "md" && "md:block", breakpoint === "lg" && "lg:block", breakpoint === "xl" && "xl:block", breakpoint === "2xl" && "2xl:block",
|
|
99
|
+
// Size variants - width is now controlled by ResizablePanel
|
|
100
|
+
className), ...props, children: children }) })] }));
|
|
100
101
|
});
|
|
101
102
|
ChatLayoutAside.displayName = "ChatLayout.Aside";
|
|
102
103
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -6,6 +6,7 @@ import { useChatStore } from "../../core/store/chat-store.js";
|
|
|
6
6
|
import { cn } from "../lib/utils.js";
|
|
7
7
|
import { Reasoning } from "./Reasoning.js";
|
|
8
8
|
import { Response } from "./Response.js";
|
|
9
|
+
import { ToolCall } from "./ToolCall.js";
|
|
9
10
|
/**
|
|
10
11
|
* MessageContent component inspired by shadcn.io/ai
|
|
11
12
|
* Provides the content container with role-based styling
|
|
@@ -97,7 +98,9 @@ export const MessageContent = React.forwardRef(({ role: roleProp, variant, isStr
|
|
|
97
98
|
const hasThinking = !!thinking;
|
|
98
99
|
// Check if waiting (streaming but no content yet)
|
|
99
100
|
const isWaiting = message.isStreaming && !message.content && message.role === "assistant";
|
|
100
|
-
content = (_jsxs(_Fragment, { children: [message.role === "assistant" && hasThinking && (_jsx(Reasoning, { content: thinking, isStreaming: message.isStreaming, mode: thinkingDisplayStyle, autoCollapse: true })), isWaiting && streamingStartTime && (_jsxs("div", { className: "flex items-center gap-2 opacity-50", children: [_jsx(Loader2Icon, { className: "size-4 animate-spin text-muted-foreground" }), _jsx(WaitingElapsedTime, { startTime: streamingStartTime })] })), message.role === "
|
|
101
|
+
content = (_jsxs(_Fragment, { children: [message.role === "assistant" && hasThinking && (_jsx(Reasoning, { content: thinking, isStreaming: message.isStreaming, mode: thinkingDisplayStyle, autoCollapse: true })), isWaiting && streamingStartTime && (_jsxs("div", { className: "flex items-center gap-2 opacity-50", children: [_jsx(Loader2Icon, { className: "size-4 animate-spin text-muted-foreground" }), _jsx(WaitingElapsedTime, { startTime: streamingStartTime })] })), message.role === "assistant" &&
|
|
102
|
+
message.toolCalls &&
|
|
103
|
+
message.toolCalls.length > 0 && (_jsx("div", { className: "flex flex-col gap-2 mb-3", children: message.toolCalls.map((toolCall) => (_jsx(ToolCall, { toolCall: toolCall }, toolCall.id))) })), message.role === "user" ? (_jsx("div", { className: "whitespace-pre-wrap", children: message.content })) : (_jsx(Response, { content: message.content, isStreaming: message.isStreaming, showEmpty: false }))] }));
|
|
101
104
|
}
|
|
102
105
|
return (_jsx("div", { ref: ref, className: cn(messageContentVariants({ role, variant }), isStreaming && "animate-pulse-subtle", className), ...props, children: content }));
|
|
103
106
|
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
|
|
2
|
+
export interface ToolCallProps {
|
|
3
|
+
toolCall: ToolCallType;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* ToolCall component - displays a single tool call with collapsible details
|
|
7
|
+
*/
|
|
8
|
+
export declare function ToolCall({ toolCall }: ToolCallProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Wrench } from "lucide-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import ReactJson from "react-json-view";
|
|
5
|
+
/**
|
|
6
|
+
* Tool call status badge styles
|
|
7
|
+
*/
|
|
8
|
+
const statusStyles = {
|
|
9
|
+
pending: "bg-transparent text-muted-foreground",
|
|
10
|
+
in_progress: "bg-transparent text-muted-foreground",
|
|
11
|
+
completed: "bg-transparent text-muted-foreground",
|
|
12
|
+
failed: "bg-transparent text-muted-foreground",
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Tool call kind icons (using emoji for simplicity)
|
|
16
|
+
*/
|
|
17
|
+
const kindIcons = {
|
|
18
|
+
read: "\u{1F4C4}",
|
|
19
|
+
edit: "\u{270F}\u{FE0F}",
|
|
20
|
+
delete: "\u{1F5D1}\u{FE0F}",
|
|
21
|
+
move: "\u{1F4E6}",
|
|
22
|
+
search: "\u{1F50D}",
|
|
23
|
+
execute: "\u{2699}\u{FE0F}",
|
|
24
|
+
think: "\u{1F4AD}",
|
|
25
|
+
fetch: "\u{1F310}",
|
|
26
|
+
switch_mode: "\u{1F501}",
|
|
27
|
+
other: "\u{1F527}",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* ToolCall component - displays a single tool call with collapsible details
|
|
31
|
+
*/
|
|
32
|
+
export function ToolCall({ toolCall }) {
|
|
33
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
34
|
+
return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("button", { type: "button", className: "flex items-center gap-1.5 cursor-pointer bg-transparent border-none p-0 text-left group w-fit", onClick: () => setIsExpanded(!isExpanded), "aria-expanded": isExpanded, children: [_jsxs("span", { className: `inline-flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded ${statusStyles[toolCall.status]}`, children: [_jsx(Wrench, { className: "h-3 w-3" }), _jsx("span", { children: toolCall.title }), toolCall.status === "completed" && _jsx("span", { children: "\u2713" })] }), _jsx("span", { className: "text-gray-400 text-xs opacity-0 group-hover:opacity-100 transition-opacity", children: isExpanded ? "▲" : "▼" })] }), isExpanded && (_jsxs("div", { className: "mt-2 space-y-3 text-sm border border-gray-200 rounded-md p-3 bg-white shadow-sm max-w-full", children: [toolCall.locations && toolCall.locations.length > 0 && (_jsxs("div", { children: [_jsx("div", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5", children: "Files" }), _jsx("ul", { className: "space-y-1", children: toolCall.locations.map((loc) => (_jsxs("li", { className: "font-mono text-xs text-gray-700 bg-gray-50 px-2 py-1 rounded", children: [loc.path, loc.line !== null &&
|
|
35
|
+
loc.line !== undefined &&
|
|
36
|
+
`:${loc.line}`] }, `${loc.path}:${loc.line ?? ""}`))) })] })), toolCall.rawInput && Object.keys(toolCall.rawInput).length > 0 && (_jsxs("div", { children: [_jsx("div", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5", children: "Input" }), _jsx("div", { className: "bg-gray-50 p-2 rounded border border-gray-200", children: _jsx(ReactJson, { src: toolCall.rawInput, name: false, collapsed: 1, displayDataTypes: false, displayObjectSize: false, enableClipboard: true, style: { fontSize: "11px", backgroundColor: "transparent" }, theme: "rjv-default" }) })] })), toolCall.content && toolCall.content.length > 0 && (_jsxs("div", { children: [_jsx("div", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5", children: "Output" }), _jsx("div", { className: "space-y-2", children: toolCall.content.map((block, idx) => {
|
|
37
|
+
// Generate a stable key based on content
|
|
38
|
+
const getBlockKey = () => {
|
|
39
|
+
if (block.type === "diff" && "path" in block) {
|
|
40
|
+
return `diff-${block.path}-${idx}`;
|
|
41
|
+
}
|
|
42
|
+
if (block.type === "terminal" && "terminalId" in block) {
|
|
43
|
+
return `terminal-${block.terminalId}`;
|
|
44
|
+
}
|
|
45
|
+
if (block.type === "text" && "text" in block) {
|
|
46
|
+
return `text-${block.text.substring(0, 20)}-${idx}`;
|
|
47
|
+
}
|
|
48
|
+
if (block.type === "content" && "content" in block) {
|
|
49
|
+
const innerContent = block.content;
|
|
50
|
+
return `content-${innerContent.text?.substring(0, 20)}-${idx}`;
|
|
51
|
+
}
|
|
52
|
+
return `block-${idx}`;
|
|
53
|
+
};
|
|
54
|
+
// Helper to render text content (with JSON parsing if applicable)
|
|
55
|
+
const renderTextContent = (text, key) => {
|
|
56
|
+
// Try to parse as JSON
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(text);
|
|
59
|
+
// If it's an object or array, render with ReactJson
|
|
60
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
61
|
+
return (_jsx("div", { className: "bg-gray-50 p-2 rounded border border-gray-200", children: _jsx(ReactJson, { src: parsed, name: false, collapsed: 1, displayDataTypes: false, displayObjectSize: false, enableClipboard: true, style: {
|
|
62
|
+
fontSize: "11px",
|
|
63
|
+
backgroundColor: "transparent",
|
|
64
|
+
}, theme: "rjv-default" }) }, key));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Not valid JSON, render as plain text
|
|
69
|
+
}
|
|
70
|
+
// Render as plain text
|
|
71
|
+
return (_jsx("pre", { className: "bg-gray-50 p-2.5 rounded border border-gray-200 text-xs overflow-x-auto font-mono text-gray-800", children: text }, key));
|
|
72
|
+
};
|
|
73
|
+
// Handle nested content blocks (ACP format)
|
|
74
|
+
if (block.type === "content" && "content" in block) {
|
|
75
|
+
const innerContent = block.content;
|
|
76
|
+
if (innerContent.type === "text" && innerContent.text) {
|
|
77
|
+
return renderTextContent(innerContent.text, getBlockKey());
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Handle direct text blocks
|
|
81
|
+
if (block.type === "text" && "text" in block) {
|
|
82
|
+
return renderTextContent(block.text, getBlockKey());
|
|
83
|
+
}
|
|
84
|
+
// Handle diff blocks
|
|
85
|
+
if (block.type === "diff" &&
|
|
86
|
+
"path" in block &&
|
|
87
|
+
"oldText" in block &&
|
|
88
|
+
"newText" in block) {
|
|
89
|
+
return (_jsxs("div", { className: "border rounded", children: [_jsxs("div", { className: "bg-gray-100 px-2 py-1 text-xs font-mono", children: [block.path, "line" in block &&
|
|
90
|
+
block.line !== null &&
|
|
91
|
+
block.line !== undefined &&
|
|
92
|
+
`:${block.line}`] }), _jsxs("div", { className: "p-2 font-mono text-xs", children: [_jsxs("div", { className: "text-red-600", children: ["- ", block.oldText] }), _jsxs("div", { className: "text-green-600", children: ["+ ", block.newText] })] })] }, getBlockKey()));
|
|
93
|
+
}
|
|
94
|
+
// Handle terminal blocks
|
|
95
|
+
if (block.type === "terminal" && "terminalId" in block) {
|
|
96
|
+
return (_jsxs("div", { className: "bg-black text-green-400 p-2 rounded text-xs font-mono", children: ["Terminal: ", block.terminalId] }, getBlockKey()));
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}) })] })), toolCall.error && (_jsxs("div", { className: "bg-red-50 border border-red-200 rounded p-2.5 text-red-700", children: [_jsx("div", { className: "text-xs font-semibold text-red-600 uppercase tracking-wide mb-1.5", children: "Error" }), _jsx("div", { className: "text-xs", children: toolCall.error })] })), toolCall.tokenUsage && (_jsxs("div", { className: "bg-gray-50 border border-gray-200 rounded p-2.5", children: [_jsx("div", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2", children: "Token Usage" }), _jsxs("div", { className: "grid grid-cols-3 gap-3 text-xs text-gray-700", children: [toolCall.tokenUsage.inputTokens !== undefined && (_jsxs("div", { children: [_jsx("div", { className: "text-gray-500 text-[10px] uppercase tracking-wide mb-0.5", children: "Input" }), _jsx("div", { className: "font-medium", children: toolCall.tokenUsage.inputTokens.toLocaleString() })] })), toolCall.tokenUsage.outputTokens !== undefined && (_jsxs("div", { children: [_jsx("div", { className: "text-gray-500 text-[10px] uppercase tracking-wide mb-0.5", children: "Output" }), _jsx("div", { className: "font-medium", children: toolCall.tokenUsage.outputTokens.toLocaleString() })] })), toolCall.tokenUsage.totalTokens !== undefined && (_jsxs("div", { children: [_jsx("div", { className: "text-gray-500 text-[10px] uppercase tracking-wide mb-0.5", children: "Total" }), _jsx("div", { className: "font-medium", children: toolCall.tokenUsage.totalTokens.toLocaleString() })] }))] })] })), toolCall.startedAt && (_jsxs("div", { className: "text-xs text-gray-500", children: ["Started: ", new Date(toolCall.startedAt).toLocaleTimeString(), toolCall.completedAt && (_jsxs(_Fragment, { children: [" ", "| Completed:", " ", new Date(toolCall.completedAt).toLocaleTimeString(), " (", Math.round((toolCall.completedAt - toolCall.startedAt) / 1000), "s)"] }))] }))] }))] }));
|
|
100
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
|
|
2
|
+
export interface ToolCallListProps {
|
|
3
|
+
toolCalls: ToolCallType[];
|
|
4
|
+
groupBy?: "status" | "chronological";
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* ToolCallList component - renders a list of tool calls, optionally grouped
|
|
8
|
+
*/
|
|
9
|
+
export declare function ToolCallList({ toolCalls, groupBy, }: ToolCallListProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ToolCall } from "./ToolCall.js";
|
|
3
|
+
/**
|
|
4
|
+
* ToolCallList component - renders a list of tool calls, optionally grouped
|
|
5
|
+
*/
|
|
6
|
+
export function ToolCallList({ toolCalls, groupBy = "chronological", }) {
|
|
7
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
// Group by status if requested
|
|
11
|
+
if (groupBy === "status") {
|
|
12
|
+
const grouped = {
|
|
13
|
+
in_progress: toolCalls.filter((tc) => tc.status === "in_progress"),
|
|
14
|
+
pending: toolCalls.filter((tc) => tc.status === "pending"),
|
|
15
|
+
completed: toolCalls.filter((tc) => tc.status === "completed"),
|
|
16
|
+
failed: toolCalls.filter((tc) => tc.status === "failed"),
|
|
17
|
+
};
|
|
18
|
+
return (_jsxs("div", { className: "space-y-4", children: [grouped.in_progress.length > 0 && (_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-700 mb-2", children: "In Progress" }), grouped.in_progress.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), grouped.pending.length > 0 && (_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-700 mb-2", children: "Pending" }), grouped.pending.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), grouped.completed.length > 0 && (_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-700 mb-2", children: "Completed" }), grouped.completed.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), grouped.failed.length > 0 && (_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-700 mb-2", children: "Failed" }), grouped.failed.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] }))] }));
|
|
19
|
+
}
|
|
20
|
+
// Default: chronological order
|
|
21
|
+
return (_jsx("div", { className: "space-y-2", children: toolCalls.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id))) }));
|
|
22
|
+
}
|
|
@@ -29,3 +29,5 @@ export { Textarea, type TextareaProps, textareaVariants } from "./Textarea.js";
|
|
|
29
29
|
export { ThinkingBlock, type ThinkingBlockProps, } from "./ThinkingBlock.js";
|
|
30
30
|
export { TodoList, type TodoListProps } from "./TodoList.js";
|
|
31
31
|
export { type TodoItem, TodoListItem, type TodoListItemProps, } from "./TodoListItem.js";
|
|
32
|
+
export { ToolCall, type ToolCallProps } from "./ToolCall.js";
|
|
33
|
+
export { ToolCallList, type ToolCallListProps } from "./ToolCallList.js";
|
|
@@ -36,3 +36,5 @@ export { Textarea, textareaVariants } from "./Textarea.js";
|
|
|
36
36
|
export { ThinkingBlock, } from "./ThinkingBlock.js";
|
|
37
37
|
export { TodoList } from "./TodoList.js";
|
|
38
38
|
export { TodoListItem, } from "./TodoListItem.js";
|
|
39
|
+
export { ToolCall } from "./ToolCall.js";
|
|
40
|
+
export { ToolCallList } from "./ToolCallList.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
2
|
+
declare const ResizablePanelGroup: ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare const ResizablePanel: ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.Panel>) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
declare const ResizableHandle: ({ withHandle, className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
|
5
|
+
withHandle?: boolean;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
const ResizablePanelGroup = ({ className, ...props }) => (_jsx(ResizablePrimitive.PanelGroup, { className: cn("flex h-full w-full data-[panel-group-direction=vertical]:flex-col", className), ...props }));
|
|
5
|
+
const ResizablePanel = ({ className, ...props }) => (_jsx(ResizablePrimitive.Panel, { className: cn(className), ...props }));
|
|
6
|
+
const ResizableHandle = ({ withHandle, className, ...props }) => (_jsx(ResizablePrimitive.PanelResizeHandle, { className: cn("relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90", className), ...props, children: withHandle && (_jsx("div", { className: "z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-2.5 w-2.5", children: [_jsx("title", { children: "Resize Handle" }), _jsx("circle", { cx: "9", cy: "12", r: "1" }), _jsx("circle", { cx: "9", cy: "5", r: "1" }), _jsx("circle", { cx: "9", cy: "19", r: "1" }), _jsx("circle", { cx: "15", cy: "12", r: "1" }), _jsx("circle", { cx: "15", cy: "5", r: "1" }), _jsx("circle", { cx: "15", cy: "19", r: "1" })] }) })) }));
|
|
7
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|