@ggui-ai/dev-stack 0.22.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,7 +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
- if (isOneShot && spentOneShots.has(actionName)) {
20842
+ if (isSpent(actionName)) {
20814
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.`);
20815
20844
  opts.onDispatchSuppressed?.({
20816
20845
  reason: "one-shot-spent",
@@ -20835,8 +20864,10 @@ function buildWireConfig(opts) {
20835
20864
  opts.onViolation(new ClientContractViolationError("outbound-action", result.violations));
20836
20865
  return;
20837
20866
  }
20838
- if (isOneShot)
20867
+ if (isOneShot && !spentOneShots.has(actionName)) {
20839
20868
  spentOneShots.add(actionName);
20869
+ notifySpent();
20870
+ }
20840
20871
  opts.emitEnvelope(envelope);
20841
20872
  },
20842
20873
  subscribe: (channelName, handler) => {
@@ -20852,65 +20883,65 @@ function buildWireConfig(opts) {
20852
20883
  }
20853
20884
 
20854
20885
  // ../mcp-apps-react/dist/index.mjs
20855
- var import_react8 = __toESM(require_react(), 1);
20886
+ var import_react9 = __toESM(require_react(), 1);
20856
20887
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
20857
20888
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
20858
- var import_react9 = __toESM(require_react(), 1);
20859
20889
  var import_react10 = __toESM(require_react(), 1);
20890
+ var import_react11 = __toESM(require_react(), 1);
20860
20891
  var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
20861
20892
  var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
20862
20893
  var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
20863
20894
  var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
20864
- var import_react11 = __toESM(require_react(), 1);
20865
20895
  var import_react12 = __toESM(require_react(), 1);
20896
+ var import_react13 = __toESM(require_react(), 1);
20866
20897
  var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
20867
20898
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
20868
20899
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
20869
- var import_react13 = __toESM(require_react(), 1);
20870
- var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20871
20900
  var import_react14 = __toESM(require_react(), 1);
20872
- var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
20901
+ var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
20873
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);
20874
20905
  var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
20875
20906
  var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
20876
- var import_react16 = __toESM(require_react(), 1);
20877
- var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20878
20907
  var import_react17 = __toESM(require_react(), 1);
20879
- var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
20908
+ var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
20880
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);
20881
20912
  var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
20882
20913
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
20883
20914
  var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
20884
- var import_react19 = __toESM(require_react(), 1);
20915
+ var import_react20 = __toESM(require_react(), 1);
20885
20916
  var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
20886
20917
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
20887
20918
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
20888
- var import_react20 = __toESM(require_react(), 1);
20889
- var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20890
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);
20891
20922
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
20892
20923
  var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
20893
- var import_react22 = __toESM(require_react(), 1);
20894
- var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20895
20924
  var import_react23 = __toESM(require_react(), 1);
20896
- var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20925
+ var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20897
20926
  var import_react24 = __toESM(require_react(), 1);
20898
- var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20927
+ var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
20899
20928
  var import_react25 = __toESM(require_react(), 1);
20900
- var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20929
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
20901
20930
  var import_react26 = __toESM(require_react(), 1);
20931
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
20902
20932
  var import_react27 = __toESM(require_react(), 1);
20903
- var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
20904
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);
20905
20936
  var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
20906
20937
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
20907
20938
  var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
20908
20939
  var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
20909
- var import_react29 = __toESM(require_react(), 1);
20910
- var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20911
20940
  var import_react30 = __toESM(require_react(), 1);
20912
- var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
20941
+ var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
20913
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);
20914
20945
  var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
20915
20946
  var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
20916
20947
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
@@ -20918,38 +20949,38 @@ var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
20918
20949
  var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
20919
20950
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
20920
20951
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
20921
- var import_react32 = __toESM(require_react(), 1);
20952
+ var import_react33 = __toESM(require_react(), 1);
20922
20953
  var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
20923
20954
  var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
20924
- var import_react33 = __toESM(require_react(), 1);
20955
+ var import_react34 = __toESM(require_react(), 1);
20925
20956
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
20926
20957
  var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
20927
- var import_react34 = __toESM(require_react(), 1);
20958
+ var import_react35 = __toESM(require_react(), 1);
20928
20959
  var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
20929
20960
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
20930
- var import_react35 = __toESM(require_react(), 1);
20961
+ var import_react36 = __toESM(require_react(), 1);
20931
20962
  var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
20932
20963
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
20933
- var import_react36 = __toESM(require_react(), 1);
20934
- var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
20935
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);
20936
20967
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
20937
20968
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
20938
20969
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
20939
- var import_react38 = __toESM(require_react(), 1);
20940
- var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20941
20970
  var import_react39 = __toESM(require_react(), 1);
20942
- var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20971
+ var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
20943
20972
  var import_react40 = __toESM(require_react(), 1);
20944
- var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
20973
+ var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
20945
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);
20946
20977
  var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
20947
20978
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
20948
- var import_react42 = __toESM(require_react(), 1);
20979
+ var import_react43 = __toESM(require_react(), 1);
20949
20980
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
20950
20981
  var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
20951
- var import_react43 = __toESM(require_react(), 1);
20952
- var GguiContext = (0, import_react7.createContext)(null);
20982
+ var import_react44 = __toESM(require_react(), 1);
20983
+ var GguiContext = (0, import_react8.createContext)(null);
20953
20984
  var KNOWN_PERMISSION_NAMES_SET2 = new Set(KNOWN_PERMISSION_NAMES);
20954
20985
  var primitives_exports = {};
20955
20986
  __export2(primitives_exports, {
@@ -21107,11 +21138,20 @@ function Container({ children, maxWidth: maxWidth2 = "lg", center = true, paddin
21107
21138
  ...style
21108
21139
  }, children });
21109
21140
  }
21141
+ function frameAttributes(frame) {
21142
+ if (frame === void 0)
21143
+ return {};
21144
+ return {
21145
+ ...frame.surface !== void 0 ? { "data-ggui-surface": frame.surface } : {},
21146
+ ...frame.bleed === true ? { "data-ggui-bleed": "" } : {}
21147
+ };
21148
+ }
21110
21149
  function renderWithTrait(trait, traitProps, root, children) {
21150
+ const marks = frameAttributes(root.frame);
21111
21151
  if (trait === void 0) {
21112
- return (0, import_react9.createElement)("div", { className: root.className, style: root.style }, children);
21152
+ return (0, import_react10.createElement)("div", { className: root.className, style: root.style, ...marks }, children);
21113
21153
  }
21114
- return (0, import_react9.createElement)(trait, { ...traitProps, className: root.className, style: root.style }, children);
21154
+ return (0, import_react10.createElement)(trait, { ...traitProps, className: root.className, style: root.style, ...marks }, children);
21115
21155
  }
21116
21156
  function resolveToneCss(tone) {
21117
21157
  switch (tone) {
@@ -21235,9 +21275,14 @@ function Card(props) {
21235
21275
  surface,
21236
21276
  style,
21237
21277
  className,
21278
+ bleed,
21238
21279
  as: Trait,
21239
21280
  ...traitProps
21240
21281
  } = props;
21282
+ const frame = {
21283
+ ...surface !== "transparent" ? { surface: surface ?? "default" } : {},
21284
+ ...bleed === true ? { bleed: true } : {}
21285
+ };
21241
21286
  const resolvedPadding = resolveSpacing(padding);
21242
21287
  const resolvedSurface = resolveSurfaceCss(surface ?? "default");
21243
21288
  const resolvedOnColor = resolveSurfaceOnColorCss(surface ?? "default");
@@ -21255,10 +21300,11 @@ function Card(props) {
21255
21300
  if (scope !== void 0) {
21256
21301
  return renderWithTrait(Trait, traitProps, {
21257
21302
  className: className ? `${className} ${scope.className}` : scope.className,
21258
- style: composedStyle
21303
+ style: composedStyle,
21304
+ frame
21259
21305
  }, (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [(0, import_jsx_runtime4.jsx)("style", { children: scope.css }), children] }));
21260
21306
  }
21261
- return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21307
+ return renderWithTrait(Trait, traitProps, { className, style: composedStyle, frame }, children);
21262
21308
  }
21263
21309
  var justifyMap = {
21264
21310
  start: "flex-start",
@@ -21289,7 +21335,7 @@ function Stack(props) {
21289
21335
  return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21290
21336
  }
21291
21337
  function Row(props) {
21292
- return (0, import_react10.createElement)(Stack, { ...props, direction: "horizontal" });
21338
+ return (0, import_react11.createElement)(Stack, { ...props, direction: "horizontal" });
21293
21339
  }
21294
21340
  var BREAKPOINTS = [
21295
21341
  ["sm", 640],
@@ -21344,7 +21390,9 @@ function Grid(props) {
21344
21390
  return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21345
21391
  }
21346
21392
  function Box(props) {
21347
- const { children, padding, paddingX, paddingY, margin, surface, assetColor, assetSemantic, radius: radius2, style, className, as: Trait, ...traitProps } = props;
21393
+ const { children, padding, paddingX, paddingY, margin, surface, assetColor, assetSemantic, radius: radius2, style, className, bleed, as: Trait, ...traitProps } = props;
21394
+ const markedSurface = surface !== void 0 && surface !== "transparent" ? surface : void 0;
21395
+ const frame = markedSurface === void 0 && bleed !== true ? void 0 : { ...markedSurface !== void 0 ? { surface: markedSurface } : {}, ...bleed === true ? { bleed: true } : {} };
21348
21396
  let computedPadding;
21349
21397
  if (paddingX !== void 0 || paddingY !== void 0) {
21350
21398
  const px = resolveSpacing(paddingX) || "0";
@@ -21369,10 +21417,11 @@ function Box(props) {
21369
21417
  if (scope !== void 0) {
21370
21418
  return renderWithTrait(Trait, traitProps, {
21371
21419
  className: className ? `${className} ${scope.className}` : scope.className,
21372
- style: composedStyle
21420
+ style: composedStyle,
21421
+ ...frame !== void 0 ? { frame } : {}
21373
21422
  }, (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [(0, import_jsx_runtime6.jsx)("style", { children: scope.css }), children] }));
21374
21423
  }
21375
- return renderWithTrait(Trait, traitProps, { className, style: composedStyle }, children);
21424
+ return renderWithTrait(Trait, traitProps, { className, style: composedStyle, ...frame !== void 0 ? { frame } : {} }, children);
21376
21425
  }
21377
21426
  function Divider({ orientation = "horizontal", margin = "var(--ggui-spacing-md, 16px)", tone, style, className }) {
21378
21427
  const resolvedMargin = typeof margin === "number" ? `${margin}px` : margin;
@@ -21455,7 +21504,7 @@ function Text({ children, size = "base", weight = "normal", caps = false, tone,
21455
21504
  ...style
21456
21505
  };
21457
21506
  const elementProps = { id, htmlFor, className, style: textStyle };
21458
- return (0, import_react11.createElement)(is, elementProps, children);
21507
+ return (0, import_react12.createElement)(is, elementProps, children);
21459
21508
  }
21460
21509
  var fontFamily = {
21461
21510
  sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
@@ -21557,7 +21606,7 @@ function Heading({ children, level = 2, tone, align, style, className }) {
21557
21606
  letterSpacing: `var(--ggui-letter-spacing-heading, ${fallback.letterSpacing})`
21558
21607
  };
21559
21608
  const resolvedColor = tone ? resolveToneCss(tone) : "var(--ggui-color-onContainer, #18181b)";
21560
- return (0, import_react12.createElement)(tag, {
21609
+ return (0, import_react13.createElement)(tag, {
21561
21610
  className,
21562
21611
  style: {
21563
21612
  ...headingStyle,
@@ -21705,7 +21754,7 @@ var sizeStyles2 = {
21705
21754
  }
21706
21755
  };
21707
21756
  function Input({ label, placeholder, value, onChange, type = "text", error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21708
- const uniqueId = (0, import_react13.useId)();
21757
+ const uniqueId = (0, import_react14.useId)();
21709
21758
  const inputId = `${uniqueId}-input`;
21710
21759
  const messageId = `${uniqueId}-message`;
21711
21760
  const hasError = Boolean(error);
@@ -21734,7 +21783,7 @@ function Input({ label, placeholder, value, onChange, type = "text", error, help
21734
21783
  }, children: error || helperText })] });
21735
21784
  }
21736
21785
  function TextArea({ label, placeholder, value, onChange, rows = 4, error, helperText, required, disabled, maxLength, showCount, autoResize, style, className, ...rest }) {
21737
- const uniqueId = (0, import_react14.useId)();
21786
+ const uniqueId = (0, import_react15.useId)();
21738
21787
  const textareaId = `${uniqueId}-textarea`;
21739
21788
  const messageId = `${uniqueId}-message`;
21740
21789
  const hasError = Boolean(error);
@@ -21776,7 +21825,7 @@ var sizeStyles3 = {
21776
21825
  lg: { padding: "12px 14px", fontSize: "var(--ggui-font-size-base, 16px)" }
21777
21826
  };
21778
21827
  function Select({ label, value, onChange, options, placeholder, error, helperText, required, disabled, size = "md", style, className, ...rest }) {
21779
- const uniqueId = (0, import_react15.useId)();
21828
+ const uniqueId = (0, import_react16.useId)();
21780
21829
  const selectId = `${uniqueId}-select`;
21781
21830
  const messageId = `${uniqueId}-message`;
21782
21831
  const hasError = Boolean(error);
@@ -21855,7 +21904,7 @@ var sizeConfig = {
21855
21904
  };
21856
21905
  function Toggle({ label, checked, onChange, disabled, size = "md", style, className }) {
21857
21906
  const config = sizeConfig[size];
21858
- const [focused, setFocused] = (0, import_react16.useState)(false);
21907
+ const [focused, setFocused] = (0, import_react17.useState)(false);
21859
21908
  return (0, import_jsx_runtime15.jsxs)("label", { className, style: {
21860
21909
  display: "flex",
21861
21910
  alignItems: "center",
@@ -21897,7 +21946,7 @@ function Toggle({ label, checked, onChange, disabled, size = "md", style, classN
21897
21946
  }, children: label })] });
21898
21947
  }
21899
21948
  function RadioGroup({ label, value, onChange, options, direction = "vertical", disabled, error, style, className }) {
21900
- const uniqueId = (0, import_react17.useId)();
21949
+ const uniqueId = (0, import_react18.useId)();
21901
21950
  const labelId = `${uniqueId}-label`;
21902
21951
  const errorId = `${uniqueId}-error`;
21903
21952
  const groupName = `${uniqueId}-radio`;
@@ -21962,7 +22011,7 @@ function RadioGroup({ label, value, onChange, options, direction = "vertical", d
21962
22011
  }, children: error })] });
21963
22012
  }
21964
22013
  function Slider({ label, value = 0, onChange, min = 0, max = 100, step = 1, disabled, showValue, style, className }) {
21965
- const uniqueId = (0, import_react18.useId)();
22014
+ const uniqueId = (0, import_react19.useId)();
21966
22015
  const sliderId = `${uniqueId}-slider`;
21967
22016
  const labelId = `${uniqueId}-label`;
21968
22017
  const percentage = (value - min) / (max - min) * 100;
@@ -22093,7 +22142,7 @@ var avatarColors = [
22093
22142
  "var(--ggui-color-info-500, #06b6d4)"
22094
22143
  ];
22095
22144
  function Avatar({ src, name, size = "md", shape = "circle", style, className }) {
22096
- const [imageError, setImageError] = (0, import_react19.useState)(false);
22145
+ const [imageError, setImageError] = (0, import_react20.useState)(false);
22097
22146
  const resolvedSize = typeof size === "number" ? size : sizeMap2[size] || 40;
22098
22147
  const initials = name ? name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
22099
22148
  const getColorFromName = (name2) => {
@@ -22229,7 +22278,7 @@ function Progress({ value, max = 100, variant = "default", size = "md", label, s
22229
22278
  }` })] })] });
22230
22279
  }
22231
22280
  function Image({ src, alt, width, height, objectFit = "cover", radius: radius2, fallback, style, className }) {
22232
- const [error, setError] = (0, import_react20.useState)(false);
22281
+ const [error, setError] = (0, import_react21.useState)(false);
22233
22282
  const resolveSize2 = (value) => {
22234
22283
  if (value === void 0)
22235
22284
  return void 0;
@@ -26790,7 +26839,7 @@ function resolveLucideName(name) {
26790
26839
  return LUCIDE_LOOKUP.get(normalized);
26791
26840
  }
26792
26841
  function renderLucideIcon(data, size, color) {
26793
- 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 })) });
26794
26843
  }
26795
26844
  function Icon({ name, size = 24, tone, children, style, className, "aria-label": ariaLabel }) {
26796
26845
  const iconColor = tone ? resolveToneCss(tone) : "currentColor";
@@ -26846,10 +26895,10 @@ function Link({ children, href, external, tone, underline = "hover", style, clas
26846
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" })] })] });
26847
26896
  }
26848
26897
  function Tooltip({ children, content, position = "top", delay = 200, style, className }) {
26849
- const [visible, setVisible] = (0, import_react22.useState)(false);
26850
- const [coords, setCoords] = (0, import_react22.useState)({ top: 0, left: 0 });
26851
- const triggerRef = (0, import_react22.useRef)(null);
26852
- 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);
26853
26902
  const showTooltip = () => {
26854
26903
  timeoutRef.current = setTimeout(() => {
26855
26904
  setVisible(true);
@@ -26861,7 +26910,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26861
26910
  }
26862
26911
  setVisible(false);
26863
26912
  };
26864
- (0, import_react22.useEffect)(() => {
26913
+ (0, import_react23.useEffect)(() => {
26865
26914
  if (visible && triggerRef.current) {
26866
26915
  const rect = triggerRef.current.getBoundingClientRect();
26867
26916
  const offset = 8;
@@ -26888,7 +26937,7 @@ function Tooltip({ children, content, position = "top", delay = 200, style, clas
26888
26937
  setCoords({ top, left });
26889
26938
  }
26890
26939
  }, [visible, position]);
26891
- (0, import_react22.useEffect)(() => {
26940
+ (0, import_react23.useEffect)(() => {
26892
26941
  return () => {
26893
26942
  if (timeoutRef.current) {
26894
26943
  clearTimeout(timeoutRef.current);
@@ -26937,7 +26986,7 @@ var sortIndicator = (active, direction) => (0, import_jsx_runtime27.jsxs)("span"
26937
26986
  opacity: active ? 1 : 0.3
26938
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" })] });
26939
26988
  function Table({ columns, data, sortKey, sortDirection = "asc", onSort, striped = false, hoverable = true, compact = false, bordered = false, caption, style, className }) {
26940
- const [hoveredRow, setHoveredRow] = (0, import_react23.useState)(null);
26989
+ const [hoveredRow, setHoveredRow] = (0, import_react24.useState)(null);
26941
26990
  const cellPadding = compact ? "var(--ggui-spacing-1, 4px) var(--ggui-spacing-2, 8px)" : "var(--ggui-spacing-2, 8px) var(--ggui-spacing-4, 16px)";
26942
26991
  const handleSort = (key) => {
26943
26992
  if (!onSort)
@@ -27008,10 +27057,10 @@ var sizeStyles5 = {
27008
27057
  }
27009
27058
  };
27010
27059
  function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullWidth = false, style, className }) {
27011
- const uniqueId = (0, import_react24.useId)();
27012
- 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);
27013
27062
  const currentKey = activeKey ?? internalKey;
27014
- const handleChange = (0, import_react24.useCallback)((key) => {
27063
+ const handleChange = (0, import_react25.useCallback)((key) => {
27015
27064
  if (onChange) {
27016
27065
  onChange(key);
27017
27066
  } else {
@@ -27019,8 +27068,8 @@ function Tabs({ items, activeKey, onChange, variant = "line", size = "md", fullW
27019
27068
  }
27020
27069
  }, [onChange]);
27021
27070
  const activeItem = items.find((item) => item.key === currentKey);
27022
- const tabListRef = (0, import_react24.useRef)(null);
27023
- const handleTabKeyDown = (0, import_react24.useCallback)((e) => {
27071
+ const tabListRef = (0, import_react25.useRef)(null);
27072
+ const handleTabKeyDown = (0, import_react25.useCallback)((e) => {
27024
27073
  const enabledItems = items.filter((item) => !item.disabled);
27025
27074
  const currentIndex = enabledItems.findIndex((item) => item.key === currentKey);
27026
27075
  let nextIndex;
@@ -27284,7 +27333,7 @@ var defaultIcons2 = {
27284
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" }) })
27285
27334
  };
27286
27335
  function Toast({ message, variant = "info", title, duration: duration2 = 5e3, onClose, visible = true, style, className }) {
27287
- (0, import_react25.useEffect)(() => {
27336
+ (0, import_react26.useEffect)(() => {
27288
27337
  if (!visible || duration2 === 0 || !onClose)
27289
27338
  return;
27290
27339
  const timer = setTimeout(onClose, duration2);
@@ -27342,8 +27391,8 @@ var chevron = (expanded) => (0, import_jsx_runtime30.jsx)("svg", { width: "16",
27342
27391
  flexShrink: 0
27343
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" }) });
27344
27393
  function Accordion({ items, expandedKeys, onChange, multiple = false, variant = "default", style, className }) {
27345
- const uniqueId = (0, import_react26.useId)();
27346
- const [internalExpanded, setInternalExpanded] = (0, import_react26.useState)([]);
27394
+ const uniqueId = (0, import_react27.useId)();
27395
+ const [internalExpanded, setInternalExpanded] = (0, import_react27.useState)([]);
27347
27396
  const currentExpanded = expandedKeys ?? internalExpanded;
27348
27397
  const handleToggle = (key) => {
27349
27398
  let newExpanded;
@@ -27423,7 +27472,7 @@ function Accordion({ items, expandedKeys, onChange, multiple = false, variant =
27423
27472
  }
27424
27473
  var STYLE_ID = "ggui-motion-keyframes";
27425
27474
  function MotionKeyframes() {
27426
- (0, import_react27.useEffect)(() => {
27475
+ (0, import_react28.useEffect)(() => {
27427
27476
  if (document.getElementById(STYLE_ID))
27428
27477
  return;
27429
27478
  const styleEl = document.createElement("style");
@@ -27440,12 +27489,12 @@ function MotionKeyframes() {
27440
27489
  return null;
27441
27490
  }
27442
27491
  function useMotion() {
27443
- const [motionEnabled, setMotionEnabled] = (0, import_react27.useState)(() => {
27492
+ const [motionEnabled, setMotionEnabled] = (0, import_react28.useState)(() => {
27444
27493
  if (typeof window === "undefined")
27445
27494
  return true;
27446
27495
  return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
27447
27496
  });
27448
- (0, import_react27.useEffect)(() => {
27497
+ (0, import_react28.useEffect)(() => {
27449
27498
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
27450
27499
  const handler = (e) => setMotionEnabled(!e.matches);
27451
27500
  mq.addEventListener("change", handler);
@@ -27454,9 +27503,9 @@ function useMotion() {
27454
27503
  return { motionEnabled };
27455
27504
  }
27456
27505
  function useAnimationKey(dep) {
27457
- const [key, setKey] = (0, import_react27.useState)(0);
27458
- const isFirst = (0, import_react27.useRef)(true);
27459
- (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)(() => {
27460
27509
  if (isFirst.current) {
27461
27510
  isFirst.current = false;
27462
27511
  return;
@@ -27483,7 +27532,7 @@ __export2(components_exports, {
27483
27532
  renderRichTextInlines: () => renderRichTextInlines
27484
27533
  });
27485
27534
  function SearchField({ value: controlledValue, onChange, onSearch, placeholder = "Search...", showButton = false, buttonText = "Search", loading, disabled, size = "md", style, className }) {
27486
- const [internalValue, setInternalValue] = (0, import_react28.useState)("");
27535
+ const [internalValue, setInternalValue] = (0, import_react29.useState)("");
27487
27536
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
27488
27537
  const handleChange = (newValue) => {
27489
27538
  if (controlledValue === void 0) {
@@ -27644,9 +27693,9 @@ function Tag({ children, variant = "default", size = "md", closable, onClose, ic
27644
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" }) }) })] });
27645
27694
  }
27646
27695
  function Dropdown({ trigger, options, value, onChange, placement = "bottom-start", disabled, style, className }) {
27647
- const [isOpen, setIsOpen] = (0, import_react29.useState)(false);
27648
- const containerRef = (0, import_react29.useRef)(null);
27649
- (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)(() => {
27650
27699
  const handleClickOutside = (event) => {
27651
27700
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27652
27701
  setIsOpen(false);
@@ -27657,7 +27706,7 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27657
27706
  return () => document.removeEventListener("mousedown", handleClickOutside);
27658
27707
  }
27659
27708
  }, [isOpen]);
27660
- (0, import_react29.useEffect)(() => {
27709
+ (0, import_react30.useEffect)(() => {
27661
27710
  const handleEscape = (event) => {
27662
27711
  if (event.key === "Escape") {
27663
27712
  setIsOpen(false);
@@ -27704,16 +27753,16 @@ function Dropdown({ trigger, options, value, onChange, placement = "bottom-start
27704
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)) })] });
27705
27754
  }
27706
27755
  function Autocomplete({ value = "", onChange, onSelect, options, placeholder, label, loading, disabled, error, noResultsText = "No results found", style, className }) {
27707
- const [isOpen, setIsOpen] = (0, import_react30.useState)(false);
27708
- const [highlightedIndex, setHighlightedIndex] = (0, import_react30.useState)(-1);
27709
- const containerRef = (0, import_react30.useRef)(null);
27710
- 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)(() => {
27711
27760
  if (!value)
27712
27761
  return options;
27713
27762
  const lowerValue = value.toLowerCase();
27714
27763
  return options.filter((opt) => opt.label.toLowerCase().includes(lowerValue) || opt.value.toLowerCase().includes(lowerValue));
27715
27764
  }, [options, value]);
27716
- (0, import_react30.useEffect)(() => {
27765
+ (0, import_react31.useEffect)(() => {
27717
27766
  const handleClickOutside = (event) => {
27718
27767
  if (containerRef.current && !containerRef.current.contains(event.target)) {
27719
27768
  setIsOpen(false);
@@ -27802,7 +27851,7 @@ function Breadcrumb({ items, separator = "/", onItemClick, style, className }) {
27802
27851
  ...style
27803
27852
  }, children: items.map((item, index) => {
27804
27853
  const isLast = index === items.length - 1;
27805
- 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: {
27806
27855
  display: "flex",
27807
27856
  alignItems: "center",
27808
27857
  color: isLast ? "var(--ggui-color-onContainer, #111827)" : "var(--ggui-color-neutral-500, #6b7280)"
@@ -28450,7 +28499,7 @@ function Header({ logo, navigation: navigation2, actions, sticky = false, backgr
28450
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 })] });
28451
28500
  }
28452
28501
  function SidebarItem({ item, activeId, onItemClick, collapsed, depth = 0 }) {
28453
- const [expanded, setExpanded] = (0, import_react32.useState)(false);
28502
+ const [expanded, setExpanded] = (0, import_react33.useState)(false);
28454
28503
  const hasChildren = item.children && item.children.length > 0;
28455
28504
  const isActive = activeId === item.id;
28456
28505
  const handleClick = () => {
@@ -28519,8 +28568,8 @@ function CardGrid({ children, columns = 3, gap = 16, style, className }) {
28519
28568
  }, children });
28520
28569
  }
28521
28570
  function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28522
- const [showReplyInput, setShowReplyInput] = (0, import_react33.useState)(false);
28523
- const [replyContent, setReplyContent] = (0, import_react33.useState)("");
28571
+ const [showReplyInput, setShowReplyInput] = (0, import_react34.useState)(false);
28572
+ const [replyContent, setReplyContent] = (0, import_react34.useState)("");
28524
28573
  const handleSubmitReply = () => {
28525
28574
  if (replyContent.trim()) {
28526
28575
  onReply?.(comment.id, replyContent);
@@ -28545,7 +28594,7 @@ function CommentItem({ comment, onReply, onReaction, depth = 0 }) {
28545
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))] });
28546
28595
  }
28547
28596
  function CommentThread({ comments, currentUser, onAddComment, onReply, onReaction, loading, style, className }) {
28548
- const [newComment, setNewComment] = (0, import_react33.useState)("");
28597
+ const [newComment, setNewComment] = (0, import_react34.useState)("");
28549
28598
  const handleSubmit = () => {
28550
28599
  if (newComment.trim()) {
28551
28600
  onAddComment?.(newComment);
@@ -28610,9 +28659,9 @@ function DataTable({ columns, data, rowKey = "id", loading, emptyText = "No data
28610
28659
  }) })] }) });
28611
28660
  }
28612
28661
  function ChatWindow({ messages, currentUserId, onSendMessage, loading, typing, placeholder = "Type a message...", header, style, className }) {
28613
- const [inputValue, setInputValue] = (0, import_react34.useState)("");
28614
- const messagesEndRef = (0, import_react34.useRef)(null);
28615
- (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)(() => {
28616
28665
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
28617
28666
  }, [messages]);
28618
28667
  const handleSend = () => {
@@ -28750,8 +28799,8 @@ function formatFileSize(bytes) {
28750
28799
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
28751
28800
  }
28752
28801
  function FileUploader({ files = [], onFilesSelected, onFileRemove, accept, multiple = true, maxSize, maxFiles, disabled, dragDrop = true, style, className }) {
28753
- const [isDragOver, setIsDragOver] = (0, import_react35.useState)(false);
28754
- const inputRef = (0, import_react35.useRef)(null);
28802
+ const [isDragOver, setIsDragOver] = (0, import_react36.useState)(false);
28803
+ const inputRef = (0, import_react36.useRef)(null);
28755
28804
  const handleFiles = (fileList) => {
28756
28805
  if (!fileList)
28757
28806
  return;
@@ -28890,12 +28939,12 @@ var sizeWidths = {
28890
28939
  full: "100vw"
28891
28940
  };
28892
28941
  function Modal({ open, onClose, title, children, footer, size = "md", closeOnOverlayClick = true, closeOnEscape = true, showCloseButton = true, style, className }) {
28893
- const handleEscape = (0, import_react36.useCallback)((e) => {
28942
+ const handleEscape = (0, import_react37.useCallback)((e) => {
28894
28943
  if (e.key === "Escape" && closeOnEscape) {
28895
28944
  onClose();
28896
28945
  }
28897
28946
  }, [closeOnEscape, onClose]);
28898
- (0, import_react36.useEffect)(() => {
28947
+ (0, import_react37.useEffect)(() => {
28899
28948
  if (open) {
28900
28949
  document.addEventListener("keydown", handleEscape);
28901
28950
  document.body.style.overflow = "hidden";
@@ -28960,9 +29009,9 @@ function Modal({ open, onClose, title, children, footer, size = "md", closeOnOve
28960
29009
  }, children: footer })] })] });
28961
29010
  }
28962
29011
  function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Search commands...", recentIds = [], loading, style, className }) {
28963
- const [query, setQuery] = (0, import_react37.useState)("");
28964
- const [selectedIndex, setSelectedIndex] = (0, import_react37.useState)(0);
28965
- 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)(() => {
28966
29015
  const filtered = query ? commands.filter((cmd) => cmd.label.toLowerCase().includes(query.toLowerCase()) || cmd.description?.toLowerCase().includes(query.toLowerCase())) : commands;
28967
29016
  const groups = /* @__PURE__ */ new Map();
28968
29017
  if (!query && recentIds.length > 0) {
@@ -28983,21 +29032,21 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
28983
29032
  });
28984
29033
  return groups;
28985
29034
  }, [commands, query, recentIds]);
28986
- const flatCommands = (0, import_react37.useMemo)(() => {
29035
+ const flatCommands = (0, import_react38.useMemo)(() => {
28987
29036
  const flat = [];
28988
29037
  filteredCommands.forEach((cmds) => flat.push(...cmds));
28989
29038
  return flat;
28990
29039
  }, [filteredCommands]);
28991
- (0, import_react37.useEffect)(() => {
29040
+ (0, import_react38.useEffect)(() => {
28992
29041
  setSelectedIndex(0);
28993
29042
  }, [query]);
28994
- (0, import_react37.useEffect)(() => {
29043
+ (0, import_react38.useEffect)(() => {
28995
29044
  if (open) {
28996
29045
  setQuery("");
28997
29046
  setSelectedIndex(0);
28998
29047
  }
28999
29048
  }, [open]);
29000
- const handleKeyDown = (0, import_react37.useCallback)((e) => {
29049
+ const handleKeyDown = (0, import_react38.useCallback)((e) => {
29001
29050
  if (e.key === "Escape") {
29002
29051
  onClose();
29003
29052
  return;
@@ -29017,7 +29066,7 @@ function CommandPalette({ open, onClose, commands, onSelect, placeholder = "Sear
29017
29066
  }
29018
29067
  }
29019
29068
  }, [flatCommands, selectedIndex, onSelect, onClose]);
29020
- (0, import_react37.useEffect)(() => {
29069
+ (0, import_react38.useEffect)(() => {
29021
29070
  if (open) {
29022
29071
  document.addEventListener("keydown", handleKeyDown);
29023
29072
  return () => document.removeEventListener("keydown", handleKeyDown);
@@ -29266,9 +29315,9 @@ __export2(interact_exports, {
29266
29315
  Hoverable: () => Hoverable,
29267
29316
  Pressable: () => Pressable
29268
29317
  });
29269
- 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) {
29270
- const [hovered, setHovered] = (0, import_react38.useState)(false);
29271
- 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);
29272
29321
  const hasClick = !!onClick;
29273
29322
  const resolvedCursor = disabled ? "not-allowed" : cursor ?? (hasClick ? "pointer" : void 0);
29274
29323
  const resolvedRole = role ?? (hasClick ? "button" : void 0);
@@ -29294,8 +29343,8 @@ var Clickable = (0, import_react38.forwardRef)(function Clickable2({ children, o
29294
29343
  setActive(false);
29295
29344
  }, onMouseDown: () => setActive(true), onMouseUp: () => setActive(false), onKeyDown: handleKeyDown, role: resolvedRole, "aria-label": ariaLabel, "aria-disabled": disabled || void 0, tabIndex: resolvedTabIndex, ...rest, children });
29296
29345
  });
29297
- var Hoverable = (0, import_react39.forwardRef)(function Hoverable2({ children, hoverStyle, onHoverChange, transition: transition2 = "all 200ms ease", style, className, ...rest }, ref) {
29298
- 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);
29299
29348
  const mergedStyle = {
29300
29349
  ...style,
29301
29350
  transition: transition2,
@@ -29309,10 +29358,10 @@ var Hoverable = (0, import_react39.forwardRef)(function Hoverable2({ children, h
29309
29358
  onHoverChange?.(false);
29310
29359
  }, ...rest, children });
29311
29360
  });
29312
- 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) {
29313
- const [hovered, setHovered] = (0, import_react40.useState)(false);
29314
- const [pressed, setPressed] = (0, import_react40.useState)(false);
29315
- 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);
29316
29365
  const hasPress = !!onPress || !!onLongPress;
29317
29366
  const handleMouseDown = (e) => {
29318
29367
  if (disabled)
@@ -32792,7 +32841,7 @@ function getTheme(id, mode = "light") {
32792
32841
  function getDefaultThemeId() {
32793
32842
  return "ggui";
32794
32843
  }
32795
- var ThemeContext = (0, import_react41.createContext)(null);
32844
+ var ThemeContext = (0, import_react42.createContext)(null);
32796
32845
  var COLOR_MIX_SUPPORTS = "@supports (color: color-mix(in srgb, red, blue))";
32797
32846
  function resolvePrimary500Hex(cssVariables) {
32798
32847
  const match = cssVariables.match(/--ggui-color-primary-500:\s*(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})\s*;/);
@@ -32891,6 +32940,8 @@ function framelessSuppressionRule(scopeClass) {
32891
32940
  return `
32892
32941
  .${scopeClass} > :where(:not(style)) { border: none !important; }`;
32893
32942
  }
32943
+ var EXPANDED_FRAME = { outerRadiusVar: "--ggui-shape-radius-xl", insetPx: 16 };
32944
+ var EXPANDED_FRAME_INNER_RADIUS = `max(0px, calc(var(${EXPANDED_FRAME.outerRadiusVar}) - ${EXPANDED_FRAME.insetPx}px))`;
32894
32945
  function structuralScaffolding(scopeClass) {
32895
32946
  return `.${scopeClass} *, .${scopeClass} *::before, .${scopeClass} *::after { box-sizing: border-box; }
32896
32947
  .${scopeClass} h1, .${scopeClass} h2, .${scopeClass} h3, .${scopeClass} h4, .${scopeClass} h5, .${scopeClass} h6, .${scopeClass} button, .${scopeClass} input, .${scopeClass} textarea, .${scopeClass} select { font-family: inherit; }`;
@@ -32947,6 +32998,11 @@ var WIRE_EXPORTS = [
32947
32998
  "useGguiContext",
32948
32999
  "useContract",
32949
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",
32950
33006
  // Provider component
32951
33007
  "GguiWireProvider"
32952
33008
  ];
@@ -33365,7 +33421,7 @@ function makeScopeClass(reactId) {
33365
33421
  }
33366
33422
  var AUTO_RETRY_LIMIT = 1;
33367
33423
  var AUTO_RETRY_DELAY = 500;
33368
- var ErrorBoundary = class extends import_react8.default.Component {
33424
+ var ErrorBoundary = class extends import_react9.default.Component {
33369
33425
  state = { error: null, catchCount: 0, autoRetrying: false };
33370
33426
  retryTimer = null;
33371
33427
  static getDerivedStateFromError(error) {
@@ -33481,12 +33537,12 @@ function ReactComponentRenderer({
33481
33537
  fallback = /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { children: "Loading component..." }),
33482
33538
  onError
33483
33539
  }) {
33484
- const reactId = (0, import_react8.useId)();
33485
- const [scopeClass] = (0, import_react8.useState)(() => makeScopeClass(reactId) || `ggui-rcr-${++scopeCounter}`);
33486
- const [Component, setComponent] = (0, import_react8.useState)(null);
33487
- const [error, setError] = (0, import_react8.useState)(null);
33488
- const [loading, setLoading] = (0, import_react8.useState)(true);
33489
- (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)(() => {
33490
33546
  if (!code || code.trim().length === 0) {
33491
33547
  setComponent(null);
33492
33548
  setLoading(false);
@@ -33514,7 +33570,7 @@ function ReactComponentRenderer({
33514
33570
  } catch {
33515
33571
  }
33516
33572
  w.__ggui__ = {
33517
- react: import_react8.default,
33573
+ react: import_react9.default,
33518
33574
  reactDom: reactDomModule,
33519
33575
  primitives: primitives_exports,
33520
33576
  components: components_exports,
@@ -33522,7 +33578,7 @@ function ReactComponentRenderer({
33522
33578
  interact: interact_exports,
33523
33579
  wire: dist_exports
33524
33580
  };
33525
- w.__REACT = import_react8.default;
33581
+ w.__REACT = import_react9.default;
33526
33582
  w.__GGUI_PRIMITIVES = primitives_exports;
33527
33583
  w.__GGUI_COMPONENTS = components_exports;
33528
33584
  w.__GGUI_COMPOSITIONS = compositions_exports;
@@ -33668,11 +33724,11 @@ function PreviewApp({
33668
33724
  token,
33669
33725
  selectedId
33670
33726
  }) {
33671
- const [state, setState] = (0, import_react44.useState)(
33727
+ const [state, setState] = (0, import_react45.useState)(
33672
33728
  selectedId ? { kind: "loading" } : { kind: "idle" }
33673
33729
  );
33674
- const [version, setVersion] = (0, import_react44.useState)(0);
33675
- (0, import_react44.useEffect)(() => {
33730
+ const [version, setVersion] = (0, import_react45.useState)(0);
33731
+ (0, import_react45.useEffect)(() => {
33676
33732
  if (!selectedId) {
33677
33733
  setState({ kind: "idle" });
33678
33734
  return;
@@ -33685,7 +33741,7 @@ function PreviewApp({
33685
33741
  });
33686
33742
  return () => controller.abort();
33687
33743
  }, [selectedId, token, version]);
33688
- (0, import_react44.useEffect)(() => {
33744
+ (0, import_react45.useEffect)(() => {
33689
33745
  if (!selectedId) return;
33690
33746
  const controller = new AbortController();
33691
33747
  subscribeToRegistry(token, controller.signal, (event) => {
@@ -33847,7 +33903,7 @@ function mount() {
33847
33903
  if (!root) throw new Error("preview-root element not found in shell");
33848
33904
  const { token, selectedId } = bootstrap();
33849
33905
  (0, import_client.createRoot)(root).render(
33850
- /* @__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 }) })
33851
33907
  );
33852
33908
  }
33853
33909
  mount();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/dev-stack",
3
- "version": "0.22.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.22.0",
32
- "@ggui-ai/project-config": "0.22.0",
33
- "@ggui-ai/ui-registry": "0.22.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.22.0",
44
- "@ggui-ai/mcp-apps-react": "0.22.0",
45
- "@ggui-ai/wire": "0.22.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",