@widgetic/chat 0.1.4

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.
Files changed (72) hide show
  1. package/README.md +440 -0
  2. package/dist/adapters/index.d.ts +2 -0
  3. package/dist/adapters/index.js +2 -0
  4. package/dist/adapters/widgeticAdapter.d.ts +185 -0
  5. package/dist/adapters/widgeticAdapter.js +766 -0
  6. package/dist/components/ActionBar.svelte +342 -0
  7. package/dist/components/ActionBar.svelte.d.ts +37 -0
  8. package/dist/components/AttachmentDisplay.svelte +547 -0
  9. package/dist/components/AttachmentDisplay.svelte.d.ts +12 -0
  10. package/dist/components/Chat.svelte +1253 -0
  11. package/dist/components/Chat.svelte.d.ts +112 -0
  12. package/dist/components/ChatHeader.svelte +182 -0
  13. package/dist/components/ChatHeader.svelte.d.ts +12 -0
  14. package/dist/components/ChatInput.svelte +290 -0
  15. package/dist/components/ChatInput.svelte.d.ts +15 -0
  16. package/dist/components/ChatMessages.svelte +996 -0
  17. package/dist/components/ChatMessages.svelte.d.ts +28 -0
  18. package/dist/components/CodeBlock.svelte +286 -0
  19. package/dist/components/CodeBlock.svelte.d.ts +10 -0
  20. package/dist/components/ContextPreview.svelte +66 -0
  21. package/dist/components/ContextPreview.svelte.d.ts +8 -0
  22. package/dist/components/LoadingIndicator.svelte +151 -0
  23. package/dist/components/LoadingIndicator.svelte.d.ts +9 -0
  24. package/dist/components/StatusIndicator.svelte +116 -0
  25. package/dist/components/StatusIndicator.svelte.d.ts +9 -0
  26. package/dist/components/SuggestionButtons.svelte +244 -0
  27. package/dist/components/SuggestionButtons.svelte.d.ts +26 -0
  28. package/dist/components/index.d.ts +12 -0
  29. package/dist/components/index.js +12 -0
  30. package/dist/config.d.ts +43 -0
  31. package/dist/config.js +67 -0
  32. package/dist/constants/colors.d.ts +20 -0
  33. package/dist/constants/colors.js +16 -0
  34. package/dist/index.d.ts +11 -0
  35. package/dist/index.js +20 -0
  36. package/dist/services/chatService.d.ts +72 -0
  37. package/dist/services/chatService.js +355 -0
  38. package/dist/services/index.d.ts +2 -0
  39. package/dist/services/index.js +2 -0
  40. package/dist/stores/chatStore.d.ts +46 -0
  41. package/dist/stores/chatStore.js +219 -0
  42. package/dist/stores/index.d.ts +2 -0
  43. package/dist/stores/index.js +2 -0
  44. package/dist/types/adapter.d.ts +86 -0
  45. package/dist/types/adapter.js +1 -0
  46. package/dist/types/api-temp.d.ts +61 -0
  47. package/dist/types/api-temp.js +42 -0
  48. package/dist/types/attachment.d.ts +84 -0
  49. package/dist/types/attachment.js +33 -0
  50. package/dist/types/chat.d.ts +114 -0
  51. package/dist/types/chat.js +1 -0
  52. package/dist/types/config.d.ts +89 -0
  53. package/dist/types/config.js +63 -0
  54. package/dist/types/context.d.ts +108 -0
  55. package/dist/types/context.js +11 -0
  56. package/dist/types/conversation.d.ts +45 -0
  57. package/dist/types/conversation.js +1 -0
  58. package/dist/types/events.d.ts +141 -0
  59. package/dist/types/events.js +1 -0
  60. package/dist/types/index.d.ts +16 -0
  61. package/dist/types/index.js +10 -0
  62. package/dist/types/message.d.ts +82 -0
  63. package/dist/types/message.js +1 -0
  64. package/dist/types/state.d.ts +117 -0
  65. package/dist/types/state.js +1 -0
  66. package/dist/utils/fileUtils.d.ts +93 -0
  67. package/dist/utils/fileUtils.js +299 -0
  68. package/dist/utils/index.d.ts +3 -0
  69. package/dist/utils/index.js +4 -0
  70. package/dist/utils/logger.d.ts +4 -0
  71. package/dist/utils/logger.js +28 -0
  72. package/package.json +104 -0
package/README.md ADDED
@@ -0,0 +1,440 @@
1
+ # @widgetic/chat
2
+
3
+ A modern, reusable chat module built with Svelte 5, TypeScript, and the Widgetic Design System. Designed for canvas-based platforms with frame content integration and LLM communication.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Modern UI** - Built with Svelte 5 runes and Tailwind CSS
8
+ - 🔌 **Platform Agnostic** - Adapter pattern for different contexts (frames, documents, etc.)
9
+ - 📱 **Responsive Design** - Mobile-friendly with collapsible interface
10
+ - 📁 **File Attachments** - Support for images, videos, documents with preview
11
+ - 🔄 **Real-time Updates** - WebSocket integration ready
12
+ - 🤖 **AI Integration** - LLM communication with context awareness
13
+ - 📦 **TypeScript** - Fully typed for better development experience
14
+ - ♿ **Accessible** - WCAG compliant with keyboard navigation
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @widgetic/chat
20
+ ```
21
+
22
+ ### Peer Dependencies
23
+
24
+ ```bash
25
+ npm install @widgetic/design-system @widgetic/api-sdk svelte @sveltejs/kit
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ```svelte
31
+ <script>
32
+ import { Chat, createChatService, createWidgeticAdapter } from '@widgetic/chat';
33
+
34
+ // Create a context for your frame/component
35
+ const context = {
36
+ id: 'canvas_123:component_456',
37
+ type: 'frame',
38
+ parentId: 'canvas_123',
39
+ title: 'My Component',
40
+ metadata: {
41
+ frameTitle: 'Interactive Button',
42
+ canvasId: 'canvas_123'
43
+ }
44
+ };
45
+ </script>
46
+
47
+ <Chat {context} />
48
+ ```
49
+
50
+ ## Core Concepts
51
+
52
+ ### Context
53
+
54
+ A context represents what the user is chatting about - typically a frame, document, or other object:
55
+
56
+ ```typescript
57
+ interface ChatContext {
58
+ id: string; // Unique identifier (e.g., "canvas_123:component_456")
59
+ type: ContextType; // 'frame' | 'text' | 'image' | 'document' | 'canvas'
60
+ parentId: string; // Parent container ID
61
+ title?: string; // Display name
62
+ thumbnail?: string; // Preview image URL
63
+ metadata?: Record<string, any>; // Additional context data
64
+ }
65
+ ```
66
+
67
+ ### Platform Adapters
68
+
69
+ Adapters handle platform-specific functionality:
70
+
71
+ ```typescript
72
+ import { createWidgeticAdapter } from '@widgetic/chat';
73
+
74
+ const adapter = createWidgeticAdapter();
75
+
76
+ // Register event handlers
77
+ adapter.onFrameSelection((frameId) => {
78
+ console.log('Frame selected:', frameId);
79
+ });
80
+
81
+ // Capture screenshots
82
+ const screenshot = await adapter.captureFrameScreenshot('frame_123');
83
+ ```
84
+
85
+ ### Chat Service
86
+
87
+ Handles API communication and data management:
88
+
89
+ ```typescript
90
+ import { createChatService } from '@widgetic/chat';
91
+
92
+ const chatService = createChatService({
93
+ // API configuration
94
+ });
95
+
96
+ // Send messages
97
+ const message = await chatService.sendMessage(conversationId, {
98
+ messageContent: 'Hello, AI!',
99
+ attachments: [file]
100
+ });
101
+ ```
102
+
103
+ ## Components
104
+
105
+ ### Main Chat Component
106
+
107
+ ```svelte
108
+ <Chat
109
+ {context}
110
+ config={{
111
+ ui: {
112
+ position: 'right',
113
+ showTimestamps: true
114
+ },
115
+ features: {
116
+ fileUpload: true,
117
+ voiceTranscription: false,
118
+ screenshot: true,
119
+ aiSuggestions: true,
120
+ screenRecording: false,
121
+ restoreCheckpoint: true
122
+ }
123
+ }}
124
+ class="custom-chat-styles"
125
+ />
126
+ ```
127
+
128
+ ### Context Preview
129
+
130
+ For collapsed chat states:
131
+
132
+ ```svelte
133
+ <ContextPreview
134
+ {context}
135
+ onclick={() => expandChat()}
136
+ />
137
+ ```
138
+
139
+ ### Individual Components
140
+
141
+ You can also use individual components:
142
+
143
+ ```svelte
144
+ <script>
145
+ import { ChatMessages, ChatInput } from '@widgetic/chat';
146
+ </script>
147
+
148
+ <ChatMessages
149
+ {messages}
150
+ {isLoading}
151
+ {context}
152
+ />
153
+
154
+ <ChatInput
155
+ value={inputText}
156
+ {attachments}
157
+ onSend={handleSend}
158
+ onInputChange={handleInputChange}
159
+ />
160
+ ```
161
+
162
+ ## State Management
163
+
164
+ The chat module uses Svelte 5 runes for reactive state management:
165
+
166
+ ```typescript
167
+ import { chatStore } from '@widgetic/chat';
168
+
169
+ // Access reactive state
170
+ let chatState = $state(chatStore);
171
+
172
+ // Dispatch actions
173
+ chatStore.dispatch({
174
+ type: 'SET_ACTIVE_CONTEXT',
175
+ payload: { contextId: 'frame_123', isExpanded: true }
176
+ });
177
+
178
+ // Helper methods
179
+ chatStore.actions.setActiveContext('frame_123', true);
180
+ chatStore.actions.addMessage(conversationId, message);
181
+ ```
182
+
183
+ ## Configuration
184
+
185
+ ### Chat Config
186
+
187
+ ```typescript
188
+ interface ChatConfig {
189
+ api: {
190
+ baseUrl?: string;
191
+ headers?: Record<string, string>;
192
+ timeout?: number;
193
+ };
194
+ ui: {
195
+ position: 'right' | 'bottom' | 'left' | 'floating';
196
+ width?: number;
197
+ height?: number;
198
+ showTimestamps?: boolean;
199
+ maxFileSize?: number;
200
+ };
201
+ features: {
202
+ fileUpload: boolean;
203
+ voiceTranscription: boolean;
204
+ screenshot: boolean;
205
+ aiSuggestions: boolean;
206
+ screenRecording: boolean;
207
+ restoreCheckpoint: boolean;
208
+ };
209
+ }
210
+ ```
211
+
212
+ ### Default Configuration
213
+
214
+ ```typescript
215
+ import { DEFAULT_CHAT_CONFIG } from '@widgetic/chat';
216
+
217
+ const customConfig = {
218
+ ...DEFAULT_CHAT_CONFIG,
219
+ ui: {
220
+ ...DEFAULT_CHAT_CONFIG.ui,
221
+ position: 'bottom'
222
+ }
223
+ };
224
+ ```
225
+
226
+ ## File Handling
227
+
228
+ ### Supported File Types
229
+
230
+ - **Images**: JPEG, PNG, SVG (max 10MB)
231
+ - **Videos**: MP4 (max 100MB)
232
+ - **Documents**: PDF, TXT, MD, .mermaid (max 25MB)
233
+
234
+ ### File Utilities
235
+
236
+ ```typescript
237
+ import {
238
+ validateFile,
239
+ createFilePreview,
240
+ compressImage
241
+ } from '@widgetic/chat';
242
+
243
+ // Validate before upload
244
+ const validation = validateFile(file);
245
+ if (!validation.valid) {
246
+ console.error(validation.error);
247
+ }
248
+
249
+ // Create preview
250
+ const preview = await createFilePreview(file);
251
+
252
+ // Compress images
253
+ const compressed = await compressImage(file, {
254
+ maxWidth: 1920,
255
+ maxHeight: 1080,
256
+ quality: 0.8
257
+ });
258
+ ```
259
+
260
+ ## API Integration
261
+
262
+ ### Widgetic API SDK
263
+
264
+ The chat service integrates with the Widgetic API SDK:
265
+
266
+ ```typescript
267
+ import { ConversationsApi, MessagesApi } from '@widgetic/api-sdk';
268
+
269
+ // The service handles API calls automatically
270
+ const conversations = await chatService.getConversations(contextId);
271
+ const messages = await chatService.getMessages(conversationId);
272
+ ```
273
+
274
+ ### Custom API Integration
275
+
276
+ You can implement custom chat services:
277
+
278
+ ```typescript
279
+ import type { ChatService } from '@widgetic/chat';
280
+
281
+ class CustomChatService implements ChatService {
282
+ async getConversations(contextId: string) {
283
+ // Your implementation
284
+ }
285
+
286
+ async sendMessage(conversationId: string, data: any) {
287
+ // Your implementation
288
+ }
289
+ }
290
+ ```
291
+
292
+ ## Styling
293
+
294
+ ### CSS Classes
295
+
296
+ The chat module uses Tailwind CSS with design system components:
297
+
298
+ ```css
299
+ .chat-container {
300
+ /* Custom chat container styles */
301
+ }
302
+
303
+ .chat-expanded {
304
+ /* Expanded chat styles */
305
+ }
306
+
307
+ .message-bubble {
308
+ /* Message bubble styles */
309
+ }
310
+ ```
311
+
312
+ ## TypeScript Support
313
+
314
+ Full TypeScript support with exported types:
315
+
316
+ ```typescript
317
+ import type {
318
+ ChatContext,
319
+ ChatMessage,
320
+ ChatConversation,
321
+ ChatConfig,
322
+ ChatState,
323
+ PlatformAdapter
324
+ } from '@widgetic/chat';
325
+ ```
326
+
327
+ ## Examples
328
+
329
+ ### Frame-based Chat
330
+
331
+ ```svelte
332
+ <script>
333
+ import { Chat } from '@widgetic/chat';
334
+
335
+ const frameContext = {
336
+ id: 'canvas_123:button_component',
337
+ type: 'frame',
338
+ parentId: 'canvas_123',
339
+ title: 'Interactive Button',
340
+ metadata: {
341
+ isPublished: true,
342
+ dimensions: { width: 200, height: 50 }
343
+ }
344
+ };
345
+ </script>
346
+
347
+ <Chat
348
+ context={frameContext}
349
+ config={{
350
+ ui: { position: 'right' },
351
+ features: {
352
+ fileUpload: true,
353
+ screenshot: true,
354
+ screenRecording: false,
355
+ restoreCheckpoint: true
356
+ }
357
+ }}
358
+ />
359
+ ```
360
+
361
+ ### Document Chat
362
+
363
+ ```svelte
364
+ <script>
365
+ const documentContext = {
366
+ id: 'doc_456',
367
+ type: 'text',
368
+ parentId: 'editor_123',
369
+ title: 'My Document.md',
370
+ metadata: {
371
+ contentType: 'markdown',
372
+ wordCount: 1250
373
+ }
374
+ };
375
+ </script>
376
+
377
+ <Chat context={documentContext} />
378
+ ```
379
+
380
+ ### Programmatic Control
381
+
382
+ ```svelte
383
+ <script>
384
+ import { chatStore, createChatService } from '@widgetic/chat';
385
+
386
+ let chatService = createChatService();
387
+
388
+ async function sendProgrammaticMessage() {
389
+ const conversation = await chatService.createConversation(
390
+ context.id,
391
+ { title: 'Auto Chat' }
392
+ );
393
+
394
+ await chatService.sendMessage(conversation.id, {
395
+ messageContent: 'This is an automated message',
396
+ messageType: 'user'
397
+ });
398
+
399
+ chatStore.actions.setActiveContext(context.id, true);
400
+ }
401
+ </script>
402
+ ```
403
+
404
+ ## Development
405
+
406
+ ### Building
407
+
408
+ ```bash
409
+ npm run build
410
+ npm run package
411
+ ```
412
+
413
+ ### Testing
414
+
415
+ ```bash
416
+ npm run check
417
+ npm run lint
418
+ ```
419
+
420
+ ### Watching
421
+
422
+ ```bash
423
+ npm run package:watch
424
+ ```
425
+
426
+ ## License
427
+
428
+ MIT
429
+
430
+ ## Contributing
431
+
432
+ 1. Fork the repository
433
+ 2. Create a feature branch
434
+ 3. Make your changes
435
+ 4. Add tests if applicable
436
+ 5. Submit a pull request
437
+
438
+ ---
439
+
440
+ For more detailed documentation, see the [API Reference](./docs/api.md) and [Examples](./docs/examples.md).
@@ -0,0 +1,2 @@
1
+ export { WidgeticCanvasAdapter, createWidgeticAdapter } from './widgeticAdapter.js';
2
+ export type { PlatformAdapter, WidgeticAdapter, AdapterFactory, AdapterConfig } from '../types/index.js';
@@ -0,0 +1,2 @@
1
+ // Platform Adapters
2
+ export { WidgeticCanvasAdapter, createWidgeticAdapter } from './widgeticAdapter.js';
@@ -0,0 +1,185 @@
1
+ import type { WidgeticAdapter, ChatContext, FrameContext, ContextCapabilities } from '../types/index.js';
2
+ /**
3
+ * Widgetic Canvas Platform Adapter
4
+ * Handles frame-based contexts for the Widgetic canvas system
5
+ */
6
+ export declare class WidgeticCanvasAdapter implements WidgeticAdapter {
7
+ name: "widgetic";
8
+ version: string;
9
+ private frameSelectionCallbacks;
10
+ private frameDeselectionCallbacks;
11
+ private contextChangeCallbacks;
12
+ private contextUpdateCallbacks;
13
+ /**
14
+ * Extract frame ID from context object
15
+ */
16
+ getContextId(contextObject: any): string;
17
+ /**
18
+ * Get human-readable title for the frame
19
+ */
20
+ getContextTitle(contextObject: any): string;
21
+ /**
22
+ * Get context type
23
+ */
24
+ getContextType(): string;
25
+ /**
26
+ * Create a standardized chat context from a frame object
27
+ */
28
+ createContext(contextObject: any): FrameContext;
29
+ /**
30
+ * Returns the capabilities supported by the Widgetic platform adapter.
31
+ *
32
+ * Capabilities explained:
33
+ * - supportsScreenshot: Can capture static images of frame content
34
+ * - supportsRecording: Can record video of user interactions within frames
35
+ * - supportsFileUpload: Can handle file uploads via drag-and-drop or file picker
36
+ * - supportsTextInput: Can handle text-based chat messages
37
+ * - supportsMediaCapture: Can handle general media input (camera access, microphone,
38
+ * file uploads, reference images) beyond just screenshots and recordings
39
+ */
40
+ getCapabilities(): ContextCapabilities;
41
+ /**
42
+ * Get AI suggestions based on frame context
43
+ */
44
+ getSuggestions(context: ChatContext): Promise<string[]>;
45
+ /**
46
+ * Get available actions for this frame
47
+ */
48
+ getActions(context: ChatContext): Promise<any[]>;
49
+ /**
50
+ * Capture screenshot of a specific frame
51
+ */
52
+ captureFrameScreenshot(frameId: string): Promise<Blob>;
53
+ /**
54
+ * Start recording a frame
55
+ */
56
+ startFrameRecording(frameId: string): Promise<void>;
57
+ /**
58
+ * Capture screenshot of any frame context
59
+ */
60
+ captureScreenshot(contextId: string): Promise<Blob>;
61
+ /**
62
+ * Start recording for any context
63
+ */
64
+ startRecording(contextId: string): Promise<void>;
65
+ /**
66
+ * Stop recording (placeholder)
67
+ */
68
+ stopRecording(): Promise<Blob>;
69
+ /**
70
+ * Get frame content and metadata with optional element-specific inspection.
71
+ *
72
+ * This method retrieves detailed information about a frame's structure, components,
73
+ * and optionally focuses on a specific element within the frame. It's used by the
74
+ * AI to understand the frame's composition and provide targeted suggestions.
75
+ *
76
+ * @param frameId - The unique identifier of the frame to inspect
77
+ * @param elementId - Optional. The specific element within the frame to focus on
78
+ * @returns Promise containing frame content, structure, and metadata
79
+ *
80
+ * Use cases:
81
+ * - General frame analysis: getFrameContent('frame-123')
82
+ * - Specific element targeting: getFrameContent('frame-123', 'button-456')
83
+ * - AI code generation based on existing components
84
+ * - Providing context for design suggestions
85
+ */
86
+ getFrameContent(frameId: string, elementId?: string): Promise<any>;
87
+ /**
88
+ * Get detailed information about a specific element within a frame.
89
+ *
90
+ * This method provides comprehensive data about a selected element, including
91
+ * its properties, styling, position, and relationships to other elements.
92
+ * Used when the user wants to make changes to a specific component.
93
+ *
94
+ * @param frameId - The frame containing the element
95
+ * @param elementId - The unique identifier of the element to inspect
96
+ * @returns Element details including properties, styling, and context
97
+ */
98
+ getElementDetails(frameId: string, elementId: string): Promise<any>;
99
+ /**
100
+ * Get the hierarchical structure of all components within a frame.
101
+ *
102
+ * This method provides a tree-like representation of the frame's content,
103
+ * showing how components are nested and organized. Useful for understanding
104
+ * the overall layout and suggesting structural improvements.
105
+ *
106
+ * @param frameId - The frame to analyze
107
+ * @returns Hierarchical structure of frame components
108
+ */
109
+ getFrameStructure(frameId: string): Promise<any>;
110
+ /**
111
+ * Get a list of all components within a frame with their basic properties.
112
+ *
113
+ * This method provides a flat list of all components for quick reference
114
+ * and bulk operations. Useful for inventory, search, and batch modifications.
115
+ *
116
+ * @param frameId - The frame to analyze
117
+ * @returns Array of component summaries
118
+ */
119
+ getFrameComponents(frameId: string): Promise<any[]>;
120
+ /**
121
+ * Enable element selection mode for a frame.
122
+ *
123
+ * This method puts the frame into a special selection mode where users can
124
+ * click on individual elements to select them for targeted AI assistance.
125
+ * When an element is selected, it becomes the focus for subsequent AI interactions.
126
+ *
127
+ * @param frameId - The frame to enable selection mode for
128
+ * @returns Promise that resolves when selection mode is active
129
+ *
130
+ * Behavior:
131
+ * - Highlights hoverable elements
132
+ * - Shows selection cursor
133
+ * - Captures element clicks
134
+ * - Provides visual feedback for selection
135
+ * - Automatically focuses chat on selected element
136
+ */
137
+ enableElementSelection(frameId: string): Promise<void>;
138
+ /**
139
+ * Select a specific element within a frame for targeted AI assistance.
140
+ *
141
+ * This method is called when a user clicks on an element during selection mode.
142
+ * It highlights the selected element and prepares it for AI interaction.
143
+ *
144
+ * @param frameId - The frame containing the element
145
+ * @param elementId - The element that was selected
146
+ * @returns Promise that resolves when element is selected
147
+ */
148
+ selectElement(frameId: string, elementId: string): Promise<void>;
149
+ /**
150
+ * Register callback for frame selection events
151
+ */
152
+ onFrameSelection(callback: (frameId: string) => void): () => void;
153
+ /**
154
+ * Register callback for frame deselection events
155
+ */
156
+ onFrameDeselection(callback: (frameId: string) => void): () => void;
157
+ /**
158
+ * Register callback for context changes
159
+ */
160
+ onContextChange(callback: (context: ChatContext | null) => void): () => void;
161
+ /**
162
+ * Register callback for context updates
163
+ */
164
+ onContextUpdate(callback: (context: ChatContext) => void): () => void;
165
+ /**
166
+ * Trigger frame selection event
167
+ */
168
+ triggerFrameSelection(frameId: string): void;
169
+ /**
170
+ * Trigger frame deselection event
171
+ */
172
+ triggerFrameDeselection(frameId: string): void;
173
+ /**
174
+ * Trigger context change event
175
+ */
176
+ triggerContextChange(context: ChatContext | null): void;
177
+ /**
178
+ * Trigger context update event
179
+ */
180
+ triggerContextUpdate(context: ChatContext): void;
181
+ }
182
+ /**
183
+ * Create a new Widgetic adapter instance
184
+ */
185
+ export declare function createWidgeticAdapter(): WidgeticCanvasAdapter;