@mdxui/do 2.1.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +115 -323
  2. package/dist/{agents-xcIn2dUB.d.ts → agents-2_r9e9i7.d.ts} +213 -2
  3. package/dist/app/index.d.ts +347 -0
  4. package/dist/app/index.js +14 -0
  5. package/dist/app/index.js.map +1 -0
  6. package/dist/breadcrumbs-C9Qn3S7d.d.ts +81 -0
  7. package/dist/capnweb-client-Bq78FtEA.d.ts +229 -0
  8. package/dist/chunk-3XKYQRXY.js +192 -0
  9. package/dist/chunk-3XKYQRXY.js.map +1 -0
  10. package/dist/chunk-4KXVN3EQ.js +56 -0
  11. package/dist/chunk-4KXVN3EQ.js.map +1 -0
  12. package/dist/chunk-5SHZZC7L.js +234 -0
  13. package/dist/chunk-5SHZZC7L.js.map +1 -0
  14. package/dist/chunk-7UFINK3Q.js +1994 -0
  15. package/dist/chunk-7UFINK3Q.js.map +1 -0
  16. package/dist/chunk-JJLAES6W.js +76 -0
  17. package/dist/chunk-JJLAES6W.js.map +1 -0
  18. package/dist/chunk-KT52UU3U.js +985 -0
  19. package/dist/chunk-KT52UU3U.js.map +1 -0
  20. package/dist/chunk-LJIWB7KE.js +95 -0
  21. package/dist/chunk-LJIWB7KE.js.map +1 -0
  22. package/dist/chunk-NA652ART.js +596 -0
  23. package/dist/chunk-NA652ART.js.map +1 -0
  24. package/dist/chunk-OVLO7UOH.js +1071 -0
  25. package/dist/chunk-OVLO7UOH.js.map +1 -0
  26. package/dist/chunk-VRLUXCLD.js +31 -0
  27. package/dist/chunk-VRLUXCLD.js.map +1 -0
  28. package/dist/chunk-WMNT4OIE.js +249 -0
  29. package/dist/chunk-WMNT4OIE.js.map +1 -0
  30. package/dist/chunk-Y52IEYVM.js +131 -0
  31. package/dist/chunk-Y52IEYVM.js.map +1 -0
  32. package/dist/components/index.d.ts +14 -732
  33. package/dist/components/index.js +3 -6
  34. package/dist/config-CxvpD8Y6.d.ts +111 -0
  35. package/dist/{do-CaQVueZw.d.ts → do-D27i5bU0.d.ts} +32 -33
  36. package/dist/errors-DratdVIz.d.ts +346 -0
  37. package/dist/hooks/index.d.ts +450 -691
  38. package/dist/hooks/index.js +6 -4
  39. package/dist/hooks/things/index.d.ts +298 -0
  40. package/dist/hooks/things/index.js +8 -0
  41. package/dist/hooks/things/index.js.map +1 -0
  42. package/dist/index.d.ts +62 -989
  43. package/dist/index.js +12 -839
  44. package/dist/index.js.map +1 -1
  45. package/dist/lib/index.d.ts +798 -0
  46. package/dist/lib/index.js +6 -0
  47. package/dist/lib/index.js.map +1 -0
  48. package/dist/providers/index.d.ts +130 -34
  49. package/dist/providers/index.js +3 -2
  50. package/dist/query-keys-CZNFikIi.d.ts +153 -0
  51. package/dist/schemas/index.d.ts +5 -5
  52. package/dist/schemas/index.js +2 -2
  53. package/dist/schemas/index.js.map +1 -1
  54. package/dist/{thing-DtI25yZh.d.ts → thing-BF25aUtJ.d.ts} +72 -72
  55. package/dist/types/index.d.ts +693 -658
  56. package/dist/types/index.js +1 -2
  57. package/dist/views/index.d.ts +131 -0
  58. package/dist/views/index.js +11 -0
  59. package/dist/views/index.js.map +1 -0
  60. package/package.json +39 -17
  61. package/dist/__test-utils__/index.d.ts +0 -399
  62. package/dist/__test-utils__/index.js +0 -34641
  63. package/dist/__test-utils__/index.js.map +0 -1
  64. package/dist/chunk-EEDMN7UF.js +0 -1351
  65. package/dist/chunk-EEDMN7UF.js.map +0 -1
  66. package/dist/chunk-G3PMV62Z.js +0 -33
  67. package/dist/chunk-G3PMV62Z.js.map +0 -1
  68. package/dist/chunk-NXPXL5NA.js +0 -3789
  69. package/dist/chunk-NXPXL5NA.js.map +0 -1
  70. package/dist/chunk-PC5FJY6M.js +0 -20
  71. package/dist/chunk-PC5FJY6M.js.map +0 -1
  72. package/dist/chunk-XF6LKY2M.js +0 -445
  73. package/dist/chunk-XF6LKY2M.js.map +0 -1
  74. package/dist/magic-string.es-J7BYFTTJ.js +0 -1307
  75. package/dist/magic-string.es-J7BYFTTJ.js.map +0 -1
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Cap'n Web Client Wrapper for DO Admin API
3
+ *
4
+ * This wraps the raw capnweb HTTP batch client to provide a structured interface
5
+ * matching the DOClient interface (client.Thing.list, client.Schema.discover, etc.)
6
+ *
7
+ * @module
8
+ */
9
+ /** SQL execution result */
10
+ interface SQLResult {
11
+ rows: Record<string, unknown>[];
12
+ columns: {
13
+ name: string;
14
+ type: string;
15
+ }[];
16
+ rowsAffected?: number;
17
+ executionTimeMs?: number;
18
+ }
19
+ interface CapnwebClientOptions {
20
+ /** Auth token to include in Authorization header */
21
+ authToken?: string;
22
+ }
23
+ /**
24
+ * Create a Cap'n Web client that matches the DOClient interface
25
+ *
26
+ * @param baseUrl - The base URL for the RPC endpoint
27
+ * @param options - Client options including auth token
28
+ */
29
+ declare function createCapnwebClient(baseUrl: string, options?: CapnwebClientOptions): {
30
+ /**
31
+ * Namespace operations
32
+ */
33
+ Namespace: {
34
+ list(_params?: {
35
+ includeSystem?: boolean;
36
+ }): Promise<{
37
+ id: string;
38
+ name: string;
39
+ }[]>;
40
+ };
41
+ /**
42
+ * Schema operations
43
+ */
44
+ Schema: {
45
+ discover(_params?: {
46
+ ns?: string;
47
+ }): Promise<{
48
+ namespaces: string[];
49
+ types: string[];
50
+ schemas: string[];
51
+ }>;
52
+ get(params: {
53
+ ns?: string;
54
+ type: string;
55
+ }): Promise<unknown>;
56
+ };
57
+ /**
58
+ * Thing operations
59
+ */
60
+ Thing: {
61
+ types(params: {
62
+ ns?: string;
63
+ includeSystem?: boolean;
64
+ }): Promise<{
65
+ name: string;
66
+ ns: string;
67
+ }[]>;
68
+ list(params: {
69
+ ns?: string;
70
+ type?: string;
71
+ limit?: number;
72
+ offset?: number;
73
+ }): Promise<{
74
+ data: unknown[];
75
+ total: number;
76
+ }>;
77
+ get(params: {
78
+ ns?: string;
79
+ type: string;
80
+ id: string;
81
+ }): Promise<unknown>;
82
+ create(params: {
83
+ ns?: string;
84
+ type: string;
85
+ data: unknown;
86
+ }): Promise<unknown>;
87
+ update(params: {
88
+ ns?: string;
89
+ type: string;
90
+ id: string;
91
+ data: unknown;
92
+ }): Promise<unknown>;
93
+ delete(params: {
94
+ ns?: string;
95
+ type: string;
96
+ id: string;
97
+ hard?: boolean;
98
+ }): Promise<{
99
+ success: boolean;
100
+ }>;
101
+ versions(_params: {
102
+ ns?: string;
103
+ type: string;
104
+ id: string;
105
+ }): Promise<never[]>;
106
+ stats(_params: {
107
+ ns?: string;
108
+ type?: string;
109
+ }): Promise<{
110
+ total: number;
111
+ byType: Record<string, number>;
112
+ }>;
113
+ };
114
+ /**
115
+ * SQL operations (not supported by capnweb servers)
116
+ */
117
+ SQL: {
118
+ execute(_params: {
119
+ query: string;
120
+ params?: unknown[];
121
+ }): Promise<SQLResult>;
122
+ };
123
+ dup: () => /*elided*/ any;
124
+ onRpcBroken: (callback: (error: unknown) => void) => void;
125
+ [Symbol.dispose]: () => void;
126
+ };
127
+ /**
128
+ * Create a capnweb client context - factory function matching DOClient interface
129
+ */
130
+ declare function $CapnwebContext(url: string, options?: CapnwebClientOptions): {
131
+ /**
132
+ * Namespace operations
133
+ */
134
+ Namespace: {
135
+ list(_params?: {
136
+ includeSystem?: boolean;
137
+ }): Promise<{
138
+ id: string;
139
+ name: string;
140
+ }[]>;
141
+ };
142
+ /**
143
+ * Schema operations
144
+ */
145
+ Schema: {
146
+ discover(_params?: {
147
+ ns?: string;
148
+ }): Promise<{
149
+ namespaces: string[];
150
+ types: string[];
151
+ schemas: string[];
152
+ }>;
153
+ get(params: {
154
+ ns?: string;
155
+ type: string;
156
+ }): Promise<unknown>;
157
+ };
158
+ /**
159
+ * Thing operations
160
+ */
161
+ Thing: {
162
+ types(params: {
163
+ ns?: string;
164
+ includeSystem?: boolean;
165
+ }): Promise<{
166
+ name: string;
167
+ ns: string;
168
+ }[]>;
169
+ list(params: {
170
+ ns?: string;
171
+ type?: string;
172
+ limit?: number;
173
+ offset?: number;
174
+ }): Promise<{
175
+ data: unknown[];
176
+ total: number;
177
+ }>;
178
+ get(params: {
179
+ ns?: string;
180
+ type: string;
181
+ id: string;
182
+ }): Promise<unknown>;
183
+ create(params: {
184
+ ns?: string;
185
+ type: string;
186
+ data: unknown;
187
+ }): Promise<unknown>;
188
+ update(params: {
189
+ ns?: string;
190
+ type: string;
191
+ id: string;
192
+ data: unknown;
193
+ }): Promise<unknown>;
194
+ delete(params: {
195
+ ns?: string;
196
+ type: string;
197
+ id: string;
198
+ hard?: boolean;
199
+ }): Promise<{
200
+ success: boolean;
201
+ }>;
202
+ versions(_params: {
203
+ ns?: string;
204
+ type: string;
205
+ id: string;
206
+ }): Promise<never[]>;
207
+ stats(_params: {
208
+ ns?: string;
209
+ type?: string;
210
+ }): Promise<{
211
+ total: number;
212
+ byType: Record<string, number>;
213
+ }>;
214
+ };
215
+ /**
216
+ * SQL operations (not supported by capnweb servers)
217
+ */
218
+ SQL: {
219
+ execute(_params: {
220
+ query: string;
221
+ params?: unknown[];
222
+ }): Promise<SQLResult>;
223
+ };
224
+ dup: () => /*elided*/ any;
225
+ onRpcBroken: (callback: (error: unknown) => void) => void;
226
+ [Symbol.dispose]: () => void;
227
+ };
228
+
229
+ export { $CapnwebContext as $, createCapnwebClient as c };
@@ -0,0 +1,192 @@
1
+ import { Input, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, DropdownMenu, DropdownMenuTrigger, BreadcrumbEllipsis, DropdownMenuContent, DropdownMenuItem } from '@mdxui/primitives';
2
+ import { Search, Server, History, Plus } from 'lucide-react';
3
+ import * as React from 'react';
4
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/components/endpoint-selector.tsx
7
+ function useIsMac() {
8
+ const [isMac, setIsMac] = React.useState(false);
9
+ React.useEffect(() => {
10
+ setIsMac(navigator.platform.toUpperCase().indexOf("MAC") >= 0);
11
+ }, []);
12
+ return isMac;
13
+ }
14
+ function EndpointSelector({
15
+ endpoint,
16
+ onEndpointChange,
17
+ recentEndpoints = [],
18
+ placeholder = "Connect to DO...",
19
+ className
20
+ }) {
21
+ const [open, setOpen] = React.useState(false);
22
+ const [customEndpoint, setCustomEndpoint] = React.useState("");
23
+ const isMac = useIsMac();
24
+ React.useEffect(() => {
25
+ function handleKeyDown(e) {
26
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
27
+ e.preventDefault();
28
+ setOpen((prev) => !prev);
29
+ }
30
+ }
31
+ document.addEventListener("keydown", handleKeyDown);
32
+ return () => document.removeEventListener("keydown", handleKeyDown);
33
+ }, []);
34
+ const handleSelect = (url) => {
35
+ onEndpointChange(url);
36
+ setOpen(false);
37
+ setCustomEndpoint("");
38
+ };
39
+ const handleCustomSubmit = () => {
40
+ if (customEndpoint.trim()) {
41
+ handleSelect(customEndpoint.trim());
42
+ }
43
+ };
44
+ const formatEndpoint = (url) => {
45
+ try {
46
+ const parsed = new URL(url);
47
+ return parsed.hostname;
48
+ } catch {
49
+ return url;
50
+ }
51
+ };
52
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
54
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
55
+ /* @__PURE__ */ jsx(
56
+ Input,
57
+ {
58
+ type: "text",
59
+ placeholder,
60
+ value: formatEndpoint(endpoint),
61
+ readOnly: true,
62
+ onClick: () => setOpen(true),
63
+ className: "w-full cursor-pointer pl-9 pr-12 shadow-none"
64
+ }
65
+ ),
66
+ /* @__PURE__ */ jsx("kbd", { className: "pointer-events-none absolute right-3 top-1/2 hidden -translate-y-1/2 select-none rounded-sm border border-border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground sm:inline-block", children: isMac ? "\u2318K" : "Ctrl+K" })
67
+ ] }) }),
68
+ /* @__PURE__ */ jsxs(
69
+ CommandDialog,
70
+ {
71
+ open,
72
+ onOpenChange: setOpen,
73
+ title: "Connect to DO",
74
+ description: "Select a DO server endpoint to connect to",
75
+ children: [
76
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search endpoints or enter URL..." }),
77
+ /* @__PURE__ */ jsxs(CommandList, { children: [
78
+ /* @__PURE__ */ jsx(CommandEmpty, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 py-2", children: [
79
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No endpoints found" }),
80
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Enter a URL above to connect to a custom endpoint" })
81
+ ] }) }),
82
+ /* @__PURE__ */ jsx(CommandGroup, { heading: "Current", children: /* @__PURE__ */ jsxs(
83
+ CommandItem,
84
+ {
85
+ value: endpoint,
86
+ onSelect: () => handleSelect(endpoint),
87
+ children: [
88
+ /* @__PURE__ */ jsx(Server, { className: "text-primary" }),
89
+ /* @__PURE__ */ jsx("span", { className: "flex-1 font-medium", children: formatEndpoint(endpoint) }),
90
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Connected" })
91
+ ]
92
+ }
93
+ ) }),
94
+ recentEndpoints.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ /* @__PURE__ */ jsx(CommandSeparator, {}),
96
+ /* @__PURE__ */ jsx(CommandGroup, { heading: "Recent", children: recentEndpoints.filter((url) => url !== endpoint).map((url) => /* @__PURE__ */ jsxs(
97
+ CommandItem,
98
+ {
99
+ value: url,
100
+ onSelect: () => handleSelect(url),
101
+ children: [
102
+ /* @__PURE__ */ jsx(History, { className: "text-muted-foreground" }),
103
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: formatEndpoint(url) })
104
+ ]
105
+ },
106
+ url
107
+ )) })
108
+ ] }),
109
+ /* @__PURE__ */ jsx(CommandSeparator, {}),
110
+ /* @__PURE__ */ jsx(CommandGroup, { heading: "Custom", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2 py-1.5", children: [
111
+ /* @__PURE__ */ jsx(Plus, { className: "size-4 shrink-0 text-muted-foreground" }),
112
+ /* @__PURE__ */ jsx(
113
+ "input",
114
+ {
115
+ type: "text",
116
+ placeholder: "Enter endpoint URL...",
117
+ value: customEndpoint,
118
+ onChange: (e) => setCustomEndpoint(e.target.value),
119
+ onKeyDown: (e) => {
120
+ if (e.key === "Enter") {
121
+ e.preventDefault();
122
+ handleCustomSubmit();
123
+ }
124
+ e.stopPropagation();
125
+ },
126
+ className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
127
+ }
128
+ ),
129
+ customEndpoint && /* @__PURE__ */ jsx(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: handleCustomSubmit,
134
+ className: "rounded-sm bg-primary px-2 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90",
135
+ children: "Connect"
136
+ }
137
+ )
138
+ ] }) })
139
+ ] })
140
+ ]
141
+ }
142
+ )
143
+ ] });
144
+ }
145
+ function DefaultLink({ href, children, className, onClick }) {
146
+ return /* @__PURE__ */ jsx("a", { href, className, onClick, children });
147
+ }
148
+ function Breadcrumbs({
149
+ items,
150
+ LinkComponent = DefaultLink,
151
+ className,
152
+ maxItems = 4,
153
+ separator
154
+ }) {
155
+ if (!items || items.length === 0) {
156
+ return null;
157
+ }
158
+ const shouldCollapse = items.length > maxItems;
159
+ const visibleItems = shouldCollapse ? [items[0], ...items.slice(-(maxItems - 1))] : items;
160
+ const hiddenItems = shouldCollapse ? items.slice(1, -(maxItems - 1)) : [];
161
+ return /* @__PURE__ */ jsx(Breadcrumb, { className, children: /* @__PURE__ */ jsx(BreadcrumbList, { children: visibleItems.map((item, index) => {
162
+ const isLast = index === visibleItems.length - 1;
163
+ const isFirst = index === 0;
164
+ if (shouldCollapse && isFirst) {
165
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
166
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) }),
167
+ /* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator }),
168
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
169
+ /* @__PURE__ */ jsx(
170
+ DropdownMenuTrigger,
171
+ {
172
+ className: "flex items-center gap-1 hover:text-foreground",
173
+ "aria-label": "Show hidden breadcrumbs",
174
+ children: /* @__PURE__ */ jsx(BreadcrumbEllipsis, { className: "size-4" })
175
+ }
176
+ ),
177
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", children: hiddenItems.map((hiddenItem) => /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: hiddenItem.href || "#", children: hiddenItem.label }) }, hiddenItem.label)) })
178
+ ] }) }),
179
+ /* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator })
180
+ ] }, item.label);
181
+ }
182
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
183
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: isLast ? /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) : item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) }),
184
+ !isLast && /* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator })
185
+ ] }, item.label);
186
+ }) }) });
187
+ }
188
+ Breadcrumbs.displayName = "Breadcrumbs";
189
+
190
+ export { Breadcrumbs, EndpointSelector };
191
+ //# sourceMappingURL=chunk-3XKYQRXY.js.map
192
+ //# sourceMappingURL=chunk-3XKYQRXY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/endpoint-selector.tsx","../src/components/breadcrumbs.tsx"],"names":["jsx","jsxs","React2"],"mappings":"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","file":"chunk-3XKYQRXY.js","sourcesContent":["\"use client\"\n\n/**\n * EndpointSelector Component\n *\n * A command palette-style input for selecting/changing the DO server endpoint.\n * Supports keyboard shortcuts (⌘K on Mac, Ctrl+K on Windows).\n */\n\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n Input,\n} from \"@mdxui/primitives\"\nimport { History, Plus, Search, Server } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface EndpointSelectorProps {\n /** Current endpoint URL */\n endpoint: string\n /** Callback when endpoint changes */\n onEndpointChange: (endpoint: string) => void\n /** Recent endpoints for quick selection */\n recentEndpoints?: string[]\n /** Placeholder text for the trigger input */\n placeholder?: string\n /** Additional class name for the trigger */\n className?: string\n}\n\n/**\n * Detects if the current platform is Mac\n */\nfunction useIsMac() {\n const [isMac, setIsMac] = React.useState(false)\n\n React.useEffect(() => {\n setIsMac(navigator.platform.toUpperCase().indexOf(\"MAC\") >= 0)\n }, [])\n\n return isMac\n}\n\n/**\n * EndpointSelector - Search-like input that opens a command palette for endpoint selection\n */\nexport function EndpointSelector({\n endpoint,\n onEndpointChange,\n recentEndpoints = [],\n placeholder = \"Connect to DO...\",\n className,\n}: EndpointSelectorProps) {\n const [open, setOpen] = React.useState(false)\n const [customEndpoint, setCustomEndpoint] = React.useState(\"\")\n const isMac = useIsMac()\n\n // Global keyboard shortcut handler\n React.useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n // ⌘K on Mac, Ctrl+K on Windows/Linux\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault()\n setOpen((prev) => !prev)\n }\n }\n\n document.addEventListener(\"keydown\", handleKeyDown)\n return () => document.removeEventListener(\"keydown\", handleKeyDown)\n }, [])\n\n // Handle selecting an endpoint\n const handleSelect = (url: string) => {\n onEndpointChange(url)\n setOpen(false)\n setCustomEndpoint(\"\")\n }\n\n // Handle custom endpoint submission\n const handleCustomSubmit = () => {\n if (customEndpoint.trim()) {\n handleSelect(customEndpoint.trim())\n }\n }\n\n // Format endpoint URL for display (show just the hostname)\n const formatEndpoint = (url: string) => {\n try {\n const parsed = new URL(url)\n return parsed.hostname\n } catch {\n return url\n }\n }\n\n return (\n <>\n {/* Trigger - search-like input */}\n <div className={className}>\n <div className=\"relative w-full\">\n <Search className=\"absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n type=\"text\"\n placeholder={placeholder}\n value={formatEndpoint(endpoint)}\n readOnly\n onClick={() => setOpen(true)}\n className=\"w-full cursor-pointer pl-9 pr-12 shadow-none\"\n />\n <kbd className=\"pointer-events-none absolute right-3 top-1/2 hidden -translate-y-1/2 select-none rounded-sm border border-border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground sm:inline-block\">\n {isMac ? \"⌘K\" : \"Ctrl+K\"}\n </kbd>\n </div>\n </div>\n\n {/* Command Dialog */}\n <CommandDialog\n open={open}\n onOpenChange={setOpen}\n title=\"Connect to DO\"\n description=\"Select a DO server endpoint to connect to\"\n >\n <CommandInput placeholder=\"Search endpoints or enter URL...\" />\n <CommandList>\n <CommandEmpty>\n <div className=\"flex flex-col gap-2 py-2\">\n <p className=\"text-muted-foreground\">No endpoints found</p>\n <p className=\"text-xs text-muted-foreground\">\n Enter a URL above to connect to a custom endpoint\n </p>\n </div>\n </CommandEmpty>\n\n {/* Current endpoint */}\n <CommandGroup heading=\"Current\">\n <CommandItem\n value={endpoint}\n onSelect={() => handleSelect(endpoint)}\n >\n <Server className=\"text-primary\" />\n <span className=\"flex-1 font-medium\">\n {formatEndpoint(endpoint)}\n </span>\n <span className=\"text-xs text-muted-foreground\">Connected</span>\n </CommandItem>\n </CommandGroup>\n\n {/* Recent endpoints */}\n {recentEndpoints.length > 0 && (\n <>\n <CommandSeparator />\n <CommandGroup heading=\"Recent\">\n {recentEndpoints\n .filter((url) => url !== endpoint)\n .map((url) => (\n <CommandItem\n key={url}\n value={url}\n onSelect={() => handleSelect(url)}\n >\n <History className=\"text-muted-foreground\" />\n <span className=\"flex-1\">{formatEndpoint(url)}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n </>\n )}\n\n {/* Custom endpoint entry */}\n <CommandSeparator />\n <CommandGroup heading=\"Custom\">\n <div className=\"flex items-center gap-2 px-2 py-1.5\">\n <Plus className=\"size-4 shrink-0 text-muted-foreground\" />\n <input\n type=\"text\"\n placeholder=\"Enter endpoint URL...\"\n value={customEndpoint}\n onChange={(e) => setCustomEndpoint(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault()\n handleCustomSubmit()\n }\n // Prevent cmdk from handling this\n e.stopPropagation()\n }}\n className=\"flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n />\n {customEndpoint && (\n <button\n type=\"button\"\n onClick={handleCustomSubmit}\n className=\"rounded-sm bg-primary px-2 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90\"\n >\n Connect\n </button>\n )}\n </div>\n </CommandGroup>\n </CommandList>\n </CommandDialog>\n </>\n )\n}\n","'use client'\n\n/**\n * Breadcrumbs Component\n *\n * Router-agnostic breadcrumbs that can work with any Link component.\n * Uses @mdxui/primitives breadcrumb components under the hood.\n */\n\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@mdxui/primitives'\nimport * as React from 'react'\n\n/**\n * Props for the Link component\n */\nexport interface BreadcrumbLinkProps {\n href: string\n children: React.ReactNode\n className?: string\n onClick?: () => void\n}\n\n/**\n * Single breadcrumb item configuration\n */\nexport interface BreadcrumbItemConfig {\n /** Display label */\n label: string\n /** Route path - last item should not have href */\n href?: string\n}\n\n/**\n * Props for the Breadcrumbs component\n */\nexport interface BreadcrumbsProps {\n /** Array of breadcrumb items */\n items: BreadcrumbItemConfig[]\n /** Custom link component (e.g., Next.js Link, TanStack Link) */\n LinkComponent?: React.ComponentType<BreadcrumbLinkProps>\n /** Additional class names */\n className?: string\n /** Maximum items to show before collapsing */\n maxItems?: number\n /** Custom separator element */\n separator?: React.ReactNode\n}\n\n/**\n * Default link component using a plain anchor tag\n */\nfunction DefaultLink({ href, children, className, onClick }: BreadcrumbLinkProps) {\n return (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n )\n}\n\n/**\n * Breadcrumbs provides navigation context showing the user's location.\n *\n * Features:\n * - Router-agnostic - works with any Link component\n * - Automatic collapse with dropdown for long paths\n * - Accessible breadcrumb semantics\n * - Custom separator support\n *\n * @example\n * ```tsx\n * // With default anchor tags\n * <Breadcrumbs\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Users', href: '/users' },\n * { label: 'John Doe' },\n * ]}\n * />\n *\n * // With TanStack Router Link\n * import { Link } from '@tanstack/react-router'\n *\n * <Breadcrumbs\n * items={breadcrumbItems}\n * LinkComponent={({ href, children, className }) => (\n * <Link to={href} className={className}>{children}</Link>\n * )}\n * />\n *\n * // With Next.js Link\n * import NextLink from 'next/link'\n *\n * <Breadcrumbs\n * items={breadcrumbItems}\n * LinkComponent={NextLink}\n * />\n * ```\n */\nexport function Breadcrumbs({\n items,\n LinkComponent = DefaultLink,\n className,\n maxItems = 4,\n separator,\n}: BreadcrumbsProps) {\n // Handle empty items\n if (!items || items.length === 0) {\n return null\n }\n\n // Determine if we need to collapse items\n const shouldCollapse = items.length > maxItems\n const visibleItems = shouldCollapse\n ? [items[0], ...items.slice(-(maxItems - 1))]\n : items\n const hiddenItems = shouldCollapse\n ? items.slice(1, -(maxItems - 1))\n : []\n\n return (\n <Breadcrumb className={className}>\n <BreadcrumbList>\n {visibleItems.map((item, index) => {\n const isLast = index === visibleItems.length - 1\n const isFirst = index === 0\n\n // Insert ellipsis after first item if collapsing\n if (shouldCollapse && isFirst) {\n return (\n <React.Fragment key={item.label}>\n <BreadcrumbItem>\n {item.href ? (\n <BreadcrumbLink asChild>\n <LinkComponent href={item.href}>{item.label}</LinkComponent>\n </BreadcrumbLink>\n ) : (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex items-center gap-1 hover:text-foreground\"\n aria-label=\"Show hidden breadcrumbs\"\n >\n <BreadcrumbEllipsis className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {hiddenItems.map((hiddenItem) => (\n <DropdownMenuItem key={hiddenItem.label} asChild>\n <LinkComponent href={hiddenItem.href || '#'}>\n {hiddenItem.label}\n </LinkComponent>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>\n </React.Fragment>\n )\n }\n\n return (\n <React.Fragment key={item.label}>\n <BreadcrumbItem>\n {isLast ? (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n ) : item.href ? (\n <BreadcrumbLink asChild>\n <LinkComponent href={item.href}>{item.label}</LinkComponent>\n </BreadcrumbLink>\n ) : (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n {!isLast && <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>}\n </React.Fragment>\n )\n })}\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n\nBreadcrumbs.displayName = 'Breadcrumbs'\n"]}
@@ -0,0 +1,56 @@
1
+ // src/lib/query-keys.ts
2
+ var thingsKeys = {
3
+ all: ["things"],
4
+ lists: () => [...thingsKeys.all, "list"],
5
+ list: (filter, sort, pagination) => [...thingsKeys.lists(), { filter, sort, pagination }],
6
+ details: () => [...thingsKeys.all, "detail"],
7
+ detail: (ns, type, id) => [...thingsKeys.details(), ns, type, id],
8
+ versions: (ns, type, id) => [...thingsKeys.detail(ns, type, id), "versions"],
9
+ types: () => [...thingsKeys.all, "types"],
10
+ typeStats: (ns, type) => [...thingsKeys.types(), ns, type]
11
+ };
12
+ var agentsKeys = {
13
+ all: ["agents"],
14
+ lists: () => [...agentsKeys.all, "list"],
15
+ list: (filter) => [...agentsKeys.lists(), filter],
16
+ details: () => [...agentsKeys.all, "detail"],
17
+ detail: (id) => [...agentsKeys.details(), id],
18
+ metrics: (id) => [...agentsKeys.detail(id), "metrics"],
19
+ executions: () => [...agentsKeys.all, "executions"],
20
+ executionsList: (filter) => [...agentsKeys.executions(), "list", filter],
21
+ execution: (id) => [...agentsKeys.executions(), "detail", id]
22
+ };
23
+ var workflowsKeys = {
24
+ all: ["workflows"],
25
+ lists: () => [...workflowsKeys.all, "list"],
26
+ list: (filter) => [...workflowsKeys.lists(), filter],
27
+ details: () => [...workflowsKeys.all, "detail"],
28
+ detail: (id) => [...workflowsKeys.details(), id],
29
+ executions: () => [...workflowsKeys.all, "executions"],
30
+ executionsList: (filter) => [...workflowsKeys.executions(), "list", filter],
31
+ execution: (id) => [...workflowsKeys.executions(), "detail", id]
32
+ };
33
+ var relationshipsKeys = {
34
+ all: ["relationships"],
35
+ lists: () => [...relationshipsKeys.all, "list"],
36
+ list: (filter) => [...relationshipsKeys.lists(), filter],
37
+ details: () => [...relationshipsKeys.all, "detail"],
38
+ detail: (id) => [...relationshipsKeys.details(), id],
39
+ graph: () => [...relationshipsKeys.all, "graph"],
40
+ traverse: (entity, pattern) => [...relationshipsKeys.graph(), entity, pattern],
41
+ stats: () => [...relationshipsKeys.all, "stats"]
42
+ };
43
+ function createQueryKeys(resource) {
44
+ const keys = {
45
+ all: [resource],
46
+ lists: () => [resource, "list"],
47
+ list: (filter) => [...keys.lists(), filter],
48
+ details: () => [resource, "detail"],
49
+ detail: (id) => [resource, "detail", id]
50
+ };
51
+ return keys;
52
+ }
53
+
54
+ export { agentsKeys, createQueryKeys, relationshipsKeys, thingsKeys, workflowsKeys };
55
+ //# sourceMappingURL=chunk-4KXVN3EQ.js.map
56
+ //# sourceMappingURL=chunk-4KXVN3EQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/query-keys.ts"],"names":[],"mappings":"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","file":"chunk-4KXVN3EQ.js","sourcesContent":["/**\n * Query Key Factory Pattern\n *\n * Provides a generic factory for creating type-safe TanStack Query keys.\n * Eliminates copy-paste duplication across hook files while maintaining\n * consistent cache invalidation patterns.\n *\n * @example\n * ```typescript\n * // Create typed keys for a resource\n * export const agentsKeys = createQueryKeys<AgentFilter>('agents')\n *\n * // Usage in hooks\n * const queryKey = agentsKeys.list({ status: ['active'] })\n * queryClient.invalidateQueries({ queryKey: agentsKeys.all })\n * ```\n */\n\nimport type {\n ThingFilter,\n ThingSort,\n ThingPagination,\n AgentFilter,\n AgentExecutionFilter,\n WorkflowFilter,\n ExecutionFilter,\n RelationshipFilter,\n EntityReference,\n GraphPattern,\n} from '../types'\n\n/**\n * Generic pagination parameters for list queries\n */\nexport interface Pagination {\n page?: number\n perPage?: number\n cursor?: string\n}\n\n// ============================================================================\n// Pre-defined keys for known resources\n// ============================================================================\n\n/**\n * Query keys for Things resource\n *\n * Things have a special key structure because:\n * - List queries include filter, sort, and pagination\n * - Detail queries use composite keys (ns, type, id) instead of a single id\n * - Additional sub-queries for versions and type stats\n */\nexport const thingsKeys = {\n all: ['things'] as const,\n lists: () => [...thingsKeys.all, 'list'] as const,\n list: (filter: ThingFilter, sort?: ThingSort, pagination?: ThingPagination) =>\n [...thingsKeys.lists(), { filter, sort, pagination }] as const,\n details: () => [...thingsKeys.all, 'detail'] as const,\n detail: (ns: string, type: string, id: string) => [...thingsKeys.details(), ns, type, id] as const,\n versions: (ns: string, type: string, id: string) =>\n [...thingsKeys.detail(ns, type, id), 'versions'] as const,\n types: () => [...thingsKeys.all, 'types'] as const,\n typeStats: (ns: string, type: string) => [...thingsKeys.types(), ns, type] as const,\n}\n\n/**\n * Query keys for Agents resource\n *\n * Includes keys for:\n * - Agent lists and details\n * - Agent metrics (per-agent)\n * - Agent executions (list and detail)\n */\nexport const agentsKeys = {\n all: ['agents'] as const,\n lists: () => [...agentsKeys.all, 'list'] as const,\n list: (filter: AgentFilter) => [...agentsKeys.lists(), filter] as const,\n details: () => [...agentsKeys.all, 'detail'] as const,\n detail: (id: string) => [...agentsKeys.details(), id] as const,\n metrics: (id: string) => [...agentsKeys.detail(id), 'metrics'] as const,\n executions: () => [...agentsKeys.all, 'executions'] as const,\n executionsList: (filter: AgentExecutionFilter) => [...agentsKeys.executions(), 'list', filter] as const,\n execution: (id: string) => [...agentsKeys.executions(), 'detail', id] as const,\n}\n\n/**\n * Query keys for Workflows resource\n *\n * Includes keys for:\n * - Workflow lists and details\n * - Workflow executions (list and detail)\n */\nexport const workflowsKeys = {\n all: ['workflows'] as const,\n lists: () => [...workflowsKeys.all, 'list'] as const,\n list: (filter: WorkflowFilter) => [...workflowsKeys.lists(), filter] as const,\n details: () => [...workflowsKeys.all, 'detail'] as const,\n detail: (id: string) => [...workflowsKeys.details(), id] as const,\n executions: () => [...workflowsKeys.all, 'executions'] as const,\n executionsList: (filter: ExecutionFilter) => [...workflowsKeys.executions(), 'list', filter] as const,\n execution: (id: string) => [...workflowsKeys.executions(), 'detail', id] as const,\n}\n\n/**\n * Query keys for Relationships resource\n *\n * Includes keys for:\n * - Relationship lists and details\n * - Graph traversal queries\n * - Graph statistics\n */\nexport const relationshipsKeys = {\n all: ['relationships'] as const,\n lists: () => [...relationshipsKeys.all, 'list'] as const,\n list: (filter: RelationshipFilter) => [...relationshipsKeys.lists(), filter] as const,\n details: () => [...relationshipsKeys.all, 'detail'] as const,\n detail: (id: string) => [...relationshipsKeys.details(), id] as const,\n graph: () => [...relationshipsKeys.all, 'graph'] as const,\n traverse: (entity: EntityReference, pattern: GraphPattern) =>\n [...relationshipsKeys.graph(), entity, pattern] as const,\n stats: () => [...relationshipsKeys.all, 'stats'] as const,\n}\n\n// ============================================================================\n// Generic Factory Functions (for custom resources)\n// ============================================================================\n\n/**\n * Base query keys structure that all resources share\n */\nexport interface QueryKeys<TFilter = unknown> {\n /** Root key for all queries of this resource */\n all: readonly [string]\n /** Key for all list queries */\n lists: () => readonly [string, 'list']\n /** Key for a specific list query with filter */\n list: (filter: TFilter) => readonly unknown[]\n /** Key for all detail queries */\n details: () => readonly [string, 'detail']\n /** Key for a specific detail query */\n detail: (id: string) => readonly [string, 'detail', string]\n}\n\n/**\n * Create a basic query key factory for a resource\n *\n * @param resource - The resource name (e.g., 'agents', 'workflows')\n * @returns Query key factory with type-safe keys\n *\n * @example\n * ```typescript\n * const customKeys = createQueryKeys<CustomFilter>('custom')\n *\n * // All queries\n * customKeys.all // ['custom']\n *\n * // List queries\n * customKeys.lists() // ['custom', 'list']\n * customKeys.list({ status: 'active' }) // ['custom', 'list', { status: 'active' }]\n *\n * // Detail queries\n * customKeys.details() // ['custom', 'detail']\n * customKeys.detail('item-1') // ['custom', 'detail', 'item-1']\n * ```\n */\nexport function createQueryKeys<TFilter = unknown>(resource: string): QueryKeys<TFilter> {\n const keys: QueryKeys<TFilter> = {\n all: [resource] as const,\n lists: () => [resource, 'list'] as const,\n list: (filter: TFilter) => [...keys.lists(), filter] as const,\n details: () => [resource, 'detail'] as const,\n detail: (id: string) => [resource, 'detail', id] as const,\n }\n return keys\n}\n"]}