@ggui-ai/dev-stack 0.23.0 → 0.24.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_react45 = __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
20440
  var import_react7 = __toESM(require_react(), 1);
20441
+ var import_react8 = __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
+ useActionSpent: () => useActionSpent,
20455
20456
  useApp: () => useApp,
20456
20457
  useAuth: () => useAuth,
20457
20458
  useContract: () => useContract,
@@ -20542,8 +20543,19 @@ function useAction(actionName) {
20542
20543
  }, [actionName, dispatch, onDispatchSuppressed]);
20543
20544
  }
20544
20545
 
20545
- // ../wire/dist/useGguiContext.js
20546
+ // ../wire/dist/action-spent.js
20546
20547
  var import_react3 = __toESM(require_react(), 1);
20548
+ var ActionSpentContext = (0, import_react3.createContext)(null);
20549
+ var noSubscription = () => () => void 0;
20550
+ function useActionSpent(actionName) {
20551
+ const source = (0, import_react3.useContext)(ActionSpentContext);
20552
+ const subscribe = (0, import_react3.useCallback)((listener) => source === null ? noSubscription() : source.subscribe(listener), [source]);
20553
+ const read = (0, import_react3.useCallback)(() => source === null ? false : source.isSpent(actionName), [source, actionName]);
20554
+ return (0, import_react3.useSyncExternalStore)(subscribe, read, read);
20555
+ }
20556
+
20557
+ // ../wire/dist/useGguiContext.js
20558
+ var import_react4 = __toESM(require_react(), 1);
20547
20559
  function useGguiContext(slotName) {
20548
20560
  const contextName = slotName.length === 0 ? "Context" : slotName.charAt(0).toUpperCase() + slotName.slice(1) + "Context";
20549
20561
  const registry = globalThis.__ggui__?.contexts;
@@ -20551,19 +20563,19 @@ function useGguiContext(slotName) {
20551
20563
  if (!ctx) {
20552
20564
  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
20565
  }
20554
- return (0, import_react3.useContext)(ctx);
20566
+ return (0, import_react4.useContext)(ctx);
20555
20567
  }
20556
20568
 
20557
20569
  // ../wire/dist/useStream.js
20558
- var import_react4 = __toESM(require_react(), 1);
20570
+ var import_react5 = __toESM(require_react(), 1);
20559
20571
  function useStream(channelName) {
20560
20572
  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);
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);
20565
20577
  allRef.current = all;
20566
- (0, import_react4.useEffect)(() => {
20578
+ (0, import_react5.useEffect)(() => {
20567
20579
  return subscribe(channelName, (delivery) => {
20568
20580
  const typed = delivery.payload;
20569
20581
  setLatest(typed);
@@ -20601,7 +20613,7 @@ function useApp() {
20601
20613
  }
20602
20614
 
20603
20615
  // ../wire/dist/useRender.js
20604
- var import_react5 = __toESM(require_react(), 1);
20616
+ var import_react6 = __toESM(require_react(), 1);
20605
20617
 
20606
20618
  // ../wire/dist/connection-store.js
20607
20619
  var ConnectionWriterConflictError = class extends Error {
@@ -20698,7 +20710,7 @@ var connectionSource = documentStore.source;
20698
20710
  // ../wire/dist/useRender.js
20699
20711
  function useRender() {
20700
20712
  const { render } = useWireContext();
20701
- const isConnected = (0, import_react5.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20713
+ const isConnected = (0, import_react6.useSyncExternalStore)(connectionSource.subscribe, connectionSource.getSnapshot, connectionSource.getSnapshot);
20702
20714
  return { sessionId: render.sessionId, isConnected };
20703
20715
  }
20704
20716
 
@@ -20800,7 +20812,24 @@ function buildWireConfig(opts) {
20800
20812
  });
20801
20813
  const validateEnvelope = opts.validateEnvelope ?? validateOutboundActionEnvelope;
20802
20814
  const spentOneShots = /* @__PURE__ */ new Set();
20815
+ const isSpent = (actionName) => opts.getActiveActionSpec()?.[actionName]?.oneShot === true && (spentOneShots.has(actionName) || opts.getSpentOneShots?.()?.includes(actionName) === true);
20816
+ const spentListeners = /* @__PURE__ */ new Set();
20817
+ const notifySpent = () => {
20818
+ for (const listener of [...spentListeners])
20819
+ listener();
20820
+ };
20821
+ const actionSpent = {
20822
+ isSpent,
20823
+ subscribe: (listener) => {
20824
+ spentListeners.add(listener);
20825
+ return () => {
20826
+ spentListeners.delete(listener);
20827
+ };
20828
+ }
20829
+ };
20830
+ opts.spentInputsChanged?.(notifySpent);
20803
20831
  return {
20832
+ actionSpent,
20804
20833
  app: opts.app,
20805
20834
  render: opts.render,
20806
20835
  auth: opts.auth,
@@ -20810,8 +20839,7 @@ function buildWireConfig(opts) {
20810
20839
  if (actionSpec === void 0)
20811
20840
  opts.onActionSpecAbsent?.(actionName);
20812
20841
  const isOneShot = actionSpec?.[actionName]?.oneShot === true;
20813
- const spent = spentOneShots.has(actionName) || opts.getSpentOneShots?.()?.includes(actionName) === true;
20814
- if (isOneShot && spent) {
20842
+ if (isSpent(actionName)) {
20815
20843
  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
20844
  opts.onDispatchSuppressed?.({
20817
20845
  reason: "one-shot-spent",
@@ -20836,8 +20864,10 @@ function buildWireConfig(opts) {
20836
20864
  opts.onViolation(new ClientContractViolationError("outbound-action", result.violations));
20837
20865
  return;
20838
20866
  }
20839
- if (isOneShot)
20867
+ if (isOneShot && !spentOneShots.has(actionName)) {
20840
20868
  spentOneShots.add(actionName);
20869
+ notifySpent();
20870
+ }
20841
20871
  opts.emitEnvelope(envelope);
20842
20872
  },
20843
20873
  subscribe: (channelName, handler) => {
@@ -20853,65 +20883,65 @@ function buildWireConfig(opts) {
20853
20883
  }
20854
20884
 
20855
20885
  // ../mcp-apps-react/dist/index.mjs
20856
- var import_react8 = __toESM(require_react(), 1);
20886
+ var import_react9 = __toESM(require_react(), 1);
20857
20887
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
20858
20888
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
20859
- var import_react9 = __toESM(require_react(), 1);
20860
20889
  var import_react10 = __toESM(require_react(), 1);
20890
+ var import_react11 = __toESM(require_react(), 1);
20861
20891
  var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
20862
20892
  var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
20863
20893
  var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
20864
20894
  var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
20865
- var import_react11 = __toESM(require_react(), 1);
20866
20895
  var import_react12 = __toESM(require_react(), 1);
20896
+ var import_react13 = __toESM(require_react(), 1);
20867
20897
  var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
20868
20898
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
20869
20899
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
20870
- var import_react13 = __toESM(require_react(), 1);
20871
- var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20872
20900
  var import_react14 = __toESM(require_react(), 1);
20873
- var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20901
+ var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20874
20902
  var import_react15 = __toESM(require_react(), 1);
20903
+ var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20904
+ var import_react16 = __toESM(require_react(), 1);
20875
20905
  var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
20876
20906
  var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
20877
- var import_react16 = __toESM(require_react(), 1);
20878
- var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20879
20907
  var import_react17 = __toESM(require_react(), 1);
20880
- var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20908
+ var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20881
20909
  var import_react18 = __toESM(require_react(), 1);
20910
+ var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20911
+ var import_react19 = __toESM(require_react(), 1);
20882
20912
  var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
20883
20913
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
20884
20914
  var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
20885
- var import_react19 = __toESM(require_react(), 1);
20915
+ var import_react20 = __toESM(require_react(), 1);
20886
20916
  var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
20887
20917
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
20888
20918
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
20889
- var import_react20 = __toESM(require_react(), 1);
20890
- var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20891
20919
  var import_react21 = __toESM(require_react(), 1);
20920
+ var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20921
+ var import_react22 = __toESM(require_react(), 1);
20892
20922
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
20893
20923
  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
20924
  var import_react23 = __toESM(require_react(), 1);
20897
- var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20925
+ var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20898
20926
  var import_react24 = __toESM(require_react(), 1);
20899
- var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20927
+ var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20900
20928
  var import_react25 = __toESM(require_react(), 1);
20901
- var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20929
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20902
20930
  var import_react26 = __toESM(require_react(), 1);
20931
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20903
20932
  var import_react27 = __toESM(require_react(), 1);
20904
- var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20905
20933
  var import_react28 = __toESM(require_react(), 1);
20934
+ var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20935
+ var import_react29 = __toESM(require_react(), 1);
20906
20936
  var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
20907
20937
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
20908
20938
  var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
20909
20939
  var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
20910
- var import_react29 = __toESM(require_react(), 1);
20911
- var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20912
20940
  var import_react30 = __toESM(require_react(), 1);
20913
- var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20941
+ var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20914
20942
  var import_react31 = __toESM(require_react(), 1);
20943
+ var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20944
+ var import_react32 = __toESM(require_react(), 1);
20915
20945
  var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
20916
20946
  var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
20917
20947
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
@@ -20919,38 +20949,38 @@ var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
20919
20949
  var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
20920
20950
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
20921
20951
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
20922
- var import_react32 = __toESM(require_react(), 1);
20952
+ var import_react33 = __toESM(require_react(), 1);
20923
20953
  var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
20924
20954
  var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
20925
- var import_react33 = __toESM(require_react(), 1);
20955
+ var import_react34 = __toESM(require_react(), 1);
20926
20956
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
20927
20957
  var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
20928
- var import_react34 = __toESM(require_react(), 1);
20958
+ var import_react35 = __toESM(require_react(), 1);
20929
20959
  var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
20930
20960
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
20931
- var import_react35 = __toESM(require_react(), 1);
20961
+ var import_react36 = __toESM(require_react(), 1);
20932
20962
  var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
20933
20963
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
20934
- var import_react36 = __toESM(require_react(), 1);
20935
- var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
20936
20964
  var import_react37 = __toESM(require_react(), 1);
20965
+ var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
20966
+ var import_react38 = __toESM(require_react(), 1);
20937
20967
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
20938
20968
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
20939
20969
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
20940
- var import_react38 = __toESM(require_react(), 1);
20941
- var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20942
20970
  var import_react39 = __toESM(require_react(), 1);
20943
- var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20971
+ var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20944
20972
  var import_react40 = __toESM(require_react(), 1);
20945
- var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
20973
+ var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20946
20974
  var import_react41 = __toESM(require_react(), 1);
20975
+ var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
20976
+ var import_react42 = __toESM(require_react(), 1);
20947
20977
  var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
20948
20978
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
20949
- var import_react42 = __toESM(require_react(), 1);
20979
+ var import_react43 = __toESM(require_react(), 1);
20950
20980
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
20951
20981
  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);
20982
+ var import_react44 = __toESM(require_react(), 1);
20983
+ var GguiContext = (0, import_react8.createContext)(null);
20954
20984
  var KNOWN_PERMISSION_NAMES_SET2 = new Set(KNOWN_PERMISSION_NAMES);
20955
20985
  var primitives_exports = {};
20956
20986
  __export2(primitives_exports, {
@@ -21119,9 +21149,9 @@ function frameAttributes(frame) {
21119
21149
  function renderWithTrait(trait, traitProps, root, children) {
21120
21150
  const marks = frameAttributes(root.frame);
21121
21151
  if (trait === void 0) {
21122
- return (0, import_react9.createElement)("div", { className: root.className, style: root.style, ...marks }, children);
21152
+ return (0, import_react10.createElement)("div", { className: root.className, style: root.style, ...marks }, children);
21123
21153
  }
21124
- return (0, import_react9.createElement)(trait, { ...traitProps, className: root.className, style: root.style, ...marks }, children);
21154
+ return (0, import_react10.createElement)(trait, { ...traitProps, className: root.className, style: root.style, ...marks }, children);
21125
21155
  }
21126
21156
  function resolveToneCss(tone) {
21127
21157
  switch (tone) {
@@ -21305,7 +21335,7 @@ function Stack(props) {
21305
21335
  return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21306
21336
  }
21307
21337
  function Row(props) {
21308
- return (0, import_react10.createElement)(Stack, { ...props, direction: "horizontal" });
21338
+ return (0, import_react11.createElement)(Stack, { ...props, direction: "horizontal" });
21309
21339
  }
21310
21340
  var BREAKPOINTS = [
21311
21341
  ["sm", 640],
@@ -21474,7 +21504,7 @@ function Text({ children, size = "base", weight = "normal", caps = false, tone,
21474
21504
  ...style
21475
21505
  };
21476
21506
  const elementProps = { id, htmlFor, className, style: textStyle };
21477
- return (0, import_react11.createElement)(is, elementProps, children);
21507
+ return (0, import_react12.createElement)(is, elementProps, children);
21478
21508
  }
21479
21509
  var fontFamily = {
21480
21510
  sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
@@ -21576,7 +21606,7 @@ function Heading({ children, level = 2, tone, align, style, className }) {
21576
21606
  letterSpacing: `var(--ggui-letter-spacing-heading, ${fallback.letterSpacing})`
21577
21607
  };
21578
21608
  const resolvedColor = tone ? resolveToneCss(tone) : "var(--ggui-color-onContainer, #18181b)";
21579
- return (0, import_react12.createElement)(tag, {
21609
+ return (0, import_react13.createElement)(tag, {
21580
21610
  className,
21581
21611
  style: {
21582
21612
  ...headingStyle,
@@ -21724,7 +21754,7 @@ var sizeStyles2 = {
21724
21754
  }
21725
21755
  };
21726
21756
  function Input({ label, placeholder, value, onChange, type = "text", error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21727
- const uniqueId = (0, import_react13.useId)();
21757
+ const uniqueId = (0, import_react14.useId)();
21728
21758
  const inputId = `${uniqueId}-input`;
21729
21759
  const messageId = `${uniqueId}-message`;
21730
21760
  const hasError = Boolean(error);
@@ -21753,7 +21783,7 @@ function Input({ label, placeholder, value, onChange, type = "text", error, help
21753
21783
  }, children: error || helperText })] });
21754
21784
  }
21755
21785
  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)();
21786
+ const uniqueId = (0, import_react15.useId)();
21757
21787
  const textareaId = `${uniqueId}-textarea`;
21758
21788
  const messageId = `${uniqueId}-message`;
21759
21789
  const hasError = Boolean(error);
@@ -21795,7 +21825,7 @@ var sizeStyles3 = {
21795
21825
  lg: { padding: "12px 14px", fontSize: "var(--ggui-font-size-base, 16px)" }
21796
21826
  };
21797
21827
  function Select({ label, value, onChange, options, placeholder, error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21798
- const uniqueId = (0, import_react15.useId)();
21828
+ const uniqueId = (0, import_react16.useId)();
21799
21829
  const selectId = `${uniqueId}-select`;
21800
21830
  const messageId = `${uniqueId}-message`;
21801
21831
  const hasError = Boolean(error);
@@ -21874,7 +21904,7 @@ var sizeConfig = {
21874
21904
  };
21875
21905
  function Toggle({ label, checked, onChange, disabled, size = "md", style, className }) {
21876
21906
  const config = sizeConfig[size];
21877
- const [focused, setFocused] = (0, import_react16.useState)(false);
21907
+ const [focused, setFocused] = (0, import_react17.useState)(false);
21878
21908
  return (0, import_jsx_runtime15.jsxs)("label", { className, style: {
21879
21909
  display: "flex",
21880
21910
  alignItems: "center",
@@ -21916,7 +21946,7 @@ function Toggle({ label, checked, onChange, disabled, size = "md", style, classN
21916
21946
  }, children: label })] });
21917
21947
  }
21918
21948
  function RadioGroup({ label, value, onChange, options, direction = "vertical", disabled, error, style, className }) {
21919
- const uniqueId = (0, import_react17.useId)();
21949
+ const uniqueId = (0, import_react18.useId)();
21920
21950
  const labelId = `${uniqueId}-label`;
21921
21951
  const errorId = `${uniqueId}-error`;
21922
21952
  const groupName = `${uniqueId}-radio`;
@@ -21981,7 +22011,7 @@ function RadioGroup({ label, value, onChange, options, direction = "vertical", d
21981
22011
  }, children: error })] });
21982
22012
  }
21983
22013
  function Slider({ label, value = 0, onChange, min = 0, max = 100, step = 1, disabled, showValue, style, className }) {
21984
- const uniqueId = (0, import_react18.useId)();
22014
+ const uniqueId = (0, import_react19.useId)();
21985
22015
  const sliderId = `${uniqueId}-slider`;
21986
22016
  const labelId = `${uniqueId}-label`;
21987
22017
  const percentage = (value - min) / (max - min) * 100;
@@ -22112,7 +22142,7 @@ var avatarColors = [
22112
22142
  "var(--ggui-color-info-500, #06b6d4)"
22113
22143
  ];
22114
22144
  function Avatar({ src, name, size = "md", shape = "circle", style, className }) {
22115
- const [imageError, setImageError] = (0, import_react19.useState)(false);
22145
+ const [imageError, setImageError] = (0, import_react20.useState)(false);
22116
22146
  const resolvedSize = typeof size === "number" ? size : sizeMap2[size] || 40;
22117
22147
  const initials = name ? name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
22118
22148
  const getColorFromName = (name2) => {
@@ -22248,7 +22278,7 @@ function Progress({ value, max = 100, variant = "default", size = "md", label, s
22248
22278
  }` })] })] });
22249
22279
  }
22250
22280
  function Image({ src, alt, width, height, objectFit = "cover", radius: radius2, fallback, style, className }) {
22251
- const [error, setError] = (0, import_react20.useState)(false);
22281
+ const [error, setError] = (0, import_react21.useState)(false);
22252
22282
  const resolveSize2 = (value) => {
22253
22283
  if (value === void 0)
22254
22284
  return void 0;
@@ -26809,7 +26839,7 @@ function resolveLucideName(name) {
26809
26839
  return LUCIDE_LOOKUP.get(normalized);
26810
26840
  }
26811
26841
  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 })) });
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 })) });
26813
26843
  }
26814
26844
  function Icon({ name, size = 24, tone, children, style, className, "aria-label": ariaLabel }) {
26815
26845
  const iconColor = tone ? resolveToneCss(tone) : "currentColor";
@@ -26865,10 +26895,10 @@ function Link({ children, href, external, tone, underline = "hover", style, clas
26865
26895
  }, ...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
26896
  }
26867
26897
  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);
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);
26872
26902
  const showTooltip = () => {
26873
26903
  timeoutRef.current = setTimeout(() => {
26874
26904
  setVisible(true);
@@ -26880,7 +26910,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26880
26910
  }
26881
26911
  setVisible(false);
26882
26912
  };
26883
- (0, import_react22.useEffect)(() => {
26913
+ (0, import_react23.useEffect)(() => {
26884
26914
  if (visible && triggerRef.current) {
26885
26915
  const rect = triggerRef.current.getBoundingClientRect();
26886
26916
  const offset = 8;
@@ -26907,7 +26937,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26907
26937
  setCoords({ top, left });
26908
26938
  }
26909
26939
  }, [visible, position]);
26910
- (0, import_react22.useEffect)(() => {
26940
+ (0, import_react23.useEffect)(() => {
26911
26941
  return () => {
26912
26942
  if (timeoutRef.current) {
26913
26943
  clearTimeout(timeoutRef.current);
@@ -26956,7 +26986,7 @@ var sortIndicator = (active, direction) => (0, import_jsx_runtime27.jsxs)("span"
26956
26986
  opacity: active ? 1 : 0.3
26957
26987
  }, 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
26988
  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);
26989
+ const [hoveredRow, setHoveredRow] = (0, import_react24.useState)(null);
26960
26990
  const cellPadding = compact ? "var(--ggui-spacing-1, 4px) var(--ggui-spacing-2, 8px)" : "var(--ggui-spacing-2, 8px) var(--ggui-spacing-4, 16px)";
26961
26991
  const handleSort = (key) => {
26962
26992
  if (!onSort)
@@ -27027,10 +27057,10 @@ var sizeStyles5 = {
27027
27057
  }
27028
27058
  };
27029
27059
  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);
27060
+ const uniqueId = (0, import_react25.useId)();
27061
+ const [internalKey, setInternalKey] = (0, import_react25.useState)(items[0]?.key);
27032
27062
  const currentKey = activeKey ?? internalKey;
27033
- const handleChange = (0, import_react24.useCallback)((key) => {
27063
+ const handleChange = (0, import_react25.useCallback)((key) => {
27034
27064
  if (onChange) {
27035
27065
  onChange(key);
27036
27066
  } else {
@@ -27038,8 +27068,8 @@ function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullW
27038
27068
  }
27039
27069
  }, [onChange]);
27040
27070
  const activeItem = items.find((item) => item.key === currentKey);
27041
- const tabListRef = (0, import_react24.useRef)(null);
27042
- const handleTabKeyDown = (0, import_react24.useCallback)((e) => {
27071
+ const tabListRef = (0, import_react25.useRef)(null);
27072
+ const handleTabKeyDown = (0, import_react25.useCallback)((e) => {
27043
27073
  const enabledItems = items.filter((item) => !item.disabled);
27044
27074
  const currentIndex = enabledItems.findIndex((item) => item.key === currentKey);
27045
27075
  let nextIndex;
@@ -27303,7 +27333,7 @@ var defaultIcons2 = {
27303
27333
  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
27334
  };
27305
27335
  function Toast({ message, variant = "info", title, duration: duration2 = 5e3, onClose, visible = true, style, className }) {
27306
- (0, import_react25.useEffect)(() => {
27336
+ (0, import_react26.useEffect)(() => {
27307
27337
  if (!visible || duration2 === 0 || !onClose)
27308
27338
  return;
27309
27339
  const timer = setTimeout(onClose, duration2);
@@ -27361,8 +27391,8 @@ var chevron = (expanded) => (0, import_jsx_runtime30.jsx)("svg", { width: "16",
27361
27391
  flexShrink: 0
27362
27392
  }, 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
27393
  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)([]);
27394
+ const uniqueId = (0, import_react27.useId)();
27395
+ const [internalExpanded, setInternalExpanded] = (0, import_react27.useState)([]);
27366
27396
  const currentExpanded = expandedKeys ?? internalExpanded;
27367
27397
  const handleToggle = (key) => {
27368
27398
  let newExpanded;
@@ -27442,7 +27472,7 @@ function Accordion({ items, expandedKeys, onChange, multiple = false, variant =
27442
27472
  }
27443
27473
  var STYLE_ID = "ggui-motion-keyframes";
27444
27474
  function MotionKeyframes() {
27445
- (0, import_react27.useEffect)(() => {
27475
+ (0, import_react28.useEffect)(() => {
27446
27476
  if (document.getElementById(STYLE_ID))
27447
27477
  return;
27448
27478
  const styleEl = document.createElement("style");
@@ -27459,12 +27489,12 @@ function MotionKeyframes() {
27459
27489
  return null;
27460
27490
  }
27461
27491
  function useMotion() {
27462
- const [motionEnabled, setMotionEnabled] = (0, import_react27.useState)(() => {
27492
+ const [motionEnabled, setMotionEnabled] = (0, import_react28.useState)(() => {
27463
27493
  if (typeof window === "undefined")
27464
27494
  return true;
27465
27495
  return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
27466
27496
  });
27467
- (0, import_react27.useEffect)(() => {
27497
+ (0, import_react28.useEffect)(() => {
27468
27498
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
27469
27499
  const handler = (e) => setMotionEnabled(!e.matches);
27470
27500
  mq.addEventListener("change", handler);
@@ -27473,9 +27503,9 @@ function useMotion() {
27473
27503
  return { motionEnabled };
27474
27504
  }
27475
27505
  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)(() => {
27506
+ const [key, setKey] = (0, import_react28.useState)(0);
27507
+ const isFirst = (0, import_react28.useRef)(true);
27508
+ (0, import_react28.useEffect)(() => {
27479
27509
  if (isFirst.current) {
27480
27510
  isFirst.current = false;
27481
27511
  return;
@@ -27502,7 +27532,7 @@ __export2(components_exports, {
27502
27532
  renderRichTextInlines: () => renderRichTextInlines
27503
27533
  });
27504
27534
  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)("");
27535
+ const [internalValue, setInternalValue] = (0, import_react29.useState)("");
27506
27536
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
27507
27537
  const handleChange = (newValue) => {
27508
27538
  if (controlledValue === void 0) {
@@ -27663,9 +27693,9 @@ function Tag({ children, variant = "default", size = "md", closable, onClose, ic
27663
27693
  }, "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
27694
  }
27665
27695
  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)(() => {
27696
+ const [isOpen, setIsOpen] = (0, import_react30.useState)(false);
27697
+ const containerRef = (0, import_react30.useRef)(null);
27698
+ (0, import_react30.useEffect)(() => {
27669
27699
  const handleClickOutside = (event) => {
27670
27700
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27671
27701
  setIsOpen(false);
@@ -27676,7 +27706,7 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27676
27706
  return () => document.removeEventListener("mousedown", handleClickOutside);
27677
27707
  }
27678
27708
  }, [isOpen]);
27679
- (0, import_react29.useEffect)(() => {
27709
+ (0, import_react30.useEffect)(() => {
27680
27710
  const handleEscape = (event) => {
27681
27711
  if (event.key === "Escape") {
27682
27712
  setIsOpen(false);
@@ -27723,16 +27753,16 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27723
27753
  }, 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
27754
  }
27725
27755
  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)(() => {
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)(() => {
27730
27760
  if (!value)
27731
27761
  return options;
27732
27762
  const lowerValue = value.toLowerCase();
27733
27763
  return options.filter((opt) => opt.label.toLowerCase().includes(lowerValue) || opt.value.toLowerCase().includes(lowerValue));
27734
27764
  }, [options, value]);
27735
- (0, import_react30.useEffect)(() => {
27765
+ (0, import_react31.useEffect)(() => {
27736
27766
  const handleClickOutside = (event) => {
27737
27767
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27738
27768
  setIsOpen(false);
@@ -27821,7 +27851,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27821
27851
  ...style
27822
27852
  }, children: items.map((item, index) => {
27823
27853
  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: {
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: {
27825
27855
  display: "flex",
27826
27856
  alignItems: "center",
27827
27857
  color: isLast ? "var(--ggui-color-onContainer, #111827)" : "var(--ggui-color-neutral-500, #6b7280)"
@@ -28469,7 +28499,7 @@ function Header({ logo, navigation: navigation2, actions, sticky = false, backgr
28469
28499
  }, 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
28500
  }
28471
28501
  function SidebarItem({ item, activeId, onItemClick, collapsed, depth = 0 }) {
28472
- const [expanded, setExpanded] = (0, import_react32.useState)(false);
28502
+ const [expanded, setExpanded] = (0, import_react33.useState)(false);
28473
28503
  const hasChildren = item.children && item.children.length > 0;
28474
28504
  const isActive = activeId === item.id;
28475
28505
  const handleClick = () => {
@@ -28538,8 +28568,8 @@ function CardGrid({ children, columns = 3, gap = 16, style, className }) {
28538
28568
  }, children });
28539
28569
  }
28540
28570
  function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28541
- const [showReplyInput, setShowReplyInput] = (0, import_react33.useState)(false);
28542
- const [replyContent, setReplyContent] = (0, import_react33.useState)("");
28571
+ const [showReplyInput, setShowReplyInput] = (0, import_react34.useState)(false);
28572
+ const [replyContent, setReplyContent] = (0, import_react34.useState)("");
28543
28573
  const handleSubmitReply = () => {
28544
28574
  if (replyContent.trim()) {
28545
28575
  onReply?.(comment.id, replyContent);
@@ -28564,7 +28594,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28564
28594
  }, 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
28595
  }
28566
28596
  function CommentThread({ comments, currentUser, onAddComment, onReply, onReaction, loading, style, className }) {
28567
- const [newComment, setNewComment] = (0, import_react33.useState)("");
28597
+ const [newComment, setNewComment] = (0, import_react34.useState)("");
28568
28598
  const handleSubmit = () => {
28569
28599
  if (newComment.trim()) {
28570
28600
  onAddComment?.(newComment);
@@ -28629,9 +28659,9 @@ function DataTable({ columns, data, rowKey = "id", loading, emptyText = "No data
28629
28659
  }) })] }) });
28630
28660
  }
28631
28661
  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)(() => {
28662
+ const [inputValue, setInputValue] = (0, import_react35.useState)("");
28663
+ const messagesEndRef = (0, import_react35.useRef)(null);
28664
+ (0, import_react35.useEffect)(() => {
28635
28665
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
28636
28666
  }, [messages]);
28637
28667
  const handleSend = () => {
@@ -28769,8 +28799,8 @@ function formatFileSize(bytes) {
28769
28799
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
28770
28800
  }
28771
28801
  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);
28802
+ const [isDragOver, setIsDragOver] = (0, import_react36.useState)(false);
28803
+ const inputRef = (0, import_react36.useRef)(null);
28774
28804
  const handleFiles = (fileList) => {
28775
28805
  if (!fileList)
28776
28806
  return;
@@ -28909,12 +28939,12 @@ var sizeWidths = {
28909
28939
  full: "100vw"
28910
28940
  };
28911
28941
  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) => {
28942
+ const handleEscape = (0, import_react37.useCallback)((e) => {
28913
28943
  if (e.key === "Escape" && closeOnEscape) {
28914
28944
  onClose();
28915
28945
  }
28916
28946
  }, [closeOnEscape, onClose]);
28917
- (0, import_react36.useEffect)(() => {
28947
+ (0, import_react37.useEffect)(() => {
28918
28948
  if (open) {
28919
28949
  document.addEventListener("keydown", handleEscape);
28920
28950
  document.body.style.overflow = "hidden";
@@ -28979,9 +29009,9 @@ function Modal({ open, onClose, title, children, footer, size = "md", closeOnOve
28979
29009
  }, children: footer })] })] });
28980
29010
  }
28981
29011
  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)(() => {
29012
+ const [query, setQuery] = (0, import_react38.useState)("");
29013
+ const [selectedIndex, setSelectedIndex] = (0, import_react38.useState)(0);
29014
+ const filteredCommands = (0, import_react38.useMemo)(() => {
28985
29015
  const filtered = query ? commands.filter((cmd) => cmd.label.toLowerCase().includes(query.toLowerCase()) || cmd.description?.toLowerCase().includes(query.toLowerCase())) : commands;
28986
29016
  const groups = /* @__PURE__ */ new Map();
28987
29017
  if (!query && recentIds.length > 0) {
@@ -29002,21 +29032,21 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29002
29032
  });
29003
29033
  return groups;
29004
29034
  }, [commands, query, recentIds]);
29005
- const flatCommands = (0, import_react37.useMemo)(() => {
29035
+ const flatCommands = (0, import_react38.useMemo)(() => {
29006
29036
  const flat = [];
29007
29037
  filteredCommands.forEach((cmds) => flat.push(...cmds));
29008
29038
  return flat;
29009
29039
  }, [filteredCommands]);
29010
- (0, import_react37.useEffect)(() => {
29040
+ (0, import_react38.useEffect)(() => {
29011
29041
  setSelectedIndex(0);
29012
29042
  }, [query]);
29013
- (0, import_react37.useEffect)(() => {
29043
+ (0, import_react38.useEffect)(() => {
29014
29044
  if (open) {
29015
29045
  setQuery("");
29016
29046
  setSelectedIndex(0);
29017
29047
  }
29018
29048
  }, [open]);
29019
- const handleKeyDown = (0, import_react37.useCallback)((e) => {
29049
+ const handleKeyDown = (0, import_react38.useCallback)((e) => {
29020
29050
  if (e.key === "Escape") {
29021
29051
  onClose();
29022
29052
  return;
@@ -29036,7 +29066,7 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29036
29066
  }
29037
29067
  }
29038
29068
  }, [flatCommands, selectedIndex, onSelect, onClose]);
29039
- (0, import_react37.useEffect)(() => {
29069
+ (0, import_react38.useEffect)(() => {
29040
29070
  if (open) {
29041
29071
  document.addEventListener("keydown", handleKeyDown);
29042
29072
  return () => document.removeEventListener("keydown", handleKeyDown);
@@ -29285,9 +29315,9 @@ __export2(interact_exports, {
29285
29315
  Hoverable: () => Hoverable,
29286
29316
  Pressable: () => Pressable
29287
29317
  });
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);
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);
29291
29321
  const hasClick = !!onClick;
29292
29322
  const resolvedCursor = disabled ? "not-allowed" : cursor ?? (hasClick ? "pointer" : void 0);
29293
29323
  const resolvedRole = role ?? (hasClick ? "button" : void 0);
@@ -29313,8 +29343,8 @@ var Clickable = (0, import_react38.forwardRef)(function Clickable2({ children, o
29313
29343
  setActive(false);
29314
29344
  }, onMouseDown: () => setActive(true), onMouseUp: () => setActive(false), onKeyDown: handleKeyDown, role: resolvedRole, "aria-label": ariaLabel, "aria-disabled": disabled || void 0, tabIndex: resolvedTabIndex, ...rest, children });
29315
29345
  });
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);
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);
29318
29348
  const mergedStyle = {
29319
29349
  ...style,
29320
29350
  transition: transition2,
@@ -29328,10 +29358,10 @@ var Hoverable = (0, import_react39.forwardRef)(function Hoverable2({ children, h
29328
29358
  onHoverChange?.(false);
29329
29359
  }, ...rest, children });
29330
29360
  });
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);
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);
29335
29365
  const hasPress = !!onPress || !!onLongPress;
29336
29366
  const handleMouseDown = (e) => {
29337
29367
  if (disabled)
@@ -32811,7 +32841,7 @@ function getTheme(id, mode = "light") {
32811
32841
  function getDefaultThemeId() {
32812
32842
  return "ggui";
32813
32843
  }
32814
- var ThemeContext = (0, import_react41.createContext)(null);
32844
+ var ThemeContext = (0, import_react42.createContext)(null);
32815
32845
  var COLOR_MIX_SUPPORTS = "@supports (color: color-mix(in srgb, red, blue))";
32816
32846
  function resolvePrimary500Hex(cssVariables) {
32817
32847
  const match = cssVariables.match(/--ggui-color-primary-500:\s*(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})\s*;/);
@@ -32968,6 +32998,11 @@ var WIRE_EXPORTS = [
32968
32998
  "useGguiContext",
32969
32999
  "useContract",
32970
33000
  "useWireContext",
33001
+ // ggui#1223: a `oneShot` action's spent state, as data. It is served here
33002
+ // one release BEFORE the triad teaches it, because a card that imports a name
33003
+ // its runtime's shim lacks fails at module link. A card generated to use it
33004
+ // must never meet a runtime without it.
33005
+ "useActionSpent",
32971
33006
  // Provider component
32972
33007
  "GguiWireProvider"
32973
33008
  ];
@@ -33386,7 +33421,7 @@ function makeScopeClass(reactId) {
33386
33421
  }
33387
33422
  var AUTO_RETRY_LIMIT = 1;
33388
33423
  var AUTO_RETRY_DELAY = 500;
33389
- var ErrorBoundary = class extends import_react8.default.Component {
33424
+ var ErrorBoundary = class extends import_react9.default.Component {
33390
33425
  state = { error: null, catchCount: 0, autoRetrying: false };
33391
33426
  retryTimer = null;
33392
33427
  static getDerivedStateFromError(error) {
@@ -33502,12 +33537,12 @@ function ReactComponentRenderer({
33502
33537
  fallback = /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { children: "Loading component..." }),
33503
33538
  onError
33504
33539
  }) {
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)(() => {
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)(() => {
33511
33546
  if (!code || code.trim().length === 0) {
33512
33547
  setComponent(null);
33513
33548
  setLoading(false);
@@ -33535,7 +33570,7 @@ function ReactComponentRenderer({
33535
33570
  } catch {
33536
33571
  }
33537
33572
  w.__ggui__ = {
33538
- react: import_react8.default,
33573
+ react: import_react9.default,
33539
33574
  reactDom: reactDomModule,
33540
33575
  primitives: primitives_exports,
33541
33576
  components: components_exports,
@@ -33543,7 +33578,7 @@ function ReactComponentRenderer({
33543
33578
  interact: interact_exports,
33544
33579
  wire: dist_exports
33545
33580
  };
33546
- w.__REACT = import_react8.default;
33581
+ w.__REACT = import_react9.default;
33547
33582
  w.__GGUI_PRIMITIVES = primitives_exports;
33548
33583
  w.__GGUI_COMPONENTS = components_exports;
33549
33584
  w.__GGUI_COMPOSITIONS = compositions_exports;
@@ -33689,11 +33724,11 @@ function PreviewApp({
33689
33724
  token,
33690
33725
  selectedId
33691
33726
  }) {
33692
- const [state, setState] = (0, import_react44.useState)(
33727
+ const [state, setState] = (0, import_react45.useState)(
33693
33728
  selectedId ? { kind: "loading" } : { kind: "idle" }
33694
33729
  );
33695
- const [version, setVersion] = (0, import_react44.useState)(0);
33696
- (0, import_react44.useEffect)(() => {
33730
+ const [version, setVersion] = (0, import_react45.useState)(0);
33731
+ (0, import_react45.useEffect)(() => {
33697
33732
  if (!selectedId) {
33698
33733
  setState({ kind: "idle" });
33699
33734
  return;
@@ -33706,7 +33741,7 @@ function PreviewApp({
33706
33741
  });
33707
33742
  return () => controller.abort();
33708
33743
  }, [selectedId, token, version]);
33709
- (0, import_react44.useEffect)(() => {
33744
+ (0, import_react45.useEffect)(() => {
33710
33745
  if (!selectedId) return;
33711
33746
  const controller = new AbortController();
33712
33747
  subscribeToRegistry(token, controller.signal, (event) => {
@@ -33868,7 +33903,7 @@ function mount() {
33868
33903
  if (!root) throw new Error("preview-root element not found in shell");
33869
33904
  const { token, selectedId } = bootstrap();
33870
33905
  (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 }) })
33906
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react45.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(PreviewApp, { token, selectedId }) })
33872
33907
  );
33873
33908
  }
33874
33909
  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.24.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.24.0",
32
+ "@ggui-ai/project-config": "0.24.0",
33
+ "@ggui-ai/ui-registry": "0.24.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.24.0",
44
+ "@ggui-ai/mcp-apps-react": "0.24.0",
45
+ "@ggui-ai/wire": "0.24.0"
46
46
  },
47
47
  "repository": {
48
48
  "type": "git",