@btst/stack 2.3.0 → 2.4.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 (136) 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 +54 -7
  6. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +54 -7
  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/schemas.cjs +17 -1
  16. package/dist/packages/stack/src/plugins/ai-chat/schemas.mjs +17 -1
  17. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +15 -2
  18. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +16 -3
  19. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs +24 -1
  20. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs +24 -1
  21. package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.cjs +26 -0
  22. package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.mjs +24 -0
  23. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs +30 -1
  24. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs +30 -1
  25. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +18 -0
  26. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +18 -0
  27. package/dist/packages/stack/src/plugins/cms/api/mutations.cjs +48 -0
  28. package/dist/packages/stack/src/plugins/cms/api/mutations.mjs +46 -0
  29. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +7 -1
  30. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +7 -1
  31. package/dist/packages/stack/src/plugins/kanban/api/mutations.cjs +91 -0
  32. package/dist/packages/stack/src/plugins/kanban/api/mutations.mjs +87 -0
  33. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +6 -1
  34. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +6 -1
  35. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +7 -3
  36. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +7 -3
  37. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.cjs +89 -0
  38. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.mjs +89 -0
  39. package/dist/plugins/ai-chat/api/index.d.cts +1 -1
  40. package/dist/plugins/ai-chat/api/index.d.mts +1 -1
  41. package/dist/plugins/ai-chat/api/index.d.ts +1 -1
  42. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  43. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  44. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  45. package/dist/plugins/ai-chat/client/context/page-ai-context.cjs +92 -0
  46. package/dist/plugins/ai-chat/client/context/page-ai-context.d.cts +84 -0
  47. package/dist/plugins/ai-chat/client/context/page-ai-context.d.mts +84 -0
  48. package/dist/plugins/ai-chat/client/context/page-ai-context.d.ts +84 -0
  49. package/dist/plugins/ai-chat/client/context/page-ai-context.mjs +88 -0
  50. package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
  51. package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
  52. package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
  53. package/dist/plugins/ai-chat/client/index.d.cts +2 -2
  54. package/dist/plugins/ai-chat/client/index.d.mts +2 -2
  55. package/dist/plugins/ai-chat/client/index.d.ts +2 -2
  56. package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
  57. package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
  58. package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
  59. package/dist/plugins/blog/api/index.d.cts +2 -2
  60. package/dist/plugins/blog/api/index.d.mts +2 -2
  61. package/dist/plugins/blog/api/index.d.ts +2 -2
  62. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  63. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  64. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  65. package/dist/plugins/blog/client/index.d.cts +1 -1
  66. package/dist/plugins/blog/client/index.d.mts +1 -1
  67. package/dist/plugins/blog/client/index.d.ts +1 -1
  68. package/dist/plugins/blog/query-keys.d.cts +2 -2
  69. package/dist/plugins/blog/query-keys.d.mts +2 -2
  70. package/dist/plugins/blog/query-keys.d.ts +2 -2
  71. package/dist/plugins/cms/api/index.cjs +2 -0
  72. package/dist/plugins/cms/api/index.d.cts +1 -1
  73. package/dist/plugins/cms/api/index.d.mts +1 -1
  74. package/dist/plugins/cms/api/index.d.ts +1 -1
  75. package/dist/plugins/cms/api/index.mjs +1 -0
  76. package/dist/plugins/cms/query-keys.d.cts +1 -1
  77. package/dist/plugins/cms/query-keys.d.mts +1 -1
  78. package/dist/plugins/cms/query-keys.d.ts +1 -1
  79. package/dist/plugins/form-builder/api/index.d.cts +1 -1
  80. package/dist/plugins/form-builder/api/index.d.mts +1 -1
  81. package/dist/plugins/form-builder/api/index.d.ts +1 -1
  82. package/dist/plugins/form-builder/query-keys.d.cts +1 -1
  83. package/dist/plugins/form-builder/query-keys.d.mts +1 -1
  84. package/dist/plugins/form-builder/query-keys.d.ts +1 -1
  85. package/dist/plugins/kanban/api/index.cjs +4 -0
  86. package/dist/plugins/kanban/api/index.d.cts +1 -1
  87. package/dist/plugins/kanban/api/index.d.mts +1 -1
  88. package/dist/plugins/kanban/api/index.d.ts +1 -1
  89. package/dist/plugins/kanban/api/index.mjs +1 -0
  90. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  91. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  92. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  93. package/dist/shared/{stack.BeSm90va.d.ts → stack.BEn34wW6.d.ts} +60 -2
  94. package/dist/shared/{stack.IdtKDRka.d.cts → stack.BUkC2EsZ.d.cts} +32 -2
  95. package/dist/shared/{stack.DaOcgmrM.d.ts → stack.BV9hnvu4.d.cts} +31 -7
  96. package/dist/shared/{stack.DaOcgmrM.d.cts → stack.BV9hnvu4.d.mts} +31 -7
  97. package/dist/shared/{stack.DaOcgmrM.d.mts → stack.BV9hnvu4.d.ts} +31 -7
  98. package/dist/shared/{stack.rTy7-wQU.d.mts → stack.BepFXT3w.d.mts} +70 -15
  99. package/dist/shared/{stack.BKfolAyK.d.ts → stack.CL8ts1Mu.d.ts} +3 -3
  100. package/dist/shared/{stack.CP68pFEH.d.mts → stack.CczspVn2.d.mts} +32 -2
  101. package/dist/shared/{stack.TIBF2AOx.d.ts → stack.CgWzG5jH.d.ts} +70 -15
  102. package/dist/shared/{stack.BpolpQpf.d.cts → stack.D3GB6wKv.d.cts} +70 -15
  103. package/dist/shared/{stack.B1EeBt1b.d.ts → stack.DASmUVjX.d.ts} +32 -2
  104. package/dist/shared/{stack.Dg09R0oB.d.mts → stack.DTDxgFj8.d.mts} +60 -2
  105. package/dist/shared/{stack.CMh_EdxW.d.cts → stack.DWoCZff7.d.cts} +60 -2
  106. package/dist/shared/{stack.snB1EDP7.d.cts → stack.Dk5r4W1F.d.mts} +3 -3
  107. package/dist/shared/{stack.BIXEI6v_.d.mts → stack.heOA9gzA.d.cts} +3 -3
  108. package/package.json +14 -1
  109. package/src/client/components/compose.tsx +7 -4
  110. package/src/plugins/ai-chat/api/page-tools.ts +111 -0
  111. package/src/plugins/ai-chat/api/plugin.ts +180 -9
  112. package/src/plugins/ai-chat/client/components/chat-input.tsx +2 -2
  113. package/src/plugins/ai-chat/client/components/chat-interface.tsx +154 -58
  114. package/src/plugins/ai-chat/client/components/chat-layout.tsx +166 -32
  115. package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +1 -1
  116. package/src/plugins/ai-chat/client/context/page-ai-context.tsx +240 -0
  117. package/src/plugins/ai-chat/schemas.ts +16 -0
  118. package/src/plugins/blog/client/components/forms/post-forms.tsx +29 -2
  119. package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +28 -0
  120. package/src/plugins/blog/client/components/pages/fill-blog-form-handler.ts +38 -0
  121. package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +33 -1
  122. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +20 -0
  123. package/src/plugins/cms/api/index.ts +4 -0
  124. package/src/plugins/cms/api/mutations.ts +84 -0
  125. package/src/plugins/cms/api/plugin.ts +9 -0
  126. package/src/plugins/kanban/api/index.ts +6 -0
  127. package/src/plugins/kanban/api/mutations.ts +169 -0
  128. package/src/plugins/kanban/api/plugin.ts +12 -0
  129. package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +4 -0
  130. package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +132 -0
  131. package/dist/shared/{stack.C5dtIncc.d.mts → stack.B7ONvlD_.d.mts} +1 -1
  132. package/dist/shared/{stack.CBON0dWL.d.cts → stack.BQmuNl5p.d.cts} +2 -2
  133. package/dist/shared/{stack.CBON0dWL.d.mts → stack.BQmuNl5p.d.mts} +2 -2
  134. package/dist/shared/{stack.CBON0dWL.d.ts → stack.BQmuNl5p.d.ts} +2 -2
  135. package/dist/shared/{stack.CIP6QS9l.d.ts → stack.Kq2-QzOC.d.ts} +1 -1
  136. package/dist/shared/{stack.Dw0Ly2TM.d.cts → stack.kcdnD4gA.d.cts} +1 -1
@@ -2,6 +2,7 @@
2
2
 
3
3
  const plugin = require('../../../packages/stack/src/plugins/kanban/api/plugin.cjs');
4
4
  const getters = require('../../../packages/stack/src/plugins/kanban/api/getters.cjs');
5
+ const mutations = require('../../../packages/stack/src/plugins/kanban/api/mutations.cjs');
5
6
  const serializers = require('../../../packages/stack/src/plugins/kanban/api/serializers.cjs');
6
7
  const queryKeyDefs = require('../../../packages/stack/src/plugins/kanban/api/query-key-defs.cjs');
7
8
 
@@ -10,6 +11,9 @@ const queryKeyDefs = require('../../../packages/stack/src/plugins/kanban/api/que
10
11
  exports.kanbanBackendPlugin = plugin.kanbanBackendPlugin;
11
12
  exports.getAllBoards = getters.getAllBoards;
12
13
  exports.getBoardById = getters.getBoardById;
14
+ exports.createKanbanTask = mutations.createKanbanTask;
15
+ exports.findOrCreateKanbanBoard = mutations.findOrCreateKanbanBoard;
16
+ exports.getKanbanColumnsByBoardId = mutations.getKanbanColumnsByBoardId;
13
17
  exports.serializeBoard = serializers.serializeBoard;
14
18
  exports.serializeColumn = serializers.serializeColumn;
15
19
  exports.serializeTask = serializers.serializeTask;
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, e as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, g as getAllBoards, d as getBoardById, k as kanbanBackendPlugin } from '../../../shared/stack.BpolpQpf.cjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.D3GB6wKv.cjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.cjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, e as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, g as getAllBoards, d as getBoardById, k as kanbanBackendPlugin } from '../../../shared/stack.rTy7-wQU.mjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.BepFXT3w.mjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.mjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, e as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, g as getAllBoards, d as getBoardById, k as kanbanBackendPlugin } from '../../../shared/stack.TIBF2AOx.js';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.CgWzG5jH.js';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.js';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';
@@ -1,4 +1,5 @@
1
1
  export { kanbanBackendPlugin } from '../../../packages/stack/src/plugins/kanban/api/plugin.mjs';
2
2
  export { getAllBoards, getBoardById } from '../../../packages/stack/src/plugins/kanban/api/getters.mjs';
3
+ export { createKanbanTask, findOrCreateKanbanBoard, getKanbanColumnsByBoardId } from '../../../packages/stack/src/plugins/kanban/api/mutations.mjs';
3
4
  export { serializeBoard, serializeColumn, serializeTask } from '../../../packages/stack/src/plugins/kanban/api/serializers.mjs';
4
5
  export { KANBAN_QUERY_KEYS } from '../../../packages/stack/src/plugins/kanban/api/query-key-defs.mjs';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, f as BoardsListDiscriminator } from '../../shared/stack.BpolpQpf.cjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.D3GB6wKv.cjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.cjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, f as BoardsListDiscriminator } from '../../shared/stack.rTy7-wQU.mjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.BepFXT3w.mjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.mjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, f as BoardsListDiscriminator } from '../../shared/stack.TIBF2AOx.js';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.CgWzG5jH.js';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.js';
5
5
  import '@btst/stack/plugins/api';
@@ -5,7 +5,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
5
5
  import * as better_call from 'better-call';
6
6
  import * as zod_v4_core from 'zod/v4/core';
7
7
  import * as zod from 'zod';
8
- import { LanguageModel, Tool } from 'ai';
8
+ import { Tool, LanguageModel } from 'ai';
9
9
 
10
10
  /**
11
11
  * Context passed to AI Chat API hooks
@@ -67,6 +67,18 @@ interface AiChatBackendHooks {
67
67
  * @param context - Request context with headers, etc.
68
68
  */
69
69
  onBeforeDeleteConversation?: (conversationId: string, context: ChatApiContext) => Promise<boolean> | boolean;
70
+ /**
71
+ * Called after the structural routeName/allowlist validation, with the list
72
+ * of tool names that passed. Return a filtered subset to further restrict
73
+ * which tools the LLM sees, or return [] to suppress all page tools.
74
+ * Throw an Error to abort the entire chat request with a 403 response.
75
+ * Not called when no tools passed the structural validation step.
76
+ *
77
+ * @param toolNames - Names that passed the routeName allowlist check
78
+ * @param routeName - routeName claimed by the request (may be undefined)
79
+ * @param context - Full request context (headers, body, etc.)
80
+ */
81
+ onBeforeToolsActivated?: (toolNames: string[], routeName: string | undefined, context: ChatApiContext) => Promise<string[]> | string[];
70
82
  /**
71
83
  * Called after a chat message is processed successfully
72
84
  * @param conversationId - ID of the conversation
@@ -152,6 +164,23 @@ type AiChatMode = "authenticated" | "public";
152
164
  /**
153
165
  * Configuration for AI Chat backend plugin
154
166
  */
167
+ /**
168
+ * Extracts only the literal (non-index-signature) keys from a type.
169
+ * For `Record<string, T>` this resolves to `never`, so collision checks are
170
+ * skipped when the tools map is typed with a broad string index.
171
+ */
172
+ type KnownKeys<T> = {
173
+ [K in keyof T]: string extends K ? never : K;
174
+ }[keyof T];
175
+ /**
176
+ * Ensures `TClientTools` has no keys that are also literal keys in `TTools`.
177
+ * Colliding keys are mapped to `never`, which produces a compile-time error
178
+ * at the point of the duplicate key. When `TTools` uses a string index
179
+ * signature the check is skipped to avoid false positives.
180
+ */
181
+ type NoKeyCollision<TTools, TClientTools extends Record<string, Tool>> = KnownKeys<TTools> & keyof TClientTools extends never ? TClientTools : {
182
+ [K in keyof TClientTools]: K extends KnownKeys<TTools> ? never : TClientTools[K];
183
+ };
155
184
  interface AiChatBackendConfig {
156
185
  /**
157
186
  * The language model to use for chat completions.
@@ -182,6 +211,29 @@ interface AiChatBackendConfig {
182
211
  * @see https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling
183
212
  */
184
213
  tools?: Record<string, Tool>;
214
+ /**
215
+ * Enable route-aware page tools.
216
+ * When true, the server will include tool schemas for client-side page tools
217
+ * (e.g. fillBlogForm, updatePageLayers) based on the availableTools list
218
+ * sent with each request.
219
+ * @default false
220
+ */
221
+ enablePageTools?: boolean;
222
+ /**
223
+ * Custom client-side tool schemas for non-BTST pages.
224
+ * Merged with built-in page tool schemas (fillBlogForm, updatePageLayers).
225
+ * Only included when enablePageTools is true and the tool name appears in
226
+ * the availableTools list sent with the request.
227
+ *
228
+ * @example
229
+ * clientToolSchemas: {
230
+ * addToCart: tool({
231
+ * description: "Add current product to cart",
232
+ * parameters: z.object({ quantity: z.number().int().min(1) }),
233
+ * }),
234
+ * }
235
+ */
236
+ clientToolSchemas?: Record<string, Tool>;
185
237
  /**
186
238
  * Optional hooks for customizing plugin behavior
187
239
  */
@@ -194,7 +246,10 @@ interface AiChatBackendConfig {
194
246
  *
195
247
  * @param config - Configuration including model, tools, and optional hooks
196
248
  */
197
- declare const aiChatBackendPlugin: (config: AiChatBackendConfig) => _btst_stack_plugins_api.BackendPlugin<{
249
+ declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record<never, Tool>, TClientTools extends Record<string, Tool> = Record<never, Tool>>(config: Omit<AiChatBackendConfig, "tools" | "clientToolSchemas"> & {
250
+ tools?: TTools;
251
+ clientToolSchemas?: NoKeyCollision<TTools, TClientTools>;
252
+ }) => _btst_stack_plugins_api.BackendPlugin<{
198
253
  chat: better_call.StrictEndpoint<"/chat", {
199
254
  method: "POST";
200
255
  body: zod.ZodObject<{
@@ -223,6 +278,9 @@ declare const aiChatBackendPlugin: (config: AiChatBackendConfig) => _btst_stack_
223
278
  }, zod_v4_core.$strip>]>>;
224
279
  conversationId: zod.ZodOptional<zod.ZodString>;
225
280
  model: zod.ZodOptional<zod.ZodString>;
281
+ pageContext: zod.ZodOptional<zod.ZodString>;
282
+ availableTools: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
283
+ routeName: zod.ZodOptional<zod.ZodString>;
226
284
  }, zod_v4_core.$strip>;
227
285
  }, Response>;
228
286
  createConversation: better_call.StrictEndpoint<"/chat/conversations", {
@@ -78,6 +78,35 @@ declare function getContentItemById(adapter: Adapter, id: string): Promise<Seria
78
78
  */
79
79
  declare function getContentItemBySlug(adapter: Adapter, contentTypeSlug: string, slug: string): Promise<SerializedContentItemWithType | null>;
80
80
 
81
+ /**
82
+ * Input for creating a new CMS content item.
83
+ */
84
+ interface CreateCMSContentItemInput {
85
+ /** URL-safe slug for the item */
86
+ slug: string;
87
+ /** Arbitrary data payload — should match the content type schema */
88
+ data: Record<string, unknown>;
89
+ }
90
+ /**
91
+ * Create a new content item for a content type (looked up by slug).
92
+ *
93
+ * Bypasses Zod schema validation and relation processing — the caller is
94
+ * responsible for providing valid, relation-free data. For relation fields or
95
+ * schema validation, use the HTTP endpoint instead.
96
+ *
97
+ * Throws if the content type is not found or the slug is already taken within
98
+ * that content type.
99
+ *
100
+ * @remarks **Security:** No authorization hooks (`onBeforeCreate`, `onAfterCreate`)
101
+ * are called. The caller is responsible for any access-control checks before
102
+ * invoking this function.
103
+ *
104
+ * @param adapter - The database adapter
105
+ * @param contentTypeSlug - Slug of the target content type
106
+ * @param input - Item slug and data payload
107
+ */
108
+ declare function createCMSContentItem(adapter: Adapter, contentTypeSlug: string, input: CreateCMSContentItemInput): Promise<SerializedContentItem>;
109
+
81
110
  /**
82
111
  * Route keys for the CMS plugin — matches the keys returned by
83
112
  * `stackClient.router.getRoute(path).routeKey`.
@@ -257,6 +286,7 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
257
286
  getContentItemBySlug: (contentTypeSlug: string, slug: string) => Promise<SerializedContentItemWithType<Record<string, unknown>> | null>;
258
287
  getContentItemById: (id: string) => Promise<SerializedContentItemWithType<Record<string, unknown>> | null>;
259
288
  prefetchForRoute: CMSPrefetchForRoute;
289
+ createContentItem: (typeSlug: string, input: Parameters<typeof createCMSContentItem>[2]) => Promise<SerializedContentItem>;
260
290
  }>;
261
291
  type CMSApiRouter = ReturnType<ReturnType<typeof cmsBackendPlugin>["routes"]>;
262
292
 
@@ -293,5 +323,5 @@ declare const CMS_QUERY_KEYS: {
293
323
  contentDetail: (typeSlug: string, id: string) => readonly ["cmsContent", "detail", string, string];
294
324
  };
295
325
 
296
- export { cmsBackendPlugin as c, getAllContentItems as d, getContentItemBySlug as e, getContentItemById as f, getAllContentTypes as g, serializeContentItem as h, serializeContentItemWithType as i, CMS_QUERY_KEYS as j, serializeContentType as s };
297
- export type { CMSApiRouter as C, ContentListDiscriminator as a, CMSRouteKey as b };
326
+ export { cmsBackendPlugin as c, getAllContentItems as d, getContentItemBySlug as e, getContentItemById as f, getAllContentTypes as g, serializeContentItem as h, serializeContentItemWithType as i, createCMSContentItem as j, CMS_QUERY_KEYS as l, serializeContentType as s };
327
+ export type { CMSApiRouter as C, ContentListDiscriminator as a, CMSRouteKey as b, CreateCMSContentItemInput as k };
@@ -244,31 +244,55 @@ interface ChatInterfaceProps {
244
244
  }
245
245
  declare function ChatInterface({ apiPath, initialMessages, id, variant, className, onMessagesChange, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
246
246
 
247
- interface ChatLayoutProps {
247
+ interface ChatLayoutBaseProps {
248
248
  /** API base URL */
249
249
  apiBaseURL: string;
250
250
  /** API base path */
251
251
  apiBasePath: string;
252
252
  /** Current conversation ID (if viewing existing conversation) */
253
253
  conversationId?: string;
254
- /** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
255
- layout?: "full" | "widget";
256
254
  /** Additional class name for the container */
257
255
  className?: string;
258
- /** Whether to show the sidebar (default: true for full layout) */
256
+ /** Whether to show the sidebar */
259
257
  showSidebar?: boolean;
260
- /** Height of the widget (only applies to widget layout) */
261
- widgetHeight?: string | number;
262
258
  /** Initial messages to populate the chat (useful for localStorage persistence in public mode) */
263
259
  initialMessages?: UIMessage[];
264
260
  /** Called whenever messages change (for persistence). Only fires in public mode. */
265
261
  onMessagesChange?: (messages: UIMessage[]) => void;
266
262
  }
263
+ interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
264
+ /** Widget mode: compact embeddable panel with a floating trigger button */
265
+ layout: "widget";
266
+ /** Height of the widget panel. Default: `"600px"` */
267
+ widgetHeight?: string | number;
268
+ /** Width of the widget panel. Default: `"380px"` */
269
+ widgetWidth?: string | number;
270
+ /**
271
+ * Whether the widget panel starts open. Default: `false`.
272
+ * Set to `true` when embedding inside an already-open container such as a
273
+ * Next.js intercepting-route modal — the panel will be immediately visible
274
+ * without the user needing to click the trigger button.
275
+ */
276
+ defaultOpen?: boolean;
277
+ /**
278
+ * Whether to render the built-in floating trigger button. Default: `true`.
279
+ * Set to `false` when you control open/close externally (e.g. a Next.js
280
+ * parallel-route slot, a custom button, or a `router.back()` dismiss action)
281
+ * so that the built-in button does not appear alongside your own UI.
282
+ */
283
+ showTrigger?: boolean;
284
+ }
285
+ interface ChatLayoutFullProps extends ChatLayoutBaseProps {
286
+ /** Full-page mode with sidebar navigation (default) */
287
+ layout?: "full";
288
+ }
289
+ /** Props for the ChatLayout component */
290
+ type ChatLayoutProps = ChatLayoutWidgetProps | ChatLayoutFullProps;
267
291
  /**
268
292
  * ChatLayout component that provides a full-page chat experience with sidebar
269
293
  * or a compact widget mode for embedding.
270
294
  */
271
- declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, initialMessages, onMessagesChange, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
295
+ declare function ChatLayout(props: ChatLayoutProps): react_jsx_runtime.JSX.Element;
272
296
 
273
297
  interface ChatSidebarProps {
274
298
  currentConversationId?: string;
@@ -244,31 +244,55 @@ interface ChatInterfaceProps {
244
244
  }
245
245
  declare function ChatInterface({ apiPath, initialMessages, id, variant, className, onMessagesChange, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
246
246
 
247
- interface ChatLayoutProps {
247
+ interface ChatLayoutBaseProps {
248
248
  /** API base URL */
249
249
  apiBaseURL: string;
250
250
  /** API base path */
251
251
  apiBasePath: string;
252
252
  /** Current conversation ID (if viewing existing conversation) */
253
253
  conversationId?: string;
254
- /** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
255
- layout?: "full" | "widget";
256
254
  /** Additional class name for the container */
257
255
  className?: string;
258
- /** Whether to show the sidebar (default: true for full layout) */
256
+ /** Whether to show the sidebar */
259
257
  showSidebar?: boolean;
260
- /** Height of the widget (only applies to widget layout) */
261
- widgetHeight?: string | number;
262
258
  /** Initial messages to populate the chat (useful for localStorage persistence in public mode) */
263
259
  initialMessages?: UIMessage[];
264
260
  /** Called whenever messages change (for persistence). Only fires in public mode. */
265
261
  onMessagesChange?: (messages: UIMessage[]) => void;
266
262
  }
263
+ interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
264
+ /** Widget mode: compact embeddable panel with a floating trigger button */
265
+ layout: "widget";
266
+ /** Height of the widget panel. Default: `"600px"` */
267
+ widgetHeight?: string | number;
268
+ /** Width of the widget panel. Default: `"380px"` */
269
+ widgetWidth?: string | number;
270
+ /**
271
+ * Whether the widget panel starts open. Default: `false`.
272
+ * Set to `true` when embedding inside an already-open container such as a
273
+ * Next.js intercepting-route modal — the panel will be immediately visible
274
+ * without the user needing to click the trigger button.
275
+ */
276
+ defaultOpen?: boolean;
277
+ /**
278
+ * Whether to render the built-in floating trigger button. Default: `true`.
279
+ * Set to `false` when you control open/close externally (e.g. a Next.js
280
+ * parallel-route slot, a custom button, or a `router.back()` dismiss action)
281
+ * so that the built-in button does not appear alongside your own UI.
282
+ */
283
+ showTrigger?: boolean;
284
+ }
285
+ interface ChatLayoutFullProps extends ChatLayoutBaseProps {
286
+ /** Full-page mode with sidebar navigation (default) */
287
+ layout?: "full";
288
+ }
289
+ /** Props for the ChatLayout component */
290
+ type ChatLayoutProps = ChatLayoutWidgetProps | ChatLayoutFullProps;
267
291
  /**
268
292
  * ChatLayout component that provides a full-page chat experience with sidebar
269
293
  * or a compact widget mode for embedding.
270
294
  */
271
- declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, initialMessages, onMessagesChange, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
295
+ declare function ChatLayout(props: ChatLayoutProps): react_jsx_runtime.JSX.Element;
272
296
 
273
297
  interface ChatSidebarProps {
274
298
  currentConversationId?: string;
@@ -244,31 +244,55 @@ interface ChatInterfaceProps {
244
244
  }
245
245
  declare function ChatInterface({ apiPath, initialMessages, id, variant, className, onMessagesChange, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
246
246
 
247
- interface ChatLayoutProps {
247
+ interface ChatLayoutBaseProps {
248
248
  /** API base URL */
249
249
  apiBaseURL: string;
250
250
  /** API base path */
251
251
  apiBasePath: string;
252
252
  /** Current conversation ID (if viewing existing conversation) */
253
253
  conversationId?: string;
254
- /** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
255
- layout?: "full" | "widget";
256
254
  /** Additional class name for the container */
257
255
  className?: string;
258
- /** Whether to show the sidebar (default: true for full layout) */
256
+ /** Whether to show the sidebar */
259
257
  showSidebar?: boolean;
260
- /** Height of the widget (only applies to widget layout) */
261
- widgetHeight?: string | number;
262
258
  /** Initial messages to populate the chat (useful for localStorage persistence in public mode) */
263
259
  initialMessages?: UIMessage[];
264
260
  /** Called whenever messages change (for persistence). Only fires in public mode. */
265
261
  onMessagesChange?: (messages: UIMessage[]) => void;
266
262
  }
263
+ interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
264
+ /** Widget mode: compact embeddable panel with a floating trigger button */
265
+ layout: "widget";
266
+ /** Height of the widget panel. Default: `"600px"` */
267
+ widgetHeight?: string | number;
268
+ /** Width of the widget panel. Default: `"380px"` */
269
+ widgetWidth?: string | number;
270
+ /**
271
+ * Whether the widget panel starts open. Default: `false`.
272
+ * Set to `true` when embedding inside an already-open container such as a
273
+ * Next.js intercepting-route modal — the panel will be immediately visible
274
+ * without the user needing to click the trigger button.
275
+ */
276
+ defaultOpen?: boolean;
277
+ /**
278
+ * Whether to render the built-in floating trigger button. Default: `true`.
279
+ * Set to `false` when you control open/close externally (e.g. a Next.js
280
+ * parallel-route slot, a custom button, or a `router.back()` dismiss action)
281
+ * so that the built-in button does not appear alongside your own UI.
282
+ */
283
+ showTrigger?: boolean;
284
+ }
285
+ interface ChatLayoutFullProps extends ChatLayoutBaseProps {
286
+ /** Full-page mode with sidebar navigation (default) */
287
+ layout?: "full";
288
+ }
289
+ /** Props for the ChatLayout component */
290
+ type ChatLayoutProps = ChatLayoutWidgetProps | ChatLayoutFullProps;
267
291
  /**
268
292
  * ChatLayout component that provides a full-page chat experience with sidebar
269
293
  * or a compact widget mode for embedding.
270
294
  */
271
- declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, initialMessages, onMessagesChange, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
295
+ declare function ChatLayout(props: ChatLayoutProps): react_jsx_runtime.JSX.Element;
272
296
 
273
297
  interface ChatSidebarProps {
274
298
  currentConversationId?: string;
@@ -1,18 +1,18 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
3
  import { Adapter } from '@btst/db';
4
- import { B as BoardWithColumns, d as Board, e as Column, T as Task, C as ColumnWithTasks } from './stack.DJaKVY7v.mjs';
4
+ import { B as BoardWithColumns, P as Priority, T as Task, d as Board, e as Column, C as ColumnWithTasks } from './stack.DJaKVY7v.mjs';
5
5
  import { z } from 'zod';
6
6
  import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
- createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
12
- updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
13
10
  slug: z.ZodOptional<z.ZodString>;
14
11
  ownerId: z.ZodOptional<z.ZodString>;
15
12
  organizationId: z.ZodOptional<z.ZodString>;
13
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -28,8 +28,8 @@ declare const createColumnSchema: z.ZodObject<{
28
28
  title: z.ZodString;
29
29
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
30
30
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
31
- boardId: z.ZodString;
32
31
  order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
32
+ boardId: z.ZodString;
33
33
  }, z.core.$strip>;
34
34
  declare const updateColumnSchema: z.ZodObject<{
35
35
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -109,6 +109,58 @@ declare function getAllBoards(adapter: Adapter, params?: z.infer<typeof BoardLis
109
109
  */
110
110
  declare function getBoardById(adapter: Adapter, id: string): Promise<BoardWithColumns | null>;
111
111
 
112
+ /**
113
+ * Input for creating a new Kanban task.
114
+ */
115
+ interface CreateKanbanTaskInput {
116
+ title: string;
117
+ columnId: string;
118
+ description?: string;
119
+ priority?: Priority;
120
+ assigneeId?: string;
121
+ }
122
+ /**
123
+ * Create a new task in a Kanban column.
124
+ * Computes the next order value from existing tasks in the column.
125
+ *
126
+ * @remarks **Security:** No authorization hooks (onBeforeCreateTask) are called.
127
+ * The caller is responsible for any access-control checks before invoking this
128
+ * function.
129
+ *
130
+ * @param adapter - The database adapter
131
+ * @param input - Task creation input
132
+ */
133
+ declare function createKanbanTask(adapter: Adapter, input: CreateKanbanTaskInput): Promise<Task>;
134
+ /**
135
+ * Find a board by slug, or create it with the given name and custom column titles.
136
+ *
137
+ * Concurrency-safe at two levels:
138
+ * - **Same process**: concurrent calls with the same slug share a single in-flight
139
+ * Promise (via `_pendingBoardCreations`), so only one DB write is attempted.
140
+ * - **Cross-instance**: the DB `unique` constraint on `slug` causes the losing
141
+ * write to throw; the catch block re-fetches and returns the winner's board.
142
+ *
143
+ * @remarks **Security:** No authorization hooks are called. The caller is
144
+ * responsible for any access-control checks before invoking this function.
145
+ *
146
+ * @param adapter - The database adapter
147
+ * @param slug - Unique URL-safe slug for the board
148
+ * @param name - Display name for the board (used only on creation)
149
+ * @param columnTitles - Ordered list of column names to create (used only on creation)
150
+ */
151
+ declare function findOrCreateKanbanBoard(adapter: Adapter, slug: string, name: string, columnTitles: string[]): Promise<Board>;
152
+ /**
153
+ * Retrieve all columns for a given board, sorted by order.
154
+ * Co-located with mutations because it is primarily used alongside
155
+ * {@link createKanbanTask} to resolve column IDs before task creation.
156
+ *
157
+ * @remarks **Security:** No authorization hooks are called.
158
+ *
159
+ * @param adapter - The database adapter
160
+ * @param boardId - The board ID
161
+ */
162
+ declare function getKanbanColumnsByBoardId(adapter: Adapter, boardId: string): Promise<Column[]>;
163
+
112
164
  /**
113
165
  * Route keys for the Kanban plugin — matches the keys returned by
114
166
  * `stackClient.router.getRoute(path).routeKey`.
@@ -271,12 +323,12 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
271
323
  method: "POST";
272
324
  body: z.ZodObject<{
273
325
  description: z.ZodOptional<z.ZodString>;
274
- name: z.ZodString;
275
- createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
276
- updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
277
326
  slug: z.ZodOptional<z.ZodString>;
278
327
  ownerId: z.ZodOptional<z.ZodString>;
279
328
  organizationId: z.ZodOptional<z.ZodString>;
329
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
330
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
331
+ name: z.ZodString;
280
332
  }, z.core.$strip>;
281
333
  }, {
282
334
  columns: ColumnWithTasks[];
@@ -293,12 +345,12 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
293
345
  method: "PUT";
294
346
  body: z.ZodObject<{
295
347
  description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
296
- name: z.ZodOptional<z.ZodString>;
297
- createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
298
- updatedAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
299
348
  slug: z.ZodOptional<z.ZodString>;
300
349
  ownerId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
301
350
  organizationId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
351
+ createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
352
+ updatedAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
353
+ name: z.ZodOptional<z.ZodString>;
302
354
  }, z.core.$strip>;
303
355
  }, Board>;
304
356
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {
@@ -312,8 +364,8 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
312
364
  title: z.ZodString;
313
365
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
314
366
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
315
- boardId: z.ZodString;
316
367
  order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
368
+ boardId: z.ZodString;
317
369
  }, z.core.$strip>;
318
370
  }, Column>;
319
371
  readonly updateColumn: better_call.StrictEndpoint<"/columns/:id", {
@@ -322,8 +374,8 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
322
374
  title: z.ZodOptional<z.ZodString>;
323
375
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
324
376
  updatedAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
325
- boardId: z.ZodOptional<z.ZodString>;
326
377
  order: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodNumber>>>;
378
+ boardId: z.ZodOptional<z.ZodString>;
327
379
  }, z.core.$strip>;
328
380
  }, Column>;
329
381
  readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {
@@ -406,6 +458,9 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
406
458
  getAllBoards: (params?: Parameters<typeof getAllBoards>[1]) => Promise<BoardListResult>;
407
459
  getBoardById: (id: string) => Promise<BoardWithColumns | null>;
408
460
  prefetchForRoute: KanbanPrefetchForRoute;
461
+ createTask: (input: Parameters<typeof createKanbanTask>[1]) => Promise<Task>;
462
+ findOrCreateBoard: (slug: string, name: string, columnTitles: string[]) => Promise<Board>;
463
+ getColumnsByBoardId: (boardId: string) => Promise<Column[]>;
409
464
  }>;
410
465
  type KanbanApiRouter = ReturnType<ReturnType<typeof kanbanBackendPlugin>["routes"]>;
411
466
 
@@ -441,5 +496,5 @@ declare const KANBAN_QUERY_KEYS: {
441
496
  boardDetail: (boardId: string) => readonly ["boards", "detail", string];
442
497
  };
443
498
 
444
- export { getBoardById as d, KANBAN_QUERY_KEYS as e, getAllBoards as g, kanbanBackendPlugin as k };
445
- export type { BoardListResult as B, KanbanApiRouter as K, KanbanRouteKey as a, KanbanApiContext as b, KanbanBackendHooks as c, BoardsListDiscriminator as f };
499
+ export { getBoardById as d, createKanbanTask as e, findOrCreateKanbanBoard as f, getAllBoards as g, getKanbanColumnsByBoardId as h, KANBAN_QUERY_KEYS as i, kanbanBackendPlugin as k };
500
+ export type { BoardListResult as B, CreateKanbanTaskInput as C, KanbanApiRouter as K, KanbanRouteKey as a, KanbanApiContext as b, KanbanBackendHooks as c, BoardsListDiscriminator as j };
@@ -1,7 +1,7 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { QueryClient } from '@tanstack/react-query';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
- import { P as Post, T as Tag, c as createPostSchema, u as updatePostSchema, S as SerializedPost, a as SerializedTag } from './stack.CBON0dWL.js';
4
+ import { P as Post, T as Tag, c as createPostSchema, u as updatePostSchema, S as SerializedPost, a as SerializedTag } from './stack.BQmuNl5p.js';
5
5
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
6
6
  import * as better_call from 'better-call';
7
7
  import { Adapter } from '@btst/db';
@@ -218,11 +218,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
218
218
  name: z.ZodString;
219
219
  slug: z.ZodString;
220
220
  }, z.core.$strip>]>>>>;
221
+ title: z.ZodString;
221
222
  slug: z.ZodOptional<z.ZodString>;
222
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
223
223
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
224
224
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
225
- title: z.ZodString;
225
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
226
226
  content: z.ZodString;
227
227
  excerpt: z.ZodString;
228
228
  image: z.ZodOptional<z.ZodString>;