@flamingo-stack/openframe-frontend-core 0.0.421-snapshot.20260713170448 → 0.0.421
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/{chunk-O3FSSWV4.cjs → chunk-4PS4F4WL.cjs} +7 -7
- package/dist/{chunk-O3FSSWV4.cjs.map → chunk-4PS4F4WL.cjs.map} +1 -1
- package/dist/{chunk-LHM2VUTO.js → chunk-4XTIANMS.js} +2 -2
- package/dist/{chunk-HFK33T6A.js → chunk-5TL2VVEN.js} +4 -4
- package/dist/{chunk-ULUH2X53.cjs → chunk-5U6C3RXX.cjs} +11 -11
- package/dist/{chunk-ULUH2X53.cjs.map → chunk-5U6C3RXX.cjs.map} +1 -1
- package/dist/{chunk-YZQNKMFQ.cjs → chunk-5UZULT35.cjs} +31 -31
- package/dist/{chunk-YZQNKMFQ.cjs.map → chunk-5UZULT35.cjs.map} +1 -1
- package/dist/{chunk-YJDVAT7J.js → chunk-5WXUR7LF.js} +3 -39
- package/dist/chunk-5WXUR7LF.js.map +1 -0
- package/dist/{chunk-2JNFQEVX.cjs → chunk-6HCWW4YM.cjs} +26 -26
- package/dist/{chunk-2JNFQEVX.cjs.map → chunk-6HCWW4YM.cjs.map} +1 -1
- package/dist/{chunk-LWC2U5OC.cjs → chunk-E5HKIBRS.cjs} +9 -9
- package/dist/{chunk-LWC2U5OC.cjs.map → chunk-E5HKIBRS.cjs.map} +1 -1
- package/dist/{chunk-4TMMYZTY.js → chunk-FHAG7O27.js} +2 -2
- package/dist/{chunk-WQEEGFDM.js → chunk-ISUMLEJ6.js} +2 -2
- package/dist/{chunk-DUHM44CQ.js → chunk-JMHU37Y6.js} +2 -2
- package/dist/{chunk-YUMFRC3D.js → chunk-LHJHMZYU.js} +4 -4
- package/dist/{chunk-WAQH35VG.cjs → chunk-PCM4HJO4.cjs} +26 -26
- package/dist/{chunk-WAQH35VG.cjs.map → chunk-PCM4HJO4.cjs.map} +1 -1
- package/dist/{chunk-PO4PXWZN.cjs → chunk-PMFK7ZKC.cjs} +5 -5
- package/dist/{chunk-PO4PXWZN.cjs.map → chunk-PMFK7ZKC.cjs.map} +1 -1
- package/dist/{chunk-RGKGRS2T.cjs → chunk-RKNF2DHY.cjs} +59 -59
- package/dist/{chunk-RGKGRS2T.cjs.map → chunk-RKNF2DHY.cjs.map} +1 -1
- package/dist/{chunk-B62DI2SC.cjs → chunk-RQXFDMRY.cjs} +15 -15
- package/dist/{chunk-B62DI2SC.cjs.map → chunk-RQXFDMRY.cjs.map} +1 -1
- package/dist/{chunk-3BGWK5QI.js → chunk-TJ7HD4KI.js} +4 -4
- package/dist/{chunk-JSL3VXGJ.js → chunk-UHSVSDF5.js} +2 -2
- package/dist/{chunk-6F5OKJTW.js → chunk-UKIVJU3A.js} +4 -4
- package/dist/{chunk-BF5BXKM7.cjs → chunk-UZOYTAK7.cjs} +62 -62
- package/dist/{chunk-BF5BXKM7.cjs.map → chunk-UZOYTAK7.cjs.map} +1 -1
- package/dist/{chunk-KUDLV25M.cjs → chunk-WDZATJTF.cjs} +127 -163
- package/dist/chunk-WDZATJTF.cjs.map +1 -0
- package/dist/{chunk-XFYQV2K2.js → chunk-XVWDKBBF.js} +2 -2
- package/dist/{chunk-A2IRUIUJ.cjs → chunk-YLSDXDD7.cjs} +37 -37
- package/dist/{chunk-A2IRUIUJ.cjs.map → chunk-YLSDXDD7.cjs.map} +1 -1
- package/dist/{chunk-4BWQYGIY.js → chunk-ZXWSOOEH.js} +2 -2
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/chat-input.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/types/api.types.d.ts +0 -10
- package/dist/components/chat/types/api.types.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +128 -128
- package/dist/components/index.js +9 -9
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/chat/chat-input.tsx +1 -5
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +3 -52
- package/src/components/chat/hooks/use-realtime-chunk-processor.ts +3 -25
- package/src/components/chat/types/api.types.ts +0 -10
- package/dist/chunk-KUDLV25M.cjs.map +0 -1
- package/dist/chunk-YJDVAT7J.js.map +0 -1
- package/src/stories/ApprovalRequestMessageClient.stories.tsx +0 -89
- package/src/stories/ChatMessageEnhanced.stories.tsx +0 -219
- package/src/stories/ChatTypingIndicator.stories.tsx +0 -51
- package/src/stories/ContextCompactionDisplay.stories.tsx +0 -44
- package/src/stories/ErrorMessageDisplay.stories.tsx +0 -66
- package/src/stories/ThinkingDisplay.stories.tsx +0 -63
- /package/dist/{chunk-LHM2VUTO.js.map → chunk-4XTIANMS.js.map} +0 -0
- /package/dist/{chunk-HFK33T6A.js.map → chunk-5TL2VVEN.js.map} +0 -0
- /package/dist/{chunk-4TMMYZTY.js.map → chunk-FHAG7O27.js.map} +0 -0
- /package/dist/{chunk-WQEEGFDM.js.map → chunk-ISUMLEJ6.js.map} +0 -0
- /package/dist/{chunk-DUHM44CQ.js.map → chunk-JMHU37Y6.js.map} +0 -0
- /package/dist/{chunk-YUMFRC3D.js.map → chunk-LHJHMZYU.js.map} +0 -0
- /package/dist/{chunk-3BGWK5QI.js.map → chunk-TJ7HD4KI.js.map} +0 -0
- /package/dist/{chunk-JSL3VXGJ.js.map → chunk-UHSVSDF5.js.map} +0 -0
- /package/dist/{chunk-6F5OKJTW.js.map → chunk-UKIVJU3A.js.map} +0 -0
- /package/dist/{chunk-XFYQV2K2.js.map → chunk-XVWDKBBF.js.map} +0 -0
- /package/dist/{chunk-4BWQYGIY.js.map → chunk-ZXWSOOEH.js.map} +0 -0
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ApprovalRequestMessage } from "../components/chat/approval-request-message";
|
|
5
|
-
import type { ApprovalRequestData } from "../components/chat/types";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* CLIENT (end-user Fae desktop app) variant of the single-command approval
|
|
9
|
-
* card — Figma node 203-11947 ("fae-approval-block").
|
|
10
|
-
*
|
|
11
|
-
* Same component and props as the Admin card, driven by `variant="client"`.
|
|
12
|
-
* The end client sees ONLY the BE-generated title (`explanation`) plus the
|
|
13
|
-
* Approve/Reject buttons, or the full-text resolved pill
|
|
14
|
-
* ("APPROVED BY JOHN SMITH"). The raw command is never rendered.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const baseData: ApprovalRequestData = {
|
|
18
|
-
command: 'brew install --cask slack',
|
|
19
|
-
requestId: "req-client-1",
|
|
20
|
-
approvalType: "CLIENT",
|
|
21
|
-
// BE-generated human-readable title — the ONLY content the client sees.
|
|
22
|
-
explanation: "Install Slack via Homebrew Cask on macOS",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const plainDecorator =
|
|
26
|
-
(width?: number) => (Story: React.ComponentType) => (
|
|
27
|
-
<div style={{ maxWidth: width ?? 400, background: "var(--color-bg)" }}>
|
|
28
|
-
<Story />
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const meta = {
|
|
33
|
-
title: "Chat/Client/ApprovalRequestMessage",
|
|
34
|
-
component: ApprovalRequestMessage,
|
|
35
|
-
tags: ["autodocs"],
|
|
36
|
-
args: { variant: "client" },
|
|
37
|
-
parameters: {
|
|
38
|
-
docs: {
|
|
39
|
-
description: {
|
|
40
|
-
component:
|
|
41
|
-
"CLIENT (Fae end-user) single-command approval card — title-only with Approve/Reject or a full-text status pill ('APPROVED BY {NAME}'). The raw command is never shown. Gated by variant='client' (Figma 203-11947).",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
decorators: [plainDecorator()],
|
|
46
|
-
} satisfies Meta<typeof ApprovalRequestMessage>;
|
|
47
|
-
|
|
48
|
-
export default meta;
|
|
49
|
-
type Story = StoryObj<typeof meta>;
|
|
50
|
-
|
|
51
|
-
/** Pending — BE title + Approve / Reject buttons. No command block. */
|
|
52
|
-
export const Pending: Story = {
|
|
53
|
-
args: {
|
|
54
|
-
data: baseData,
|
|
55
|
-
status: "pending",
|
|
56
|
-
onApprove: () => {},
|
|
57
|
-
onReject: () => {},
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/** Approved with resolver — green "APPROVED BY JOHN SMITH" pill. */
|
|
62
|
-
export const ApprovedByUser: Story = {
|
|
63
|
-
args: { data: baseData, status: "approved", resolvedByName: "John Smith" },
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/** Approved without a resolver name — plain "APPROVED" pill (system action). */
|
|
67
|
-
export const Approved: Story = {
|
|
68
|
-
args: { data: baseData, status: "approved" },
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
/** Rejected with resolver — red "REJECTED BY JOHN SMITH" pill. */
|
|
72
|
-
export const RejectedByUser: Story = {
|
|
73
|
-
args: { data: baseData, status: "rejected", resolvedByName: "John Smith" },
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/** Cancelled — grey status pill. */
|
|
77
|
-
export const Cancelled: Story = {
|
|
78
|
-
args: { data: baseData, status: "cancelled" },
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/** Missing BE title — falls back to the "Approval required" placeholder. */
|
|
82
|
-
export const NoTitleFallback: Story = {
|
|
83
|
-
args: {
|
|
84
|
-
data: { ...baseData, explanation: undefined },
|
|
85
|
-
status: "pending",
|
|
86
|
-
onApprove: () => {},
|
|
87
|
-
onReject: () => {},
|
|
88
|
-
},
|
|
89
|
-
};
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ChatMessageEnhanced } from "../components/chat/chat-message-enhanced";
|
|
5
|
-
import { ChatTypingIndicator } from "../components/chat/chat-typing-indicator";
|
|
6
|
-
import type { MessageSegment } from "../components/chat/types";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* `<ChatMessageEnhanced>` — THE chat message renderer used by
|
|
10
|
-
* ChatMessageList / EmbeddableChat. Renders the avatar + name + timestamp
|
|
11
|
-
* header (Fae pink / Mingo cyan / user grey) and every message-segment type:
|
|
12
|
-
* text (markdown), thinking, tool_execution, approval_request/batch, error,
|
|
13
|
-
* context_compaction.
|
|
14
|
-
*
|
|
15
|
-
* The Fae conversation scenes reproduce the Fae desktop-app flow: greeting →
|
|
16
|
-
* user request → approval block → typing dots (Figma "fae-approval-block").
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
// Fixed time-of-day so the header always reads "2:47 PM" — messages dated
|
|
20
|
-
// today render time-only (see formatMessageTimestamp).
|
|
21
|
-
const at247 = () => {
|
|
22
|
-
const d = new Date();
|
|
23
|
-
d.setHours(14, 47, 0, 0);
|
|
24
|
-
return d;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const panelDecorator = (Story: React.ComponentType) => (
|
|
28
|
-
<div
|
|
29
|
-
style={{ maxWidth: 640, background: "var(--color-bg)" }}
|
|
30
|
-
className="p-[var(--spacing-system-m)]"
|
|
31
|
-
>
|
|
32
|
-
<Story />
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const meta = {
|
|
37
|
-
title: "Chat/ChatMessageEnhanced",
|
|
38
|
-
component: ChatMessageEnhanced,
|
|
39
|
-
tags: ["autodocs"],
|
|
40
|
-
parameters: {
|
|
41
|
-
docs: {
|
|
42
|
-
description: {
|
|
43
|
-
component:
|
|
44
|
-
"Single chat message row — avatar + colored author name + timestamp header, plus the full segment renderer (text/thinking/tool/approval/error/compaction). Used by ChatMessageList in both the admin (Mingo) and client (Fae) chats.",
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
decorators: [panelDecorator],
|
|
49
|
-
} satisfies Meta<typeof ChatMessageEnhanced>;
|
|
50
|
-
|
|
51
|
-
export default meta;
|
|
52
|
-
type Story = StoryObj<typeof meta>;
|
|
53
|
-
|
|
54
|
-
/** Assistant (Fae) text message — pink mono name + timestamp. */
|
|
55
|
-
export const AssistantFae: Story = {
|
|
56
|
-
args: {
|
|
57
|
-
role: "assistant",
|
|
58
|
-
name: "Fae",
|
|
59
|
-
content: "Good morning! How can I help you today?",
|
|
60
|
-
timestamp: at247(),
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
/** Assistant (Mingo) text message — cyan mono name. */
|
|
65
|
-
export const AssistantMingo: Story = {
|
|
66
|
-
args: {
|
|
67
|
-
role: "assistant",
|
|
68
|
-
name: "Mingo",
|
|
69
|
-
assistantType: "mingo",
|
|
70
|
-
content: "I've pulled the device list for Acme Corp — 3 endpoints are offline.",
|
|
71
|
-
timestamp: at247(),
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/** User message — grey mono name, no avatar block until user avatars ship. */
|
|
76
|
-
export const UserMessage: Story = {
|
|
77
|
-
args: {
|
|
78
|
-
role: "user",
|
|
79
|
-
name: "John Smith",
|
|
80
|
-
content: "hey can u install slack on my mac",
|
|
81
|
-
timestamp: at247(),
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Fae flow, step 1 — greeting, user request, and the assistant "typing"
|
|
87
|
-
* row (empty message + `<ChatTypingIndicator>`, as the Fae desktop host
|
|
88
|
-
* renders it while the reply streams in).
|
|
89
|
-
*/
|
|
90
|
-
export const FaeConversationTyping: Story = {
|
|
91
|
-
args: { role: "assistant", content: "" },
|
|
92
|
-
render: () => (
|
|
93
|
-
<div className="flex flex-col">
|
|
94
|
-
<ChatMessageEnhanced
|
|
95
|
-
role="assistant"
|
|
96
|
-
name="Fae"
|
|
97
|
-
content="Good morning! How can I help you today?"
|
|
98
|
-
timestamp={at247()}
|
|
99
|
-
/>
|
|
100
|
-
<ChatMessageEnhanced
|
|
101
|
-
role="user"
|
|
102
|
-
name="John Smith"
|
|
103
|
-
content="hey can u install slack on my mac"
|
|
104
|
-
timestamp={at247()}
|
|
105
|
-
/>
|
|
106
|
-
<ChatMessageEnhanced role="assistant" name="Fae" content="" isTyping timestamp={at247()} />
|
|
107
|
-
<ChatTypingIndicator size="sm" />
|
|
108
|
-
</div>
|
|
109
|
-
),
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const approvedSegments: MessageSegment[] = [
|
|
113
|
-
{ type: "text", text: "On it! Just need your quick approval here." },
|
|
114
|
-
{
|
|
115
|
-
type: "approval_request",
|
|
116
|
-
data: {
|
|
117
|
-
command: "brew install --cask slack",
|
|
118
|
-
requestId: "req-1",
|
|
119
|
-
approvalType: "CLIENT",
|
|
120
|
-
explanation: "Install Slack via Homebrew Cask on macOS",
|
|
121
|
-
},
|
|
122
|
-
status: "approved",
|
|
123
|
-
resolvedByName: "John Smith",
|
|
124
|
-
},
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Fae flow, step 2 — the reply carries an `approval_request` segment
|
|
129
|
-
* rendered as the CLIENT card with the resolved "APPROVED BY JOHN SMITH"
|
|
130
|
-
* pill (`approvalVariant="client"`), then Fae keeps typing.
|
|
131
|
-
*/
|
|
132
|
-
export const FaeConversationApproved: Story = {
|
|
133
|
-
args: { role: "assistant", content: "" },
|
|
134
|
-
render: () => (
|
|
135
|
-
<div className="flex flex-col">
|
|
136
|
-
<ChatMessageEnhanced
|
|
137
|
-
role="assistant"
|
|
138
|
-
name="Fae"
|
|
139
|
-
content="Good morning! How can I help you today?"
|
|
140
|
-
timestamp={at247()}
|
|
141
|
-
/>
|
|
142
|
-
<ChatMessageEnhanced
|
|
143
|
-
role="user"
|
|
144
|
-
name="John Smith"
|
|
145
|
-
content="hey can u install slack on my mac"
|
|
146
|
-
timestamp={at247()}
|
|
147
|
-
/>
|
|
148
|
-
<ChatMessageEnhanced
|
|
149
|
-
role="assistant"
|
|
150
|
-
name="Fae"
|
|
151
|
-
content={approvedSegments}
|
|
152
|
-
approvalVariant="client"
|
|
153
|
-
timestamp={at247()}
|
|
154
|
-
/>
|
|
155
|
-
<ChatMessageEnhanced role="assistant" name="Fae" content="" isTyping timestamp={at247()} />
|
|
156
|
-
<ChatTypingIndicator size="sm" />
|
|
157
|
-
</div>
|
|
158
|
-
),
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
/** Pending approval inside a message — Approve/Reject buttons (client card). */
|
|
162
|
-
export const PendingApprovalSegment: Story = {
|
|
163
|
-
args: {
|
|
164
|
-
role: "assistant",
|
|
165
|
-
name: "Fae",
|
|
166
|
-
approvalVariant: "client",
|
|
167
|
-
timestamp: at247(),
|
|
168
|
-
content: [
|
|
169
|
-
{ type: "text", text: "On it! Just need your quick approval here." },
|
|
170
|
-
{
|
|
171
|
-
type: "approval_request",
|
|
172
|
-
data: {
|
|
173
|
-
command: "brew install --cask slack",
|
|
174
|
-
requestId: "req-2",
|
|
175
|
-
approvalType: "CLIENT",
|
|
176
|
-
explanation: "Install Slack via Homebrew Cask on macOS",
|
|
177
|
-
},
|
|
178
|
-
status: "pending",
|
|
179
|
-
onApprove: () => {},
|
|
180
|
-
onReject: () => {},
|
|
181
|
-
},
|
|
182
|
-
] satisfies MessageSegment[],
|
|
183
|
-
},
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
/** Every remaining segment type in one message — thinking, tool execution, context compaction, error. */
|
|
187
|
-
export const AllSegmentTypes: Story = {
|
|
188
|
-
args: {
|
|
189
|
-
role: "assistant",
|
|
190
|
-
name: "Fae",
|
|
191
|
-
timestamp: at247(),
|
|
192
|
-
content: [
|
|
193
|
-
{
|
|
194
|
-
type: "thinking",
|
|
195
|
-
text: "The user wants Slack installed. Homebrew is present on the endpoint, so `brew install --cask slack` is the cleanest path.",
|
|
196
|
-
},
|
|
197
|
-
{ type: "text", text: "Installing Slack now." },
|
|
198
|
-
{
|
|
199
|
-
type: "tool_execution",
|
|
200
|
-
data: {
|
|
201
|
-
type: "EXECUTED_TOOL",
|
|
202
|
-
integratedToolType: "OPENFRAME_RMM",
|
|
203
|
-
toolFunction: "run_script",
|
|
204
|
-
toolTitle: "Install Slack via Homebrew Cask",
|
|
205
|
-
parameters: { command: "brew install --cask slack" },
|
|
206
|
-
result: "🍺 slack was successfully installed!",
|
|
207
|
-
success: true,
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
{ type: "context_compaction", status: "completed" },
|
|
211
|
-
{
|
|
212
|
-
type: "error",
|
|
213
|
-
title: "Notification delivery failed",
|
|
214
|
-
details: "Slack webhook returned 429 — the completion ping was skipped. The install itself succeeded.",
|
|
215
|
-
},
|
|
216
|
-
{ type: "text", text: "Done — Slack is installed and ready to use." },
|
|
217
|
-
] satisfies MessageSegment[],
|
|
218
|
-
},
|
|
219
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ChatTypingIndicator } from "../components/chat/chat-typing-indicator";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Three pulsing dots shown while the assistant reply streams in — the
|
|
8
|
-
* "Fae is typing" affordance under the message header. Also rendered
|
|
9
|
-
* inside `<ChatInput>` (size="sm") while a send is in flight.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const plainDecorator = (Story: React.ComponentType) => (
|
|
13
|
-
<div style={{ maxWidth: 400, background: "var(--color-bg)" }} className="p-4">
|
|
14
|
-
<Story />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const meta = {
|
|
19
|
-
title: "Chat/ChatTypingIndicator",
|
|
20
|
-
component: ChatTypingIndicator,
|
|
21
|
-
tags: ["autodocs"],
|
|
22
|
-
parameters: {
|
|
23
|
-
docs: {
|
|
24
|
-
description: {
|
|
25
|
-
component:
|
|
26
|
-
"Pulsing three-dot typing indicator. Sizes sm/md/lg; optional 'Assistant is typing' label; dot color overridable via dotClassName.",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
decorators: [plainDecorator],
|
|
31
|
-
} satisfies Meta<typeof ChatTypingIndicator>;
|
|
32
|
-
|
|
33
|
-
export default meta;
|
|
34
|
-
type Story = StoryObj<typeof meta>;
|
|
35
|
-
|
|
36
|
-
/** Default — medium dots, no label. */
|
|
37
|
-
export const Default: Story = {};
|
|
38
|
-
|
|
39
|
-
/** Small — as rendered inside ChatInput while a send is in flight. */
|
|
40
|
-
export const Small: Story = { args: { size: "sm" } };
|
|
41
|
-
|
|
42
|
-
/** Large dots. */
|
|
43
|
-
export const Large: Story = { args: { size: "lg" } };
|
|
44
|
-
|
|
45
|
-
/** With the "Assistant is typing" label. */
|
|
46
|
-
export const WithText: Story = { args: { showText: true } };
|
|
47
|
-
|
|
48
|
-
/** Muted dots via dotClassName override. */
|
|
49
|
-
export const MutedDots: Story = {
|
|
50
|
-
args: { dotClassName: "bg-ods-text-secondary" },
|
|
51
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ContextCompactionDisplay } from "../components/chat/context-compaction-display";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Inline status pill for `context_compaction` message segments — shown when
|
|
8
|
-
* the conversation hits the context limit and earlier messages get
|
|
9
|
-
* summarized. `started` shows a dots loader, `completed` a green check.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const plainDecorator = (Story: React.ComponentType) => (
|
|
13
|
-
<div style={{ maxWidth: 640, background: "var(--color-bg)" }} className="p-4">
|
|
14
|
-
<Story />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const meta = {
|
|
19
|
-
title: "Chat/ContextCompactionDisplay",
|
|
20
|
-
component: ContextCompactionDisplay,
|
|
21
|
-
tags: ["autodocs"],
|
|
22
|
-
parameters: {
|
|
23
|
-
docs: {
|
|
24
|
-
description: {
|
|
25
|
-
component:
|
|
26
|
-
"Renders a `context_compaction` message segment — 'Context limit reached…' with a dots loader while running, 'Earlier context summarized.' with a check once done.",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
decorators: [plainDecorator],
|
|
31
|
-
} satisfies Meta<typeof ContextCompactionDisplay>;
|
|
32
|
-
|
|
33
|
-
export default meta;
|
|
34
|
-
type Story = StoryObj<typeof meta>;
|
|
35
|
-
|
|
36
|
-
/** In progress — summarizing earlier messages. */
|
|
37
|
-
export const Started: Story = {
|
|
38
|
-
args: { status: "started" },
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/** Finished — earlier context summarized. */
|
|
42
|
-
export const Completed: Story = {
|
|
43
|
-
args: { status: "completed" },
|
|
44
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ErrorMessageDisplay } from "../components/chat/error-message-display";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Inline error card for `error` message segments — mono uppercase title
|
|
8
|
-
* with an alert icon; optional details expand under the chevron.
|
|
9
|
-
* `type` tints the icon: error (red) / warning (yellow) / info (grey).
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const plainDecorator = (Story: React.ComponentType) => (
|
|
13
|
-
<div style={{ maxWidth: 640, background: "var(--color-bg)" }} className="p-4">
|
|
14
|
-
<Story />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const meta = {
|
|
19
|
-
title: "Chat/ErrorMessageDisplay",
|
|
20
|
-
component: ErrorMessageDisplay,
|
|
21
|
-
tags: ["autodocs"],
|
|
22
|
-
parameters: {
|
|
23
|
-
docs: {
|
|
24
|
-
description: {
|
|
25
|
-
component:
|
|
26
|
-
"Renders an `error` message segment — collapsed mono title row, expandable details. Icon tint follows type: error / warning / info.",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
decorators: [plainDecorator],
|
|
31
|
-
} satisfies Meta<typeof ErrorMessageDisplay>;
|
|
32
|
-
|
|
33
|
-
export default meta;
|
|
34
|
-
type Story = StoryObj<typeof meta>;
|
|
35
|
-
|
|
36
|
-
/** Error with expandable details. */
|
|
37
|
-
export const WithDetails: Story = {
|
|
38
|
-
args: {
|
|
39
|
-
title: "Tool execution failed",
|
|
40
|
-
details:
|
|
41
|
-
"run_script exited with code 1: brew not found on this endpoint. Install Homebrew first or use the direct .dmg fallback.",
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/** Title only — no chevron, row is not clickable. */
|
|
46
|
-
export const TitleOnly: Story = {
|
|
47
|
-
args: { title: "Stream disconnected — retrying" },
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/** Warning tint. */
|
|
51
|
-
export const Warning: Story = {
|
|
52
|
-
args: {
|
|
53
|
-
type: "warning",
|
|
54
|
-
title: "Approval expired",
|
|
55
|
-
details: "The approval request timed out after 15 minutes and was cancelled automatically.",
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/** Info tint. */
|
|
60
|
-
export const Info: Story = {
|
|
61
|
-
args: {
|
|
62
|
-
type: "info",
|
|
63
|
-
title: "Session resumed",
|
|
64
|
-
details: "Reconnected to the stream; missed chunks were replayed from history.",
|
|
65
|
-
},
|
|
66
|
-
};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
|
|
4
|
-
import { ThinkingDisplay } from "../components/chat/thinking-display";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Collapsible "Thought" block for `thinking` message segments — muted
|
|
8
|
-
* markdown inside a bordered card, one line collapsed, expandable via the
|
|
9
|
-
* chevron. While the segment is still streaming the label reads "Thinking"
|
|
10
|
-
* and the collapse transition is disabled.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const SHORT_THOUGHT =
|
|
14
|
-
"The user wants Slack installed. Homebrew is present, so `brew install --cask slack` is the cleanest path.";
|
|
15
|
-
|
|
16
|
-
const LONG_THOUGHT = `The user asked to install Slack on their Mac.
|
|
17
|
-
|
|
18
|
-
**Options considered:**
|
|
19
|
-
|
|
20
|
-
1. Direct \`.dmg\` download — needs manual mounting and copying, hard to automate.
|
|
21
|
-
2. Homebrew Cask — \`brew install --cask slack\`, idempotent and scriptable.
|
|
22
|
-
3. Mac App Store via \`mas\` — requires the user to be signed in to the store.
|
|
23
|
-
|
|
24
|
-
Homebrew is already present on this endpoint (verified in the device inventory), so option 2 is the cleanest path. The install needs client approval because it modifies installed software.`;
|
|
25
|
-
|
|
26
|
-
const plainDecorator = (Story: React.ComponentType) => (
|
|
27
|
-
<div style={{ maxWidth: 640, background: "var(--color-bg)" }} className="p-4">
|
|
28
|
-
<Story />
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const meta = {
|
|
33
|
-
title: "Chat/ThinkingDisplay",
|
|
34
|
-
component: ThinkingDisplay,
|
|
35
|
-
tags: ["autodocs"],
|
|
36
|
-
parameters: {
|
|
37
|
-
docs: {
|
|
38
|
-
description: {
|
|
39
|
-
component:
|
|
40
|
-
"Renders a `thinking` message segment — collapsed single-line 'Thought' card that expands to the full muted-markdown reasoning. Streaming state shows 'Thinking' with a dots loader.",
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
decorators: [plainDecorator],
|
|
45
|
-
} satisfies Meta<typeof ThinkingDisplay>;
|
|
46
|
-
|
|
47
|
-
export default meta;
|
|
48
|
-
type Story = StoryObj<typeof meta>;
|
|
49
|
-
|
|
50
|
-
/** Finished thought — collapsed to one line, expandable. */
|
|
51
|
-
export const Thought: Story = {
|
|
52
|
-
args: { text: SHORT_THOUGHT },
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/** Streaming — "Thinking" label, transition disabled while tokens arrive. */
|
|
56
|
-
export const Streaming: Story = {
|
|
57
|
-
args: { text: SHORT_THOUGHT, isStreaming: true },
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/** Long markdown thought — headings, list, inline code; expand to read. */
|
|
61
|
-
export const LongMarkdown: Story = {
|
|
62
|
-
args: { text: LONG_THOUGHT },
|
|
63
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|