@townco/ui 0.1.37 → 0.1.39
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/use-chat-messages.d.ts +2 -0
- package/dist/core/hooks/use-chat-messages.js +19 -1
- package/dist/core/hooks/use-tool-calls.d.ts +2 -0
- package/dist/core/lib/logger.d.ts +0 -35
- package/dist/core/lib/logger.js +25 -108
- package/dist/core/schemas/chat.d.ts +4 -0
- package/dist/core/schemas/tool-call.d.ts +2 -0
- package/dist/core/schemas/tool-call.js +4 -0
- package/dist/gui/components/ChatEmptyState.d.ts +6 -0
- package/dist/gui/components/ChatEmptyState.js +2 -2
- package/dist/gui/components/ChatInput.js +1 -1
- package/dist/gui/components/ChatLayout.js +102 -8
- package/dist/gui/components/ChatPanelTabContent.d.ts +1 -1
- package/dist/gui/components/ChatPanelTabContent.js +10 -3
- package/dist/gui/components/ChatView.js +37 -13
- package/dist/gui/components/ContextUsageButton.d.ts +7 -0
- package/dist/gui/components/ContextUsageButton.js +18 -0
- package/dist/gui/components/FileSystemItem.js +6 -7
- package/dist/gui/components/FileSystemView.js +3 -3
- package/dist/gui/components/InlineToolCallSummary.d.ts +14 -0
- package/dist/gui/components/InlineToolCallSummary.js +110 -0
- package/dist/gui/components/InlineToolCallSummaryACP.d.ts +15 -0
- package/dist/gui/components/InlineToolCallSummaryACP.js +90 -0
- package/dist/gui/components/Response.js +2 -2
- package/dist/gui/components/SourceListItem.js +9 -1
- package/dist/gui/components/TodoListItem.js +19 -2
- package/dist/gui/components/ToolCall.js +21 -2
- package/dist/gui/components/Tooltip.d.ts +7 -0
- package/dist/gui/components/Tooltip.js +10 -0
- package/dist/gui/components/index.d.ts +4 -0
- package/dist/gui/components/index.js +5 -0
- package/dist/gui/components/tool-call-summary.d.ts +44 -0
- package/dist/gui/components/tool-call-summary.js +67 -0
- package/dist/gui/data/mockSourceData.d.ts +10 -0
- package/dist/gui/data/mockSourceData.js +40 -0
- package/dist/gui/data/mockTodoData.d.ts +10 -0
- package/dist/gui/data/mockTodoData.js +35 -0
- package/dist/gui/examples/FileSystemDemo.d.ts +5 -0
- package/dist/gui/examples/FileSystemDemo.js +24 -0
- package/dist/gui/examples/FileSystemExample.d.ts +17 -0
- package/dist/gui/examples/FileSystemExample.js +94 -0
- package/dist/sdk/schemas/session.d.ts +2 -0
- package/dist/sdk/transports/http.js +12 -0
- package/dist/sdk/transports/stdio.js +13 -0
- package/package.json +4 -3
- package/dist/tui/components/LogsPanel.d.ts +0 -5
- package/dist/tui/components/LogsPanel.js +0 -29
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool call summary data from the /summarize endpoint
|
|
3
|
+
*/
|
|
4
|
+
export interface ToolCallSummary {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
input: Record<string, unknown>;
|
|
9
|
+
output?: string | undefined;
|
|
10
|
+
status: "pending" | "completed" | "error";
|
|
11
|
+
error?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface SummaryResponse {
|
|
14
|
+
summary: {
|
|
15
|
+
total: number;
|
|
16
|
+
byStatus: Record<string, number>;
|
|
17
|
+
byTool: Record<string, number>;
|
|
18
|
+
};
|
|
19
|
+
toolCalls: ToolCallSummary[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Props for ToolCallSummaryDisplay component
|
|
23
|
+
*/
|
|
24
|
+
export interface ToolCallSummaryDisplayProps {
|
|
25
|
+
/** ACP server URL */
|
|
26
|
+
serverUrl: string;
|
|
27
|
+
/** Anthropic API request (messages with tool calls) */
|
|
28
|
+
request: {
|
|
29
|
+
model?: string;
|
|
30
|
+
messages: Array<{
|
|
31
|
+
role: "user" | "assistant";
|
|
32
|
+
content: string | Array<{
|
|
33
|
+
type: string;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
/** Custom className for styling */
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Display a summary of tool calls from an Anthropic API request
|
|
43
|
+
*/
|
|
44
|
+
export declare function ToolCallSummaryDisplay({ serverUrl, request, className, }: ToolCallSummaryDisplayProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createLogger } from "@townco/core";
|
|
3
|
+
import { AlertCircle, CheckCircle, Clock, Loader2, RefreshCw, } from "lucide-react";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { cn } from "../lib/utils";
|
|
6
|
+
const logger = createLogger("tool-call-summary");
|
|
7
|
+
/**
|
|
8
|
+
* Display a summary of tool calls from an Anthropic API request
|
|
9
|
+
*/
|
|
10
|
+
export function ToolCallSummaryDisplay({ serverUrl, request, className, }) {
|
|
11
|
+
const [summary, setSummary] = useState(null);
|
|
12
|
+
const [loading, setLoading] = useState(false);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const fetchSummary = async () => {
|
|
15
|
+
setLoading(true);
|
|
16
|
+
setError(null);
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(`${serverUrl}/summarize`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify(request),
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const errorData = await response.json();
|
|
27
|
+
throw new Error(errorData.error || "Failed to fetch summary");
|
|
28
|
+
}
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
setSummary(data);
|
|
31
|
+
logger.info("Tool call summary fetched", {
|
|
32
|
+
total: data.summary.total,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
37
|
+
setError(message);
|
|
38
|
+
logger.error("Failed to fetch tool call summary", { error: message });
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
setLoading(false);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
// Fetch summary on mount and when request changes
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
fetchSummary();
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [serverUrl, request]);
|
|
49
|
+
if (loading && !summary) {
|
|
50
|
+
return (_jsxs("div", { className: cn("flex items-center justify-center p-4 text-muted-foreground", className), children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), _jsx("span", { className: "text-paragraph-sm", children: "Loading summary..." })] }));
|
|
51
|
+
}
|
|
52
|
+
if (error) {
|
|
53
|
+
return (_jsx("div", { className: cn("rounded-lg border border-destructive/20 p-4", className), children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 text-destructive shrink-0 mt-0.5" }), _jsxs("div", { className: "flex-1", children: [_jsx("p", { className: "text-paragraph-sm font-medium text-destructive", children: "Error loading summary" }), _jsx("p", { className: "text-paragraph-sm text-muted-foreground mt-1", children: error })] }), _jsx("button", { type: "button", onClick: fetchSummary, className: "text-muted-foreground hover:text-foreground transition-colors", children: _jsx(RefreshCw, { className: "h-4 w-4" }) })] }) }));
|
|
54
|
+
}
|
|
55
|
+
if (!summary || summary.summary.total === 0) {
|
|
56
|
+
return (_jsx("div", { className: cn("flex items-center justify-center p-4 text-muted-foreground", className), children: _jsx("span", { className: "text-paragraph-sm", children: "No tool calls found" }) }));
|
|
57
|
+
}
|
|
58
|
+
return (_jsxs("div", { className: cn("space-y-4", className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("h3", { className: "text-heading-5 font-semibold", children: ["Tool Calls (", summary.summary.total, ")"] }), _jsx("button", { type: "button", onClick: fetchSummary, disabled: loading, className: "text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50", children: _jsx(RefreshCw, { className: cn("h-4 w-4", loading && "animate-spin") }) })] }), _jsxs("div", { className: "flex gap-4", children: [(summary.summary.byStatus.completed ?? 0) > 0 && (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(CheckCircle, { className: "h-4 w-4 text-success" }), _jsxs("span", { className: "text-paragraph-sm text-muted-foreground", children: [summary.summary.byStatus.completed, " completed"] })] })), (summary.summary.byStatus.pending ?? 0) > 0 && (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Clock, { className: "h-4 w-4 text-warning" }), _jsxs("span", { className: "text-paragraph-sm text-muted-foreground", children: [summary.summary.byStatus.pending, " pending"] })] })), (summary.summary.byStatus.error ?? 0) > 0 && (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(AlertCircle, { className: "h-4 w-4 text-destructive" }), _jsxs("span", { className: "text-paragraph-sm text-muted-foreground", children: [summary.summary.byStatus.error, " errors"] })] }))] }), _jsx("div", { className: "space-y-2", children: summary.toolCalls.map((toolCall) => (_jsx(ToolCallSummaryItem, { toolCall: toolCall }, toolCall.id))) })] }));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Display a single tool call summary
|
|
62
|
+
*/
|
|
63
|
+
function ToolCallSummaryItem({ toolCall }) {
|
|
64
|
+
const [expanded, setExpanded] = useState(false);
|
|
65
|
+
const statusIcon = toolCall.status === "completed" ? (_jsx(CheckCircle, { className: "h-4 w-4 text-success" })) : toolCall.status === "error" ? (_jsx(AlertCircle, { className: "h-4 w-4 text-destructive" })) : (_jsx(Clock, { className: "h-4 w-4 text-warning" }));
|
|
66
|
+
return (_jsxs("div", { className: "rounded-lg border border-border bg-card p-3 space-y-2", children: [_jsxs("button", { type: "button", onClick: () => setExpanded(!expanded), className: "flex items-start gap-2 w-full text-left", children: [statusIcon, _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-paragraph-sm font-medium text-foreground truncate", children: toolCall.description }), _jsx("p", { className: "text-paragraph-xs text-muted-foreground", children: toolCall.name })] })] }), expanded && (_jsxs("div", { className: "pl-6 space-y-2", children: [Object.keys(toolCall.input).length > 0 && (_jsxs("div", { children: [_jsx("p", { className: "text-paragraph-xs font-medium text-muted-foreground mb-1", children: "Input:" }), _jsx("pre", { className: "text-paragraph-xs bg-muted p-2 rounded overflow-x-auto", children: JSON.stringify(toolCall.input, null, 2) })] })), toolCall.output && (_jsxs("div", { children: [_jsx("p", { className: "text-paragraph-xs font-medium text-muted-foreground mb-1", children: "Output:" }), _jsx("pre", { className: "text-paragraph-xs bg-muted p-2 rounded overflow-x-auto", children: toolCall.output })] })), toolCall.error && (_jsxs("div", { children: [_jsx("p", { className: "text-paragraph-xs font-medium text-destructive mb-1", children: "Error:" }), _jsx("p", { className: "text-paragraph-xs text-destructive bg-destructive/10 p-2 rounded", children: toolCall.error })] }))] }))] }));
|
|
67
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock source data - stub implementation
|
|
3
|
+
* Replace this with real source data from agent later
|
|
4
|
+
*/
|
|
5
|
+
import type { SourceItem } from "../components/SourceListItem.js";
|
|
6
|
+
/**
|
|
7
|
+
* Stub source data
|
|
8
|
+
* This data can be easily replaced with real sources from the agent
|
|
9
|
+
*/
|
|
10
|
+
export declare const mockSourceData: SourceItem[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock source data - stub implementation
|
|
3
|
+
* Replace this with real source data from agent later
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Stub source data
|
|
7
|
+
* This data can be easily replaced with real sources from the agent
|
|
8
|
+
*/
|
|
9
|
+
export const mockSourceData = [
|
|
10
|
+
{
|
|
11
|
+
id: "1",
|
|
12
|
+
title: "Boeing Scores Early Wins at Dubai Airshow",
|
|
13
|
+
url: "https://www.reuters.com/business/aerospace-defense/boeing-scores-early-wins-dubai-airshow-2024-11-17",
|
|
14
|
+
snippet: "DUBAI, Nov 17 (Reuters) - Boeing (BA.N), opens new tab took centre stage at day one of the Dubai Airshow on Monday, booking a $38 billion order from host carrier Emirates and clinching more deals with African carriers, while China displayed its C919 in the Middle East for the first time.",
|
|
15
|
+
sourceName: "Reuters",
|
|
16
|
+
favicon: "https://www.reuters.com/favicon.ico",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "2",
|
|
20
|
+
title: "Boeing's Sustainable Aviation Goals Take Flight",
|
|
21
|
+
url: "https://www.forbes.com/boeing-sustainability",
|
|
22
|
+
snippet: "SEATTLE, Nov 18 (Reuters) - Boeing is making headway towards its sustainability targets, unveiling plans for a new eco-friendly aircraft design aimed at reducing emissions by 50% by 2030.",
|
|
23
|
+
sourceName: "Forbes",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "3",
|
|
27
|
+
title: "Boeing Faces Increased Competition in Global Aviation Market",
|
|
28
|
+
url: "https://www.reuters.com/business/aerospace-defense/boeing-competition-2024-11-19",
|
|
29
|
+
snippet: "CHICAGO, Nov 19 (Reuters) - As the global aviation industry rebounds post-pandemic, Boeing is grappling with intensified competition from rival manufacturers, particularly in the Asian market.",
|
|
30
|
+
sourceName: "Reuters",
|
|
31
|
+
favicon: "https://www.reuters.com/favicon.ico",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "4",
|
|
35
|
+
title: "Boeing's Starliner Successfully Completes Orbital Test Flight",
|
|
36
|
+
url: "https://www.theverge.com/boeing-starliner",
|
|
37
|
+
snippet: "NASA, Nov 20 (Reuters) - Boeing's CST-100 Starliner spacecraft achieves a significant milestone, successfully completing its orbital test flight, paving the way for future crewed missions to the International Space Station.",
|
|
38
|
+
sourceName: "The Verge",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock todo data - stub implementation
|
|
3
|
+
* Replace this with real todo data from agent/store later
|
|
4
|
+
*/
|
|
5
|
+
import type { TodoItem } from "../components/TodoListItem.js";
|
|
6
|
+
/**
|
|
7
|
+
* Stub todo data
|
|
8
|
+
* This data can be easily replaced with real todo queries from the agent
|
|
9
|
+
*/
|
|
10
|
+
export declare const mockTodoData: TodoItem[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock todo data - stub implementation
|
|
3
|
+
* Replace this with real todo data from agent/store later
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Stub todo data
|
|
7
|
+
* This data can be easily replaced with real todo queries from the agent
|
|
8
|
+
*/
|
|
9
|
+
export const mockTodoData = [
|
|
10
|
+
{
|
|
11
|
+
id: "todo-1",
|
|
12
|
+
text: "Review filesystem implementation",
|
|
13
|
+
status: "completed",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "todo-2",
|
|
17
|
+
text: "Add overflow menu actions",
|
|
18
|
+
status: "in_progress",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "todo-3",
|
|
22
|
+
text: "Connect to real filesystem API",
|
|
23
|
+
status: "pending",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "todo-4",
|
|
27
|
+
text: "Implement drag and drop support",
|
|
28
|
+
status: "pending",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "todo-5",
|
|
32
|
+
text: "Add file preview functionality",
|
|
33
|
+
status: "pending",
|
|
34
|
+
},
|
|
35
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* FileSystemDemo - A demo page showcasing the FileSystemView component
|
|
4
|
+
* Can be integrated into the GUI app for testing and demonstration
|
|
5
|
+
*/
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { FileSystemView } from "../components/FileSystemView.js";
|
|
8
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/Card.js";
|
|
9
|
+
export function FileSystemDemo() {
|
|
10
|
+
const [selectedItem, setSelectedItem] = React.useState(null);
|
|
11
|
+
const handleDownload = (item) => {
|
|
12
|
+
console.log("Download:", item.name);
|
|
13
|
+
// Implement download logic
|
|
14
|
+
};
|
|
15
|
+
const handleRename = (item) => {
|
|
16
|
+
console.log("Rename:", item.name);
|
|
17
|
+
// Implement rename logic
|
|
18
|
+
};
|
|
19
|
+
const handleDelete = (item) => {
|
|
20
|
+
console.log("Delete:", item.name);
|
|
21
|
+
// Implement delete logic
|
|
22
|
+
};
|
|
23
|
+
return (_jsx("div", { className: "w-full h-full p-8 bg-background", children: _jsxs("div", { className: "max-w-7xl mx-auto space-y-6", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "File Manager" }), _jsx("p", { className: "text-muted-foreground mt-2", children: "A hierarchical file system view with stub data. Replace the MockFileSystemProvider with a real implementation to connect to actual filesystem data." })] }), _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [_jsxs(Card, { className: "lg:col-span-2", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Files" }), _jsx(CardDescription, { children: "Browse files and folders. Click folders to expand/collapse." })] }), _jsx(CardContent, { className: "p-0", children: _jsx(FileSystemView, { onItemSelect: setSelectedItem, onDownload: handleDownload, onRename: handleRename, onDelete: handleDelete, className: "max-h-[600px] overflow-y-auto" }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Details" }), _jsx(CardDescription, { children: "Information about the selected item" })] }), _jsx(CardContent, { children: selectedItem ? (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Name" }), _jsx("p", { className: "text-base font-mono", children: selectedItem.name })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Type" }), _jsx("p", { className: "text-base capitalize", children: selectedItem.type })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "ID" }), _jsx("p", { className: "text-base font-mono text-xs", children: selectedItem.id })] }), selectedItem.extension && (_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Extension" }), _jsxs("p", { className: "text-base", children: [".", selectedItem.extension] })] })), selectedItem.children && (_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Children" }), _jsxs("p", { className: "text-base", children: [selectedItem.children.length, " item(s)"] })] })), selectedItem.path && (_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Path" }), _jsx("p", { className: "text-base font-mono text-xs", children: selectedItem.path })] }))] })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: "Select a file or folder to view details" })) })] })] }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: "Implementation Notes" }) }), _jsxs(CardContent, { className: "space-y-2 text-sm", children: [_jsxs("p", { children: [_jsx("strong", { children: "Stub System:" }), " Currently using ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "MockFileSystemProvider" }), " with hardcoded data."] }), _jsxs("p", { children: [_jsx("strong", { children: "Easy Replacement:" }), " Implement the ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded", children: "FileSystemProvider" }), " ", "interface to connect to real data sources."] }), _jsxs("p", { children: [_jsx("strong", { children: "Design:" }), " Based on shadcn file manager components and Figma specifications."] })] })] })] }) }));
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example usage of FileSystemView component
|
|
3
|
+
* This demonstrates how to use the stub filesystem and how to replace it with real data
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Basic usage with default mock data
|
|
7
|
+
*/
|
|
8
|
+
export declare function BasicFileSystemExample(): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Custom mock data example
|
|
11
|
+
* Shows how to create custom stub data
|
|
12
|
+
*/
|
|
13
|
+
export declare function CustomDataExample(): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
/**
|
|
15
|
+
* Example with real provider (commented out to avoid actual API calls)
|
|
16
|
+
*/
|
|
17
|
+
export declare function RealDataExample(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Example usage of FileSystemView component
|
|
4
|
+
* This demonstrates how to use the stub filesystem and how to replace it with real data
|
|
5
|
+
*/
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { FileSystemView } from "../components/FileSystemView.js";
|
|
8
|
+
import { MockFileSystemProvider } from "../data/mockFileSystemData.js";
|
|
9
|
+
/**
|
|
10
|
+
* Basic usage with default mock data
|
|
11
|
+
*/
|
|
12
|
+
export function BasicFileSystemExample() {
|
|
13
|
+
return (_jsx("div", { className: "w-full h-full bg-background", children: _jsx(FileSystemView, { onItemSelect: (item) => {
|
|
14
|
+
console.log("Selected:", item);
|
|
15
|
+
} }) }));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Custom mock data example
|
|
19
|
+
* Shows how to create custom stub data
|
|
20
|
+
*/
|
|
21
|
+
export function CustomDataExample() {
|
|
22
|
+
const customData = [
|
|
23
|
+
{
|
|
24
|
+
id: "src",
|
|
25
|
+
name: "src",
|
|
26
|
+
type: "folder",
|
|
27
|
+
children: [
|
|
28
|
+
{
|
|
29
|
+
id: "components",
|
|
30
|
+
name: "components",
|
|
31
|
+
type: "folder",
|
|
32
|
+
children: [
|
|
33
|
+
{ id: "button", name: "Button.tsx", type: "file", extension: "tsx" },
|
|
34
|
+
{ id: "card", name: "Card.tsx", type: "file", extension: "tsx" },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{ id: "app", name: "App.tsx", type: "file", extension: "tsx" },
|
|
38
|
+
{ id: "index", name: "index.ts", type: "file", extension: "ts" },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "public",
|
|
43
|
+
name: "public",
|
|
44
|
+
type: "folder",
|
|
45
|
+
children: [
|
|
46
|
+
{ id: "favicon", name: "favicon.ico", type: "file" },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const customProvider = new MockFileSystemProvider(customData);
|
|
51
|
+
return (_jsx("div", { className: "w-full h-full bg-background", children: _jsx(FileSystemView, { provider: customProvider, onItemSelect: (item) => {
|
|
52
|
+
console.log("Selected:", item);
|
|
53
|
+
} }) }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Example of how to implement a real FileSystemProvider
|
|
57
|
+
* Replace MockFileSystemProvider with this when connecting to real data
|
|
58
|
+
*/
|
|
59
|
+
class RealFileSystemProvider {
|
|
60
|
+
apiUrl;
|
|
61
|
+
constructor(apiUrl) {
|
|
62
|
+
this.apiUrl = apiUrl;
|
|
63
|
+
}
|
|
64
|
+
async getRootItems() {
|
|
65
|
+
// Replace with actual API call
|
|
66
|
+
const response = await fetch(`${this.apiUrl}/filesystem/root`);
|
|
67
|
+
return response.json();
|
|
68
|
+
}
|
|
69
|
+
async getItemChildren(itemId) {
|
|
70
|
+
// Replace with actual API call
|
|
71
|
+
const response = await fetch(`${this.apiUrl}/filesystem/items/${itemId}/children`);
|
|
72
|
+
return response.json();
|
|
73
|
+
}
|
|
74
|
+
async getItemDetails(itemId) {
|
|
75
|
+
// Replace with actual API call
|
|
76
|
+
const response = await fetch(`${this.apiUrl}/filesystem/items/${itemId}`);
|
|
77
|
+
return response.json();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Example with real provider (commented out to avoid actual API calls)
|
|
82
|
+
*/
|
|
83
|
+
export function RealDataExample() {
|
|
84
|
+
// Uncomment and configure when ready to use real data:
|
|
85
|
+
// const realProvider = new RealFileSystemProvider('https://your-api.com');
|
|
86
|
+
return (_jsx("div", { className: "w-full h-full bg-background", children: _jsx(FileSystemView
|
|
87
|
+
// provider={realProvider}
|
|
88
|
+
, {
|
|
89
|
+
// provider={realProvider}
|
|
90
|
+
onItemSelect: (item) => {
|
|
91
|
+
console.log("Selected:", item);
|
|
92
|
+
// Handle file selection - open file, show details, etc.
|
|
93
|
+
} }) }));
|
|
94
|
+
}
|
|
@@ -158,6 +158,8 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
158
158
|
toolCall: z.ZodObject<{
|
|
159
159
|
id: z.ZodString;
|
|
160
160
|
title: z.ZodString;
|
|
161
|
+
prettyName: z.ZodOptional<z.ZodString>;
|
|
162
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
161
163
|
kind: z.ZodEnum<{
|
|
162
164
|
read: "read";
|
|
163
165
|
edit: "edit";
|
|
@@ -519,10 +519,22 @@ export class HttpTransport {
|
|
|
519
519
|
"messageId" in update._meta
|
|
520
520
|
? String(update._meta.messageId)
|
|
521
521
|
: undefined;
|
|
522
|
+
const prettyName = update._meta &&
|
|
523
|
+
typeof update._meta === "object" &&
|
|
524
|
+
"prettyName" in update._meta
|
|
525
|
+
? String(update._meta.prettyName)
|
|
526
|
+
: undefined;
|
|
527
|
+
const icon = update._meta &&
|
|
528
|
+
typeof update._meta === "object" &&
|
|
529
|
+
"icon" in update._meta
|
|
530
|
+
? String(update._meta.icon)
|
|
531
|
+
: undefined;
|
|
522
532
|
// Initial tool call notification
|
|
523
533
|
const toolCall = {
|
|
524
534
|
id: update.toolCallId ?? "",
|
|
525
535
|
title: update.title ?? "",
|
|
536
|
+
prettyName,
|
|
537
|
+
icon,
|
|
526
538
|
kind: update.kind || "other",
|
|
527
539
|
status: update.status || "pending",
|
|
528
540
|
locations: update.locations,
|
|
@@ -60,10 +60,23 @@ export class StdioTransport {
|
|
|
60
60
|
const sessionId = self.currentSessionId || params.sessionId;
|
|
61
61
|
// Handle ACP tool call notifications
|
|
62
62
|
if (update?.sessionUpdate === "tool_call") {
|
|
63
|
+
// Extract prettyName and icon from _meta
|
|
64
|
+
const prettyName = update._meta &&
|
|
65
|
+
typeof update._meta === "object" &&
|
|
66
|
+
"prettyName" in update._meta
|
|
67
|
+
? String(update._meta.prettyName)
|
|
68
|
+
: undefined;
|
|
69
|
+
const icon = update._meta &&
|
|
70
|
+
typeof update._meta === "object" &&
|
|
71
|
+
"icon" in update._meta
|
|
72
|
+
? String(update._meta.icon)
|
|
73
|
+
: undefined;
|
|
63
74
|
// Initial tool call notification
|
|
64
75
|
const toolCall = {
|
|
65
76
|
id: update.toolCallId ?? "",
|
|
66
77
|
title: update.title ?? "",
|
|
78
|
+
prettyName,
|
|
79
|
+
icon,
|
|
67
80
|
kind: update.kind || "other",
|
|
68
81
|
status: update.status || "pending",
|
|
69
82
|
locations: update.locations,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@townco/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@agentclientprotocol/sdk": "^0.5.1",
|
|
43
|
-
"@townco/core": "0.0.
|
|
43
|
+
"@townco/core": "0.0.17",
|
|
44
44
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
45
45
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
46
46
|
"@radix-ui/react-label": "^2.1.8",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"lucide-react": "^0.552.0",
|
|
55
55
|
"react-markdown": "^10.1.0",
|
|
56
56
|
"react-resizable-panels": "^3.0.6",
|
|
57
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
57
58
|
"remark-gfm": "^4.0.1",
|
|
58
59
|
"sonner": "^2.0.7",
|
|
59
60
|
"tailwind-merge": "^3.3.1",
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
65
|
"@tailwindcss/postcss": "^4.1.17",
|
|
65
|
-
"@townco/tsconfig": "0.1.
|
|
66
|
+
"@townco/tsconfig": "0.1.36",
|
|
66
67
|
"@types/node": "^24.10.0",
|
|
67
68
|
"@types/react": "^19.2.2",
|
|
68
69
|
"ink": "^6.4.0",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import { subscribeToLogs } from "../../core/lib/logger.js";
|
|
5
|
-
// Color mapping for log levels
|
|
6
|
-
const LOG_LEVEL_COLORS = {
|
|
7
|
-
trace: "gray",
|
|
8
|
-
debug: "blue",
|
|
9
|
-
info: "green",
|
|
10
|
-
warn: "yellow",
|
|
11
|
-
error: "red",
|
|
12
|
-
fatal: "red",
|
|
13
|
-
};
|
|
14
|
-
export function LogsPanel({ logs: initialLogs }) {
|
|
15
|
-
const [logs, setLogs] = useState(initialLogs);
|
|
16
|
-
// Subscribe to new logs
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
const unsubscribe = subscribeToLogs((entry) => {
|
|
19
|
-
setLogs((prev) => [...prev, entry]);
|
|
20
|
-
});
|
|
21
|
-
return unsubscribe;
|
|
22
|
-
}, []);
|
|
23
|
-
if (logs.length === 0) {
|
|
24
|
-
return (_jsx(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: _jsx(Text, { dimColor: true, children: "No logs yet..." }) }));
|
|
25
|
-
}
|
|
26
|
-
// Show last 100 logs
|
|
27
|
-
const displayLogs = logs.slice(-100);
|
|
28
|
-
return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: displayLogs.map((log) => (_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { dimColor: true, children: new Date(log.timestamp).toLocaleTimeString() }), _jsxs(Text, { color: LOG_LEVEL_COLORS[log.level], bold: true, children: ["[", log.level.toUpperCase(), "]"] }), _jsxs(Text, { dimColor: true, children: ["[", log.service, "]"] }), _jsx(Text, { children: log.message }), log.metadata && (_jsx(Text, { dimColor: true, children: JSON.stringify(log.metadata) }))] }, log.id))) }));
|
|
29
|
-
}
|