ai-design-system 0.1.73 → 0.1.75

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 (47) hide show
  1. package/components/ai-elements/node.tsx +9 -9
  2. package/components/ai-elements/prompt-input.tsx +2 -2
  3. package/components/blocks/AIConversation/AIConversation.tsx +36 -3
  4. package/components/blocks/BmcCanvas/bmc-layout.ts +115 -0
  5. package/components/blocks/BmcCanvas/bmc-tooltips.ts +63 -0
  6. package/components/blocks/BmcCanvas/index.ts +3 -0
  7. package/components/blocks/BmcCanvas/interfaces.ts +58 -0
  8. package/components/blocks/WorkflowCanvas/WorkflowCanvas.tsx +1 -1
  9. package/components/blocks/index.ts +3 -0
  10. package/components/composites/AgentIndicator/AgentIndicator.tsx +1 -1
  11. package/components/composites/AuthCard/AuthCard.stories.tsx +65 -0
  12. package/components/composites/AuthCard/AuthCard.tsx +360 -0
  13. package/components/composites/AuthCard/index.ts +2 -0
  14. package/components/composites/SpatialContainerNode/SpatialContainerNode.tsx +84 -21
  15. package/components/composites/SpecialistMessage/SpecialistMessage.tsx +1 -1
  16. package/components/composites/SystemMessage/SystemMessage.stories.tsx +46 -0
  17. package/components/composites/SystemMessage/SystemMessage.tsx +54 -0
  18. package/components/composites/SystemMessage/index.ts +2 -0
  19. package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +1 -1
  20. package/components/composites/WorkflowToolbar/WorkflowToolbar.tsx +8 -9
  21. package/components/composites/WorkflowToolbar/interfaces.ts +1 -0
  22. package/components/composites/index.ts +8 -0
  23. package/components/features/AuthFeature/AuthFeature.behaviors.stories.tsx +80 -0
  24. package/components/features/AuthFeature/AuthFeature.mocks.ts +41 -0
  25. package/components/features/AuthFeature/AuthFeature.stories.tsx +102 -0
  26. package/components/features/AuthFeature/AuthFeature.tsx +186 -0
  27. package/components/features/AuthFeature/README.md +33 -0
  28. package/components/features/AuthFeature/index.ts +10 -0
  29. package/components/features/AuthFeature/useAuthFeature.d.ts +57 -0
  30. package/components/features/AuthFeature/useAuthFeature.mock.ts +113 -0
  31. package/components/features/ChatPanel/ChatPanel.tsx +18 -2
  32. package/components/features/ChatPanel/useChatPanel.d.ts +1 -1
  33. package/components/features/NodeEditor/NodeEditor.mocks.ts +51 -123
  34. package/components/features/NodeEditor/NodeEditor.stories.tsx +1 -1
  35. package/components/features/NodeEditor/NodeEditor.tsx +13 -6
  36. package/components/features/NodeEditor/useNodeEditor.d.ts +1 -0
  37. package/components/features/NodeEditor/useNodeEditor.mock.ts +5 -0
  38. package/components/features/index.ts +5 -0
  39. package/components/index.ts +1 -1
  40. package/components/ui/button.tsx +2 -0
  41. package/dist/index.cjs +743 -44
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.css +235 -22
  44. package/dist/index.d.ts +309 -39
  45. package/dist/index.js +742 -45
  46. package/dist/index.js.map +1 -1
  47. package/package.json +1 -1
@@ -23,7 +23,7 @@ export type NodeProps = ComponentProps<typeof Card> & {
23
23
  export const Node = ({ handles, className, status, ...props }: NodeProps) => (
24
24
  <Card
25
25
  className={cn(
26
- "node-container relative h-[52px] w-[180px] gap-0 overflow-hidden rounded-md bg-card p-0 transition-all duration-200",
26
+ "node-container group relative h-[52px] w-[180px] gap-0 overflow-hidden rounded-md bg-card p-0 transition-all duration-200",
27
27
  status === "success" && "border-green-500 border-2",
28
28
  status === "error" && "border-red-500 border-2",
29
29
  className
@@ -33,18 +33,18 @@ export const Node = ({ handles, className, status, ...props }: NodeProps) => (
33
33
  {status === "running" && <AnimatedBorder />}
34
34
  {handles.target && (
35
35
  <>
36
- <Handle id="target-top" position={Position.Top} type="target" />
37
- <Handle id="target-right" position={Position.Right} type="target" />
38
- <Handle id="target-bottom" position={Position.Bottom} type="target" />
39
- <Handle id="target-left" position={Position.Left} type="target" />
36
+ <Handle id="target-top" position={Position.Top} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
37
+ <Handle id="target-right" position={Position.Right} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
38
+ <Handle id="target-bottom" position={Position.Bottom} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
39
+ <Handle id="target-left" position={Position.Left} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
40
40
  </>
41
41
  )}
42
42
  {handles.source && (
43
43
  <>
44
- <Handle id="source-top" position={Position.Top} type="source" />
45
- <Handle id="source-right" position={Position.Right} type="source" />
46
- <Handle id="source-bottom" position={Position.Bottom} type="source" />
47
- <Handle id="source-left" position={Position.Left} type="source" />
44
+ <Handle id="source-top" position={Position.Top} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
45
+ <Handle id="source-right" position={Position.Right} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
46
+ <Handle id="source-bottom" position={Position.Bottom} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
47
+ <Handle id="source-left" position={Position.Left} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
48
48
  </>
49
49
  )}
50
50
  {props.children}
@@ -969,8 +969,8 @@ export const PromptInputSubmit = ({
969
969
  if (status === "submitted") {
970
970
  Icon = <Loader2Icon className="size-4 animate-spin" />;
971
971
  } else if (status === "streaming") {
972
- Icon = <SquareIcon className="size-3.5 fill-current" />;
973
- buttonVariant = "default";
972
+ Icon = <SquareIcon className="size-3.5 fill-white text-white" />;
973
+ buttonVariant = "outline-primary";
974
974
  customClass = cn("rounded-full", className);
975
975
  } else if (status === "error") {
976
976
  Icon = <XIcon className="size-4" />;
@@ -10,6 +10,7 @@ import type { ToolCall, SubAgent } from "@/components/composites"
10
10
  import { UserMessage } from "@/components/composites/UserMessage"
11
11
  import { SpecialistMessage } from "@/components/composites/SpecialistMessage"
12
12
  import { OrchestratorMessage } from "@/components/composites/OrchestratorMessage"
13
+ import { SystemMessage } from "@/components/composites/SystemMessage"
13
14
  import { ToolCallDisplay } from "@/components/composites/ToolCallDisplay"
14
15
  import { ReasoningDisplay } from "@/components/composites/ReasoningDisplay"
15
16
 
@@ -71,6 +72,11 @@ export interface AIConversationProps
71
72
  * Callback fired when a tool action (like a link click) is triggered
72
73
  */
73
74
  onToolAction?: (toolCall: ToolCall, action: string) => void
75
+ /**
76
+ * Custom renderer for system messages.
77
+ * Receives the raw content string and returns a ReactNode.
78
+ */
79
+ renderSystemMessage?: (content: string) => React.ReactNode
74
80
  }
75
81
 
76
82
  /**
@@ -84,6 +90,7 @@ export const AIConversation = React.memo<AIConversationProps>(
84
90
  selectedSubAgent,
85
91
  emptyState,
86
92
  onToolAction,
93
+ renderSystemMessage,
87
94
  ...conversationProps
88
95
  }) => {
89
96
  const isEmpty = React.useMemo(
@@ -117,6 +124,15 @@ export const AIConversation = React.memo<AIConversationProps>(
117
124
  (!msg.toolCalls || msg.toolCalls.length === 0) &&
118
125
  (!msg.subAgents || msg.subAgents.length === 0);
119
126
 
127
+ const currentGroupHasTools =
128
+ currentGroup &&
129
+ ((currentGroup.toolCalls && currentGroup.toolCalls.length > 0) ||
130
+ (currentGroup.subAgents && currentGroup.subAgents.length > 0));
131
+
132
+ if (currentGroupHasTools && isFinalResponse) {
133
+ currentGroup = null;
134
+ }
135
+
120
136
  if (currentGroup) {
121
137
  if (msg.content) {
122
138
  currentGroup.content = currentGroup.content
@@ -221,6 +237,23 @@ export const AIConversation = React.memo<AIConversationProps>(
221
237
  const contentStr = toMessageString(message.content)
222
238
 
223
239
  // Render based on role field
240
+ if (message.role === "system") {
241
+ if (!contentStr || !contentStr.trim()) {
242
+ return null;
243
+ }
244
+ return (
245
+ <SystemMessage
246
+ key={message.id}
247
+ message={{
248
+ id: message.id,
249
+ content: contentStr,
250
+ avatarName: message.avatarName,
251
+ }}
252
+ renderContent={renderSystemMessage}
253
+ />
254
+ )
255
+ }
256
+
224
257
  if (message.role === "user") {
225
258
  return (
226
259
  <UserMessage
@@ -252,9 +285,9 @@ export const AIConversation = React.memo<AIConversationProps>(
252
285
  const directToolCalls = allToolCalls.filter((tc) => tc.visibility !== "reasoning")
253
286
 
254
287
  const hasReasoning = reasoningCalls.length > 0 || subAgents.length > 0 || directToolCalls.length > 0 || (message.isLoading && contentStr.trim() !== "");
255
- const reasoningText = (hasReasoning && (!message.blocks || message.blocks.length === 0)) ? contentStr : undefined
256
- const displayContentStr = hasReasoning ? "" : contentStr
257
- const hasDisplayContent = displayContentStr.trim() !== ""
288
+ const reasoningText = (hasReasoning && (!message.blocks || message.blocks.length === 0)) ? contentStr : undefined;
289
+ const displayContentStr = hasReasoning ? "" : contentStr;
290
+ const hasDisplayContent = displayContentStr.trim() !== "";
258
291
 
259
292
  if (!hasDisplayContent && directToolCalls.length === 0 && reasoningCalls.length === 0 && subAgents.length === 0 && !message.isLoading && (!message.blocks || message.blocks.length === 0)) {
260
293
  return null;
@@ -0,0 +1,115 @@
1
+ import type { WorkflowNode, WorkflowEdge } from "@/components/blocks/WorkflowCanvas";
2
+ import type { SpatialContainerColorTheme, SpatialContainerVariant } from "@/components/composites/SpatialContainerNode";
3
+ import type { BmcBlock, BmcBlockId, BmcCanvasView, CompiledBmc } from "./interfaces";
4
+
5
+ interface BlockLayout {
6
+ id: string;
7
+ themeColor: SpatialContainerColorTheme;
8
+ variant: SpatialContainerVariant;
9
+ icon: string;
10
+ position: { x: number; y: number };
11
+ size: { width: number; height: number };
12
+ layout: 'column' | 'row';
13
+ }
14
+
15
+ const BLOCK_LAYOUTS: Record<BmcBlockId, BlockLayout> = {
16
+ key_partnerships: { id: 'cp', themeColor: 'blue', variant: 'extruded3d', icon: 'handshake', position: { x: 40, y: 40 }, size: { width: 280, height: 400 }, layout: 'column' },
17
+ key_activities: { id: 'ka', themeColor: 'emerald', variant: 'extruded3d', icon: 'activity', position: { x: 350, y: 40 }, size: { width: 280, height: 190 }, layout: 'column' },
18
+ key_resources: { id: 'kr', themeColor: 'emerald', variant: 'extruded3d', icon: 'database', position: { x: 350, y: 250 }, size: { width: 280, height: 190 }, layout: 'column' },
19
+ value_propositions: { id: 'vp', themeColor: 'indigo', variant: 'extruded3d', icon: 'box', position: { x: 660, y: 40 }, size: { width: 300, height: 400 }, layout: 'column' },
20
+ customer_relationships: { id: 'cr', themeColor: 'purple', variant: 'extruded3d', icon: 'heart', position: { x: 990, y: 40 }, size: { width: 300, height: 190 }, layout: 'column' },
21
+ channels: { id: 'ch', themeColor: 'amber', variant: 'extruded3d', icon: 'truck', position: { x: 990, y: 250 }, size: { width: 300, height: 190 }, layout: 'column' },
22
+ customer_segments: { id: 'cs', themeColor: 'purple', variant: 'extruded3d', icon: 'users', position: { x: 1320, y: 40 }, size: { width: 280, height: 400 }, layout: 'column' },
23
+ cost_structure: { id: 'cost', themeColor: 'rose', variant: 'extruded3d', icon: 'wallet', position: { x: 40, y: 465 }, size: { width: 760, height: 180 }, layout: 'row' },
24
+ revenue_streams: { id: 'rev', themeColor: 'cyan', variant: 'extruded3d', icon: 'wallet', position: { x: 840, y: 465 }, size: { width: 760, height: 180 }, layout: 'row' },
25
+ };
26
+
27
+ function blockEntries(bmc: CompiledBmc): Array<{ block: BmcBlock; layout: BlockLayout }> {
28
+ return [
29
+ { block: bmc.keyPartnerships, layout: BLOCK_LAYOUTS.key_partnerships },
30
+ { block: bmc.keyActivities, layout: BLOCK_LAYOUTS.key_activities },
31
+ { block: bmc.keyResources, layout: BLOCK_LAYOUTS.key_resources },
32
+ { block: bmc.valuePropositions, layout: BLOCK_LAYOUTS.value_propositions },
33
+ { block: bmc.customerRelationships, layout: BLOCK_LAYOUTS.customer_relationships },
34
+ { block: bmc.channels, layout: BLOCK_LAYOUTS.channels },
35
+ { block: bmc.customerSegments, layout: BLOCK_LAYOUTS.customer_segments },
36
+ { block: bmc.costStructure, layout: BLOCK_LAYOUTS.cost_structure },
37
+ { block: bmc.revenueStreams, layout: BLOCK_LAYOUTS.revenue_streams },
38
+ ];
39
+ }
40
+
41
+ import { BMC_TOOLTIPS } from "./bmc-tooltips";
42
+
43
+ export function bmcToCanvas(bmc: CompiledBmc | null, message?: string): BmcCanvasView {
44
+ if (!bmc) {
45
+ return {
46
+ canvasName: null,
47
+ nodes: [],
48
+ edges: [],
49
+ emptyBlocks: [],
50
+ message: message ?? 'No business model data available for this session',
51
+ };
52
+ }
53
+
54
+ const nodes: WorkflowNode[] = [];
55
+
56
+ for (const { block, layout } of blockEntries(bmc)) {
57
+ const itemCount = block.items.length;
58
+ const badgeText = block.empty || itemCount === 0 ? 'empty' : `${itemCount} item${itemCount === 1 ? '' : 's'}`;
59
+
60
+ const items = block.items.map((item, idx) => ({
61
+ id: `${layout.id}-${idx + 1}`,
62
+ label: item.name,
63
+ description: item.description,
64
+ }));
65
+
66
+ const blockId = layout.id === 'cp' ? 'key_partnerships'
67
+ : layout.id === 'ka' ? 'key_activities'
68
+ : layout.id === 'kr' ? 'key_resources'
69
+ : layout.id === 'vp' ? 'value_propositions'
70
+ : layout.id === 'cr' ? 'customer_relationships'
71
+ : layout.id === 'ch' ? 'channels'
72
+ : layout.id === 'cs' ? 'customer_segments'
73
+ : layout.id === 'cost' ? 'cost_structure'
74
+ : layout.id === 'rev' ? 'revenue_streams'
75
+ : '';
76
+
77
+ const tooltipInfo = BMC_TOOLTIPS[blockId];
78
+ const description = tooltipInfo
79
+ ? `${tooltipInfo.description}\n\nKey Question: "${tooltipInfo.question}"\n\nExamples: ${tooltipInfo.examples.join(', ')}`
80
+ : block.name;
81
+
82
+ nodes.push({
83
+ id: layout.id,
84
+ type: 'spatialContainer',
85
+ position: layout.position,
86
+ style: layout.size,
87
+ data: {
88
+ label: block.name,
89
+ description,
90
+ type: 'spatialContainer',
91
+ themeColor: layout.themeColor,
92
+ variant: layout.variant,
93
+ icon: layout.icon,
94
+ badgeText,
95
+ items,
96
+ },
97
+ });
98
+ }
99
+
100
+ const edges: WorkflowEdge[] = [
101
+ { id: 'e-ka-vp', source: 'ka', target: 'vp', type: 'animated' },
102
+ { id: 'e-vp-cr', source: 'vp', target: 'cr', type: 'animated' },
103
+ { id: 'e-cr-cs', source: 'cr', target: 'cs', type: 'animated' },
104
+ { id: 'e-vp-ch', source: 'vp', target: 'ch', type: 'straight' },
105
+ { id: 'e-ch-cs', source: 'ch', target: 'cs', type: 'animated' },
106
+ ];
107
+
108
+ return {
109
+ canvasName: bmc.canvas.name,
110
+ nodes,
111
+ edges,
112
+ emptyBlocks: bmc.emptyBlocks,
113
+ message,
114
+ };
115
+ }
@@ -0,0 +1,63 @@
1
+ export interface BmcTooltipContent {
2
+ title: string;
3
+ description: string;
4
+ question: string;
5
+ examples: string[];
6
+ }
7
+
8
+ export const BMC_TOOLTIPS: Record<string, BmcTooltipContent> = {
9
+ key_partnerships: {
10
+ title: "Key Partnerships",
11
+ description: "The external companies, suppliers, or vendors that help your business operate and grow.",
12
+ question: "Who do we rely on outside our company to make this business work?",
13
+ examples: ["Cloud hosting providers", "Payment gateways", "Material suppliers", "Strategic alliances"]
14
+ },
15
+ key_activities: {
16
+ title: "Key Activities",
17
+ description: "The most critical daily tasks and operations your team must execute to deliver your offer.",
18
+ question: "What core things must we do every day to operate and succeed?",
19
+ examples: ["Software development", "AI model training", "Content creation", "Customer support"]
20
+ },
21
+ key_resources: {
22
+ title: "Key Resources",
23
+ description: "The most vital assets—physical, intellectual, human, or financial—needed to run your business.",
24
+ question: "What essential assets do we need to own or access to deliver our value?",
25
+ examples: ["Skilled engineers", "Proprietary algorithms", "Brand identity", "Capital"]
26
+ },
27
+ value_propositions: {
28
+ title: "Value Propositions",
29
+ description: "The collection of products, services, and benefits that solve customer problems or satisfy their needs.",
30
+ question: "Why do customers choose us over competitors? What problem are we solving?",
31
+ examples: ["Time savings", "Cost reduction", "Ease of use", "Premium quality"]
32
+ },
33
+ customer_relationships: {
34
+ title: "Customer Relationships",
35
+ description: "The type of interaction and ongoing relationship you establish with each customer group.",
36
+ question: "How do we interact with our customers across their lifecycle?",
37
+ examples: ["Self-service onboarding", "Dedicated account management", "Automated support"]
38
+ },
39
+ channels: {
40
+ title: "Channels",
41
+ description: "The touchpoints and pathways you use to communicate with, sell to, and deliver value to customers.",
42
+ question: "How do customers find, evaluate, buy, and receive our product or service?",
43
+ examples: ["Direct web platform", "Sales team", "Mobile app", "Partner marketplaces"]
44
+ },
45
+ customer_segments: {
46
+ title: "Customer Segments",
47
+ description: "The specific groups of people or organizations your business aims to reach and serve.",
48
+ question: "Who are we creating value for? Who is our ideal buyer?",
49
+ examples: ["Enterprise B2B teams", "Thought leaders", "Small business owners"]
50
+ },
51
+ cost_structure: {
52
+ title: "Cost Structure",
53
+ description: "All major fixed and variable expenses required to operate your business model.",
54
+ question: "What are the biggest costs inherent in running our business?",
55
+ examples: ["Server/compute costs", "Team salaries", "R&D licensing", "Marketing"]
56
+ },
57
+ revenue_streams: {
58
+ title: "Revenue Streams",
59
+ description: "The different ways your business earns cash and captures value from each customer segment.",
60
+ question: "How does money flow into the business? What are customers paying for?",
61
+ examples: ["Monthly SaaS subscriptions", "Usage-based fees", "One-time setup charges"]
62
+ }
63
+ };
@@ -0,0 +1,3 @@
1
+ export { bmcToCanvas } from "./bmc-layout";
2
+ export { BMC_TOOLTIPS, type BmcTooltipContent } from "./bmc-tooltips";
3
+ export type { BmcBlockId, BmcItem, BmcBlock, CompiledBmc, BmcCanvasView } from "./interfaces";
@@ -0,0 +1,58 @@
1
+ import type { WorkflowEdge, WorkflowNode } from "@/components/blocks/WorkflowCanvas";
2
+
3
+ export type BmcBlockId =
4
+ | 'customer_segments'
5
+ | 'value_propositions'
6
+ | 'channels'
7
+ | 'customer_relationships'
8
+ | 'revenue_streams'
9
+ | 'key_resources'
10
+ | 'key_activities'
11
+ | 'key_partnerships'
12
+ | 'cost_structure';
13
+
14
+ export interface BmcItem {
15
+ id: string;
16
+ name: string;
17
+ description?: string;
18
+ sourceRefs: string[];
19
+ [k: string]: unknown;
20
+ }
21
+
22
+ export interface BmcBlock {
23
+ key: BmcBlockId;
24
+ name: string;
25
+ items: BmcItem[];
26
+ empty: boolean;
27
+ derived: boolean;
28
+ sourceRefs: string[];
29
+ }
30
+
31
+ export interface CompiledBmc {
32
+ canvas: {
33
+ id: string;
34
+ name: string;
35
+ description: string;
36
+ derived: boolean;
37
+ source: { businessDocId?: string; productDocId?: string };
38
+ generatedAt: string;
39
+ };
40
+ customerSegments: BmcBlock;
41
+ valuePropositions: BmcBlock;
42
+ channels: BmcBlock;
43
+ customerRelationships: BmcBlock;
44
+ revenueStreams: BmcBlock;
45
+ keyResources: BmcBlock;
46
+ keyActivities: BmcBlock;
47
+ keyPartnerships: BmcBlock;
48
+ costStructure: BmcBlock & { strategicFocus?: string; drivers: string[] };
49
+ emptyBlocks: BmcBlockId[];
50
+ }
51
+
52
+ export interface BmcCanvasView {
53
+ canvasName: string | null;
54
+ nodes: WorkflowNode[];
55
+ edges: WorkflowEdge[];
56
+ emptyBlocks: BmcBlockId[];
57
+ message?: string;
58
+ }
@@ -81,7 +81,7 @@ function WorkflowCanvasInner({
81
81
  }}
82
82
  >
83
83
  <Canvas
84
- className="bg-background"
84
+ className="bg-background [&_.react-flow\_\_handle]:opacity-0 [&_.react-flow\_\_handle]:pointer-events-none [&_.react-flow\_\_node:hover_.react-flow\_\_handle]:opacity-100 [&_.react-flow\_\_node:hover_.react-flow\_\_handle]:pointer-events-auto [&_.react-flow\_\_node.selected_.react-flow\_\_handle]:opacity-100 [&_.react-flow\_\_node.selected_.react-flow\_\_handle]:pointer-events-auto [&_.react-flow\_\_handle]:transition-opacity [&_.react-flow\_\_handle]:duration-150"
85
85
  connectionLineComponent={ConnectionLine}
86
86
  connectionMode={ConnectionMode.Strict}
87
87
  edges={edges}
@@ -16,6 +16,9 @@ export * from './SectionLayout'
16
16
  export { WorkflowCanvas, getLayoutedElements } from './WorkflowCanvas'
17
17
  export type { WorkflowCanvasProps, WorkflowNode, WorkflowEdge, WorkflowNodeData } from './WorkflowCanvas'
18
18
 
19
+ export { bmcToCanvas } from './BmcCanvas'
20
+ export type { BmcBlockId, BmcItem, BmcBlock, CompiledBmc, BmcCanvasView } from './BmcCanvas'
21
+
19
22
  export { DashboardMetrics } from './DashboardMetrics'
20
23
  export type { DashboardMetricsProps } from './DashboardMetrics'
21
24
 
@@ -16,7 +16,7 @@ export interface SubAgent {
16
16
  subAgentName: string
17
17
  input: string | Record<string, unknown>
18
18
  output?: string | Record<string, unknown>
19
- status: "pending" | "active" | "completed" | "error"
19
+ status: "pending" | "active" | "completed" | "error" | "running" | "in_progress"
20
20
  }
21
21
 
22
22
  export interface AgentIndicatorProps {
@@ -0,0 +1,65 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { AuthCard } from "./AuthCard";
3
+ import { fn } from "@storybook/test";
4
+
5
+ const meta: Meta<typeof AuthCard> = {
6
+ title: "Composites/AuthCard",
7
+ component: AuthCard,
8
+ parameters: {
9
+ layout: "centered",
10
+ },
11
+ args: {
12
+ appName: "Waypoint",
13
+ mode: "login",
14
+ email: "",
15
+ isLoading: false,
16
+ allowSso: true,
17
+ socialProviders: ["apple", "google"],
18
+ onEmailChange: fn(),
19
+ onNameChange: fn(),
20
+ onPasswordChange: fn(),
21
+ onConfirmPasswordChange: fn(),
22
+ onSubmit: fn(),
23
+ onSsoClick: fn(),
24
+ onSocialClick: fn(),
25
+ onToggleMode: fn(),
26
+ },
27
+ } satisfies Meta<typeof AuthCard>;
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof AuthCard>;
31
+
32
+ export const LoginDefault: Story = {
33
+ args: {
34
+ mode: "login",
35
+ },
36
+ };
37
+
38
+ export const LoginFilled: Story = {
39
+ args: {
40
+ mode: "login",
41
+ email: "alex@example.com",
42
+ },
43
+ };
44
+
45
+ export const SignupDefault: Story = {
46
+ args: {
47
+ mode: "signup",
48
+ },
49
+ };
50
+
51
+ export const LoadingState: Story = {
52
+ args: {
53
+ mode: "login",
54
+ email: "alex@example.com",
55
+ isLoading: true,
56
+ },
57
+ };
58
+
59
+ export const WithError: Story = {
60
+ args: {
61
+ mode: "login",
62
+ email: "alex@example.com",
63
+ error: "Invalid email or authentication session expired. Please try again.",
64
+ },
65
+ };