@ggui-ai/dev-stack 0.23.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_react44 = __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_react6 = __toESM(require_react(), 1);
20441
- var import_react7 = __toESM(require_react(), 1);
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,8 @@ __export(dist_exports, {
20452
20452
  buildWireConfig: () => buildWireConfig,
20453
20453
  connectionSource: () => connectionSource,
20454
20454
  useAction: () => useAction,
20455
+ useActionPending: () => useActionPending,
20456
+ useActionSpent: () => useActionSpent,
20455
20457
  useApp: () => useApp,
20456
20458
  useAuth: () => useAuth,
20457
20459
  useContract: () => useContract,
@@ -20542,8 +20544,30 @@ function useAction(actionName) {
20542
20544
  }, [actionName, dispatch, onDispatchSuppressed]);
20543
20545
  }
20544
20546
 
20545
- // ../wire/dist/useGguiContext.js
20547
+ // ../wire/dist/action-spent.js
20546
20548
  var import_react3 = __toESM(require_react(), 1);
20549
+ var ActionSpentContext = (0, import_react3.createContext)(null);
20550
+ var noSubscription = () => () => void 0;
20551
+ function useActionSpent(actionName) {
20552
+ const source = (0, import_react3.useContext)(ActionSpentContext);
20553
+ const subscribe = (0, import_react3.useCallback)((listener) => source === null ? noSubscription() : source.subscribe(listener), [source]);
20554
+ const read = (0, import_react3.useCallback)(() => source === null ? false : source.isSpent(actionName), [source, actionName]);
20555
+ return (0, import_react3.useSyncExternalStore)(subscribe, read, read);
20556
+ }
20557
+
20558
+ // ../wire/dist/action-pending.js
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);
20547
20571
  function useGguiContext(slotName) {
20548
20572
  const contextName = slotName.length === 0 ? "Context" : slotName.charAt(0).toUpperCase() + slotName.slice(1) + "Context";
20549
20573
  const registry = globalThis.__ggui__?.contexts;
@@ -20551,19 +20575,19 @@ function useGguiContext(slotName) {
20551
20575
  if (!ctx) {
20552
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.`);
20553
20577
  }
20554
- return (0, import_react3.useContext)(ctx);
20578
+ return (0, import_react5.useContext)(ctx);
20555
20579
  }
20556
20580
 
20557
20581
  // ../wire/dist/useStream.js
20558
- var import_react4 = __toESM(require_react(), 1);
20582
+ var import_react6 = __toESM(require_react(), 1);
20559
20583
  function useStream(channelName) {
20560
20584
  const { subscribe } = useWireContext();
20561
- const [latest, setLatest] = (0, import_react4.useState)(null);
20562
- const [all, setAll] = (0, import_react4.useState)([]);
20563
- const [isComplete, setIsComplete] = (0, import_react4.useState)(false);
20564
- const allRef = (0, import_react4.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);
20565
20589
  allRef.current = all;
20566
- (0, import_react4.useEffect)(() => {
20590
+ (0, import_react6.useEffect)(() => {
20567
20591
  return subscribe(channelName, (delivery) => {
20568
20592
  const typed = delivery.payload;
20569
20593
  setLatest(typed);
@@ -20601,7 +20625,7 @@ function useApp() {
20601
20625
  }
20602
20626
 
20603
20627
  // ../wire/dist/useRender.js
20604
- var import_react5 = __toESM(require_react(), 1);
20628
+ var import_react7 = __toESM(require_react(), 1);
20605
20629
 
20606
20630
  // ../wire/dist/connection-store.js
20607
20631
  var ConnectionWriterConflictError = class extends Error {
@@ -20698,7 +20722,7 @@ var connectionSource = documentStore.source;
20698
20722
  // ../wire/dist/useRender.js
20699
20723
  function useRender() {
20700
20724
  const { render } = useWireContext();
20701
- const isConnected = (0, import_react5.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20725
+ const isConnected = (0, import_react7.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20702
20726
  return { sessionId: render.sessionId, isConnected };
20703
20727
  }
20704
20728
 
@@ -20792,6 +20816,7 @@ var StreamBus = class {
20792
20816
  }
20793
20817
  }
20794
20818
  };
20819
+ var DEFAULT_ACTION_PENDING_BOUND_MS = 2e4;
20795
20820
  function buildWireConfig(opts) {
20796
20821
  let internalSeq = 0;
20797
20822
  const nextClientSeq = opts.nextClientSeq ?? (() => {
@@ -20800,7 +20825,59 @@ function buildWireConfig(opts) {
20800
20825
  });
20801
20826
  const validateEnvelope = opts.validateEnvelope ?? validateOutboundActionEnvelope;
20802
20827
  const spentOneShots = /* @__PURE__ */ new Set();
20828
+ const isSpent = (actionName) => opts.getActiveActionSpec()?.[actionName]?.oneShot === true && (spentOneShots.has(actionName) || opts.getSpentOneShots?.()?.includes(actionName) === true);
20829
+ const spentListeners = /* @__PURE__ */ new Set();
20830
+ const notifySpent = () => {
20831
+ for (const listener of [...spentListeners])
20832
+ listener();
20833
+ };
20834
+ const actionSpent = {
20835
+ isSpent,
20836
+ subscribe: (listener) => {
20837
+ spentListeners.add(listener);
20838
+ return () => {
20839
+ spentListeners.delete(listener);
20840
+ };
20841
+ }
20842
+ };
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
+ });
20803
20878
  return {
20879
+ actionSpent,
20880
+ actionPending,
20804
20881
  app: opts.app,
20805
20882
  render: opts.render,
20806
20883
  auth: opts.auth,
@@ -20810,8 +20887,7 @@ function buildWireConfig(opts) {
20810
20887
  if (actionSpec === void 0)
20811
20888
  opts.onActionSpecAbsent?.(actionName);
20812
20889
  const isOneShot = actionSpec?.[actionName]?.oneShot === true;
20813
- const spent = spentOneShots.has(actionName) || opts.getSpentOneShots?.()?.includes(actionName) === true;
20814
- if (isOneShot && spent) {
20890
+ if (isSpent(actionName)) {
20815
20891
  console.warn(`[ggui] dispatch('${actionName}') suppressed: this action is declared oneShot and already fired for this render. A second gesture is NOT sent to the agent \u2014 the submitted control is spent for the render's lifetime. If the action is meant to repeat, remove \`oneShot\` from its contract entry.`);
20816
20892
  opts.onDispatchSuppressed?.({
20817
20893
  reason: "one-shot-spent",
@@ -20836,9 +20912,12 @@ function buildWireConfig(opts) {
20836
20912
  opts.onViolation(new ClientContractViolationError("outbound-action", result.violations));
20837
20913
  return;
20838
20914
  }
20839
- if (isOneShot)
20915
+ if (isOneShot && !spentOneShots.has(actionName)) {
20840
20916
  spentOneShots.add(actionName);
20917
+ notifySpent();
20918
+ }
20841
20919
  opts.emitEnvelope(envelope);
20920
+ markPending(actionName);
20842
20921
  },
20843
20922
  subscribe: (channelName, handler) => {
20844
20923
  return opts.streamBus.subscribe(channelName, (env) => {
@@ -20853,65 +20932,65 @@ function buildWireConfig(opts) {
20853
20932
  }
20854
20933
 
20855
20934
  // ../mcp-apps-react/dist/index.mjs
20856
- var import_react8 = __toESM(require_react(), 1);
20935
+ var import_react10 = __toESM(require_react(), 1);
20857
20936
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
20858
20937
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
20859
- var import_react9 = __toESM(require_react(), 1);
20860
- var import_react10 = __toESM(require_react(), 1);
20938
+ var import_react11 = __toESM(require_react(), 1);
20939
+ var import_react12 = __toESM(require_react(), 1);
20861
20940
  var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
20862
20941
  var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
20863
20942
  var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
20864
20943
  var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
20865
- var import_react11 = __toESM(require_react(), 1);
20866
- var import_react12 = __toESM(require_react(), 1);
20944
+ var import_react13 = __toESM(require_react(), 1);
20945
+ var import_react14 = __toESM(require_react(), 1);
20867
20946
  var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
20868
20947
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
20869
20948
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
20870
- var import_react13 = __toESM(require_react(), 1);
20949
+ var import_react15 = __toESM(require_react(), 1);
20871
20950
  var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20872
- var import_react14 = __toESM(require_react(), 1);
20951
+ var import_react16 = __toESM(require_react(), 1);
20873
20952
  var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20874
- var import_react15 = __toESM(require_react(), 1);
20953
+ var import_react17 = __toESM(require_react(), 1);
20875
20954
  var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
20876
20955
  var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
20877
- var import_react16 = __toESM(require_react(), 1);
20956
+ var import_react18 = __toESM(require_react(), 1);
20878
20957
  var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20879
- var import_react17 = __toESM(require_react(), 1);
20958
+ var import_react19 = __toESM(require_react(), 1);
20880
20959
  var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20881
- var import_react18 = __toESM(require_react(), 1);
20960
+ var import_react20 = __toESM(require_react(), 1);
20882
20961
  var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
20883
20962
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
20884
20963
  var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
20885
- var import_react19 = __toESM(require_react(), 1);
20964
+ var import_react21 = __toESM(require_react(), 1);
20886
20965
  var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
20887
20966
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
20888
20967
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
20889
- var import_react20 = __toESM(require_react(), 1);
20968
+ var import_react22 = __toESM(require_react(), 1);
20890
20969
  var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20891
- var import_react21 = __toESM(require_react(), 1);
20970
+ var import_react23 = __toESM(require_react(), 1);
20892
20971
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
20893
20972
  var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
20894
- var import_react22 = __toESM(require_react(), 1);
20895
- var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20896
- var import_react23 = __toESM(require_react(), 1);
20897
- var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20898
20973
  var import_react24 = __toESM(require_react(), 1);
20899
- var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20974
+ var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20900
20975
  var import_react25 = __toESM(require_react(), 1);
20901
- var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20976
+ var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20902
20977
  var import_react26 = __toESM(require_react(), 1);
20978
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20903
20979
  var import_react27 = __toESM(require_react(), 1);
20904
- var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20980
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20905
20981
  var import_react28 = __toESM(require_react(), 1);
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);
20906
20985
  var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
20907
20986
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
20908
20987
  var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
20909
20988
  var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
20910
- var import_react29 = __toESM(require_react(), 1);
20989
+ var import_react31 = __toESM(require_react(), 1);
20911
20990
  var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20912
- var import_react30 = __toESM(require_react(), 1);
20991
+ var import_react32 = __toESM(require_react(), 1);
20913
20992
  var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20914
- var import_react31 = __toESM(require_react(), 1);
20993
+ var import_react33 = __toESM(require_react(), 1);
20915
20994
  var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
20916
20995
  var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
20917
20996
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
@@ -20919,38 +20998,38 @@ var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
20919
20998
  var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
20920
20999
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
20921
21000
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
20922
- var import_react32 = __toESM(require_react(), 1);
21001
+ var import_react34 = __toESM(require_react(), 1);
20923
21002
  var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
20924
21003
  var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
20925
- var import_react33 = __toESM(require_react(), 1);
21004
+ var import_react35 = __toESM(require_react(), 1);
20926
21005
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
20927
21006
  var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
20928
- var import_react34 = __toESM(require_react(), 1);
21007
+ var import_react36 = __toESM(require_react(), 1);
20929
21008
  var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
20930
21009
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
20931
- var import_react35 = __toESM(require_react(), 1);
21010
+ var import_react37 = __toESM(require_react(), 1);
20932
21011
  var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
20933
21012
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
20934
- var import_react36 = __toESM(require_react(), 1);
21013
+ var import_react38 = __toESM(require_react(), 1);
20935
21014
  var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
20936
- var import_react37 = __toESM(require_react(), 1);
21015
+ var import_react39 = __toESM(require_react(), 1);
20937
21016
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
20938
21017
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
20939
21018
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
20940
- var import_react38 = __toESM(require_react(), 1);
21019
+ var import_react40 = __toESM(require_react(), 1);
20941
21020
  var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20942
- var import_react39 = __toESM(require_react(), 1);
21021
+ var import_react41 = __toESM(require_react(), 1);
20943
21022
  var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20944
- var import_react40 = __toESM(require_react(), 1);
21023
+ var import_react42 = __toESM(require_react(), 1);
20945
21024
  var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
20946
- var import_react41 = __toESM(require_react(), 1);
21025
+ var import_react43 = __toESM(require_react(), 1);
20947
21026
  var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
20948
21027
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
20949
- var import_react42 = __toESM(require_react(), 1);
21028
+ var import_react44 = __toESM(require_react(), 1);
20950
21029
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
20951
21030
  var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
20952
- var import_react43 = __toESM(require_react(), 1);
20953
- var GguiContext = (0, import_react7.createContext)(null);
21031
+ var import_react45 = __toESM(require_react(), 1);
21032
+ var GguiContext = (0, import_react9.createContext)(null);
20954
21033
  var KNOWN_PERMISSION_NAMES_SET2 = new Set(KNOWN_PERMISSION_NAMES);
20955
21034
  var primitives_exports = {};
20956
21035
  __export2(primitives_exports, {
@@ -21119,9 +21198,9 @@ function frameAttributes(frame) {
21119
21198
  function renderWithTrait(trait, traitProps, root, children) {
21120
21199
  const marks = frameAttributes(root.frame);
21121
21200
  if (trait === void 0) {
21122
- return (0, import_react9.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);
21123
21202
  }
21124
- return (0, import_react9.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);
21125
21204
  }
21126
21205
  function resolveToneCss(tone) {
21127
21206
  switch (tone) {
@@ -21305,7 +21384,7 @@ function Stack(props) {
21305
21384
  return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21306
21385
  }
21307
21386
  function Row(props) {
21308
- return (0, import_react10.createElement)(Stack, { ...props, direction: "horizontal" });
21387
+ return (0, import_react12.createElement)(Stack, { ...props, direction: "horizontal" });
21309
21388
  }
21310
21389
  var BREAKPOINTS = [
21311
21390
  ["sm", 640],
@@ -21474,7 +21553,7 @@ function Text({ children, size = "base", weight = "normal", caps = false, tone,
21474
21553
  ...style
21475
21554
  };
21476
21555
  const elementProps = { id, htmlFor, className, style: textStyle };
21477
- return (0, import_react11.createElement)(is, elementProps, children);
21556
+ return (0, import_react13.createElement)(is, elementProps, children);
21478
21557
  }
21479
21558
  var fontFamily = {
21480
21559
  sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
@@ -21576,7 +21655,7 @@ function Heading({ children, level = 2, tone, align, style, className }) {
21576
21655
  letterSpacing: `var(--ggui-letter-spacing-heading, ${fallback.letterSpacing})`
21577
21656
  };
21578
21657
  const resolvedColor = tone ? resolveToneCss(tone) : "var(--ggui-color-onContainer, #18181b)";
21579
- return (0, import_react12.createElement)(tag, {
21658
+ return (0, import_react14.createElement)(tag, {
21580
21659
  className,
21581
21660
  style: {
21582
21661
  ...headingStyle,
@@ -21724,7 +21803,7 @@ var sizeStyles2 = {
21724
21803
  }
21725
21804
  };
21726
21805
  function Input({ label, placeholder, value, onChange, type = "text", error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21727
- const uniqueId = (0, import_react13.useId)();
21806
+ const uniqueId = (0, import_react15.useId)();
21728
21807
  const inputId = `${uniqueId}-input`;
21729
21808
  const messageId = `${uniqueId}-message`;
21730
21809
  const hasError = Boolean(error);
@@ -21753,7 +21832,7 @@ function Input({ label, placeholder, value, onChange, type = "text", error, help
21753
21832
  }, children: error || helperText })] });
21754
21833
  }
21755
21834
  function TextArea({ label, placeholder, value, onChange, rows = 4, error, helperText, required, disabled, maxLength, showCount, autoResize, style, className, ...rest }) {
21756
- const uniqueId = (0, import_react14.useId)();
21835
+ const uniqueId = (0, import_react16.useId)();
21757
21836
  const textareaId = `${uniqueId}-textarea`;
21758
21837
  const messageId = `${uniqueId}-message`;
21759
21838
  const hasError = Boolean(error);
@@ -21795,7 +21874,7 @@ var sizeStyles3 = {
21795
21874
  lg: { padding: "12px 14px", fontSize: "var(--ggui-font-size-base, 16px)" }
21796
21875
  };
21797
21876
  function Select({ label, value, onChange, options, placeholder, error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21798
- const uniqueId = (0, import_react15.useId)();
21877
+ const uniqueId = (0, import_react17.useId)();
21799
21878
  const selectId = `${uniqueId}-select`;
21800
21879
  const messageId = `${uniqueId}-message`;
21801
21880
  const hasError = Boolean(error);
@@ -21874,7 +21953,7 @@ var sizeConfig = {
21874
21953
  };
21875
21954
  function Toggle({ label, checked, onChange, disabled, size = "md", style, className }) {
21876
21955
  const config = sizeConfig[size];
21877
- const [focused, setFocused] = (0, import_react16.useState)(false);
21956
+ const [focused, setFocused] = (0, import_react18.useState)(false);
21878
21957
  return (0, import_jsx_runtime15.jsxs)("label", { className, style: {
21879
21958
  display: "flex",
21880
21959
  alignItems: "center",
@@ -21916,7 +21995,7 @@ function Toggle({ label, checked, onChange, disabled, size = "md", style, classN
21916
21995
  }, children: label })] });
21917
21996
  }
21918
21997
  function RadioGroup({ label, value, onChange, options, direction = "vertical", disabled, error, style, className }) {
21919
- const uniqueId = (0, import_react17.useId)();
21998
+ const uniqueId = (0, import_react19.useId)();
21920
21999
  const labelId = `${uniqueId}-label`;
21921
22000
  const errorId = `${uniqueId}-error`;
21922
22001
  const groupName = `${uniqueId}-radio`;
@@ -21981,7 +22060,7 @@ function RadioGroup({ label, value, onChange, options, direction = "vertical", d
21981
22060
  }, children: error })] });
21982
22061
  }
21983
22062
  function Slider({ label, value = 0, onChange, min = 0, max = 100, step = 1, disabled, showValue, style, className }) {
21984
- const uniqueId = (0, import_react18.useId)();
22063
+ const uniqueId = (0, import_react20.useId)();
21985
22064
  const sliderId = `${uniqueId}-slider`;
21986
22065
  const labelId = `${uniqueId}-label`;
21987
22066
  const percentage = (value - min) / (max - min) * 100;
@@ -22112,7 +22191,7 @@ var avatarColors = [
22112
22191
  "var(--ggui-color-info-500, #06b6d4)"
22113
22192
  ];
22114
22193
  function Avatar({ src, name, size = "md", shape = "circle", style, className }) {
22115
- const [imageError, setImageError] = (0, import_react19.useState)(false);
22194
+ const [imageError, setImageError] = (0, import_react21.useState)(false);
22116
22195
  const resolvedSize = typeof size === "number" ? size : sizeMap2[size] || 40;
22117
22196
  const initials = name ? name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
22118
22197
  const getColorFromName = (name2) => {
@@ -22248,7 +22327,7 @@ function Progress({ value, max = 100, variant = "default", size = "md", label, s
22248
22327
  }` })] })] });
22249
22328
  }
22250
22329
  function Image({ src, alt, width, height, objectFit = "cover", radius: radius2, fallback, style, className }) {
22251
- const [error, setError] = (0, import_react20.useState)(false);
22330
+ const [error, setError] = (0, import_react22.useState)(false);
22252
22331
  const resolveSize2 = (value) => {
22253
22332
  if (value === void 0)
22254
22333
  return void 0;
@@ -26809,7 +26888,7 @@ function resolveLucideName(name) {
26809
26888
  return LUCIDE_LOOKUP.get(normalized);
26810
26889
  }
26811
26890
  function renderLucideIcon(data, size, color) {
26812
- 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_react21.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 })) });
26813
26892
  }
26814
26893
  function Icon({ name, size = 24, tone, children, style, className, "aria-label": ariaLabel }) {
26815
26894
  const iconColor = tone ? resolveToneCss(tone) : "currentColor";
@@ -26865,10 +26944,10 @@ function Link({ children, href, external, tone, underline = "hover", style, clas
26865
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" })] })] });
26866
26945
  }
26867
26946
  function Tooltip({ children, content, position = "top", delay = 200, style, className }) {
26868
- const [visible, setVisible] = (0, import_react22.useState)(false);
26869
- const [coords, setCoords] = (0, import_react22.useState)({ top: 0, left: 0 });
26870
- const triggerRef = (0, import_react22.useRef)(null);
26871
- const timeoutRef = (0, import_react22.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);
26872
26951
  const showTooltip = () => {
26873
26952
  timeoutRef.current = setTimeout(() => {
26874
26953
  setVisible(true);
@@ -26880,7 +26959,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26880
26959
  }
26881
26960
  setVisible(false);
26882
26961
  };
26883
- (0, import_react22.useEffect)(() => {
26962
+ (0, import_react24.useEffect)(() => {
26884
26963
  if (visible && triggerRef.current) {
26885
26964
  const rect = triggerRef.current.getBoundingClientRect();
26886
26965
  const offset = 8;
@@ -26907,7 +26986,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26907
26986
  setCoords({ top, left });
26908
26987
  }
26909
26988
  }, [visible, position]);
26910
- (0, import_react22.useEffect)(() => {
26989
+ (0, import_react24.useEffect)(() => {
26911
26990
  return () => {
26912
26991
  if (timeoutRef.current) {
26913
26992
  clearTimeout(timeoutRef.current);
@@ -26956,7 +27035,7 @@ var sortIndicator = (active, direction) => (0, import_jsx_runtime27.jsxs)("span"
26956
27035
  opacity: active ? 1 : 0.3
26957
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" })] });
26958
27037
  function Table({ columns, data, sortKey, sortDirection = "asc", onSort, striped = false, hoverable = true, compact = false, bordered = false, caption, style, className }) {
26959
- const [hoveredRow, setHoveredRow] = (0, import_react23.useState)(null);
27038
+ const [hoveredRow, setHoveredRow] = (0, import_react25.useState)(null);
26960
27039
  const cellPadding = compact ? "var(--ggui-spacing-1, 4px) var(--ggui-spacing-2, 8px)" : "var(--ggui-spacing-2, 8px) var(--ggui-spacing-4, 16px)";
26961
27040
  const handleSort = (key) => {
26962
27041
  if (!onSort)
@@ -27027,10 +27106,10 @@ var sizeStyles5 = {
27027
27106
  }
27028
27107
  };
27029
27108
  function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullWidth = false, style, className }) {
27030
- const uniqueId = (0, import_react24.useId)();
27031
- const [internalKey, setInternalKey] = (0, import_react24.useState)(items[0]?.key);
27109
+ const uniqueId = (0, import_react26.useId)();
27110
+ const [internalKey, setInternalKey] = (0, import_react26.useState)(items[0]?.key);
27032
27111
  const currentKey = activeKey ?? internalKey;
27033
- const handleChange = (0, import_react24.useCallback)((key) => {
27112
+ const handleChange = (0, import_react26.useCallback)((key) => {
27034
27113
  if (onChange) {
27035
27114
  onChange(key);
27036
27115
  } else {
@@ -27038,8 +27117,8 @@ function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullW
27038
27117
  }
27039
27118
  }, [onChange]);
27040
27119
  const activeItem = items.find((item) => item.key === currentKey);
27041
- const tabListRef = (0, import_react24.useRef)(null);
27042
- const handleTabKeyDown = (0, import_react24.useCallback)((e) => {
27120
+ const tabListRef = (0, import_react26.useRef)(null);
27121
+ const handleTabKeyDown = (0, import_react26.useCallback)((e) => {
27043
27122
  const enabledItems = items.filter((item) => !item.disabled);
27044
27123
  const currentIndex = enabledItems.findIndex((item) => item.key === currentKey);
27045
27124
  let nextIndex;
@@ -27303,7 +27382,7 @@ var defaultIcons2 = {
27303
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" }) })
27304
27383
  };
27305
27384
  function Toast({ message, variant = "info", title, duration: duration2 = 5e3, onClose, visible = true, style, className }) {
27306
- (0, import_react25.useEffect)(() => {
27385
+ (0, import_react27.useEffect)(() => {
27307
27386
  if (!visible || duration2 === 0 || !onClose)
27308
27387
  return;
27309
27388
  const timer = setTimeout(onClose, duration2);
@@ -27361,8 +27440,8 @@ var chevron = (expanded) => (0, import_jsx_runtime30.jsx)("svg", { width: "16",
27361
27440
  flexShrink: 0
27362
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" }) });
27363
27442
  function Accordion({ items, expandedKeys, onChange, multiple = false, variant = "default", style, className }) {
27364
- const uniqueId = (0, import_react26.useId)();
27365
- const [internalExpanded, setInternalExpanded] = (0, import_react26.useState)([]);
27443
+ const uniqueId = (0, import_react28.useId)();
27444
+ const [internalExpanded, setInternalExpanded] = (0, import_react28.useState)([]);
27366
27445
  const currentExpanded = expandedKeys ?? internalExpanded;
27367
27446
  const handleToggle = (key) => {
27368
27447
  let newExpanded;
@@ -27442,7 +27521,7 @@ function Accordion({ items, expandedKeys, onChange, multiple = false, variant =
27442
27521
  }
27443
27522
  var STYLE_ID = "ggui-motion-keyframes";
27444
27523
  function MotionKeyframes() {
27445
- (0, import_react27.useEffect)(() => {
27524
+ (0, import_react29.useEffect)(() => {
27446
27525
  if (document.getElementById(STYLE_ID))
27447
27526
  return;
27448
27527
  const styleEl = document.createElement("style");
@@ -27459,12 +27538,12 @@ function MotionKeyframes() {
27459
27538
  return null;
27460
27539
  }
27461
27540
  function useMotion() {
27462
- const [motionEnabled, setMotionEnabled] = (0, import_react27.useState)(() => {
27541
+ const [motionEnabled, setMotionEnabled] = (0, import_react29.useState)(() => {
27463
27542
  if (typeof window === "undefined")
27464
27543
  return true;
27465
27544
  return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
27466
27545
  });
27467
- (0, import_react27.useEffect)(() => {
27546
+ (0, import_react29.useEffect)(() => {
27468
27547
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
27469
27548
  const handler = (e) => setMotionEnabled(!e.matches);
27470
27549
  mq.addEventListener("change", handler);
@@ -27473,9 +27552,9 @@ function useMotion() {
27473
27552
  return { motionEnabled };
27474
27553
  }
27475
27554
  function useAnimationKey(dep) {
27476
- const [key, setKey] = (0, import_react27.useState)(0);
27477
- const isFirst = (0, import_react27.useRef)(true);
27478
- (0, import_react27.useEffect)(() => {
27555
+ const [key, setKey] = (0, import_react29.useState)(0);
27556
+ const isFirst = (0, import_react29.useRef)(true);
27557
+ (0, import_react29.useEffect)(() => {
27479
27558
  if (isFirst.current) {
27480
27559
  isFirst.current = false;
27481
27560
  return;
@@ -27502,7 +27581,7 @@ __export2(components_exports, {
27502
27581
  renderRichTextInlines: () => renderRichTextInlines
27503
27582
  });
27504
27583
  function SearchField({ value: controlledValue, onChange, onSearch, placeholder = "Search...", showButton = false, buttonText = "Search", loading, disabled, size = "md", style, className }) {
27505
- const [internalValue, setInternalValue] = (0, import_react28.useState)("");
27584
+ const [internalValue, setInternalValue] = (0, import_react30.useState)("");
27506
27585
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
27507
27586
  const handleChange = (newValue) => {
27508
27587
  if (controlledValue === void 0) {
@@ -27663,9 +27742,9 @@ function Tag({ children, variant = "default", size = "md", closable, onClose, ic
27663
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" }) }) })] });
27664
27743
  }
27665
27744
  function Dropdown({ trigger, options, value, onChange, placement = "bottom-start", disabled, style, className }) {
27666
- const [isOpen, setIsOpen] = (0, import_react29.useState)(false);
27667
- const containerRef = (0, import_react29.useRef)(null);
27668
- (0, import_react29.useEffect)(() => {
27745
+ const [isOpen, setIsOpen] = (0, import_react31.useState)(false);
27746
+ const containerRef = (0, import_react31.useRef)(null);
27747
+ (0, import_react31.useEffect)(() => {
27669
27748
  const handleClickOutside = (event) => {
27670
27749
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27671
27750
  setIsOpen(false);
@@ -27676,7 +27755,7 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27676
27755
  return () => document.removeEventListener("mousedown", handleClickOutside);
27677
27756
  }
27678
27757
  }, [isOpen]);
27679
- (0, import_react29.useEffect)(() => {
27758
+ (0, import_react31.useEffect)(() => {
27680
27759
  const handleEscape = (event) => {
27681
27760
  if (event.key === "Escape") {
27682
27761
  setIsOpen(false);
@@ -27723,16 +27802,16 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27723
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)) })] });
27724
27803
  }
27725
27804
  function Autocomplete({ value = "", onChange, onSelect, options, placeholder, label, loading, disabled, error, noResultsText = "No results found", style, className }) {
27726
- const [isOpen, setIsOpen] = (0, import_react30.useState)(false);
27727
- const [highlightedIndex, setHighlightedIndex] = (0, import_react30.useState)(-1);
27728
- const containerRef = (0, import_react30.useRef)(null);
27729
- const filteredOptions = (0, import_react30.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)(() => {
27730
27809
  if (!value)
27731
27810
  return options;
27732
27811
  const lowerValue = value.toLowerCase();
27733
27812
  return options.filter((opt) => opt.label.toLowerCase().includes(lowerValue) || opt.value.toLowerCase().includes(lowerValue));
27734
27813
  }, [options, value]);
27735
- (0, import_react30.useEffect)(() => {
27814
+ (0, import_react32.useEffect)(() => {
27736
27815
  const handleClickOutside = (event) => {
27737
27816
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27738
27817
  setIsOpen(false);
@@ -27821,7 +27900,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27821
27900
  ...style
27822
27901
  }, children: items.map((item, index) => {
27823
27902
  const isLast = index === items.length - 1;
27824
- return (0, import_jsx_runtime37.jsxs)(import_react31.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: {
27825
27904
  display: "flex",
27826
27905
  alignItems: "center",
27827
27906
  color: isLast ? "var(--ggui-color-onContainer, #111827)" : "var(--ggui-color-neutral-500, #6b7280)"
@@ -28469,7 +28548,7 @@ function Header({ logo, navigation: navigation2, actions, sticky = false, backgr
28469
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 })] });
28470
28549
  }
28471
28550
  function SidebarItem({ item, activeId, onItemClick, collapsed, depth = 0 }) {
28472
- const [expanded, setExpanded] = (0, import_react32.useState)(false);
28551
+ const [expanded, setExpanded] = (0, import_react34.useState)(false);
28473
28552
  const hasChildren = item.children && item.children.length > 0;
28474
28553
  const isActive = activeId === item.id;
28475
28554
  const handleClick = () => {
@@ -28538,8 +28617,8 @@ function CardGrid({ children, columns = 3, gap = 16, style, className }) {
28538
28617
  }, children });
28539
28618
  }
28540
28619
  function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28541
- const [showReplyInput, setShowReplyInput] = (0, import_react33.useState)(false);
28542
- const [replyContent, setReplyContent] = (0, import_react33.useState)("");
28620
+ const [showReplyInput, setShowReplyInput] = (0, import_react35.useState)(false);
28621
+ const [replyContent, setReplyContent] = (0, import_react35.useState)("");
28543
28622
  const handleSubmitReply = () => {
28544
28623
  if (replyContent.trim()) {
28545
28624
  onReply?.(comment.id, replyContent);
@@ -28564,7 +28643,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28564
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))] });
28565
28644
  }
28566
28645
  function CommentThread({ comments, currentUser, onAddComment, onReply, onReaction, loading, style, className }) {
28567
- const [newComment, setNewComment] = (0, import_react33.useState)("");
28646
+ const [newComment, setNewComment] = (0, import_react35.useState)("");
28568
28647
  const handleSubmit = () => {
28569
28648
  if (newComment.trim()) {
28570
28649
  onAddComment?.(newComment);
@@ -28629,9 +28708,9 @@ function DataTable({ columns, data, rowKey = "id", loading, emptyText = "No data
28629
28708
  }) })] }) });
28630
28709
  }
28631
28710
  function ChatWindow({ messages, currentUserId, onSendMessage, loading, typing, placeholder = "Type a message...", header, style, className }) {
28632
- const [inputValue, setInputValue] = (0, import_react34.useState)("");
28633
- const messagesEndRef = (0, import_react34.useRef)(null);
28634
- (0, import_react34.useEffect)(() => {
28711
+ const [inputValue, setInputValue] = (0, import_react36.useState)("");
28712
+ const messagesEndRef = (0, import_react36.useRef)(null);
28713
+ (0, import_react36.useEffect)(() => {
28635
28714
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
28636
28715
  }, [messages]);
28637
28716
  const handleSend = () => {
@@ -28769,8 +28848,8 @@ function formatFileSize(bytes) {
28769
28848
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
28770
28849
  }
28771
28850
  function FileUploader({ files = [], onFilesSelected, onFileRemove, accept, multiple = true, maxSize, maxFiles, disabled, dragDrop = true, style, className }) {
28772
- const [isDragOver, setIsDragOver] = (0, import_react35.useState)(false);
28773
- const inputRef = (0, import_react35.useRef)(null);
28851
+ const [isDragOver, setIsDragOver] = (0, import_react37.useState)(false);
28852
+ const inputRef = (0, import_react37.useRef)(null);
28774
28853
  const handleFiles = (fileList) => {
28775
28854
  if (!fileList)
28776
28855
  return;
@@ -28909,12 +28988,12 @@ var sizeWidths = {
28909
28988
  full: "100vw"
28910
28989
  };
28911
28990
  function Modal({ open, onClose, title, children, footer, size = "md", closeOnOverlayClick = true, closeOnEscape = true, showCloseButton = true, style, className }) {
28912
- const handleEscape = (0, import_react36.useCallback)((e) => {
28991
+ const handleEscape = (0, import_react38.useCallback)((e) => {
28913
28992
  if (e.key === "Escape" && closeOnEscape) {
28914
28993
  onClose();
28915
28994
  }
28916
28995
  }, [closeOnEscape, onClose]);
28917
- (0, import_react36.useEffect)(() => {
28996
+ (0, import_react38.useEffect)(() => {
28918
28997
  if (open) {
28919
28998
  document.addEventListener("keydown", handleEscape);
28920
28999
  document.body.style.overflow = "hidden";
@@ -28979,9 +29058,9 @@ function Modal({ open, onClose, title, children, footer, size = "md", closeOnOve
28979
29058
  }, children: footer })] })] });
28980
29059
  }
28981
29060
  function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Search commands...", recentIds = [], loading, style, className }) {
28982
- const [query, setQuery] = (0, import_react37.useState)("");
28983
- const [selectedIndex, setSelectedIndex] = (0, import_react37.useState)(0);
28984
- const filteredCommands = (0, import_react37.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)(() => {
28985
29064
  const filtered = query ? commands.filter((cmd) => cmd.label.toLowerCase().includes(query.toLowerCase()) || cmd.description?.toLowerCase().includes(query.toLowerCase())) : commands;
28986
29065
  const groups = /* @__PURE__ */ new Map();
28987
29066
  if (!query && recentIds.length > 0) {
@@ -29002,21 +29081,21 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29002
29081
  });
29003
29082
  return groups;
29004
29083
  }, [commands, query, recentIds]);
29005
- const flatCommands = (0, import_react37.useMemo)(() => {
29084
+ const flatCommands = (0, import_react39.useMemo)(() => {
29006
29085
  const flat = [];
29007
29086
  filteredCommands.forEach((cmds) => flat.push(...cmds));
29008
29087
  return flat;
29009
29088
  }, [filteredCommands]);
29010
- (0, import_react37.useEffect)(() => {
29089
+ (0, import_react39.useEffect)(() => {
29011
29090
  setSelectedIndex(0);
29012
29091
  }, [query]);
29013
- (0, import_react37.useEffect)(() => {
29092
+ (0, import_react39.useEffect)(() => {
29014
29093
  if (open) {
29015
29094
  setQuery("");
29016
29095
  setSelectedIndex(0);
29017
29096
  }
29018
29097
  }, [open]);
29019
- const handleKeyDown = (0, import_react37.useCallback)((e) => {
29098
+ const handleKeyDown = (0, import_react39.useCallback)((e) => {
29020
29099
  if (e.key === "Escape") {
29021
29100
  onClose();
29022
29101
  return;
@@ -29036,7 +29115,7 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29036
29115
  }
29037
29116
  }
29038
29117
  }, [flatCommands, selectedIndex, onSelect, onClose]);
29039
- (0, import_react37.useEffect)(() => {
29118
+ (0, import_react39.useEffect)(() => {
29040
29119
  if (open) {
29041
29120
  document.addEventListener("keydown", handleKeyDown);
29042
29121
  return () => document.removeEventListener("keydown", handleKeyDown);
@@ -29285,9 +29364,9 @@ __export2(interact_exports, {
29285
29364
  Hoverable: () => Hoverable,
29286
29365
  Pressable: () => Pressable
29287
29366
  });
29288
- var Clickable = (0, import_react38.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) {
29289
- const [hovered, setHovered] = (0, import_react38.useState)(false);
29290
- const [active, setActive] = (0, import_react38.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);
29291
29370
  const hasClick = !!onClick;
29292
29371
  const resolvedCursor = disabled ? "not-allowed" : cursor ?? (hasClick ? "pointer" : void 0);
29293
29372
  const resolvedRole = role ?? (hasClick ? "button" : void 0);
@@ -29313,8 +29392,8 @@ var Clickable = (0, import_react38.forwardRef)(function Clickable2({ children, o
29313
29392
  setActive(false);
29314
29393
  }, onMouseDown: () => setActive(true), onMouseUp: () => setActive(false), onKeyDown: handleKeyDown, role: resolvedRole, "aria-label": ariaLabel, "aria-disabled": disabled || void 0, tabIndex: resolvedTabIndex, ...rest, children });
29315
29394
  });
29316
- var Hoverable = (0, import_react39.forwardRef)(function Hoverable2({ children, hoverStyle, onHoverChange, transition: transition2 = "all 200ms ease", style, className, ...rest }, ref) {
29317
- const [hovered, setHovered] = (0, import_react39.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);
29318
29397
  const mergedStyle = {
29319
29398
  ...style,
29320
29399
  transition: transition2,
@@ -29328,10 +29407,10 @@ var Hoverable = (0, import_react39.forwardRef)(function Hoverable2({ children, h
29328
29407
  onHoverChange?.(false);
29329
29408
  }, ...rest, children });
29330
29409
  });
29331
- var Pressable = (0, import_react40.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) {
29332
- const [hovered, setHovered] = (0, import_react40.useState)(false);
29333
- const [pressed, setPressed] = (0, import_react40.useState)(false);
29334
- const [longPressTimer, setLongPressTimer] = (0, import_react40.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);
29335
29414
  const hasPress = !!onPress || !!onLongPress;
29336
29415
  const handleMouseDown = (e) => {
29337
29416
  if (disabled)
@@ -29685,17 +29764,20 @@ function scrimTint(tone) {
29685
29764
  return "#000000";
29686
29765
  return tokenValue(tone);
29687
29766
  }
29688
- function familyRamp(group, anchor) {
29767
+ function familyRamp(group, anchor, ground) {
29689
29768
  const statedStops = {};
29690
29769
  for (const stop of STOPS) {
29691
29770
  const v = stated(group, stop);
29692
29771
  if (v !== void 0)
29693
29772
  statedStops[stop] = v;
29694
29773
  }
29695
- return rampFrom(statedStops, anchor);
29774
+ return rampFrom(statedStops, anchor, ground);
29696
29775
  }
29697
- function rampFrom(statedStops, anchor) {
29776
+ var NEUTRAL_ANCHOR_CHROMA = 0.02;
29777
+ var LIGHT_STOP_COUNT = 5;
29778
+ function rampFrom(statedStops, anchor, ground) {
29698
29779
  const a = hexToOklch(anchor);
29780
+ const g = ground !== void 0 && a.c < NEUTRAL_ANCHOR_CHROMA ? hexToOklch(ground) : void 0;
29699
29781
  const out = {};
29700
29782
  STOPS.forEach((stop, i) => {
29701
29783
  const v = statedStops[stop];
@@ -29703,7 +29785,16 @@ function rampFrom(statedStops, anchor) {
29703
29785
  out[stop] = v;
29704
29786
  return;
29705
29787
  }
29706
- 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 });
29707
29798
  });
29708
29799
  return out;
29709
29800
  }
@@ -29798,7 +29889,7 @@ function deriveThemeVariables(doc, mode, options = {}) {
29798
29889
  anchor = "#000000";
29799
29890
  }
29800
29891
  }
29801
- const ramp2 = familyRamp(g, anchor);
29892
+ const ramp2 = familyRamp(g, anchor, ground);
29802
29893
  for (const stop of STOPS)
29803
29894
  V[`--ggui-color-${fam}-${stop}`] = ramp2[stop];
29804
29895
  const cap = fam[0].toUpperCase() + fam.slice(1);
@@ -32811,7 +32902,7 @@ function getTheme(id, mode = "light") {
32811
32902
  function getDefaultThemeId() {
32812
32903
  return "ggui";
32813
32904
  }
32814
- var ThemeContext = (0, import_react41.createContext)(null);
32905
+ var ThemeContext = (0, import_react43.createContext)(null);
32815
32906
  var COLOR_MIX_SUPPORTS = "@supports (color: color-mix(in srgb, red, blue))";
32816
32907
  function resolvePrimary500Hex(cssVariables) {
32817
32908
  const match = cssVariables.match(/--ggui-color-primary-500:\s*(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})\s*;/);
@@ -32912,13 +33003,21 @@ function framelessSuppressionRule(scopeClass) {
32912
33003
  }
32913
33004
  var EXPANDED_FRAME = { outerRadiusVar: "--ggui-shape-radius-xl", insetPx: 16 };
32914
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
+ };
32915
33012
  function structuralScaffolding(scopeClass) {
32916
33013
  return `.${scopeClass} *, .${scopeClass} *::before, .${scopeClass} *::after { box-sizing: border-box; }
32917
33014
  .${scopeClass} h1, .${scopeClass} h2, .${scopeClass} h3, .${scopeClass} h4, .${scopeClass} h5, .${scopeClass} h6, .${scopeClass} button, .${scopeClass} input, .${scopeClass} textarea, .${scopeClass} select { font-family: inherit; }`;
32918
33015
  }
33016
+ var BODY_COPY_SIZE = "font-size: var(--ggui-font-size-base);";
32919
33017
  function baseInheritsRule(scopeClass) {
32920
33018
  return `.${scopeClass} {
32921
33019
  font-family: var(--ggui-font-family-sans);
33020
+ ${BODY_COPY_SIZE}
32922
33021
  color: var(--ggui-color-onGround);
32923
33022
  background-color: transparent;
32924
33023
  }`;
@@ -32968,6 +33067,15 @@ var WIRE_EXPORTS = [
32968
33067
  "useGguiContext",
32969
33068
  "useContract",
32970
33069
  "useWireContext",
33070
+ // ggui#1223: a `oneShot` action's spent state, as data. It is served here
33071
+ // one release BEFORE the triad teaches it, because a card that imports a name
33072
+ // its runtime's shim lacks fails at module link. A card generated to use it
33073
+ // must never meet a runtime without it.
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",
32971
33079
  // Provider component
32972
33080
  "GguiWireProvider"
32973
33081
  ];
@@ -33386,7 +33494,7 @@ function makeScopeClass(reactId) {
33386
33494
  }
33387
33495
  var AUTO_RETRY_LIMIT = 1;
33388
33496
  var AUTO_RETRY_DELAY = 500;
33389
- var ErrorBoundary = class extends import_react8.default.Component {
33497
+ var ErrorBoundary = class extends import_react10.default.Component {
33390
33498
  state = { error: null, catchCount: 0, autoRetrying: false };
33391
33499
  retryTimer = null;
33392
33500
  static getDerivedStateFromError(error) {
@@ -33502,12 +33610,12 @@ function ReactComponentRenderer({
33502
33610
  fallback = /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { children: "Loading component..." }),
33503
33611
  onError
33504
33612
  }) {
33505
- const reactId = (0, import_react8.useId)();
33506
- const [scopeClass] = (0, import_react8.useState)(() => makeScopeClass(reactId) || `ggui-rcr-${++scopeCounter}`);
33507
- const [Component, setComponent] = (0, import_react8.useState)(null);
33508
- const [error, setError] = (0, import_react8.useState)(null);
33509
- const [loading, setLoading] = (0, import_react8.useState)(true);
33510
- (0, import_react8.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)(() => {
33511
33619
  if (!code || code.trim().length === 0) {
33512
33620
  setComponent(null);
33513
33621
  setLoading(false);
@@ -33535,7 +33643,7 @@ function ReactComponentRenderer({
33535
33643
  } catch {
33536
33644
  }
33537
33645
  w.__ggui__ = {
33538
- react: import_react8.default,
33646
+ react: import_react10.default,
33539
33647
  reactDom: reactDomModule,
33540
33648
  primitives: primitives_exports,
33541
33649
  components: components_exports,
@@ -33543,7 +33651,7 @@ function ReactComponentRenderer({
33543
33651
  interact: interact_exports,
33544
33652
  wire: dist_exports
33545
33653
  };
33546
- w.__REACT = import_react8.default;
33654
+ w.__REACT = import_react10.default;
33547
33655
  w.__GGUI_PRIMITIVES = primitives_exports;
33548
33656
  w.__GGUI_COMPONENTS = components_exports;
33549
33657
  w.__GGUI_COMPOSITIONS = compositions_exports;
@@ -33689,11 +33797,11 @@ function PreviewApp({
33689
33797
  token,
33690
33798
  selectedId
33691
33799
  }) {
33692
- const [state, setState] = (0, import_react44.useState)(
33800
+ const [state, setState] = (0, import_react46.useState)(
33693
33801
  selectedId ? { kind: "loading" } : { kind: "idle" }
33694
33802
  );
33695
- const [version, setVersion] = (0, import_react44.useState)(0);
33696
- (0, import_react44.useEffect)(() => {
33803
+ const [version, setVersion] = (0, import_react46.useState)(0);
33804
+ (0, import_react46.useEffect)(() => {
33697
33805
  if (!selectedId) {
33698
33806
  setState({ kind: "idle" });
33699
33807
  return;
@@ -33706,7 +33814,7 @@ function PreviewApp({
33706
33814
  });
33707
33815
  return () => controller.abort();
33708
33816
  }, [selectedId, token, version]);
33709
- (0, import_react44.useEffect)(() => {
33817
+ (0, import_react46.useEffect)(() => {
33710
33818
  if (!selectedId) return;
33711
33819
  const controller = new AbortController();
33712
33820
  subscribeToRegistry(token, controller.signal, (event) => {
@@ -33868,7 +33976,7 @@ function mount() {
33868
33976
  if (!root) throw new Error("preview-root element not found in shell");
33869
33977
  const { token, selectedId } = bootstrap();
33870
33978
  (0, import_client.createRoot)(root).render(
33871
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react44.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 }) })
33872
33980
  );
33873
33981
  }
33874
33982
  mount();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/dev-stack",
3
- "version": "0.23.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.23.0",
32
- "@ggui-ai/project-config": "0.23.0",
33
- "@ggui-ai/ui-registry": "0.23.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.23.0",
44
- "@ggui-ai/mcp-apps-react": "0.23.0",
45
- "@ggui-ai/wire": "0.23.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",