@btst/stack 4.2.0 → 4.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 (72) hide show
  1. package/README.md +2 -2
  2. package/dist/packages/stack/src/plugins/ai-chat/api/compaction.cjs +249 -0
  3. package/dist/packages/stack/src/plugins/ai-chat/api/compaction.mjs +241 -0
  4. package/dist/packages/stack/src/plugins/ai-chat/api/operations.cjs +20 -0
  5. package/dist/packages/stack/src/plugins/ai-chat/api/operations.mjs +20 -0
  6. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +5 -0
  7. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +5 -0
  8. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +38 -3
  9. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +38 -3
  10. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +173 -72
  11. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +176 -75
  12. package/dist/packages/stack/src/plugins/ai-chat/client/context-checkpoint.cjs +30 -0
  13. package/dist/packages/stack/src/plugins/ai-chat/client/context-checkpoint.mjs +27 -0
  14. package/dist/packages/stack/src/plugins/ai-chat/schemas.cjs +2 -0
  15. package/dist/packages/stack/src/plugins/ai-chat/schemas.mjs +2 -0
  16. package/dist/packages/ui/src/components/markdown-content.cjs +9 -9
  17. package/dist/packages/ui/src/components/markdown-content.mjs +9 -9
  18. package/dist/plugins/ai-chat/api/index.d.cts +2 -2
  19. package/dist/plugins/ai-chat/api/index.d.mts +2 -2
  20. package/dist/plugins/ai-chat/api/index.d.ts +2 -2
  21. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  22. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  23. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  24. package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
  25. package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
  26. package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
  27. package/dist/plugins/ai-chat/client/index.d.cts +3 -3
  28. package/dist/plugins/ai-chat/client/index.d.mts +3 -3
  29. package/dist/plugins/ai-chat/client/index.d.ts +3 -3
  30. package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
  31. package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
  32. package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
  33. package/dist/plugins/blog/api/index.d.cts +2 -2
  34. package/dist/plugins/blog/api/index.d.mts +2 -2
  35. package/dist/plugins/blog/api/index.d.ts +2 -2
  36. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  37. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  38. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  39. package/dist/plugins/blog/client/index.d.cts +2 -2
  40. package/dist/plugins/blog/client/index.d.mts +2 -2
  41. package/dist/plugins/blog/client/index.d.ts +2 -2
  42. package/dist/plugins/blog/query-keys.d.cts +2 -2
  43. package/dist/plugins/blog/query-keys.d.mts +2 -2
  44. package/dist/plugins/blog/query-keys.d.ts +2 -2
  45. package/dist/shared/{stack.BTStHVTy.d.cts → stack.BGzgFx3R.d.cts} +5 -5
  46. package/dist/shared/{stack.DBH1Bjko.d.ts → stack.C4zspX0T.d.ts} +13 -2
  47. package/dist/shared/{stack.94kN3pEK.d.mts → stack.CjCSDfWy.d.mts} +5 -5
  48. package/dist/shared/{stack.D5b9l24t.d.ts → stack.Clil75lW.d.ts} +35 -35
  49. package/dist/shared/{stack.xAiy2VtO.d.cts → stack.DDQlE2Pm.d.cts} +10 -3
  50. package/dist/shared/{stack.Ce6V7eDj.d.cts → stack.DNw6Hv5o.d.cts} +35 -35
  51. package/dist/shared/{stack.CTneIW0u.d.mts → stack.DhZtP2JZ.d.mts} +35 -35
  52. package/dist/shared/{stack.C-eQN_Jt.d.ts → stack.DlehgNZZ.d.ts} +10 -3
  53. package/dist/shared/{stack.DfrRYOIl.d.ts → stack.Dpg_JjIo.d.ts} +5 -5
  54. package/dist/shared/{stack.B7Mj74BQ.d.mts → stack.Ps3MDhTC.d.mts} +13 -2
  55. package/dist/shared/{stack.C5FZr-jJ.d.mts → stack.tAUeRAtd.d.mts} +10 -3
  56. package/dist/shared/{stack.Dgt3MCtW.d.cts → stack.ymWsP4HZ.d.cts} +13 -2
  57. package/package.json +2 -2
  58. package/src/__tests__/markdown-link-navigation.test.tsx +29 -0
  59. package/src/plugins/ai-chat/__tests__/classnames-overrides.test.tsx +22 -2
  60. package/src/plugins/ai-chat/__tests__/compaction.test.ts +272 -0
  61. package/src/plugins/ai-chat/__tests__/page-widget.test.tsx +103 -1
  62. package/src/plugins/ai-chat/api/compaction.ts +310 -0
  63. package/src/plugins/ai-chat/api/operations.ts +25 -0
  64. package/src/plugins/ai-chat/api/plugin.ts +14 -0
  65. package/src/plugins/ai-chat/client/components/chat-interface.tsx +58 -3
  66. package/src/plugins/ai-chat/client/components/chat-layout.tsx +197 -72
  67. package/src/plugins/ai-chat/client/context-checkpoint.ts +47 -0
  68. package/src/plugins/ai-chat/client/localization/index.ts +5 -0
  69. package/src/plugins/ai-chat/schemas.ts +2 -0
  70. package/dist/shared/{stack.CKc_Bais.d.cts → stack.Csi-4Mgz.d.cts} +7 -7
  71. package/dist/shared/{stack.CKc_Bais.d.mts → stack.Csi-4Mgz.d.mts} +7 -7
  72. package/dist/shared/{stack.CKc_Bais.d.ts → stack.Csi-4Mgz.d.ts} +7 -7
@@ -2,7 +2,7 @@ import * as _btst_stack_plugins_client from '@btst/stack/plugins/client';
2
2
  import { createApiClient } from '@btst/stack/plugins/client';
3
3
  import * as zod from 'zod';
4
4
  import { z } from 'zod';
5
- import { c as createPostSchema, u as updatePostSchema } from './stack.CKc_Bais.cjs';
5
+ import { c as createPostSchema, u as updatePostSchema } from './stack.Csi-4Mgz.cjs';
6
6
  import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.cjs';
7
7
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
8
8
  import { DeepReadonly, OperationContext, OperationErrorContext } from '@btst/stack/plugins/api';
@@ -89,12 +89,6 @@ declare const NextPreviousPostsQuerySchema: z.ZodObject<{
89
89
  date: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
90
90
  }, z.core.$strip>;
91
91
  declare const CreatePostOperationInputSchema: z.ZodObject<{
92
- slug: z.ZodOptional<z.ZodString>;
93
- title: z.ZodString;
94
- content: z.ZodString;
95
- excerpt: z.ZodString;
96
- image: z.ZodOptional<z.ZodString>;
97
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
98
92
  tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
99
93
  name: z.ZodString;
100
94
  }, z.core.$strip>, z.ZodObject<{
@@ -102,6 +96,12 @@ declare const CreatePostOperationInputSchema: z.ZodObject<{
102
96
  name: z.ZodString;
103
97
  slug: z.ZodString;
104
98
  }, z.core.$strip>]>>>>;
99
+ slug: z.ZodOptional<z.ZodString>;
100
+ title: z.ZodString;
101
+ content: z.ZodString;
102
+ excerpt: z.ZodString;
103
+ image: z.ZodOptional<z.ZodString>;
104
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
105
105
  publishedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
106
106
  createdAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
107
107
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
@@ -109,12 +109,6 @@ declare const CreatePostOperationInputSchema: z.ZodObject<{
109
109
  declare const UpdatePostOperationInputSchema: z.ZodObject<{
110
110
  id: z.ZodString;
111
111
  data: z.ZodObject<{
112
- slug: z.ZodString;
113
- title: z.ZodString;
114
- content: z.ZodString;
115
- excerpt: z.ZodString;
116
- image: z.ZodOptional<z.ZodString>;
117
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
118
112
  tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
119
113
  name: z.ZodString;
120
114
  }, z.core.$strip>, z.ZodObject<{
@@ -122,6 +116,12 @@ declare const UpdatePostOperationInputSchema: z.ZodObject<{
122
116
  name: z.ZodString;
123
117
  slug: z.ZodString;
124
118
  }, z.core.$strip>]>>>>;
119
+ slug: z.ZodString;
120
+ title: z.ZodString;
121
+ content: z.ZodString;
122
+ excerpt: z.ZodString;
123
+ image: z.ZodOptional<z.ZodString>;
124
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
125
125
  publishedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
126
126
  createdAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
127
127
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
@@ -386,9 +386,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
386
386
  title: string;
387
387
  content: string;
388
388
  excerpt: string;
389
- slug?: string | undefined;
390
- image?: string | undefined;
391
- published?: boolean | undefined;
392
389
  tags?: ({
393
390
  name: string;
394
391
  } | {
@@ -396,6 +393,9 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
396
393
  name: string;
397
394
  slug: string;
398
395
  })[] | undefined;
396
+ slug?: string | undefined;
397
+ image?: string | undefined;
398
+ published?: boolean | undefined;
399
399
  publishedAt?: unknown;
400
400
  createdAt?: unknown;
401
401
  updatedAt?: unknown;
@@ -403,9 +403,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
403
403
  title: string;
404
404
  content: string;
405
405
  excerpt: string;
406
- slug?: string | undefined;
407
- image?: string | undefined;
408
- published?: boolean | undefined;
409
406
  tags?: ({
410
407
  name: string;
411
408
  } | {
@@ -413,6 +410,9 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
413
410
  name: string;
414
411
  slug: string;
415
412
  })[] | undefined;
413
+ slug?: string | undefined;
414
+ image?: string | undefined;
415
+ published?: boolean | undefined;
416
416
  publishedAt?: unknown;
417
417
  createdAt?: unknown;
418
418
  updatedAt?: unknown;
@@ -448,8 +448,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
448
448
  title: string;
449
449
  content: string;
450
450
  excerpt: string;
451
- image?: string | undefined;
452
- published?: boolean | undefined;
453
451
  tags?: ({
454
452
  name: string;
455
453
  } | {
@@ -457,6 +455,8 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
457
455
  name: string;
458
456
  slug: string;
459
457
  })[] | undefined;
458
+ image?: string | undefined;
459
+ published?: boolean | undefined;
460
460
  publishedAt?: unknown;
461
461
  createdAt?: unknown;
462
462
  updatedAt?: unknown;
@@ -465,8 +465,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
465
465
  title: string;
466
466
  content: string;
467
467
  excerpt: string;
468
- image?: string | undefined;
469
- published?: boolean | undefined;
470
468
  tags?: ({
471
469
  name: string;
472
470
  } | {
@@ -474,6 +472,8 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
474
472
  name: string;
475
473
  slug: string;
476
474
  })[] | undefined;
475
+ image?: string | undefined;
476
+ published?: boolean | undefined;
477
477
  publishedAt?: unknown;
478
478
  createdAt?: unknown;
479
479
  updatedAt?: unknown;
@@ -627,12 +627,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
627
627
  total: number;
628
628
  }, false>;
629
629
  readonly createPost: _btst_stack_plugins_api.Operation<zod.ZodObject<{
630
- slug: zod.ZodOptional<zod.ZodString>;
631
- title: zod.ZodString;
632
- content: zod.ZodString;
633
- excerpt: zod.ZodString;
634
- image: zod.ZodOptional<zod.ZodString>;
635
- published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
636
630
  tags: zod.ZodDefault<zod.ZodOptional<zod.ZodArray<zod.ZodUnion<readonly [zod.ZodObject<{
637
631
  name: zod.ZodString;
638
632
  }, zod_v4_core.$strip>, zod.ZodObject<{
@@ -640,6 +634,12 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
640
634
  name: zod.ZodString;
641
635
  slug: zod.ZodString;
642
636
  }, zod_v4_core.$strip>]>>>>;
637
+ slug: zod.ZodOptional<zod.ZodString>;
638
+ title: zod.ZodString;
639
+ content: zod.ZodString;
640
+ excerpt: zod.ZodString;
641
+ image: zod.ZodOptional<zod.ZodString>;
642
+ published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
643
643
  publishedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
644
644
  createdAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
645
645
  updatedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
@@ -673,12 +673,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
673
673
  readonly updatePost: _btst_stack_plugins_api.Operation<zod.ZodObject<{
674
674
  id: zod.ZodString;
675
675
  data: zod.ZodObject<{
676
- slug: zod.ZodString;
677
- title: zod.ZodString;
678
- content: zod.ZodString;
679
- excerpt: zod.ZodString;
680
- image: zod.ZodOptional<zod.ZodString>;
681
- published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
682
676
  tags: zod.ZodDefault<zod.ZodOptional<zod.ZodArray<zod.ZodUnion<readonly [zod.ZodObject<{
683
677
  name: zod.ZodString;
684
678
  }, zod_v4_core.$strip>, zod.ZodObject<{
@@ -686,6 +680,12 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
686
680
  name: zod.ZodString;
687
681
  slug: zod.ZodString;
688
682
  }, zod_v4_core.$strip>]>>>>;
683
+ slug: zod.ZodString;
684
+ title: zod.ZodString;
685
+ content: zod.ZodString;
686
+ excerpt: zod.ZodString;
687
+ image: zod.ZodOptional<zod.ZodString>;
688
+ published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
689
689
  publishedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
690
690
  createdAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
691
691
  updatedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
@@ -2,7 +2,7 @@ import * as _btst_stack_plugins_client from '@btst/stack/plugins/client';
2
2
  import { createApiClient } from '@btst/stack/plugins/client';
3
3
  import * as zod from 'zod';
4
4
  import { z } from 'zod';
5
- import { c as createPostSchema, u as updatePostSchema } from './stack.CKc_Bais.mjs';
5
+ import { c as createPostSchema, u as updatePostSchema } from './stack.Csi-4Mgz.mjs';
6
6
  import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.mjs';
7
7
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
8
8
  import { DeepReadonly, OperationContext, OperationErrorContext } from '@btst/stack/plugins/api';
@@ -89,12 +89,6 @@ declare const NextPreviousPostsQuerySchema: z.ZodObject<{
89
89
  date: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
90
90
  }, z.core.$strip>;
91
91
  declare const CreatePostOperationInputSchema: z.ZodObject<{
92
- slug: z.ZodOptional<z.ZodString>;
93
- title: z.ZodString;
94
- content: z.ZodString;
95
- excerpt: z.ZodString;
96
- image: z.ZodOptional<z.ZodString>;
97
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
98
92
  tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
99
93
  name: z.ZodString;
100
94
  }, z.core.$strip>, z.ZodObject<{
@@ -102,6 +96,12 @@ declare const CreatePostOperationInputSchema: z.ZodObject<{
102
96
  name: z.ZodString;
103
97
  slug: z.ZodString;
104
98
  }, z.core.$strip>]>>>>;
99
+ slug: z.ZodOptional<z.ZodString>;
100
+ title: z.ZodString;
101
+ content: z.ZodString;
102
+ excerpt: z.ZodString;
103
+ image: z.ZodOptional<z.ZodString>;
104
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
105
105
  publishedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
106
106
  createdAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
107
107
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
@@ -109,12 +109,6 @@ declare const CreatePostOperationInputSchema: z.ZodObject<{
109
109
  declare const UpdatePostOperationInputSchema: z.ZodObject<{
110
110
  id: z.ZodString;
111
111
  data: z.ZodObject<{
112
- slug: z.ZodString;
113
- title: z.ZodString;
114
- content: z.ZodString;
115
- excerpt: z.ZodString;
116
- image: z.ZodOptional<z.ZodString>;
117
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
118
112
  tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
119
113
  name: z.ZodString;
120
114
  }, z.core.$strip>, z.ZodObject<{
@@ -122,6 +116,12 @@ declare const UpdatePostOperationInputSchema: z.ZodObject<{
122
116
  name: z.ZodString;
123
117
  slug: z.ZodString;
124
118
  }, z.core.$strip>]>>>>;
119
+ slug: z.ZodString;
120
+ title: z.ZodString;
121
+ content: z.ZodString;
122
+ excerpt: z.ZodString;
123
+ image: z.ZodOptional<z.ZodString>;
124
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
125
125
  publishedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
126
126
  createdAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
127
127
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>>;
@@ -386,9 +386,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
386
386
  title: string;
387
387
  content: string;
388
388
  excerpt: string;
389
- slug?: string | undefined;
390
- image?: string | undefined;
391
- published?: boolean | undefined;
392
389
  tags?: ({
393
390
  name: string;
394
391
  } | {
@@ -396,6 +393,9 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
396
393
  name: string;
397
394
  slug: string;
398
395
  })[] | undefined;
396
+ slug?: string | undefined;
397
+ image?: string | undefined;
398
+ published?: boolean | undefined;
399
399
  publishedAt?: unknown;
400
400
  createdAt?: unknown;
401
401
  updatedAt?: unknown;
@@ -403,9 +403,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
403
403
  title: string;
404
404
  content: string;
405
405
  excerpt: string;
406
- slug?: string | undefined;
407
- image?: string | undefined;
408
- published?: boolean | undefined;
409
406
  tags?: ({
410
407
  name: string;
411
408
  } | {
@@ -413,6 +410,9 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
413
410
  name: string;
414
411
  slug: string;
415
412
  })[] | undefined;
413
+ slug?: string | undefined;
414
+ image?: string | undefined;
415
+ published?: boolean | undefined;
416
416
  publishedAt?: unknown;
417
417
  createdAt?: unknown;
418
418
  updatedAt?: unknown;
@@ -448,8 +448,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
448
448
  title: string;
449
449
  content: string;
450
450
  excerpt: string;
451
- image?: string | undefined;
452
- published?: boolean | undefined;
453
451
  tags?: ({
454
452
  name: string;
455
453
  } | {
@@ -457,6 +455,8 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
457
455
  name: string;
458
456
  slug: string;
459
457
  })[] | undefined;
458
+ image?: string | undefined;
459
+ published?: boolean | undefined;
460
460
  publishedAt?: unknown;
461
461
  createdAt?: unknown;
462
462
  updatedAt?: unknown;
@@ -465,8 +465,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
465
465
  title: string;
466
466
  content: string;
467
467
  excerpt: string;
468
- image?: string | undefined;
469
- published?: boolean | undefined;
470
468
  tags?: ({
471
469
  name: string;
472
470
  } | {
@@ -474,6 +472,8 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
474
472
  name: string;
475
473
  slug: string;
476
474
  })[] | undefined;
475
+ image?: string | undefined;
476
+ published?: boolean | undefined;
477
477
  publishedAt?: unknown;
478
478
  createdAt?: unknown;
479
479
  updatedAt?: unknown;
@@ -627,12 +627,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
627
627
  total: number;
628
628
  }, false>;
629
629
  readonly createPost: _btst_stack_plugins_api.Operation<zod.ZodObject<{
630
- slug: zod.ZodOptional<zod.ZodString>;
631
- title: zod.ZodString;
632
- content: zod.ZodString;
633
- excerpt: zod.ZodString;
634
- image: zod.ZodOptional<zod.ZodString>;
635
- published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
636
630
  tags: zod.ZodDefault<zod.ZodOptional<zod.ZodArray<zod.ZodUnion<readonly [zod.ZodObject<{
637
631
  name: zod.ZodString;
638
632
  }, zod_v4_core.$strip>, zod.ZodObject<{
@@ -640,6 +634,12 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
640
634
  name: zod.ZodString;
641
635
  slug: zod.ZodString;
642
636
  }, zod_v4_core.$strip>]>>>>;
637
+ slug: zod.ZodOptional<zod.ZodString>;
638
+ title: zod.ZodString;
639
+ content: zod.ZodString;
640
+ excerpt: zod.ZodString;
641
+ image: zod.ZodOptional<zod.ZodString>;
642
+ published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
643
643
  publishedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
644
644
  createdAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
645
645
  updatedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
@@ -673,12 +673,6 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
673
673
  readonly updatePost: _btst_stack_plugins_api.Operation<zod.ZodObject<{
674
674
  id: zod.ZodString;
675
675
  data: zod.ZodObject<{
676
- slug: zod.ZodString;
677
- title: zod.ZodString;
678
- content: zod.ZodString;
679
- excerpt: zod.ZodString;
680
- image: zod.ZodOptional<zod.ZodString>;
681
- published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
682
676
  tags: zod.ZodDefault<zod.ZodOptional<zod.ZodArray<zod.ZodUnion<readonly [zod.ZodObject<{
683
677
  name: zod.ZodString;
684
678
  }, zod_v4_core.$strip>, zod.ZodObject<{
@@ -686,6 +680,12 @@ declare const blogBackendPlugin: (options?: BlogBackendOptions) => _btst_stack_p
686
680
  name: zod.ZodString;
687
681
  slug: zod.ZodString;
688
682
  }, zod_v4_core.$strip>]>>>>;
683
+ slug: zod.ZodString;
684
+ title: zod.ZodString;
685
+ content: zod.ZodString;
686
+ excerpt: zod.ZodString;
687
+ image: zod.ZodOptional<zod.ZodString>;
688
+ published: zod.ZodDefault<zod.ZodOptional<zod.ZodBoolean>>;
689
689
  publishedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
690
690
  createdAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
691
691
  updatedAt: zod.ZodOptional<zod.ZodPipe<zod.ZodCoercedDate<unknown>, zod.ZodTransform<string, Date>>>;
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { UIMessage } from 'ai';
3
- import { ComponentType, CSSProperties, FormEvent } from 'react';
3
+ import { ComponentType, CSSProperties, ReactNode, FormEvent } from 'react';
4
4
  import { PageAIContextConfig } from '../plugins/ai-chat/client/context/page-ai-context.js';
5
5
 
6
6
  /** Content-free usage events. No prompts, answers, page descriptions, or tool outputs. */
@@ -43,6 +43,7 @@ interface AiChatLocalization {
43
43
  CHAT_SEND_BUTTON: string;
44
44
  CHAT_EMPTY_STATE: string;
45
45
  CHAT_LOADING: string;
46
+ CHAT_COMPACTING?: string;
46
47
  CHAT_ERROR: string;
47
48
  CHAT_RETRY: string;
48
49
  CHAT_GENERIC_ERROR_TITLE: string;
@@ -101,6 +102,8 @@ interface AiChatLocalization {
101
102
  A11Y_CHAT_TITLE: string;
102
103
  A11Y_CLEAR_CHAT: string;
103
104
  A11Y_CLOSE_CHAT: string;
105
+ A11Y_EXPAND_CHAT: string;
106
+ A11Y_COLLAPSE_CHAT: string;
104
107
  A11Y_OPEN_CHAT: string;
105
108
  A11Y_DISMISS_CHAT_TIP: string;
106
109
  PAGE_CONTENT_READING: string;
@@ -317,10 +320,12 @@ interface ChatLayoutBaseProps {
317
320
  interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
318
321
  /** Widget mode: compact embeddable panel with a floating trigger button */
319
322
  layout: "widget";
320
- /** Height of the widget panel. Default: `"min(600px, calc(100dvh - 112px))"` */
323
+ /** Height of the widget panel. Default: `"min(640px, calc(100dvh - 112px))"` */
321
324
  widgetHeight?: string | number;
322
- /** Width of the widget panel. Default: `"min(380px, calc(100vw - 32px))"` */
325
+ /** Width of the widget panel. Default: `"min(440px, calc(100vw - 32px))"` */
323
326
  widgetWidth?: string | number;
327
+ /** Show a button to expand the widget to the viewport. Default: false. Escape restores the compact size. */
328
+ expandable?: boolean;
324
329
  /** Fix the widget to the bottom right. Default: false (embedded). Override offsets with className or style. */
325
330
  floating?: boolean;
326
331
  /** Optional dismissible introduction shown while the widget is closed. */
@@ -341,6 +346,8 @@ interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
341
346
  * so that the built-in button does not appear alongside your own UI.
342
347
  */
343
348
  showTrigger?: boolean;
349
+ /** Icon shown in the closed widget's trigger button. Defaults to Sparkles. */
350
+ triggerIcon?: ReactNode;
344
351
  }
345
352
  interface ChatLayoutFullProps extends ChatLayoutBaseProps {
346
353
  /** Full-page mode with sidebar navigation (default) */
@@ -2,7 +2,7 @@ import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { z } from 'zod';
3
3
  import { ResourceFormConfig, ResourceFormResult } from '@btst/stack/plugins/client/hooks';
4
4
  import { S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.js';
5
- import { c as createPostSchema, u as updatePostSchema } from './stack.CKc_Bais.js';
5
+ import { c as createPostSchema, u as updatePostSchema } from './stack.Csi-4Mgz.js';
6
6
 
7
7
  /**
8
8
  * Options for the usePosts hook
@@ -136,10 +136,6 @@ declare function useSuspenseTags(): {
136
136
  declare function usePostForm<TValues>(config: ResourceFormConfig<TValues, SerializedPost | null, SerializedPost | null>): ResourceFormResult<TValues, SerializedPost | null, SerializedPost | null>;
137
137
  /** Create a new post */
138
138
  declare function useCreatePost(): _tanstack_react_query.UseMutationResult<SerializedPost | null, Error, {
139
- title: string;
140
- content: string;
141
- excerpt: string;
142
- published: boolean;
143
139
  tags: ({
144
140
  name: string;
145
141
  } | {
@@ -147,6 +143,10 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
147
143
  name: string;
148
144
  slug: string;
149
145
  })[];
146
+ title: string;
147
+ content: string;
148
+ excerpt: string;
149
+ published: boolean;
150
150
  slug?: string | undefined;
151
151
  publishedAt?: Date | undefined;
152
152
  createdAt?: Date | undefined;
@@ -55,6 +55,12 @@ interface AiChatPageContentConfig {
55
55
  description?: string;
56
56
  }
57
57
 
58
+ /** Opt-in context compaction for public, text-only conversations. */
59
+ interface AiChatCompactionConfig {
60
+ /** Actual context window. Configure the model's output limit at or below 20% of this. */
61
+ contextWindowTokens: number;
62
+ }
63
+
58
64
  type AiChatAccess = "authorized" | "public";
59
65
  /** Runtime input for one conversation operation. */
60
66
  declare const ConversationOperationInputSchema: z.ZodObject<{
@@ -85,6 +91,7 @@ type ChatOperationInput = {
85
91
  readonly metadata?: any;
86
92
  })[];
87
93
  readonly conversationId?: string;
94
+ readonly contextSummary?: string;
88
95
  readonly model?: string;
89
96
  readonly pageContext?: string;
90
97
  readonly availableTools?: readonly string[];
@@ -221,6 +228,8 @@ interface AiChatBackendConfig {
221
228
  */
222
229
  access?: AiChatAccess;
223
230
  systemPrompt?: string;
231
+ /** Automatically summarize older context in public text chats; off by default. */
232
+ compaction?: AiChatCompactionConfig;
224
233
  tools?: Record<string, Tool>;
225
234
  /** Enable the standard readPage server tool for full page content. Reserves the readPage tool name. */
226
235
  pageContent?: AiChatPageContentConfig;
@@ -253,6 +262,7 @@ declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record
253
262
  metadata?: any;
254
263
  })[];
255
264
  conversationId?: string | undefined;
265
+ contextSummary?: string | undefined;
256
266
  model?: string | undefined;
257
267
  pageContext?: string | undefined;
258
268
  availableTools?: string[] | undefined;
@@ -273,6 +283,7 @@ declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record
273
283
  metadata?: any;
274
284
  })[];
275
285
  conversationId?: string | undefined;
286
+ contextSummary?: string | undefined;
276
287
  model?: string | undefined;
277
288
  pageContext?: string | undefined;
278
289
  availableTools?: string[] | undefined;
@@ -519,5 +530,5 @@ declare function createAiChatQueryKeys(client: ReturnType<typeof createApiClient
519
530
  }>;
520
531
  type AiChatQueryKeys = ReturnType<typeof createAiChatQueryKeys>;
521
532
 
522
- export { UpdateConversationOperationInputSchema as U, aiChatIdentityKey as d, aiChatResources as e, createAiChatQueryKeys as f, aiChatBackendPlugin as i, AI_CHAT_OPERATION_INVENTORY as o, AI_CHAT_RAW_ESCAPE_HATCH_INVENTORY as p, AiChatOperationError as q, ChatOperationInputSchema as r, ConversationOperationInputSchema as s };
523
- export type { AiChatIdentityPartition as A, ConversationWithMessages as C, Message as M, RenameConversationInput as R, SerializedConversation as S, SerializedMessage as a, CreateConversationInput as b, Conversation as c, AiChatQueryKeys as g, AiChatBackendConfig as h, AiChatApiRouter as j, AiChatPageContentConfig as k, AiChatAccess as l, AiChatBackendHooks as m, ChatApiContext as n };
533
+ export { UpdateConversationOperationInputSchema as U, aiChatIdentityKey as d, aiChatResources as e, createAiChatQueryKeys as f, aiChatBackendPlugin as i, AI_CHAT_OPERATION_INVENTORY as p, AI_CHAT_RAW_ESCAPE_HATCH_INVENTORY as q, AiChatOperationError as r, ChatOperationInputSchema as s, ConversationOperationInputSchema as t };
534
+ export type { AiChatIdentityPartition as A, ConversationWithMessages as C, Message as M, RenameConversationInput as R, SerializedConversation as S, SerializedMessage as a, CreateConversationInput as b, Conversation as c, AiChatQueryKeys as g, AiChatBackendConfig as h, AiChatApiRouter as j, AiChatCompactionConfig as k, AiChatPageContentConfig as l, AiChatAccess as m, AiChatBackendHooks as n, ChatApiContext as o };
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { UIMessage } from 'ai';
3
- import { ComponentType, CSSProperties, FormEvent } from 'react';
3
+ import { ComponentType, CSSProperties, ReactNode, FormEvent } from 'react';
4
4
  import { PageAIContextConfig } from '../plugins/ai-chat/client/context/page-ai-context.mjs';
5
5
 
6
6
  /** Content-free usage events. No prompts, answers, page descriptions, or tool outputs. */
@@ -43,6 +43,7 @@ interface AiChatLocalization {
43
43
  CHAT_SEND_BUTTON: string;
44
44
  CHAT_EMPTY_STATE: string;
45
45
  CHAT_LOADING: string;
46
+ CHAT_COMPACTING?: string;
46
47
  CHAT_ERROR: string;
47
48
  CHAT_RETRY: string;
48
49
  CHAT_GENERIC_ERROR_TITLE: string;
@@ -101,6 +102,8 @@ interface AiChatLocalization {
101
102
  A11Y_CHAT_TITLE: string;
102
103
  A11Y_CLEAR_CHAT: string;
103
104
  A11Y_CLOSE_CHAT: string;
105
+ A11Y_EXPAND_CHAT: string;
106
+ A11Y_COLLAPSE_CHAT: string;
104
107
  A11Y_OPEN_CHAT: string;
105
108
  A11Y_DISMISS_CHAT_TIP: string;
106
109
  PAGE_CONTENT_READING: string;
@@ -317,10 +320,12 @@ interface ChatLayoutBaseProps {
317
320
  interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
318
321
  /** Widget mode: compact embeddable panel with a floating trigger button */
319
322
  layout: "widget";
320
- /** Height of the widget panel. Default: `"min(600px, calc(100dvh - 112px))"` */
323
+ /** Height of the widget panel. Default: `"min(640px, calc(100dvh - 112px))"` */
321
324
  widgetHeight?: string | number;
322
- /** Width of the widget panel. Default: `"min(380px, calc(100vw - 32px))"` */
325
+ /** Width of the widget panel. Default: `"min(440px, calc(100vw - 32px))"` */
323
326
  widgetWidth?: string | number;
327
+ /** Show a button to expand the widget to the viewport. Default: false. Escape restores the compact size. */
328
+ expandable?: boolean;
324
329
  /** Fix the widget to the bottom right. Default: false (embedded). Override offsets with className or style. */
325
330
  floating?: boolean;
326
331
  /** Optional dismissible introduction shown while the widget is closed. */
@@ -341,6 +346,8 @@ interface ChatLayoutWidgetProps extends ChatLayoutBaseProps {
341
346
  * so that the built-in button does not appear alongside your own UI.
342
347
  */
343
348
  showTrigger?: boolean;
349
+ /** Icon shown in the closed widget's trigger button. Defaults to Sparkles. */
350
+ triggerIcon?: ReactNode;
344
351
  }
345
352
  interface ChatLayoutFullProps extends ChatLayoutBaseProps {
346
353
  /** Full-page mode with sidebar navigation (default) */
@@ -55,6 +55,12 @@ interface AiChatPageContentConfig {
55
55
  description?: string;
56
56
  }
57
57
 
58
+ /** Opt-in context compaction for public, text-only conversations. */
59
+ interface AiChatCompactionConfig {
60
+ /** Actual context window. Configure the model's output limit at or below 20% of this. */
61
+ contextWindowTokens: number;
62
+ }
63
+
58
64
  type AiChatAccess = "authorized" | "public";
59
65
  /** Runtime input for one conversation operation. */
60
66
  declare const ConversationOperationInputSchema: z.ZodObject<{
@@ -85,6 +91,7 @@ type ChatOperationInput = {
85
91
  readonly metadata?: any;
86
92
  })[];
87
93
  readonly conversationId?: string;
94
+ readonly contextSummary?: string;
88
95
  readonly model?: string;
89
96
  readonly pageContext?: string;
90
97
  readonly availableTools?: readonly string[];
@@ -221,6 +228,8 @@ interface AiChatBackendConfig {
221
228
  */
222
229
  access?: AiChatAccess;
223
230
  systemPrompt?: string;
231
+ /** Automatically summarize older context in public text chats; off by default. */
232
+ compaction?: AiChatCompactionConfig;
224
233
  tools?: Record<string, Tool>;
225
234
  /** Enable the standard readPage server tool for full page content. Reserves the readPage tool name. */
226
235
  pageContent?: AiChatPageContentConfig;
@@ -253,6 +262,7 @@ declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record
253
262
  metadata?: any;
254
263
  })[];
255
264
  conversationId?: string | undefined;
265
+ contextSummary?: string | undefined;
256
266
  model?: string | undefined;
257
267
  pageContext?: string | undefined;
258
268
  availableTools?: string[] | undefined;
@@ -273,6 +283,7 @@ declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record
273
283
  metadata?: any;
274
284
  })[];
275
285
  conversationId?: string | undefined;
286
+ contextSummary?: string | undefined;
276
287
  model?: string | undefined;
277
288
  pageContext?: string | undefined;
278
289
  availableTools?: string[] | undefined;
@@ -519,5 +530,5 @@ declare function createAiChatQueryKeys(client: ReturnType<typeof createApiClient
519
530
  }>;
520
531
  type AiChatQueryKeys = ReturnType<typeof createAiChatQueryKeys>;
521
532
 
522
- export { UpdateConversationOperationInputSchema as U, aiChatIdentityKey as d, aiChatResources as e, createAiChatQueryKeys as f, aiChatBackendPlugin as i, AI_CHAT_OPERATION_INVENTORY as o, AI_CHAT_RAW_ESCAPE_HATCH_INVENTORY as p, AiChatOperationError as q, ChatOperationInputSchema as r, ConversationOperationInputSchema as s };
523
- export type { AiChatIdentityPartition as A, ConversationWithMessages as C, Message as M, RenameConversationInput as R, SerializedConversation as S, SerializedMessage as a, CreateConversationInput as b, Conversation as c, AiChatQueryKeys as g, AiChatBackendConfig as h, AiChatApiRouter as j, AiChatPageContentConfig as k, AiChatAccess as l, AiChatBackendHooks as m, ChatApiContext as n };
533
+ export { UpdateConversationOperationInputSchema as U, aiChatIdentityKey as d, aiChatResources as e, createAiChatQueryKeys as f, aiChatBackendPlugin as i, AI_CHAT_OPERATION_INVENTORY as p, AI_CHAT_RAW_ESCAPE_HATCH_INVENTORY as q, AiChatOperationError as r, ChatOperationInputSchema as s, ConversationOperationInputSchema as t };
534
+ export type { AiChatIdentityPartition as A, ConversationWithMessages as C, Message as M, RenameConversationInput as R, SerializedConversation as S, SerializedMessage as a, CreateConversationInput as b, Conversation as c, AiChatQueryKeys as g, AiChatBackendConfig as h, AiChatApiRouter as j, AiChatCompactionConfig as k, AiChatPageContentConfig as l, AiChatAccess as m, AiChatBackendHooks as n, ChatApiContext as o };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btst/stack",
3
- "version": "4.2.0",
3
+ "version": "4.4.0",
4
4
  "description": "A composable, plugin-based library for building full-stack applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1142,7 +1142,7 @@
1142
1142
  "@better-fetch/fetch": "1.3.2",
1143
1143
  "@btst/adapter-memory": "3.0.0",
1144
1144
  "@btst/yar": "1.3.2",
1145
- "@tanstack/react-router": "1.168.10",
1145
+ "@tanstack/react-router": "1.170.41",
1146
1146
  "@types/react": "^19.0.0",
1147
1147
  "@types/react-dom": "^19.0.0",
1148
1148
  "@types/slug": "^5.0.9",
@@ -0,0 +1,29 @@
1
+ import { renderToStaticMarkup } from "react-dom/server";
2
+ import { describe, expect, it } from "vitest";
3
+ import { MarkdownContent } from "@workspace/ui/components/markdown-content";
4
+
5
+ describe("markdown link navigation", () => {
6
+ it("uses the supplied link component for body links and heading anchors", () => {
7
+ const html = renderToStaticMarkup(
8
+ <MarkdownContent
9
+ markdown={
10
+ "## Evidence\n\n[Profile](/compounds/one) and [Study](https://example.org/study)."
11
+ }
12
+ LinkComponent={(props) => (
13
+ <a {...props} target="_blank" rel="noopener" />
14
+ )}
15
+ />,
16
+ );
17
+ const anchors = html.match(/<a\b[^>]*>/g)!;
18
+ expect(anchors).toHaveLength(3);
19
+ for (const anchor of anchors) expect(anchor).toContain('target="_blank"');
20
+ expect(html).toContain('href="#evidence"');
21
+ });
22
+ it("retains ordinary anchors when navigation is not overridden", () => {
23
+ const html = renderToStaticMarkup(
24
+ <MarkdownContent markdown={"## Evidence\n\n[Profile](/compounds/one)"} />,
25
+ );
26
+ expect(html).not.toContain('target="_blank"');
27
+ expect(html).toContain('href="/compounds/one"');
28
+ });
29
+ });