@motiadev/workbench 0.7.3-beta.136 → 0.8.0-beta.137

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 (74) hide show
  1. package/dist/src/App.js +2 -2
  2. package/dist/src/components/flow/base-edge.js +4 -2
  3. package/dist/src/components/flow/flow-view.js +2 -1
  4. package/dist/src/components/flow/hooks/use-save-workflow-config.js +1 -1
  5. package/dist/src/components/header/header.js +1 -1
  6. package/dist/src/components/logs/log-detail.js +1 -1
  7. package/dist/src/components/logs/logs-page.js +4 -4
  8. package/dist/src/components/observability/trace-item/trace-item-detail.js +1 -2
  9. package/dist/src/components/observability/trace-item/trace-item.js +1 -1
  10. package/dist/src/components/observability/trace-timeline.js +1 -1
  11. package/dist/src/components/observability/traces-groups.js +1 -1
  12. package/dist/src/components/observability/traces-page.js +17 -5
  13. package/dist/src/components/states/hooks/states-hooks.d.ts +7 -1
  14. package/dist/src/components/states/hooks/states-hooks.js +11 -3
  15. package/dist/src/components/states/state-editor.js +1 -1
  16. package/dist/src/components/states/state-sidebar.js +1 -1
  17. package/dist/src/components/states/states-page.js +46 -8
  18. package/dist/src/components/tutorial/engine/workbench-xpath.d.ts +5 -0
  19. package/dist/src/components/tutorial/engine/workbench-xpath.js +7 -2
  20. package/dist/src/components/tutorial/tutorial-step.js +2 -1
  21. package/dist/src/components/{endpoints → ui}/json-editor.js +1 -1
  22. package/dist/src/components/ui/table.js +1 -1
  23. package/dist/src/components/ui/theme-toggle.js +1 -2
  24. package/dist/src/index.css +10 -6
  25. package/dist/src/lib/utils.d.ts +0 -2
  26. package/dist/src/lib/utils.js +0 -5
  27. package/dist/src/publicComponents/base-node/base-node.js +1 -1
  28. package/dist/src/publicComponents/base-node/code-display.js +3 -3
  29. package/dist/src/publicComponents/base-node/feature-card.js +1 -1
  30. package/dist/src/publicComponents/base-node/node-header.js +1 -1
  31. package/dist/src/publicComponents/base-node/node-sidebar.js +1 -1
  32. package/dist/src/stores/use-flow-store.d.ts +5 -3
  33. package/dist/src/stores/use-global-store.d.ts +5 -3
  34. package/dist/src/stores/use-tabs-store.d.ts +5 -3
  35. package/dist/tsconfig.app.tsbuildinfo +1 -1
  36. package/dist/tsconfig.node.tsbuildinfo +1 -1
  37. package/package.json +4 -3
  38. package/dist/src/components/endpoints/endpoint-badge.d.ts +0 -10
  39. package/dist/src/components/endpoints/endpoint-badge.js +0 -22
  40. package/dist/src/components/endpoints/endpoint-body-panel.d.ts +0 -13
  41. package/dist/src/components/endpoints/endpoint-body-panel.js +0 -16
  42. package/dist/src/components/endpoints/endpoint-call.d.ts +0 -7
  43. package/dist/src/components/endpoints/endpoint-call.js +0 -58
  44. package/dist/src/components/endpoints/endpoint-description.d.ts +0 -7
  45. package/dist/src/components/endpoints/endpoint-description.js +0 -13
  46. package/dist/src/components/endpoints/endpoint-path-params-panel.d.ts +0 -8
  47. package/dist/src/components/endpoints/endpoint-path-params-panel.js +0 -17
  48. package/dist/src/components/endpoints/endpoint-query-params-panel.d.ts +0 -8
  49. package/dist/src/components/endpoints/endpoint-query-params-panel.js +0 -16
  50. package/dist/src/components/endpoints/endpoint-response-schema.d.ts +0 -10
  51. package/dist/src/components/endpoints/endpoint-response-schema.js +0 -17
  52. package/dist/src/components/endpoints/endpoint-response.d.ts +0 -8
  53. package/dist/src/components/endpoints/endpoint-response.js +0 -50
  54. package/dist/src/components/endpoints/endpoint-side-panel.d.ts +0 -8
  55. package/dist/src/components/endpoints/endpoint-side-panel.js +0 -25
  56. package/dist/src/components/endpoints/endpoints-page.d.ts +0 -1
  57. package/dist/src/components/endpoints/endpoints-page.js +0 -14
  58. package/dist/src/components/endpoints/hooks/use-get-endpoints.d.ts +0 -2
  59. package/dist/src/components/endpoints/hooks/use-get-endpoints.js +0 -8
  60. package/dist/src/components/endpoints/hooks/use-json-schema-to-json.d.ts +0 -4
  61. package/dist/src/components/endpoints/hooks/use-json-schema-to-json.js +0 -11
  62. package/dist/src/components/endpoints/hooks/use-path-params.d.ts +0 -1
  63. package/dist/src/components/endpoints/hooks/use-path-params.js +0 -4
  64. package/dist/src/components/endpoints/hooks/use-state-stream.d.ts +0 -7
  65. package/dist/src/components/endpoints/hooks/use-state-stream.js +0 -11
  66. package/dist/src/components/endpoints/hooks/utils.d.ts +0 -1
  67. package/dist/src/components/endpoints/hooks/utils.js +0 -29
  68. package/dist/src/components/endpoints/response-body.d.ts +0 -7
  69. package/dist/src/components/endpoints/response-body.js +0 -6
  70. package/dist/src/components/sidebar/sidebar.d.ts +0 -8
  71. package/dist/src/components/sidebar/sidebar.js +0 -39
  72. package/dist/src/stores/use-theme-store.d.ts +0 -16
  73. package/dist/src/stores/use-theme-store.js +0 -26
  74. /package/dist/src/components/{endpoints → ui}/json-editor.d.ts +0 -0
package/dist/src/App.js CHANGED
@@ -4,15 +4,15 @@ import { analytics } from '@/lib/analytics';
4
4
  import { ReactFlowProvider } from '@xyflow/react';
5
5
  import { File, GanttChart, Link2, LogsIcon } from 'lucide-react';
6
6
  import { useCallback, useEffect, useMemo, useState } from 'react';
7
- import { EndpointsPage } from './components/endpoints/endpoints-page';
8
7
  import { FlowPage } from './components/flow/flow-page';
9
8
  import { FlowTabMenuItem } from './components/flow/flow-tab-menu-item';
10
9
  import { Header } from './components/header/header';
11
10
  import { LogsPage } from './components/logs/logs-page';
12
11
  import { TracesPage } from './components/observability/traces-page';
13
- import { APP_SIDEBAR_CONTAINER_ID } from './components/sidebar/sidebar';
12
+ import { APP_SIDEBAR_CONTAINER_ID } from '@motiadev/ui';
14
13
  import { StatesPage } from './components/states/states-page';
15
14
  import { useTabsStore } from './stores/use-tabs-store';
15
+ import { EndpointsPage } from '@motiadev/plugin-endpoint';
16
16
  var TabLocation;
17
17
  (function (TabLocation) {
18
18
  TabLocation["TOP"] = "top";
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { BaseEdge as BaseReactFlowEdge, EdgeLabelRenderer, getSmoothStepPath } from '@xyflow/react';
3
3
  import { cva } from 'class-variance-authority';
4
- import { cn } from '@/lib/utils';
4
+ import { cn, useThemeStore } from '@motiadev/ui';
5
5
  const labelVariants = cva('absolute pointer-events-all text-cs border p-1 px-2', {
6
6
  variants: {
7
7
  color: {
@@ -14,9 +14,11 @@ const labelVariants = cva('absolute pointer-events-all text-cs border p-1 px-2',
14
14
  },
15
15
  });
16
16
  export const BaseEdge = (props) => {
17
+ const theme = useThemeStore((state) => state.theme);
17
18
  const { sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data } = props;
18
19
  const label = data?.label;
19
20
  const labelVariant = data?.labelVariant;
21
+ const virtualColor = theme === 'dark' ? 'rgb(225, 225, 225)' : 'rgb(85, 85, 85)';
20
22
  const [edgePath, labelX, labelY] = getSmoothStepPath({
21
23
  sourceX,
22
24
  sourceY,
@@ -28,7 +30,7 @@ export const BaseEdge = (props) => {
28
30
  offset: 10,
29
31
  });
30
32
  return (_jsxs(_Fragment, { children: [_jsx(BaseReactFlowEdge, { path: edgePath, style: {
31
- stroke: data?.variant === 'virtual' ? 'rgb(111, 111, 111)' : '#0094FF',
33
+ stroke: data?.variant === 'virtual' ? virtualColor : '#0094FF',
32
34
  strokeWidth: 2,
33
35
  shapeRendering: 'geometricPrecision',
34
36
  fill: 'none',
@@ -6,6 +6,7 @@ import { FlowLoader } from './flow-loader';
6
6
  import { useGetFlowState } from './hooks/use-get-flow-state';
7
7
  import { NodeOrganizer } from './node-organizer';
8
8
  import '@xyflow/react/dist/style.css';
9
+ import { BackgroundEffect } from '@motiadev/ui';
9
10
  const edgeTypes = {
10
11
  base: BaseEdge,
11
12
  };
@@ -17,5 +18,5 @@ export const FlowView = ({ flow, flowConfig }) => {
17
18
  if (!nodeTypes) {
18
19
  return null;
19
20
  }
20
- return (_jsxs("div", { className: "w-full h-full relative", children: [!initialized && _jsx(FlowLoader, {}), _jsxs(ReactFlow, { minZoom: 0.1, nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodesChange: onNodesChangeHandler, onEdgesChange: onEdgesChange, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 50, size: 2, className: "bg-canvas-background!" }), _jsx(NodeOrganizer, { onInitialized: onInitialized, nodes: nodes, edges: edges })] })] }));
21
+ return (_jsxs("div", { className: "w-full h-full relative", children: [!initialized && _jsx(FlowLoader, {}), _jsxs(ReactFlow, { minZoom: 0.1, nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodesChange: onNodesChangeHandler, onEdgesChange: onEdgesChange, className: "isolate", children: [_jsx(BackgroundEffect, {}), _jsx(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1 }), _jsx(NodeOrganizer, { onInitialized: onInitialized, nodes: nodes, edges: edges })] })] }));
21
22
  };
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
2
2
  export const useSaveWorkflowConfig = () => {
3
3
  return useCallback(async (body) => {
4
4
  try {
5
- const response = await fetch(`/flows/${body.id}/config`, {
5
+ const response = await fetch(`/__motia/flows/${body.id}/config`, {
6
6
  method: 'POST',
7
7
  headers: {
8
8
  'Content-Type': 'application/json',
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import motiaLogoDark from '@/assets/motia-dark.png';
3
3
  import motiaLogoLight from '@/assets/motia-light.png';
4
- import { useThemeStore } from '@/stores/use-theme-store';
4
+ import { useThemeStore } from '@motiadev/ui';
5
5
  import { useEffect, useState } from 'react';
6
6
  import { Tutorial } from '../tutorial/tutorial';
7
7
  import { TutorialButton } from '../tutorial/tutorial-button';
@@ -5,7 +5,7 @@ import ReactJson from 'react18-json-view';
5
5
  import 'react18-json-view/src/dark.css';
6
6
  import 'react18-json-view/src/style.css';
7
7
  import { LogLevelDot } from './log-level-dot';
8
- import { Sidebar } from '@/components/sidebar/sidebar';
8
+ import { Sidebar } from '@motiadev/ui';
9
9
  import { X } from 'lucide-react';
10
10
  const defaultProps = ['id', 'msg', 'time', 'level', 'step', 'flows', 'traceId'];
11
11
  export const LogDetail = ({ log, onClose }) => {
@@ -1,13 +1,13 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table';
3
3
  import { formatTimestamp } from '@/lib/utils';
4
4
  import { useGlobalStore } from '@/stores/use-global-store';
5
5
  import { useLogsStore } from '@/stores/use-logs-store';
6
+ import { Button, cn, Input } from '@motiadev/ui';
7
+ import { Search, Trash, X } from 'lucide-react';
6
8
  import { useMemo, useState } from 'react';
7
9
  import { LogDetail } from './log-detail';
8
10
  import { LogLevelDot } from './log-level-dot';
9
- import { Button, cn, Input } from '@motiadev/ui';
10
- import { CircleX, Trash } from 'lucide-react';
11
11
  export const LogsPage = () => {
12
12
  const logs = useLogsStore((state) => state.logs);
13
13
  const resetLogs = useLogsStore((state) => state.resetLogs);
@@ -22,7 +22,7 @@ export const LogsPage = () => {
22
22
  log.step.toLowerCase().includes(search.toLowerCase()));
23
23
  });
24
24
  }, [logs, search]);
25
- return (_jsxs("div", { className: "h-full flex flex-row", "data-testid": "logs-container", children: [_jsxs("div", { className: "flex-1 overflow-y-auto overflow-x-auto", children: [_jsxs("div", { className: "flex p-2 border-b gap-4", "data-testid": "logs-search-container", children: [_jsxs("div", { className: "flex-1 relative", children: [_jsx(Input, { variant: "shade", value: search, onChange: (e) => setSearch(e.target.value), className: "pr-10 font-medium" }), _jsx(CircleX, { className: "cursor-pointer absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50 hover:text-muted-foreground", onClick: () => setSearch('') })] }), _jsxs(Button, { variant: "outline", onClick: resetLogs, children: [_jsx(Trash, {}), " Clear"] })] }), _jsx(Table, { children: _jsx(TableBody, { className: "font-mono font-medium", children: filteredLogs.map((log, index) => (_jsxs(TableRow, { "data-testid": "log-row", className: cn('font-mono font-semibold cursor-pointer border-0', {
25
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid grid-rows-[auto_1fr] h-full", "data-testid": "logs-container", children: [_jsxs("div", { className: "flex p-2 border-b gap-2", "data-testid": "logs-search-container", children: [_jsxs("div", { className: "flex-1 relative", children: [_jsx(Input, { variant: "shade", value: search, onChange: (e) => setSearch(e.target.value), className: "px-9 font-medium", placeholder: "Search by Trace ID or Message" }), _jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50" }), _jsx(X, { className: "cursor-pointer absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50 hover:text-muted-foreground", onClick: () => setSearch('') })] }), _jsxs(Button, { variant: "default", onClick: resetLogs, className: "h-[34px]", children: [_jsx(Trash, {}), " Clear"] })] }), _jsx(Table, { children: _jsx(TableBody, { className: "font-mono font-medium", children: filteredLogs.map((log, index) => (_jsxs(TableRow, { "data-testid": "log-row", className: cn('font-mono font-semibold cursor-pointer border-0', {
26
26
  'bg-muted-foreground/10 hover:bg-muted-foreground/20': selectedLogId === log.id,
27
27
  'hover:bg-muted-foreground/10': selectedLogId !== log.id,
28
28
  }), onClick: () => selectLogId(log.id), children: [_jsxs(TableCell, { "data-testid": `time-${index}`, className: "whitespace-nowrap flex items-center gap-2 text-muted-foreground", children: [_jsx(LogLevelDot, { level: log.level }), formatTimestamp(log.time)] }), _jsx(TableCell, { "data-testid": `trace-${log.traceId}`, className: "whitespace-nowrap cursor-pointer hover:text-primary text-muted-foreground", onClick: () => setSearch(log.traceId), children: log.traceId }), _jsx(TableCell, { "data-testid": `step-${index}`, "aria-label": log.step, className: "whitespace-nowrap", children: log.step }), _jsx(TableCell, { "data-testid": `msg-${index}`, "aria-label": log.msg, className: "whitespace-nowrap max-w-[500px] truncate w-full", children: log.msg })] }, index))) }) })] }), _jsx(LogDetail, { log: selectedLog, onClose: () => selectLogId(undefined) })] }));
@@ -1,6 +1,5 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Sidebar } from '@/components/sidebar/sidebar';
3
- import { Badge } from '@motiadev/ui';
2
+ import { Sidebar, Badge } from '@motiadev/ui';
4
3
  import { formatDuration } from '@/lib/utils';
5
4
  import { X } from 'lucide-react';
6
5
  import { memo } from 'react';
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '@/lib/utils';
2
+ import { cn } from '@motiadev/ui';
3
3
  export const TraceItem = ({ trace, group, groupEndTime, onExpand }) => {
4
4
  return (_jsxs("div", { className: "flex hover:bg-muted-foreground/10 relative cursor-pointer", onClick: () => onExpand(trace.id), "data-testid": "trace-timeline-item", children: [_jsx("div", { className: "flex items-center min-w-[200px] max-w-[200px] h-[32px] max-h-[32px] py-4 px-2 text-sm font-semibold text-foreground truncate sticky left-0 bg-card z-9", children: trace.name }), _jsx("div", { className: "flex w-full flex-row items-center hover:bg-muted/50 rounded-md", children: _jsx("div", { className: "relative w-full h-[32px] flex items-center", children: _jsx("div", { className: cn('h-[24px] rounded-[4px] hover:opacity-80 transition-all duration-200', {
5
5
  'bg-[repeating-linear-gradient(140deg,#BEFE29,#BEFE29_8px,#ABE625_8px,#ABE625_16px)]': trace.status === 'running',
@@ -25,5 +25,5 @@ export const TraceTimeline = memo(({ groupId }) => {
25
25
  };
26
26
  if (!group)
27
27
  return null;
28
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col flex-1 overflow-x-auto h-full relative", children: _jsxs("div", { className: "flex flex-col items-center min-w-full sticky top-0", style: { width: `${zoom * 1000}px` }, children: [_jsxs("div", { className: "flex flex-1 w-full sticky top-0 bg-background z-10", children: [_jsxs("div", { className: "w-full min-h-[37px] h-[37px] min-w-[200px] max-w-[200px] flex items-center justify-center gap-2 sticky left-0 top-0 bg-card", children: [_jsx(Button, { variant: "icon", size: "sm", className: "px-2", onClick: zoomMinus, children: _jsx(Minus, { className: "w-4 h-4 cursor-pointer" }) }), _jsxs("span", { className: "text-sm font-bold text-muted-foreground", children: [Math.floor(zoom * 100), "%"] }), _jsx(Button, { variant: "icon", size: "sm", className: "px-2", onClick: () => setZoom(zoom + 0.1), children: _jsx(Plus, { className: "w-4 h-4 cursor-pointer" }) })] }), _jsxs("div", { className: "flex justify-between font-mono p-2 w-full text-xs text-muted-foreground bg-card", children: [_jsx("span", { children: "0ms" }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.25), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.5), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.75), "ms"] }), _jsxs("span", { children: [Math.floor(endTime - group.startTime), "ms"] }), _jsxs("div", { className: "absolute bottom-[-4px] w-full flex justify-between", children: [_jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" })] })] })] }), _jsx("div", { className: "flex flex-col w-full h-full", children: data?.map((trace) => (_jsx(TraceItem, { trace: trace, group: group, groupEndTime: endTime, onExpand: selectTraceId }, trace.id))) })] }) }), selectedTrace && _jsx(TraceItemDetail, { trace: selectedTrace, onClose: () => selectTraceId(undefined) })] }));
28
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col flex-1 overflow-x-auto h-full relative", children: _jsxs("div", { className: "flex flex-col items-center min-w-full sticky top-0", style: { width: `${zoom * 1000}px` }, children: [_jsxs("div", { className: "flex flex-1 w-full sticky top-0 bg-background z-10", children: [_jsxs("div", { className: "w-full min-h-[37px] h-[37px] min-w-[200px] max-w-[200px] flex items-center justify-center gap-2 sticky left-0 top-0 bg-card backdrop-blur-[4px] backdrop-filter", children: [_jsx(Button, { variant: "icon", size: "sm", className: "px-2", onClick: zoomMinus, children: _jsx(Minus, { className: "w-4 h-4 cursor-pointer" }) }), _jsxs("span", { className: "text-sm font-bold text-muted-foreground", children: [Math.floor(zoom * 100), "%"] }), _jsx(Button, { variant: "icon", size: "sm", className: "px-2", onClick: () => setZoom(zoom + 0.1), children: _jsx(Plus, { className: "w-4 h-4 cursor-pointer" }) })] }), _jsxs("div", { className: "flex justify-between font-mono p-2 w-full text-xs text-muted-foreground bg-card", children: [_jsx("span", { children: "0ms" }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.25), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.5), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.75), "ms"] }), _jsxs("span", { children: [Math.floor(endTime - group.startTime), "ms"] }), _jsxs("div", { className: "absolute bottom-[-4px] w-full flex justify-between", children: [_jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" }), _jsx("span", { className: "w-[1px] h-full bg-blue-500" })] })] })] }), _jsx("div", { className: "flex flex-col w-full h-full", children: data?.map((trace) => (_jsx(TraceItem, { trace: trace, group: group, groupEndTime: endTime, onExpand: selectTraceId }, trace.id))) })] }) }), selectedTrace && _jsx(TraceItemDetail, { trace: selectedTrace, onClose: () => selectTraceId(undefined) })] }));
29
29
  });
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '@/lib/utils';
2
+ import { cn } from '@motiadev/ui';
3
3
  import { formatDistanceToNow } from 'date-fns';
4
4
  import { memo } from 'react';
5
5
  import { TraceStatusBadge } from './trace-status';
@@ -3,19 +3,31 @@ import { TraceTimeline } from '@/components/observability/trace-timeline';
3
3
  import { useStreamGroup } from '@motiadev/stream-client-react';
4
4
  import { TracesGroups } from '@/components/observability/traces-groups';
5
5
  import { useGlobalStore } from '../../stores/use-global-store';
6
- import { useEffect } from 'react';
6
+ import { useEffect, useMemo, useState } from 'react';
7
+ import { Button, cn, Input } from '@motiadev/ui';
8
+ import { Search, Trash, X } from 'lucide-react';
7
9
  export const TracesPage = () => {
8
10
  const selectedGroupId = useGlobalStore((state) => state.selectedTraceGroupId);
9
11
  const selectTraceGroupId = useGlobalStore((state) => state.selectTraceGroupId);
10
12
  const { data } = useStreamGroup({ streamName: 'motia-trace-group', groupId: 'default' });
11
13
  const handleGroupSelect = (group) => selectTraceGroupId(group.id);
14
+ const [search, setSearch] = useState('');
15
+ const clearTraces = () => fetch('/__motia/trace/clear', { method: 'POST' });
16
+ const traceGroups = useMemo(() => data?.filter((group) => group.name.toLowerCase().includes(search.toLowerCase()) ||
17
+ group.id.toLowerCase().includes(search.toLowerCase())), [data, search]);
12
18
  useEffect(() => {
13
- if (data && data.length > 0) {
14
- const group = data[data.length - 1];
19
+ if (traceGroups && traceGroups.length > 0) {
20
+ const group = traceGroups[traceGroups.length - 1];
15
21
  if (group && group.status === 'running' && group.id !== selectedGroupId) {
16
22
  selectTraceGroupId(group.id);
17
23
  }
18
24
  }
19
- }, [data]);
20
- return (_jsxs("div", { className: "flex flex-1 overflow-hidden h-full", children: [_jsx("div", { className: "max-w-1/3 border-r border-border overflow-auto h-full", "data-testid": "traces-container", children: _jsx(TracesGroups, { groups: data, selectedGroupId: selectedGroupId, onGroupSelect: handleGroupSelect }) }), _jsxs("div", { className: "flex-2 overflow-auto", "data-testid": "trace-details", children: [selectedGroupId && _jsx(TraceTimeline, { groupId: selectedGroupId }), !selectedGroupId && (_jsx("div", { className: "flex items-center justify-center h-full text-muted-foreground", children: "Select a trace or trace group to view the timeline" }))] })] }));
25
+ else if (selectedGroupId) {
26
+ selectTraceGroupId(undefined);
27
+ }
28
+ }, [traceGroups]);
29
+ return (_jsxs("div", { className: "grid grid-rows-[auto_1fr] h-full", children: [_jsxs("div", { className: "flex p-2 border-b gap-2", "data-testid": "logs-search-container", children: [_jsxs("div", { className: "flex-1 relative", children: [_jsx(Input, { variant: "shade", value: search, onChange: (e) => setSearch(e.target.value), className: "px-9 font-medium", placeholder: "Search by Trace ID or Step Name" }), _jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50" }), _jsx(X, { className: cn('cursor-pointer absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50 hover:text-muted-foreground', {
30
+ visible: search !== '',
31
+ invisible: search === '',
32
+ }), onClick: () => setSearch('') })] }), _jsxs(Button, { variant: "default", onClick: clearTraces, className: "h-[34px]", children: [_jsx(Trash, {}), " Clear"] })] }), _jsxs("div", { className: "grid grid-cols-[300px_1fr] overflow-hidden", children: [_jsx("div", { className: "w-[300px] border-r border-border overflow-auto h-full", "data-testid": "traces-container", children: _jsx(TracesGroups, { groups: traceGroups, selectedGroupId: selectedGroupId, onGroupSelect: handleGroupSelect }) }), _jsxs("div", { className: "overflow-auto", "data-testid": "trace-details", children: [selectedGroupId && _jsx(TraceTimeline, { groupId: selectedGroupId }), !selectedGroupId && (_jsx("div", { className: "flex items-center justify-center h-full text-muted-foreground", children: "Select a trace or trace group to view the timeline" }))] })] })] }));
21
33
  };
@@ -4,4 +4,10 @@ export interface StateItem {
4
4
  type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null';
5
5
  value: string | number | boolean | object | unknown[] | null;
6
6
  }
7
- export declare const useGetStateItems: () => StateItem[];
7
+ type Output = {
8
+ items: StateItem[];
9
+ deleteItems: (ids: string[]) => void;
10
+ refetch: () => void;
11
+ };
12
+ export declare const useGetStateItems: () => Output;
13
+ export {};
@@ -1,7 +1,7 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useState, useCallback } from 'react';
2
2
  export const useGetStateItems = () => {
3
3
  const [items, setItems] = useState([]);
4
- useEffect(() => {
4
+ const refetch = useCallback(() => {
5
5
  fetch('/__motia/state')
6
6
  .then(async (res) => {
7
7
  if (res.ok) {
@@ -14,5 +14,13 @@ export const useGetStateItems = () => {
14
14
  .then(setItems)
15
15
  .catch((err) => console.error(err));
16
16
  }, []);
17
- return items;
17
+ const deleteItems = (ids) => {
18
+ fetch('/__motia/state/delete', {
19
+ method: 'POST',
20
+ headers: { 'Content-Type': 'application/json' },
21
+ body: JSON.stringify({ ids }),
22
+ }).then(() => refetch());
23
+ };
24
+ useEffect(refetch, [refetch]);
25
+ return { items, deleteItems, refetch };
18
26
  };
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Button } from '@motiadev/ui';
3
3
  import { AlertCircle, Check, Loader2, Save } from 'lucide-react';
4
4
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
- import { JsonEditor } from '../endpoints/json-editor';
5
+ import { JsonEditor } from '../ui/json-editor';
6
6
  export const StateEditor = ({ state }) => {
7
7
  const [isRequestLoading, setIsRequestLoading] = useState(false);
8
8
  const [isValid, setIsValid] = useState(true);
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Sidebar } from '@/components/sidebar/sidebar';
2
+ import { Sidebar } from '@motiadev/ui';
3
3
  import { X } from 'lucide-react';
4
4
  import { StateDetails } from './state-details';
5
5
  import { StateEditor } from './state-editor';
@@ -1,18 +1,56 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useGlobalStore } from '@/stores/use-global-store';
3
- import { cn } from '@motiadev/ui';
4
- import { useMemo } from 'react';
3
+ import { Checkbox, Button, cn, Input } from '@motiadev/ui';
4
+ import { RefreshCw, Search, Trash, X } from 'lucide-react';
5
+ import { useMemo, useState } from 'react';
5
6
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
6
7
  import { useGetStateItems } from './hooks/states-hooks';
7
8
  import { StateSidebar } from './state-sidebar';
8
9
  export const StatesPage = () => {
9
10
  const selectedStateId = useGlobalStore((state) => state.selectedStateId);
10
11
  const selectStateId = useGlobalStore((state) => state.selectStateId);
11
- const items = useGetStateItems();
12
- const selectedItem = useMemo(() => (selectedStateId ? items.find((item) => `${item.groupId}:${item.key}` === selectedStateId) : null), [items, selectedStateId]);
12
+ const { items, deleteItems, refetch } = useGetStateItems();
13
+ const [search, setSearch] = useState('');
14
+ const filteredItems = useMemo(() => {
15
+ return items.filter((item) => {
16
+ return (item.groupId.toLowerCase().includes(search.toLowerCase()) ||
17
+ item.key.toLowerCase().includes(search.toLowerCase()));
18
+ });
19
+ }, [items, search]);
20
+ const selectedItem = useMemo(() => (selectedStateId ? filteredItems.find((item) => `${item.groupId}:${item.key}` === selectedStateId) : null), [filteredItems, selectedStateId]);
21
+ const [checkedItems, setCheckedItems] = useState(new Set());
13
22
  const handleRowClick = (item) => selectStateId(`${item.groupId}:${item.key}`);
14
23
  const onClose = () => selectStateId(undefined);
15
- return (_jsxs("div", { className: "flex flex-row gap-4 h-full", "data-testid": "states-container", children: [selectedItem && _jsx(StateSidebar, { state: selectedItem, onClose: onClose }), _jsxs(Table, { children: [_jsx(TableHeader, { className: "sticky top-0 bg-background", children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "rounded-0", children: "Group ID" }), _jsx(TableHead, { children: "Key" }), _jsx(TableHead, { children: "Type" })] }) }), _jsx(TableBody, { children: items.map((item) => (_jsxs(TableRow, { "data-testid": `item-${item}`, onClick: () => handleRowClick(item), className: cn('font-mono font-semibold cursor-pointer border-0', selectedItem === item
16
- ? 'bg-muted-foreground/10 hover:bg-muted-foreground/20'
17
- : 'hover:bg-muted-foreground/10'), children: [_jsx(TableCell, { className: "hover:bg-transparent", children: item.groupId }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.key }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.type })] }, `${item.groupId}:${item.key}`))) })] })] }));
24
+ const deleteStates = () => {
25
+ deleteItems(Array.from(checkedItems));
26
+ setCheckedItems(new Set());
27
+ };
28
+ const handleCheckboxChange = (item) => {
29
+ const isChecked = checkedItems.has(`${item.groupId}:${item.key}`);
30
+ setCheckedItems((prev) => {
31
+ const newSet = new Set(prev);
32
+ if (isChecked) {
33
+ newSet.delete(`${item.groupId}:${item.key}`);
34
+ }
35
+ else {
36
+ newSet.add(`${item.groupId}:${item.key}`);
37
+ }
38
+ return newSet;
39
+ });
40
+ };
41
+ const toggleSelectAll = (checked) => {
42
+ setCheckedItems((prev) => {
43
+ const newSet = new Set(prev);
44
+ if (checked) {
45
+ filteredItems.forEach((item) => newSet.add(`${item.groupId}:${item.key}`));
46
+ }
47
+ else {
48
+ filteredItems.forEach((item) => newSet.delete(`${item.groupId}:${item.key}`));
49
+ }
50
+ return newSet;
51
+ });
52
+ };
53
+ return (_jsxs(_Fragment, { children: [selectedItem && _jsx(StateSidebar, { state: selectedItem, onClose: onClose }), _jsxs("div", { className: "grid grid-rows-[auto_1fr] h-full", "data-testid": "states-container", children: [_jsxs("div", { className: "flex p-2 border-b gap-2", "data-testid": "logs-search-container", children: [_jsxs("div", { className: "flex-1 relative", children: [_jsx(Input, { variant: "shade", value: search, onChange: (e) => setSearch(e.target.value), className: "px-9 font-medium", placeholder: "Search by Group ID or Key" }), _jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50" }), _jsx(X, { className: "cursor-pointer absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/50 hover:text-muted-foreground", onClick: () => setSearch('') })] }), _jsxs(Button, { variant: "default", className: "h-[34px]", disabled: checkedItems.size === 0, onClick: deleteStates, children: [_jsx(Trash, {}), " Delete"] }), _jsx(Button, { variant: "default", className: "h-[34px]", onClick: refetch, children: _jsx(RefreshCw, { className: "w-4 h-4 text-muted-foreground" }) })] }), _jsxs(Table, { children: [_jsx(TableHeader, { className: "sticky top-0 bg-background/20 backdrop-blur-sm", children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: _jsx(Checkbox, { onClick: (evt) => evt.stopPropagation(), onCheckedChange: toggleSelectAll }) }), _jsx(TableHead, { className: "rounded-0", children: "Group ID" }), _jsx(TableHead, { children: "Key" }), _jsx(TableHead, { children: "Type" })] }) }), _jsx(TableBody, { children: filteredItems.map((item) => (_jsxs(TableRow, { "data-testid": `item-${item}`, onClick: () => handleRowClick(item), className: cn('font-mono font-semibold cursor-pointer border-0', selectedItem === item
54
+ ? 'bg-muted-foreground/10 hover:bg-muted-foreground/20'
55
+ : 'hover:bg-muted-foreground/10'), children: [_jsx(TableCell, { onClick: (evt) => evt.stopPropagation(), children: _jsx(Checkbox, { checked: checkedItems.has(`${item.groupId}:${item.key}`), onClick: () => handleCheckboxChange(item) }) }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.groupId }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.key }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.type })] }, `${item.groupId}:${item.key}`))) })] })] })] }));
18
56
  };
@@ -9,8 +9,13 @@ export declare const workbenchXPath: {
9
9
  node: (stepId: string) => string;
10
10
  };
11
11
  endpoints: {
12
+ endpointsList: string;
12
13
  endpoint: (method: string, path: string) => string;
13
14
  callPanel: string;
15
+ specButton: string;
16
+ bodyTab: string;
17
+ headersTab: string;
18
+ paramsTab: string;
14
19
  callTab: string;
15
20
  response: string;
16
21
  playButton: string;
@@ -9,9 +9,14 @@ export const workbenchXPath = {
9
9
  node: (stepId) => `//div[@data-testid="node-${stepId}"]`,
10
10
  },
11
11
  endpoints: {
12
+ endpointsList: '//div[@data-testid="endpoints-list"]',
12
13
  endpoint: (method, path) => `//div[@data-testid="endpoint-${method}-${path}"]`,
13
- callPanel: '//div[@data-testid="endpoint-body-panel__call"]',
14
- callTab: '//button[@data-testid="endpoint-call-tab"]',
14
+ callPanel: '//div[@data-testid="endpoint-details-panel"]',
15
+ specButton: '//button[@data-testid="endpoint-spec-button"]',
16
+ bodyTab: '//button[@data-testid="endpoint-body-tab"]',
17
+ headersTab: '//button[@data-testid="endpoint-headers-tab"]',
18
+ paramsTab: '//button[@data-testid="endpoint-params-tab"]',
19
+ callTab: '//button[@data-testid="endpoint-body-tab"]', // deprecated
15
20
  response: '//div[@data-testid="endpoint-response-container"]',
16
21
  playButton: '//button[@data-testid="endpoint-play-button"]',
17
22
  },
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef, useEffect } from 'react';
3
+ import { BackgroundEffect } from '@motiadev/ui';
3
4
  export const TutorialStep = forwardRef(({ step, totalSteps, title, description, link, image, onNext, onClose }, ref) => {
4
5
  useEffect(() => {
5
6
  const handleKeyDown = (e) => {
@@ -13,6 +14,6 @@ export const TutorialStep = forwardRef(({ step, totalSteps, title, description,
13
14
  window.addEventListener('keydown', handleKeyDown);
14
15
  return () => window.removeEventListener('keydown', handleKeyDown);
15
16
  }, [onClose, onNext]);
16
- return (_jsxs("div", { ref: ref, className: "driver-popover", children: [image && (_jsx("img", { src: image.src, alt: "Step visual", className: "driver-popover-image object-cover", style: { height: image.height, width: '100%' } })), _jsx("div", { className: "driver-popover-title", children: _jsx("h2", { className: "popover-title", children: title }) }), _jsx("div", { className: "driver-popover-description", children: description }), link && (_jsx("a", { href: link, target: "_blank", className: "text-foreground text-xs font-semibold px-4 hover:underline", children: "Learn more" })), _jsxs("div", { className: "driver-popover-footer flex items-center justify-between", children: [_jsxs("div", { className: "text-sm text-muted-foreground font-semibold", children: [step, " ", _jsx("span", { className: "text-foreground", children: "/" }), " ", totalSteps] }), _jsx("div", { className: "driver-popover-navigation-btns driver-popover-navigation-btns-hint flex gap-2", children: _jsx("button", { className: "driver-popover-next-btn", onClick: onNext, children: step < totalSteps ? 'Continue' : 'Finish' }) })] }), step < totalSteps && (_jsx("div", { className: "tutorial-opt-out-container", children: _jsx("button", { className: "tutorial-opt-out-button", onClick: onClose, children: "Close" }) }))] }));
17
+ return (_jsxs("div", { ref: ref, className: "driver-popover ", children: [image && (_jsx("img", { src: image.src, alt: "Step visual", className: "driver-popover-image object-cover", style: { height: image.height, width: '100%' } })), _jsxs("div", { className: "isolate relative", children: [_jsx(BackgroundEffect, {}), _jsx("div", { className: "driver-popover-title", children: _jsx("h2", { className: "popover-title", children: title }) }), _jsx("div", { className: "driver-popover-description", children: description }), link && (_jsx("a", { href: link, target: "_blank", className: "text-foreground text-xs font-semibold px-4 hover:underline", children: "Learn more" })), _jsxs("div", { className: "driver-popover-footer flex items-center justify-between", children: [_jsxs("div", { className: "text-sm text-muted-foreground font-semibold", children: [step, " ", _jsx("span", { className: "text-foreground", children: "/" }), " ", totalSteps] }), _jsx("div", { className: "driver-popover-navigation-btns driver-popover-navigation-btns-hint flex gap-2", children: _jsx("button", { className: "driver-popover-next-btn", onClick: onNext, children: step < totalSteps ? 'Continue' : 'Finish' }) })] }), step < totalSteps && (_jsx("div", { className: "tutorial-opt-out-container", children: _jsx("button", { className: "tutorial-opt-out-button", onClick: onClose, children: "Close" }) }))] })] }));
17
18
  });
18
19
  TutorialStep.displayName = 'TutorialStep';
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useThemeStore } from '@/stores/use-theme-store';
2
+ import { useThemeStore } from '@motiadev/ui';
3
3
  import Editor, { useMonaco } from '@monaco-editor/react';
4
4
  import { useEffect, useMemo } from 'react';
5
5
  export const JsonEditor = ({ value, height = 300, schema, onChange, onValidate, language = 'json', readOnly = false, }) => {
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import { cn } from '@/lib/utils';
3
+ import { cn } from '@motiadev/ui';
4
4
  const Table = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { className: "relative w-full overflow-auto", children: _jsx("table", { ref: ref, className: cn('w-full caption-bottom text-sm', className), ...props }) })));
5
5
  Table.displayName = 'Table';
6
6
  const TableHeader = React.forwardRef(({ className, ...props }, ref) => _jsx("thead", { ref: ref, className: cn('[&_tr]:border-b', className), ...props }));
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn, useThemeStore } from '@motiadev/ui';
2
3
  import { Moon, Sun } from 'lucide-react';
3
- import { useThemeStore } from '@/stores/use-theme-store';
4
- import { cn } from '@/lib/utils';
5
4
  import { useEffect } from 'react';
6
5
  export const ThemeToggle = () => {
7
6
  const theme = useThemeStore((state) => state.theme);
@@ -1,5 +1,7 @@
1
- @import "@motiadev/ui/styles.css";
2
- @import "@motiadev/ui/globals.css";
1
+ @import '@motiadev/plugin-endpoint/styles.css';
2
+ @import '@motiadev/ui/styles.css';
3
+ @import '@motiadev/ui/globals.css';
4
+
3
5
  @import 'tw-animate-css';
4
6
  @config "../tailwind.config.js";
5
7
 
@@ -13,12 +15,12 @@
13
15
  }
14
16
 
15
17
  .json-view {
16
- background:rgba(0, 0, 0, 0.1);
18
+ background: rgba(0, 0, 0, 0.1);
17
19
  }
18
20
 
19
21
  .dark {
20
22
  .react-flow__panel {
21
- background: var(--background)
23
+ background: var(--background);
22
24
  }
23
25
  .json-view {
24
26
  background: rgba(0, 0, 0, 0.8);
@@ -45,10 +47,12 @@
45
47
  font-weight: 500;
46
48
  }
47
49
 
48
- .json-view--pair, .json-view--property, .json-view > span {
50
+ .json-view--pair,
51
+ .json-view--property,
52
+ .json-view > span {
49
53
  line-height: 24px;
50
54
  }
51
55
 
52
56
  .json-view--property {
53
57
  font-weight: 600;
54
- }
58
+ }
@@ -1,4 +1,2 @@
1
- import { type ClassValue } from 'clsx';
2
- export declare function cn(...inputs: ClassValue[]): string;
3
1
  export declare const formatDuration: (duration?: number) => string;
4
2
  export declare const formatTimestamp: (time: number) => string;
@@ -1,8 +1,3 @@
1
- import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
- export function cn(...inputs) {
4
- return twMerge(clsx(inputs));
5
- }
6
1
  export const formatDuration = (duration) => {
7
2
  if (!duration)
8
3
  return 'N/A';
@@ -24,7 +24,7 @@ export const BaseNode = ({ title, variant, children, disableSourceHandle, disabl
24
24
  }, [data.id, isOpen, fetchContent]);
25
25
  return (_jsxs("div", { className: cn('p-1 rounded-lg max-w-[350px]', {
26
26
  'bg-muted-foreground/20': isOpen,
27
- }), children: [_jsx("div", { className: "rounded-lg dark:bg-[#222] bg-background border-1 border-muted-foreground/30 border-solid", "data-testid": `node-${title?.toLowerCase().replace(/ /g, '-')}`, children: _jsxs("div", { className: "group relative", children: [_jsx(NodeHeader, { text: title, variant: variant, className: "border-b-2 border-muted-foreground/10", children: _jsx("div", { className: "flex justify-end", children: _jsx(Button, { "data-testid": `open-code-preview-button-${title?.toLowerCase()}`, variant: "ghost", className: "h-5 p-0.5", onClick: () => setIsOpen(true), children: _jsx(ScanSearch, { className: "w-4 h-4" }) }) }) }), subtitle && _jsx("div", { className: "py-4 px-6 text-sm text-muted-foreground", children: subtitle }), children && (_jsx("div", { className: "p-2", children: _jsx("div", { className: cn('space-y-3 p-4 text-sm text-muted-foreground', {
27
+ }), children: [_jsx("div", { className: "rounded-lg dark:bg-[#101010] bg-background border-1 border-muted-foreground/30 border-solid", "data-testid": `node-${title?.toLowerCase().replace(/ /g, '-')}`, children: _jsxs("div", { className: "group relative", children: [_jsx(NodeHeader, { text: title, variant: variant, className: "border-b-2 border-muted-foreground/10", children: _jsx("div", { className: "flex justify-end", children: _jsx(Button, { "data-testid": `open-code-preview-button-${title?.toLowerCase()}`, variant: "ghost", className: "h-5 p-0.5", onClick: () => setIsOpen(true), children: _jsx(ScanSearch, { className: "w-4 h-4" }) }) }) }), subtitle && _jsx("div", { className: "py-4 px-6 text-sm text-muted-foreground", children: subtitle }), children && (_jsx("div", { className: "p-2", children: _jsx("div", { className: cn('space-y-3 p-4 text-sm text-muted-foreground', {
28
28
  'bg-card': variant !== 'noop',
29
29
  }), children: children }) })), !disableTargetHandle && (_jsx(BaseHandle, { type: "target", position: targetPosition, onTogglePosition: toggleTargetPosition })), !disableSourceHandle && (_jsx(BaseHandle, { type: "source", position: sourcePosition, onTogglePosition: toggleSourcePosition }))] }) }), content && (_jsx(NodeSidebar, { features: features, content: content, title: title, subtitle: subtitle, variant: variant, language: language, isOpen: isOpen, onClose: () => setIsOpen(false) }))] }));
30
30
  };
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useThemeStore } from '@/stores/use-theme-store';
2
+ import { useThemeStore } from '@motiadev/ui';
3
3
  import { FeatureCard } from './feature-card';
4
4
  import { useRef, useState } from 'react';
5
5
  import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
6
- import { dracula, oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
6
+ import { oneDark, oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
7
7
  import { LanguageIndicator } from './language-indicator';
8
8
  const codeTagProps = {
9
9
  style: {
@@ -31,7 +31,7 @@ const getFirstLineNumber = (line) => {
31
31
  };
32
32
  export const CodeDisplay = ({ code, language, features }) => {
33
33
  const theme = useThemeStore((state) => state.theme);
34
- const themeStyle = theme === 'dark' ? dracula : oneLight;
34
+ const themeStyle = theme === 'dark' ? oneDark : oneLight;
35
35
  const [highlightedLines, setHighlightedLines] = useState([]);
36
36
  const [selectedFeature, setSelectedFeature] = useState(null);
37
37
  const ref = useRef(null);
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '@/lib/utils';
2
+ import { cn } from '@motiadev/ui';
3
3
  export const FeatureCard = ({ feature, highlighted, onClick, onHover }) => {
4
4
  return (_jsxs("div", { "data-feature-id": feature.id, className: cn('p-4 rounded-lg bg-card shadow-sm cursor-pointer hover:bg-card/50 border-2 border-transparent', highlighted && 'border-2 border-accent-1000 bg-accent-100'), onClick: onClick, onMouseEnter: onHover, children: [_jsx("div", { className: "text-md font-semibold text-foreground leading-tight whitespace-nowrap mb-2", children: feature.title }), _jsx("div", { className: "text-sm font-medium text-muted-foreground leading-tight", children: feature.description }), feature.link && (_jsx("div", { className: "text-sm font-medium text-muted-foreground leading-tight", children: _jsx("a", { href: feature.link, children: "Learn more" }) }))] }));
5
5
  };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '@/lib/utils';
2
+ import { cn } from '@motiadev/ui';
3
3
  import { cva } from 'class-variance-authority';
4
4
  import { CalendarClock, CircleOff, Link2, Waypoints } from 'lucide-react';
5
5
  const baseIcon = cva('rounded-md p-2', {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Sidebar } from '@/components/sidebar/sidebar';
2
+ import { Sidebar } from '@motiadev/ui';
3
3
  import { X } from 'lucide-react';
4
4
  import { CodeDisplay } from './code-display';
5
5
  export const NodeSidebar = ({ content, title, subtitle, language, isOpen, onClose, features, }) => {
@@ -4,15 +4,17 @@ type UseFlowStore = {
4
4
  flows: string[];
5
5
  setFlows: (flows: string[]) => void;
6
6
  };
7
- export declare const useFlowStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseFlowStore>, "persist"> & {
7
+ export declare const useFlowStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseFlowStore>, "setState" | "persist"> & {
8
+ setState(partial: UseFlowStore | Partial<UseFlowStore> | ((state: UseFlowStore) => UseFlowStore | Partial<UseFlowStore>), replace?: false | undefined): unknown;
9
+ setState(state: UseFlowStore | ((state: UseFlowStore) => UseFlowStore), replace: true): unknown;
8
10
  persist: {
9
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore>>) => void;
11
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore, unknown>>) => void;
10
12
  clearStorage: () => void;
11
13
  rehydrate: () => Promise<void> | void;
12
14
  hasHydrated: () => boolean;
13
15
  onHydrate: (fn: (state: UseFlowStore) => void) => () => void;
14
16
  onFinishHydration: (fn: (state: UseFlowStore) => void) => () => void;
15
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore>>;
17
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore, unknown>>;
16
18
  };
17
19
  }>;
18
20
  export {};
@@ -10,15 +10,17 @@ type UseGlobalStore = {
10
10
  selectedLogId?: string;
11
11
  selectLogId: (logId?: string) => void;
12
12
  };
13
- export declare const useGlobalStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseGlobalStore>, "persist"> & {
13
+ export declare const useGlobalStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseGlobalStore>, "setState" | "persist"> & {
14
+ setState(partial: UseGlobalStore | Partial<UseGlobalStore> | ((state: UseGlobalStore) => UseGlobalStore | Partial<UseGlobalStore>), replace?: false | undefined): unknown;
15
+ setState(state: UseGlobalStore | ((state: UseGlobalStore) => UseGlobalStore), replace: true): unknown;
14
16
  persist: {
15
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore>>) => void;
17
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore, unknown>>) => void;
16
18
  clearStorage: () => void;
17
19
  rehydrate: () => Promise<void> | void;
18
20
  hasHydrated: () => boolean;
19
21
  onHydrate: (fn: (state: UseGlobalStore) => void) => () => void;
20
22
  onFinishHydration: (fn: (state: UseGlobalStore) => void) => () => void;
21
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore>>;
23
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore, unknown>>;
22
24
  };
23
25
  }>;
24
26
  export {};