sonance-brand-mcp 1.3.110 → 1.3.111
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/assets/api/sonance-ai-edit/route.ts +30 -7
- package/dist/assets/api/sonance-vision-apply/route.ts +33 -8
- package/dist/assets/api/sonance-vision-edit/route.ts +33 -8
- package/dist/assets/dev-tools/SonanceDevTools.tsx +441 -365
- package/dist/assets/dev-tools/components/ChatHistory.tsx +141 -0
- package/dist/assets/dev-tools/components/ChatInterface.tsx +402 -294
- package/dist/assets/dev-tools/components/ChatTabBar.tsx +82 -0
- package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +204 -0
- package/dist/assets/dev-tools/components/InspectorOverlay.tsx +12 -9
- package/dist/assets/dev-tools/components/PropertiesPanel.tsx +695 -0
- package/dist/assets/dev-tools/components/VisionModeBorder.tsx +16 -7
- package/dist/assets/dev-tools/constants.ts +38 -6
- package/dist/assets/dev-tools/hooks/useComputedStyles.ts +365 -0
- package/dist/assets/dev-tools/index.ts +3 -0
- package/dist/assets/dev-tools/panels/AnalysisPanel.tsx +32 -32
- package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +277 -127
- package/dist/assets/dev-tools/types.ts +51 -2
- package/dist/index.js +22 -3
- package/package.json +2 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useRef, useEffect } from "react";
|
|
4
|
+
import { User, Bot, AlertCircle, CheckCircle, RotateCcw } from "lucide-react";
|
|
5
|
+
import { cn } from "../../../lib/utils";
|
|
6
|
+
import { ChatMessage } from "../types";
|
|
7
|
+
import { InlineDiffPreview } from "./InlineDiffPreview";
|
|
8
|
+
|
|
9
|
+
export interface ChatHistoryProps {
|
|
10
|
+
messages: ChatMessage[];
|
|
11
|
+
onAcceptChanges?: (messageId: string) => void;
|
|
12
|
+
onRevertChanges?: (messageId: string) => void;
|
|
13
|
+
visionMode?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function ChatHistory({
|
|
17
|
+
messages,
|
|
18
|
+
onAcceptChanges,
|
|
19
|
+
onRevertChanges,
|
|
20
|
+
visionMode = false,
|
|
21
|
+
}: ChatHistoryProps) {
|
|
22
|
+
const scrollRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
const bottomRef = useRef<HTMLDivElement>(null);
|
|
24
|
+
|
|
25
|
+
// Auto-scroll to bottom when new messages arrive
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
28
|
+
}, [messages]);
|
|
29
|
+
|
|
30
|
+
// Format timestamp
|
|
31
|
+
const formatTime = (date: Date) => {
|
|
32
|
+
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (messages.length === 0) {
|
|
36
|
+
return null; // Empty state is handled by parent
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
ref={scrollRef}
|
|
42
|
+
className="flex-1 overflow-y-auto px-3 py-4 space-y-4 bg-background"
|
|
43
|
+
style={{ overscrollBehavior: "contain" }}
|
|
44
|
+
>
|
|
45
|
+
{messages.map((message, index) => (
|
|
46
|
+
<div
|
|
47
|
+
key={message.id}
|
|
48
|
+
className={cn(
|
|
49
|
+
"flex gap-3 animate-in fade-in-0 slide-in-from-bottom-2",
|
|
50
|
+
message.role === "system" && "justify-center"
|
|
51
|
+
)}
|
|
52
|
+
style={{ animationDelay: `${Math.min(index * 30, 150)}ms` }}
|
|
53
|
+
>
|
|
54
|
+
{/* Avatar */}
|
|
55
|
+
{message.role !== "system" && (
|
|
56
|
+
<div
|
|
57
|
+
className={cn(
|
|
58
|
+
"flex-shrink-0 w-7 h-7 rounded-full flex items-center justify-center",
|
|
59
|
+
message.role === "user"
|
|
60
|
+
? "bg-gradient-to-br from-[#00A3E1] to-[#0090c8]"
|
|
61
|
+
: "bg-gradient-to-br from-gray-200 to-gray-300 dark:from-gray-600 dark:to-gray-700"
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
{message.role === "user" ? (
|
|
65
|
+
<User className="h-3.5 w-3.5 text-white" />
|
|
66
|
+
) : (
|
|
67
|
+
<Bot className="h-3.5 w-3.5 text-gray-600 dark:text-gray-300" />
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
|
|
72
|
+
{/* Message Content */}
|
|
73
|
+
<div className={cn("flex-1 min-w-0", message.role === "system" && "text-center")}>
|
|
74
|
+
{/* Role Label + Timestamp */}
|
|
75
|
+
{message.role !== "system" && (
|
|
76
|
+
<div className="flex items-center gap-2 mb-1">
|
|
77
|
+
<span className="text-[11px] font-semibold text-foreground">
|
|
78
|
+
{message.role === "user" ? "You" : "AI Assistant"}
|
|
79
|
+
</span>
|
|
80
|
+
<span className="text-[10px] text-foreground-muted">
|
|
81
|
+
{formatTime(message.timestamp)}
|
|
82
|
+
</span>
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
{/* Message Text */}
|
|
87
|
+
<div
|
|
88
|
+
className={cn(
|
|
89
|
+
"text-sm leading-relaxed",
|
|
90
|
+
message.role === "user" && "text-foreground",
|
|
91
|
+
message.role === "assistant" && "text-foreground-secondary",
|
|
92
|
+
message.role === "system" && "text-xs text-foreground-muted italic"
|
|
93
|
+
)}
|
|
94
|
+
>
|
|
95
|
+
<p className="whitespace-pre-wrap">{message.content}</p>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
{/* Inline Diff Preview for actions */}
|
|
99
|
+
{message.action && message.action.files && message.action.files.length > 0 && (
|
|
100
|
+
<div className="mt-3">
|
|
101
|
+
<InlineDiffPreview
|
|
102
|
+
action={message.action}
|
|
103
|
+
onAccept={() => onAcceptChanges?.(message.id)}
|
|
104
|
+
onRevert={() => onRevertChanges?.(message.id)}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
)}
|
|
108
|
+
|
|
109
|
+
{/* Status badge for actions without files */}
|
|
110
|
+
{message.action && (!message.action.files || message.action.files.length === 0) && (
|
|
111
|
+
<div className="mt-2">
|
|
112
|
+
{message.action.status === "accepted" && (
|
|
113
|
+
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-400 text-xs rounded-md">
|
|
114
|
+
<CheckCircle className="h-3 w-3" />
|
|
115
|
+
<span>Changes accepted</span>
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
{message.action.status === "reverted" && (
|
|
119
|
+
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-amber-50 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 text-xs rounded-md">
|
|
120
|
+
<RotateCcw className="h-3 w-3" />
|
|
121
|
+
<span>Changes reverted</span>
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
124
|
+
{message.action.status === "error" && (
|
|
125
|
+
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400 text-xs rounded-md">
|
|
126
|
+
<AlertCircle className="h-3 w-3" />
|
|
127
|
+
<span>Error occurred</span>
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
130
|
+
</div>
|
|
131
|
+
)}
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
))}
|
|
135
|
+
|
|
136
|
+
{/* Scroll anchor */}
|
|
137
|
+
<div ref={bottomRef} />
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|