@btst/stack 2.3.0 → 2.5.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.
Files changed (208) hide show
  1. package/dist/packages/stack/src/client/components/compose.cjs +1 -2
  2. package/dist/packages/stack/src/client/components/compose.mjs +1 -2
  3. package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.cjs +71 -0
  4. package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.mjs +68 -0
  5. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +87 -54
  6. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +87 -54
  7. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +2 -2
  8. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +2 -2
  9. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +89 -22
  10. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +90 -23
  11. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +110 -33
  12. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +112 -35
  13. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +1 -1
  14. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +1 -1
  15. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +14 -21
  16. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +15 -22
  17. package/dist/packages/stack/src/plugins/ai-chat/schemas.cjs +17 -1
  18. package/dist/packages/stack/src/plugins/ai-chat/schemas.mjs +17 -1
  19. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +28 -45
  20. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +22 -39
  21. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +15 -2
  22. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +16 -3
  23. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs +24 -1
  24. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs +24 -1
  25. package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.cjs +26 -0
  26. package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.mjs +24 -0
  27. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs +30 -1
  28. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs +30 -1
  29. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +18 -0
  30. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +18 -0
  31. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +23 -27
  32. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +24 -28
  33. package/dist/packages/stack/src/plugins/cms/api/mutations.cjs +48 -0
  34. package/dist/packages/stack/src/plugins/cms/api/mutations.mjs +46 -0
  35. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +21 -18
  36. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +21 -18
  37. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +11 -15
  38. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +12 -16
  39. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +58 -62
  40. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +58 -62
  41. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +12 -12
  42. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +13 -13
  43. package/dist/packages/stack/src/plugins/kanban/api/mutations.cjs +91 -0
  44. package/dist/packages/stack/src/plugins/kanban/api/mutations.mjs +87 -0
  45. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +92 -118
  46. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +89 -115
  47. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +7 -3
  48. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +7 -3
  49. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +22 -29
  50. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +23 -30
  51. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.cjs +89 -0
  52. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.mjs +89 -0
  53. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +8 -8
  54. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +9 -9
  55. package/dist/packages/stack/src/plugins/utils.cjs +42 -0
  56. package/dist/packages/stack/src/plugins/utils.mjs +41 -1
  57. package/dist/plugins/ai-chat/api/index.d.cts +1 -1
  58. package/dist/plugins/ai-chat/api/index.d.mts +1 -1
  59. package/dist/plugins/ai-chat/api/index.d.ts +1 -1
  60. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  61. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  62. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  63. package/dist/plugins/ai-chat/client/context/page-ai-context.cjs +92 -0
  64. package/dist/plugins/ai-chat/client/context/page-ai-context.d.cts +84 -0
  65. package/dist/plugins/ai-chat/client/context/page-ai-context.d.mts +84 -0
  66. package/dist/plugins/ai-chat/client/context/page-ai-context.d.ts +84 -0
  67. package/dist/plugins/ai-chat/client/context/page-ai-context.mjs +88 -0
  68. package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
  69. package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
  70. package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
  71. package/dist/plugins/ai-chat/client/index.d.cts +10 -10
  72. package/dist/plugins/ai-chat/client/index.d.mts +10 -10
  73. package/dist/plugins/ai-chat/client/index.d.ts +10 -10
  74. package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
  75. package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
  76. package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
  77. package/dist/plugins/blog/api/index.d.cts +2 -2
  78. package/dist/plugins/blog/api/index.d.mts +2 -2
  79. package/dist/plugins/blog/api/index.d.ts +2 -2
  80. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  81. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  82. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  83. package/dist/plugins/blog/client/index.d.cts +13 -13
  84. package/dist/plugins/blog/client/index.d.mts +13 -13
  85. package/dist/plugins/blog/client/index.d.ts +13 -13
  86. package/dist/plugins/blog/query-keys.d.cts +2 -2
  87. package/dist/plugins/blog/query-keys.d.mts +2 -2
  88. package/dist/plugins/blog/query-keys.d.ts +2 -2
  89. package/dist/plugins/client/index.cjs +1 -0
  90. package/dist/plugins/client/index.d.cts +8 -1
  91. package/dist/plugins/client/index.d.mts +8 -1
  92. package/dist/plugins/client/index.d.ts +8 -1
  93. package/dist/plugins/client/index.mjs +1 -1
  94. package/dist/plugins/cms/api/index.cjs +2 -0
  95. package/dist/plugins/cms/api/index.d.cts +2 -2
  96. package/dist/plugins/cms/api/index.d.mts +2 -2
  97. package/dist/plugins/cms/api/index.d.ts +2 -2
  98. package/dist/plugins/cms/api/index.mjs +1 -0
  99. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  100. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  101. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  102. package/dist/plugins/cms/client/index.d.cts +6 -6
  103. package/dist/plugins/cms/client/index.d.mts +6 -6
  104. package/dist/plugins/cms/client/index.d.ts +6 -6
  105. package/dist/plugins/cms/query-keys.d.cts +2 -2
  106. package/dist/plugins/cms/query-keys.d.mts +2 -2
  107. package/dist/plugins/cms/query-keys.d.ts +2 -2
  108. package/dist/plugins/form-builder/api/index.d.cts +2 -2
  109. package/dist/plugins/form-builder/api/index.d.mts +2 -2
  110. package/dist/plugins/form-builder/api/index.d.ts +2 -2
  111. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  112. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  113. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  114. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  115. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  116. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  117. package/dist/plugins/form-builder/client/index.d.cts +6 -6
  118. package/dist/plugins/form-builder/client/index.d.mts +6 -6
  119. package/dist/plugins/form-builder/client/index.d.ts +6 -6
  120. package/dist/plugins/form-builder/query-keys.d.cts +2 -2
  121. package/dist/plugins/form-builder/query-keys.d.mts +2 -2
  122. package/dist/plugins/form-builder/query-keys.d.ts +2 -2
  123. package/dist/plugins/kanban/api/index.cjs +4 -0
  124. package/dist/plugins/kanban/api/index.d.cts +1 -1
  125. package/dist/plugins/kanban/api/index.d.mts +1 -1
  126. package/dist/plugins/kanban/api/index.d.ts +1 -1
  127. package/dist/plugins/kanban/api/index.mjs +1 -0
  128. package/dist/plugins/kanban/client/index.d.cts +12 -12
  129. package/dist/plugins/kanban/client/index.d.mts +12 -12
  130. package/dist/plugins/kanban/client/index.d.ts +12 -12
  131. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  132. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  133. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  134. package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
  135. package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
  136. package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
  137. package/dist/plugins/ui-builder/client/index.d.cts +3 -3
  138. package/dist/plugins/ui-builder/client/index.d.mts +3 -3
  139. package/dist/plugins/ui-builder/client/index.d.ts +3 -3
  140. package/dist/plugins/ui-builder/index.d.cts +2 -2
  141. package/dist/plugins/ui-builder/index.d.mts +2 -2
  142. package/dist/plugins/ui-builder/index.d.ts +2 -2
  143. package/dist/shared/{stack.C-WUPMT6.d.cts → stack.B2xZTSiO.d.cts} +4 -4
  144. package/dist/shared/{stack.B1EeBt1b.d.ts → stack.B58oHdqm.d.mts} +33 -3
  145. package/dist/shared/{stack.CVDTkMoO.d.mts → stack.B8QD11QU.d.cts} +7 -7
  146. package/dist/shared/{stack.CVDTkMoO.d.cts → stack.B8QD11QU.d.mts} +7 -7
  147. package/dist/shared/{stack.CVDTkMoO.d.ts → stack.B8QD11QU.d.ts} +7 -7
  148. package/dist/shared/{stack.CIP6QS9l.d.ts → stack.BDVEpue1.d.ts} +1 -1
  149. package/dist/shared/{stack.C5dtIncc.d.mts → stack.BTvbxZvw.d.cts} +1 -1
  150. package/dist/shared/{stack.DaOcgmrM.d.ts → stack.BV9hnvu4.d.cts} +31 -7
  151. package/dist/shared/{stack.DaOcgmrM.d.cts → stack.BV9hnvu4.d.mts} +31 -7
  152. package/dist/shared/{stack.DaOcgmrM.d.mts → stack.BV9hnvu4.d.ts} +31 -7
  153. package/dist/shared/{stack.DdI5W6MB.d.mts → stack.BozPgbrZ.d.cts} +19 -19
  154. package/dist/shared/{stack.DdI5W6MB.d.ts → stack.BozPgbrZ.d.mts} +19 -19
  155. package/dist/shared/{stack.DdI5W6MB.d.cts → stack.BozPgbrZ.d.ts} +19 -19
  156. package/dist/shared/{stack.CP68pFEH.d.mts → stack.C9Mg2Q46.d.cts} +33 -3
  157. package/dist/shared/{stack.BeSm90va.d.ts → stack.CTDVxbrA.d.ts} +72 -14
  158. package/dist/shared/{stack.C-Ptrz8s.d.ts → stack.Cj_zKww4.d.ts} +4 -4
  159. package/dist/shared/{stack.TIBF2AOx.d.ts → stack.CxaFNQCV.d.mts} +89 -34
  160. package/dist/shared/{stack.CMh_EdxW.d.cts → stack.D-b5zbPm.d.cts} +72 -14
  161. package/dist/shared/{stack.Dw0Ly2TM.d.cts → stack.DTtmJPQO.d.mts} +1 -1
  162. package/dist/shared/{stack.BKfolAyK.d.ts → stack.DXnclTG7.d.ts} +11 -11
  163. package/dist/shared/{stack.snB1EDP7.d.cts → stack.DaZM10cp.d.cts} +11 -11
  164. package/dist/shared/{stack.Dg09R0oB.d.mts → stack.FVWf2JhZ.d.mts} +72 -14
  165. package/dist/shared/{stack.BIXEI6v_.d.mts → stack.cfCkioTe.d.mts} +11 -11
  166. package/dist/shared/{stack.6fUOjLs9.d.mts → stack.dH7u-TJH.d.mts} +4 -4
  167. package/dist/shared/{stack.BpolpQpf.d.cts → stack.j75TpKh2.d.ts} +89 -34
  168. package/dist/shared/{stack.rTy7-wQU.d.mts → stack.n1_i1p2B.d.cts} +89 -34
  169. package/dist/shared/{stack.IdtKDRka.d.cts → stack.sO33ZDhK.d.ts} +33 -3
  170. package/package.json +14 -1
  171. package/src/client/components/compose.tsx +7 -4
  172. package/src/plugins/ai-chat/api/page-tools.ts +111 -0
  173. package/src/plugins/ai-chat/api/plugin.ts +228 -72
  174. package/src/plugins/ai-chat/client/components/chat-input.tsx +2 -2
  175. package/src/plugins/ai-chat/client/components/chat-interface.tsx +154 -58
  176. package/src/plugins/ai-chat/client/components/chat-layout.tsx +166 -32
  177. package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +1 -1
  178. package/src/plugins/ai-chat/client/context/page-ai-context.tsx +240 -0
  179. package/src/plugins/ai-chat/client/plugin.tsx +23 -31
  180. package/src/plugins/ai-chat/schemas.ts +16 -0
  181. package/src/plugins/blog/api/plugin.ts +31 -47
  182. package/src/plugins/blog/client/components/forms/post-forms.tsx +29 -2
  183. package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +28 -0
  184. package/src/plugins/blog/client/components/pages/fill-blog-form-handler.ts +38 -0
  185. package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +33 -1
  186. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +20 -0
  187. package/src/plugins/blog/client/plugin.tsx +36 -39
  188. package/src/plugins/client/index.ts +5 -1
  189. package/src/plugins/cms/api/index.ts +4 -0
  190. package/src/plugins/cms/api/mutations.ts +84 -0
  191. package/src/plugins/cms/api/plugin.ts +23 -17
  192. package/src/plugins/cms/client/plugin.tsx +18 -21
  193. package/src/plugins/cms/types.ts +7 -7
  194. package/src/plugins/form-builder/api/plugin.ts +64 -64
  195. package/src/plugins/form-builder/client/plugin.tsx +19 -18
  196. package/src/plugins/form-builder/types.ts +19 -24
  197. package/src/plugins/kanban/api/index.ts +6 -0
  198. package/src/plugins/kanban/api/mutations.ts +169 -0
  199. package/src/plugins/kanban/api/plugin.ts +123 -136
  200. package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +4 -0
  201. package/src/plugins/kanban/client/plugin.tsx +35 -41
  202. package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +132 -0
  203. package/src/plugins/ui-builder/client/plugin.tsx +11 -10
  204. package/src/plugins/ui-builder/types.ts +4 -4
  205. package/src/plugins/utils.ts +92 -1
  206. package/dist/shared/{stack.CBON0dWL.d.mts → stack.BQmuNl5p.d.cts} +2 -2
  207. package/dist/shared/{stack.CBON0dWL.d.ts → stack.BQmuNl5p.d.mts} +2 -2
  208. package/dist/shared/{stack.CBON0dWL.d.cts → stack.BQmuNl5p.d.ts} +2 -2
@@ -1,4 +1,4 @@
1
- export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.cjs';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.BV9hnvu4.cjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -1,4 +1,4 @@
1
- export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.mjs';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.BV9hnvu4.mjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -1,4 +1,4 @@
1
- export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.js';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.BV9hnvu4.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -0,0 +1,92 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+
7
+ const PageAIAPIContext = React.createContext(null);
8
+ const PageAIVersionContext = React.createContext(0);
9
+ function PageAIContextProvider({
10
+ children
11
+ }) {
12
+ const registrationsRef = React.useRef(/* @__PURE__ */ new Map());
13
+ const insertionOrderRef = React.useRef([]);
14
+ const [version, setVersion] = React.useState(0);
15
+ const bumpVersion = React.useCallback(() => setVersion((v) => v + 1), []);
16
+ const register = React.useCallback(
17
+ (id, config) => {
18
+ registrationsRef.current.set(id, config);
19
+ insertionOrderRef.current = insertionOrderRef.current.filter(
20
+ (k) => k !== id
21
+ );
22
+ insertionOrderRef.current.push(id);
23
+ bumpVersion();
24
+ },
25
+ [bumpVersion]
26
+ );
27
+ const unregister = React.useCallback(
28
+ (id) => {
29
+ registrationsRef.current.delete(id);
30
+ insertionOrderRef.current = insertionOrderRef.current.filter(
31
+ (k) => k !== id
32
+ );
33
+ bumpVersion();
34
+ },
35
+ [bumpVersion]
36
+ );
37
+ const getActive = React.useCallback(() => {
38
+ const order = insertionOrderRef.current;
39
+ if (order.length === 0) return null;
40
+ const lastId = order[order.length - 1];
41
+ if (!lastId) return null;
42
+ return registrationsRef.current.get(lastId) ?? null;
43
+ }, []);
44
+ const api = React.useMemo(
45
+ () => ({ register, unregister, getActive }),
46
+ [register, unregister, getActive]
47
+ );
48
+ return /* @__PURE__ */ jsxRuntime.jsx(PageAIAPIContext.Provider, { value: api, children: /* @__PURE__ */ jsxRuntime.jsx(PageAIVersionContext.Provider, { value: version, children }) });
49
+ }
50
+ function useRegisterPageAIContext(config) {
51
+ const ctx = React.useContext(PageAIAPIContext);
52
+ const id = React.useId();
53
+ const configRef = React.useRef(config);
54
+ configRef.current = config;
55
+ React.useEffect(() => {
56
+ if (!ctx || !configRef.current) return;
57
+ ctx.register(id, {
58
+ get routeName() {
59
+ return configRef.current?.routeName ?? "";
60
+ },
61
+ get pageDescription() {
62
+ return configRef.current?.pageDescription ?? "";
63
+ },
64
+ get suggestions() {
65
+ return configRef.current?.suggestions;
66
+ },
67
+ get clientTools() {
68
+ return configRef.current?.clientTools;
69
+ }
70
+ });
71
+ return () => {
72
+ ctx.unregister(id);
73
+ };
74
+ }, [
75
+ ctx,
76
+ id,
77
+ config === null,
78
+ config?.routeName,
79
+ config?.pageDescription,
80
+ JSON.stringify(config?.suggestions)
81
+ ]);
82
+ }
83
+ function usePageAIContext() {
84
+ React.useContext(PageAIVersionContext);
85
+ const ctx = React.useContext(PageAIAPIContext);
86
+ if (!ctx) return null;
87
+ return ctx.getActive();
88
+ }
89
+
90
+ exports.PageAIContextProvider = PageAIContextProvider;
91
+ exports.usePageAIContext = usePageAIContext;
92
+ exports.useRegisterPageAIContext = useRegisterPageAIContext;
@@ -0,0 +1,84 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * A client-side tool handler — receives the AI's tool call args and returns a result.
5
+ * The result is sent back to the model so it can continue the conversation.
6
+ */
7
+ type PageAIClientTool = (args: any) => Promise<{
8
+ success: boolean;
9
+ message?: string;
10
+ }>;
11
+ /**
12
+ * Configuration registered by a page to provide AI context and capabilities.
13
+ * Any component in the tree can call useRegisterPageAIContext with this config.
14
+ */
15
+ interface PageAIContextConfig {
16
+ /**
17
+ * Identifier for the current route/page (e.g. "blog-post", "ui-builder-edit-page").
18
+ * Shown as a badge in the chat header.
19
+ */
20
+ routeName: string;
21
+ /**
22
+ * Human-readable description of the current page and its content.
23
+ * Injected into the AI system prompt so it understands what the user is looking at.
24
+ * Capped at 8,000 characters server-side.
25
+ */
26
+ pageDescription: string;
27
+ /**
28
+ * Optional suggested prompts shown as quick-action chips in the chat empty state.
29
+ * These augment (not replace) any static suggestions configured in plugin overrides.
30
+ */
31
+ suggestions?: string[];
32
+ /**
33
+ * Client-side tool handlers keyed by tool name.
34
+ * When the AI calls a tool by this name, the handler is invoked with the tool args.
35
+ * The result is sent back to the model via addToolResult.
36
+ *
37
+ * Tool schemas must be registered server-side via enablePageTools + clientToolSchemas
38
+ * in aiChatBackendPlugin (built-in tools like fillBlogForm are pre-registered).
39
+ */
40
+ clientTools?: Record<string, PageAIClientTool>;
41
+ }
42
+ /**
43
+ * Provider that enables route-aware AI context across the app.
44
+ *
45
+ * Place this at the root layout — above all StackProviders — so it spans
46
+ * both your main app tree and any chat modals rendered as parallel/intercept routes.
47
+ *
48
+ * @example
49
+ * // app/layout.tsx
50
+ * import { PageAIContextProvider } from "@btst/stack/plugins/ai-chat/client/context"
51
+ *
52
+ * export default function RootLayout({ children }) {
53
+ * return <PageAIContextProvider>{children}</PageAIContextProvider>
54
+ * }
55
+ */
56
+ declare function PageAIContextProvider({ children, }: {
57
+ children: React.ReactNode;
58
+ }): react_jsx_runtime.JSX.Element;
59
+ /**
60
+ * Register page AI context from any component.
61
+ * The registration is cleaned up automatically when the component unmounts.
62
+ *
63
+ * Pass `null` to conditionally disable context (e.g. while data is loading).
64
+ *
65
+ * @example
66
+ * // Blog post page
67
+ * useRegisterPageAIContext(post ? {
68
+ * routeName: "blog-post",
69
+ * pageDescription: `Blog post: "${post.title}"\n\n${post.content?.slice(0, 16000)}`,
70
+ * suggestions: ["Summarize this post", "What are the key takeaways?"],
71
+ * } : null)
72
+ */
73
+ declare function useRegisterPageAIContext(config: PageAIContextConfig | null): void;
74
+ /**
75
+ * Read the currently active page AI context.
76
+ * Returns null when no page has registered context, or when PageAIContextProvider
77
+ * is not in the tree.
78
+ *
79
+ * Used internally by ChatInterface to inject context into requests.
80
+ */
81
+ declare function usePageAIContext(): PageAIContextConfig | null;
82
+
83
+ export { PageAIContextProvider, usePageAIContext, useRegisterPageAIContext };
84
+ export type { PageAIClientTool, PageAIContextConfig };
@@ -0,0 +1,84 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * A client-side tool handler — receives the AI's tool call args and returns a result.
5
+ * The result is sent back to the model so it can continue the conversation.
6
+ */
7
+ type PageAIClientTool = (args: any) => Promise<{
8
+ success: boolean;
9
+ message?: string;
10
+ }>;
11
+ /**
12
+ * Configuration registered by a page to provide AI context and capabilities.
13
+ * Any component in the tree can call useRegisterPageAIContext with this config.
14
+ */
15
+ interface PageAIContextConfig {
16
+ /**
17
+ * Identifier for the current route/page (e.g. "blog-post", "ui-builder-edit-page").
18
+ * Shown as a badge in the chat header.
19
+ */
20
+ routeName: string;
21
+ /**
22
+ * Human-readable description of the current page and its content.
23
+ * Injected into the AI system prompt so it understands what the user is looking at.
24
+ * Capped at 8,000 characters server-side.
25
+ */
26
+ pageDescription: string;
27
+ /**
28
+ * Optional suggested prompts shown as quick-action chips in the chat empty state.
29
+ * These augment (not replace) any static suggestions configured in plugin overrides.
30
+ */
31
+ suggestions?: string[];
32
+ /**
33
+ * Client-side tool handlers keyed by tool name.
34
+ * When the AI calls a tool by this name, the handler is invoked with the tool args.
35
+ * The result is sent back to the model via addToolResult.
36
+ *
37
+ * Tool schemas must be registered server-side via enablePageTools + clientToolSchemas
38
+ * in aiChatBackendPlugin (built-in tools like fillBlogForm are pre-registered).
39
+ */
40
+ clientTools?: Record<string, PageAIClientTool>;
41
+ }
42
+ /**
43
+ * Provider that enables route-aware AI context across the app.
44
+ *
45
+ * Place this at the root layout — above all StackProviders — so it spans
46
+ * both your main app tree and any chat modals rendered as parallel/intercept routes.
47
+ *
48
+ * @example
49
+ * // app/layout.tsx
50
+ * import { PageAIContextProvider } from "@btst/stack/plugins/ai-chat/client/context"
51
+ *
52
+ * export default function RootLayout({ children }) {
53
+ * return <PageAIContextProvider>{children}</PageAIContextProvider>
54
+ * }
55
+ */
56
+ declare function PageAIContextProvider({ children, }: {
57
+ children: React.ReactNode;
58
+ }): react_jsx_runtime.JSX.Element;
59
+ /**
60
+ * Register page AI context from any component.
61
+ * The registration is cleaned up automatically when the component unmounts.
62
+ *
63
+ * Pass `null` to conditionally disable context (e.g. while data is loading).
64
+ *
65
+ * @example
66
+ * // Blog post page
67
+ * useRegisterPageAIContext(post ? {
68
+ * routeName: "blog-post",
69
+ * pageDescription: `Blog post: "${post.title}"\n\n${post.content?.slice(0, 16000)}`,
70
+ * suggestions: ["Summarize this post", "What are the key takeaways?"],
71
+ * } : null)
72
+ */
73
+ declare function useRegisterPageAIContext(config: PageAIContextConfig | null): void;
74
+ /**
75
+ * Read the currently active page AI context.
76
+ * Returns null when no page has registered context, or when PageAIContextProvider
77
+ * is not in the tree.
78
+ *
79
+ * Used internally by ChatInterface to inject context into requests.
80
+ */
81
+ declare function usePageAIContext(): PageAIContextConfig | null;
82
+
83
+ export { PageAIContextProvider, usePageAIContext, useRegisterPageAIContext };
84
+ export type { PageAIClientTool, PageAIContextConfig };
@@ -0,0 +1,84 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * A client-side tool handler — receives the AI's tool call args and returns a result.
5
+ * The result is sent back to the model so it can continue the conversation.
6
+ */
7
+ type PageAIClientTool = (args: any) => Promise<{
8
+ success: boolean;
9
+ message?: string;
10
+ }>;
11
+ /**
12
+ * Configuration registered by a page to provide AI context and capabilities.
13
+ * Any component in the tree can call useRegisterPageAIContext with this config.
14
+ */
15
+ interface PageAIContextConfig {
16
+ /**
17
+ * Identifier for the current route/page (e.g. "blog-post", "ui-builder-edit-page").
18
+ * Shown as a badge in the chat header.
19
+ */
20
+ routeName: string;
21
+ /**
22
+ * Human-readable description of the current page and its content.
23
+ * Injected into the AI system prompt so it understands what the user is looking at.
24
+ * Capped at 8,000 characters server-side.
25
+ */
26
+ pageDescription: string;
27
+ /**
28
+ * Optional suggested prompts shown as quick-action chips in the chat empty state.
29
+ * These augment (not replace) any static suggestions configured in plugin overrides.
30
+ */
31
+ suggestions?: string[];
32
+ /**
33
+ * Client-side tool handlers keyed by tool name.
34
+ * When the AI calls a tool by this name, the handler is invoked with the tool args.
35
+ * The result is sent back to the model via addToolResult.
36
+ *
37
+ * Tool schemas must be registered server-side via enablePageTools + clientToolSchemas
38
+ * in aiChatBackendPlugin (built-in tools like fillBlogForm are pre-registered).
39
+ */
40
+ clientTools?: Record<string, PageAIClientTool>;
41
+ }
42
+ /**
43
+ * Provider that enables route-aware AI context across the app.
44
+ *
45
+ * Place this at the root layout — above all StackProviders — so it spans
46
+ * both your main app tree and any chat modals rendered as parallel/intercept routes.
47
+ *
48
+ * @example
49
+ * // app/layout.tsx
50
+ * import { PageAIContextProvider } from "@btst/stack/plugins/ai-chat/client/context"
51
+ *
52
+ * export default function RootLayout({ children }) {
53
+ * return <PageAIContextProvider>{children}</PageAIContextProvider>
54
+ * }
55
+ */
56
+ declare function PageAIContextProvider({ children, }: {
57
+ children: React.ReactNode;
58
+ }): react_jsx_runtime.JSX.Element;
59
+ /**
60
+ * Register page AI context from any component.
61
+ * The registration is cleaned up automatically when the component unmounts.
62
+ *
63
+ * Pass `null` to conditionally disable context (e.g. while data is loading).
64
+ *
65
+ * @example
66
+ * // Blog post page
67
+ * useRegisterPageAIContext(post ? {
68
+ * routeName: "blog-post",
69
+ * pageDescription: `Blog post: "${post.title}"\n\n${post.content?.slice(0, 16000)}`,
70
+ * suggestions: ["Summarize this post", "What are the key takeaways?"],
71
+ * } : null)
72
+ */
73
+ declare function useRegisterPageAIContext(config: PageAIContextConfig | null): void;
74
+ /**
75
+ * Read the currently active page AI context.
76
+ * Returns null when no page has registered context, or when PageAIContextProvider
77
+ * is not in the tree.
78
+ *
79
+ * Used internally by ChatInterface to inject context into requests.
80
+ */
81
+ declare function usePageAIContext(): PageAIContextConfig | null;
82
+
83
+ export { PageAIContextProvider, usePageAIContext, useRegisterPageAIContext };
84
+ export type { PageAIClientTool, PageAIContextConfig };
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { createContext, useRef, useState, useCallback, useMemo, useContext, useId, useEffect } from 'react';
4
+
5
+ const PageAIAPIContext = createContext(null);
6
+ const PageAIVersionContext = createContext(0);
7
+ function PageAIContextProvider({
8
+ children
9
+ }) {
10
+ const registrationsRef = useRef(/* @__PURE__ */ new Map());
11
+ const insertionOrderRef = useRef([]);
12
+ const [version, setVersion] = useState(0);
13
+ const bumpVersion = useCallback(() => setVersion((v) => v + 1), []);
14
+ const register = useCallback(
15
+ (id, config) => {
16
+ registrationsRef.current.set(id, config);
17
+ insertionOrderRef.current = insertionOrderRef.current.filter(
18
+ (k) => k !== id
19
+ );
20
+ insertionOrderRef.current.push(id);
21
+ bumpVersion();
22
+ },
23
+ [bumpVersion]
24
+ );
25
+ const unregister = useCallback(
26
+ (id) => {
27
+ registrationsRef.current.delete(id);
28
+ insertionOrderRef.current = insertionOrderRef.current.filter(
29
+ (k) => k !== id
30
+ );
31
+ bumpVersion();
32
+ },
33
+ [bumpVersion]
34
+ );
35
+ const getActive = useCallback(() => {
36
+ const order = insertionOrderRef.current;
37
+ if (order.length === 0) return null;
38
+ const lastId = order[order.length - 1];
39
+ if (!lastId) return null;
40
+ return registrationsRef.current.get(lastId) ?? null;
41
+ }, []);
42
+ const api = useMemo(
43
+ () => ({ register, unregister, getActive }),
44
+ [register, unregister, getActive]
45
+ );
46
+ return /* @__PURE__ */ jsx(PageAIAPIContext.Provider, { value: api, children: /* @__PURE__ */ jsx(PageAIVersionContext.Provider, { value: version, children }) });
47
+ }
48
+ function useRegisterPageAIContext(config) {
49
+ const ctx = useContext(PageAIAPIContext);
50
+ const id = useId();
51
+ const configRef = useRef(config);
52
+ configRef.current = config;
53
+ useEffect(() => {
54
+ if (!ctx || !configRef.current) return;
55
+ ctx.register(id, {
56
+ get routeName() {
57
+ return configRef.current?.routeName ?? "";
58
+ },
59
+ get pageDescription() {
60
+ return configRef.current?.pageDescription ?? "";
61
+ },
62
+ get suggestions() {
63
+ return configRef.current?.suggestions;
64
+ },
65
+ get clientTools() {
66
+ return configRef.current?.clientTools;
67
+ }
68
+ });
69
+ return () => {
70
+ ctx.unregister(id);
71
+ };
72
+ }, [
73
+ ctx,
74
+ id,
75
+ config === null,
76
+ config?.routeName,
77
+ config?.pageDescription,
78
+ JSON.stringify(config?.suggestions)
79
+ ]);
80
+ }
81
+ function usePageAIContext() {
82
+ useContext(PageAIVersionContext);
83
+ const ctx = useContext(PageAIAPIContext);
84
+ if (!ctx) return null;
85
+ return ctx.getActive();
86
+ }
87
+
88
+ export { PageAIContextProvider, usePageAIContext, useRegisterPageAIContext };
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { f as ConversationWithMessages } from '../../../../shared/stack.CMh_EdxW.cjs';
2
+ import { f as ConversationWithMessages } from '../../../../shared/stack.D-b5zbPm.cjs';
3
3
  import { S as SerializedConversation } from '../../../../shared/stack.Be1QIHEn.cjs';
4
4
  export { a as SerializedMessage } from '../../../../shared/stack.Be1QIHEn.cjs';
5
5
  import '@btst/stack/plugins/client';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { f as ConversationWithMessages } from '../../../../shared/stack.Dg09R0oB.mjs';
2
+ import { f as ConversationWithMessages } from '../../../../shared/stack.FVWf2JhZ.mjs';
3
3
  import { S as SerializedConversation } from '../../../../shared/stack.Be1QIHEn.mjs';
4
4
  export { a as SerializedMessage } from '../../../../shared/stack.Be1QIHEn.mjs';
5
5
  import '@btst/stack/plugins/client';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { f as ConversationWithMessages } from '../../../../shared/stack.BeSm90va.js';
2
+ import { f as ConversationWithMessages } from '../../../../shared/stack.CTDVxbrA.js';
3
3
  import { S as SerializedConversation } from '../../../../shared/stack.Be1QIHEn.js';
4
4
  export { a as SerializedMessage } from '../../../../shared/stack.Be1QIHEn.js';
5
5
  import '@btst/stack/plugins/client';
@@ -3,8 +3,8 @@ import * as react from 'react';
3
3
  import * as _btst_yar from '@btst/yar';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedConversation, a as SerializedMessage } from '../../../shared/stack.Be1QIHEn.cjs';
6
- import { A as AiChatMode } from '../../../shared/stack.DaOcgmrM.cjs';
7
- export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.DaOcgmrM.cjs';
6
+ import { A as AiChatMode } from '../../../shared/stack.BV9hnvu4.cjs';
7
+ export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.BV9hnvu4.cjs';
8
8
  export { UIMessage } from 'ai';
9
9
  import 'react/jsx-runtime';
10
10
 
@@ -83,31 +83,31 @@ interface AiChatClientConfig {
83
83
  */
84
84
  interface AiChatClientHooks {
85
85
  /**
86
- * Called before loading conversations list. Return false to cancel loading.
86
+ * Called before loading conversations list. Throw an error to cancel loading.
87
87
  * @param context - Loader context with path, params, etc.
88
88
  */
89
- beforeLoadConversations?: (context: LoaderContext) => Promise<boolean> | boolean;
89
+ beforeLoadConversations?: (context: LoaderContext) => Promise<void> | void;
90
90
  /**
91
- * Called after conversations are loaded. Return false to cancel further processing.
91
+ * Called after conversations are loaded. Throw an error to cancel further processing.
92
92
  * @param conversations - Array of loaded conversations or null
93
93
  * @param context - Loader context
94
94
  */
95
- afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<boolean> | boolean;
95
+ afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<void> | void;
96
96
  /**
97
- * Called before loading a single conversation. Return false to cancel loading.
97
+ * Called before loading a single conversation. Throw an error to cancel loading.
98
98
  * @param id - Conversation ID being loaded
99
99
  * @param context - Loader context
100
100
  */
101
- beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<boolean> | boolean;
101
+ beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<void> | void;
102
102
  /**
103
- * Called after a conversation is loaded. Return false to cancel further processing.
103
+ * Called after a conversation is loaded. Throw an error to cancel further processing.
104
104
  * @param conversation - Loaded conversation or null if not found
105
105
  * @param id - Conversation ID that was requested
106
106
  * @param context - Loader context
107
107
  */
108
108
  afterLoadConversation?: (conversation: (SerializedConversation & {
109
109
  messages: SerializedMessage[];
110
- }) | null, id: string, context: LoaderContext) => Promise<boolean> | boolean;
110
+ }) | null, id: string, context: LoaderContext) => Promise<void> | void;
111
111
  /**
112
112
  * Called when a loading error occurs
113
113
  * @param error - The error that occurred
@@ -3,8 +3,8 @@ import * as react from 'react';
3
3
  import * as _btst_yar from '@btst/yar';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedConversation, a as SerializedMessage } from '../../../shared/stack.Be1QIHEn.mjs';
6
- import { A as AiChatMode } from '../../../shared/stack.DaOcgmrM.mjs';
7
- export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.DaOcgmrM.mjs';
6
+ import { A as AiChatMode } from '../../../shared/stack.BV9hnvu4.mjs';
7
+ export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.BV9hnvu4.mjs';
8
8
  export { UIMessage } from 'ai';
9
9
  import 'react/jsx-runtime';
10
10
 
@@ -83,31 +83,31 @@ interface AiChatClientConfig {
83
83
  */
84
84
  interface AiChatClientHooks {
85
85
  /**
86
- * Called before loading conversations list. Return false to cancel loading.
86
+ * Called before loading conversations list. Throw an error to cancel loading.
87
87
  * @param context - Loader context with path, params, etc.
88
88
  */
89
- beforeLoadConversations?: (context: LoaderContext) => Promise<boolean> | boolean;
89
+ beforeLoadConversations?: (context: LoaderContext) => Promise<void> | void;
90
90
  /**
91
- * Called after conversations are loaded. Return false to cancel further processing.
91
+ * Called after conversations are loaded. Throw an error to cancel further processing.
92
92
  * @param conversations - Array of loaded conversations or null
93
93
  * @param context - Loader context
94
94
  */
95
- afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<boolean> | boolean;
95
+ afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<void> | void;
96
96
  /**
97
- * Called before loading a single conversation. Return false to cancel loading.
97
+ * Called before loading a single conversation. Throw an error to cancel loading.
98
98
  * @param id - Conversation ID being loaded
99
99
  * @param context - Loader context
100
100
  */
101
- beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<boolean> | boolean;
101
+ beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<void> | void;
102
102
  /**
103
- * Called after a conversation is loaded. Return false to cancel further processing.
103
+ * Called after a conversation is loaded. Throw an error to cancel further processing.
104
104
  * @param conversation - Loaded conversation or null if not found
105
105
  * @param id - Conversation ID that was requested
106
106
  * @param context - Loader context
107
107
  */
108
108
  afterLoadConversation?: (conversation: (SerializedConversation & {
109
109
  messages: SerializedMessage[];
110
- }) | null, id: string, context: LoaderContext) => Promise<boolean> | boolean;
110
+ }) | null, id: string, context: LoaderContext) => Promise<void> | void;
111
111
  /**
112
112
  * Called when a loading error occurs
113
113
  * @param error - The error that occurred
@@ -3,8 +3,8 @@ import * as react from 'react';
3
3
  import * as _btst_yar from '@btst/yar';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedConversation, a as SerializedMessage } from '../../../shared/stack.Be1QIHEn.js';
6
- import { A as AiChatMode } from '../../../shared/stack.DaOcgmrM.js';
7
- export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.DaOcgmrM.js';
6
+ import { A as AiChatMode } from '../../../shared/stack.BV9hnvu4.js';
7
+ export { a as AiChatPluginOverrides, b as AllowedFileType, i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, D as DEFAULT_ALLOWED_FILE_TYPES, j as ToolCallDisplay, T as ToolCallProps, d as ToolCallRenderer, c as ToolCallState } from '../../../shared/stack.BV9hnvu4.js';
8
8
  export { UIMessage } from 'ai';
9
9
  import 'react/jsx-runtime';
10
10
 
@@ -83,31 +83,31 @@ interface AiChatClientConfig {
83
83
  */
84
84
  interface AiChatClientHooks {
85
85
  /**
86
- * Called before loading conversations list. Return false to cancel loading.
86
+ * Called before loading conversations list. Throw an error to cancel loading.
87
87
  * @param context - Loader context with path, params, etc.
88
88
  */
89
- beforeLoadConversations?: (context: LoaderContext) => Promise<boolean> | boolean;
89
+ beforeLoadConversations?: (context: LoaderContext) => Promise<void> | void;
90
90
  /**
91
- * Called after conversations are loaded. Return false to cancel further processing.
91
+ * Called after conversations are loaded. Throw an error to cancel further processing.
92
92
  * @param conversations - Array of loaded conversations or null
93
93
  * @param context - Loader context
94
94
  */
95
- afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<boolean> | boolean;
95
+ afterLoadConversations?: (conversations: SerializedConversation[] | null, context: LoaderContext) => Promise<void> | void;
96
96
  /**
97
- * Called before loading a single conversation. Return false to cancel loading.
97
+ * Called before loading a single conversation. Throw an error to cancel loading.
98
98
  * @param id - Conversation ID being loaded
99
99
  * @param context - Loader context
100
100
  */
101
- beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<boolean> | boolean;
101
+ beforeLoadConversation?: (id: string, context: LoaderContext) => Promise<void> | void;
102
102
  /**
103
- * Called after a conversation is loaded. Return false to cancel further processing.
103
+ * Called after a conversation is loaded. Throw an error to cancel further processing.
104
104
  * @param conversation - Loaded conversation or null if not found
105
105
  * @param id - Conversation ID that was requested
106
106
  * @param context - Loader context
107
107
  */
108
108
  afterLoadConversation?: (conversation: (SerializedConversation & {
109
109
  messages: SerializedMessage[];
110
- }) | null, id: string, context: LoaderContext) => Promise<boolean> | boolean;
110
+ }) | null, id: string, context: LoaderContext) => Promise<void> | void;
111
111
  /**
112
112
  * Called when a loading error occurs
113
113
  * @param error - The error that occurred
@@ -1,7 +1,7 @@
1
1
  import '@tanstack/react-query';
2
2
  import '@btst/stack/plugins/client';
3
3
  import '../../shared/stack.Be1QIHEn.cjs';
4
- export { f as ConversationWithMessages, c as createAiChatQueryKeys } from '../../shared/stack.CMh_EdxW.cjs';
4
+ export { f as ConversationWithMessages, c as createAiChatQueryKeys } from '../../shared/stack.D-b5zbPm.cjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import 'better-call';
7
7
  import 'zod/v4/core';
@@ -1,7 +1,7 @@
1
1
  import '@tanstack/react-query';
2
2
  import '@btst/stack/plugins/client';
3
3
  import '../../shared/stack.Be1QIHEn.mjs';
4
- export { f as ConversationWithMessages, c as createAiChatQueryKeys } from '../../shared/stack.Dg09R0oB.mjs';
4
+ export { f as ConversationWithMessages, c as createAiChatQueryKeys } from '../../shared/stack.FVWf2JhZ.mjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import 'better-call';
7
7
  import 'zod/v4/core';