@ggui-ai/dev-stack 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19920,7 +19920,7 @@ var require_jsx_runtime = __commonJS({
19920
19920
  });
19921
19921
 
19922
19922
  // hub-preview-client/main.tsx
19923
- var import_react45 = __toESM(require_react(), 1);
19923
+ var import_react46 = __toESM(require_react(), 1);
19924
19924
  var import_client = __toESM(require_client(), 1);
19925
19925
 
19926
19926
  // ../mcp-apps-react/dist/chunk-7P6ASYW6.mjs
@@ -20437,8 +20437,8 @@ function makeActionEnvelope(parts) {
20437
20437
  }
20438
20438
 
20439
20439
  // ../mcp-apps-react/dist/index.mjs
20440
- var import_react7 = __toESM(require_react(), 1);
20441
20440
  var import_react8 = __toESM(require_react(), 1);
20441
+ var import_react9 = __toESM(require_react(), 1);
20442
20442
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
20443
20443
 
20444
20444
  // ../wire/dist/index.js
@@ -20452,6 +20452,7 @@ __export(dist_exports, {
20452
20452
  buildWireConfig: () => buildWireConfig,
20453
20453
  connectionSource: () => connectionSource,
20454
20454
  useAction: () => useAction,
20455
+ useActionPending: () => useActionPending,
20455
20456
  useActionSpent: () => useActionSpent,
20456
20457
  useApp: () => useApp,
20457
20458
  useAuth: () => useAuth,
@@ -20554,8 +20555,19 @@ function useActionSpent(actionName) {
20554
20555
  return (0, import_react3.useSyncExternalStore)(subscribe, read, read);
20555
20556
  }
20556
20557
 
20557
- // ../wire/dist/useGguiContext.js
20558
+ // ../wire/dist/action-pending.js
20558
20559
  var import_react4 = __toESM(require_react(), 1);
20560
+ var ActionPendingContext = (0, import_react4.createContext)(null);
20561
+ var noSubscription2 = () => () => void 0;
20562
+ function useActionPending(actionName) {
20563
+ const source = (0, import_react4.useContext)(ActionPendingContext);
20564
+ const subscribe = (0, import_react4.useCallback)((listener) => source === null ? noSubscription2() : source.subscribe(listener), [source]);
20565
+ const read = (0, import_react4.useCallback)(() => source === null ? false : source.isPending(actionName), [source, actionName]);
20566
+ return (0, import_react4.useSyncExternalStore)(subscribe, read, read);
20567
+ }
20568
+
20569
+ // ../wire/dist/useGguiContext.js
20570
+ var import_react5 = __toESM(require_react(), 1);
20559
20571
  function useGguiContext(slotName) {
20560
20572
  const contextName = slotName.length === 0 ? "Context" : slotName.charAt(0).toUpperCase() + slotName.slice(1) + "Context";
20561
20573
  const registry = globalThis.__ggui__?.contexts;
@@ -20563,19 +20575,19 @@ function useGguiContext(slotName) {
20563
20575
  if (!ctx) {
20564
20576
  throw new Error(`[ggui] useGguiContext('${slotName}'): no Context registered. The contract must declare 'contextSpec.${slotName}' AND the runtime must have synthesized the per-slot React Context at boot. If you see this in production code generated by the LLM, the boilerplate's destructure line drifted from the contract.`);
20565
20577
  }
20566
- return (0, import_react4.useContext)(ctx);
20578
+ return (0, import_react5.useContext)(ctx);
20567
20579
  }
20568
20580
 
20569
20581
  // ../wire/dist/useStream.js
20570
- var import_react5 = __toESM(require_react(), 1);
20582
+ var import_react6 = __toESM(require_react(), 1);
20571
20583
  function useStream(channelName) {
20572
20584
  const { subscribe } = useWireContext();
20573
- const [latest, setLatest] = (0, import_react5.useState)(null);
20574
- const [all, setAll] = (0, import_react5.useState)([]);
20575
- const [isComplete, setIsComplete] = (0, import_react5.useState)(false);
20576
- const allRef = (0, import_react5.useRef)(all);
20585
+ const [latest, setLatest] = (0, import_react6.useState)(null);
20586
+ const [all, setAll] = (0, import_react6.useState)([]);
20587
+ const [isComplete, setIsComplete] = (0, import_react6.useState)(false);
20588
+ const allRef = (0, import_react6.useRef)(all);
20577
20589
  allRef.current = all;
20578
- (0, import_react5.useEffect)(() => {
20590
+ (0, import_react6.useEffect)(() => {
20579
20591
  return subscribe(channelName, (delivery) => {
20580
20592
  const typed = delivery.payload;
20581
20593
  setLatest(typed);
@@ -20613,7 +20625,7 @@ function useApp() {
20613
20625
  }
20614
20626
 
20615
20627
  // ../wire/dist/useRender.js
20616
- var import_react6 = __toESM(require_react(), 1);
20628
+ var import_react7 = __toESM(require_react(), 1);
20617
20629
 
20618
20630
  // ../wire/dist/connection-store.js
20619
20631
  var ConnectionWriterConflictError = class extends Error {
@@ -20710,7 +20722,7 @@ var connectionSource = documentStore.source;
20710
20722
  // ../wire/dist/useRender.js
20711
20723
  function useRender() {
20712
20724
  const { render } = useWireContext();
20713
- const isConnected = (0, import_react6.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20725
+ const isConnected = (0, import_react7.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20714
20726
  return { sessionId: render.sessionId, isConnected };
20715
20727
  }
20716
20728
 
@@ -20804,6 +20816,7 @@ var StreamBus = class {
20804
20816
  }
20805
20817
  }
20806
20818
  };
20819
+ var DEFAULT_ACTION_PENDING_BOUND_MS = 2e4;
20807
20820
  function buildWireConfig(opts) {
20808
20821
  let internalSeq = 0;
20809
20822
  const nextClientSeq = opts.nextClientSeq ?? (() => {
@@ -20828,8 +20841,43 @@ function buildWireConfig(opts) {
20828
20841
  }
20829
20842
  };
20830
20843
  opts.spentInputsChanged?.(notifySpent);
20844
+ const pendingBoundMs = opts.actionPendingBoundMs ?? DEFAULT_ACTION_PENDING_BOUND_MS;
20845
+ const pending = /* @__PURE__ */ new Map();
20846
+ const pendingListeners = /* @__PURE__ */ new Set();
20847
+ const notifyPending = () => {
20848
+ for (const listener of [...pendingListeners])
20849
+ listener();
20850
+ };
20851
+ const markPending = (actionName) => {
20852
+ const previous = pending.get(actionName);
20853
+ if (previous !== void 0)
20854
+ clearTimeout(previous);
20855
+ pending.set(actionName, setTimeout(() => {
20856
+ pending.delete(actionName);
20857
+ notifyPending();
20858
+ }, pendingBoundMs));
20859
+ notifyPending();
20860
+ };
20861
+ const actionPending = {
20862
+ isPending: (actionName) => pending.has(actionName),
20863
+ subscribe: (listener) => {
20864
+ pendingListeners.add(listener);
20865
+ return () => {
20866
+ pendingListeners.delete(listener);
20867
+ };
20868
+ }
20869
+ };
20870
+ opts.pendingInputsChanged?.(() => {
20871
+ if (pending.size === 0)
20872
+ return;
20873
+ for (const timer of pending.values())
20874
+ clearTimeout(timer);
20875
+ pending.clear();
20876
+ notifyPending();
20877
+ });
20831
20878
  return {
20832
20879
  actionSpent,
20880
+ actionPending,
20833
20881
  app: opts.app,
20834
20882
  render: opts.render,
20835
20883
  auth: opts.auth,
@@ -20869,6 +20917,7 @@ function buildWireConfig(opts) {
20869
20917
  notifySpent();
20870
20918
  }
20871
20919
  opts.emitEnvelope(envelope);
20920
+ markPending(actionName);
20872
20921
  },
20873
20922
  subscribe: (channelName, handler) => {
20874
20923
  return opts.streamBus.subscribe(channelName, (env) => {
@@ -20883,65 +20932,65 @@ function buildWireConfig(opts) {
20883
20932
  }
20884
20933
 
20885
20934
  // ../mcp-apps-react/dist/index.mjs
20886
- var import_react9 = __toESM(require_react(), 1);
20935
+ var import_react10 = __toESM(require_react(), 1);
20887
20936
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
20888
20937
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
20889
- var import_react10 = __toESM(require_react(), 1);
20890
20938
  var import_react11 = __toESM(require_react(), 1);
20939
+ var import_react12 = __toESM(require_react(), 1);
20891
20940
  var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
20892
20941
  var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
20893
20942
  var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
20894
20943
  var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
20895
- var import_react12 = __toESM(require_react(), 1);
20896
20944
  var import_react13 = __toESM(require_react(), 1);
20945
+ var import_react14 = __toESM(require_react(), 1);
20897
20946
  var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
20898
20947
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
20899
20948
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
20900
- var import_react14 = __toESM(require_react(), 1);
20901
- var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20902
20949
  var import_react15 = __toESM(require_react(), 1);
20903
- var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20950
+ var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20904
20951
  var import_react16 = __toESM(require_react(), 1);
20952
+ var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20953
+ var import_react17 = __toESM(require_react(), 1);
20905
20954
  var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
20906
20955
  var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
20907
- var import_react17 = __toESM(require_react(), 1);
20908
- var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20909
20956
  var import_react18 = __toESM(require_react(), 1);
20910
- var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20957
+ var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20911
20958
  var import_react19 = __toESM(require_react(), 1);
20959
+ var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20960
+ var import_react20 = __toESM(require_react(), 1);
20912
20961
  var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
20913
20962
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
20914
20963
  var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
20915
- var import_react20 = __toESM(require_react(), 1);
20964
+ var import_react21 = __toESM(require_react(), 1);
20916
20965
  var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
20917
20966
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
20918
20967
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
20919
- var import_react21 = __toESM(require_react(), 1);
20920
- var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20921
20968
  var import_react22 = __toESM(require_react(), 1);
20969
+ var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20970
+ var import_react23 = __toESM(require_react(), 1);
20922
20971
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
20923
20972
  var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
20924
- var import_react23 = __toESM(require_react(), 1);
20925
- var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20926
20973
  var import_react24 = __toESM(require_react(), 1);
20927
- var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20974
+ var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20928
20975
  var import_react25 = __toESM(require_react(), 1);
20929
- var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20976
+ var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20930
20977
  var import_react26 = __toESM(require_react(), 1);
20931
- var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20978
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20932
20979
  var import_react27 = __toESM(require_react(), 1);
20980
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20933
20981
  var import_react28 = __toESM(require_react(), 1);
20934
- var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20935
20982
  var import_react29 = __toESM(require_react(), 1);
20983
+ var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20984
+ var import_react30 = __toESM(require_react(), 1);
20936
20985
  var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
20937
20986
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
20938
20987
  var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
20939
20988
  var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
20940
- var import_react30 = __toESM(require_react(), 1);
20941
- var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20942
20989
  var import_react31 = __toESM(require_react(), 1);
20943
- var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20990
+ var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20944
20991
  var import_react32 = __toESM(require_react(), 1);
20992
+ var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20993
+ var import_react33 = __toESM(require_react(), 1);
20945
20994
  var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
20946
20995
  var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
20947
20996
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
@@ -20949,38 +20998,38 @@ var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
20949
20998
  var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
20950
20999
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
20951
21000
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
20952
- var import_react33 = __toESM(require_react(), 1);
21001
+ var import_react34 = __toESM(require_react(), 1);
20953
21002
  var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
20954
21003
  var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
20955
- var import_react34 = __toESM(require_react(), 1);
21004
+ var import_react35 = __toESM(require_react(), 1);
20956
21005
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
20957
21006
  var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
20958
- var import_react35 = __toESM(require_react(), 1);
21007
+ var import_react36 = __toESM(require_react(), 1);
20959
21008
  var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
20960
21009
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
20961
- var import_react36 = __toESM(require_react(), 1);
21010
+ var import_react37 = __toESM(require_react(), 1);
20962
21011
  var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
20963
21012
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
20964
- var import_react37 = __toESM(require_react(), 1);
20965
- var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
20966
21013
  var import_react38 = __toESM(require_react(), 1);
21014
+ var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
21015
+ var import_react39 = __toESM(require_react(), 1);
20967
21016
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
20968
21017
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
20969
21018
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
20970
- var import_react39 = __toESM(require_react(), 1);
20971
- var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20972
21019
  var import_react40 = __toESM(require_react(), 1);
20973
- var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
21020
+ var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20974
21021
  var import_react41 = __toESM(require_react(), 1);
20975
- var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
21022
+ var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20976
21023
  var import_react42 = __toESM(require_react(), 1);
21024
+ var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
21025
+ var import_react43 = __toESM(require_react(), 1);
20977
21026
  var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
20978
21027
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
20979
- var import_react43 = __toESM(require_react(), 1);
21028
+ var import_react44 = __toESM(require_react(), 1);
20980
21029
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
20981
21030
  var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
20982
- var import_react44 = __toESM(require_react(), 1);
20983
- var GguiContext = (0, import_react8.createContext)(null);
21031
+ var import_react45 = __toESM(require_react(), 1);
21032
+ var GguiContext = (0, import_react9.createContext)(null);
20984
21033
  var KNOWN_PERMISSION_NAMES_SET2 = new Set(KNOWN_PERMISSION_NAMES);
20985
21034
  var primitives_exports = {};
20986
21035
  __export2(primitives_exports, {
@@ -21149,9 +21198,9 @@ function frameAttributes(frame) {
21149
21198
  function renderWithTrait(trait, traitProps, root, children) {
21150
21199
  const marks = frameAttributes(root.frame);
21151
21200
  if (trait === void 0) {
21152
- return (0, import_react10.createElement)("div", { className: root.className, style: root.style, ...marks }, children);
21201
+ return (0, import_react11.createElement)("div", { className: root.className, style: root.style, ...marks }, children);
21153
21202
  }
21154
- return (0, import_react10.createElement)(trait, { ...traitProps, className: root.className, style: root.style, ...marks }, children);
21203
+ return (0, import_react11.createElement)(trait, { ...traitProps, className: root.className, style: root.style, ...marks }, children);
21155
21204
  }
21156
21205
  function resolveToneCss(tone) {
21157
21206
  switch (tone) {
@@ -21335,7 +21384,7 @@ function Stack(props) {
21335
21384
  return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21336
21385
  }
21337
21386
  function Row(props) {
21338
- return (0, import_react11.createElement)(Stack, { ...props, direction: "horizontal" });
21387
+ return (0, import_react12.createElement)(Stack, { ...props, direction: "horizontal" });
21339
21388
  }
21340
21389
  var BREAKPOINTS = [
21341
21390
  ["sm", 640],
@@ -21504,7 +21553,7 @@ function Text({ children, size = "base", weight = "normal", caps = false, tone,
21504
21553
  ...style
21505
21554
  };
21506
21555
  const elementProps = { id, htmlFor, className, style: textStyle };
21507
- return (0, import_react12.createElement)(is, elementProps, children);
21556
+ return (0, import_react13.createElement)(is, elementProps, children);
21508
21557
  }
21509
21558
  var fontFamily = {
21510
21559
  sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
@@ -21606,7 +21655,7 @@ function Heading({ children, level = 2, tone, align, style, className }) {
21606
21655
  letterSpacing: `var(--ggui-letter-spacing-heading, ${fallback.letterSpacing})`
21607
21656
  };
21608
21657
  const resolvedColor = tone ? resolveToneCss(tone) : "var(--ggui-color-onContainer, #18181b)";
21609
- return (0, import_react13.createElement)(tag, {
21658
+ return (0, import_react14.createElement)(tag, {
21610
21659
  className,
21611
21660
  style: {
21612
21661
  ...headingStyle,
@@ -21754,7 +21803,7 @@ var sizeStyles2 = {
21754
21803
  }
21755
21804
  };
21756
21805
  function Input({ label, placeholder, value, onChange, type = "text", error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21757
- const uniqueId = (0, import_react14.useId)();
21806
+ const uniqueId = (0, import_react15.useId)();
21758
21807
  const inputId = `${uniqueId}-input`;
21759
21808
  const messageId = `${uniqueId}-message`;
21760
21809
  const hasError = Boolean(error);
@@ -21783,7 +21832,7 @@ function Input({ label, placeholder, value, onChange, type = "text", error, help
21783
21832
  }, children: error || helperText })] });
21784
21833
  }
21785
21834
  function TextArea({ label, placeholder, value, onChange, rows = 4, error, helperText, required, disabled, maxLength, showCount, autoResize, style, className, ...rest }) {
21786
- const uniqueId = (0, import_react15.useId)();
21835
+ const uniqueId = (0, import_react16.useId)();
21787
21836
  const textareaId = `${uniqueId}-textarea`;
21788
21837
  const messageId = `${uniqueId}-message`;
21789
21838
  const hasError = Boolean(error);
@@ -21825,7 +21874,7 @@ var sizeStyles3 = {
21825
21874
  lg: { padding: "12px 14px", fontSize: "var(--ggui-font-size-base, 16px)" }
21826
21875
  };
21827
21876
  function Select({ label, value, onChange, options, placeholder, error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21828
- const uniqueId = (0, import_react16.useId)();
21877
+ const uniqueId = (0, import_react17.useId)();
21829
21878
  const selectId = `${uniqueId}-select`;
21830
21879
  const messageId = `${uniqueId}-message`;
21831
21880
  const hasError = Boolean(error);
@@ -21904,7 +21953,7 @@ var sizeConfig = {
21904
21953
  };
21905
21954
  function Toggle({ label, checked, onChange, disabled, size = "md", style, className }) {
21906
21955
  const config = sizeConfig[size];
21907
- const [focused, setFocused] = (0, import_react17.useState)(false);
21956
+ const [focused, setFocused] = (0, import_react18.useState)(false);
21908
21957
  return (0, import_jsx_runtime15.jsxs)("label", { className, style: {
21909
21958
  display: "flex",
21910
21959
  alignItems: "center",
@@ -21946,7 +21995,7 @@ function Toggle({ label, checked, onChange, disabled, size = "md", style, classN
21946
21995
  }, children: label })] });
21947
21996
  }
21948
21997
  function RadioGroup({ label, value, onChange, options, direction = "vertical", disabled, error, style, className }) {
21949
- const uniqueId = (0, import_react18.useId)();
21998
+ const uniqueId = (0, import_react19.useId)();
21950
21999
  const labelId = `${uniqueId}-label`;
21951
22000
  const errorId = `${uniqueId}-error`;
21952
22001
  const groupName = `${uniqueId}-radio`;
@@ -22011,7 +22060,7 @@ function RadioGroup({ label, value, onChange, options, direction = "vertical", d
22011
22060
  }, children: error })] });
22012
22061
  }
22013
22062
  function Slider({ label, value = 0, onChange, min = 0, max = 100, step = 1, disabled, showValue, style, className }) {
22014
- const uniqueId = (0, import_react19.useId)();
22063
+ const uniqueId = (0, import_react20.useId)();
22015
22064
  const sliderId = `${uniqueId}-slider`;
22016
22065
  const labelId = `${uniqueId}-label`;
22017
22066
  const percentage = (value - min) / (max - min) * 100;
@@ -22142,7 +22191,7 @@ var avatarColors = [
22142
22191
  "var(--ggui-color-info-500, #06b6d4)"
22143
22192
  ];
22144
22193
  function Avatar({ src, name, size = "md", shape = "circle", style, className }) {
22145
- const [imageError, setImageError] = (0, import_react20.useState)(false);
22194
+ const [imageError, setImageError] = (0, import_react21.useState)(false);
22146
22195
  const resolvedSize = typeof size === "number" ? size : sizeMap2[size] || 40;
22147
22196
  const initials = name ? name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
22148
22197
  const getColorFromName = (name2) => {
@@ -22278,7 +22327,7 @@ function Progress({ value, max = 100, variant = "default", size = "md", label, s
22278
22327
  }` })] })] });
22279
22328
  }
22280
22329
  function Image({ src, alt, width, height, objectFit = "cover", radius: radius2, fallback, style, className }) {
22281
- const [error, setError] = (0, import_react21.useState)(false);
22330
+ const [error, setError] = (0, import_react22.useState)(false);
22282
22331
  const resolveSize2 = (value) => {
22283
22332
  if (value === void 0)
22284
22333
  return void 0;
@@ -26839,7 +26888,7 @@ function resolveLucideName(name) {
26839
26888
  return LUCIDE_LOOKUP.get(normalized);
26840
26889
  }
26841
26890
  function renderLucideIcon(data, size, color) {
26842
- return (0, import_jsx_runtime24.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: data.map(([tag, attrs], i) => import_react22.default.createElement(tag, { key: i, ...attrs })) });
26891
+ return (0, import_jsx_runtime24.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: data.map(([tag, attrs], i) => import_react23.default.createElement(tag, { key: i, ...attrs })) });
26843
26892
  }
26844
26893
  function Icon({ name, size = 24, tone, children, style, className, "aria-label": ariaLabel }) {
26845
26894
  const iconColor = tone ? resolveToneCss(tone) : "currentColor";
@@ -26895,10 +26944,10 @@ function Link({ children, href, external, tone, underline = "hover", style, clas
26895
26944
  }, ...rest, children: [children, external && (0, import_jsx_runtime25.jsxs)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", style: { marginLeft: "4px", verticalAlign: "middle" }, children: [(0, import_jsx_runtime25.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), (0, import_jsx_runtime25.jsx)("polyline", { points: "15 3 21 3 21 9" }), (0, import_jsx_runtime25.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] })] });
26896
26945
  }
26897
26946
  function Tooltip({ children, content, position = "top", delay = 200, style, className }) {
26898
- const [visible, setVisible] = (0, import_react23.useState)(false);
26899
- const [coords, setCoords] = (0, import_react23.useState)({ top: 0, left: 0 });
26900
- const triggerRef = (0, import_react23.useRef)(null);
26901
- const timeoutRef = (0, import_react23.useRef)(null);
26947
+ const [visible, setVisible] = (0, import_react24.useState)(false);
26948
+ const [coords, setCoords] = (0, import_react24.useState)({ top: 0, left: 0 });
26949
+ const triggerRef = (0, import_react24.useRef)(null);
26950
+ const timeoutRef = (0, import_react24.useRef)(null);
26902
26951
  const showTooltip = () => {
26903
26952
  timeoutRef.current = setTimeout(() => {
26904
26953
  setVisible(true);
@@ -26910,7 +26959,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26910
26959
  }
26911
26960
  setVisible(false);
26912
26961
  };
26913
- (0, import_react23.useEffect)(() => {
26962
+ (0, import_react24.useEffect)(() => {
26914
26963
  if (visible && triggerRef.current) {
26915
26964
  const rect = triggerRef.current.getBoundingClientRect();
26916
26965
  const offset = 8;
@@ -26937,7 +26986,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26937
26986
  setCoords({ top, left });
26938
26987
  }
26939
26988
  }, [visible, position]);
26940
- (0, import_react23.useEffect)(() => {
26989
+ (0, import_react24.useEffect)(() => {
26941
26990
  return () => {
26942
26991
  if (timeoutRef.current) {
26943
26992
  clearTimeout(timeoutRef.current);
@@ -26986,7 +27035,7 @@ var sortIndicator = (active, direction) => (0, import_jsx_runtime27.jsxs)("span"
26986
27035
  opacity: active ? 1 : 0.3
26987
27036
  }, children: [(0, import_jsx_runtime27.jsx)("span", { style: { opacity: active && direction === "asc" ? 1 : 0.4 }, children: "\u25B2" }), (0, import_jsx_runtime27.jsx)("span", { style: { opacity: active && direction === "desc" ? 1 : 0.4 }, children: "\u25BC" })] });
26988
27037
  function Table({ columns, data, sortKey, sortDirection = "asc", onSort, striped = false, hoverable = true, compact = false, bordered = false, caption, style, className }) {
26989
- const [hoveredRow, setHoveredRow] = (0, import_react24.useState)(null);
27038
+ const [hoveredRow, setHoveredRow] = (0, import_react25.useState)(null);
26990
27039
  const cellPadding = compact ? "var(--ggui-spacing-1, 4px) var(--ggui-spacing-2, 8px)" : "var(--ggui-spacing-2, 8px) var(--ggui-spacing-4, 16px)";
26991
27040
  const handleSort = (key) => {
26992
27041
  if (!onSort)
@@ -27057,10 +27106,10 @@ var sizeStyles5 = {
27057
27106
  }
27058
27107
  };
27059
27108
  function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullWidth = false, style, className }) {
27060
- const uniqueId = (0, import_react25.useId)();
27061
- const [internalKey, setInternalKey] = (0, import_react25.useState)(items[0]?.key);
27109
+ const uniqueId = (0, import_react26.useId)();
27110
+ const [internalKey, setInternalKey] = (0, import_react26.useState)(items[0]?.key);
27062
27111
  const currentKey = activeKey ?? internalKey;
27063
- const handleChange = (0, import_react25.useCallback)((key) => {
27112
+ const handleChange = (0, import_react26.useCallback)((key) => {
27064
27113
  if (onChange) {
27065
27114
  onChange(key);
27066
27115
  } else {
@@ -27068,8 +27117,8 @@ function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullW
27068
27117
  }
27069
27118
  }, [onChange]);
27070
27119
  const activeItem = items.find((item) => item.key === currentKey);
27071
- const tabListRef = (0, import_react25.useRef)(null);
27072
- const handleTabKeyDown = (0, import_react25.useCallback)((e) => {
27120
+ const tabListRef = (0, import_react26.useRef)(null);
27121
+ const handleTabKeyDown = (0, import_react26.useCallback)((e) => {
27073
27122
  const enabledItems = items.filter((item) => !item.disabled);
27074
27123
  const currentIndex = enabledItems.findIndex((item) => item.key === currentKey);
27075
27124
  let nextIndex;
@@ -27333,7 +27382,7 @@ var defaultIcons2 = {
27333
27382
  error: (0, import_jsx_runtime29.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "currentColor", children: (0, import_jsx_runtime29.jsx)("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) })
27334
27383
  };
27335
27384
  function Toast({ message, variant = "info", title, duration: duration2 = 5e3, onClose, visible = true, style, className }) {
27336
- (0, import_react26.useEffect)(() => {
27385
+ (0, import_react27.useEffect)(() => {
27337
27386
  if (!visible || duration2 === 0 || !onClose)
27338
27387
  return;
27339
27388
  const timer = setTimeout(onClose, duration2);
@@ -27391,8 +27440,8 @@ var chevron = (expanded) => (0, import_jsx_runtime30.jsx)("svg", { width: "16",
27391
27440
  flexShrink: 0
27392
27441
  }, children: (0, import_jsx_runtime30.jsx)("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) });
27393
27442
  function Accordion({ items, expandedKeys, onChange, multiple = false, variant = "default", style, className }) {
27394
- const uniqueId = (0, import_react27.useId)();
27395
- const [internalExpanded, setInternalExpanded] = (0, import_react27.useState)([]);
27443
+ const uniqueId = (0, import_react28.useId)();
27444
+ const [internalExpanded, setInternalExpanded] = (0, import_react28.useState)([]);
27396
27445
  const currentExpanded = expandedKeys ?? internalExpanded;
27397
27446
  const handleToggle = (key) => {
27398
27447
  let newExpanded;
@@ -27472,7 +27521,7 @@ function Accordion({ items, expandedKeys, onChange, multiple = false, variant =
27472
27521
  }
27473
27522
  var STYLE_ID = "ggui-motion-keyframes";
27474
27523
  function MotionKeyframes() {
27475
- (0, import_react28.useEffect)(() => {
27524
+ (0, import_react29.useEffect)(() => {
27476
27525
  if (document.getElementById(STYLE_ID))
27477
27526
  return;
27478
27527
  const styleEl = document.createElement("style");
@@ -27489,12 +27538,12 @@ function MotionKeyframes() {
27489
27538
  return null;
27490
27539
  }
27491
27540
  function useMotion() {
27492
- const [motionEnabled, setMotionEnabled] = (0, import_react28.useState)(() => {
27541
+ const [motionEnabled, setMotionEnabled] = (0, import_react29.useState)(() => {
27493
27542
  if (typeof window === "undefined")
27494
27543
  return true;
27495
27544
  return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
27496
27545
  });
27497
- (0, import_react28.useEffect)(() => {
27546
+ (0, import_react29.useEffect)(() => {
27498
27547
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
27499
27548
  const handler = (e) => setMotionEnabled(!e.matches);
27500
27549
  mq.addEventListener("change", handler);
@@ -27503,9 +27552,9 @@ function useMotion() {
27503
27552
  return { motionEnabled };
27504
27553
  }
27505
27554
  function useAnimationKey(dep) {
27506
- const [key, setKey] = (0, import_react28.useState)(0);
27507
- const isFirst = (0, import_react28.useRef)(true);
27508
- (0, import_react28.useEffect)(() => {
27555
+ const [key, setKey] = (0, import_react29.useState)(0);
27556
+ const isFirst = (0, import_react29.useRef)(true);
27557
+ (0, import_react29.useEffect)(() => {
27509
27558
  if (isFirst.current) {
27510
27559
  isFirst.current = false;
27511
27560
  return;
@@ -27532,7 +27581,7 @@ __export2(components_exports, {
27532
27581
  renderRichTextInlines: () => renderRichTextInlines
27533
27582
  });
27534
27583
  function SearchField({ value: controlledValue, onChange, onSearch, placeholder = "Search...", showButton = false, buttonText = "Search", loading, disabled, size = "md", style, className }) {
27535
- const [internalValue, setInternalValue] = (0, import_react29.useState)("");
27584
+ const [internalValue, setInternalValue] = (0, import_react30.useState)("");
27536
27585
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
27537
27586
  const handleChange = (newValue) => {
27538
27587
  if (controlledValue === void 0) {
@@ -27693,9 +27742,9 @@ function Tag({ children, variant = "default", size = "md", closable, onClose, ic
27693
27742
  }, "aria-label": "Remove", children: (0, import_jsx_runtime34.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor", children: (0, import_jsx_runtime34.jsx)("path", { d: "M9.5 3.205L8.795 2.5 6 5.295 3.205 2.5l-.705.705L5.295 6 2.5 8.795l.705.705L6 6.705 8.795 9.5l.705-.705L6.705 6 9.5 3.205z" }) }) })] });
27694
27743
  }
27695
27744
  function Dropdown({ trigger, options, value, onChange, placement = "bottom-start", disabled, style, className }) {
27696
- const [isOpen, setIsOpen] = (0, import_react30.useState)(false);
27697
- const containerRef = (0, import_react30.useRef)(null);
27698
- (0, import_react30.useEffect)(() => {
27745
+ const [isOpen, setIsOpen] = (0, import_react31.useState)(false);
27746
+ const containerRef = (0, import_react31.useRef)(null);
27747
+ (0, import_react31.useEffect)(() => {
27699
27748
  const handleClickOutside = (event) => {
27700
27749
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27701
27750
  setIsOpen(false);
@@ -27706,7 +27755,7 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27706
27755
  return () => document.removeEventListener("mousedown", handleClickOutside);
27707
27756
  }
27708
27757
  }, [isOpen]);
27709
- (0, import_react30.useEffect)(() => {
27758
+ (0, import_react31.useEffect)(() => {
27710
27759
  const handleEscape = (event) => {
27711
27760
  if (event.key === "Escape") {
27712
27761
  setIsOpen(false);
@@ -27753,16 +27802,16 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27753
27802
  }, children: options.map((option) => (0, import_jsx_runtime35.jsx)(MenuItem, { label: option.label, icon: option.icon, onClick: () => handleSelect(option.value), disabled: option.disabled, active: value === option.value, danger: option.danger }, option.value)) })] });
27754
27803
  }
27755
27804
  function Autocomplete({ value = "", onChange, onSelect, options, placeholder, label, loading, disabled, error, noResultsText = "No results found", style, className }) {
27756
- const [isOpen, setIsOpen] = (0, import_react31.useState)(false);
27757
- const [highlightedIndex, setHighlightedIndex] = (0, import_react31.useState)(-1);
27758
- const containerRef = (0, import_react31.useRef)(null);
27759
- const filteredOptions = (0, import_react31.useMemo)(() => {
27805
+ const [isOpen, setIsOpen] = (0, import_react32.useState)(false);
27806
+ const [highlightedIndex, setHighlightedIndex] = (0, import_react32.useState)(-1);
27807
+ const containerRef = (0, import_react32.useRef)(null);
27808
+ const filteredOptions = (0, import_react32.useMemo)(() => {
27760
27809
  if (!value)
27761
27810
  return options;
27762
27811
  const lowerValue = value.toLowerCase();
27763
27812
  return options.filter((opt) => opt.label.toLowerCase().includes(lowerValue) || opt.value.toLowerCase().includes(lowerValue));
27764
27813
  }, [options, value]);
27765
- (0, import_react31.useEffect)(() => {
27814
+ (0, import_react32.useEffect)(() => {
27766
27815
  const handleClickOutside = (event) => {
27767
27816
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27768
27817
  setIsOpen(false);
@@ -27851,7 +27900,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27851
27900
  ...style
27852
27901
  }, children: items.map((item, index) => {
27853
27902
  const isLast = index === items.length - 1;
27854
- return (0, import_jsx_runtime37.jsxs)(import_react32.Fragment, { children: [index > 0 && (0, import_jsx_runtime37.jsx)("span", { style: { color: "var(--ggui-color-neutral-400, #9ca3af)" }, children: separator }), item.icon && (0, import_jsx_runtime37.jsx)("span", { style: {
27903
+ return (0, import_jsx_runtime37.jsxs)(import_react33.Fragment, { children: [index > 0 && (0, import_jsx_runtime37.jsx)("span", { style: { color: "var(--ggui-color-neutral-400, #9ca3af)" }, children: separator }), item.icon && (0, import_jsx_runtime37.jsx)("span", { style: {
27855
27904
  display: "flex",
27856
27905
  alignItems: "center",
27857
27906
  color: isLast ? "var(--ggui-color-onContainer, #111827)" : "var(--ggui-color-neutral-500, #6b7280)"
@@ -28499,7 +28548,7 @@ function Header({ logo, navigation: navigation2, actions, sticky = false, backgr
28499
28548
  }, children: [logo && (0, import_jsx_runtime43.jsx)("div", { style: { flexShrink: 0 }, children: logo }), navigation2 && (0, import_jsx_runtime43.jsx)("nav", { style: { display: "flex", alignItems: "center", flex: 1, marginLeft: "32px" }, children: navigation2 }), actions && (0, import_jsx_runtime43.jsx)("div", { style: { display: "flex", alignItems: "center", gap: "12px", flexShrink: 0 }, children: actions })] });
28500
28549
  }
28501
28550
  function SidebarItem({ item, activeId, onItemClick, collapsed, depth = 0 }) {
28502
- const [expanded, setExpanded] = (0, import_react33.useState)(false);
28551
+ const [expanded, setExpanded] = (0, import_react34.useState)(false);
28503
28552
  const hasChildren = item.children && item.children.length > 0;
28504
28553
  const isActive = activeId === item.id;
28505
28554
  const handleClick = () => {
@@ -28568,8 +28617,8 @@ function CardGrid({ children, columns = 3, gap = 16, style, className }) {
28568
28617
  }, children });
28569
28618
  }
28570
28619
  function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28571
- const [showReplyInput, setShowReplyInput] = (0, import_react34.useState)(false);
28572
- const [replyContent, setReplyContent] = (0, import_react34.useState)("");
28620
+ const [showReplyInput, setShowReplyInput] = (0, import_react35.useState)(false);
28621
+ const [replyContent, setReplyContent] = (0, import_react35.useState)("");
28573
28622
  const handleSubmitReply = () => {
28574
28623
  if (replyContent.trim()) {
28575
28624
  onReply?.(comment.id, replyContent);
@@ -28594,7 +28643,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28594
28643
  }, children: "Reply" })] }), showReplyInput && (0, import_jsx_runtime46.jsxs)("div", { style: { marginTop: "12px" }, children: [(0, import_jsx_runtime46.jsx)(TextArea, { value: replyContent, onChange: setReplyContent, placeholder: "Write a reply...", rows: 2 }), (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [(0, import_jsx_runtime46.jsx)(Button, { size: "sm", onClick: handleSubmitReply, children: "Reply" }), (0, import_jsx_runtime46.jsx)(Button, { size: "sm", variant: "ghost", onClick: () => setShowReplyInput(false), children: "Cancel" })] })] })] })] }), comment.replies?.map((reply) => (0, import_jsx_runtime46.jsx)("div", { style: { marginTop: "16px" }, children: (0, import_jsx_runtime46.jsx)(CommentItem, { comment: reply, onReply, onReaction, depth: depth + 1 }) }, reply.id))] });
28595
28644
  }
28596
28645
  function CommentThread({ comments, currentUser, onAddComment, onReply, onReaction, loading, style, className }) {
28597
- const [newComment, setNewComment] = (0, import_react34.useState)("");
28646
+ const [newComment, setNewComment] = (0, import_react35.useState)("");
28598
28647
  const handleSubmit = () => {
28599
28648
  if (newComment.trim()) {
28600
28649
  onAddComment?.(newComment);
@@ -28659,9 +28708,9 @@ function DataTable({ columns, data, rowKey = "id", loading, emptyText = "No data
28659
28708
  }) })] }) });
28660
28709
  }
28661
28710
  function ChatWindow({ messages, currentUserId, onSendMessage, loading, typing, placeholder = "Type a message...", header, style, className }) {
28662
- const [inputValue, setInputValue] = (0, import_react35.useState)("");
28663
- const messagesEndRef = (0, import_react35.useRef)(null);
28664
- (0, import_react35.useEffect)(() => {
28711
+ const [inputValue, setInputValue] = (0, import_react36.useState)("");
28712
+ const messagesEndRef = (0, import_react36.useRef)(null);
28713
+ (0, import_react36.useEffect)(() => {
28665
28714
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
28666
28715
  }, [messages]);
28667
28716
  const handleSend = () => {
@@ -28799,8 +28848,8 @@ function formatFileSize(bytes) {
28799
28848
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
28800
28849
  }
28801
28850
  function FileUploader({ files = [], onFilesSelected, onFileRemove, accept, multiple = true, maxSize, maxFiles, disabled, dragDrop = true, style, className }) {
28802
- const [isDragOver, setIsDragOver] = (0, import_react36.useState)(false);
28803
- const inputRef = (0, import_react36.useRef)(null);
28851
+ const [isDragOver, setIsDragOver] = (0, import_react37.useState)(false);
28852
+ const inputRef = (0, import_react37.useRef)(null);
28804
28853
  const handleFiles = (fileList) => {
28805
28854
  if (!fileList)
28806
28855
  return;
@@ -28939,12 +28988,12 @@ var sizeWidths = {
28939
28988
  full: "100vw"
28940
28989
  };
28941
28990
  function Modal({ open, onClose, title, children, footer, size = "md", closeOnOverlayClick = true, closeOnEscape = true, showCloseButton = true, style, className }) {
28942
- const handleEscape = (0, import_react37.useCallback)((e) => {
28991
+ const handleEscape = (0, import_react38.useCallback)((e) => {
28943
28992
  if (e.key === "Escape" && closeOnEscape) {
28944
28993
  onClose();
28945
28994
  }
28946
28995
  }, [closeOnEscape, onClose]);
28947
- (0, import_react37.useEffect)(() => {
28996
+ (0, import_react38.useEffect)(() => {
28948
28997
  if (open) {
28949
28998
  document.addEventListener("keydown", handleEscape);
28950
28999
  document.body.style.overflow = "hidden";
@@ -29009,9 +29058,9 @@ function Modal({ open, onClose, title, children, footer, size = "md", closeOnOve
29009
29058
  }, children: footer })] })] });
29010
29059
  }
29011
29060
  function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Search commands...", recentIds = [], loading, style, className }) {
29012
- const [query, setQuery] = (0, import_react38.useState)("");
29013
- const [selectedIndex, setSelectedIndex] = (0, import_react38.useState)(0);
29014
- const filteredCommands = (0, import_react38.useMemo)(() => {
29061
+ const [query, setQuery] = (0, import_react39.useState)("");
29062
+ const [selectedIndex, setSelectedIndex] = (0, import_react39.useState)(0);
29063
+ const filteredCommands = (0, import_react39.useMemo)(() => {
29015
29064
  const filtered = query ? commands.filter((cmd) => cmd.label.toLowerCase().includes(query.toLowerCase()) || cmd.description?.toLowerCase().includes(query.toLowerCase())) : commands;
29016
29065
  const groups = /* @__PURE__ */ new Map();
29017
29066
  if (!query && recentIds.length > 0) {
@@ -29032,21 +29081,21 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29032
29081
  });
29033
29082
  return groups;
29034
29083
  }, [commands, query, recentIds]);
29035
- const flatCommands = (0, import_react38.useMemo)(() => {
29084
+ const flatCommands = (0, import_react39.useMemo)(() => {
29036
29085
  const flat = [];
29037
29086
  filteredCommands.forEach((cmds) => flat.push(...cmds));
29038
29087
  return flat;
29039
29088
  }, [filteredCommands]);
29040
- (0, import_react38.useEffect)(() => {
29089
+ (0, import_react39.useEffect)(() => {
29041
29090
  setSelectedIndex(0);
29042
29091
  }, [query]);
29043
- (0, import_react38.useEffect)(() => {
29092
+ (0, import_react39.useEffect)(() => {
29044
29093
  if (open) {
29045
29094
  setQuery("");
29046
29095
  setSelectedIndex(0);
29047
29096
  }
29048
29097
  }, [open]);
29049
- const handleKeyDown = (0, import_react38.useCallback)((e) => {
29098
+ const handleKeyDown = (0, import_react39.useCallback)((e) => {
29050
29099
  if (e.key === "Escape") {
29051
29100
  onClose();
29052
29101
  return;
@@ -29066,7 +29115,7 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29066
29115
  }
29067
29116
  }
29068
29117
  }, [flatCommands, selectedIndex, onSelect, onClose]);
29069
- (0, import_react38.useEffect)(() => {
29118
+ (0, import_react39.useEffect)(() => {
29070
29119
  if (open) {
29071
29120
  document.addEventListener("keydown", handleKeyDown);
29072
29121
  return () => document.removeEventListener("keydown", handleKeyDown);
@@ -29315,9 +29364,9 @@ __export2(interact_exports, {
29315
29364
  Hoverable: () => Hoverable,
29316
29365
  Pressable: () => Pressable
29317
29366
  });
29318
- var Clickable = (0, import_react39.forwardRef)(function Clickable2({ children, onClick, onDoubleClick, hoverStyle, activeStyle, cursor, transition: transition2 = "all 200ms ease", disabled = false, role, "aria-label": ariaLabel, tabIndex, style, className, ...rest }, ref) {
29319
- const [hovered, setHovered] = (0, import_react39.useState)(false);
29320
- const [active, setActive] = (0, import_react39.useState)(false);
29367
+ var Clickable = (0, import_react40.forwardRef)(function Clickable2({ children, onClick, onDoubleClick, hoverStyle, activeStyle, cursor, transition: transition2 = "all 200ms ease", disabled = false, role, "aria-label": ariaLabel, tabIndex, style, className, ...rest }, ref) {
29368
+ const [hovered, setHovered] = (0, import_react40.useState)(false);
29369
+ const [active, setActive] = (0, import_react40.useState)(false);
29321
29370
  const hasClick = !!onClick;
29322
29371
  const resolvedCursor = disabled ? "not-allowed" : cursor ?? (hasClick ? "pointer" : void 0);
29323
29372
  const resolvedRole = role ?? (hasClick ? "button" : void 0);
@@ -29343,8 +29392,8 @@ var Clickable = (0, import_react39.forwardRef)(function Clickable2({ children, o
29343
29392
  setActive(false);
29344
29393
  }, onMouseDown: () => setActive(true), onMouseUp: () => setActive(false), onKeyDown: handleKeyDown, role: resolvedRole, "aria-label": ariaLabel, "aria-disabled": disabled || void 0, tabIndex: resolvedTabIndex, ...rest, children });
29345
29394
  });
29346
- var Hoverable = (0, import_react40.forwardRef)(function Hoverable2({ children, hoverStyle, onHoverChange, transition: transition2 = "all 200ms ease", style, className, ...rest }, ref) {
29347
- const [hovered, setHovered] = (0, import_react40.useState)(false);
29395
+ var Hoverable = (0, import_react41.forwardRef)(function Hoverable2({ children, hoverStyle, onHoverChange, transition: transition2 = "all 200ms ease", style, className, ...rest }, ref) {
29396
+ const [hovered, setHovered] = (0, import_react41.useState)(false);
29348
29397
  const mergedStyle = {
29349
29398
  ...style,
29350
29399
  transition: transition2,
@@ -29358,10 +29407,10 @@ var Hoverable = (0, import_react40.forwardRef)(function Hoverable2({ children, h
29358
29407
  onHoverChange?.(false);
29359
29408
  }, ...rest, children });
29360
29409
  });
29361
- var Pressable = (0, import_react41.forwardRef)(function Pressable2({ children, onPress, onLongPress, longPressDelay = 500, hoverStyle, pressStyle, disabled = false, transition: transition2 = "all 150ms ease", role, "aria-label": ariaLabel, tabIndex, style, className, ...rest }, ref) {
29362
- const [hovered, setHovered] = (0, import_react41.useState)(false);
29363
- const [pressed, setPressed] = (0, import_react41.useState)(false);
29364
- const [longPressTimer, setLongPressTimer] = (0, import_react41.useState)(null);
29410
+ var Pressable = (0, import_react42.forwardRef)(function Pressable2({ children, onPress, onLongPress, longPressDelay = 500, hoverStyle, pressStyle, disabled = false, transition: transition2 = "all 150ms ease", role, "aria-label": ariaLabel, tabIndex, style, className, ...rest }, ref) {
29411
+ const [hovered, setHovered] = (0, import_react42.useState)(false);
29412
+ const [pressed, setPressed] = (0, import_react42.useState)(false);
29413
+ const [longPressTimer, setLongPressTimer] = (0, import_react42.useState)(null);
29365
29414
  const hasPress = !!onPress || !!onLongPress;
29366
29415
  const handleMouseDown = (e) => {
29367
29416
  if (disabled)
@@ -29715,17 +29764,20 @@ function scrimTint(tone) {
29715
29764
  return "#000000";
29716
29765
  return tokenValue(tone);
29717
29766
  }
29718
- function familyRamp(group, anchor) {
29767
+ function familyRamp(group, anchor, ground) {
29719
29768
  const statedStops = {};
29720
29769
  for (const stop of STOPS) {
29721
29770
  const v = stated(group, stop);
29722
29771
  if (v !== void 0)
29723
29772
  statedStops[stop] = v;
29724
29773
  }
29725
- return rampFrom(statedStops, anchor);
29774
+ return rampFrom(statedStops, anchor, ground);
29726
29775
  }
29727
- function rampFrom(statedStops, anchor) {
29776
+ var NEUTRAL_ANCHOR_CHROMA = 0.02;
29777
+ var LIGHT_STOP_COUNT = 5;
29778
+ function rampFrom(statedStops, anchor, ground) {
29728
29779
  const a = hexToOklch(anchor);
29780
+ const g = ground !== void 0 && a.c < NEUTRAL_ANCHOR_CHROMA ? hexToOklch(ground) : void 0;
29729
29781
  const out = {};
29730
29782
  STOPS.forEach((stop, i) => {
29731
29783
  const v = statedStops[stop];
@@ -29733,7 +29785,16 @@ function rampFrom(statedStops, anchor) {
29733
29785
  out[stop] = v;
29734
29786
  return;
29735
29787
  }
29736
- out[stop] = stop === "500" ? anchor : oklchToHex({ l: RAMP_L[i], c: a.c * RAMP_C[i], h: a.h });
29788
+ if (stop === "500") {
29789
+ out[stop] = anchor;
29790
+ return;
29791
+ }
29792
+ if (g !== void 0 && i < LIGHT_STOP_COUNT) {
29793
+ const t = g.l === a.l ? 1 : Math.min(1, Math.max(0, (RAMP_L[i] - g.l) / (a.l - g.l)));
29794
+ out[stop] = oklchToHex({ l: RAMP_L[i], c: g.c + (a.c - g.c) * t, h: g.h });
29795
+ return;
29796
+ }
29797
+ out[stop] = oklchToHex({ l: RAMP_L[i], c: a.c * RAMP_C[i], h: a.h });
29737
29798
  });
29738
29799
  return out;
29739
29800
  }
@@ -29828,7 +29889,7 @@ function deriveThemeVariables(doc, mode, options = {}) {
29828
29889
  anchor = "#000000";
29829
29890
  }
29830
29891
  }
29831
- const ramp2 = familyRamp(g, anchor);
29892
+ const ramp2 = familyRamp(g, anchor, ground);
29832
29893
  for (const stop of STOPS)
29833
29894
  V[`--ggui-color-${fam}-${stop}`] = ramp2[stop];
29834
29895
  const cap = fam[0].toUpperCase() + fam.slice(1);
@@ -32841,7 +32902,7 @@ function getTheme(id, mode = "light") {
32841
32902
  function getDefaultThemeId() {
32842
32903
  return "ggui";
32843
32904
  }
32844
- var ThemeContext = (0, import_react42.createContext)(null);
32905
+ var ThemeContext = (0, import_react43.createContext)(null);
32845
32906
  var COLOR_MIX_SUPPORTS = "@supports (color: color-mix(in srgb, red, blue))";
32846
32907
  function resolvePrimary500Hex(cssVariables) {
32847
32908
  const match = cssVariables.match(/--ggui-color-primary-500:\s*(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})\s*;/);
@@ -32942,13 +33003,21 @@ function framelessSuppressionRule(scopeClass) {
32942
33003
  }
32943
33004
  var EXPANDED_FRAME = { outerRadiusVar: "--ggui-shape-radius-xl", insetPx: 16 };
32944
33005
  var EXPANDED_FRAME_INNER_RADIUS = `max(0px, calc(var(${EXPANDED_FRAME.outerRadiusVar}) - ${EXPANDED_FRAME.insetPx}px))`;
33006
+ var EXPANDED_FRAME_CHROME = {
33007
+ radius: `var(${EXPANDED_FRAME.outerRadiusVar})`,
33008
+ hairline: "color-mix(in srgb, var(--ggui-color-onGround) 6%, transparent)",
33009
+ shadowVar: "--ggui-shape-shadow-sm",
33010
+ ground: "var(--ggui-color-neutral-50)"
33011
+ };
32945
33012
  function structuralScaffolding(scopeClass) {
32946
33013
  return `.${scopeClass} *, .${scopeClass} *::before, .${scopeClass} *::after { box-sizing: border-box; }
32947
33014
  .${scopeClass} h1, .${scopeClass} h2, .${scopeClass} h3, .${scopeClass} h4, .${scopeClass} h5, .${scopeClass} h6, .${scopeClass} button, .${scopeClass} input, .${scopeClass} textarea, .${scopeClass} select { font-family: inherit; }`;
32948
33015
  }
33016
+ var BODY_COPY_SIZE = "font-size: var(--ggui-font-size-base);";
32949
33017
  function baseInheritsRule(scopeClass) {
32950
33018
  return `.${scopeClass} {
32951
33019
  font-family: var(--ggui-font-family-sans);
33020
+ ${BODY_COPY_SIZE}
32952
33021
  color: var(--ggui-color-onGround);
32953
33022
  background-color: transparent;
32954
33023
  }`;
@@ -33003,6 +33072,10 @@ var WIRE_EXPORTS = [
33003
33072
  // its runtime's shim lacks fails at module link. A card generated to use it
33004
33073
  // must never meet a runtime without it.
33005
33074
  "useActionSpent",
33075
+ // ggui#1398: whether a dispatched action is waiting for the agent's answer,
33076
+ // as data. Served one release before the triad teaches it, for the same
33077
+ // reason as `useActionSpent` above.
33078
+ "useActionPending",
33006
33079
  // Provider component
33007
33080
  "GguiWireProvider"
33008
33081
  ];
@@ -33421,7 +33494,7 @@ function makeScopeClass(reactId) {
33421
33494
  }
33422
33495
  var AUTO_RETRY_LIMIT = 1;
33423
33496
  var AUTO_RETRY_DELAY = 500;
33424
- var ErrorBoundary = class extends import_react9.default.Component {
33497
+ var ErrorBoundary = class extends import_react10.default.Component {
33425
33498
  state = { error: null, catchCount: 0, autoRetrying: false };
33426
33499
  retryTimer = null;
33427
33500
  static getDerivedStateFromError(error) {
@@ -33537,12 +33610,12 @@ function ReactComponentRenderer({
33537
33610
  fallback = /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { children: "Loading component..." }),
33538
33611
  onError
33539
33612
  }) {
33540
- const reactId = (0, import_react9.useId)();
33541
- const [scopeClass] = (0, import_react9.useState)(() => makeScopeClass(reactId) || `ggui-rcr-${++scopeCounter}`);
33542
- const [Component, setComponent] = (0, import_react9.useState)(null);
33543
- const [error, setError] = (0, import_react9.useState)(null);
33544
- const [loading, setLoading] = (0, import_react9.useState)(true);
33545
- (0, import_react9.useEffect)(() => {
33613
+ const reactId = (0, import_react10.useId)();
33614
+ const [scopeClass] = (0, import_react10.useState)(() => makeScopeClass(reactId) || `ggui-rcr-${++scopeCounter}`);
33615
+ const [Component, setComponent] = (0, import_react10.useState)(null);
33616
+ const [error, setError] = (0, import_react10.useState)(null);
33617
+ const [loading, setLoading] = (0, import_react10.useState)(true);
33618
+ (0, import_react10.useEffect)(() => {
33546
33619
  if (!code || code.trim().length === 0) {
33547
33620
  setComponent(null);
33548
33621
  setLoading(false);
@@ -33570,7 +33643,7 @@ function ReactComponentRenderer({
33570
33643
  } catch {
33571
33644
  }
33572
33645
  w.__ggui__ = {
33573
- react: import_react9.default,
33646
+ react: import_react10.default,
33574
33647
  reactDom: reactDomModule,
33575
33648
  primitives: primitives_exports,
33576
33649
  components: components_exports,
@@ -33578,7 +33651,7 @@ function ReactComponentRenderer({
33578
33651
  interact: interact_exports,
33579
33652
  wire: dist_exports
33580
33653
  };
33581
- w.__REACT = import_react9.default;
33654
+ w.__REACT = import_react10.default;
33582
33655
  w.__GGUI_PRIMITIVES = primitives_exports;
33583
33656
  w.__GGUI_COMPONENTS = components_exports;
33584
33657
  w.__GGUI_COMPOSITIONS = compositions_exports;
@@ -33724,11 +33797,11 @@ function PreviewApp({
33724
33797
  token,
33725
33798
  selectedId
33726
33799
  }) {
33727
- const [state, setState] = (0, import_react45.useState)(
33800
+ const [state, setState] = (0, import_react46.useState)(
33728
33801
  selectedId ? { kind: "loading" } : { kind: "idle" }
33729
33802
  );
33730
- const [version, setVersion] = (0, import_react45.useState)(0);
33731
- (0, import_react45.useEffect)(() => {
33803
+ const [version, setVersion] = (0, import_react46.useState)(0);
33804
+ (0, import_react46.useEffect)(() => {
33732
33805
  if (!selectedId) {
33733
33806
  setState({ kind: "idle" });
33734
33807
  return;
@@ -33741,7 +33814,7 @@ function PreviewApp({
33741
33814
  });
33742
33815
  return () => controller.abort();
33743
33816
  }, [selectedId, token, version]);
33744
- (0, import_react45.useEffect)(() => {
33817
+ (0, import_react46.useEffect)(() => {
33745
33818
  if (!selectedId) return;
33746
33819
  const controller = new AbortController();
33747
33820
  subscribeToRegistry(token, controller.signal, (event) => {
@@ -33903,7 +33976,7 @@ function mount() {
33903
33976
  if (!root) throw new Error("preview-root element not found in shell");
33904
33977
  const { token, selectedId } = bootstrap();
33905
33978
  (0, import_client.createRoot)(root).render(
33906
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react45.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(PreviewApp, { token, selectedId }) })
33979
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react46.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(PreviewApp, { token, selectedId }) })
33907
33980
  );
33908
33981
  }
33909
33982
  mount();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/dev-stack",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Shared local dev engine for the ggui protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
5
5
  "keywords": [
6
6
  "ggui",
@@ -28,9 +28,9 @@
28
28
  "dependencies": {
29
29
  "chokidar": "^4.0.3",
30
30
  "esbuild": "^0.28.2",
31
- "@ggui-ai/agent-runtime": "0.24.0",
32
- "@ggui-ai/project-config": "0.24.0",
33
- "@ggui-ai/ui-registry": "0.24.0"
31
+ "@ggui-ai/agent-runtime": "0.25.0",
32
+ "@ggui-ai/project-config": "0.25.0",
33
+ "@ggui-ai/ui-registry": "0.25.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^24.0.0",
@@ -40,9 +40,9 @@
40
40
  "react-dom": "^19.0.0",
41
41
  "typescript": "^5.0.0",
42
42
  "vitest": "^3.2.6",
43
- "@ggui-ai/design": "0.24.0",
44
- "@ggui-ai/mcp-apps-react": "0.24.0",
45
- "@ggui-ai/wire": "0.24.0"
43
+ "@ggui-ai/design": "0.25.0",
44
+ "@ggui-ai/mcp-apps-react": "0.25.0",
45
+ "@ggui-ai/wire": "0.25.0"
46
46
  },
47
47
  "repository": {
48
48
  "type": "git",