nexus-shell 0.2.0 → 0.2.1

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.
@@ -1,33 +1,33 @@
1
1
  var Ee = Object.defineProperty;
2
- var De = (o, e, n) => e in o ? Ee(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
3
- var J = (o, e, n) => De(o, typeof e != "symbol" ? e + "" : e, n);
4
- import { jsxs as c, jsx as t, Fragment as fe } from "react/jsx-runtime";
5
- import { Settings as Ie, MessageCircle as pe, X as _, User as ge, Terminal as he, Send as Oe, Search as X, Loader2 as be, ChevronsUpDown as ze, ChevronUp as xe, ChevronDown as ve, ChevronRight as ye, Info as Le, HelpCircle as Ae, AlertCircle as Pe, Clock as Me, Sun as Ke, Moon as $e, GraduationCap as Re, Plus as je, FolderPlus as Fe, Edit as Ue, Trash2 as _e, Folder as Je, File as He, Check as We, Camera as Be, Edit2 as Ge } from "lucide-react";
6
- import { clsx as Ye } from "clsx";
7
- import { twMerge as qe } from "tailwind-merge";
8
- import oe, { useState as O, useRef as M, useEffect as z, useMemo as j } from "react";
9
- import { TableVirtuoso as Ve, Virtuoso as Qe } from "react-virtuoso";
10
- import { Model as $, Actions as B, DockLocation as Xe, Layout as Ze } from "flexlayout-react";
2
+ var Ie = (o, e, n) => e in o ? Ee(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
3
+ var H = (o, e, n) => Ie(o, typeof e != "symbol" ? e + "" : e, n);
4
+ import { jsxs as c, jsx as r, Fragment as he } from "react/jsx-runtime";
5
+ import se, { useMemo as R, useState as A, useRef as P, useEffect as z } from "react";
6
+ import { Model as $, Actions as G, DockLocation as Oe, Layout as ze } from "flexlayout-react";
11
7
  import "flexlayout-react/style/light.css";
12
- import { create as F } from "zustand";
8
+ import { Settings as Ae, MessageCircle as be, X as J, User as xe, Terminal as ve, Send as Le, ChevronRight as ye, Sun as Me, Moon as Pe, GraduationCap as Ke, ChevronUp as we, Search as X, Info as $e, HelpCircle as je, AlertCircle as Re, Check as Fe, Camera as Ue, Edit2 as _e, Loader2 as Ne, ChevronsUpDown as Je, ChevronDown as ke, Clock as He, Plus as We, FolderPlus as Be, Edit as Ge, Trash2 as Ve, Folder as Ye, File as qe } from "lucide-react";
9
+ import { clsx as Qe } from "clsx";
10
+ import { twMerge as Xe } from "tailwind-merge";
11
+ import { create as U } from "zustand";
12
+ import { TableVirtuoso as Ze, Virtuoso as et } from "react-virtuoso";
13
13
  function S(...o) {
14
- return qe(Ye(o));
14
+ return Xe(Qe(o));
15
15
  }
16
- const et = [
17
- { id: "settings", label: "Settings", icon: Ie }
18
- ], tt = ({
16
+ const tt = [
17
+ { id: "settings", label: "Settings", icon: Ae }
18
+ ], rt = ({
19
19
  items: o = [],
20
- bottomItems: e = et,
20
+ bottomItems: e = tt,
21
21
  activeId: n = null,
22
- onSelect: r,
22
+ onSelect: t,
23
23
  className: a,
24
24
  "aria-label": s = "Activity Bar"
25
25
  }) => {
26
- const l = ({ id: u, label: i, icon: d }) => /* @__PURE__ */ t(
26
+ const l = ({ id: u, label: i, icon: d }) => /* @__PURE__ */ r(
27
27
  "button",
28
28
  {
29
29
  type: "button",
30
- onClick: () => r == null ? void 0 : r(u),
30
+ onClick: () => t == null ? void 0 : t(u),
31
31
  "aria-label": i,
32
32
  title: i,
33
33
  "aria-pressed": n === u,
@@ -35,7 +35,7 @@ const et = [
35
35
  "p-2 cursor-pointer rounded text-muted-foreground hover:text-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
36
36
  n === u && "text-foreground border-l-2 border-primary rounded-none"
37
37
  ),
38
- children: /* @__PURE__ */ t(d, { size: 20 })
38
+ children: /* @__PURE__ */ r(d, { size: 20 })
39
39
  },
40
40
  u
41
41
  );
@@ -49,32 +49,60 @@ const et = [
49
49
  a
50
50
  ),
51
51
  children: [
52
- /* @__PURE__ */ t("div", { className: "flex-1 flex flex-col space-y-4", children: o.map(l) }),
53
- e.length > 0 && /* @__PURE__ */ t("div", { className: "flex flex-col space-y-4", children: e.map(l) })
52
+ /* @__PURE__ */ r("div", { className: "flex-1 flex flex-col space-y-4", children: o.map(l) }),
53
+ e.length > 0 && /* @__PURE__ */ r("div", { className: "flex flex-col space-y-4", children: e.map(l) })
54
54
  ]
55
55
  }
56
56
  );
57
- }, rt = /* @__PURE__ */ c("div", { className: "h-full flex flex-col items-center justify-center text-center px-6 text-muted-foreground", children: [
58
- /* @__PURE__ */ t(pe, { size: 28, className: "mb-3 opacity-40" }),
59
- /* @__PURE__ */ t("p", { className: "text-xs", children: "No messages yet." }),
57
+ }, q = "nexus-shell-sidebar", F = U((o) => {
58
+ const e = localStorage.getItem(q);
59
+ return {
60
+ activeSidebar: e !== null ? e : null,
61
+ panels: [],
62
+ setActiveSidebar: (t) => {
63
+ t === null ? localStorage.removeItem(q) : localStorage.setItem(q, t), o({ activeSidebar: t });
64
+ },
65
+ toggleSidebar: (t) => o((a) => {
66
+ const s = a.activeSidebar === t ? null : t;
67
+ return s === null ? localStorage.removeItem(q) : localStorage.setItem(q, s), { activeSidebar: s };
68
+ }),
69
+ setPanels: (t) => o({ panels: t })
70
+ };
71
+ }), nt = (o) => {
72
+ const e = F((s) => s.panels), n = F((s) => s.activeSidebar), t = F((s) => s.toggleSidebar), a = R(
73
+ () => e.map(({ id: s, label: l, icon: u }) => ({ id: s, label: l, icon: u })),
74
+ [e]
75
+ );
76
+ return /* @__PURE__ */ r(
77
+ rt,
78
+ {
79
+ ...o,
80
+ items: a,
81
+ activeId: n,
82
+ onSelect: t
83
+ }
84
+ );
85
+ }, ot = /* @__PURE__ */ c("div", { className: "h-full flex flex-col items-center justify-center text-center px-6 text-muted-foreground", children: [
86
+ /* @__PURE__ */ r(be, { size: 28, className: "mb-3 opacity-40" }),
87
+ /* @__PURE__ */ r("p", { className: "text-xs", children: "No messages yet." }),
60
88
  /* @__PURE__ */ c("p", { className: "text-[11px] mt-1 opacity-70", children: [
61
89
  "Type a message, or ",
62
- /* @__PURE__ */ t("span", { className: "font-mono", children: "/" }),
90
+ /* @__PURE__ */ r("span", { className: "font-mono", children: "/" }),
63
91
  " for commands."
64
92
  ] })
65
- ] }), nt = ({
93
+ ] }), st = ({
66
94
  messages: o = [],
67
95
  onSend: e,
68
96
  slashCommands: n = [],
69
- onSlashCommand: r,
97
+ onSlashCommand: t,
70
98
  onClose: a,
71
99
  title: s = "Chat",
72
100
  placeholder: l = "Send a message…",
73
- emptyState: u = rt,
101
+ emptyState: u = ot,
74
102
  className: i
75
103
  }) => {
76
- const [d, p] = O(""), [g, m] = O(0), w = M(null), C = M(null), x = d.startsWith("/") ? n.filter(
77
- (v) => `/${v.command}`.startsWith(d.toLowerCase().split(" ")[0])
104
+ const [d, f] = A(""), [p, m] = A(0), k = P(null), C = P(null), x = d.startsWith("/") ? n.filter(
105
+ (y) => `/${y.command}`.startsWith(d.toLowerCase().split(" ")[0])
78
106
  ) : [], h = x.length > 0;
79
107
  z(() => {
80
108
  C.current && (C.current.scrollTop = C.current.scrollHeight);
@@ -82,27 +110,27 @@ const et = [
82
110
  m(0);
83
111
  }, [d]);
84
112
  const T = () => {
85
- const v = d.trim();
86
- v && (e == null || e(v), p(""));
87
- }, N = (v) => {
88
- var f;
89
- r == null || r(v), p(`/${v.command} `), (f = w.current) == null || f.focus();
90
- }, b = (v) => {
113
+ const y = d.trim();
114
+ y && (e == null || e(y), f(""));
115
+ }, I = (y) => {
116
+ var g;
117
+ t == null || t(y), f(`/${y.command} `), (g = k.current) == null || g.focus();
118
+ }, N = (y) => {
91
119
  if (h) {
92
- if (v.key === "ArrowDown") {
93
- v.preventDefault(), m((f) => (f + 1) % x.length);
120
+ if (y.key === "ArrowDown") {
121
+ y.preventDefault(), m((g) => (g + 1) % x.length);
94
122
  return;
95
123
  }
96
- if (v.key === "ArrowUp") {
97
- v.preventDefault(), m((f) => (f - 1 + x.length) % x.length);
124
+ if (y.key === "ArrowUp") {
125
+ y.preventDefault(), m((g) => (g - 1 + x.length) % x.length);
98
126
  return;
99
127
  }
100
- if (v.key === "Tab" || v.key === "Enter" && !v.shiftKey) {
101
- v.preventDefault(), N(x[g]);
128
+ if (y.key === "Tab" || y.key === "Enter" && !y.shiftKey) {
129
+ y.preventDefault(), I(x[p]);
102
130
  return;
103
131
  }
104
132
  }
105
- v.key === "Enter" && !v.shiftKey && (v.preventDefault(), T());
133
+ y.key === "Enter" && !y.shiftKey && (y.preventDefault(), T());
106
134
  };
107
135
  return /* @__PURE__ */ c(
108
136
  "aside",
@@ -116,100 +144,100 @@ const et = [
116
144
  children: [
117
145
  /* @__PURE__ */ c("div", { className: "h-10 flex items-center justify-between px-4 shrink-0", children: [
118
146
  /* @__PURE__ */ c("div", { className: "flex items-center space-x-2 text-muted-foreground", children: [
119
- /* @__PURE__ */ t(pe, { size: 13 }),
120
- /* @__PURE__ */ t("span", { className: "text-[11px] font-bold uppercase tracking-widest", children: s })
147
+ /* @__PURE__ */ r(be, { size: 13 }),
148
+ /* @__PURE__ */ r("span", { className: "text-[11px] font-bold uppercase tracking-widest", children: s })
121
149
  ] }),
122
- a && /* @__PURE__ */ t(
150
+ a && /* @__PURE__ */ r(
123
151
  "button",
124
152
  {
125
153
  type: "button",
126
154
  onClick: a,
127
155
  "aria-label": "Close Chat",
128
156
  className: "p-1 rounded hover:bg-accent hover:text-foreground text-muted-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
129
- children: /* @__PURE__ */ t(_, { size: 14 })
157
+ children: /* @__PURE__ */ r(J, { size: 14 })
130
158
  }
131
159
  )
132
160
  ] }),
133
- /* @__PURE__ */ t(
161
+ /* @__PURE__ */ r(
134
162
  "div",
135
163
  {
136
164
  ref: C,
137
165
  role: "log",
138
166
  "aria-label": `${s} transcript`,
139
167
  className: "flex-1 overflow-y-auto border-t border-border/50 bg-background/50 px-3 py-3 space-y-3",
140
- children: o.length === 0 ? u : o.map((v) => {
141
- const f = v.role === "user";
168
+ children: o.length === 0 ? u : o.map((y) => {
169
+ const g = y.role === "user";
142
170
  return /* @__PURE__ */ c(
143
171
  "div",
144
172
  {
145
- className: S("flex flex-col", f ? "items-end" : "items-start"),
173
+ className: S("flex flex-col", g ? "items-end" : "items-start"),
146
174
  children: [
147
175
  /* @__PURE__ */ c("div", { className: "flex items-center space-x-1 mb-1 text-[10px] uppercase tracking-wider text-muted-foreground font-bold", children: [
148
- f ? /* @__PURE__ */ t(ge, { size: 10 }) : /* @__PURE__ */ t(he, { size: 10 }),
149
- /* @__PURE__ */ t("span", { children: v.author ?? (f ? "You" : "Assistant") })
176
+ g ? /* @__PURE__ */ r(xe, { size: 10 }) : /* @__PURE__ */ r(ve, { size: 10 }),
177
+ /* @__PURE__ */ r("span", { children: y.author ?? (g ? "You" : "Assistant") })
150
178
  ] }),
151
- /* @__PURE__ */ t(
179
+ /* @__PURE__ */ r(
152
180
  "div",
153
181
  {
154
182
  className: S(
155
183
  "max-w-[85%] rounded-lg px-3 py-2 text-xs whitespace-pre-wrap break-words",
156
- f ? "bg-primary text-primary-foreground" : "bg-card border border-border text-foreground"
184
+ g ? "bg-primary text-primary-foreground" : "bg-card border border-border text-foreground"
157
185
  ),
158
- children: v.text
186
+ children: y.text
159
187
  }
160
188
  )
161
189
  ]
162
190
  },
163
- v.id
191
+ y.id
164
192
  );
165
193
  })
166
194
  }
167
195
  ),
168
196
  /* @__PURE__ */ c("div", { className: "relative border-t border-border/50 p-2 shrink-0", children: [
169
- h && /* @__PURE__ */ t(
197
+ h && /* @__PURE__ */ r(
170
198
  "div",
171
199
  {
172
200
  role: "listbox",
173
201
  "aria-label": "Slash commands",
174
202
  className: "absolute bottom-full left-2 right-2 mb-1 bg-popover border border-border rounded-md shadow-lg overflow-hidden z-20",
175
- children: x.map((v, f) => /* @__PURE__ */ c(
203
+ children: x.map((y, g) => /* @__PURE__ */ c(
176
204
  "div",
177
205
  {
178
206
  role: "option",
179
- "aria-selected": f === g,
180
- onMouseEnter: () => m(f),
181
- onClick: () => N(v),
207
+ "aria-selected": g === p,
208
+ onMouseEnter: () => m(g),
209
+ onClick: () => I(y),
182
210
  className: S(
183
211
  "px-3 py-1.5 text-xs cursor-pointer flex items-baseline justify-between gap-3",
184
- f === g ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
212
+ g === p ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
185
213
  ),
186
214
  children: [
187
215
  /* @__PURE__ */ c("span", { className: "font-mono", children: [
188
216
  "/",
189
- v.command
217
+ y.command
190
218
  ] }),
191
- /* @__PURE__ */ t("span", { className: "text-[10px] text-muted-foreground truncate", children: v.description })
219
+ /* @__PURE__ */ r("span", { className: "text-[10px] text-muted-foreground truncate", children: y.description })
192
220
  ]
193
221
  },
194
- v.command
222
+ y.command
195
223
  ))
196
224
  }
197
225
  ),
198
226
  /* @__PURE__ */ c("div", { className: "flex items-end space-x-2", children: [
199
- /* @__PURE__ */ t(
227
+ /* @__PURE__ */ r(
200
228
  "textarea",
201
229
  {
202
- ref: w,
230
+ ref: k,
203
231
  rows: 1,
204
232
  value: d,
205
233
  "aria-label": `${s} message`,
206
234
  placeholder: l,
207
- onChange: (v) => p(v.target.value),
208
- onKeyDown: b,
235
+ onChange: (y) => f(y.target.value),
236
+ onKeyDown: N,
209
237
  className: "flex-1 resize-none bg-background border border-border rounded-md px-3 py-2 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 max-h-32"
210
238
  }
211
239
  ),
212
- /* @__PURE__ */ t(
240
+ /* @__PURE__ */ r(
213
241
  "button",
214
242
  {
215
243
  type: "button",
@@ -217,7 +245,7 @@ const et = [
217
245
  disabled: !d.trim(),
218
246
  "aria-label": "Send message",
219
247
  className: "p-2 rounded-md bg-primary text-primary-foreground disabled:opacity-40 disabled:cursor-not-allowed hover:bg-primary/90 transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
220
- children: /* @__PURE__ */ t(Oe, { size: 14 })
248
+ children: /* @__PURE__ */ r(Le, { size: 14 })
221
249
  }
222
250
  )
223
251
  ] })
@@ -225,443 +253,131 @@ const et = [
225
253
  ]
226
254
  }
227
255
  );
228
- }, ot = (o, e) => {
229
- const n = e.toLowerCase();
230
- return o.label.toLowerCase().includes(n) || o.id.toLowerCase().includes(n);
231
- }, st = ({
232
- open: o,
233
- commands: e,
234
- onSelect: n,
235
- onClose: r,
236
- inline: a = !1,
237
- placeholder: s = "Type a command to run…",
238
- filter: l = ot,
239
- className: u
240
- }) => {
241
- const [i, d] = O(""), [p, g] = O(0), m = M(null), w = j(
242
- () => e.filter((x) => l(x, i)),
243
- [e, i, l]
244
- );
245
- if (z(() => {
246
- var x;
247
- o && (d(""), g(0), (x = m.current) == null || x.focus());
248
- }, [o]), z(() => {
249
- g(0);
250
- }, [i]), !o) return null;
251
- const C = (x) => {
252
- x.key === "ArrowDown" ? (x.preventDefault(), g((h) => w.length ? (h + 1) % w.length : 0)) : x.key === "ArrowUp" ? (x.preventDefault(), g(
253
- (h) => w.length ? (h - 1 + w.length) % w.length : 0
254
- )) : x.key === "Enter" ? (x.preventDefault(), w[p] && n(w[p])) : x.key === "Escape" && (x.preventDefault(), r == null || r());
255
- };
256
- return /* @__PURE__ */ t(
257
- "div",
256
+ };
257
+ let at = 0;
258
+ const lt = () => `msg-${Date.now()}-${at += 1}`, Q = U((o) => ({
259
+ messages: [],
260
+ slashCommands: [],
261
+ setMessages: (e) => o({ messages: e }),
262
+ addMessage: (e) => o((n) => ({
263
+ messages: [...n.messages, { ...e, id: e.id ?? lt() }]
264
+ })),
265
+ clearMessages: () => o({ messages: [] }),
266
+ setSlashCommands: (e) => o({ slashCommands: e }),
267
+ registerSlashCommand: (e) => o((n) => ({ slashCommands: [...n.slashCommands, e] }))
268
+ })), te = "nexus-shell-right-sidebar", ae = U((o) => ({
269
+ isChatOpen: localStorage.getItem(te) === "true",
270
+ setChatOpen: (t) => {
271
+ localStorage.setItem(te, String(t)), o({ isChatOpen: t });
272
+ },
273
+ toggleChat: () => o((t) => {
274
+ const a = !t.isChatOpen;
275
+ return localStorage.setItem(te, String(a)), { isChatOpen: a };
276
+ })
277
+ })), it = ({ onSend: o, ...e }) => {
278
+ const n = ae((i) => i.isChatOpen), t = ae((i) => i.setChatOpen), a = Q((i) => i.messages), s = Q((i) => i.slashCommands), l = Q((i) => i.addMessage);
279
+ return n ? /* @__PURE__ */ r(
280
+ st,
258
281
  {
259
- onClick: a ? void 0 : r,
260
- className: S(
261
- "z-[100] flex items-start justify-center",
262
- a ? "relative w-full max-w-xl" : "fixed inset-0 pt-[10vh] bg-black/50 backdrop-blur-sm"
263
- ),
264
- children: /* @__PURE__ */ c(
265
- "div",
266
- {
267
- role: "dialog",
268
- "aria-modal": !a,
269
- "aria-label": "Command Palette",
270
- onClick: (x) => x.stopPropagation(),
271
- className: S(
272
- "w-full max-w-xl bg-popover text-popover-foreground border shadow-2xl rounded-xl overflow-hidden animate-in fade-in zoom-in duration-200",
273
- u
274
- ),
275
- children: [
276
- /* @__PURE__ */ c("div", { className: "flex items-center px-4 border-b", children: [
277
- /* @__PURE__ */ t(X, { size: 18, className: "text-muted-foreground mr-3" }),
278
- /* @__PURE__ */ t(
279
- "input",
280
- {
281
- ref: m,
282
- type: "text",
283
- role: "combobox",
284
- "aria-expanded": !0,
285
- "aria-controls": "command-palette-list",
286
- "aria-label": "Command",
287
- placeholder: s,
288
- value: i,
289
- onChange: (x) => d(x.target.value),
290
- onKeyDown: C,
291
- className: "flex-1 h-14 bg-transparent outline-none text-base text-foreground placeholder:text-muted-foreground"
292
- }
293
- )
294
- ] }),
295
- /* @__PURE__ */ t(
296
- "div",
297
- {
298
- id: "command-palette-list",
299
- role: "listbox",
300
- className: "max-h-[300px] overflow-y-auto py-2",
301
- children: w.length === 0 ? /* @__PURE__ */ t("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: i ? `No commands found matching "${i}"` : "No commands available." }) : w.map((x, h) => /* @__PURE__ */ c(
302
- "div",
303
- {
304
- role: "option",
305
- "aria-selected": h === p,
306
- onClick: () => n(x),
307
- onMouseEnter: () => g(h),
308
- className: S(
309
- "px-4 py-2 cursor-pointer flex justify-between items-center text-sm",
310
- h === p ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
311
- ),
312
- children: [
313
- /* @__PURE__ */ t("span", { children: x.label }),
314
- x.keybinding && /* @__PURE__ */ t("span", { className: "text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded border border-border/50", children: x.keybinding })
315
- ]
316
- },
317
- x.id
318
- ))
319
- }
320
- ),
321
- /* @__PURE__ */ c("div", { className: "px-4 py-2 border-t bg-muted/30 flex justify-between items-center text-[10px] text-muted-foreground", children: [
322
- /* @__PURE__ */ c("div", { className: "flex gap-3", children: [
323
- /* @__PURE__ */ c("span", { children: [
324
- /* @__PURE__ */ t("kbd", { className: "bg-muted px-1 rounded border", children: "↑↓" }),
325
- " to navigate"
326
- ] }),
327
- /* @__PURE__ */ c("span", { children: [
328
- /* @__PURE__ */ t("kbd", { className: "bg-muted px-1 rounded border", children: "Enter" }),
329
- " to select"
330
- ] })
331
- ] }),
332
- /* @__PURE__ */ c("span", { children: [
333
- /* @__PURE__ */ t("kbd", { className: "bg-muted px-1 rounded border", children: "Esc" }),
334
- " to close"
335
- ] })
336
- ] })
337
- ]
282
+ ...e,
283
+ messages: a,
284
+ slashCommands: s,
285
+ onSend: (i) => {
286
+ if (l({ role: "user", text: i }), i.startsWith("/")) {
287
+ const [d, ...f] = i.slice(1).split(/\s+/), p = s.find((m) => m.command === d);
288
+ if (p) {
289
+ p.execute(f);
290
+ return;
291
+ }
292
+ l({ role: "assistant", text: `Unknown command: /${d}` });
293
+ return;
338
294
  }
339
- )
295
+ o == null || o(i);
296
+ },
297
+ onClose: () => t(!1)
340
298
  }
341
- );
342
- }, at = ({ x: o, y: e, items: n, onClose: r, className: a }) => {
343
- const s = M(null);
344
- return z(() => {
345
- const l = (i) => {
346
- s.current && !s.current.contains(i.target) && r();
347
- }, u = (i) => {
348
- i.key === "Escape" && r();
349
- };
350
- return document.addEventListener("mousedown", l), document.addEventListener("keydown", u), () => {
351
- document.removeEventListener("mousedown", l), document.removeEventListener("keydown", u);
352
- };
353
- }, [r]), /* @__PURE__ */ t(
299
+ ) : null;
300
+ }, dt = ({
301
+ menus: o = {},
302
+ onSelect: e,
303
+ title: n,
304
+ center: t,
305
+ right: a,
306
+ className: s
307
+ }) => {
308
+ const l = (i) => i.keybinding ? /* @__PURE__ */ r("span", { className: "text-[10px] text-muted-foreground opacity-60 ml-4", children: i.keybinding }) : null, u = (i) => /* @__PURE__ */ r(
354
309
  "div",
355
310
  {
356
- ref: s,
357
311
  role: "menu",
358
- style: { top: e, left: o },
359
- className: S(
360
- "fixed z-[1000] min-w-[160px] bg-popover text-popover-foreground border shadow-md rounded-md py-1 animate-in fade-in zoom-in-95 duration-100",
361
- a
362
- ),
363
- children: n.map((l, u) => /* @__PURE__ */ c(oe.Fragment, { children: [
364
- l.divider && /* @__PURE__ */ t("div", { className: "h-[1px] bg-border my-1" }),
312
+ className: "absolute left-0 top-full hidden group-hover:block z-50 min-w-[180px] bg-popover text-popover-foreground border shadow-md rounded-md py-1",
313
+ children: i.map((d) => /* @__PURE__ */ c("div", { className: "relative group/sub", children: [
365
314
  /* @__PURE__ */ c(
366
315
  "div",
367
316
  {
368
317
  role: "menuitem",
369
- tabIndex: l.disabled ? void 0 : 0,
370
- "aria-disabled": l.disabled,
371
- onClick: () => {
372
- l.disabled || (l.onClick(), r());
373
- },
374
- onKeyDown: (i) => {
375
- l.disabled || i.key !== "Enter" && i.key !== " " || (i.preventDefault(), l.onClick(), r());
318
+ tabIndex: 0,
319
+ onClick: () => !d.submenu && (e == null ? void 0 : e(d)),
320
+ onKeyDown: (f) => {
321
+ !d.submenu && (f.key === "Enter" || f.key === " ") && (f.preventDefault(), e == null || e(d));
376
322
  },
377
- className: S(
378
- "px-3 py-1.5 text-xs flex items-center focus:outline-none",
379
- l.disabled ? "opacity-40 cursor-default" : "cursor-pointer hover:bg-accent hover:text-accent-foreground focus:bg-accent"
380
- ),
323
+ className: "px-3 py-1.5 hover:bg-accent hover:text-accent-foreground cursor-pointer text-xs flex justify-between items-center focus:outline-none focus:bg-accent",
381
324
  children: [
382
- l.icon && /* @__PURE__ */ t("span", { className: "mr-2 opacity-70", children: l.icon }),
383
- /* @__PURE__ */ t("span", { children: l.label })
325
+ /* @__PURE__ */ r("span", { children: d.label }),
326
+ /* @__PURE__ */ c("div", { className: "flex items-center space-x-2", children: [
327
+ l(d),
328
+ d.submenu && /* @__PURE__ */ r(ye, { size: 10 })
329
+ ] })
384
330
  ]
385
331
  }
332
+ ),
333
+ d.submenu && /* @__PURE__ */ r(
334
+ "div",
335
+ {
336
+ role: "menu",
337
+ className: "absolute left-full top-0 hidden group-hover/sub:block z-[60] min-w-[180px] bg-popover text-popover-foreground border shadow-md rounded-md py-1 ml-[-2px]",
338
+ children: d.submenu.map((f) => /* @__PURE__ */ c(
339
+ "div",
340
+ {
341
+ role: "menuitem",
342
+ tabIndex: 0,
343
+ onClick: () => e == null ? void 0 : e(f),
344
+ onKeyDown: (p) => {
345
+ (p.key === "Enter" || p.key === " ") && (p.preventDefault(), e == null || e(f));
346
+ },
347
+ className: "px-3 py-1.5 hover:bg-accent hover:text-accent-foreground cursor-pointer text-xs flex justify-between items-center focus:outline-none focus:bg-accent",
348
+ children: [
349
+ /* @__PURE__ */ r("span", { children: f.label }),
350
+ l(f)
351
+ ]
352
+ },
353
+ f.id
354
+ ))
355
+ }
386
356
  )
387
- ] }, `${l.label}-${u}`))
357
+ ] }, d.id))
388
358
  }
389
359
  );
390
- }, Ht = ({
391
- columns: o,
392
- data: e,
393
- onRowClick: n,
394
- selectedRowId: r,
395
- rowKey: a = "id",
396
- virtualized: s = !0,
397
- showFilter: l = !0,
398
- loading: u = !1,
399
- placeholder: i = "No data available",
400
- className: d
401
- }) => {
402
- const [p, g] = O(""), [m, w] = O(null), [C, x] = O(-1), h = M(null);
403
- z(() => {
404
- x(-1);
405
- }, [p, m]);
406
- const T = j(() => {
407
- if (!p) return e;
408
- const y = p.toLowerCase();
409
- return e.filter((D) => Object.values(D).some((I) => I == null ? !1 : String(I).toLowerCase().includes(y)));
410
- }, [e, p]), N = j(() => {
411
- if (!m) return T;
412
- const { key: y, direction: D } = m;
413
- return [...T].sort((I, R) => {
414
- const K = I[y], P = R[y];
415
- if (K === P) return 0;
416
- if (K == null) return 1;
417
- if (P == null) return -1;
418
- const Z = Number(K), ee = Number(P);
419
- if (!isNaN(Z) && !isNaN(ee))
420
- return D === "asc" ? Z - ee : ee - Z;
421
- const se = String(K).toLowerCase(), ae = String(P).toLowerCase();
422
- return D === "asc" ? se.localeCompare(ae) : ae.localeCompare(se);
423
- });
424
- }, [T, m]), b = (y, D) => {
425
- D !== !1 && w((I) => !I || I.key !== y ? { key: y, direction: "asc" } : I.direction === "asc" ? { key: y, direction: "desc" } : null);
426
- }, v = (y) => {
427
- if (!(N.length === 0 || u)) {
428
- if (y.key === "ArrowDown")
429
- y.preventDefault(), x((D) => {
430
- const I = D + 1;
431
- return I >= N.length ? 0 : I;
432
- });
433
- else if (y.key === "ArrowUp")
434
- y.preventDefault(), x((D) => {
435
- const I = D - 1;
436
- return I < 0 ? N.length - 1 : I;
437
- });
438
- else if ((y.key === "Enter" || y.key === " ") && (y.preventDefault(), C >= 0 && C < N.length)) {
439
- const D = N[C];
440
- n && n(D);
441
- }
442
- }
443
- }, f = (y) => y.sortable === !1 ? null : (m == null ? void 0 : m.key) !== y.key ? /* @__PURE__ */ t(ze, { size: 14, className: "text-muted-foreground/60 ml-1.5 opacity-0 group-hover:opacity-100 transition-opacity" }) : m.direction === "asc" ? /* @__PURE__ */ t(xe, { size: 14, className: "text-primary ml-1.5" }) : /* @__PURE__ */ t(ve, { size: 14, className: "text-primary ml-1.5" }), E = () => /* @__PURE__ */ t("tr", { role: "row", className: "border-b border-border bg-muted/30 select-none", children: o.map((y) => /* @__PURE__ */ t(
444
- "th",
360
+ return /* @__PURE__ */ c(
361
+ "header",
445
362
  {
446
- role: "columnheader",
447
- "aria-sort": (m == null ? void 0 : m.key) === y.key ? m.direction === "asc" ? "ascending" : "descending" : "none",
363
+ role: "banner",
364
+ "aria-label": "Application Header",
448
365
  className: S(
449
- "p-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-left transition-colors",
450
- y.sortable !== !1 && "cursor-pointer hover:bg-accent/30 hover:text-foreground group"
451
- ),
452
- style: { width: y.width },
453
- onClick: () => b(y.key, y.sortable),
454
- children: /* @__PURE__ */ c("div", { className: "flex items-center", children: [
455
- /* @__PURE__ */ t("span", { children: y.header }),
456
- f(y)
457
- ] })
458
- },
459
- y.key
460
- )) }), L = (y, D) => {
461
- const I = r !== void 0 && y[a] === r;
462
- return /* @__PURE__ */ t(
463
- "tr",
464
- {
465
- role: "row",
466
- "aria-selected": I,
467
- onClick: () => n && n(y),
468
- className: S(
469
- "border-b border-border/40 hover:bg-accent/40 transition-colors cursor-pointer text-sm outline-none",
470
- I && "bg-primary/10 text-primary hover:bg-primary/15 font-medium border-l-2 border-l-primary",
471
- C === D && "bg-accent/60 ring-1 ring-inset ring-ring"
472
- ),
473
- children: o.map((K) => {
474
- const P = y[K.key];
475
- return /* @__PURE__ */ t("td", { role: "gridcell", className: "p-3 align-middle truncate max-w-xs", children: K.render ? K.render(P, y) : P != null ? String(P) : "" }, K.key);
476
- })
477
- },
478
- String(y[a] || D)
479
- );
480
- }, k = j(() => ({
481
- Table: (y) => /* @__PURE__ */ t(
482
- "table",
483
- {
484
- ...y,
485
- role: "grid",
486
- className: "w-full border-collapse text-left bg-background text-foreground"
487
- }
488
- ),
489
- TableHead: oe.forwardRef((y, D) => /* @__PURE__ */ t("thead", { ref: D, ...y, className: "sticky top-0 bg-background z-10 shadow-[0_1px_0_0_rgba(0,0,0,0.1)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.05)]" })),
490
- TableBody: oe.forwardRef((y, D) => /* @__PURE__ */ t("tbody", { ref: D, ...y })),
491
- TableRow: ({ item: y, context: D, ...I }) => {
492
- if (!D || !y) return /* @__PURE__ */ t("tr", { ...I });
493
- const R = D.selectedRowId !== void 0 && y[D.rowKey] === D.selectedRowId, K = D.focusedIndex === I["data-index"];
494
- return /* @__PURE__ */ t(
495
- "tr",
496
- {
497
- ...I,
498
- onClick: () => {
499
- var P;
500
- return (P = D.onRowClick) == null ? void 0 : P.call(D, y);
501
- },
502
- className: S(
503
- "border-b border-border/40 hover:bg-accent/40 transition-colors cursor-pointer text-sm outline-none",
504
- R && "bg-primary/10 text-primary hover:bg-primary/15 font-medium border-l-2 border-l-primary",
505
- K && "bg-accent/60 ring-1 ring-inset ring-ring"
506
- )
507
- }
508
- );
509
- }
510
- }), []), A = () => u ? /* @__PURE__ */ c("div", { className: "flex flex-col items-center justify-center h-64 space-y-3", children: [
511
- /* @__PURE__ */ t(be, { className: "animate-spin text-primary", size: 24 }),
512
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: "Loading dataset..." })
513
- ] }) : N.length === 0 ? /* @__PURE__ */ c("div", { className: "flex flex-col items-center justify-center h-48 text-center px-4", children: [
514
- /* @__PURE__ */ t("span", { className: "text-sm font-medium text-foreground", children: i }),
515
- /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground mt-1", children: "No items matched your search query." })
516
- ] }) : s ? /* @__PURE__ */ t("div", { className: "flex-1 min-h-[300px] h-full relative", children: /* @__PURE__ */ t(
517
- Ve,
518
- {
519
- data: N,
520
- context: {
521
- selectedRowId: r,
522
- focusedIndex: C,
523
- rowKey: a,
524
- onRowClick: n
525
- },
526
- components: k,
527
- fixedHeaderContent: E,
528
- itemContent: (y, D) => /* @__PURE__ */ t(fe, { children: o.map((I) => {
529
- const R = D[I.key];
530
- return /* @__PURE__ */ t("td", { role: "gridcell", className: "p-3 align-middle truncate max-w-xs", children: I.render ? I.render(R, D) : R != null ? String(R) : "" }, I.key);
531
- }) })
532
- }
533
- ) }) : /* @__PURE__ */ t("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ c("table", { role: "grid", className: "w-full border-collapse text-left bg-background text-foreground", children: [
534
- /* @__PURE__ */ t("thead", { children: E() }),
535
- /* @__PURE__ */ t("tbody", { children: N.map((y, D) => L(y, D)) })
536
- ] }) });
537
- return /* @__PURE__ */ c(
538
- "div",
539
- {
540
- ref: h,
541
- role: "region",
542
- "aria-label": "Data Grid",
543
- tabIndex: 0,
544
- onKeyDown: v,
545
- className: S(
546
- "flex flex-col h-full bg-background border border-border rounded-lg shadow-sm overflow-hidden focus:outline-none focus:ring-1 focus:ring-ring focus:border-transparent",
547
- d
548
- ),
549
- children: [
550
- l && /* @__PURE__ */ c("div", { className: "flex items-center justify-between p-3 border-b border-border bg-muted/20", children: [
551
- /* @__PURE__ */ c("div", { className: "relative flex-1 max-w-sm", children: [
552
- /* @__PURE__ */ t(X, { size: 14, className: "absolute left-2.5 top-2.5 text-muted-foreground" }),
553
- /* @__PURE__ */ t(
554
- "input",
555
- {
556
- type: "text",
557
- placeholder: "Filter table rows...",
558
- className: "w-full bg-secondary/40 border border-border rounded-md pl-8 pr-7 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary focus:border-transparent transition-all",
559
- value: p,
560
- onChange: (y) => g(y.target.value)
561
- }
562
- ),
563
- p && /* @__PURE__ */ t(
564
- "button",
565
- {
566
- onClick: () => g(""),
567
- className: "absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",
568
- "aria-label": "Clear filter",
569
- children: /* @__PURE__ */ t(_, { size: 12 })
570
- }
571
- )
572
- ] }),
573
- /* @__PURE__ */ c("div", { className: "text-[11px] text-muted-foreground font-medium ml-4", children: [
574
- N.length,
575
- " of ",
576
- e.length,
577
- " records"
578
- ] })
579
- ] }),
580
- A()
581
- ]
582
- }
583
- );
584
- }, lt = ({
585
- menus: o = {},
586
- onSelect: e,
587
- title: n,
588
- center: r,
589
- right: a,
590
- className: s
591
- }) => {
592
- const l = (i) => i.keybinding ? /* @__PURE__ */ t("span", { className: "text-[10px] text-muted-foreground opacity-60 ml-4", children: i.keybinding }) : null, u = (i) => /* @__PURE__ */ t(
593
- "div",
594
- {
595
- role: "menu",
596
- className: "absolute left-0 top-full hidden group-hover:block z-50 min-w-[180px] bg-popover text-popover-foreground border shadow-md rounded-md py-1",
597
- children: i.map((d) => /* @__PURE__ */ c("div", { className: "relative group/sub", children: [
598
- /* @__PURE__ */ c(
599
- "div",
600
- {
601
- role: "menuitem",
602
- tabIndex: 0,
603
- onClick: () => !d.submenu && (e == null ? void 0 : e(d)),
604
- onKeyDown: (p) => {
605
- !d.submenu && (p.key === "Enter" || p.key === " ") && (p.preventDefault(), e == null || e(d));
606
- },
607
- className: "px-3 py-1.5 hover:bg-accent hover:text-accent-foreground cursor-pointer text-xs flex justify-between items-center focus:outline-none focus:bg-accent",
608
- children: [
609
- /* @__PURE__ */ t("span", { children: d.label }),
610
- /* @__PURE__ */ c("div", { className: "flex items-center space-x-2", children: [
611
- l(d),
612
- d.submenu && /* @__PURE__ */ t(ye, { size: 10 })
613
- ] })
614
- ]
615
- }
616
- ),
617
- d.submenu && /* @__PURE__ */ t(
618
- "div",
619
- {
620
- role: "menu",
621
- className: "absolute left-full top-0 hidden group-hover/sub:block z-[60] min-w-[180px] bg-popover text-popover-foreground border shadow-md rounded-md py-1 ml-[-2px]",
622
- children: d.submenu.map((p) => /* @__PURE__ */ c(
623
- "div",
624
- {
625
- role: "menuitem",
626
- tabIndex: 0,
627
- onClick: () => e == null ? void 0 : e(p),
628
- onKeyDown: (g) => {
629
- (g.key === "Enter" || g.key === " ") && (g.preventDefault(), e == null || e(p));
630
- },
631
- className: "px-3 py-1.5 hover:bg-accent hover:text-accent-foreground cursor-pointer text-xs flex justify-between items-center focus:outline-none focus:bg-accent",
632
- children: [
633
- /* @__PURE__ */ t("span", { children: p.label }),
634
- l(p)
635
- ]
636
- },
637
- p.id
638
- ))
639
- }
640
- )
641
- ] }, d.id))
642
- }
643
- );
644
- return /* @__PURE__ */ c(
645
- "header",
646
- {
647
- role: "banner",
648
- "aria-label": "Application Header",
649
- className: S(
650
- "bg-muted border-b flex items-center justify-between px-4 select-none shrink-0 transition-all z-50 relative",
651
- n !== void 0 ? "h-12 bg-card/65 backdrop-blur-sm" : "h-8",
652
- s
366
+ "bg-muted border-b flex items-center justify-between px-4 select-none shrink-0 transition-all z-50 relative",
367
+ n !== void 0 ? "h-12 bg-card/65 backdrop-blur-sm" : "h-8",
368
+ s
653
369
  ),
654
370
  children: [
655
371
  /* @__PURE__ */ c("div", { className: "flex items-center flex-1 min-w-0", children: [
656
- n !== void 0 ? /* @__PURE__ */ t("div", { className: "mr-12 flex items-center shrink-0", children: n }) : /* @__PURE__ */ t("div", { className: "font-semibold mr-6 text-sm shrink-0", children: "Nexus Shell" }),
657
- /* @__PURE__ */ t(
372
+ n !== void 0 ? /* @__PURE__ */ r("div", { className: "mr-12 flex items-center shrink-0", children: n }) : /* @__PURE__ */ r("div", { className: "font-semibold mr-6 text-sm shrink-0", children: "Nexus Shell" }),
373
+ /* @__PURE__ */ r(
658
374
  "nav",
659
375
  {
660
376
  role: "navigation",
661
377
  "aria-label": "Main Menu",
662
378
  className: "flex space-x-1 text-sm shrink-0",
663
379
  children: Object.entries(o).map(([i, d]) => /* @__PURE__ */ c("div", { className: "relative group", children: [
664
- /* @__PURE__ */ t(
380
+ /* @__PURE__ */ r(
665
381
  "div",
666
382
  {
667
383
  role: "button",
@@ -675,439 +391,190 @@ const et = [
675
391
  ] }, i))
676
392
  }
677
393
  ),
678
- r && /* @__PURE__ */ t("div", { className: "ml-8 w-60 md:w-72 relative hidden sm:block", children: r })
394
+ t && /* @__PURE__ */ r("div", { className: "ml-8 w-60 md:w-72 relative hidden sm:block", children: t })
679
395
  ] }),
680
- a && /* @__PURE__ */ t("div", { className: "flex items-center ml-4 shrink-0", children: a })
396
+ a && /* @__PURE__ */ r("div", { className: "flex items-center ml-4 shrink-0", children: a })
681
397
  ]
682
398
  }
683
399
  );
684
- }, it = {
685
- alert: Pe,
686
- confirm: Ae,
687
- prompt: Le
688
- }, ct = {
689
- alert: "text-destructive",
690
- confirm: "text-amber-500",
691
- prompt: "text-blue-500"
692
- }, dt = ({
693
- open: o,
694
- type: e = "alert",
695
- title: n,
696
- message: r,
697
- defaultValue: a = "",
698
- onConfirm: s,
699
- onCancel: l,
700
- confirmLabel: u,
701
- cancelLabel: i = "Cancel",
702
- placeholder: d = "Enter value…",
703
- className: p
704
- }) => {
705
- const [g, m] = O(a), w = M(null);
706
- if (z(() => {
707
- if (!o || (m(a), e !== "prompt")) return;
708
- const T = window.setTimeout(() => {
709
- var N, b;
710
- (N = w.current) == null || N.focus(), (b = w.current) == null || b.select();
711
- }, 50);
712
- return () => window.clearTimeout(T);
713
- }, [o, e, a]), z(() => {
714
- if (!o) return;
715
- const T = (N) => {
716
- N.key === "Escape" && (N.preventDefault(), l == null || l());
717
- };
718
- return document.addEventListener("keydown", T), () => document.removeEventListener("keydown", T);
719
- }, [o, l]), !o) return null;
720
- const C = () => s == null ? void 0 : s(e === "prompt" ? g : void 0), x = (T) => {
721
- T.key === "Enter" && (T.preventDefault(), C());
722
- }, h = it[e];
723
- return /* @__PURE__ */ t(
400
+ };
401
+ class ct {
402
+ constructor() {
403
+ H(this, "menus", /* @__PURE__ */ new Map());
404
+ }
405
+ registerMenu(e, n) {
406
+ var t;
407
+ this.menus.has(e) || this.menus.set(e, []), (t = this.menus.get(e)) == null || t.push(n);
408
+ }
409
+ setMenus(e) {
410
+ this.menus = new Map(Object.entries(e));
411
+ }
412
+ getMenu(e) {
413
+ return this.menus.get(e) || [];
414
+ }
415
+ getAllMenus() {
416
+ const e = {};
417
+ return this.menus.forEach((n, t) => {
418
+ e[t] = n;
419
+ }), e;
420
+ }
421
+ }
422
+ const le = new ct();
423
+ class ut {
424
+ constructor() {
425
+ H(this, "commands", /* @__PURE__ */ new Map());
426
+ }
427
+ registerCommand(e) {
428
+ if (this.commands.has(e.id)) {
429
+ console.warn(`Command ${e.id} is already registered.`);
430
+ return;
431
+ }
432
+ this.commands.set(e.id, e);
433
+ }
434
+ executeCommand(e, ...n) {
435
+ const t = this.commands.get(e);
436
+ t ? t.execute(...n) : console.warn(`Command ${e} not found.`);
437
+ }
438
+ getCommand(e) {
439
+ return this.commands.get(e);
440
+ }
441
+ getCommands() {
442
+ return Array.from(this.commands.values());
443
+ }
444
+ }
445
+ const B = new ut(), Ce = (o) => o.map((e) => {
446
+ var n;
447
+ return {
448
+ ...e,
449
+ keybinding: e.keybinding ?? (e.commandId ? (n = B.getCommand(e.commandId)) == null ? void 0 : n.keybinding : void 0),
450
+ submenu: e.submenu ? Ce(e.submenu) : void 0
451
+ };
452
+ }), Se = (o, e) => {
453
+ for (const n of o) {
454
+ if (n.id === e) return n;
455
+ const t = n.submenu && Se(n.submenu, e);
456
+ if (t) return t;
457
+ }
458
+ }, mt = (o) => {
459
+ const e = le.getAllMenus(), n = Object.fromEntries(
460
+ Object.entries(e).map(([a, s]) => [a, Ce(s)])
461
+ );
462
+ return /* @__PURE__ */ r(dt, { ...o, menus: n, onSelect: (a) => {
463
+ for (const s of Object.values(e)) {
464
+ const l = Se(s, a.id);
465
+ if (l != null && l.commandId) {
466
+ B.executeCommand(l.commandId);
467
+ return;
468
+ }
469
+ }
470
+ } });
471
+ }, re = ({
472
+ title: o,
473
+ children: e,
474
+ onClose: n,
475
+ width: t = "300px",
476
+ className: a
477
+ }) => /* @__PURE__ */ c(
478
+ "aside",
479
+ {
480
+ role: "tabpanel",
481
+ "aria-label": `${o} Panel`,
482
+ style: { width: t },
483
+ className: S(
484
+ "h-full bg-muted border-r flex flex-col select-none shrink-0",
485
+ a
486
+ ),
487
+ children: [
488
+ /* @__PURE__ */ c("div", { className: "h-10 flex items-center justify-between px-4 text-[11px] font-bold text-muted-foreground uppercase tracking-widest", children: [
489
+ /* @__PURE__ */ r("span", { className: "truncate", children: o }),
490
+ n && /* @__PURE__ */ r(
491
+ "button",
492
+ {
493
+ type: "button",
494
+ onClick: n,
495
+ "aria-label": "Close Panel",
496
+ className: "p-1 hover:bg-accent hover:text-foreground rounded transition-colors focus:outline-none focus:ring-2 focus:ring-ring shrink-0",
497
+ children: /* @__PURE__ */ r(J, { size: 14 })
498
+ }
499
+ )
500
+ ] }),
501
+ /* @__PURE__ */ r("div", { className: "flex-1 overflow-auto border-t border-border/50 bg-background/50", children: e })
502
+ ]
503
+ }
504
+ ), ft = [
505
+ { id: "light", label: "Light", icon: Me },
506
+ { id: "dark", label: "Dark", icon: Pe },
507
+ { id: "gt", label: "Georgia Tech", icon: Ke }
508
+ ], pt = ({
509
+ theme: o,
510
+ onThemeChange: e,
511
+ themes: n = ft,
512
+ className: t
513
+ }) => /* @__PURE__ */ r("div", { className: S("p-4 space-y-6", t), children: /* @__PURE__ */ c("section", { children: [
514
+ /* @__PURE__ */ r("h3", { className: "text-[11px] font-bold text-muted-foreground uppercase mb-3", children: "Theme" }),
515
+ /* @__PURE__ */ r(
724
516
  "div",
725
517
  {
726
- className: "fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-background/80 backdrop-blur-sm transition-all duration-300",
727
- onClick: l,
728
- children: /* @__PURE__ */ c(
729
- "div",
518
+ role: "radiogroup",
519
+ "aria-label": "Theme",
520
+ className: "grid grid-cols-1 gap-2",
521
+ children: n.map(({ id: a, label: s, icon: l }) => /* @__PURE__ */ c(
522
+ "button",
730
523
  {
731
- role: "dialog",
732
- "aria-modal": "true",
733
- "aria-label": n,
734
- onClick: (T) => T.stopPropagation(),
735
- onKeyDown: x,
524
+ type: "button",
525
+ role: "radio",
526
+ "aria-checked": o === a,
527
+ onClick: () => e(a),
736
528
  className: S(
737
- "relative flex flex-col w-full max-w-md p-6 bg-card border border-border shadow-2xl rounded-2xl animate-in fade-in zoom-in-95 ring-1 ring-white/10",
738
- p
529
+ "flex items-center space-x-3 px-3 py-2 rounded-md border text-sm transition-all focus:outline-none focus:ring-2 focus:ring-ring",
530
+ o === a ? "bg-primary text-primary-foreground border-primary" : "bg-background hover:bg-accent border-border"
739
531
  ),
740
532
  children: [
741
- /* @__PURE__ */ t(
742
- "button",
743
- {
744
- type: "button",
745
- onClick: l,
746
- "aria-label": "Close",
747
- className: "absolute top-4 right-4 p-1 rounded-full text-muted-foreground hover:bg-muted hover:text-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
748
- children: /* @__PURE__ */ t(_, { size: 18 })
749
- }
750
- ),
751
- /* @__PURE__ */ c("div", { className: "flex items-start space-x-4 mb-4", children: [
752
- /* @__PURE__ */ t("div", { className: S("p-2 bg-muted rounded-full shrink-0", ct[e]), children: /* @__PURE__ */ t(h, { size: 24 }) }),
753
- /* @__PURE__ */ c("div", { className: "flex-1 mt-1", children: [
754
- /* @__PURE__ */ t("h2", { className: "text-lg font-semibold tracking-tight pr-6", children: n }),
755
- r && /* @__PURE__ */ t("p", { className: "text-sm text-muted-foreground mt-1 whitespace-pre-wrap", children: r })
756
- ] })
757
- ] }),
758
- e === "prompt" && /* @__PURE__ */ t("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ t(
759
- "input",
760
- {
761
- ref: w,
762
- type: "text",
763
- "aria-label": n,
764
- value: g,
765
- placeholder: d,
766
- onChange: (T) => m(T.target.value),
767
- className: "w-full bg-background border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all placeholder:text-muted-foreground/50"
768
- }
769
- ) }),
770
- /* @__PURE__ */ c("div", { className: "flex items-center justify-end space-x-3 mt-4", children: [
771
- e !== "alert" && /* @__PURE__ */ t(
772
- "button",
773
- {
774
- type: "button",
775
- onClick: l,
776
- className: "px-4 py-2 text-sm font-medium rounded-lg border border-border hover:bg-muted transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
777
- children: i
778
- }
779
- ),
780
- /* @__PURE__ */ t(
781
- "button",
782
- {
783
- type: "button",
784
- onClick: C,
785
- autoFocus: e !== "prompt",
786
- className: "px-4 py-2 text-sm font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
787
- children: u ?? (e === "alert" ? "OK" : "Confirm")
788
- }
789
- )
790
- ] })
791
- ]
792
- }
793
- )
794
- }
795
- );
796
- }, Wt = ({
797
- results: o,
798
- onQueryChange: e,
799
- onSelect: n,
800
- categories: r,
801
- placeholder: a = "Search…",
802
- debounceMs: s = 200,
803
- className: l
804
- }) => {
805
- const [u, i] = O(""), [d, p] = O(!1), [g, m] = O(0), w = M(null), C = M(null), x = j(() => r || [...new Set(o.map((b) => b.category))], [r, o]), h = j(
806
- () => x.flatMap((b) => o.filter((v) => v.category === b)),
807
- [x, o]
808
- );
809
- z(() => {
810
- const b = (v) => {
811
- w.current && !w.current.contains(v.target) && p(!1);
812
- };
813
- return document.addEventListener("mousedown", b), () => document.removeEventListener("mousedown", b);
814
- }, []), z(() => {
815
- if (!e) return;
816
- const b = window.setTimeout(() => e(u), s);
817
- return () => window.clearTimeout(b);
818
- }, [u, s, e]), z(() => {
819
- m(0);
820
- }, [o]);
821
- const T = (b) => {
822
- n(b), p(!1), i("");
823
- }, N = (b) => {
824
- var v;
825
- if (!d) {
826
- (b.key === "ArrowDown" || b.key === "Enter") && p(!0);
827
- return;
828
- }
829
- b.key === "ArrowDown" ? (b.preventDefault(), m((f) => h.length ? (f + 1) % h.length : 0)) : b.key === "ArrowUp" ? (b.preventDefault(), m(
830
- (f) => h.length ? (f - 1 + h.length) % h.length : 0
831
- )) : b.key === "Enter" ? (b.preventDefault(), h[g] && T(h[g])) : b.key === "Escape" && (b.preventDefault(), p(!1), (v = C.current) == null || v.blur());
832
- };
833
- return /* @__PURE__ */ c("div", { ref: w, className: S("relative w-full", l), children: [
834
- /* @__PURE__ */ c("div", { className: "relative flex items-center", children: [
835
- /* @__PURE__ */ t(
836
- X,
837
- {
838
- size: 13,
839
- className: "absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground"
840
- }
841
- ),
842
- /* @__PURE__ */ t(
843
- "input",
844
- {
845
- ref: C,
846
- type: "text",
847
- role: "combobox",
848
- "aria-expanded": d,
849
- "aria-label": a,
850
- value: u,
851
- placeholder: a,
852
- onChange: (b) => {
853
- i(b.target.value), p(!0);
854
- },
855
- onFocus: () => p(!0),
856
- onKeyDown: N,
857
- className: "w-full h-7 pl-8 pr-7 bg-secondary/35 border border-border/40 rounded-md text-xs text-foreground placeholder:text-muted-foreground/75 focus:outline-none focus:ring-1 focus:ring-primary/40 focus:bg-background/95 focus:border-primary/50 transition-all font-sans"
858
- }
859
- ),
860
- u && /* @__PURE__ */ t(
861
- "button",
862
- {
863
- type: "button",
864
- onClick: () => {
865
- var b;
866
- i(""), (b = C.current) == null || b.focus();
867
- },
868
- "aria-label": "Clear search",
869
- className: "absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
870
- children: /* @__PURE__ */ t(_, { size: 11 })
871
- }
872
- )
873
- ] }),
874
- d && u.trim() && /* @__PURE__ */ c(
875
- "div",
876
- {
877
- role: "listbox",
878
- className: "absolute right-0 md:left-0 mt-1.5 w-80 max-h-[380px] bg-popover text-popover-foreground border border-border shadow-lg rounded-lg overflow-hidden flex flex-col z-[100] animate-in fade-in-50 slide-in-from-top-1 duration-100",
879
- children: [
880
- /* @__PURE__ */ t("div", { className: "flex-1 overflow-y-auto py-1", children: h.length === 0 ? /* @__PURE__ */ c("div", { className: "px-4 py-6 text-center text-xs text-muted-foreground italic", children: [
881
- 'No results found matching "',
882
- u,
883
- '"'
884
- ] }) : x.map((b) => {
885
- const v = o.filter((f) => f.category === b);
886
- return v.length === 0 ? null : /* @__PURE__ */ c("div", { className: "flex flex-col", children: [
887
- /* @__PURE__ */ t("div", { className: "px-3 py-1 text-[9px] font-bold uppercase tracking-wider text-muted-foreground/80 bg-muted/40 border-y border-border/20 first:border-t-0", children: b }),
888
- v.map((f) => {
889
- const E = f.icon, L = h.indexOf(f), k = L === g;
890
- return /* @__PURE__ */ c(
891
- "div",
892
- {
893
- role: "option",
894
- "aria-selected": k,
895
- onClick: () => T(f),
896
- onMouseEnter: () => m(L),
897
- className: S(
898
- "px-3 py-2 cursor-pointer flex items-start space-x-2.5 transition-colors border-l-2",
899
- k ? "bg-accent text-accent-foreground border-primary" : "border-transparent hover:bg-accent/40"
900
- ),
901
- children: [
902
- E && /* @__PURE__ */ t(
903
- "div",
904
- {
905
- className: S(
906
- "mt-0.5 p-1 rounded bg-muted/50",
907
- k && "bg-background text-primary"
908
- ),
909
- children: /* @__PURE__ */ t(E, { size: 12 })
910
- }
911
- ),
912
- /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
913
- /* @__PURE__ */ t("div", { className: "text-xs font-medium truncate", children: f.title }),
914
- f.description && /* @__PURE__ */ t("div", { className: "text-[10px] text-muted-foreground truncate mt-0.5", children: f.description })
915
- ] })
916
- ]
917
- },
918
- `${f.category}-${f.id}`
919
- );
920
- })
921
- ] }, b);
922
- }) }),
923
- h.length > 0 && /* @__PURE__ */ c("div", { className: "px-3 py-1.5 border-t border-border bg-muted/20 flex items-center justify-between text-[9px] text-muted-foreground select-none shrink-0 font-mono", children: [
924
- /* @__PURE__ */ c("div", { className: "flex space-x-2", children: [
925
- /* @__PURE__ */ c("span", { children: [
926
- /* @__PURE__ */ t("kbd", { className: "bg-muted px-1 rounded border border-border/60", children: "↑↓" }),
927
- " ",
928
- "navigate"
929
- ] }),
930
- /* @__PURE__ */ c("span", { children: [
931
- /* @__PURE__ */ t("kbd", { className: "bg-muted px-1 rounded border border-border/60", children: "↵" }),
932
- " ",
933
- "select"
934
- ] })
935
- ] }),
936
- /* @__PURE__ */ t("span", { children: "ESC to close" })
937
- ] })
938
- ]
939
- }
940
- )
941
- ] });
942
- }, Bt = ({
943
- placeholder: o = "Search...",
944
- onSearch: e,
945
- results: n,
946
- onSelect: r,
947
- suggestions: a = [],
948
- loading: s = !1,
949
- className: l
950
- }) => {
951
- const [u, i] = O(""), [d, p] = O(!1), [g, m] = O(-1), w = M(null);
952
- z(() => {
953
- const h = setTimeout(() => {
954
- e(u);
955
- }, 300);
956
- return () => clearTimeout(h);
957
- }, [u, e]);
958
- const C = a.filter(
959
- (h) => h.toLowerCase().includes(u.toLowerCase()) && h.toLowerCase() !== u.toLowerCase()
960
- ), x = (h) => {
961
- d && C.length > 0 && (h.key === "ArrowDown" ? (h.preventDefault(), m((T) => (T + 1) % C.length)) : h.key === "ArrowUp" ? (h.preventDefault(), m((T) => (T - 1 + C.length) % C.length)) : h.key === "Enter" && g >= 0 && (h.preventDefault(), i(C[g]), p(!1)));
962
- };
963
- return /* @__PURE__ */ c("div", { ref: w, className: S("flex flex-col h-full bg-background", l), children: [
964
- /* @__PURE__ */ c("div", { className: "p-3 border-b border-border/50", children: [
965
- /* @__PURE__ */ c("div", { className: "relative", children: [
966
- /* @__PURE__ */ t("div", { className: "absolute left-2.5 top-2.5 text-muted-foreground", children: s ? /* @__PURE__ */ t(be, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ t(X, { size: 14 }) }),
967
- /* @__PURE__ */ t(
968
- "input",
969
- {
970
- type: "text",
971
- className: "w-full bg-secondary/50 border border-border rounded-md pl-9 pr-8 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all",
972
- placeholder: o,
973
- value: u,
974
- onChange: (h) => {
975
- i(h.target.value), p(!0), m(-1);
976
- },
977
- onKeyDown: x,
978
- onFocus: () => p(!0)
979
- }
980
- ),
981
- u && /* @__PURE__ */ t(
982
- "button",
983
- {
984
- onClick: () => {
985
- i(""), e("");
986
- },
987
- className: "absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",
988
- children: /* @__PURE__ */ t(_, { size: 14 })
989
- }
990
- )
991
- ] }),
992
- d && C.length > 0 && /* @__PURE__ */ t("div", { className: "absolute left-3 right-3 mt-1 bg-popover border shadow-lg rounded-md z-50 py-1 overflow-hidden", children: C.map((h, T) => /* @__PURE__ */ c(
993
- "div",
994
- {
995
- className: S(
996
- "px-3 py-1.5 text-xs cursor-pointer flex items-center space-x-2",
997
- T === g ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
998
- ),
999
- onClick: () => {
1000
- i(h), p(!1);
1001
- },
1002
- children: [
1003
- /* @__PURE__ */ t(Me, { size: 12, className: "text-muted-foreground" }),
1004
- /* @__PURE__ */ t("span", { children: h })
1005
- ]
1006
- },
1007
- h
1008
- )) })
1009
- ] }),
1010
- /* @__PURE__ */ t("div", { className: "flex-1 overflow-y-auto", children: n.length === 0 ? /* @__PURE__ */ t("div", { className: "p-8 text-center text-xs text-muted-foreground italic", children: u ? `No results found for "${u}"` : "Type to start searching..." }) : /* @__PURE__ */ t("div", { className: "py-2", children: n.map((h) => {
1011
- const T = h.icon;
1012
- return /* @__PURE__ */ t(
1013
- "div",
1014
- {
1015
- onClick: () => r(h),
1016
- className: "px-4 py-2 hover:bg-accent/50 cursor-pointer group transition-colors border-l-2 border-transparent hover:border-primary",
1017
- children: /* @__PURE__ */ c("div", { className: "flex items-start space-x-3", children: [
1018
- T && /* @__PURE__ */ t("div", { className: "mt-0.5 p-1 rounded bg-muted group-hover:bg-background transition-colors", children: /* @__PURE__ */ t(T, { size: 14, className: "text-muted-foreground group-hover:text-primary" }) }),
1019
- /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
1020
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between", children: [
1021
- /* @__PURE__ */ t("span", { className: "text-xs font-medium truncate", children: h.title }),
1022
- h.category && /* @__PURE__ */ t("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground font-bold px-1.5 py-0.5 bg-muted rounded", children: h.category })
1023
- ] }),
1024
- h.description && /* @__PURE__ */ t("p", { className: "text-[11px] text-muted-foreground truncate mt-0.5", children: h.description })
1025
- ] })
1026
- ] })
1027
- },
1028
- h.id
1029
- );
1030
- }) }) })
1031
- ] });
1032
- }, ut = [
1033
- { id: "light", label: "Light", icon: Ke },
1034
- { id: "dark", label: "Dark", icon: $e },
1035
- { id: "gt", label: "Georgia Tech", icon: Re }
1036
- ], mt = ({
1037
- theme: o,
1038
- onThemeChange: e,
1039
- themes: n = ut,
1040
- className: r
1041
- }) => /* @__PURE__ */ t("div", { className: S("p-4 space-y-6", r), children: /* @__PURE__ */ c("section", { children: [
1042
- /* @__PURE__ */ t("h3", { className: "text-[11px] font-bold text-muted-foreground uppercase mb-3", children: "Theme" }),
1043
- /* @__PURE__ */ t(
1044
- "div",
1045
- {
1046
- role: "radiogroup",
1047
- "aria-label": "Theme",
1048
- className: "grid grid-cols-1 gap-2",
1049
- children: n.map(({ id: a, label: s, icon: l }) => /* @__PURE__ */ c(
1050
- "button",
1051
- {
1052
- type: "button",
1053
- role: "radio",
1054
- "aria-checked": o === a,
1055
- onClick: () => e(a),
1056
- className: S(
1057
- "flex items-center space-x-3 px-3 py-2 rounded-md border text-sm transition-all focus:outline-none focus:ring-2 focus:ring-ring",
1058
- o === a ? "bg-primary text-primary-foreground border-primary" : "bg-background hover:bg-accent border-border"
1059
- ),
1060
- children: [
1061
- /* @__PURE__ */ t(l, { size: 16 }),
1062
- /* @__PURE__ */ t("span", { children: s })
533
+ /* @__PURE__ */ r(l, { size: 16 }),
534
+ /* @__PURE__ */ r("span", { children: s })
1063
535
  ]
1064
536
  },
1065
537
  a
1066
538
  ))
1067
539
  }
1068
540
  )
1069
- ] }) }), te = ({
1070
- title: o,
1071
- children: e,
1072
- onClose: n,
1073
- width: r = "300px",
1074
- className: a
1075
- }) => /* @__PURE__ */ c(
1076
- "aside",
1077
- {
1078
- role: "tabpanel",
1079
- "aria-label": `${o} Panel`,
1080
- style: { width: r },
1081
- className: S(
1082
- "h-full bg-muted border-r flex flex-col select-none shrink-0",
1083
- a
1084
- ),
1085
- children: [
1086
- /* @__PURE__ */ c("div", { className: "h-10 flex items-center justify-between px-4 text-[11px] font-bold text-muted-foreground uppercase tracking-widest", children: [
1087
- /* @__PURE__ */ t("span", { className: "truncate", children: o }),
1088
- n && /* @__PURE__ */ t(
1089
- "button",
1090
- {
1091
- type: "button",
1092
- onClick: n,
1093
- "aria-label": "Close Panel",
1094
- className: "p-1 hover:bg-accent hover:text-foreground rounded transition-colors focus:outline-none focus:ring-2 focus:ring-ring shrink-0",
1095
- children: /* @__PURE__ */ t(_, { size: 14 })
1096
- }
1097
- )
1098
- ] }),
1099
- /* @__PURE__ */ t("div", { className: "flex-1 overflow-auto border-t border-border/50 bg-background/50", children: e })
1100
- ]
1101
- }
1102
- ), re = (o, e) => (e.priority ?? 0) - (o.priority ?? 0), ft = ({
541
+ ] }) }), ue = "nexus-shell-theme", me = (o) => {
542
+ const e = window.document.documentElement;
543
+ e.classList.remove("theme-light", "theme-dark", "theme-gt"), e.classList.add(`theme-${o}`);
544
+ }, Y = U((o) => {
545
+ const n = localStorage.getItem(ue) || "light";
546
+ return me(n), {
547
+ theme: n,
548
+ setTheme: (t) => {
549
+ localStorage.setItem(ue, t), me(t), o({ theme: t });
550
+ }
551
+ };
552
+ }), gt = (o) => {
553
+ const e = F((d) => d.activeSidebar), n = F((d) => d.panels), t = F((d) => d.setActiveSidebar), a = Y((d) => d.theme), s = Y((d) => d.setTheme);
554
+ if (!e) return null;
555
+ const l = () => t(null);
556
+ if (e === "settings")
557
+ return /* @__PURE__ */ r(re, { ...o, title: "Settings", onClose: l, children: /* @__PURE__ */ r(
558
+ pt,
559
+ {
560
+ theme: a,
561
+ onThemeChange: (d) => s(d)
562
+ }
563
+ ) });
564
+ const u = n.find((d) => d.id === e);
565
+ if (!u)
566
+ return /* @__PURE__ */ r(re, { ...o, title: e, onClose: l, children: /* @__PURE__ */ r("div", { className: "p-4 text-sm italic text-muted-foreground", children: "Panel content not found." }) });
567
+ const i = typeof u.component == "function" ? u.component : null;
568
+ return /* @__PURE__ */ r(re, { ...o, title: u.label, onClose: l, children: i ? /* @__PURE__ */ r(i, {}) : u.component });
569
+ }, ne = (o, e) => (e.priority ?? 0) - (o.priority ?? 0), ht = ({
1103
570
  widgets: o = [],
1104
571
  className: e,
1105
572
  "aria-label": n = "Status Bar"
1106
573
  }) => {
1107
- const r = {
1108
- left: o.filter((s) => s.alignment === "left").sort(re),
1109
- center: o.filter((s) => s.alignment === "center").sort(re),
1110
- right: o.filter((s) => s.alignment === "right").sort(re)
574
+ const t = {
575
+ left: o.filter((s) => s.alignment === "left").sort(ne),
576
+ center: o.filter((s) => s.alignment === "center").sort(ne),
577
+ right: o.filter((s) => s.alignment === "right").sort(ne)
1111
578
  }, a = (s) => {
1112
579
  const l = s.icon, u = !!s.onClick;
1113
580
  return /* @__PURE__ */ c(
@@ -1126,8 +593,8 @@ const et = [
1126
593
  s.className
1127
594
  ),
1128
595
  children: [
1129
- l && /* @__PURE__ */ t(l, { size: 12 }),
1130
- s.label && /* @__PURE__ */ t("span", { children: s.label })
596
+ l && /* @__PURE__ */ r(l, { size: 12 }),
597
+ s.label && /* @__PURE__ */ r("span", { children: s.label })
1131
598
  ]
1132
599
  },
1133
600
  s.id
@@ -1143,34 +610,57 @@ const et = [
1143
610
  e
1144
611
  ),
1145
612
  children: [
1146
- /* @__PURE__ */ t("div", { className: "flex items-center space-x-1 h-full", children: r.left.map(a) }),
1147
- /* @__PURE__ */ t("div", { className: "flex items-center space-x-1 h-full", children: r.center.map(a) }),
1148
- /* @__PURE__ */ t("div", { className: "flex items-center space-x-1 h-full", children: r.right.map(a) })
613
+ /* @__PURE__ */ r("div", { className: "flex items-center space-x-1 h-full", children: t.left.map(a) }),
614
+ /* @__PURE__ */ r("div", { className: "flex items-center space-x-1 h-full", children: t.center.map(a) }),
615
+ /* @__PURE__ */ r("div", { className: "flex items-center space-x-1 h-full", children: t.right.map(a) })
1149
616
  ]
1150
617
  }
1151
618
  );
1152
- }, pt = ({
619
+ }, ie = U((o) => ({
620
+ widgets: [],
621
+ setWidgets: (e) => o({ widgets: e }),
622
+ addWidget: (e) => o((n) => ({
623
+ widgets: [...n.widgets, e].sort(
624
+ (t, a) => (a.priority || 0) - (t.priority || 0)
625
+ )
626
+ })),
627
+ removeWidget: (e) => o((n) => ({
628
+ widgets: n.widgets.filter((t) => t.id !== e)
629
+ })),
630
+ updateWidget: (e, n) => o((t) => ({
631
+ widgets: t.widgets.map((a) => a.id === e ? { ...a, ...n } : a)
632
+ }))
633
+ })), bt = (o) => {
634
+ const e = ie((t) => t.widgets), n = R(
635
+ () => e.map(({ commandId: t, ...a }) => ({
636
+ ...a,
637
+ onClick: a.onClick ?? (t ? () => B.executeCommand(t) : void 0)
638
+ })),
639
+ [e]
640
+ );
641
+ return /* @__PURE__ */ r(ht, { ...o, widgets: n });
642
+ }, xt = ({
1153
643
  history: o = [],
1154
644
  onCommand: e,
1155
645
  onClose: n,
1156
- height: r = "250px",
646
+ height: t = "250px",
1157
647
  prompt: a = "$",
1158
648
  title: s = "Terminal",
1159
649
  className: l
1160
650
  }) => {
1161
- const [u, i] = O(""), d = M(null), p = M(null);
651
+ const [u, i] = A(""), d = P(null), f = P(null);
1162
652
  z(() => {
1163
653
  d.current && (d.current.scrollTop = d.current.scrollHeight);
1164
654
  }, [o]);
1165
- const g = (m) => {
655
+ const p = (m) => {
1166
656
  if (m.key !== "Enter") return;
1167
- const w = u.trim();
1168
- w && (e == null || e(w), i(""));
657
+ const k = u.trim();
658
+ k && (e == null || e(k), i(""));
1169
659
  };
1170
660
  return /* @__PURE__ */ c(
1171
661
  "div",
1172
662
  {
1173
- style: { height: r },
663
+ style: { height: t },
1174
664
  className: S(
1175
665
  "bg-card border-t border-border flex flex-col shrink-0 font-mono text-xs",
1176
666
  l
@@ -1178,33 +668,33 @@ const et = [
1178
668
  children: [
1179
669
  /* @__PURE__ */ c("div", { className: "h-8 flex items-center justify-between px-3 border-b border-border/50 shrink-0", children: [
1180
670
  /* @__PURE__ */ c("div", { className: "flex items-center space-x-2 text-muted-foreground", children: [
1181
- /* @__PURE__ */ t(he, { size: 13 }),
1182
- /* @__PURE__ */ t("span", { className: "text-[11px] font-bold uppercase tracking-widest", children: s })
671
+ /* @__PURE__ */ r(ve, { size: 13 }),
672
+ /* @__PURE__ */ r("span", { className: "text-[11px] font-bold uppercase tracking-widest", children: s })
1183
673
  ] }),
1184
674
  n && /* @__PURE__ */ c("div", { className: "flex items-center space-x-1", children: [
1185
- /* @__PURE__ */ t(
675
+ /* @__PURE__ */ r(
1186
676
  "button",
1187
677
  {
1188
678
  type: "button",
1189
679
  onClick: n,
1190
680
  "aria-label": "Collapse Terminal",
1191
681
  className: "p-1 rounded hover:bg-accent hover:text-foreground text-muted-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
1192
- children: /* @__PURE__ */ t(xe, { size: 14 })
682
+ children: /* @__PURE__ */ r(we, { size: 14 })
1193
683
  }
1194
684
  ),
1195
- /* @__PURE__ */ t(
685
+ /* @__PURE__ */ r(
1196
686
  "button",
1197
687
  {
1198
688
  type: "button",
1199
689
  onClick: n,
1200
690
  "aria-label": "Close Terminal",
1201
691
  className: "p-1 rounded hover:bg-accent hover:text-foreground text-muted-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
1202
- children: /* @__PURE__ */ t(_, { size: 14 })
692
+ children: /* @__PURE__ */ r(J, { size: 14 })
1203
693
  }
1204
694
  )
1205
695
  ] })
1206
696
  ] }),
1207
- /* @__PURE__ */ t(
697
+ /* @__PURE__ */ r(
1208
698
  "div",
1209
699
  {
1210
700
  ref: d,
@@ -1213,22 +703,22 @@ const et = [
1213
703
  className: "flex-1 overflow-y-auto px-3 py-2 space-y-0.5",
1214
704
  onClick: () => {
1215
705
  var m;
1216
- return (m = p.current) == null ? void 0 : m.focus();
706
+ return (m = f.current) == null ? void 0 : m.focus();
1217
707
  },
1218
- children: o.map((m, w) => /* @__PURE__ */ t("div", { className: "whitespace-pre-wrap break-all text-foreground/90", children: m }, w))
708
+ children: o.map((m, k) => /* @__PURE__ */ r("div", { className: "whitespace-pre-wrap break-all text-foreground/90", children: m }, k))
1219
709
  }
1220
710
  ),
1221
711
  /* @__PURE__ */ c("div", { className: "flex items-center px-3 py-2 border-t border-border/50 shrink-0", children: [
1222
- /* @__PURE__ */ t("span", { className: "text-primary mr-2 select-none", children: a }),
1223
- /* @__PURE__ */ t(
712
+ /* @__PURE__ */ r("span", { className: "text-primary mr-2 select-none", children: a }),
713
+ /* @__PURE__ */ r(
1224
714
  "input",
1225
715
  {
1226
- ref: p,
716
+ ref: f,
1227
717
  type: "text",
1228
718
  "aria-label": `${s} input`,
1229
719
  value: u,
1230
720
  onChange: (m) => i(m.target.value),
1231
- onKeyDown: g,
721
+ onKeyDown: p,
1232
722
  spellCheck: !1,
1233
723
  autoComplete: "off",
1234
724
  className: "flex-1 bg-transparent outline-none text-foreground placeholder:text-muted-foreground"
@@ -1238,1125 +728,1702 @@ const et = [
1238
728
  ]
1239
729
  }
1240
730
  );
1241
- }, gt = [
1242
- { id: "light", label: "Light" },
1243
- { id: "dark", label: "Dark" },
1244
- { id: "gt", label: "GT" }
1245
- ], ht = ({
1246
- value: o,
1247
- onChange: e,
1248
- options: n = gt,
1249
- className: r,
1250
- "aria-label": a = "Theme"
1251
- }) => /* @__PURE__ */ t(
1252
- "div",
1253
- {
1254
- role: "radiogroup",
1255
- "aria-label": a,
1256
- className: S(
1257
- "flex items-center border border-border rounded-lg p-0.5 bg-secondary/80 select-none",
1258
- r
1259
- ),
1260
- children: n.map((s) => /* @__PURE__ */ t(
1261
- "button",
1262
- {
1263
- role: "radio",
1264
- "aria-checked": o === s.id,
1265
- onClick: () => e(s.id),
1266
- className: S(
1267
- "px-2.5 py-1 text-[9px] font-extrabold uppercase rounded-md transition-all font-mono cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-ring",
1268
- o === s.id ? "bg-primary text-primary-foreground shadow" : "text-muted-foreground hover:bg-accent hover:text-foreground"
1269
- ),
1270
- children: s.label
731
+ }, V = U((o) => ({
732
+ isOpen: !1,
733
+ history: ["Welcome to Nexus Shell Terminal v0.1.0", 'Type "help" for a list of commands.'],
734
+ setOpen: (e) => o({ isOpen: e }),
735
+ toggle: () => o((e) => ({ isOpen: !e.isOpen })),
736
+ addHistory: (e) => o((n) => ({ history: [...n.history, e] })),
737
+ clearHistory: () => o({ history: [] })
738
+ })), vt = [
739
+ "Available commands:",
740
+ " help — show this message",
741
+ " clear — clear the terminal"
742
+ ], yt = ({
743
+ onCommand: o,
744
+ ...e
745
+ }) => {
746
+ const n = V((i) => i.isOpen), t = V((i) => i.history), a = V((i) => i.setOpen), s = V((i) => i.addHistory), l = V((i) => i.clearHistory);
747
+ return n ? /* @__PURE__ */ r(
748
+ xt,
749
+ {
750
+ ...e,
751
+ history: t,
752
+ onCommand: (i) => {
753
+ s(`$ ${i}`);
754
+ const d = i.toLowerCase();
755
+ if (d === "clear") {
756
+ l();
757
+ return;
758
+ }
759
+ if (d === "help") {
760
+ vt.forEach(s);
761
+ return;
762
+ }
763
+ (o == null ? void 0 : o(i)) !== !0 && s(`command not found: ${i.split(" ")[0]}`);
1271
764
  },
1272
- s.id
1273
- ))
765
+ onClose: () => a(!1)
766
+ }
767
+ ) : null;
768
+ };
769
+ class wt {
770
+ constructor() {
771
+ H(this, "components", /* @__PURE__ */ new Map());
1274
772
  }
1275
- ), we = (o, e = 0) => o.reduce((n, r) => (n.push({ ...r, level: e }), r.isOpen && r.children && n.push(...we(r.children, e + 1)), n), []), Gt = ({
1276
- data: o,
1277
- onToggle: e,
1278
- onActivate: n,
1279
- onMoveNode: r,
1280
- actions: a,
1281
- onNewFile: s,
1282
- onNewFolder: l,
1283
- onRename: u,
1284
- onDelete: i,
1285
- indent: d = 12,
1286
- virtualized: p = !0,
1287
- className: g
1288
- }) => {
1289
- const [m, w] = O(null), [C, x] = O(null), h = j(() => we(o), [o]);
1290
- z(() => {
1291
- x(null);
1292
- }, [o]);
1293
- const N = (a ?? [
773
+ /**
774
+ * Register a component with a unique ID.
775
+ * This ID is what you use in your FlexLayout models.
776
+ */
777
+ register(e, n) {
778
+ this.components.has(e) && console.warn(`Component with ID "${e}" is already registered.`), this.components.set(e, n);
779
+ }
780
+ /**
781
+ * Retrieve a registered component by its ID.
782
+ */
783
+ get(e) {
784
+ return this.components.get(e);
785
+ }
786
+ /**
787
+ * Get all registered component IDs.
788
+ */
789
+ getRegisteredIds() {
790
+ return Array.from(this.components.keys());
791
+ }
792
+ }
793
+ const Nt = new wt(), _ = {
794
+ global: { tabEnableClose: !0, tabSetEnableMaximize: !1, tabSetEnableDivide: !0 },
795
+ borders: [
1294
796
  {
1295
- id: "new-file",
1296
- label: "New File",
1297
- icon: /* @__PURE__ */ t(je, { size: 14 }),
1298
- onSelect: ({ nodeId: f }) => s == null ? void 0 : s(f)
797
+ type: "border",
798
+ location: "left",
799
+ children: []
800
+ }
801
+ ],
802
+ layout: {
803
+ type: "row",
804
+ weight: 100,
805
+ children: [
806
+ {
807
+ type: "tabset",
808
+ weight: 50,
809
+ children: [
810
+ {
811
+ type: "tab",
812
+ name: "Welcome",
813
+ component: "welcome"
814
+ }
815
+ ]
816
+ }
817
+ ]
818
+ }
819
+ }, fe = "nexus-shell-layout", kt = U((o, e) => {
820
+ let n;
821
+ if (typeof window < "u")
822
+ try {
823
+ const t = localStorage.getItem(fe);
824
+ if (t) {
825
+ const a = JSON.parse(t);
826
+ n = $.fromJson(a);
827
+ const s = /* @__PURE__ */ new Set(["dialogue-library", "argument-inspector"]), l = [];
828
+ n.visitNodes((u) => {
829
+ if (u.getType() === "tab") {
830
+ const i = u;
831
+ s.has(i.getComponent()) && l.push(i.getId());
832
+ }
833
+ }), l.forEach((u) => {
834
+ n.doAction(G.deleteTab(u));
835
+ });
836
+ } else
837
+ n = $.fromJson(_);
838
+ } catch (t) {
839
+ console.warn("Failed to load layout from storage, using default", t), n = $.fromJson(_);
840
+ }
841
+ else
842
+ n = $.fromJson(_);
843
+ return {
844
+ model: n,
845
+ dirtyTabs: /* @__PURE__ */ new Set(),
846
+ storageKey: fe,
847
+ disableLocalStorage: !1,
848
+ initLayout: (t, a) => {
849
+ let s;
850
+ if (t && Object.keys(t).length > 0)
851
+ try {
852
+ s = $.fromJson(t);
853
+ } catch (l) {
854
+ console.warn("Failed to parse init layout json, using default", l), s = $.fromJson(_);
855
+ }
856
+ else
857
+ s = $.fromJson(_);
858
+ o({ model: s, disableLocalStorage: a || !1 });
1299
859
  },
1300
- {
1301
- id: "new-folder",
1302
- label: "New Folder",
1303
- icon: /* @__PURE__ */ t(Fe, { size: 14 }),
1304
- onSelect: ({ nodeId: f }) => l == null ? void 0 : l(f)
860
+ setModel: (t) => {
861
+ o({ model: t });
862
+ const a = e().storageKey;
863
+ if (typeof window < "u" && !e().disableLocalStorage)
864
+ try {
865
+ localStorage.setItem(a, JSON.stringify(t.toJson()));
866
+ } catch (s) {
867
+ console.error("Failed to save layout to storage", s);
868
+ }
1305
869
  },
1306
- {
1307
- id: "rename",
1308
- label: "Rename",
1309
- icon: /* @__PURE__ */ t(Ue, { size: 14 }),
1310
- divider: !0,
1311
- showFor: ["file", "folder"],
1312
- onSelect: ({ nodeId: f }) => f && (u == null ? void 0 : u(f))
870
+ setStorageKey: (t, a) => {
871
+ let s;
872
+ if (typeof window < "u")
873
+ try {
874
+ const l = localStorage.getItem(t);
875
+ l ? s = $.fromJson(JSON.parse(l)) : s = $.fromJson(a || _);
876
+ } catch (l) {
877
+ console.warn("Failed to load layout from storage for key", t, l), s = $.fromJson(a || _);
878
+ }
879
+ else
880
+ s = $.fromJson(a || _);
881
+ o({ storageKey: t, model: s });
1313
882
  },
1314
- {
1315
- id: "delete",
1316
- label: "Delete",
1317
- icon: /* @__PURE__ */ t(_e, { size: 14, className: "text-destructive" }),
1318
- showFor: ["file", "folder"],
1319
- onSelect: ({ nodeId: f }) => f && (i == null ? void 0 : i(f))
883
+ setTabDirty: (t, a) => {
884
+ o((s) => {
885
+ const l = new Set(s.dirtyTabs);
886
+ return a ? l.add(t) : l.delete(t), { dirtyTabs: l };
887
+ });
888
+ },
889
+ isTabDirty: (t) => e().dirtyTabs.has(t),
890
+ addTab: (t, a, s) => {
891
+ const l = e().model, u = l.getActiveTabset();
892
+ let i = u == null ? void 0 : u.getId();
893
+ if (!i)
894
+ try {
895
+ const p = l.getFirstTabSet();
896
+ i = p == null ? void 0 : p.getId();
897
+ } catch (p) {
898
+ console.warn("Failed to get first tabset fallback", p);
899
+ }
900
+ const f = { ...{}, ...s };
901
+ if (["nexus-dashboard", "nexus-docs"].includes(t)) {
902
+ let p = null;
903
+ if (l.visitNodes((m) => {
904
+ if (m.getType() === "tab") {
905
+ const k = m;
906
+ k.getComponent() === t && (p = k.getId());
907
+ }
908
+ }), p) {
909
+ l.doAction(G.selectTab(p));
910
+ return;
911
+ }
912
+ }
913
+ if (f.mapId) {
914
+ let p = null;
915
+ if (l.visitNodes((m) => {
916
+ var k;
917
+ if (m.getType() === "tab") {
918
+ const C = m;
919
+ ((k = C.getConfig()) == null ? void 0 : k.mapId) === f.mapId && (p = C.getId());
920
+ }
921
+ }), p) {
922
+ l.doAction(G.selectTab(p));
923
+ return;
924
+ }
925
+ }
926
+ if (f.projectId) {
927
+ let p = null;
928
+ if (l.visitNodes((m) => {
929
+ var k;
930
+ if (m.getType() === "tab") {
931
+ const C = m;
932
+ ((k = C.getConfig()) == null ? void 0 : k.projectId) === f.projectId && (p = C.getId());
933
+ }
934
+ }), p) {
935
+ l.doAction(G.selectTab(p));
936
+ return;
937
+ }
938
+ }
939
+ i && l.doAction(
940
+ G.addNode(
941
+ { type: "tab", component: t, name: a || t, config: f },
942
+ i,
943
+ Oe.CENTER,
944
+ -1
945
+ )
946
+ );
1320
947
  }
1321
- ]).filter(
1322
- (f) => !f.showFor || m && f.showFor.includes(m.scope)
1323
- ).map((f) => ({
1324
- label: f.label,
1325
- icon: f.icon,
1326
- divider: f.divider,
1327
- onClick: () => m && f.onSelect(m.context)
1328
- })), b = (f, E, L) => {
1329
- f.preventDefault(), f.stopPropagation(), w({
1330
- x: f.clientX,
1331
- y: f.clientY,
1332
- scope: L,
1333
- context: { nodeId: (E == null ? void 0 : E.id) ?? null, node: E }
948
+ };
949
+ }), Te = U((o, e) => ({
950
+ isOpen: !1,
951
+ type: "alert",
952
+ title: "",
953
+ message: "",
954
+ defaultValue: "",
955
+ resolve: null,
956
+ openAlert: (n, t = "Alert") => new Promise((a) => {
957
+ o({ isOpen: !0, type: "alert", title: t, message: n, defaultValue: "", resolve: a });
958
+ }),
959
+ openConfirm: (n, t = "Confirm") => new Promise((a) => {
960
+ o({ isOpen: !0, type: "confirm", title: t, message: n, defaultValue: "", resolve: a });
961
+ }),
962
+ openPrompt: (n, t = "", a = "Prompt") => new Promise((s) => {
963
+ o({ isOpen: !0, type: "prompt", title: a, message: n, defaultValue: t, resolve: s });
964
+ }),
965
+ close: (n = null) => {
966
+ const { resolve: t } = e();
967
+ t && t(n), o({ isOpen: !1, resolve: null });
968
+ }
969
+ })), Gt = ({
970
+ panels: o,
971
+ slashCommands: e,
972
+ menuConfig: n,
973
+ statusBarConfig: t,
974
+ title: a,
975
+ rightMenuBarContent: s,
976
+ centerMenuBarContent: l,
977
+ layoutModel: u,
978
+ initialLayoutJson: i,
979
+ disableLocalStorage: d = !1,
980
+ onLayoutChange: f
981
+ }) => {
982
+ const { model: p, setModel: m, initLayout: k, isTabDirty: C, setTabDirty: x } = kt(), h = Y((b) => b.theme), T = F((b) => b.setPanels), I = Q((b) => b.setSlashCommands), N = ie((b) => b.setWidgets);
983
+ z(() => {
984
+ o && T(o);
985
+ }, [o, T]), z(() => {
986
+ e && I(e);
987
+ }, [e, I]), z(() => {
988
+ n && le.setMenus(n);
989
+ }, [n]), z(() => {
990
+ t && N(t);
991
+ }, [t, N]), z(() => {
992
+ u || !i && !d || k(i, d);
993
+ }, []);
994
+ const y = (b) => {
995
+ try {
996
+ const E = b.getComponent(), w = b.getConfig() || {}, L = E ? Nt.get(E) : void 0;
997
+ return L ? /* @__PURE__ */ r(L, { node: b, ...w }) : /* @__PURE__ */ c("div", { className: "p-4 text-sm", children: [
998
+ "Unknown Component: ",
999
+ E
1000
+ ] });
1001
+ } catch (E) {
1002
+ return console.error("Error in component factory:", E), /* @__PURE__ */ c("div", { className: "p-8 text-destructive bg-destructive/10 border border-destructive/20 h-full flex items-center justify-center", children: [
1003
+ "Error rendering component: ",
1004
+ E instanceof Error ? E.message : "Unknown error"
1005
+ ] });
1006
+ }
1007
+ }, g = (b) => {
1008
+ if (b.type !== G.DELETE_TAB) return b;
1009
+ const E = p.getNodeById(b.data.node);
1010
+ if (!E || !C(E.getId())) return b;
1011
+ Te.getState().openConfirm(
1012
+ `Tab "${E.getName()}" has unsaved changes. Are you sure you want to close it?`
1013
+ ).then((w) => {
1014
+ w && (x(E.getId(), !1), p.doAction(b));
1334
1015
  });
1335
- }, v = (f) => {
1336
- const E = h[f], L = E.type === "folder";
1337
- return /* @__PURE__ */ c(
1338
- "div",
1339
- {
1340
- role: "treeitem",
1341
- "aria-expanded": L ? !!E.isOpen : void 0,
1342
- "aria-level": E.level + 1,
1343
- tabIndex: 0,
1344
- draggable: !0,
1345
- onDragStart: (k) => {
1346
- k.dataTransfer.setData("text/plain", E.id), k.dataTransfer.effectAllowed = "move";
1347
- },
1348
- onDragOver: (k) => {
1349
- L && (k.preventDefault(), x(E.id));
1350
- },
1351
- onDragLeave: () => x(null),
1352
- onDrop: (k) => {
1353
- k.preventDefault(), x(null);
1354
- const A = k.dataTransfer.getData("text/plain");
1355
- A && A !== E.id && L && (r == null || r(A, E.id));
1356
- },
1357
- onClick: () => L && (e == null ? void 0 : e(E)),
1358
- onDoubleClick: () => n == null ? void 0 : n(E),
1359
- onKeyDown: (k) => {
1360
- k.key === "Enter" && (k.preventDefault(), L ? e == null || e(E) : n == null || n(E));
1361
- },
1362
- onContextMenu: (k) => b(k, E, E.type),
1363
- style: { paddingLeft: `${E.level * d + 8}px` },
1364
- className: S(
1365
- "flex items-center py-1 px-2 cursor-pointer hover:bg-accent hover:text-accent-foreground select-none text-xs",
1366
- "transition-colors duration-150 relative focus:outline-none focus:ring-1 focus:ring-ring",
1367
- C === E.id && "bg-primary/20 ring-1 ring-primary/50 rounded-sm"
1368
- ),
1369
- children: [
1370
- /* @__PURE__ */ t("div", { className: "w-4 h-4 mr-1 flex items-center justify-center", children: L && (E.isOpen ? /* @__PURE__ */ t(ve, { size: 14 }) : /* @__PURE__ */ t(ye, { size: 14 })) }),
1371
- /* @__PURE__ */ t("div", { className: "mr-2", children: L ? /* @__PURE__ */ t(Je, { size: 14, className: "text-blue-400 fill-blue-400/20" }) : /* @__PURE__ */ t(He, { size: 14, className: "text-muted-foreground" }) }),
1372
- /* @__PURE__ */ t("span", { className: "truncate", children: E.label })
1373
- ]
1374
- },
1375
- E.id
1376
- );
1377
1016
  };
1378
1017
  return /* @__PURE__ */ c(
1379
1018
  "div",
1380
1019
  {
1381
- role: "tree",
1382
- className: S("h-full w-full bg-muted/30", g),
1383
- onContextMenu: (f) => b(f, null, "background"),
1020
+ className: `flex flex-col h-screen w-screen bg-background text-foreground overflow-hidden theme-${h}`,
1384
1021
  children: [
1385
- p ? /* @__PURE__ */ t(
1386
- Qe,
1387
- {
1388
- style: { height: "100%" },
1389
- totalCount: h.length,
1390
- itemContent: v
1391
- }
1392
- ) : /* @__PURE__ */ t("div", { className: "h-full overflow-auto", children: h.map((f, E) => v(E)) }),
1393
- m && N.length > 0 && /* @__PURE__ */ t(
1394
- at,
1022
+ /* @__PURE__ */ r(
1023
+ mt,
1395
1024
  {
1396
- x: m.x,
1397
- y: m.y,
1398
- items: N,
1399
- onClose: () => w(null)
1025
+ title: a,
1026
+ center: l,
1027
+ right: s
1400
1028
  }
1401
- )
1029
+ ),
1030
+ /* @__PURE__ */ c("div", { className: "flex-1 flex overflow-hidden", children: [
1031
+ /* @__PURE__ */ r(nt, {}),
1032
+ /* @__PURE__ */ r(gt, {}),
1033
+ /* @__PURE__ */ c("div", { className: "flex-1 flex flex-col min-w-0 bg-card", children: [
1034
+ /* @__PURE__ */ r("div", { className: "flex-1 relative h-full w-full", children: /* @__PURE__ */ r(
1035
+ ze,
1036
+ {
1037
+ model: u || p,
1038
+ factory: y,
1039
+ onModelChange: (b) => {
1040
+ u || m(b), f == null || f(b.toJson());
1041
+ },
1042
+ onAction: g
1043
+ }
1044
+ ) }),
1045
+ /* @__PURE__ */ r(yt, {})
1046
+ ] }),
1047
+ /* @__PURE__ */ r(it, {})
1048
+ ] }),
1049
+ /* @__PURE__ */ r(bt, {})
1402
1050
  ]
1403
1051
  }
1404
1052
  );
1405
- }, bt = ({
1406
- profile: o,
1407
- actions: e = [],
1408
- onProfileChange: n,
1409
- onAvatarChange: r,
1410
- onClick: a,
1411
- showName: s = !0,
1412
- className: l
1413
- }) => {
1414
- const { name: u, role: i, email: d, avatarUrl: p } = o, [g, m] = O(!1), [w, C] = O(!1), [x, h] = O(u), [T, N] = O(i ?? ""), b = M(null), v = M(null);
1415
- z(() => {
1416
- g && (h(u), N(i ?? ""), C(!1));
1417
- }, [g, u, i]), z(() => {
1418
- if (!g) return;
1419
- const k = (A) => {
1420
- b.current && !b.current.contains(A.target) && m(!1);
1421
- };
1422
- return document.addEventListener("mousedown", k), () => document.removeEventListener("mousedown", k);
1423
- }, [g]);
1424
- const f = (k) => {
1425
- k.preventDefault(), n == null || n({ name: x, role: T }), C(!1);
1426
- }, E = (k) => {
1427
- var y;
1428
- const A = (y = k.target.files) == null ? void 0 : y[0];
1429
- A && (r == null || r(A)), k.target.value = "";
1430
- }, L = (k) => p ? /* @__PURE__ */ t("img", { src: p, alt: u, className: "w-full h-full object-cover" }) : /* @__PURE__ */ t(ge, { size: k, className: "text-muted-foreground" });
1431
- return /* @__PURE__ */ c("div", { ref: b, className: "relative inline-block text-left", children: [
1432
- /* @__PURE__ */ c(
1433
- "button",
1434
- {
1435
- type: "button",
1436
- onClick: () => a ? a() : m((k) => !k),
1437
- "aria-haspopup": a ? void 0 : "menu",
1438
- "aria-expanded": a ? void 0 : g,
1439
- "aria-label": "User Profile Menu",
1440
- className: S(
1441
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none transition-all duration-200 select-none",
1442
- s ? "flex items-center space-x-2 px-2 py-1 rounded-md hover:bg-accent/50 hover:text-accent-foreground text-left cursor-pointer border border-transparent hover:border-border/30" : "w-7 h-7 rounded-full bg-secondary/80 border border-border flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-secondary cursor-pointer",
1443
- g && (s ? "bg-accent/60 border-border/40" : "border-primary/50 text-foreground ring-1 ring-primary/20"),
1444
- l
1445
- ),
1446
- children: [
1447
- /* @__PURE__ */ t(
1448
- "div",
1449
- {
1450
- className: S(
1451
- "rounded-full overflow-hidden border border-border/50 bg-muted flex items-center justify-center shrink-0 shadow-sm",
1452
- s ? "w-6 h-6" : "w-full h-full"
1453
- ),
1454
- children: L(s ? 13 : 12)
1455
- }
1456
- ),
1457
- s && /* @__PURE__ */ c("div", { className: "flex flex-col min-w-0 leading-tight pr-1", children: [
1458
- /* @__PURE__ */ t("span", { className: "text-[11px] font-semibold truncate text-foreground", children: u }),
1459
- i && /* @__PURE__ */ t("span", { className: "text-[9px] text-muted-foreground/80 truncate font-medium", children: i })
1460
- ] })
1461
- ]
1462
- }
1463
- ),
1464
- r && /* @__PURE__ */ t(
1465
- "input",
1466
- {
1467
- type: "file",
1468
- ref: v,
1469
- onChange: E,
1470
- accept: "image/*",
1471
- "aria-label": "Upload avatar",
1472
- className: "hidden"
1473
- }
1474
- ),
1475
- g && /* @__PURE__ */ t(
1476
- "div",
1477
- {
1478
- role: "menu",
1479
- className: S(
1480
- "absolute z-50 w-64 rounded-lg border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-md p-2 flex flex-col gap-1 mt-1.5 animate-in fade-in slide-in-from-top-2 duration-150 origin-top-right",
1481
- s ? "left-0" : "right-0"
1482
- ),
1483
- children: w ? /* @__PURE__ */ c("form", { onSubmit: f, className: "p-2 flex flex-col gap-2", children: [
1484
- /* @__PURE__ */ t("span", { className: "text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: "Edit Profile" }),
1485
- /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: [
1486
- /* @__PURE__ */ t("label", { htmlFor: "profile-name", className: "text-[9px] font-semibold text-muted-foreground", children: "Name" }),
1487
- /* @__PURE__ */ t(
1488
- "input",
1489
- {
1490
- id: "profile-name",
1491
- type: "text",
1492
- value: x,
1493
- onChange: (k) => h(k.target.value),
1494
- required: !0,
1495
- className: "w-full px-2 py-1 text-xs border rounded bg-background focus:ring-1 focus:ring-primary focus:outline-none"
1496
- }
1497
- )
1498
- ] }),
1499
- /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: [
1500
- /* @__PURE__ */ t("label", { htmlFor: "profile-role", className: "text-[9px] font-semibold text-muted-foreground", children: "Role" }),
1501
- /* @__PURE__ */ t(
1502
- "input",
1503
- {
1504
- id: "profile-role",
1505
- type: "text",
1506
- value: T,
1507
- onChange: (k) => N(k.target.value),
1508
- className: "w-full px-2 py-1 text-xs border rounded bg-background focus:ring-1 focus:ring-primary focus:outline-none"
1509
- }
1510
- )
1511
- ] }),
1512
- /* @__PURE__ */ c("div", { className: "flex gap-1.5 mt-1 justify-end", children: [
1513
- /* @__PURE__ */ c(
1514
- "button",
1515
- {
1516
- type: "button",
1517
- onClick: () => C(!1),
1518
- className: "px-2 py-1 text-[10px] rounded hover:bg-accent text-muted-foreground flex items-center gap-1 border border-border/30",
1519
- children: [
1520
- /* @__PURE__ */ t(_, { size: 10 }),
1521
- " Cancel"
1522
- ]
1523
- }
1524
- ),
1525
- /* @__PURE__ */ c(
1526
- "button",
1527
- {
1528
- type: "submit",
1529
- className: "px-2 py-1 text-[10px] rounded bg-primary text-primary-foreground hover:bg-primary/95 flex items-center gap-1 font-semibold",
1530
- children: [
1531
- /* @__PURE__ */ t(We, { size: 10 }),
1532
- " Save"
1533
- ]
1534
- }
1535
- )
1536
- ] })
1537
- ] }) : /* @__PURE__ */ c(fe, { children: [
1538
- /* @__PURE__ */ c("div", { className: "p-2 flex items-center gap-3 border-b border-border/40 pb-2.5 mb-1", children: [
1539
- /* @__PURE__ */ c(
1540
- "div",
1541
- {
1542
- onClick: () => {
1543
- var k;
1544
- return r && ((k = v.current) == null ? void 0 : k.click());
1545
- },
1546
- title: r ? "Upload avatar image" : void 0,
1547
- className: S(
1548
- "group relative w-12 h-12 rounded-full overflow-hidden border border-border/80 bg-muted flex items-center justify-center shrink-0 shadow-inner",
1549
- r && "cursor-pointer"
1550
- ),
1551
- children: [
1552
- L(24),
1553
- r && /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity", children: /* @__PURE__ */ t(Be, { size: 14, className: "text-white" }) })
1554
- ]
1555
- }
1556
- ),
1557
- /* @__PURE__ */ c("div", { className: "flex flex-col min-w-0 leading-normal flex-1", children: [
1558
- /* @__PURE__ */ c("div", { className: "flex items-center gap-1", children: [
1559
- /* @__PURE__ */ t("span", { className: "text-xs font-bold truncate text-foreground", children: u }),
1560
- n && /* @__PURE__ */ t(
1561
- "button",
1562
- {
1563
- type: "button",
1564
- onClick: () => C(!0),
1565
- title: "Edit Profile",
1566
- "aria-label": "Edit Profile",
1567
- className: "p-1 text-muted-foreground hover:text-foreground hover:bg-accent/40 rounded transition-colors",
1568
- children: /* @__PURE__ */ t(Ge, { size: 10 })
1569
- }
1570
- )
1571
- ] }),
1572
- i && /* @__PURE__ */ t("span", { className: "text-[10px] text-muted-foreground/80 truncate font-semibold", children: i }),
1573
- d && /* @__PURE__ */ t("span", { className: "text-[9px] text-muted-foreground/60 truncate font-mono mt-0.5", children: d })
1574
- ] })
1575
- ] }),
1576
- e.map((k) => {
1577
- const A = k.icon;
1578
- return /* @__PURE__ */ c(
1579
- "button",
1580
- {
1581
- type: "button",
1582
- role: "menuitem",
1583
- onClick: () => {
1584
- k.onSelect(), m(!1);
1585
- },
1586
- className: S(
1587
- "w-full px-2 py-1.5 text-left rounded-md text-[11px] font-medium flex items-center gap-2 cursor-pointer transition-colors",
1588
- k.destructive ? "text-destructive hover:bg-destructive/10" : "hover:bg-accent/60 hover:text-accent-foreground",
1589
- k.divider && "border-t border-border/20 pt-2 mt-1"
1590
- ),
1591
- children: [
1592
- A && /* @__PURE__ */ t(A, { size: 12, className: "opacity-70" }),
1593
- k.label
1594
- ]
1595
- },
1596
- k.id
1597
- );
1598
- })
1599
- ] })
1600
- }
1601
- )
1602
- ] });
1603
- }, Yt = ({ title: o, subtitle: e, icon: n, className: r }) => /* @__PURE__ */ c("div", { className: S("flex items-center space-x-3 select-none", r), children: [
1604
- n && /* @__PURE__ */ t("div", { className: "w-8 h-8 rounded-lg bg-primary/10 border border-primary/30 flex items-center justify-center text-primary shadow-inner shrink-0", children: n }),
1605
- /* @__PURE__ */ c("div", { className: "min-w-0", children: [
1606
- /* @__PURE__ */ t("h1", { className: "text-xs font-black uppercase tracking-wider text-foreground font-mono truncate", children: o }),
1607
- e && /* @__PURE__ */ t("p", { className: "text-[9px] text-muted-foreground font-semibold truncate", children: e })
1608
- ] })
1609
- ] }), G = "nexus-shell-sidebar", W = F((o) => {
1610
- const e = localStorage.getItem(G);
1611
- return {
1612
- activeSidebar: e !== null ? e : null,
1613
- panels: [],
1614
- setActiveSidebar: (r) => {
1615
- r === null ? localStorage.removeItem(G) : localStorage.setItem(G, r), o({ activeSidebar: r });
1616
- },
1617
- toggleSidebar: (r) => o((a) => {
1618
- const s = a.activeSidebar === r ? null : r;
1619
- return s === null ? localStorage.removeItem(G) : localStorage.setItem(G, s), { activeSidebar: s };
1620
- }),
1621
- setPanels: (r) => o({ panels: r })
1622
- };
1623
- }), xt = (o) => {
1624
- const e = W((s) => s.panels), n = W((s) => s.activeSidebar), r = W((s) => s.toggleSidebar), a = j(
1625
- () => e.map(({ id: s, label: l, icon: u }) => ({ id: s, label: l, icon: u })),
1626
- [e]
1627
- );
1628
- return /* @__PURE__ */ t(
1629
- tt,
1630
- {
1631
- ...o,
1632
- items: a,
1633
- activeId: n,
1634
- onSelect: r
1053
+ }, Vt = [
1054
+ "view.toggleTerminal",
1055
+ "view.toggleChat",
1056
+ "view.toggleSidebar",
1057
+ "theme.light",
1058
+ "theme.dark",
1059
+ "theme.gt"
1060
+ ], oe = (o) => () => Y.getState().setTheme(o), Ct = [
1061
+ {
1062
+ id: "view.toggleTerminal",
1063
+ label: "View: Toggle Terminal",
1064
+ keybinding: "Control+`",
1065
+ execute: () => V.getState().toggle()
1066
+ },
1067
+ {
1068
+ id: "view.toggleChat",
1069
+ label: "View: Toggle Chat",
1070
+ execute: () => ae.getState().toggleChat()
1071
+ },
1072
+ {
1073
+ id: "view.toggleSidebar",
1074
+ label: "View: Toggle Sidebar",
1075
+ keybinding: "Control+b",
1076
+ execute: () => {
1077
+ var t;
1078
+ const { activeSidebar: o, panels: e, setActiveSidebar: n } = F.getState();
1079
+ n(o ? null : ((t = e[0]) == null ? void 0 : t.id) ?? null);
1635
1080
  }
1636
- );
1637
- };
1638
- let vt = 0;
1639
- const yt = () => `msg-${Date.now()}-${vt += 1}`, Q = F((o) => ({
1640
- messages: [],
1641
- slashCommands: [],
1642
- setMessages: (e) => o({ messages: e }),
1643
- addMessage: (e) => o((n) => ({
1644
- messages: [...n.messages, { ...e, id: e.id ?? yt() }]
1645
- })),
1646
- clearMessages: () => o({ messages: [] }),
1647
- setSlashCommands: (e) => o({ slashCommands: e }),
1648
- registerSlashCommand: (e) => o((n) => ({ slashCommands: [...n.slashCommands, e] }))
1649
- })), ne = "nexus-shell-right-sidebar", le = F((o) => ({
1650
- isChatOpen: localStorage.getItem(ne) === "true",
1651
- setChatOpen: (r) => {
1652
- localStorage.setItem(ne, String(r)), o({ isChatOpen: r });
1653
1081
  },
1654
- toggleChat: () => o((r) => {
1655
- const a = !r.isChatOpen;
1656
- return localStorage.setItem(ne, String(a)), { isChatOpen: a };
1657
- })
1658
- })), wt = ({ onSend: o, ...e }) => {
1659
- const n = le((i) => i.isChatOpen), r = le((i) => i.setChatOpen), a = Q((i) => i.messages), s = Q((i) => i.slashCommands), l = Q((i) => i.addMessage);
1660
- return n ? /* @__PURE__ */ t(
1661
- nt,
1082
+ { id: "theme.light", label: "Preferences: Light Theme", execute: oe("light") },
1083
+ { id: "theme.dark", label: "Preferences: Dark Theme", execute: oe("dark") },
1084
+ { id: "theme.gt", label: "Preferences: Georgia Tech Theme", execute: oe("gt") }
1085
+ ], St = {
1086
+ View: [
1087
+ { id: "view.terminal", label: "Toggle Terminal", commandId: "view.toggleTerminal" },
1088
+ { id: "view.chat", label: "Toggle Chat", commandId: "view.toggleChat" },
1089
+ { id: "view.sidebar", label: "Toggle Sidebar", commandId: "view.toggleSidebar" },
1662
1090
  {
1663
- ...e,
1664
- messages: a,
1665
- slashCommands: s,
1666
- onSend: (i) => {
1667
- if (l({ role: "user", text: i }), i.startsWith("/")) {
1668
- const [d, ...p] = i.slice(1).split(/\s+/), g = s.find((m) => m.command === d);
1669
- if (g) {
1670
- g.execute(p);
1671
- return;
1672
- }
1673
- l({ role: "assistant", text: `Unknown command: /${d}` });
1674
- return;
1675
- }
1676
- o == null || o(i);
1677
- },
1678
- onClose: () => r(!1)
1091
+ id: "view.theme",
1092
+ label: "Theme",
1093
+ submenu: [
1094
+ { id: "view.theme.light", label: "Light", commandId: "theme.light" },
1095
+ { id: "view.theme.dark", label: "Dark", commandId: "theme.dark" },
1096
+ { id: "view.theme.gt", label: "Georgia Tech", commandId: "theme.gt" }
1097
+ ]
1679
1098
  }
1680
- ) : null;
1099
+ ]
1100
+ }, Yt = (o = {}) => {
1101
+ const {
1102
+ panels: e,
1103
+ menus: n,
1104
+ commands: t,
1105
+ statusBar: a,
1106
+ slashCommands: s,
1107
+ defaultCommands: l = !0,
1108
+ defaultMenus: u = !0
1109
+ } = o;
1110
+ l && Ct.forEach((d) => B.registerCommand(d)), t == null || t.forEach((d) => B.registerCommand(d));
1111
+ const i = {
1112
+ ...l && u ? St : {},
1113
+ ...n ?? {}
1114
+ };
1115
+ Object.keys(i).length > 0 && le.setMenus(i), e && F.getState().setPanels(e), a && ie.getState().setWidgets(a), s && Q.getState().setSlashCommands(s);
1681
1116
  };
1682
- class Nt {
1117
+ class Tt {
1683
1118
  constructor() {
1684
- J(this, "menus", /* @__PURE__ */ new Map());
1119
+ H(this, "plugins", /* @__PURE__ */ new Map());
1120
+ H(this, "loaders", /* @__PURE__ */ new Map());
1121
+ H(this, "statuses", /* @__PURE__ */ new Map());
1685
1122
  }
1686
- registerMenu(e, n) {
1687
- var r;
1688
- this.menus.has(e) || this.menus.set(e, []), (r = this.menus.get(e)) == null || r.push(n);
1689
- }
1690
- setMenus(e) {
1691
- this.menus = new Map(Object.entries(e));
1123
+ registerPlugin(e) {
1124
+ if (this.plugins.has(e.id)) {
1125
+ console.warn(`Plugin ${e.id} is already registered.`);
1126
+ return;
1127
+ }
1128
+ this.plugins.set(e.id, e), this.statuses.set(e.id, "registered"), console.log(`Plugin ${e.name} (${e.id}) registered.`);
1692
1129
  }
1693
- getMenu(e) {
1694
- return this.menus.get(e) || [];
1130
+ registerLazyPlugin(e, n) {
1131
+ if (this.loaders.has(e) || this.plugins.has(e)) {
1132
+ console.warn(`Plugin ${e} is already registered or has a loader.`);
1133
+ return;
1134
+ }
1135
+ this.loaders.set(e, n), this.statuses.set(e, "inactive"), console.log(`Lazy plugin loader for ${e} registered.`);
1695
1136
  }
1696
- getAllMenus() {
1697
- const e = {};
1698
- return this.menus.forEach((n, r) => {
1699
- e[r] = n;
1700
- }), e;
1137
+ async activatePlugin(e) {
1138
+ let n = this.plugins.get(e);
1139
+ if (!n && this.loaders.has(e))
1140
+ try {
1141
+ n = await this.loaders.get(e)(), this.plugins.set(e, n), this.statuses.set(e, "registered"), console.log(`Lazy plugin ${e} loaded.`);
1142
+ } catch (t) {
1143
+ console.error(`Failed to load lazy plugin ${e}`, t), this.statuses.set(e, "failed");
1144
+ return;
1145
+ }
1146
+ if (n)
1147
+ try {
1148
+ this.statuses.set(e, "activating"), n.activate(), this.statuses.set(e, "active"), console.log(`Plugin ${n.name} activated.`);
1149
+ } catch (t) {
1150
+ console.error(`Failed to activate plugin ${e}`, t), this.statuses.set(e, "failed");
1151
+ }
1152
+ else
1153
+ console.warn(`Plugin ${e} not found for activation.`), this.statuses.set(e, "failed");
1701
1154
  }
1702
- }
1703
- const Ne = new Nt();
1704
- class kt {
1705
- constructor() {
1706
- J(this, "commands", /* @__PURE__ */ new Map());
1155
+ async deactivatePlugin(e) {
1156
+ const n = this.plugins.get(e);
1157
+ if (n)
1158
+ try {
1159
+ n.deactivate(), this.statuses.set(e, "deactivated"), console.log(`Plugin ${n.name} deactivated.`);
1160
+ } catch (t) {
1161
+ console.error(`Failed to deactivate plugin ${e}`, t), this.statuses.set(e, "failed");
1162
+ }
1707
1163
  }
1708
- registerCommand(e) {
1709
- if (this.commands.has(e.id)) {
1710
- console.warn(`Command ${e.id} is already registered.`);
1711
- return;
1712
- }
1713
- this.commands.set(e.id, e);
1164
+ getPluginStatus(e) {
1165
+ return this.statuses.get(e);
1714
1166
  }
1715
- executeCommand(e, ...n) {
1716
- const r = this.commands.get(e);
1717
- r ? r.execute(...n) : console.warn(`Command ${e} not found.`);
1167
+ getPluginStatuses() {
1168
+ const e = {};
1169
+ return this.statuses.forEach((n, t) => {
1170
+ e[t] = n;
1171
+ }), e;
1718
1172
  }
1719
- getCommand(e) {
1720
- return this.commands.get(e);
1173
+ getPlugin(e) {
1174
+ return this.plugins.get(e);
1721
1175
  }
1722
- getCommands() {
1723
- return Array.from(this.commands.values());
1176
+ getAllPlugins() {
1177
+ return Array.from(this.plugins.values());
1724
1178
  }
1725
1179
  }
1726
- const V = new kt(), ke = (o) => o.map((e) => {
1727
- var n;
1728
- return {
1729
- ...e,
1730
- keybinding: e.keybinding ?? (e.commandId ? (n = V.getCommand(e.commandId)) == null ? void 0 : n.keybinding : void 0),
1731
- submenu: e.submenu ? ke(e.submenu) : void 0
1732
- };
1733
- }), Ce = (o, e) => {
1734
- for (const n of o) {
1735
- if (n.id === e) return n;
1736
- const r = n.submenu && Ce(n.submenu, e);
1737
- if (r) return r;
1738
- }
1739
- }, Ct = (o) => {
1740
- const e = Ne.getAllMenus(), n = Object.fromEntries(
1741
- Object.entries(e).map(([a, s]) => [a, ke(s)])
1742
- );
1743
- return /* @__PURE__ */ t(lt, { ...o, menus: n, onSelect: (a) => {
1744
- for (const s of Object.values(e)) {
1745
- const l = Ce(s, a.id);
1746
- if (l != null && l.commandId) {
1747
- V.executeCommand(l.commandId);
1748
- return;
1749
- }
1750
- }
1751
- } });
1752
- }, ie = "nexus-shell-theme", ce = (o) => {
1753
- const e = window.document.documentElement;
1754
- e.classList.remove("theme-light", "theme-dark", "theme-gt"), e.classList.add(`theme-${o}`);
1755
- }, q = F((o) => {
1756
- const n = localStorage.getItem(ie) || "light";
1757
- return ce(n), {
1758
- theme: n,
1759
- setTheme: (r) => {
1760
- localStorage.setItem(ie, r), ce(r), o({ theme: r });
1180
+ const qt = new Tt(), pe = "nexus-shell-user-profile", ge = {
1181
+ name: "David Tech",
1182
+ role: "Shell Architect",
1183
+ email: "david@techmuch.io",
1184
+ avatarUrl: "",
1185
+ customAvatar: ""
1186
+ }, W = U((o) => {
1187
+ let e = { ...ge };
1188
+ if (typeof window < "u")
1189
+ try {
1190
+ const t = localStorage.getItem(pe);
1191
+ t && (e = { ...ge, ...JSON.parse(t) });
1192
+ } catch (t) {
1193
+ console.error("Failed to parse saved user profile:", t);
1761
1194
  }
1762
- };
1763
- }), St = (o) => {
1764
- const e = W((d) => d.activeSidebar), n = W((d) => d.panels), r = W((d) => d.setActiveSidebar), a = q((d) => d.theme), s = q((d) => d.setTheme);
1765
- if (!e) return null;
1766
- const l = () => r(null);
1767
- if (e === "settings")
1768
- return /* @__PURE__ */ t(te, { ...o, title: "Settings", onClose: l, children: /* @__PURE__ */ t(
1769
- mt,
1770
- {
1771
- theme: a,
1772
- onThemeChange: (d) => s(d)
1195
+ const n = (t) => {
1196
+ if (typeof window < "u")
1197
+ try {
1198
+ localStorage.setItem(
1199
+ pe,
1200
+ JSON.stringify({
1201
+ name: t.name,
1202
+ role: t.role,
1203
+ email: t.email,
1204
+ avatarUrl: t.avatarUrl,
1205
+ customAvatar: t.customAvatar
1206
+ })
1207
+ );
1208
+ } catch (a) {
1209
+ console.error("Failed to save user profile:", a);
1773
1210
  }
1774
- ) });
1775
- const u = n.find((d) => d.id === e);
1776
- if (!u)
1777
- return /* @__PURE__ */ t(te, { ...o, title: e, onClose: l, children: /* @__PURE__ */ t("div", { className: "p-4 text-sm italic text-muted-foreground", children: "Panel content not found." }) });
1778
- const i = typeof u.component == "function" ? u.component : null;
1779
- return /* @__PURE__ */ t(te, { ...o, title: u.label, onClose: l, children: i ? /* @__PURE__ */ t(i, {}) : u.component });
1780
- }, Se = F((o) => ({
1781
- widgets: [],
1782
- setWidgets: (e) => o({ widgets: e }),
1783
- addWidget: (e) => o((n) => ({
1784
- widgets: [...n.widgets, e].sort(
1785
- (r, a) => (a.priority || 0) - (r.priority || 0)
1786
- )
1787
- })),
1788
- removeWidget: (e) => o((n) => ({
1789
- widgets: n.widgets.filter((r) => r.id !== e)
1790
- })),
1791
- updateWidget: (e, n) => o((r) => ({
1792
- widgets: r.widgets.map((a) => a.id === e ? { ...a, ...n } : a)
1793
- }))
1794
- })), Tt = (o) => {
1795
- const e = Se((r) => r.widgets), n = j(
1796
- () => e.map(({ commandId: r, ...a }) => ({
1797
- ...a,
1798
- onClick: a.onClick ?? (r ? () => V.executeCommand(r) : void 0)
1799
- })),
1800
- [e]
1211
+ };
1212
+ return {
1213
+ ...e,
1214
+ updateProfile: (t) => o((a) => {
1215
+ const s = { ...a, ...t };
1216
+ return n(s), t;
1217
+ }),
1218
+ setCustomAvatar: (t) => o((a) => {
1219
+ const s = { ...a, customAvatar: t };
1220
+ return n(s), { customAvatar: t };
1221
+ }),
1222
+ clearCustomAvatar: () => o((t) => {
1223
+ const a = { ...t, customAvatar: "" };
1224
+ return n(a), { customAvatar: "" };
1225
+ })
1226
+ };
1227
+ }), Qt = () => {
1228
+ z(() => {
1229
+ const o = (e) => {
1230
+ const n = B.getCommands();
1231
+ for (const t of n)
1232
+ if (t.keybinding && Dt(e, t.keybinding)) {
1233
+ e.preventDefault(), t.execute();
1234
+ break;
1235
+ }
1236
+ };
1237
+ return window.addEventListener("keydown", o), () => window.removeEventListener("keydown", o);
1238
+ }, []);
1239
+ };
1240
+ function Dt(o, e) {
1241
+ var m;
1242
+ const n = e.split("+"), t = (m = n.pop()) == null ? void 0 : m.toLowerCase(), a = n.includes("Control") || n.includes("Ctrl"), s = n.includes("Shift"), l = n.includes("Alt"), u = n.includes("Meta") || n.includes("Cmd"), i = o.ctrlKey, d = o.shiftKey, f = o.altKey, p = o.metaKey;
1243
+ return o.key.toLowerCase() === t && i === a && d === s && f === l && p === u;
1244
+ }
1245
+ const Et = (o, e) => {
1246
+ const n = e.toLowerCase();
1247
+ return o.label.toLowerCase().includes(n) || o.id.toLowerCase().includes(n);
1248
+ }, It = ({
1249
+ open: o,
1250
+ commands: e,
1251
+ onSelect: n,
1252
+ onClose: t,
1253
+ inline: a = !1,
1254
+ placeholder: s = "Type a command to run…",
1255
+ filter: l = Et,
1256
+ className: u
1257
+ }) => {
1258
+ const [i, d] = A(""), [f, p] = A(0), m = P(null), k = R(
1259
+ () => e.filter((x) => l(x, i)),
1260
+ [e, i, l]
1801
1261
  );
1802
- return /* @__PURE__ */ t(ft, { ...o, widgets: n });
1803
- }, Y = F((o) => ({
1804
- isOpen: !1,
1805
- history: ["Welcome to Nexus Shell Terminal v0.1.0", 'Type "help" for a list of commands.'],
1806
- setOpen: (e) => o({ isOpen: e }),
1807
- toggle: () => o((e) => ({ isOpen: !e.isOpen })),
1808
- addHistory: (e) => o((n) => ({ history: [...n.history, e] })),
1809
- clearHistory: () => o({ history: [] })
1810
- })), Et = [
1811
- "Available commands:",
1812
- " help — show this message",
1813
- " clear — clear the terminal"
1814
- ], Dt = ({
1815
- onCommand: o,
1262
+ if (z(() => {
1263
+ var x;
1264
+ o && (d(""), p(0), (x = m.current) == null || x.focus());
1265
+ }, [o]), z(() => {
1266
+ p(0);
1267
+ }, [i]), !o) return null;
1268
+ const C = (x) => {
1269
+ x.key === "ArrowDown" ? (x.preventDefault(), p((h) => k.length ? (h + 1) % k.length : 0)) : x.key === "ArrowUp" ? (x.preventDefault(), p(
1270
+ (h) => k.length ? (h - 1 + k.length) % k.length : 0
1271
+ )) : x.key === "Enter" ? (x.preventDefault(), k[f] && n(k[f])) : x.key === "Escape" && (x.preventDefault(), t == null || t());
1272
+ };
1273
+ return /* @__PURE__ */ r(
1274
+ "div",
1275
+ {
1276
+ onClick: a ? void 0 : t,
1277
+ className: S(
1278
+ "z-[100] flex items-start justify-center",
1279
+ a ? "relative w-full max-w-xl" : "fixed inset-0 pt-[10vh] bg-black/50 backdrop-blur-sm"
1280
+ ),
1281
+ children: /* @__PURE__ */ c(
1282
+ "div",
1283
+ {
1284
+ role: "dialog",
1285
+ "aria-modal": !a,
1286
+ "aria-label": "Command Palette",
1287
+ onClick: (x) => x.stopPropagation(),
1288
+ className: S(
1289
+ "w-full max-w-xl bg-popover text-popover-foreground border shadow-2xl rounded-xl overflow-hidden animate-in fade-in zoom-in duration-200",
1290
+ u
1291
+ ),
1292
+ children: [
1293
+ /* @__PURE__ */ c("div", { className: "flex items-center px-4 border-b", children: [
1294
+ /* @__PURE__ */ r(X, { size: 18, className: "text-muted-foreground mr-3" }),
1295
+ /* @__PURE__ */ r(
1296
+ "input",
1297
+ {
1298
+ ref: m,
1299
+ type: "text",
1300
+ role: "combobox",
1301
+ "aria-expanded": !0,
1302
+ "aria-controls": "command-palette-list",
1303
+ "aria-label": "Command",
1304
+ placeholder: s,
1305
+ value: i,
1306
+ onChange: (x) => d(x.target.value),
1307
+ onKeyDown: C,
1308
+ className: "flex-1 h-14 bg-transparent outline-none text-base text-foreground placeholder:text-muted-foreground"
1309
+ }
1310
+ )
1311
+ ] }),
1312
+ /* @__PURE__ */ r(
1313
+ "div",
1314
+ {
1315
+ id: "command-palette-list",
1316
+ role: "listbox",
1317
+ className: "max-h-[300px] overflow-y-auto py-2",
1318
+ children: k.length === 0 ? /* @__PURE__ */ r("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: i ? `No commands found matching "${i}"` : "No commands available." }) : k.map((x, h) => /* @__PURE__ */ c(
1319
+ "div",
1320
+ {
1321
+ role: "option",
1322
+ "aria-selected": h === f,
1323
+ onClick: () => n(x),
1324
+ onMouseEnter: () => p(h),
1325
+ className: S(
1326
+ "px-4 py-2 cursor-pointer flex justify-between items-center text-sm",
1327
+ h === f ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
1328
+ ),
1329
+ children: [
1330
+ /* @__PURE__ */ r("span", { children: x.label }),
1331
+ x.keybinding && /* @__PURE__ */ r("span", { className: "text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded border border-border/50", children: x.keybinding })
1332
+ ]
1333
+ },
1334
+ x.id
1335
+ ))
1336
+ }
1337
+ ),
1338
+ /* @__PURE__ */ c("div", { className: "px-4 py-2 border-t bg-muted/30 flex justify-between items-center text-[10px] text-muted-foreground", children: [
1339
+ /* @__PURE__ */ c("div", { className: "flex gap-3", children: [
1340
+ /* @__PURE__ */ c("span", { children: [
1341
+ /* @__PURE__ */ r("kbd", { className: "bg-muted px-1 rounded border", children: "↑↓" }),
1342
+ " to navigate"
1343
+ ] }),
1344
+ /* @__PURE__ */ c("span", { children: [
1345
+ /* @__PURE__ */ r("kbd", { className: "bg-muted px-1 rounded border", children: "Enter" }),
1346
+ " to select"
1347
+ ] })
1348
+ ] }),
1349
+ /* @__PURE__ */ c("span", { children: [
1350
+ /* @__PURE__ */ r("kbd", { className: "bg-muted px-1 rounded border", children: "Esc" }),
1351
+ " to close"
1352
+ ] })
1353
+ ] })
1354
+ ]
1355
+ }
1356
+ )
1357
+ }
1358
+ );
1359
+ }, Xt = ({
1360
+ shortcutKey: o = "p",
1816
1361
  ...e
1817
1362
  }) => {
1818
- const n = Y((i) => i.isOpen), r = Y((i) => i.history), a = Y((i) => i.setOpen), s = Y((i) => i.addHistory), l = Y((i) => i.clearHistory);
1819
- return n ? /* @__PURE__ */ t(
1820
- pt,
1363
+ const [n, t] = A(!1);
1364
+ return z(() => {
1365
+ if (o === null) return;
1366
+ const a = (s) => {
1367
+ (s.metaKey || s.ctrlKey) && s.shiftKey && s.key.toLowerCase() === o && (s.preventDefault(), t((l) => !l));
1368
+ };
1369
+ return window.addEventListener("keydown", a), () => window.removeEventListener("keydown", a);
1370
+ }, [o]), /* @__PURE__ */ r(
1371
+ It,
1821
1372
  {
1822
1373
  ...e,
1823
- history: r,
1824
- onCommand: (i) => {
1825
- s(`$ ${i}`);
1826
- const d = i.toLowerCase();
1827
- if (d === "clear") {
1828
- l();
1829
- return;
1830
- }
1831
- if (d === "help") {
1832
- Et.forEach(s);
1833
- return;
1834
- }
1835
- (o == null ? void 0 : o(i)) !== !0 && s(`command not found: ${i.split(" ")[0]}`);
1374
+ open: n,
1375
+ commands: B.getCommands(),
1376
+ onSelect: (a) => {
1377
+ a.execute(), t(!1);
1836
1378
  },
1837
- onClose: () => a(!1)
1379
+ onClose: () => t(!1)
1838
1380
  }
1839
- ) : null;
1840
- };
1841
- class It {
1842
- constructor() {
1843
- J(this, "components", /* @__PURE__ */ new Map());
1844
- }
1845
- /**
1846
- * Register a component with a unique ID.
1847
- * This ID is what you use in your FlexLayout models.
1848
- */
1849
- register(e, n) {
1850
- this.components.has(e) && console.warn(`Component with ID "${e}" is already registered.`), this.components.set(e, n);
1851
- }
1852
- /**
1853
- * Retrieve a registered component by its ID.
1854
- */
1855
- get(e) {
1856
- return this.components.get(e);
1857
- }
1858
- /**
1859
- * Get all registered component IDs.
1860
- */
1861
- getRegisteredIds() {
1862
- return Array.from(this.components.keys());
1863
- }
1864
- }
1865
- const Ot = new It(), U = {
1866
- global: { tabEnableClose: !0, tabSetEnableMaximize: !1, tabSetEnableDivide: !0 },
1867
- borders: [
1381
+ );
1382
+ }, Ot = {
1383
+ alert: Re,
1384
+ confirm: je,
1385
+ prompt: $e
1386
+ }, zt = {
1387
+ alert: "text-destructive",
1388
+ confirm: "text-amber-500",
1389
+ prompt: "text-blue-500"
1390
+ }, At = ({
1391
+ open: o,
1392
+ type: e = "alert",
1393
+ title: n,
1394
+ message: t,
1395
+ defaultValue: a = "",
1396
+ onConfirm: s,
1397
+ onCancel: l,
1398
+ confirmLabel: u,
1399
+ cancelLabel: i = "Cancel",
1400
+ placeholder: d = "Enter value…",
1401
+ className: f
1402
+ }) => {
1403
+ const [p, m] = A(a), k = P(null);
1404
+ if (z(() => {
1405
+ if (!o || (m(a), e !== "prompt")) return;
1406
+ const T = window.setTimeout(() => {
1407
+ var I, N;
1408
+ (I = k.current) == null || I.focus(), (N = k.current) == null || N.select();
1409
+ }, 50);
1410
+ return () => window.clearTimeout(T);
1411
+ }, [o, e, a]), z(() => {
1412
+ if (!o) return;
1413
+ const T = (I) => {
1414
+ I.key === "Escape" && (I.preventDefault(), l == null || l());
1415
+ };
1416
+ return document.addEventListener("keydown", T), () => document.removeEventListener("keydown", T);
1417
+ }, [o, l]), !o) return null;
1418
+ const C = () => s == null ? void 0 : s(e === "prompt" ? p : void 0), x = (T) => {
1419
+ T.key === "Enter" && (T.preventDefault(), C());
1420
+ }, h = Ot[e];
1421
+ return /* @__PURE__ */ r(
1422
+ "div",
1868
1423
  {
1869
- type: "border",
1870
- location: "left",
1871
- children: []
1872
- }
1873
- ],
1874
- layout: {
1875
- type: "row",
1876
- weight: 100,
1877
- children: [
1878
- {
1879
- type: "tabset",
1880
- weight: 50,
1881
- children: [
1882
- {
1883
- type: "tab",
1884
- name: "Welcome",
1885
- component: "welcome"
1886
- }
1887
- ]
1888
- }
1889
- ]
1890
- }
1891
- }, de = "nexus-shell-layout", zt = F((o, e) => {
1892
- let n;
1893
- if (typeof window < "u")
1894
- try {
1895
- const r = localStorage.getItem(de);
1896
- if (r) {
1897
- const a = JSON.parse(r);
1898
- n = $.fromJson(a);
1899
- const s = /* @__PURE__ */ new Set(["dialogue-library", "argument-inspector"]), l = [];
1900
- n.visitNodes((u) => {
1901
- if (u.getType() === "tab") {
1902
- const i = u;
1903
- s.has(i.getComponent()) && l.push(i.getId());
1424
+ className: "fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-background/80 backdrop-blur-sm transition-all duration-300",
1425
+ onClick: l,
1426
+ children: /* @__PURE__ */ c(
1427
+ "div",
1428
+ {
1429
+ role: "dialog",
1430
+ "aria-modal": "true",
1431
+ "aria-label": n,
1432
+ onClick: (T) => T.stopPropagation(),
1433
+ onKeyDown: x,
1434
+ className: S(
1435
+ "relative flex flex-col w-full max-w-md p-6 bg-card border border-border shadow-2xl rounded-2xl animate-in fade-in zoom-in-95 ring-1 ring-white/10",
1436
+ f
1437
+ ),
1438
+ children: [
1439
+ /* @__PURE__ */ r(
1440
+ "button",
1441
+ {
1442
+ type: "button",
1443
+ onClick: l,
1444
+ "aria-label": "Close",
1445
+ className: "absolute top-4 right-4 p-1 rounded-full text-muted-foreground hover:bg-muted hover:text-foreground transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
1446
+ children: /* @__PURE__ */ r(J, { size: 18 })
1447
+ }
1448
+ ),
1449
+ /* @__PURE__ */ c("div", { className: "flex items-start space-x-4 mb-4", children: [
1450
+ /* @__PURE__ */ r("div", { className: S("p-2 bg-muted rounded-full shrink-0", zt[e]), children: /* @__PURE__ */ r(h, { size: 24 }) }),
1451
+ /* @__PURE__ */ c("div", { className: "flex-1 mt-1", children: [
1452
+ /* @__PURE__ */ r("h2", { className: "text-lg font-semibold tracking-tight pr-6", children: n }),
1453
+ t && /* @__PURE__ */ r("p", { className: "text-sm text-muted-foreground mt-1 whitespace-pre-wrap", children: t })
1454
+ ] })
1455
+ ] }),
1456
+ e === "prompt" && /* @__PURE__ */ r("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ r(
1457
+ "input",
1458
+ {
1459
+ ref: k,
1460
+ type: "text",
1461
+ "aria-label": n,
1462
+ value: p,
1463
+ placeholder: d,
1464
+ onChange: (T) => m(T.target.value),
1465
+ className: "w-full bg-background border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all placeholder:text-muted-foreground/50"
1466
+ }
1467
+ ) }),
1468
+ /* @__PURE__ */ c("div", { className: "flex items-center justify-end space-x-3 mt-4", children: [
1469
+ e !== "alert" && /* @__PURE__ */ r(
1470
+ "button",
1471
+ {
1472
+ type: "button",
1473
+ onClick: l,
1474
+ className: "px-4 py-2 text-sm font-medium rounded-lg border border-border hover:bg-muted transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
1475
+ children: i
1476
+ }
1477
+ ),
1478
+ /* @__PURE__ */ r(
1479
+ "button",
1480
+ {
1481
+ type: "button",
1482
+ onClick: C,
1483
+ autoFocus: e !== "prompt",
1484
+ className: "px-4 py-2 text-sm font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
1485
+ children: u ?? (e === "alert" ? "OK" : "Confirm")
1486
+ }
1487
+ )
1488
+ ] })
1489
+ ]
1490
+ }
1491
+ )
1492
+ }
1493
+ );
1494
+ }, Zt = (o) => {
1495
+ const { isOpen: e, type: n, title: t, message: a, defaultValue: s, close: l } = Te();
1496
+ return /* @__PURE__ */ r(
1497
+ At,
1498
+ {
1499
+ ...o,
1500
+ open: e,
1501
+ type: n,
1502
+ title: t,
1503
+ message: a,
1504
+ defaultValue: s,
1505
+ onConfirm: (d) => {
1506
+ n === "prompt" ? l(d ?? "") : n === "confirm" ? l(!0) : l();
1507
+ },
1508
+ onCancel: () => {
1509
+ n === "prompt" ? l(null) : n === "confirm" ? l(!1) : l();
1510
+ }
1511
+ }
1512
+ );
1513
+ }, Lt = [
1514
+ { id: "light", label: "Light" },
1515
+ { id: "dark", label: "Dark" },
1516
+ { id: "gt", label: "GT" }
1517
+ ], Mt = ({
1518
+ value: o,
1519
+ onChange: e,
1520
+ options: n = Lt,
1521
+ className: t,
1522
+ "aria-label": a = "Theme"
1523
+ }) => /* @__PURE__ */ r(
1524
+ "div",
1525
+ {
1526
+ role: "radiogroup",
1527
+ "aria-label": a,
1528
+ className: S(
1529
+ "flex items-center border border-border rounded-lg p-0.5 bg-secondary/80 select-none",
1530
+ t
1531
+ ),
1532
+ children: n.map((s) => /* @__PURE__ */ r(
1533
+ "button",
1534
+ {
1535
+ role: "radio",
1536
+ "aria-checked": o === s.id,
1537
+ onClick: () => e(s.id),
1538
+ className: S(
1539
+ "px-2.5 py-1 text-[9px] font-extrabold uppercase rounded-md transition-all font-mono cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-ring",
1540
+ o === s.id ? "bg-primary text-primary-foreground shadow" : "text-muted-foreground hover:bg-accent hover:text-foreground"
1541
+ ),
1542
+ children: s.label
1543
+ },
1544
+ s.id
1545
+ ))
1546
+ }
1547
+ ), er = (o) => {
1548
+ const e = Y((t) => t.theme), n = Y((t) => t.setTheme);
1549
+ return /* @__PURE__ */ r(Mt, { ...o, value: e, onChange: n });
1550
+ }, Pt = ({
1551
+ profile: o,
1552
+ actions: e = [],
1553
+ onProfileChange: n,
1554
+ onAvatarChange: t,
1555
+ onClick: a,
1556
+ showName: s = !0,
1557
+ className: l
1558
+ }) => {
1559
+ const { name: u, role: i, email: d, avatarUrl: f } = o, [p, m] = A(!1), [k, C] = A(!1), [x, h] = A(u), [T, I] = A(i ?? ""), N = P(null), y = P(null);
1560
+ z(() => {
1561
+ p && (h(u), I(i ?? ""), C(!1));
1562
+ }, [p, u, i]), z(() => {
1563
+ if (!p) return;
1564
+ const w = (L) => {
1565
+ N.current && !N.current.contains(L.target) && m(!1);
1566
+ };
1567
+ return document.addEventListener("mousedown", w), () => document.removeEventListener("mousedown", w);
1568
+ }, [p]);
1569
+ const g = (w) => {
1570
+ w.preventDefault(), n == null || n({ name: x, role: T }), C(!1);
1571
+ }, b = (w) => {
1572
+ var v;
1573
+ const L = (v = w.target.files) == null ? void 0 : v[0];
1574
+ L && (t == null || t(L)), w.target.value = "";
1575
+ }, E = (w) => f ? /* @__PURE__ */ r("img", { src: f, alt: u, className: "w-full h-full object-cover" }) : /* @__PURE__ */ r(xe, { size: w, className: "text-muted-foreground" });
1576
+ return /* @__PURE__ */ c("div", { ref: N, className: "relative inline-block text-left", children: [
1577
+ /* @__PURE__ */ c(
1578
+ "button",
1579
+ {
1580
+ type: "button",
1581
+ onClick: () => a ? a() : m((w) => !w),
1582
+ "aria-haspopup": a ? void 0 : "menu",
1583
+ "aria-expanded": a ? void 0 : p,
1584
+ "aria-label": "User Profile Menu",
1585
+ className: S(
1586
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none transition-all duration-200 select-none",
1587
+ s ? "flex items-center space-x-2 px-2 py-1 rounded-md hover:bg-accent/50 hover:text-accent-foreground text-left cursor-pointer border border-transparent hover:border-border/30" : "w-7 h-7 rounded-full bg-secondary/80 border border-border flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-secondary cursor-pointer",
1588
+ p && (s ? "bg-accent/60 border-border/40" : "border-primary/50 text-foreground ring-1 ring-primary/20"),
1589
+ l
1590
+ ),
1591
+ children: [
1592
+ /* @__PURE__ */ r(
1593
+ "div",
1594
+ {
1595
+ className: S(
1596
+ "rounded-full overflow-hidden border border-border/50 bg-muted flex items-center justify-center shrink-0 shadow-sm",
1597
+ s ? "w-6 h-6" : "w-full h-full"
1598
+ ),
1599
+ children: E(s ? 13 : 12)
1600
+ }
1601
+ ),
1602
+ s && /* @__PURE__ */ c("div", { className: "flex flex-col min-w-0 leading-tight pr-1", children: [
1603
+ /* @__PURE__ */ r("span", { className: "text-[11px] font-semibold truncate text-foreground", children: u }),
1604
+ i && /* @__PURE__ */ r("span", { className: "text-[9px] text-muted-foreground/80 truncate font-medium", children: i })
1605
+ ] })
1606
+ ]
1607
+ }
1608
+ ),
1609
+ t && /* @__PURE__ */ r(
1610
+ "input",
1611
+ {
1612
+ type: "file",
1613
+ ref: y,
1614
+ onChange: b,
1615
+ accept: "image/*",
1616
+ "aria-label": "Upload avatar",
1617
+ className: "hidden"
1618
+ }
1619
+ ),
1620
+ p && /* @__PURE__ */ r(
1621
+ "div",
1622
+ {
1623
+ role: "menu",
1624
+ className: S(
1625
+ "absolute z-50 w-64 rounded-lg border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-md p-2 flex flex-col gap-1 mt-1.5 animate-in fade-in slide-in-from-top-2 duration-150 origin-top-right",
1626
+ s ? "left-0" : "right-0"
1627
+ ),
1628
+ children: k ? /* @__PURE__ */ c("form", { onSubmit: g, className: "p-2 flex flex-col gap-2", children: [
1629
+ /* @__PURE__ */ r("span", { className: "text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: "Edit Profile" }),
1630
+ /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: [
1631
+ /* @__PURE__ */ r("label", { htmlFor: "profile-name", className: "text-[9px] font-semibold text-muted-foreground", children: "Name" }),
1632
+ /* @__PURE__ */ r(
1633
+ "input",
1634
+ {
1635
+ id: "profile-name",
1636
+ type: "text",
1637
+ value: x,
1638
+ onChange: (w) => h(w.target.value),
1639
+ required: !0,
1640
+ className: "w-full px-2 py-1 text-xs border rounded bg-background focus:ring-1 focus:ring-primary focus:outline-none"
1641
+ }
1642
+ )
1643
+ ] }),
1644
+ /* @__PURE__ */ c("div", { className: "flex flex-col gap-1", children: [
1645
+ /* @__PURE__ */ r("label", { htmlFor: "profile-role", className: "text-[9px] font-semibold text-muted-foreground", children: "Role" }),
1646
+ /* @__PURE__ */ r(
1647
+ "input",
1648
+ {
1649
+ id: "profile-role",
1650
+ type: "text",
1651
+ value: T,
1652
+ onChange: (w) => I(w.target.value),
1653
+ className: "w-full px-2 py-1 text-xs border rounded bg-background focus:ring-1 focus:ring-primary focus:outline-none"
1654
+ }
1655
+ )
1656
+ ] }),
1657
+ /* @__PURE__ */ c("div", { className: "flex gap-1.5 mt-1 justify-end", children: [
1658
+ /* @__PURE__ */ c(
1659
+ "button",
1660
+ {
1661
+ type: "button",
1662
+ onClick: () => C(!1),
1663
+ className: "px-2 py-1 text-[10px] rounded hover:bg-accent text-muted-foreground flex items-center gap-1 border border-border/30",
1664
+ children: [
1665
+ /* @__PURE__ */ r(J, { size: 10 }),
1666
+ " Cancel"
1667
+ ]
1668
+ }
1669
+ ),
1670
+ /* @__PURE__ */ c(
1671
+ "button",
1672
+ {
1673
+ type: "submit",
1674
+ className: "px-2 py-1 text-[10px] rounded bg-primary text-primary-foreground hover:bg-primary/95 flex items-center gap-1 font-semibold",
1675
+ children: [
1676
+ /* @__PURE__ */ r(Fe, { size: 10 }),
1677
+ " Save"
1678
+ ]
1679
+ }
1680
+ )
1681
+ ] })
1682
+ ] }) : /* @__PURE__ */ c(he, { children: [
1683
+ /* @__PURE__ */ c("div", { className: "p-2 flex items-center gap-3 border-b border-border/40 pb-2.5 mb-1", children: [
1684
+ /* @__PURE__ */ c(
1685
+ "div",
1686
+ {
1687
+ onClick: () => {
1688
+ var w;
1689
+ return t && ((w = y.current) == null ? void 0 : w.click());
1690
+ },
1691
+ title: t ? "Upload avatar image" : void 0,
1692
+ className: S(
1693
+ "group relative w-12 h-12 rounded-full overflow-hidden border border-border/80 bg-muted flex items-center justify-center shrink-0 shadow-inner",
1694
+ t && "cursor-pointer"
1695
+ ),
1696
+ children: [
1697
+ E(24),
1698
+ t && /* @__PURE__ */ r("div", { className: "absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity", children: /* @__PURE__ */ r(Ue, { size: 14, className: "text-white" }) })
1699
+ ]
1700
+ }
1701
+ ),
1702
+ /* @__PURE__ */ c("div", { className: "flex flex-col min-w-0 leading-normal flex-1", children: [
1703
+ /* @__PURE__ */ c("div", { className: "flex items-center gap-1", children: [
1704
+ /* @__PURE__ */ r("span", { className: "text-xs font-bold truncate text-foreground", children: u }),
1705
+ n && /* @__PURE__ */ r(
1706
+ "button",
1707
+ {
1708
+ type: "button",
1709
+ onClick: () => C(!0),
1710
+ title: "Edit Profile",
1711
+ "aria-label": "Edit Profile",
1712
+ className: "p-1 text-muted-foreground hover:text-foreground hover:bg-accent/40 rounded transition-colors",
1713
+ children: /* @__PURE__ */ r(_e, { size: 10 })
1714
+ }
1715
+ )
1716
+ ] }),
1717
+ i && /* @__PURE__ */ r("span", { className: "text-[10px] text-muted-foreground/80 truncate font-semibold", children: i }),
1718
+ d && /* @__PURE__ */ r("span", { className: "text-[9px] text-muted-foreground/60 truncate font-mono mt-0.5", children: d })
1719
+ ] })
1720
+ ] }),
1721
+ e.map((w) => {
1722
+ const L = w.icon;
1723
+ return /* @__PURE__ */ c(
1724
+ "button",
1725
+ {
1726
+ type: "button",
1727
+ role: "menuitem",
1728
+ onClick: () => {
1729
+ w.onSelect(), m(!1);
1730
+ },
1731
+ className: S(
1732
+ "w-full px-2 py-1.5 text-left rounded-md text-[11px] font-medium flex items-center gap-2 cursor-pointer transition-colors",
1733
+ w.destructive ? "text-destructive hover:bg-destructive/10" : "hover:bg-accent/60 hover:text-accent-foreground",
1734
+ w.divider && "border-t border-border/20 pt-2 mt-1"
1735
+ ),
1736
+ children: [
1737
+ L && /* @__PURE__ */ r(L, { size: 12, className: "opacity-70" }),
1738
+ w.label
1739
+ ]
1740
+ },
1741
+ w.id
1742
+ );
1743
+ })
1744
+ ] })
1745
+ }
1746
+ )
1747
+ ] });
1748
+ }, tr = (o) => {
1749
+ const e = W((d) => d.name), n = W((d) => d.role), t = W((d) => d.email), a = W((d) => d.avatarUrl), s = W((d) => d.customAvatar), l = W((d) => d.updateProfile), u = W((d) => d.setCustomAvatar);
1750
+ return /* @__PURE__ */ r(
1751
+ Pt,
1752
+ {
1753
+ ...o,
1754
+ profile: { name: e, role: n, email: t, avatarUrl: s || a },
1755
+ onProfileChange: l,
1756
+ onAvatarChange: (d) => {
1757
+ const f = new FileReader();
1758
+ f.onloadend = () => {
1759
+ typeof f.result == "string" && u(f.result);
1760
+ }, f.readAsDataURL(d);
1761
+ }
1762
+ }
1763
+ );
1764
+ }, rr = ({ title: o, subtitle: e, icon: n, className: t }) => /* @__PURE__ */ c("div", { className: S("flex items-center space-x-3 select-none", t), children: [
1765
+ n && /* @__PURE__ */ r("div", { className: "w-8 h-8 rounded-lg bg-primary/10 border border-primary/30 flex items-center justify-center text-primary shadow-inner shrink-0", children: n }),
1766
+ /* @__PURE__ */ c("div", { className: "min-w-0", children: [
1767
+ /* @__PURE__ */ r("h1", { className: "text-xs font-black uppercase tracking-wider text-foreground font-mono truncate", children: o }),
1768
+ e && /* @__PURE__ */ r("p", { className: "text-[9px] text-muted-foreground font-semibold truncate", children: e })
1769
+ ] })
1770
+ ] }), Kt = ({ x: o, y: e, items: n, onClose: t, className: a }) => {
1771
+ const s = P(null);
1772
+ return z(() => {
1773
+ const l = (i) => {
1774
+ s.current && !s.current.contains(i.target) && t();
1775
+ }, u = (i) => {
1776
+ i.key === "Escape" && t();
1777
+ };
1778
+ return document.addEventListener("mousedown", l), document.addEventListener("keydown", u), () => {
1779
+ document.removeEventListener("mousedown", l), document.removeEventListener("keydown", u);
1780
+ };
1781
+ }, [t]), /* @__PURE__ */ r(
1782
+ "div",
1783
+ {
1784
+ ref: s,
1785
+ role: "menu",
1786
+ style: { top: e, left: o },
1787
+ className: S(
1788
+ "fixed z-[1000] min-w-[160px] bg-popover text-popover-foreground border shadow-md rounded-md py-1 animate-in fade-in zoom-in-95 duration-100",
1789
+ a
1790
+ ),
1791
+ children: n.map((l, u) => /* @__PURE__ */ c(se.Fragment, { children: [
1792
+ l.divider && /* @__PURE__ */ r("div", { className: "h-[1px] bg-border my-1" }),
1793
+ /* @__PURE__ */ c(
1794
+ "div",
1795
+ {
1796
+ role: "menuitem",
1797
+ tabIndex: l.disabled ? void 0 : 0,
1798
+ "aria-disabled": l.disabled,
1799
+ onClick: () => {
1800
+ l.disabled || (l.onClick(), t());
1801
+ },
1802
+ onKeyDown: (i) => {
1803
+ l.disabled || i.key !== "Enter" && i.key !== " " || (i.preventDefault(), l.onClick(), t());
1804
+ },
1805
+ className: S(
1806
+ "px-3 py-1.5 text-xs flex items-center focus:outline-none",
1807
+ l.disabled ? "opacity-40 cursor-default" : "cursor-pointer hover:bg-accent hover:text-accent-foreground focus:bg-accent"
1808
+ ),
1809
+ children: [
1810
+ l.icon && /* @__PURE__ */ r("span", { className: "mr-2 opacity-70", children: l.icon }),
1811
+ /* @__PURE__ */ r("span", { children: l.label })
1812
+ ]
1904
1813
  }
1905
- }), l.forEach((u) => {
1906
- n.doAction(B.deleteTab(u));
1814
+ )
1815
+ ] }, `${l.label}-${u}`))
1816
+ }
1817
+ );
1818
+ }, nr = ({
1819
+ columns: o,
1820
+ data: e,
1821
+ onRowClick: n,
1822
+ selectedRowId: t,
1823
+ rowKey: a = "id",
1824
+ virtualized: s = !0,
1825
+ showFilter: l = !0,
1826
+ loading: u = !1,
1827
+ placeholder: i = "No data available",
1828
+ className: d
1829
+ }) => {
1830
+ const [f, p] = A(""), [m, k] = A(null), [C, x] = A(-1), h = P(null);
1831
+ z(() => {
1832
+ x(-1);
1833
+ }, [f, m]);
1834
+ const T = R(() => {
1835
+ if (!f) return e;
1836
+ const v = f.toLowerCase();
1837
+ return e.filter((D) => Object.values(D).some((O) => O == null ? !1 : String(O).toLowerCase().includes(v)));
1838
+ }, [e, f]), I = R(() => {
1839
+ if (!m) return T;
1840
+ const { key: v, direction: D } = m;
1841
+ return [...T].sort((O, j) => {
1842
+ const K = O[v], M = j[v];
1843
+ if (K === M) return 0;
1844
+ if (K == null) return 1;
1845
+ if (M == null) return -1;
1846
+ const Z = Number(K), ee = Number(M);
1847
+ if (!isNaN(Z) && !isNaN(ee))
1848
+ return D === "asc" ? Z - ee : ee - Z;
1849
+ const de = String(K).toLowerCase(), ce = String(M).toLowerCase();
1850
+ return D === "asc" ? de.localeCompare(ce) : ce.localeCompare(de);
1851
+ });
1852
+ }, [T, m]), N = (v, D) => {
1853
+ D !== !1 && k((O) => !O || O.key !== v ? { key: v, direction: "asc" } : O.direction === "asc" ? { key: v, direction: "desc" } : null);
1854
+ }, y = (v) => {
1855
+ if (!(I.length === 0 || u)) {
1856
+ if (v.key === "ArrowDown")
1857
+ v.preventDefault(), x((D) => {
1858
+ const O = D + 1;
1859
+ return O >= I.length ? 0 : O;
1907
1860
  });
1908
- } else
1909
- n = $.fromJson(U);
1910
- } catch (r) {
1911
- console.warn("Failed to load layout from storage, using default", r), n = $.fromJson(U);
1861
+ else if (v.key === "ArrowUp")
1862
+ v.preventDefault(), x((D) => {
1863
+ const O = D - 1;
1864
+ return O < 0 ? I.length - 1 : O;
1865
+ });
1866
+ else if ((v.key === "Enter" || v.key === " ") && (v.preventDefault(), C >= 0 && C < I.length)) {
1867
+ const D = I[C];
1868
+ n && n(D);
1869
+ }
1912
1870
  }
1913
- else
1914
- n = $.fromJson(U);
1915
- return {
1916
- model: n,
1917
- dirtyTabs: /* @__PURE__ */ new Set(),
1918
- storageKey: de,
1919
- disableLocalStorage: !1,
1920
- initLayout: (r, a) => {
1921
- let s;
1922
- if (r && Object.keys(r).length > 0)
1923
- try {
1924
- s = $.fromJson(r);
1925
- } catch (l) {
1926
- console.warn("Failed to parse init layout json, using default", l), s = $.fromJson(U);
1927
- }
1928
- else
1929
- s = $.fromJson(U);
1930
- o({ model: s, disableLocalStorage: a || !1 });
1871
+ }, g = (v) => v.sortable === !1 ? null : (m == null ? void 0 : m.key) !== v.key ? /* @__PURE__ */ r(Je, { size: 14, className: "text-muted-foreground/60 ml-1.5 opacity-0 group-hover:opacity-100 transition-opacity" }) : m.direction === "asc" ? /* @__PURE__ */ r(we, { size: 14, className: "text-primary ml-1.5" }) : /* @__PURE__ */ r(ke, { size: 14, className: "text-primary ml-1.5" }), b = () => /* @__PURE__ */ r("tr", { role: "row", className: "border-b border-border bg-muted/30 select-none", children: o.map((v) => /* @__PURE__ */ r(
1872
+ "th",
1873
+ {
1874
+ role: "columnheader",
1875
+ "aria-sort": (m == null ? void 0 : m.key) === v.key ? m.direction === "asc" ? "ascending" : "descending" : "none",
1876
+ className: S(
1877
+ "p-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-left transition-colors",
1878
+ v.sortable !== !1 && "cursor-pointer hover:bg-accent/30 hover:text-foreground group"
1879
+ ),
1880
+ style: { width: v.width },
1881
+ onClick: () => N(v.key, v.sortable),
1882
+ children: /* @__PURE__ */ c("div", { className: "flex items-center", children: [
1883
+ /* @__PURE__ */ r("span", { children: v.header }),
1884
+ g(v)
1885
+ ] })
1931
1886
  },
1932
- setModel: (r) => {
1933
- o({ model: r });
1934
- const a = e().storageKey;
1935
- if (typeof window < "u" && !e().disableLocalStorage)
1936
- try {
1937
- localStorage.setItem(a, JSON.stringify(r.toJson()));
1938
- } catch (s) {
1939
- console.error("Failed to save layout to storage", s);
1887
+ v.key
1888
+ )) }), E = (v, D) => {
1889
+ const O = t !== void 0 && v[a] === t;
1890
+ return /* @__PURE__ */ r(
1891
+ "tr",
1892
+ {
1893
+ role: "row",
1894
+ "aria-selected": O,
1895
+ onClick: () => n && n(v),
1896
+ className: S(
1897
+ "border-b border-border/40 hover:bg-accent/40 transition-colors cursor-pointer text-sm outline-none",
1898
+ O && "bg-primary/10 text-primary hover:bg-primary/15 font-medium border-l-2 border-l-primary",
1899
+ C === D && "bg-accent/60 ring-1 ring-inset ring-ring"
1900
+ ),
1901
+ children: o.map((K) => {
1902
+ const M = v[K.key];
1903
+ return /* @__PURE__ */ r("td", { role: "gridcell", className: "p-3 align-middle truncate max-w-xs", children: K.render ? K.render(M, v) : M != null ? String(M) : "" }, K.key);
1904
+ })
1905
+ },
1906
+ String(v[a] || D)
1907
+ );
1908
+ }, w = R(() => ({
1909
+ Table: (v) => /* @__PURE__ */ r(
1910
+ "table",
1911
+ {
1912
+ ...v,
1913
+ role: "grid",
1914
+ className: "w-full border-collapse text-left bg-background text-foreground"
1915
+ }
1916
+ ),
1917
+ TableHead: se.forwardRef((v, D) => /* @__PURE__ */ r("thead", { ref: D, ...v, className: "sticky top-0 bg-background z-10 shadow-[0_1px_0_0_rgba(0,0,0,0.1)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.05)]" })),
1918
+ TableBody: se.forwardRef((v, D) => /* @__PURE__ */ r("tbody", { ref: D, ...v })),
1919
+ TableRow: ({ item: v, context: D, ...O }) => {
1920
+ if (!D || !v) return /* @__PURE__ */ r("tr", { ...O });
1921
+ const j = D.selectedRowId !== void 0 && v[D.rowKey] === D.selectedRowId, K = D.focusedIndex === O["data-index"];
1922
+ return /* @__PURE__ */ r(
1923
+ "tr",
1924
+ {
1925
+ ...O,
1926
+ onClick: () => {
1927
+ var M;
1928
+ return (M = D.onRowClick) == null ? void 0 : M.call(D, v);
1929
+ },
1930
+ className: S(
1931
+ "border-b border-border/40 hover:bg-accent/40 transition-colors cursor-pointer text-sm outline-none",
1932
+ j && "bg-primary/10 text-primary hover:bg-primary/15 font-medium border-l-2 border-l-primary",
1933
+ K && "bg-accent/60 ring-1 ring-inset ring-ring"
1934
+ )
1940
1935
  }
1941
- },
1942
- setStorageKey: (r, a) => {
1943
- let s;
1944
- if (typeof window < "u")
1945
- try {
1946
- const l = localStorage.getItem(r);
1947
- l ? s = $.fromJson(JSON.parse(l)) : s = $.fromJson(a || U);
1948
- } catch (l) {
1949
- console.warn("Failed to load layout from storage for key", r, l), s = $.fromJson(a || U);
1936
+ );
1937
+ }
1938
+ }), []), L = () => u ? /* @__PURE__ */ c("div", { className: "flex flex-col items-center justify-center h-64 space-y-3", children: [
1939
+ /* @__PURE__ */ r(Ne, { className: "animate-spin text-primary", size: 24 }),
1940
+ /* @__PURE__ */ r("span", { className: "text-xs text-muted-foreground", children: "Loading dataset..." })
1941
+ ] }) : I.length === 0 ? /* @__PURE__ */ c("div", { className: "flex flex-col items-center justify-center h-48 text-center px-4", children: [
1942
+ /* @__PURE__ */ r("span", { className: "text-sm font-medium text-foreground", children: i }),
1943
+ /* @__PURE__ */ r("span", { className: "text-xs text-muted-foreground mt-1", children: "No items matched your search query." })
1944
+ ] }) : s ? /* @__PURE__ */ r("div", { className: "flex-1 min-h-[300px] h-full relative", children: /* @__PURE__ */ r(
1945
+ Ze,
1946
+ {
1947
+ data: I,
1948
+ context: {
1949
+ selectedRowId: t,
1950
+ focusedIndex: C,
1951
+ rowKey: a,
1952
+ onRowClick: n
1953
+ },
1954
+ components: w,
1955
+ fixedHeaderContent: b,
1956
+ itemContent: (v, D) => /* @__PURE__ */ r(he, { children: o.map((O) => {
1957
+ const j = D[O.key];
1958
+ return /* @__PURE__ */ r("td", { role: "gridcell", className: "p-3 align-middle truncate max-w-xs", children: O.render ? O.render(j, D) : j != null ? String(j) : "" }, O.key);
1959
+ }) })
1960
+ }
1961
+ ) }) : /* @__PURE__ */ r("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ c("table", { role: "grid", className: "w-full border-collapse text-left bg-background text-foreground", children: [
1962
+ /* @__PURE__ */ r("thead", { children: b() }),
1963
+ /* @__PURE__ */ r("tbody", { children: I.map((v, D) => E(v, D)) })
1964
+ ] }) });
1965
+ return /* @__PURE__ */ c(
1966
+ "div",
1967
+ {
1968
+ ref: h,
1969
+ role: "region",
1970
+ "aria-label": "Data Grid",
1971
+ tabIndex: 0,
1972
+ onKeyDown: y,
1973
+ className: S(
1974
+ "flex flex-col h-full bg-background border border-border rounded-lg shadow-sm overflow-hidden focus:outline-none focus:ring-1 focus:ring-ring focus:border-transparent",
1975
+ d
1976
+ ),
1977
+ children: [
1978
+ l && /* @__PURE__ */ c("div", { className: "flex items-center justify-between p-3 border-b border-border bg-muted/20", children: [
1979
+ /* @__PURE__ */ c("div", { className: "relative flex-1 max-w-sm", children: [
1980
+ /* @__PURE__ */ r(X, { size: 14, className: "absolute left-2.5 top-2.5 text-muted-foreground" }),
1981
+ /* @__PURE__ */ r(
1982
+ "input",
1983
+ {
1984
+ type: "text",
1985
+ placeholder: "Filter table rows...",
1986
+ className: "w-full bg-secondary/40 border border-border rounded-md pl-8 pr-7 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary focus:border-transparent transition-all",
1987
+ value: f,
1988
+ onChange: (v) => p(v.target.value)
1989
+ }
1990
+ ),
1991
+ f && /* @__PURE__ */ r(
1992
+ "button",
1993
+ {
1994
+ onClick: () => p(""),
1995
+ className: "absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",
1996
+ "aria-label": "Clear filter",
1997
+ children: /* @__PURE__ */ r(J, { size: 12 })
1998
+ }
1999
+ )
2000
+ ] }),
2001
+ /* @__PURE__ */ c("div", { className: "text-[11px] text-muted-foreground font-medium ml-4", children: [
2002
+ I.length,
2003
+ " of ",
2004
+ e.length,
2005
+ " records"
2006
+ ] })
2007
+ ] }),
2008
+ L()
2009
+ ]
2010
+ }
2011
+ );
2012
+ }, or = ({
2013
+ results: o,
2014
+ onQueryChange: e,
2015
+ onSelect: n,
2016
+ categories: t,
2017
+ placeholder: a = "Search…",
2018
+ debounceMs: s = 200,
2019
+ className: l
2020
+ }) => {
2021
+ const [u, i] = A(""), [d, f] = A(!1), [p, m] = A(0), k = P(null), C = P(null), x = R(() => t || [...new Set(o.map((N) => N.category))], [t, o]), h = R(
2022
+ () => x.flatMap((N) => o.filter((y) => y.category === N)),
2023
+ [x, o]
2024
+ );
2025
+ z(() => {
2026
+ const N = (y) => {
2027
+ k.current && !k.current.contains(y.target) && f(!1);
2028
+ };
2029
+ return document.addEventListener("mousedown", N), () => document.removeEventListener("mousedown", N);
2030
+ }, []), z(() => {
2031
+ if (!e) return;
2032
+ const N = window.setTimeout(() => e(u), s);
2033
+ return () => window.clearTimeout(N);
2034
+ }, [u, s, e]), z(() => {
2035
+ m(0);
2036
+ }, [o]);
2037
+ const T = (N) => {
2038
+ n(N), f(!1), i("");
2039
+ }, I = (N) => {
2040
+ var y;
2041
+ if (!d) {
2042
+ (N.key === "ArrowDown" || N.key === "Enter") && f(!0);
2043
+ return;
2044
+ }
2045
+ N.key === "ArrowDown" ? (N.preventDefault(), m((g) => h.length ? (g + 1) % h.length : 0)) : N.key === "ArrowUp" ? (N.preventDefault(), m(
2046
+ (g) => h.length ? (g - 1 + h.length) % h.length : 0
2047
+ )) : N.key === "Enter" ? (N.preventDefault(), h[p] && T(h[p])) : N.key === "Escape" && (N.preventDefault(), f(!1), (y = C.current) == null || y.blur());
2048
+ };
2049
+ return /* @__PURE__ */ c("div", { ref: k, className: S("relative w-full", l), children: [
2050
+ /* @__PURE__ */ c("div", { className: "relative flex items-center", children: [
2051
+ /* @__PURE__ */ r(
2052
+ X,
2053
+ {
2054
+ size: 13,
2055
+ className: "absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground"
1950
2056
  }
1951
- else
1952
- s = $.fromJson(a || U);
1953
- o({ storageKey: r, model: s });
1954
- },
1955
- setTabDirty: (r, a) => {
1956
- o((s) => {
1957
- const l = new Set(s.dirtyTabs);
1958
- return a ? l.add(r) : l.delete(r), { dirtyTabs: l };
1959
- });
1960
- },
1961
- isTabDirty: (r) => e().dirtyTabs.has(r),
1962
- addTab: (r, a, s) => {
1963
- const l = e().model, u = l.getActiveTabset();
1964
- let i = u == null ? void 0 : u.getId();
1965
- if (!i)
1966
- try {
1967
- const g = l.getFirstTabSet();
1968
- i = g == null ? void 0 : g.getId();
1969
- } catch (g) {
1970
- console.warn("Failed to get first tabset fallback", g);
2057
+ ),
2058
+ /* @__PURE__ */ r(
2059
+ "input",
2060
+ {
2061
+ ref: C,
2062
+ type: "text",
2063
+ role: "combobox",
2064
+ "aria-expanded": d,
2065
+ "aria-label": a,
2066
+ value: u,
2067
+ placeholder: a,
2068
+ onChange: (N) => {
2069
+ i(N.target.value), f(!0);
2070
+ },
2071
+ onFocus: () => f(!0),
2072
+ onKeyDown: I,
2073
+ className: "w-full h-7 pl-8 pr-7 bg-secondary/35 border border-border/40 rounded-md text-xs text-foreground placeholder:text-muted-foreground/75 focus:outline-none focus:ring-1 focus:ring-primary/40 focus:bg-background/95 focus:border-primary/50 transition-all font-sans"
1971
2074
  }
1972
- const p = { ...{}, ...s };
1973
- if (["nexus-dashboard", "nexus-docs"].includes(r)) {
1974
- let g = null;
1975
- if (l.visitNodes((m) => {
1976
- if (m.getType() === "tab") {
1977
- const w = m;
1978
- w.getComponent() === r && (g = w.getId());
1979
- }
1980
- }), g) {
1981
- l.doAction(B.selectTab(g));
1982
- return;
2075
+ ),
2076
+ u && /* @__PURE__ */ r(
2077
+ "button",
2078
+ {
2079
+ type: "button",
2080
+ onClick: () => {
2081
+ var N;
2082
+ i(""), (N = C.current) == null || N.focus();
2083
+ },
2084
+ "aria-label": "Clear search",
2085
+ className: "absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
2086
+ children: /* @__PURE__ */ r(J, { size: 11 })
1983
2087
  }
2088
+ )
2089
+ ] }),
2090
+ d && u.trim() && /* @__PURE__ */ c(
2091
+ "div",
2092
+ {
2093
+ role: "listbox",
2094
+ className: "absolute right-0 md:left-0 mt-1.5 w-80 max-h-[380px] bg-popover text-popover-foreground border border-border shadow-lg rounded-lg overflow-hidden flex flex-col z-[100] animate-in fade-in-50 slide-in-from-top-1 duration-100",
2095
+ children: [
2096
+ /* @__PURE__ */ r("div", { className: "flex-1 overflow-y-auto py-1", children: h.length === 0 ? /* @__PURE__ */ c("div", { className: "px-4 py-6 text-center text-xs text-muted-foreground italic", children: [
2097
+ 'No results found matching "',
2098
+ u,
2099
+ '"'
2100
+ ] }) : x.map((N) => {
2101
+ const y = o.filter((g) => g.category === N);
2102
+ return y.length === 0 ? null : /* @__PURE__ */ c("div", { className: "flex flex-col", children: [
2103
+ /* @__PURE__ */ r("div", { className: "px-3 py-1 text-[9px] font-bold uppercase tracking-wider text-muted-foreground/80 bg-muted/40 border-y border-border/20 first:border-t-0", children: N }),
2104
+ y.map((g) => {
2105
+ const b = g.icon, E = h.indexOf(g), w = E === p;
2106
+ return /* @__PURE__ */ c(
2107
+ "div",
2108
+ {
2109
+ role: "option",
2110
+ "aria-selected": w,
2111
+ onClick: () => T(g),
2112
+ onMouseEnter: () => m(E),
2113
+ className: S(
2114
+ "px-3 py-2 cursor-pointer flex items-start space-x-2.5 transition-colors border-l-2",
2115
+ w ? "bg-accent text-accent-foreground border-primary" : "border-transparent hover:bg-accent/40"
2116
+ ),
2117
+ children: [
2118
+ b && /* @__PURE__ */ r(
2119
+ "div",
2120
+ {
2121
+ className: S(
2122
+ "mt-0.5 p-1 rounded bg-muted/50",
2123
+ w && "bg-background text-primary"
2124
+ ),
2125
+ children: /* @__PURE__ */ r(b, { size: 12 })
2126
+ }
2127
+ ),
2128
+ /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
2129
+ /* @__PURE__ */ r("div", { className: "text-xs font-medium truncate", children: g.title }),
2130
+ g.description && /* @__PURE__ */ r("div", { className: "text-[10px] text-muted-foreground truncate mt-0.5", children: g.description })
2131
+ ] })
2132
+ ]
2133
+ },
2134
+ `${g.category}-${g.id}`
2135
+ );
2136
+ })
2137
+ ] }, N);
2138
+ }) }),
2139
+ h.length > 0 && /* @__PURE__ */ c("div", { className: "px-3 py-1.5 border-t border-border bg-muted/20 flex items-center justify-between text-[9px] text-muted-foreground select-none shrink-0 font-mono", children: [
2140
+ /* @__PURE__ */ c("div", { className: "flex space-x-2", children: [
2141
+ /* @__PURE__ */ c("span", { children: [
2142
+ /* @__PURE__ */ r("kbd", { className: "bg-muted px-1 rounded border border-border/60", children: "↑↓" }),
2143
+ " ",
2144
+ "navigate"
2145
+ ] }),
2146
+ /* @__PURE__ */ c("span", { children: [
2147
+ /* @__PURE__ */ r("kbd", { className: "bg-muted px-1 rounded border border-border/60", children: "↵" }),
2148
+ " ",
2149
+ "select"
2150
+ ] })
2151
+ ] }),
2152
+ /* @__PURE__ */ r("span", { children: "ESC to close" })
2153
+ ] })
2154
+ ]
1984
2155
  }
1985
- if (p.mapId) {
1986
- let g = null;
1987
- if (l.visitNodes((m) => {
1988
- var w;
1989
- if (m.getType() === "tab") {
1990
- const C = m;
1991
- ((w = C.getConfig()) == null ? void 0 : w.mapId) === p.mapId && (g = C.getId());
2156
+ )
2157
+ ] });
2158
+ }, sr = ({
2159
+ placeholder: o = "Search...",
2160
+ onSearch: e,
2161
+ results: n,
2162
+ onSelect: t,
2163
+ suggestions: a = [],
2164
+ loading: s = !1,
2165
+ className: l
2166
+ }) => {
2167
+ const [u, i] = A(""), [d, f] = A(!1), [p, m] = A(-1), k = P(null);
2168
+ z(() => {
2169
+ const h = setTimeout(() => {
2170
+ e(u);
2171
+ }, 300);
2172
+ return () => clearTimeout(h);
2173
+ }, [u, e]);
2174
+ const C = a.filter(
2175
+ (h) => h.toLowerCase().includes(u.toLowerCase()) && h.toLowerCase() !== u.toLowerCase()
2176
+ ), x = (h) => {
2177
+ d && C.length > 0 && (h.key === "ArrowDown" ? (h.preventDefault(), m((T) => (T + 1) % C.length)) : h.key === "ArrowUp" ? (h.preventDefault(), m((T) => (T - 1 + C.length) % C.length)) : h.key === "Enter" && p >= 0 && (h.preventDefault(), i(C[p]), f(!1)));
2178
+ };
2179
+ return /* @__PURE__ */ c("div", { ref: k, className: S("flex flex-col h-full bg-background", l), children: [
2180
+ /* @__PURE__ */ c("div", { className: "p-3 border-b border-border/50", children: [
2181
+ /* @__PURE__ */ c("div", { className: "relative", children: [
2182
+ /* @__PURE__ */ r("div", { className: "absolute left-2.5 top-2.5 text-muted-foreground", children: s ? /* @__PURE__ */ r(Ne, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ r(X, { size: 14 }) }),
2183
+ /* @__PURE__ */ r(
2184
+ "input",
2185
+ {
2186
+ type: "text",
2187
+ className: "w-full bg-secondary/50 border border-border rounded-md pl-9 pr-8 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all",
2188
+ placeholder: o,
2189
+ value: u,
2190
+ onChange: (h) => {
2191
+ i(h.target.value), f(!0), m(-1);
2192
+ },
2193
+ onKeyDown: x,
2194
+ onFocus: () => f(!0)
1992
2195
  }
1993
- }), g) {
1994
- l.doAction(B.selectTab(g));
1995
- return;
1996
- }
1997
- }
1998
- if (p.projectId) {
1999
- let g = null;
2000
- if (l.visitNodes((m) => {
2001
- var w;
2002
- if (m.getType() === "tab") {
2003
- const C = m;
2004
- ((w = C.getConfig()) == null ? void 0 : w.projectId) === p.projectId && (g = C.getId());
2196
+ ),
2197
+ u && /* @__PURE__ */ r(
2198
+ "button",
2199
+ {
2200
+ onClick: () => {
2201
+ i(""), e("");
2202
+ },
2203
+ className: "absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",
2204
+ children: /* @__PURE__ */ r(J, { size: 14 })
2005
2205
  }
2006
- }), g) {
2007
- l.doAction(B.selectTab(g));
2008
- return;
2009
- }
2010
- }
2011
- i && l.doAction(
2012
- B.addNode(
2013
- { type: "tab", component: r, name: a || r, config: p },
2014
- i,
2015
- Xe.CENTER,
2016
- -1
2017
2206
  )
2207
+ ] }),
2208
+ d && C.length > 0 && /* @__PURE__ */ r("div", { className: "absolute left-3 right-3 mt-1 bg-popover border shadow-lg rounded-md z-50 py-1 overflow-hidden", children: C.map((h, T) => /* @__PURE__ */ c(
2209
+ "div",
2210
+ {
2211
+ className: S(
2212
+ "px-3 py-1.5 text-xs cursor-pointer flex items-center space-x-2",
2213
+ T === p ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
2214
+ ),
2215
+ onClick: () => {
2216
+ i(h), f(!1);
2217
+ },
2218
+ children: [
2219
+ /* @__PURE__ */ r(He, { size: 12, className: "text-muted-foreground" }),
2220
+ /* @__PURE__ */ r("span", { children: h })
2221
+ ]
2222
+ },
2223
+ h
2224
+ )) })
2225
+ ] }),
2226
+ /* @__PURE__ */ r("div", { className: "flex-1 overflow-y-auto", children: n.length === 0 ? /* @__PURE__ */ r("div", { className: "p-8 text-center text-xs text-muted-foreground italic", children: u ? `No results found for "${u}"` : "Type to start searching..." }) : /* @__PURE__ */ r("div", { className: "py-2", children: n.map((h) => {
2227
+ const T = h.icon;
2228
+ return /* @__PURE__ */ r(
2229
+ "div",
2230
+ {
2231
+ onClick: () => t(h),
2232
+ className: "px-4 py-2 hover:bg-accent/50 cursor-pointer group transition-colors border-l-2 border-transparent hover:border-primary",
2233
+ children: /* @__PURE__ */ c("div", { className: "flex items-start space-x-3", children: [
2234
+ T && /* @__PURE__ */ r("div", { className: "mt-0.5 p-1 rounded bg-muted group-hover:bg-background transition-colors", children: /* @__PURE__ */ r(T, { size: 14, className: "text-muted-foreground group-hover:text-primary" }) }),
2235
+ /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
2236
+ /* @__PURE__ */ c("div", { className: "flex items-center justify-between", children: [
2237
+ /* @__PURE__ */ r("span", { className: "text-xs font-medium truncate", children: h.title }),
2238
+ h.category && /* @__PURE__ */ r("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground font-bold px-1.5 py-0.5 bg-muted rounded", children: h.category })
2239
+ ] }),
2240
+ h.description && /* @__PURE__ */ r("p", { className: "text-[11px] text-muted-foreground truncate mt-0.5", children: h.description })
2241
+ ] })
2242
+ ] })
2243
+ },
2244
+ h.id
2018
2245
  );
2019
- }
2020
- };
2021
- }), Te = F((o, e) => ({
2022
- isOpen: !1,
2023
- type: "alert",
2024
- title: "",
2025
- message: "",
2026
- defaultValue: "",
2027
- resolve: null,
2028
- openAlert: (n, r = "Alert") => new Promise((a) => {
2029
- o({ isOpen: !0, type: "alert", title: r, message: n, defaultValue: "", resolve: a });
2030
- }),
2031
- openConfirm: (n, r = "Confirm") => new Promise((a) => {
2032
- o({ isOpen: !0, type: "confirm", title: r, message: n, defaultValue: "", resolve: a });
2033
- }),
2034
- openPrompt: (n, r = "", a = "Prompt") => new Promise((s) => {
2035
- o({ isOpen: !0, type: "prompt", title: a, message: n, defaultValue: r, resolve: s });
2036
- }),
2037
- close: (n = null) => {
2038
- const { resolve: r } = e();
2039
- r && r(n), o({ isOpen: !1, resolve: null });
2040
- }
2041
- })), qt = ({
2042
- panels: o,
2043
- slashCommands: e,
2044
- menuConfig: n,
2045
- statusBarConfig: r,
2046
- title: a,
2047
- rightMenuBarContent: s,
2048
- centerMenuBarContent: l,
2049
- layoutModel: u
2246
+ }) }) })
2247
+ ] });
2248
+ }, De = (o, e = 0) => o.reduce((n, t) => (n.push({ ...t, level: e }), t.isOpen && t.children && n.push(...De(t.children, e + 1)), n), []), ar = ({
2249
+ data: o,
2250
+ onToggle: e,
2251
+ onActivate: n,
2252
+ onMoveNode: t,
2253
+ actions: a,
2254
+ onNewFile: s,
2255
+ onNewFolder: l,
2256
+ onRename: u,
2257
+ onDelete: i,
2258
+ indent: d = 12,
2259
+ virtualized: f = !0,
2260
+ className: p
2050
2261
  }) => {
2051
- const { model: i, setModel: d, isTabDirty: p, setTabDirty: g } = zt(), m = q((N) => N.theme), w = W((N) => N.setPanels), C = Q((N) => N.setSlashCommands), x = Se((N) => N.setWidgets);
2262
+ const [m, k] = A(null), [C, x] = A(null), h = R(() => De(o), [o]);
2052
2263
  z(() => {
2053
- o && w(o);
2054
- }, [o, w]), z(() => {
2055
- e && C(e);
2056
- }, [e, C]), z(() => {
2057
- n && Ne.setMenus(n);
2058
- }, [n]), z(() => {
2059
- r && x(r);
2060
- }, [r, x]);
2061
- const h = (N) => {
2062
- try {
2063
- const b = N.getComponent(), v = N.getConfig() || {}, f = b ? Ot.get(b) : void 0;
2064
- return f ? /* @__PURE__ */ t(f, { node: N, ...v }) : /* @__PURE__ */ c("div", { className: "p-4 text-sm", children: [
2065
- "Unknown Component: ",
2066
- b
2067
- ] });
2068
- } catch (b) {
2069
- return console.error("Error in component factory:", b), /* @__PURE__ */ c("div", { className: "p-8 text-destructive bg-destructive/10 border border-destructive/20 h-full flex items-center justify-center", children: [
2070
- "Error rendering component: ",
2071
- b instanceof Error ? b.message : "Unknown error"
2072
- ] });
2264
+ x(null);
2265
+ }, [o]);
2266
+ const I = (a ?? [
2267
+ {
2268
+ id: "new-file",
2269
+ label: "New File",
2270
+ icon: /* @__PURE__ */ r(We, { size: 14 }),
2271
+ onSelect: ({ nodeId: g }) => s == null ? void 0 : s(g)
2272
+ },
2273
+ {
2274
+ id: "new-folder",
2275
+ label: "New Folder",
2276
+ icon: /* @__PURE__ */ r(Be, { size: 14 }),
2277
+ onSelect: ({ nodeId: g }) => l == null ? void 0 : l(g)
2278
+ },
2279
+ {
2280
+ id: "rename",
2281
+ label: "Rename",
2282
+ icon: /* @__PURE__ */ r(Ge, { size: 14 }),
2283
+ divider: !0,
2284
+ showFor: ["file", "folder"],
2285
+ onSelect: ({ nodeId: g }) => g && (u == null ? void 0 : u(g))
2286
+ },
2287
+ {
2288
+ id: "delete",
2289
+ label: "Delete",
2290
+ icon: /* @__PURE__ */ r(Ve, { size: 14, className: "text-destructive" }),
2291
+ showFor: ["file", "folder"],
2292
+ onSelect: ({ nodeId: g }) => g && (i == null ? void 0 : i(g))
2073
2293
  }
2074
- }, T = (N) => {
2075
- if (N.type !== B.DELETE_TAB) return N;
2076
- const b = i.getNodeById(N.data.node);
2077
- if (!b || !p(b.getId())) return N;
2078
- Te.getState().openConfirm(
2079
- `Tab "${b.getName()}" has unsaved changes. Are you sure you want to close it?`
2080
- ).then((v) => {
2081
- v && (g(b.getId(), !1), i.doAction(N));
2294
+ ]).filter(
2295
+ (g) => !g.showFor || m && g.showFor.includes(m.scope)
2296
+ ).map((g) => ({
2297
+ label: g.label,
2298
+ icon: g.icon,
2299
+ divider: g.divider,
2300
+ onClick: () => m && g.onSelect(m.context)
2301
+ })), N = (g, b, E) => {
2302
+ g.preventDefault(), g.stopPropagation(), k({
2303
+ x: g.clientX,
2304
+ y: g.clientY,
2305
+ scope: E,
2306
+ context: { nodeId: (b == null ? void 0 : b.id) ?? null, node: b }
2082
2307
  });
2308
+ }, y = (g) => {
2309
+ const b = h[g], E = b.type === "folder";
2310
+ return /* @__PURE__ */ c(
2311
+ "div",
2312
+ {
2313
+ role: "treeitem",
2314
+ "aria-expanded": E ? !!b.isOpen : void 0,
2315
+ "aria-level": b.level + 1,
2316
+ tabIndex: 0,
2317
+ draggable: !0,
2318
+ onDragStart: (w) => {
2319
+ w.dataTransfer.setData("text/plain", b.id), w.dataTransfer.effectAllowed = "move";
2320
+ },
2321
+ onDragOver: (w) => {
2322
+ E && (w.preventDefault(), x(b.id));
2323
+ },
2324
+ onDragLeave: () => x(null),
2325
+ onDrop: (w) => {
2326
+ w.preventDefault(), x(null);
2327
+ const L = w.dataTransfer.getData("text/plain");
2328
+ L && L !== b.id && E && (t == null || t(L, b.id));
2329
+ },
2330
+ onClick: () => E && (e == null ? void 0 : e(b)),
2331
+ onDoubleClick: () => n == null ? void 0 : n(b),
2332
+ onKeyDown: (w) => {
2333
+ w.key === "Enter" && (w.preventDefault(), E ? e == null || e(b) : n == null || n(b));
2334
+ },
2335
+ onContextMenu: (w) => N(w, b, b.type),
2336
+ style: { paddingLeft: `${b.level * d + 8}px` },
2337
+ className: S(
2338
+ "flex items-center py-1 px-2 cursor-pointer hover:bg-accent hover:text-accent-foreground select-none text-xs",
2339
+ "transition-colors duration-150 relative focus:outline-none focus:ring-1 focus:ring-ring",
2340
+ C === b.id && "bg-primary/20 ring-1 ring-primary/50 rounded-sm"
2341
+ ),
2342
+ children: [
2343
+ /* @__PURE__ */ r("div", { className: "w-4 h-4 mr-1 flex items-center justify-center", children: E && (b.isOpen ? /* @__PURE__ */ r(ke, { size: 14 }) : /* @__PURE__ */ r(ye, { size: 14 })) }),
2344
+ /* @__PURE__ */ r("div", { className: "mr-2", children: E ? /* @__PURE__ */ r(Ye, { size: 14, className: "text-blue-400 fill-blue-400/20" }) : /* @__PURE__ */ r(qe, { size: 14, className: "text-muted-foreground" }) }),
2345
+ /* @__PURE__ */ r("span", { className: "truncate", children: b.label })
2346
+ ]
2347
+ },
2348
+ b.id
2349
+ );
2083
2350
  };
2084
2351
  return /* @__PURE__ */ c(
2085
2352
  "div",
2086
2353
  {
2087
- className: `flex flex-col h-screen w-screen bg-background text-foreground overflow-hidden theme-${m}`,
2354
+ role: "tree",
2355
+ className: S("h-full w-full bg-muted/30", p),
2356
+ onContextMenu: (g) => N(g, null, "background"),
2088
2357
  children: [
2089
- /* @__PURE__ */ t(
2090
- Ct,
2358
+ f ? /* @__PURE__ */ r(
2359
+ et,
2091
2360
  {
2092
- title: a,
2093
- center: l,
2094
- right: s
2361
+ style: { height: "100%" },
2362
+ totalCount: h.length,
2363
+ itemContent: y
2095
2364
  }
2096
- ),
2097
- /* @__PURE__ */ c("div", { className: "flex-1 flex overflow-hidden", children: [
2098
- /* @__PURE__ */ t(xt, {}),
2099
- /* @__PURE__ */ t(St, {}),
2100
- /* @__PURE__ */ c("div", { className: "flex-1 flex flex-col min-w-0 bg-card", children: [
2101
- /* @__PURE__ */ t("div", { className: "flex-1 relative h-full w-full", children: /* @__PURE__ */ t(
2102
- Ze,
2103
- {
2104
- model: u || i,
2105
- factory: h,
2106
- onModelChange: (N) => {
2107
- u || d(N);
2108
- },
2109
- onAction: T
2110
- }
2111
- ) }),
2112
- /* @__PURE__ */ t(Dt, {})
2113
- ] }),
2114
- /* @__PURE__ */ t(wt, {})
2115
- ] }),
2116
- /* @__PURE__ */ t(Tt, {})
2365
+ ) : /* @__PURE__ */ r("div", { className: "h-full overflow-auto", children: h.map((g, b) => y(b)) }),
2366
+ m && I.length > 0 && /* @__PURE__ */ r(
2367
+ Kt,
2368
+ {
2369
+ x: m.x,
2370
+ y: m.y,
2371
+ items: I,
2372
+ onClose: () => k(null)
2373
+ }
2374
+ )
2117
2375
  ]
2118
2376
  }
2119
2377
  );
2120
- }, Vt = ({
2121
- shortcutKey: o = "p",
2122
- ...e
2123
- }) => {
2124
- const [n, r] = O(!1);
2125
- return z(() => {
2126
- if (o === null) return;
2127
- const a = (s) => {
2128
- (s.metaKey || s.ctrlKey) && s.shiftKey && s.key.toLowerCase() === o && (s.preventDefault(), r((l) => !l));
2129
- };
2130
- return window.addEventListener("keydown", a), () => window.removeEventListener("keydown", a);
2131
- }, [o]), /* @__PURE__ */ t(
2132
- st,
2133
- {
2134
- ...e,
2135
- open: n,
2136
- commands: V.getCommands(),
2137
- onSelect: (a) => {
2138
- a.execute(), r(!1);
2139
- },
2140
- onClose: () => r(!1)
2141
- }
2142
- );
2143
- }, Qt = (o) => {
2144
- const { isOpen: e, type: n, title: r, message: a, defaultValue: s, close: l } = Te();
2145
- return /* @__PURE__ */ t(
2146
- dt,
2147
- {
2148
- ...o,
2149
- open: e,
2150
- type: n,
2151
- title: r,
2152
- message: a,
2153
- defaultValue: s,
2154
- onConfirm: (d) => {
2155
- n === "prompt" ? l(d ?? "") : n === "confirm" ? l(!0) : l();
2156
- },
2157
- onCancel: () => {
2158
- n === "prompt" ? l(null) : n === "confirm" ? l(!1) : l();
2159
- }
2160
- }
2161
- );
2162
- }, Xt = (o) => {
2163
- const e = q((r) => r.theme), n = q((r) => r.setTheme);
2164
- return /* @__PURE__ */ t(ht, { ...o, value: e, onChange: n });
2165
- }, ue = "nexus-shell-user-profile", me = {
2166
- name: "David Tech",
2167
- role: "Shell Architect",
2168
- email: "david@techmuch.io",
2169
- avatarUrl: "",
2170
- customAvatar: ""
2171
- }, H = F((o) => {
2172
- let e = { ...me };
2173
- if (typeof window < "u")
2174
- try {
2175
- const r = localStorage.getItem(ue);
2176
- r && (e = { ...me, ...JSON.parse(r) });
2177
- } catch (r) {
2178
- console.error("Failed to parse saved user profile:", r);
2179
- }
2180
- const n = (r) => {
2181
- if (typeof window < "u")
2182
- try {
2183
- localStorage.setItem(
2184
- ue,
2185
- JSON.stringify({
2186
- name: r.name,
2187
- role: r.role,
2188
- email: r.email,
2189
- avatarUrl: r.avatarUrl,
2190
- customAvatar: r.customAvatar
2191
- })
2192
- );
2193
- } catch (a) {
2194
- console.error("Failed to save user profile:", a);
2195
- }
2196
- };
2197
- return {
2198
- ...e,
2199
- updateProfile: (r) => o((a) => {
2200
- const s = { ...a, ...r };
2201
- return n(s), r;
2202
- }),
2203
- setCustomAvatar: (r) => o((a) => {
2204
- const s = { ...a, customAvatar: r };
2205
- return n(s), { customAvatar: r };
2206
- }),
2207
- clearCustomAvatar: () => o((r) => {
2208
- const a = { ...r, customAvatar: "" };
2209
- return n(a), { customAvatar: "" };
2210
- })
2211
- };
2212
- }), Zt = (o) => {
2213
- const e = H((d) => d.name), n = H((d) => d.role), r = H((d) => d.email), a = H((d) => d.avatarUrl), s = H((d) => d.customAvatar), l = H((d) => d.updateProfile), u = H((d) => d.setCustomAvatar);
2214
- return /* @__PURE__ */ t(
2215
- bt,
2216
- {
2217
- ...o,
2218
- profile: { name: e, role: n, email: r, avatarUrl: s || a },
2219
- onProfileChange: l,
2220
- onAvatarChange: (d) => {
2221
- const p = new FileReader();
2222
- p.onloadend = () => {
2223
- typeof p.result == "string" && u(p.result);
2224
- }, p.readAsDataURL(d);
2225
- }
2226
- }
2227
- );
2228
- };
2229
- class Lt {
2230
- constructor() {
2231
- J(this, "plugins", /* @__PURE__ */ new Map());
2232
- J(this, "loaders", /* @__PURE__ */ new Map());
2233
- J(this, "statuses", /* @__PURE__ */ new Map());
2234
- }
2235
- registerPlugin(e) {
2236
- if (this.plugins.has(e.id)) {
2237
- console.warn(`Plugin ${e.id} is already registered.`);
2238
- return;
2239
- }
2240
- this.plugins.set(e.id, e), this.statuses.set(e.id, "registered"), console.log(`Plugin ${e.name} (${e.id}) registered.`);
2241
- }
2242
- registerLazyPlugin(e, n) {
2243
- if (this.loaders.has(e) || this.plugins.has(e)) {
2244
- console.warn(`Plugin ${e} is already registered or has a loader.`);
2245
- return;
2246
- }
2247
- this.loaders.set(e, n), this.statuses.set(e, "inactive"), console.log(`Lazy plugin loader for ${e} registered.`);
2248
- }
2249
- async activatePlugin(e) {
2250
- let n = this.plugins.get(e);
2251
- if (!n && this.loaders.has(e))
2252
- try {
2253
- n = await this.loaders.get(e)(), this.plugins.set(e, n), this.statuses.set(e, "registered"), console.log(`Lazy plugin ${e} loaded.`);
2254
- } catch (r) {
2255
- console.error(`Failed to load lazy plugin ${e}`, r), this.statuses.set(e, "failed");
2256
- return;
2257
- }
2258
- if (n)
2259
- try {
2260
- this.statuses.set(e, "activating"), n.activate(), this.statuses.set(e, "active"), console.log(`Plugin ${n.name} activated.`);
2261
- } catch (r) {
2262
- console.error(`Failed to activate plugin ${e}`, r), this.statuses.set(e, "failed");
2263
- }
2264
- else
2265
- console.warn(`Plugin ${e} not found for activation.`), this.statuses.set(e, "failed");
2266
- }
2267
- async deactivatePlugin(e) {
2268
- const n = this.plugins.get(e);
2269
- if (n)
2270
- try {
2271
- n.deactivate(), this.statuses.set(e, "deactivated"), console.log(`Plugin ${n.name} deactivated.`);
2272
- } catch (r) {
2273
- console.error(`Failed to deactivate plugin ${e}`, r), this.statuses.set(e, "failed");
2274
- }
2275
- }
2276
- getPluginStatus(e) {
2277
- return this.statuses.get(e);
2278
- }
2279
- getPluginStatuses() {
2280
- const e = {};
2281
- return this.statuses.forEach((n, r) => {
2282
- e[r] = n;
2283
- }), e;
2284
- }
2285
- getPlugin(e) {
2286
- return this.plugins.get(e);
2287
- }
2288
- getAllPlugins() {
2289
- return Array.from(this.plugins.values());
2290
- }
2291
- }
2292
- const er = new Lt(), tr = () => {
2293
- z(() => {
2294
- const o = (e) => {
2295
- const n = V.getCommands();
2296
- for (const r of n)
2297
- if (r.keybinding && At(e, r.keybinding)) {
2298
- e.preventDefault(), r.execute();
2299
- break;
2300
- }
2301
- };
2302
- return window.addEventListener("keydown", o), () => window.removeEventListener("keydown", o);
2303
- }, []);
2304
- };
2305
- function At(o, e) {
2306
- var m;
2307
- const n = e.split("+"), r = (m = n.pop()) == null ? void 0 : m.toLowerCase(), a = n.includes("Control") || n.includes("Ctrl"), s = n.includes("Shift"), l = n.includes("Alt"), u = n.includes("Meta") || n.includes("Cmd"), i = o.ctrlKey, d = o.shiftKey, p = o.altKey, g = o.metaKey;
2308
- return o.key.toLowerCase() === r && i === a && d === s && p === l && g === u;
2309
- }
2310
- const rr = (o) => {
2311
2378
  };
2312
2379
  export {
2313
- tt as ActivityBar,
2314
- Yt as AppTitle,
2315
- nt as ChatPane,
2316
- st as CommandPalette,
2317
- kt as CommandRegistry,
2318
- xt as ConnectedActivityBar,
2319
- wt as ConnectedChatPane,
2320
- Vt as ConnectedCommandPalette,
2321
- Ct as ConnectedMenuBar,
2322
- Qt as ConnectedModal,
2323
- St as ConnectedSidebarPane,
2324
- Tt as ConnectedStatusBar,
2325
- Dt as ConnectedTerminalPane,
2326
- Xt as ConnectedThemeSwitcher,
2327
- Zt as ConnectedUserProfile,
2328
- at as ContextMenu,
2329
- ut as DEFAULT_SETTINGS_THEMES,
2330
- gt as DEFAULT_THEME_OPTIONS,
2331
- Ht as DataGrid,
2332
- lt as MenuBar,
2333
- Nt as MenuRegistry,
2334
- dt as Modal,
2335
- qt as NexusWorkspaceShell,
2336
- Wt as QuickSearch,
2337
- Bt as SearchWidget,
2338
- mt as SettingsPanel,
2339
- qt as ShellLayout,
2340
- te as SidebarPane,
2341
- ft as StatusBar,
2342
- pt as TerminalPane,
2343
- ht as ThemeSwitcher,
2344
- Gt as TreeWidget,
2345
- bt as UserProfile,
2380
+ rt as ActivityBar,
2381
+ rr as AppTitle,
2382
+ st as ChatPane,
2383
+ It as CommandPalette,
2384
+ ut as CommandRegistry,
2385
+ nt as ConnectedActivityBar,
2386
+ it as ConnectedChatPane,
2387
+ Xt as ConnectedCommandPalette,
2388
+ mt as ConnectedMenuBar,
2389
+ Zt as ConnectedModal,
2390
+ gt as ConnectedSidebarPane,
2391
+ bt as ConnectedStatusBar,
2392
+ yt as ConnectedTerminalPane,
2393
+ er as ConnectedThemeSwitcher,
2394
+ tr as ConnectedUserProfile,
2395
+ Kt as ContextMenu,
2396
+ Vt as DEFAULT_COMMAND_IDS,
2397
+ ft as DEFAULT_SETTINGS_THEMES,
2398
+ Lt as DEFAULT_THEME_OPTIONS,
2399
+ nr as DataGrid,
2400
+ dt as MenuBar,
2401
+ ct as MenuRegistry,
2402
+ At as Modal,
2403
+ or as QuickSearch,
2404
+ sr as SearchWidget,
2405
+ pt as SettingsPanel,
2406
+ Gt as ShellLayout,
2407
+ re as SidebarPane,
2408
+ ht as StatusBar,
2409
+ xt as TerminalPane,
2410
+ Mt as ThemeSwitcher,
2411
+ ar as TreeWidget,
2412
+ Pt as UserProfile,
2346
2413
  S as cn,
2347
- V as commandRegistry,
2348
- Ot as componentRegistry,
2349
- rr as initializeShell,
2350
- Ne as menuRegistry,
2351
- er as pluginRegistry,
2414
+ B as commandRegistry,
2415
+ Nt as componentRegistry,
2416
+ Yt as initializeShell,
2417
+ le as menuRegistry,
2418
+ qt as pluginRegistry,
2352
2419
  Q as useChatStore,
2353
- tr as useKeyboardShortcuts,
2354
- zt as useLayoutStore,
2420
+ Qt as useKeyboardShortcuts,
2421
+ kt as useLayoutStore,
2355
2422
  Te as useModalStore,
2356
- le as useRightSidebarStore,
2357
- W as useSidebarStore,
2358
- Se as useStatusBarStore,
2359
- Y as useTerminalStore,
2360
- q as useThemeStore,
2361
- H as useUserProfileStore
2423
+ ae as useRightSidebarStore,
2424
+ F as useSidebarStore,
2425
+ ie as useStatusBarStore,
2426
+ V as useTerminalStore,
2427
+ Y as useThemeStore,
2428
+ W as useUserProfileStore
2362
2429
  };