@colletdev/docs 0.2.2 → 0.2.3

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 (3) hide show
  1. package/cli.mjs +4 -3
  2. package/messages.md +343 -0
  3. package/package.json +3 -2
package/cli.mjs CHANGED
@@ -85,6 +85,7 @@ Read the reference that matches the user's context:
85
85
  | .component.ts / Angular | core.md + angular.md |
86
86
  | Custom Elements / @colletdev/core | core.md only |
87
87
  | Component API question | components.md |
88
+ | Chat / messages / streaming | messages.md |
88
89
 
89
90
  Always read core.md first, then the framework-specific reference.
90
91
 
@@ -100,14 +101,14 @@ Always read core.md first, then the framework-specific reference.
100
101
  writeFileSync(resolve(skillDir, 'SKILL.md'), skillMd);
101
102
 
102
103
  // Copy all reference docs
103
- for (const file of ['core.md', 'components.md', 'react.md', 'vue.md', 'svelte.md', 'angular.md']) {
104
+ for (const file of ['core.md', 'components.md', 'messages.md', 'react.md', 'vue.md', 'svelte.md', 'angular.md']) {
104
105
  const src = docPath(file);
105
106
  if (existsSync(src)) {
106
107
  writeFileSync(resolve(refDir, file), readDoc(file));
107
108
  }
108
109
  }
109
110
 
110
- console.log(` Claude Code: .claude/skills/collet/ (SKILL.md + 6 references)`);
111
+ console.log(` Claude Code: .claude/skills/collet/ (SKILL.md + 7 references)`);
111
112
 
112
113
  // Add to .claude/CLAUDE.md if it exists and doesn't already mention collet
113
114
  const claudeMd = resolve(CWD, '.claude/CLAUDE.md');
@@ -293,7 +294,7 @@ function main() {
293
294
 
294
295
  console.log('');
295
296
  console.log('Done. Your AI agent now has full Collet component knowledge.');
296
- console.log('Reference: 7 doc files from @colletdev/docs (108 KB total)');
297
+ console.log('Reference: 8 doc files from @colletdev/docs');
297
298
  console.log('');
298
299
  }
299
300
 
package/messages.md ADDED
@@ -0,0 +1,343 @@
1
+ # Messages — Composition Guide
2
+
3
+ How to build chat interfaces, AI assistant UIs, and conversational experiences
4
+ with Collet's message component system.
5
+
6
+ ---
7
+
8
+ ## Architecture
9
+
10
+ Messages are **composed, not monolithic**. There is no single `<Message>` component.
11
+ Instead, four specialized components snap together like building blocks:
12
+
13
+ ```
14
+ MessageBubble ← outer container (alignment, avatar, timestamp)
15
+ └── MessageGroup ← groups connected content blocks
16
+ ├── MessagePart ← text, code, tool calls, errors, thinking
17
+ ├── MessagePart ← another content block
18
+ └── ActivityGroup ← tool call/result group with derived status
19
+ ```
20
+
21
+ This design lets you build anything from a simple chat bubble to a full
22
+ AI coding assistant with tool calls, streaming markdown, and code blocks.
23
+
24
+ ---
25
+
26
+ ## The Components
27
+
28
+ ### MessageBubble
29
+
30
+ The outer container. Controls sender alignment, avatar, name, and timestamp.
31
+
32
+ ```tsx
33
+ import { MessageBubble } from '@colletdev/react';
34
+
35
+ <MessageBubble role="assistant" senderName="Collet" avatar="/collet.svg">
36
+ {/* MessageGroup(s) go here */}
37
+ </MessageBubble>
38
+
39
+ <MessageBubble role="user" senderName="Dan">
40
+ {/* User message content */}
41
+ </MessageBubble>
42
+ ```
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | `role` | `'user' \| 'assistant'` | `'user'` | Determines alignment and color |
47
+ | `senderName` | `string` | — | Name displayed above the bubble |
48
+ | `avatar` | `string` | — | Avatar image URL |
49
+ | `timestamp` | `string` | — | Timestamp text |
50
+ | `variant` | `'filled' \| 'ghost'` | `'filled'` | Visual style |
51
+ | `shape` | `'sharp' \| 'rounded'` | `'rounded'` | Border radius |
52
+
53
+ **Alignment:** `role="user"` right-aligns, `role="assistant"` left-aligns.
54
+
55
+ ### MessageGroup
56
+
57
+ Groups multiple `MessagePart` blocks into a single connected card. Parts within
58
+ a group share edges (no gaps between them).
59
+
60
+ ```tsx
61
+ import { MessageGroup } from '@colletdev/react';
62
+
63
+ <MessageGroup role="assistant">
64
+ <MessagePart kind="text">Here is what I found:</MessagePart>
65
+ <MessagePart kind="code-block" language="rust" filename="main.rs">
66
+ fn main() { println!("Hello"); }
67
+ </MessagePart>
68
+ </MessageGroup>
69
+ ```
70
+
71
+ | Prop | Type | Default | Description |
72
+ |------|------|---------|-------------|
73
+ | `role` | `'user' \| 'assistant'` | `'user'` | Color scheme |
74
+ | `variant` | `'filled' \| 'ghost'` | `'filled'` | Visual style |
75
+
76
+ ### MessagePart
77
+
78
+ The individual content block. Each part has a `kind` that determines its rendering:
79
+
80
+ | Kind | Renders as | Use for |
81
+ |------|-----------|---------|
82
+ | `text` | Plain or markdown text | Chat messages, explanations |
83
+ | `code-block` | Syntax-highlighted code with terminal chrome | Code snippets, file contents |
84
+ | `tool-call` | Collapsible tool invocation row | Function calls, API requests |
85
+ | `tool-result` | Collapsible tool output | Function responses |
86
+ | `thinking` | Shimmer animation or completed indicator | "Thinking..." state |
87
+ | `error` | Danger-styled error message | Error responses |
88
+
89
+ ```tsx
90
+ import { MessagePart } from '@colletdev/react';
91
+
92
+ {/* Plain text */}
93
+ <MessagePart kind="text">Hello, how can I help?</MessagePart>
94
+
95
+ {/* Markdown text */}
96
+ <MessagePart kind="text" markdown>
97
+ Here is a **bold** statement with a [link](https://example.com).
98
+ </MessagePart>
99
+
100
+ {/* Code block */}
101
+ <MessagePart kind="code-block" language="typescript" filename="setup.ts">
102
+ import { init } from '@colletdev/core';
103
+ await init();
104
+ </MessagePart>
105
+
106
+ {/* Tool call (pending) */}
107
+ <MessagePart
108
+ kind="tool-call"
109
+ toolName="search_docs"
110
+ toolArguments='{"query": "auth"}'
111
+ status="pending"
112
+ />
113
+
114
+ {/* Tool result */}
115
+ <MessagePart
116
+ kind="tool-result"
117
+ toolName="search_docs"
118
+ status="success"
119
+ collapsible
120
+ >
121
+ Found 3 results...
122
+ </MessagePart>
123
+
124
+ {/* Thinking indicator */}
125
+ <MessagePart kind="thinking" thinkingLabel="Analyzing code..." />
126
+
127
+ {/* Error */}
128
+ <MessagePart kind="error">Connection timed out</MessagePart>
129
+ ```
130
+
131
+ ### ActivityGroup
132
+
133
+ Groups related tool calls and results with a derived status indicator.
134
+ The status is computed from child tool states — you don't set it manually.
135
+
136
+ ```tsx
137
+ import { ActivityGroup } from '@colletdev/react';
138
+
139
+ <ActivityGroup label="Code analysis" status="running">
140
+ <MessagePart kind="tool-call" toolName="read_file" status="success" />
141
+ <MessagePart kind="tool-call" toolName="search_code" status="pending" />
142
+ </ActivityGroup>
143
+ ```
144
+
145
+ | Status | Meaning | Visual |
146
+ |--------|---------|--------|
147
+ | `running` | At least one tool is pending | Shimmer animation |
148
+ | `done` | All tools completed successfully | Checkmark |
149
+ | `error` | At least one tool failed | Error indicator |
150
+
151
+ ---
152
+
153
+ ## Markdown Rendering
154
+
155
+ MessagePart with `kind="text"` and `markdown` enabled renders GitHub Flavored
156
+ Markdown through Collet's WASM-powered renderer:
157
+
158
+ ```tsx
159
+ <MessagePart kind="text" markdown>
160
+ ## Features
161
+
162
+ - **Tables** with column alignment
163
+ - `inline code` and fenced code blocks
164
+ - Task lists: - [x] done - [ ] todo
165
+ - [Links](https://example.com) with external indicators
166
+ - Heading anchors for deep linking
167
+ </MessagePart>
168
+ ```
169
+
170
+ **What's supported:** paragraphs, headings (h1-h6) with anchor IDs, bold, italic,
171
+ strikethrough, ordered/unordered/nested lists, task lists, tables, inline code,
172
+ fenced code blocks with language labels, blockquotes, links, images, horizontal rules.
173
+
174
+ **Security:** XSS-safe at compile time — raw HTML in markdown source is escaped,
175
+ not passed through. No runtime sanitizer needed.
176
+
177
+ **Programmatic rendering:**
178
+
179
+ ```tsx
180
+ import { renderMarkdown } from '@colletdev/core/markdown';
181
+
182
+ // Async (lazy-loads WASM)
183
+ const html = await renderMarkdown('**Hello** world');
184
+
185
+ // Sync (after WASM is loaded)
186
+ import { renderMarkdownSync } from '@colletdev/core/markdown';
187
+ const html = renderMarkdownSync('**Hello** world');
188
+ ```
189
+
190
+ **React hook:**
191
+
192
+ ```tsx
193
+ import { useMarkdown } from '@colletdev/react';
194
+
195
+ function MyComponent({ content }) {
196
+ const html = useMarkdown(content);
197
+ return <div dangerouslySetInnerHTML={{ __html: html }} />;
198
+ }
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Streaming Messages
204
+
205
+ For real-time AI responses, use the streaming API on MessagePart:
206
+
207
+ ```tsx
208
+ import { useRef } from 'react';
209
+ import { MessagePart } from '@colletdev/react';
210
+ import type { MessagePartRef } from '@colletdev/react';
211
+
212
+ function StreamingMessage() {
213
+ const ref = useRef<MessagePartRef>(null);
214
+
215
+ useEffect(() => {
216
+ // Start streaming
217
+ ref.current?.startStream();
218
+
219
+ // Append tokens as they arrive
220
+ eventSource.onmessage = (e) => {
221
+ ref.current?.appendTokens(e.data);
222
+ };
223
+
224
+ // End stream (triggers WASM re-render for XSS safety)
225
+ eventSource.onclose = () => {
226
+ ref.current?.endStream();
227
+ };
228
+ }, []);
229
+
230
+ return <MessagePart ref={ref} kind="text" stream markdown />;
231
+ }
232
+ ```
233
+
234
+ **How streaming works:**
235
+ 1. `startStream()` — switches to DOM-based incremental rendering (fast)
236
+ 2. `appendTokens(text)` — appends text tokens with rAF batching
237
+ 3. `endStream()` — re-renders accumulated text through WASM markdown pipeline
238
+ (defense-in-depth XSS sanitization)
239
+
240
+ ---
241
+
242
+ ## MessageTimeline (Rust-side reducer)
243
+
244
+ For production chat UIs with tool calls, streaming, and complex turn lifecycle,
245
+ Collet provides a Rust-side chronological reducer. This is the recommended way
246
+ to build AI assistant interfaces.
247
+
248
+ **What it handles:**
249
+ - Chronological ordering of text, thinking, tool calls, code blocks, errors
250
+ - Out-of-order tool result hydration
251
+ - Tool group status derivation (running → done/error) from child state
252
+ - Thinking auto-settlement when the turn advances
253
+ - Duplicate tool result deduplication
254
+ - Terminal turn immutability (completed/aborted turns reject new events)
255
+
256
+ **Note:** MessageTimeline is currently Rust-side only. It renders directly to HTML
257
+ via the SSR gallery. WASM/npm export is planned — see the project roadmap.
258
+
259
+ ---
260
+
261
+ ## Complete Example
262
+
263
+ A full AI assistant conversation with tool calls:
264
+
265
+ ```tsx
266
+ import {
267
+ MessageBubble, MessageGroup, MessagePart, ActivityGroup
268
+ } from '@colletdev/react';
269
+
270
+ function Conversation() {
271
+ return (
272
+ <div style={{ maxWidth: '48rem', margin: '0 auto' }}>
273
+ {/* User message */}
274
+ <MessageBubble role="user" senderName="Dan">
275
+ <MessageGroup role="user">
276
+ <MessagePart kind="text">
277
+ How do I set up Collet in my Next.js app?
278
+ </MessagePart>
279
+ </MessageGroup>
280
+ </MessageBubble>
281
+
282
+ {/* Assistant response with tool calls */}
283
+ <MessageBubble role="assistant" senderName="Collet" avatar="/collet.svg">
284
+ <MessageGroup role="assistant">
285
+ {/* Thinking */}
286
+ <MessagePart kind="thinking" completed thinkingLabel="Searched documentation" />
287
+
288
+ {/* Tool activity */}
289
+ <ActivityGroup label="Documentation search" status="done">
290
+ <MessagePart
291
+ kind="tool-call"
292
+ toolName="search_docs"
293
+ status="success"
294
+ description="Searched Next.js setup guide"
295
+ />
296
+ </ActivityGroup>
297
+
298
+ {/* Response text with markdown */}
299
+ <MessagePart kind="text" markdown>
300
+ Here's how to set up Collet in Next.js:
301
+
302
+ 1. Install the packages
303
+ 2. Add the Vite plugin (or configure manually for Next.js)
304
+ 3. Call `init()` in your root layout
305
+ </MessagePart>
306
+
307
+ {/* Code example */}
308
+ <MessagePart kind="code-block" language="tsx" filename="app/layout.tsx">
309
+ {`import { init } from '@colletdev/core';
310
+
311
+ init();
312
+
313
+ export default function RootLayout({ children }) {
314
+ return <html><body>{children}</body></html>;
315
+ }`}
316
+ </MessagePart>
317
+ </MessageGroup>
318
+ </MessageBubble>
319
+ </div>
320
+ );
321
+ }
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Standalone Code Blocks
327
+
328
+ For code display outside of messages, use the dedicated `CodeBlock` component:
329
+
330
+ ```tsx
331
+ import { CodeBlock } from '@colletdev/react';
332
+
333
+ {/* Full terminal chrome */}
334
+ <CodeBlock content="fn main() {}" language="rust" filename="main.rs" />
335
+
336
+ {/* Minimal (no chrome, hover copy button) */}
337
+ <CodeBlock content="npm install @colletdev/core" variant="minimal" />
338
+
339
+ {/* No traffic lights */}
340
+ <CodeBlock content="code" language="js" trafficLights={false} />
341
+ ```
342
+
343
+ See the [CodeBlock component docs](./components.md#codeblock) for full props reference.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colletdev/docs",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Collet component library documentation — API reference, framework guides, and AI agent setup",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,8 @@
13
13
  "./vue": "./vue.md",
14
14
  "./svelte": "./svelte.md",
15
15
  "./angular": "./angular.md",
16
- "./core": "./core.md"
16
+ "./core": "./core.md",
17
+ "./messages": "./messages.md"
17
18
  },
18
19
  "files": [
19
20
  "*.md",