@tangle-network/ui 1.0.0
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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/active-sessions-store-CeOmXgv5.d.ts +85 -0
- package/dist/artifact-pane-DvJyPWV4.d.ts +24 -0
- package/dist/auth.d.ts +74 -0
- package/dist/auth.js +15 -0
- package/dist/button-CMQuQEW_.d.ts +17 -0
- package/dist/chat.d.ts +232 -0
- package/dist/chat.js +30 -0
- package/dist/chunk-2NFQRQOD.js +1009 -0
- package/dist/chunk-2VH6PUXD.js +186 -0
- package/dist/chunk-34A66VBG.js +214 -0
- package/dist/chunk-3OI2QKFD.js +0 -0
- package/dist/chunk-4CLN43XT.js +45 -0
- package/dist/chunk-54SQQMMM.js +156 -0
- package/dist/chunk-5Z5ZYMOJ.js +0 -0
- package/dist/chunk-66BNMOVT.js +167 -0
- package/dist/chunk-6BGQA4BQ.js +0 -0
- package/dist/chunk-7UO2ZMRQ.js +133 -0
- package/dist/chunk-BX6AQMUS.js +183 -0
- package/dist/chunk-CD53GZOM.js +59 -0
- package/dist/chunk-CSAIKY36.js +54 -0
- package/dist/chunk-EEE55AVS.js +1201 -0
- package/dist/chunk-GYPQXTJU.js +230 -0
- package/dist/chunk-HFL6R6IF.js +37 -0
- package/dist/chunk-HJKCSXCH.js +737 -0
- package/dist/chunk-LISXUB4D.js +1222 -0
- package/dist/chunk-LQS34IGP.js +0 -0
- package/dist/chunk-MKTSMWVD.js +109 -0
- package/dist/chunk-NKDZ7GZE.js +192 -0
- package/dist/chunk-OEX7NZE3.js +321 -0
- package/dist/chunk-Q56BYXQF.js +61 -0
- package/dist/chunk-Q7EIIWTC.js +0 -0
- package/dist/chunk-REJESC5U.js +117 -0
- package/dist/chunk-RQGKSCEZ.js +0 -0
- package/dist/chunk-RQHJBTEU.js +10 -0
- package/dist/chunk-TMFOPHHN.js +299 -0
- package/dist/chunk-XGKULLYE.js +40 -0
- package/dist/chunk-XIHMJ7ZQ.js +614 -0
- package/dist/chunk-YJ2G3XO5.js +1048 -0
- package/dist/chunk-YNN4O57I.js +754 -0
- package/dist/code-block-DjXf8eOG.d.ts +19 -0
- package/dist/document-editor-pane-A5LT5H4N.js +12 -0
- package/dist/document-editor-pane-DyDEX_Zm.d.ts +124 -0
- package/dist/editor.d.ts +120 -0
- package/dist/editor.js +34 -0
- package/dist/files.d.ts +175 -0
- package/dist/files.js +20 -0
- package/dist/hooks.d.ts +56 -0
- package/dist/hooks.js +41 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +446 -0
- package/dist/markdown.d.ts +15 -0
- package/dist/markdown.js +14 -0
- package/dist/message-BHWbxBtT.d.ts +15 -0
- package/dist/openui.d.ts +115 -0
- package/dist/openui.js +12 -0
- package/dist/parts-dj7AcUg0.d.ts +36 -0
- package/dist/primitives.d.ts +332 -0
- package/dist/primitives.js +191 -0
- package/dist/run-PfLmDAox.d.ts +41 -0
- package/dist/run.d.ts +69 -0
- package/dist/run.js +36 -0
- package/dist/sdk-hooks.d.ts +285 -0
- package/dist/sdk-hooks.js +31 -0
- package/dist/stores.d.ts +17 -0
- package/dist/stores.js +76 -0
- package/dist/tool-call-feed-Bs3MyQMT.d.ts +68 -0
- package/dist/tool-display-z4JcDmMQ.d.ts +32 -0
- package/dist/tool-previews.d.ts +48 -0
- package/dist/tool-previews.js +21 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +45 -0
- package/dist/utils.js +32 -0
- package/package.json +193 -0
- package/src/auth/auth.tsx +228 -0
- package/src/auth/index.ts +13 -0
- package/src/auth/login-layout.tsx +46 -0
- package/src/chat/agent-timeline.stories.tsx +429 -0
- package/src/chat/agent-timeline.tsx +360 -0
- package/src/chat/chat-container.tsx +486 -0
- package/src/chat/chat-input.stories.tsx +142 -0
- package/src/chat/chat-input.tsx +389 -0
- package/src/chat/chat-message.stories.tsx +237 -0
- package/src/chat/chat-message.tsx +129 -0
- package/src/chat/index.ts +18 -0
- package/src/chat/message-list.stories.tsx +336 -0
- package/src/chat/message-list.tsx +79 -0
- package/src/chat/thinking-indicator.stories.tsx +56 -0
- package/src/chat/thinking-indicator.tsx +30 -0
- package/src/chat/user-message.stories.tsx +92 -0
- package/src/chat/user-message.tsx +43 -0
- package/src/editor/document-editor-pane.tsx +351 -0
- package/src/editor/editor-provider.tsx +428 -0
- package/src/editor/editor-toolbar.tsx +130 -0
- package/src/editor/index.ts +31 -0
- package/src/editor/markdown-conversion.ts +21 -0
- package/src/editor/markdown-document-editor.tsx +137 -0
- package/src/editor/tiptap-editor.tsx +331 -0
- package/src/editor/use-editor.ts +221 -0
- package/src/files/file-artifact-pane.tsx +183 -0
- package/src/files/file-preview.tsx +342 -0
- package/src/files/file-tabs.tsx +71 -0
- package/src/files/file-tree.tsx +258 -0
- package/src/files/index.ts +17 -0
- package/src/files/rich-file-tree.stories.tsx +104 -0
- package/src/files/rich-file-tree.test.tsx +42 -0
- package/src/files/rich-file-tree.tsx +232 -0
- package/src/hooks/index.ts +10 -0
- package/src/hooks/use-auth.ts +153 -0
- package/src/hooks/use-auto-scroll.ts +59 -0
- package/src/hooks/use-dropdown-menu.ts +40 -0
- package/src/hooks/use-live-time.test.tsx +40 -0
- package/src/hooks/use-live-time.ts +27 -0
- package/src/hooks/use-realtime-session.ts +319 -0
- package/src/hooks/use-run-collapse-state.ts +25 -0
- package/src/hooks/use-run-groups.ts +111 -0
- package/src/hooks/use-sdk-session.ts +575 -0
- package/src/hooks/use-sse-stream.ts +475 -0
- package/src/hooks/use-tool-call-stream.ts +96 -0
- package/src/index.ts +14 -0
- package/src/lib/utils.ts +6 -0
- package/src/markdown/code-block.tsx +198 -0
- package/src/markdown/index.ts +2 -0
- package/src/markdown/markdown.stories.tsx +190 -0
- package/src/markdown/markdown.tsx +62 -0
- package/src/openui/index.ts +20 -0
- package/src/openui/openui-artifact-renderer.tsx +542 -0
- package/src/primitives/artifact-pane.tsx +91 -0
- package/src/primitives/avatar.stories.tsx +95 -0
- package/src/primitives/avatar.tsx +47 -0
- package/src/primitives/badge.stories.tsx +57 -0
- package/src/primitives/badge.tsx +97 -0
- package/src/primitives/button.stories.tsx +48 -0
- package/src/primitives/button.tsx +115 -0
- package/src/primitives/card.stories.tsx +53 -0
- package/src/primitives/card.tsx +98 -0
- package/src/primitives/code-block.stories.tsx +115 -0
- package/src/primitives/code-block.tsx +22 -0
- package/src/primitives/design-tokens.stories.tsx +162 -0
- package/src/primitives/dialog.stories.tsx +176 -0
- package/src/primitives/dialog.tsx +137 -0
- package/src/primitives/drop-zone.stories.tsx +123 -0
- package/src/primitives/drop-zone.tsx +131 -0
- package/src/primitives/dropdown-menu.stories.tsx +122 -0
- package/src/primitives/dropdown-menu.tsx +214 -0
- package/src/primitives/empty-state.stories.tsx +81 -0
- package/src/primitives/empty-state.tsx +40 -0
- package/src/primitives/index.ts +118 -0
- package/src/primitives/input.stories.tsx +113 -0
- package/src/primitives/input.tsx +136 -0
- package/src/primitives/label.stories.tsx +84 -0
- package/src/primitives/label.tsx +24 -0
- package/src/primitives/progress.stories.tsx +93 -0
- package/src/primitives/progress.tsx +50 -0
- package/src/primitives/segmented-control.test.tsx +328 -0
- package/src/primitives/segmented-control.tsx +154 -0
- package/src/primitives/select.stories.tsx +164 -0
- package/src/primitives/select.tsx +158 -0
- package/src/primitives/sidebar-drop-zone.stories.tsx +100 -0
- package/src/primitives/sidebar-drop-zone.tsx +149 -0
- package/src/primitives/skeleton.stories.tsx +79 -0
- package/src/primitives/skeleton.tsx +55 -0
- package/src/primitives/stat-card.stories.tsx +137 -0
- package/src/primitives/stat-card.tsx +97 -0
- package/src/primitives/switch.stories.tsx +85 -0
- package/src/primitives/switch.tsx +28 -0
- package/src/primitives/table.stories.tsx +170 -0
- package/src/primitives/table.tsx +116 -0
- package/src/primitives/tabs.stories.tsx +180 -0
- package/src/primitives/tabs.tsx +71 -0
- package/src/primitives/terminal-display.stories.tsx +191 -0
- package/src/primitives/terminal-display.tsx +189 -0
- package/src/primitives/theme-toggle.stories.tsx +32 -0
- package/src/primitives/theme-toggle.tsx +96 -0
- package/src/primitives/toast.stories.tsx +155 -0
- package/src/primitives/toast.tsx +190 -0
- package/src/primitives/upload-progress.stories.tsx +120 -0
- package/src/primitives/upload-progress.tsx +110 -0
- package/src/run/expanded-tool-detail.stories.tsx +182 -0
- package/src/run/expanded-tool-detail.tsx +186 -0
- package/src/run/index.ts +13 -0
- package/src/run/inline-thinking-item.stories.tsx +136 -0
- package/src/run/inline-thinking-item.tsx +120 -0
- package/src/run/inline-tool-item.stories.tsx +222 -0
- package/src/run/inline-tool-item.tsx +190 -0
- package/src/run/run-group.stories.tsx +322 -0
- package/src/run/run-group.tsx +569 -0
- package/src/run/run-item-primitives.tsx +17 -0
- package/src/run/tool-call-feed.stories.tsx +294 -0
- package/src/run/tool-call-feed.tsx +192 -0
- package/src/run/tool-call-step.stories.tsx +198 -0
- package/src/run/tool-call-step.tsx +240 -0
- package/src/sdk-hooks.ts +38 -0
- package/src/stores/active-sessions-store.ts +455 -0
- package/src/stores/chat-store.ts +43 -0
- package/src/stores/index.ts +2 -0
- package/src/tool-previews/command-preview.tsx +116 -0
- package/src/tool-previews/diff-preview.tsx +85 -0
- package/src/tool-previews/glob-results-preview.tsx +98 -0
- package/src/tool-previews/grep-results-preview.tsx +157 -0
- package/src/tool-previews/index.ts +22 -0
- package/src/tool-previews/preview-primitives.tsx +84 -0
- package/src/tool-previews/question-preview.tsx +101 -0
- package/src/tool-previews/web-search-preview.tsx +117 -0
- package/src/tool-previews/write-file-preview.tsx +80 -0
- package/src/types/branding.ts +11 -0
- package/src/types/index.ts +5 -0
- package/src/types/message.ts +13 -0
- package/src/types/parts.ts +51 -0
- package/src/types/run.ts +56 -0
- package/src/types/tool-display.ts +41 -0
- package/src/utils/copy-text.ts +30 -0
- package/src/utils/format.test.ts +43 -0
- package/src/utils/format.ts +56 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/time-ago.ts +9 -0
- package/src/utils/tool-display.ts +238 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import { Code, FileText } from 'lucide-react'
|
|
4
|
+
import { AgentTimeline } from './agent-timeline'
|
|
5
|
+
import type { AgentTimelineItem } from './agent-timeline'
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof AgentTimeline> = {
|
|
8
|
+
title: 'Chat/AgentTimeline',
|
|
9
|
+
component: AgentTimeline,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
backgrounds: { default: 'dark' },
|
|
13
|
+
},
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<div className="min-h-screen bg-[var(--bg-root)]">
|
|
17
|
+
<Story />
|
|
18
|
+
</div>
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default meta
|
|
24
|
+
type Story = StoryObj<typeof AgentTimeline>
|
|
25
|
+
|
|
26
|
+
const NOW = Date.now()
|
|
27
|
+
const t = (offsetSeconds: number) => new Date(NOW - offsetSeconds * 1000)
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Full coding session — agent answers a TypeScript question with tool use
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
const codingSession: AgentTimelineItem[] = [
|
|
34
|
+
{
|
|
35
|
+
id: 'user-1',
|
|
36
|
+
kind: 'message',
|
|
37
|
+
role: 'user',
|
|
38
|
+
content:
|
|
39
|
+
'I need a generic `Result<T, E>` type with helper functions for TypeScript. No external deps.',
|
|
40
|
+
timestamp: t(180),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'status-start',
|
|
44
|
+
kind: 'status',
|
|
45
|
+
label: 'Planning implementation',
|
|
46
|
+
detail: 'Analyzing requirements — generic Result type with Ok/Err constructors and combinators.',
|
|
47
|
+
tone: 'info',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'tool-glob',
|
|
51
|
+
kind: 'tool',
|
|
52
|
+
call: {
|
|
53
|
+
id: 'tc-1',
|
|
54
|
+
type: 'glob',
|
|
55
|
+
label: 'Find **/*.ts in src/',
|
|
56
|
+
status: 'success',
|
|
57
|
+
output:
|
|
58
|
+
'src/index.ts\nsrc/types.ts\nsrc/utils/format.ts\nsrc/utils/parse.ts',
|
|
59
|
+
duration: 18,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'tool-read',
|
|
64
|
+
kind: 'tool',
|
|
65
|
+
call: {
|
|
66
|
+
id: 'tc-2',
|
|
67
|
+
type: 'read',
|
|
68
|
+
label: 'Read src/types.ts',
|
|
69
|
+
status: 'success',
|
|
70
|
+
output:
|
|
71
|
+
'// Existing types\nexport type Maybe<T> = T | null | undefined\nexport type Nullable<T> = T | null',
|
|
72
|
+
duration: 31,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'asst-1',
|
|
77
|
+
kind: 'message',
|
|
78
|
+
role: 'assistant',
|
|
79
|
+
content:
|
|
80
|
+
"Your existing `types.ts` has `Maybe` and `Nullable` — I'll add `Result<T, E>` alongside them and write it to the same file.",
|
|
81
|
+
timestamp: t(150),
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: 'tool-write',
|
|
85
|
+
kind: 'tool',
|
|
86
|
+
call: {
|
|
87
|
+
id: 'tc-3',
|
|
88
|
+
type: 'write',
|
|
89
|
+
label: 'Write src/types.ts',
|
|
90
|
+
status: 'success',
|
|
91
|
+
output: 'File written — 47 lines added.',
|
|
92
|
+
duration: 22,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'tool-bash-test',
|
|
97
|
+
kind: 'tool',
|
|
98
|
+
call: {
|
|
99
|
+
id: 'tc-4',
|
|
100
|
+
type: 'bash',
|
|
101
|
+
label: 'npx tsc --noEmit',
|
|
102
|
+
status: 'success',
|
|
103
|
+
detail: 'npx tsc --noEmit --strict',
|
|
104
|
+
output: '✓ No type errors',
|
|
105
|
+
duration: 1840,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'status-done',
|
|
110
|
+
kind: 'status',
|
|
111
|
+
label: 'Type-checks clean',
|
|
112
|
+
tone: 'success',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'asst-final',
|
|
116
|
+
kind: 'message',
|
|
117
|
+
role: 'assistant',
|
|
118
|
+
content: `Here's the \`Result<T, E>\` implementation added to \`src/types.ts\`:
|
|
119
|
+
|
|
120
|
+
\`\`\`typescript
|
|
121
|
+
export type Ok<T> = { readonly ok: true; readonly value: T }
|
|
122
|
+
export type Err<E> = { readonly ok: false; readonly error: E }
|
|
123
|
+
export type Result<T, E = Error> = Ok<T> | Err<E>
|
|
124
|
+
|
|
125
|
+
export const ok = <T>(value: T): Ok<T> => ({ ok: true, value })
|
|
126
|
+
export const err = <E>(error: E): Err<E> => ({ ok: false, error })
|
|
127
|
+
|
|
128
|
+
export function map<T, U, E>(
|
|
129
|
+
result: Result<T, E>,
|
|
130
|
+
fn: (value: T) => U,
|
|
131
|
+
): Result<U, E> {
|
|
132
|
+
return result.ok ? ok(fn(result.value)) : result
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function flatMap<T, U, E>(
|
|
136
|
+
result: Result<T, E>,
|
|
137
|
+
fn: (value: T) => Result<U, E>,
|
|
138
|
+
): Result<U, E> {
|
|
139
|
+
return result.ok ? fn(result.value) : result
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function unwrapOr<T, E>(result: Result<T, E>, fallback: T): T {
|
|
143
|
+
return result.ok ? result.value : fallback
|
|
144
|
+
}
|
|
145
|
+
\`\`\`
|
|
146
|
+
|
|
147
|
+
All helpers are zero-dependency and fully typed. \`tsc --strict\` passes clean.`,
|
|
148
|
+
timestamp: t(120),
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'artifact-types',
|
|
152
|
+
kind: 'artifact',
|
|
153
|
+
title: 'src/types.ts',
|
|
154
|
+
description: 'Result<T, E> type + ok / err / map / flatMap / unwrapOr helpers',
|
|
155
|
+
tone: 'success',
|
|
156
|
+
icon: <FileText className="h-4 w-4" />,
|
|
157
|
+
meta: <>47 lines added · TypeScript · Zero deps</>,
|
|
158
|
+
},
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
export const CodingSession: Story = {
|
|
162
|
+
args: {
|
|
163
|
+
items: codingSession,
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Session with thinking indicator active
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
export const WhileThinking: Story = {
|
|
172
|
+
args: {
|
|
173
|
+
items: [
|
|
174
|
+
{
|
|
175
|
+
id: 'user-1',
|
|
176
|
+
kind: 'message',
|
|
177
|
+
role: 'user',
|
|
178
|
+
content: 'Implement a distributed rate limiter using Redis sorted sets.',
|
|
179
|
+
timestamp: new Date(),
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: 'status-planning',
|
|
183
|
+
kind: 'status',
|
|
184
|
+
label: 'Reading codebase',
|
|
185
|
+
tone: 'info',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'tool-glob',
|
|
189
|
+
kind: 'tool',
|
|
190
|
+
call: {
|
|
191
|
+
id: 'tc-1',
|
|
192
|
+
type: 'glob',
|
|
193
|
+
label: 'Find **/*.ts in src/',
|
|
194
|
+
status: 'success',
|
|
195
|
+
duration: 14,
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
isThinking: true,
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// Tool group — parallel reads shown together
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
export const WithToolGroup: Story = {
|
|
208
|
+
args: {
|
|
209
|
+
items: [
|
|
210
|
+
{
|
|
211
|
+
id: 'user-1',
|
|
212
|
+
kind: 'message',
|
|
213
|
+
role: 'user',
|
|
214
|
+
content:
|
|
215
|
+
'Audit all the route handlers in src/routes/ and tell me which ones are missing auth middleware.',
|
|
216
|
+
timestamp: t(90),
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: 'tool-group-reads',
|
|
220
|
+
kind: 'tool_group',
|
|
221
|
+
title: 'Reading route files',
|
|
222
|
+
calls: [
|
|
223
|
+
{
|
|
224
|
+
id: 'tc-1',
|
|
225
|
+
type: 'read',
|
|
226
|
+
label: 'Read src/routes/users.ts',
|
|
227
|
+
status: 'success',
|
|
228
|
+
output: "router.get('/', authMiddleware, listUsers)\nrouter.post('/', authMiddleware, createUser)",
|
|
229
|
+
duration: 24,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'tc-2',
|
|
233
|
+
type: 'read',
|
|
234
|
+
label: 'Read src/routes/sessions.ts',
|
|
235
|
+
status: 'success',
|
|
236
|
+
output: "router.get('/', listSessions) // missing auth!\nrouter.delete('/:id', authMiddleware, deleteSession)",
|
|
237
|
+
duration: 19,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: 'tc-3',
|
|
241
|
+
type: 'read',
|
|
242
|
+
label: 'Read src/routes/health.ts',
|
|
243
|
+
status: 'success',
|
|
244
|
+
output: "router.get('/', healthCheck) // intentionally public",
|
|
245
|
+
duration: 11,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: 'status-warn',
|
|
251
|
+
kind: 'status',
|
|
252
|
+
label: 'Auth gap found in sessions route',
|
|
253
|
+
detail: 'GET /sessions is publicly accessible — no authMiddleware applied.',
|
|
254
|
+
tone: 'warning',
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: 'asst-1',
|
|
258
|
+
kind: 'message',
|
|
259
|
+
role: 'assistant',
|
|
260
|
+
content: `Found one unprotected route:
|
|
261
|
+
|
|
262
|
+
| Route | File | Auth |
|
|
263
|
+
|-------|------|------|
|
|
264
|
+
| \`GET /users\` | users.ts | ✅ |
|
|
265
|
+
| \`POST /users\` | users.ts | ✅ |
|
|
266
|
+
| \`GET /sessions\` | sessions.ts | ❌ Missing |
|
|
267
|
+
| \`DELETE /sessions/:id\` | sessions.ts | ✅ |
|
|
268
|
+
| \`GET /health\` | health.ts | ✅ (intentional) |
|
|
269
|
+
|
|
270
|
+
**Fix:** add \`authMiddleware\` to \`router.get('/', ...)\` in \`sessions.ts\`.`,
|
|
271
|
+
timestamp: t(60),
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
// Error state
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
|
|
281
|
+
export const WithError: Story = {
|
|
282
|
+
args: {
|
|
283
|
+
items: [
|
|
284
|
+
{
|
|
285
|
+
id: 'user-1',
|
|
286
|
+
kind: 'message',
|
|
287
|
+
role: 'user',
|
|
288
|
+
content: 'Run the test suite.',
|
|
289
|
+
timestamp: t(30),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: 'tool-bash',
|
|
293
|
+
kind: 'tool',
|
|
294
|
+
call: {
|
|
295
|
+
id: 'tc-1',
|
|
296
|
+
type: 'bash',
|
|
297
|
+
label: 'pnpm test',
|
|
298
|
+
status: 'error',
|
|
299
|
+
detail: 'pnpm test --run',
|
|
300
|
+
output:
|
|
301
|
+
'FAIL src/utils/parse.test.ts\n ✕ parseDate handles invalid input (12ms)\n Expected: { ok: false }\n Received: { ok: true, value: Invalid Date }\n\nTest Suites: 1 failed, 4 passed\nTests: 1 failed, 31 passed',
|
|
302
|
+
duration: 3400,
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: 'status-error',
|
|
307
|
+
kind: 'status',
|
|
308
|
+
label: '1 test failed — parseDate accepts Invalid Date',
|
|
309
|
+
detail: 'src/utils/parse.test.ts:14 — parseDate should return Err for non-date strings.',
|
|
310
|
+
tone: 'error',
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: 'asst-1',
|
|
314
|
+
kind: 'message',
|
|
315
|
+
role: 'assistant',
|
|
316
|
+
content: '`parseDate` returns `ok(new Date(str))` without validating `isNaN`. Fix: check `isNaN(result.getTime())` and return `err(...)` instead.',
|
|
317
|
+
timestamp: t(10),
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// ---------------------------------------------------------------------------
|
|
324
|
+
// Artifact handoff
|
|
325
|
+
// ---------------------------------------------------------------------------
|
|
326
|
+
|
|
327
|
+
export const WithArtifact: Story = {
|
|
328
|
+
args: {
|
|
329
|
+
items: [
|
|
330
|
+
{
|
|
331
|
+
id: 'user-1',
|
|
332
|
+
kind: 'message',
|
|
333
|
+
role: 'user',
|
|
334
|
+
content: 'Generate an OpenAPI spec for the users API.',
|
|
335
|
+
timestamp: t(60),
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: 'tool-write',
|
|
339
|
+
kind: 'tool',
|
|
340
|
+
call: {
|
|
341
|
+
id: 'tc-1',
|
|
342
|
+
type: 'write',
|
|
343
|
+
label: 'Write openapi.yaml',
|
|
344
|
+
status: 'success',
|
|
345
|
+
output: '187 lines written.',
|
|
346
|
+
duration: 44,
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: 'asst-1',
|
|
351
|
+
kind: 'message',
|
|
352
|
+
role: 'assistant',
|
|
353
|
+
content: 'OpenAPI 3.1 spec generated with all CRUD endpoints, request/response schemas, and error codes.',
|
|
354
|
+
timestamp: t(30),
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
id: 'artifact-spec',
|
|
358
|
+
kind: 'artifact',
|
|
359
|
+
title: 'openapi.yaml',
|
|
360
|
+
description: 'OpenAPI 3.1 specification — Users API with auth, CRUD, and error schemas',
|
|
361
|
+
tone: 'success',
|
|
362
|
+
icon: <Code className="h-4 w-4" />,
|
|
363
|
+
meta: <>187 lines · OpenAPI 3.1 · YAML</>,
|
|
364
|
+
onClick: () => alert('Open openapi.yaml'),
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
},
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
// Empty state
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
|
|
374
|
+
export const Empty: Story = {
|
|
375
|
+
args: {
|
|
376
|
+
items: [],
|
|
377
|
+
emptyState: (
|
|
378
|
+
<div className="text-center text-sm text-muted-foreground">
|
|
379
|
+
No messages yet — start a conversation.
|
|
380
|
+
</div>
|
|
381
|
+
),
|
|
382
|
+
},
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ---------------------------------------------------------------------------
|
|
386
|
+
// All status tones
|
|
387
|
+
// ---------------------------------------------------------------------------
|
|
388
|
+
|
|
389
|
+
export const StatusTones: Story = {
|
|
390
|
+
args: {
|
|
391
|
+
items: [
|
|
392
|
+
{
|
|
393
|
+
id: 's-default',
|
|
394
|
+
kind: 'status',
|
|
395
|
+
label: 'Default status',
|
|
396
|
+
detail: 'Neutral informational message.',
|
|
397
|
+
tone: 'default',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
id: 's-info',
|
|
401
|
+
kind: 'status',
|
|
402
|
+
label: 'Info status',
|
|
403
|
+
detail: 'Agent is reading files.',
|
|
404
|
+
tone: 'info',
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: 's-success',
|
|
408
|
+
kind: 'status',
|
|
409
|
+
label: 'Success status',
|
|
410
|
+
detail: 'All tests passed.',
|
|
411
|
+
tone: 'success',
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: 's-warning',
|
|
415
|
+
kind: 'status',
|
|
416
|
+
label: 'Warning status',
|
|
417
|
+
detail: 'Unprotected route detected.',
|
|
418
|
+
tone: 'warning',
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
id: 's-error',
|
|
422
|
+
kind: 'status',
|
|
423
|
+
label: 'Error status',
|
|
424
|
+
detail: '3 tests failed.',
|
|
425
|
+
tone: 'error',
|
|
426
|
+
},
|
|
427
|
+
],
|
|
428
|
+
},
|
|
429
|
+
}
|