@carlonicora/nextjs-jsonapi 3.12.0 → 3.13.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 (143) hide show
  1. package/dist/{AssistantInterface-DwdBzS9f.d.ts → AssistantInterface-RvZzlcA_.d.ts} +2 -0
  2. package/dist/{AssistantInterface-DMh-zApr.d.mts → AssistantInterface-jL56dyNc.d.mts} +2 -0
  3. package/dist/{AssistantMessageInterface-0zyVingf.d.ts → AssistantMessageInterface-CuaMDs2i.d.ts} +1 -1
  4. package/dist/{AssistantMessageInterface-ddyG114R.d.mts → AssistantMessageInterface-Du3ShThp.d.mts} +1 -1
  5. package/dist/{BlockNoteEditor-6G27S6P3.js → BlockNoteEditor-CFVSHS46.js} +19 -19
  6. package/dist/{BlockNoteEditor-6G27S6P3.js.map → BlockNoteEditor-CFVSHS46.js.map} +1 -1
  7. package/dist/{BlockNoteEditor-CR5KH4AI.mjs → BlockNoteEditor-SERY337S.mjs} +4 -4
  8. package/dist/{BlockNoteViewer-5MITJ7AD.js → BlockNoteViewer-CWFPYYIU.js} +3 -3
  9. package/dist/{BlockNoteViewer-5MITJ7AD.js.map → BlockNoteViewer-CWFPYYIU.js.map} +1 -1
  10. package/dist/{BlockNoteViewer-NJKFUNXP.mjs → BlockNoteViewer-P2VKEFRN.mjs} +2 -2
  11. package/dist/{ai-connection.module-28f-hux0.d.mts → HandbookSectionInterface-BOxIdBdd.d.mts} +54 -1
  12. package/dist/{ai-connection.module-Bqwh_DnR.d.ts → HandbookSectionInterface-CAXxbDw0.d.ts} +54 -1
  13. package/dist/{auth.interface-B6ZQLGjS.d.ts → auth.interface-BC1jp_ni.d.ts} +1 -1
  14. package/dist/{auth.interface-jYD8Gc4P.d.mts → auth.interface-dR2-6gPM.d.mts} +1 -1
  15. package/dist/billing/index.js +401 -401
  16. package/dist/billing/index.mjs +3 -3
  17. package/dist/{chunk-L7DZSTFU.js → chunk-IB7DTXWG.js} +846 -129
  18. package/dist/chunk-IB7DTXWG.js.map +1 -0
  19. package/dist/{chunk-OKGGYCO5.js → chunk-LVE3BJ6K.js} +2088 -1134
  20. package/dist/chunk-LVE3BJ6K.js.map +1 -0
  21. package/dist/{chunk-Q2BREXH3.mjs → chunk-OSFYCSTW.mjs} +724 -7
  22. package/dist/chunk-OSFYCSTW.mjs.map +1 -0
  23. package/dist/{chunk-JEGL7KHK.mjs → chunk-UQXE3SME.mjs} +2081 -1127
  24. package/dist/chunk-UQXE3SME.mjs.map +1 -0
  25. package/dist/{chunk-HVNEWDRF.mjs → chunk-VZKJIAND.mjs} +2 -2
  26. package/dist/{chunk-4ETVCRQD.js → chunk-XH4IURUD.js} +7 -7
  27. package/dist/{chunk-4ETVCRQD.js.map → chunk-XH4IURUD.js.map} +1 -1
  28. package/dist/client/index.d.mts +2 -2
  29. package/dist/client/index.d.ts +2 -2
  30. package/dist/client/index.js +4 -4
  31. package/dist/client/index.mjs +3 -3
  32. package/dist/components/index.d.mts +258 -7
  33. package/dist/components/index.d.ts +258 -7
  34. package/dist/components/index.js +30 -4
  35. package/dist/components/index.js.map +1 -1
  36. package/dist/components/index.mjs +29 -3
  37. package/dist/contexts/index.d.mts +17 -5
  38. package/dist/contexts/index.d.ts +17 -5
  39. package/dist/contexts/index.js +4 -4
  40. package/dist/contexts/index.mjs +3 -3
  41. package/dist/core/index.d.mts +491 -11
  42. package/dist/core/index.d.ts +491 -11
  43. package/dist/core/index.js +38 -2
  44. package/dist/core/index.js.map +1 -1
  45. package/dist/core/index.mjs +37 -1
  46. package/dist/features/help/index.js +37 -37
  47. package/dist/features/help/index.mjs +3 -3
  48. package/dist/features/tokenusage/index.js +101 -101
  49. package/dist/features/tokenusage/index.mjs +3 -3
  50. package/dist/index.d.mts +7 -7
  51. package/dist/index.d.ts +7 -7
  52. package/dist/index.js +39 -3
  53. package/dist/index.js.map +1 -1
  54. package/dist/index.mjs +38 -2
  55. package/dist/{notification.interface-DYF56CtE.d.ts → notification.interface-CjzV_KII.d.ts} +1 -1
  56. package/dist/{notification.interface-BWOCvKRP.d.mts → notification.interface-MnRt1Tjm.d.mts} +1 -1
  57. package/dist/{s3.service-D_dswjgz.d.mts → s3.service-C0Yq2Sx3.d.mts} +2 -2
  58. package/dist/{s3.service-DserU9VK.d.ts → s3.service-CUGarZs3.d.ts} +2 -2
  59. package/dist/server/index.d.mts +3 -3
  60. package/dist/server/index.d.ts +3 -3
  61. package/dist/server/index.js +3 -3
  62. package/dist/server/index.mjs +1 -1
  63. package/dist/{useSocket-BZG9oX-L.d.mts → useSocket-BcH7l7B8.d.mts} +1 -1
  64. package/dist/{useSocket-CiyTtYFj.d.ts → useSocket-DCZd_eJk.d.ts} +1 -1
  65. package/package.json +1 -1
  66. package/src/components/containers/ReactMarkdownContainer.tsx +61 -11
  67. package/src/components/index.ts +1 -0
  68. package/src/core/index.ts +5 -0
  69. package/src/core/registry/ModuleRegistry.ts +4 -0
  70. package/src/features/assistant/components/parts/AssistantComposer.tsx +22 -3
  71. package/src/features/assistant/components/parts/AssistantSidebar.tsx +13 -3
  72. package/src/features/assistant/components/parts/AssistantThreadHeader.tsx +10 -3
  73. package/src/features/assistant/contexts/AssistantContext.tsx +30 -3
  74. package/src/features/assistant/contexts/__tests__/AssistantContext.spec.tsx +32 -0
  75. package/src/features/assistant/data/Assistant.ts +2 -0
  76. package/src/features/assistant/data/AssistantInterface.ts +2 -0
  77. package/src/features/assistant/data/AssistantService.ts +4 -0
  78. package/src/features/assistant-message/components/parts/MessageSourcesContainer.tsx +5 -1
  79. package/src/features/assistant-message/data/AssistantMessage.ts +27 -2
  80. package/src/features/content/data/content.interface.ts +1 -1
  81. package/src/features/handbook/HandbookPageModule.ts +41 -0
  82. package/src/features/handbook/HandbookSectionModule.ts +35 -0
  83. package/src/features/handbook/HandbookThreadMessageModule.ts +21 -0
  84. package/src/features/handbook/HandbookThreadModule.ts +29 -0
  85. package/src/features/handbook/components/containers/HandbookAdminContainer.tsx +17 -0
  86. package/src/features/handbook/components/containers/HandbookAskContainer.tsx +142 -0
  87. package/src/features/handbook/components/containers/HandbookAskSheet.tsx +149 -0
  88. package/src/features/handbook/components/containers/HandbookPageContainer.tsx +143 -0
  89. package/src/features/handbook/components/containers/__tests__/HandbookAskContainer.spec.tsx +268 -0
  90. package/src/features/handbook/components/containers/__tests__/HandbookAskSheet.spec.tsx +143 -0
  91. package/src/features/handbook/components/containers/__tests__/HandbookPageContainer.spec.tsx +288 -0
  92. package/src/features/handbook/components/details/HandbookPageDetails.tsx +27 -0
  93. package/src/features/handbook/components/details/HandbookPageNeighbours.tsx +72 -0
  94. package/src/features/handbook/components/details/HandbookPageToc.tsx +165 -0
  95. package/src/features/handbook/components/forms/HandbookSyncButton.tsx +43 -0
  96. package/src/features/handbook/components/forms/__tests__/HandbookSyncButton.spec.tsx +42 -0
  97. package/src/features/handbook/components/index.ts +12 -0
  98. package/src/features/handbook/components/lists/HandbookContents.tsx +196 -0
  99. package/src/features/handbook/components/lists/HandbookSectionGroup.tsx +153 -0
  100. package/src/features/handbook/components/lists/__tests__/HandbookContents.spec.tsx +247 -0
  101. package/src/features/handbook/components/parts/HandbookIndexStatus.tsx +62 -0
  102. package/src/features/handbook/components/parts/HandbookPageNavigator.tsx +143 -0
  103. package/src/features/handbook/contexts/HandbookContext.tsx +109 -0
  104. package/src/features/handbook/contexts/__tests__/HandbookContext.spec.tsx +131 -0
  105. package/src/features/handbook/data/HandbookPage.spec.ts +136 -0
  106. package/src/features/handbook/data/HandbookPage.ts +99 -0
  107. package/src/features/handbook/data/HandbookPageFields.ts +31 -0
  108. package/src/features/handbook/data/HandbookPageInput.ts +8 -0
  109. package/src/features/handbook/data/HandbookPageInterface.ts +29 -0
  110. package/src/features/handbook/data/HandbookPageService.ts +60 -0
  111. package/src/features/handbook/data/HandbookSection.spec.ts +58 -0
  112. package/src/features/handbook/data/HandbookSection.ts +73 -0
  113. package/src/features/handbook/data/HandbookSectionInput.ts +12 -0
  114. package/src/features/handbook/data/HandbookSectionInterface.ts +26 -0
  115. package/src/features/handbook/data/HandbookSectionService.ts +26 -0
  116. package/src/features/handbook/data/HandbookThread.ts +114 -0
  117. package/src/features/handbook/data/HandbookThreadInterface.ts +31 -0
  118. package/src/features/handbook/data/HandbookThreadMessage.ts +144 -0
  119. package/src/features/handbook/data/HandbookThreadMessageInterface.ts +35 -0
  120. package/src/features/handbook/data/HandbookThreadMessageService.ts +30 -0
  121. package/src/features/handbook/data/HandbookThreadService.ts +86 -0
  122. package/src/features/handbook/data/__tests__/HandbookThreadService.spec.ts +112 -0
  123. package/src/features/handbook/data/handbookDisplay.spec.ts +92 -0
  124. package/src/features/handbook/data/handbookDisplay.ts +55 -0
  125. package/src/features/handbook/data/index.ts +16 -0
  126. package/src/features/handbook/hooks/__tests__/useHandbookAsk.spec.ts +198 -0
  127. package/src/features/handbook/hooks/useHandbookAsk.ts +213 -0
  128. package/src/features/handbook/i18n-keys.ts +46 -0
  129. package/src/features/handbook/index.ts +7 -0
  130. package/src/features/how-to/components/forms/HowToEditor.tsx +0 -1
  131. package/src/features/how-to/components/forms/HowToReindexButton.spec.tsx +84 -0
  132. package/src/features/how-to/components/forms/HowToReindexButton.tsx +46 -0
  133. package/src/features/how-to/components/index.ts +1 -0
  134. package/src/features/how-to/components/lists/HowToList.tsx +5 -1
  135. package/src/features/how-to/data/HowTo.spec.ts +61 -1
  136. package/src/features/how-to/data/HowToService.ts +13 -0
  137. package/dist/chunk-JEGL7KHK.mjs.map +0 -1
  138. package/dist/chunk-L7DZSTFU.js.map +0 -1
  139. package/dist/chunk-OKGGYCO5.js.map +0 -1
  140. package/dist/chunk-Q2BREXH3.mjs.map +0 -1
  141. /package/dist/{BlockNoteEditor-CR5KH4AI.mjs.map → BlockNoteEditor-SERY337S.mjs.map} +0 -0
  142. /package/dist/{BlockNoteViewer-NJKFUNXP.mjs.map → BlockNoteViewer-P2VKEFRN.mjs.map} +0 -0
  143. /package/dist/{chunk-HVNEWDRF.mjs.map → chunk-VZKJIAND.mjs.map} +0 -0
@@ -5922,6 +5922,18 @@ var HowToService = class extends AbstractService {
5922
5922
  endpoint: new EndpointCreator({ endpoint: Modules.HowTo, id: params.howToId }).generate()
5923
5923
  });
5924
5924
  }
5925
+ /**
5926
+ * POST /howtos/reindex — re-queues every guide for chunking. Replies 204.
5927
+ * Chunking otherwise only happens on create and update, so a guide that was
5928
+ * never chunked stays invisible to help-mode retrieval with no way back.
5929
+ */
5930
+ static async reindex() {
5931
+ await this.callApi({
5932
+ type: Modules.HowTo,
5933
+ method: "POST" /* POST */,
5934
+ endpoint: new EndpointCreator({ endpoint: Modules.HowTo, id: "reindex" }).generate()
5935
+ });
5936
+ }
5925
5937
  static async findPublished(params = {}) {
5926
5938
  const endpoint = new EndpointCreator({ endpoint: `public/${Modules.HowTo.name}` });
5927
5939
  if (params.howToType) endpoint.addAdditionalParam("type", params.howToType);
@@ -5980,6 +5992,675 @@ var HowToService = class extends AbstractService {
5980
5992
  }
5981
5993
  };
5982
5994
 
5995
+ // src/features/handbook/HandbookPageModule.ts
5996
+ import { BookOpenIcon } from "lucide-react";
5997
+
5998
+ // src/features/handbook/data/HandbookPage.ts
5999
+ var HandbookPage = class extends AbstractApiData {
6000
+ static {
6001
+ __name(this, "HandbookPage");
6002
+ }
6003
+ _path;
6004
+ _title;
6005
+ _content;
6006
+ _contentHash;
6007
+ _wordCount;
6008
+ _aiStatus;
6009
+ _section;
6010
+ _order;
6011
+ _summary;
6012
+ _displayTitle;
6013
+ _displaySummary;
6014
+ _displayContent;
6015
+ get path() {
6016
+ return this._path ?? "";
6017
+ }
6018
+ get title() {
6019
+ return this._title ?? "";
6020
+ }
6021
+ get content() {
6022
+ return this._content ?? "";
6023
+ }
6024
+ get contentHash() {
6025
+ return this._contentHash ?? "";
6026
+ }
6027
+ get wordCount() {
6028
+ return this._wordCount ?? 0;
6029
+ }
6030
+ get aiStatus() {
6031
+ return this._aiStatus;
6032
+ }
6033
+ get section() {
6034
+ return this._section ?? "";
6035
+ }
6036
+ get order() {
6037
+ return this._order ?? "";
6038
+ }
6039
+ get summary() {
6040
+ return this._summary;
6041
+ }
6042
+ get displayTitle() {
6043
+ return this._displayTitle;
6044
+ }
6045
+ get displaySummary() {
6046
+ return this._displaySummary;
6047
+ }
6048
+ get displayContent() {
6049
+ return this._displayContent;
6050
+ }
6051
+ rehydrate(data) {
6052
+ super.rehydrate(data);
6053
+ this._path = data.jsonApi.attributes.path;
6054
+ this._title = data.jsonApi.attributes.title;
6055
+ this._content = data.jsonApi.attributes.content;
6056
+ this._contentHash = data.jsonApi.attributes.contentHash;
6057
+ this._wordCount = data.jsonApi.attributes.wordCount;
6058
+ this._aiStatus = data.jsonApi.attributes.aiStatus;
6059
+ this._section = data.jsonApi.attributes.section;
6060
+ this._order = data.jsonApi.attributes.order;
6061
+ this._summary = data.jsonApi.attributes.summary;
6062
+ this._displayTitle = data.jsonApi.attributes.displayTitle;
6063
+ this._displaySummary = data.jsonApi.attributes.displaySummary;
6064
+ this._displayContent = data.jsonApi.attributes.displayContent;
6065
+ return this;
6066
+ }
6067
+ createJsonApi(data) {
6068
+ const response = {
6069
+ data: {
6070
+ type: Modules.HandbookPage.name,
6071
+ id: data.id,
6072
+ attributes: {},
6073
+ relationships: {}
6074
+ },
6075
+ included: []
6076
+ };
6077
+ return response;
6078
+ }
6079
+ };
6080
+
6081
+ // src/features/handbook/HandbookPageModule.ts
6082
+ var HandbookPageModule = /* @__PURE__ */ __name((factory) => factory({
6083
+ moduleId: "b1f1c2d6-6a0e-4e93-9b6d-3f5f4a2c81e7",
6084
+ pageUrl: "/administration/handbook",
6085
+ name: "handbookpages",
6086
+ model: HandbookPage,
6087
+ icon: BookOpenIcon,
6088
+ inclusions: {
6089
+ lists: {
6090
+ // `content` is deliberately omitted: the list renders titles and
6091
+ // status, and a thousand pages of markdown do not belong in a list
6092
+ // payload. `section`, `order` and `summary` are the index fields the
6093
+ // contents page groups, orders and describes pages by, so they are the
6094
+ // one part of the payload the list surface cannot do without.
6095
+ //
6096
+ // `displayTitle` and `displaySummary` are the translated halves of the
6097
+ // two strings the contents page prints, and a sparse fieldset that
6098
+ // omitted them would leave every row in English. `displayContent` is
6099
+ // NOT here for the same reason `content` is not: it is the whole
6100
+ // markdown body, and it belongs to the detail read alone.
6101
+ fields: [
6102
+ createJsonApiInclusion("handbookpages", [
6103
+ "path",
6104
+ "title",
6105
+ "displayTitle",
6106
+ "section",
6107
+ "order",
6108
+ "summary",
6109
+ "displaySummary",
6110
+ "wordCount",
6111
+ "aiStatus"
6112
+ ])
6113
+ ]
6114
+ }
6115
+ }
6116
+ }), "HandbookPageModule");
6117
+
6118
+ // src/features/handbook/HandbookSectionModule.ts
6119
+ import { LibraryIcon } from "lucide-react";
6120
+
6121
+ // src/features/handbook/data/HandbookSection.ts
6122
+ var HandbookSection = class extends AbstractApiData {
6123
+ static {
6124
+ __name(this, "HandbookSection");
6125
+ }
6126
+ _key;
6127
+ _title;
6128
+ _summary;
6129
+ _order;
6130
+ _displayTitle;
6131
+ _displaySummary;
6132
+ get key() {
6133
+ return this._key ?? "";
6134
+ }
6135
+ get title() {
6136
+ return this._title ?? "";
6137
+ }
6138
+ get summary() {
6139
+ return this._summary;
6140
+ }
6141
+ get order() {
6142
+ return this._order ?? "";
6143
+ }
6144
+ get displayTitle() {
6145
+ return this._displayTitle;
6146
+ }
6147
+ get displaySummary() {
6148
+ return this._displaySummary;
6149
+ }
6150
+ rehydrate(data) {
6151
+ super.rehydrate(data);
6152
+ this._key = data.jsonApi.attributes.key;
6153
+ this._title = data.jsonApi.attributes.title;
6154
+ this._summary = data.jsonApi.attributes.summary;
6155
+ this._order = data.jsonApi.attributes.order;
6156
+ this._displayTitle = data.jsonApi.attributes.displayTitle;
6157
+ this._displaySummary = data.jsonApi.attributes.displaySummary;
6158
+ return this;
6159
+ }
6160
+ /**
6161
+ * Nothing calls this: sections are read-only over HTTP and written only by
6162
+ * the ingest. It exists because every model implements `createJsonApi()`, and
6163
+ * a model that throws on serialisation is a trap for the next writer.
6164
+ */
6165
+ createJsonApi(data) {
6166
+ const response = {
6167
+ data: {
6168
+ type: Modules.HandbookSection.name,
6169
+ id: data.id,
6170
+ attributes: {},
6171
+ relationships: {}
6172
+ },
6173
+ included: []
6174
+ };
6175
+ if (data.key !== void 0) response.data.attributes.key = data.key;
6176
+ if (data.title !== void 0) response.data.attributes.title = data.title;
6177
+ if (data.summary !== void 0) response.data.attributes.summary = data.summary;
6178
+ if (data.order !== void 0) response.data.attributes.order = data.order;
6179
+ return response;
6180
+ }
6181
+ };
6182
+
6183
+ // src/features/handbook/HandbookSectionModule.ts
6184
+ var HandbookSectionModule = /* @__PURE__ */ __name((factory) => factory({
6185
+ moduleId: "6b0a2f74-1c53-4a0e-9c1d-2e7b4a9d6f30",
6186
+ name: "handbooksections",
6187
+ model: HandbookSection,
6188
+ icon: LibraryIcon,
6189
+ inclusions: {
6190
+ lists: {
6191
+ // `HandbookSectionService.findMany` is the ONLY read of this resource and
6192
+ // it limits to these fields, so the translated halves have to be here:
6193
+ // without them every section heading on the contents page and in the
6194
+ // reader's navigator would stay English however good the translation is.
6195
+ fields: [
6196
+ createJsonApiInclusion("handbooksections", [
6197
+ "key",
6198
+ "title",
6199
+ "displayTitle",
6200
+ "summary",
6201
+ "displaySummary",
6202
+ "order"
6203
+ ])
6204
+ ]
6205
+ }
6206
+ }
6207
+ }), "HandbookSectionModule");
6208
+
6209
+ // src/features/handbook/HandbookThreadMessageModule.ts
6210
+ import { MessageCircleQuestionIcon } from "lucide-react";
6211
+
6212
+ // src/features/handbook/data/HandbookThreadMessage.ts
6213
+ import { v4 as uuidv4 } from "uuid";
6214
+ var HandbookThreadMessage = class _HandbookThreadMessage extends AbstractApiData {
6215
+ static {
6216
+ __name(this, "HandbookThreadMessage");
6217
+ }
6218
+ _role;
6219
+ _content;
6220
+ _position;
6221
+ _sources;
6222
+ _isOptimistic = false;
6223
+ get role() {
6224
+ return this._role ?? "assistant";
6225
+ }
6226
+ get content() {
6227
+ return this._content ?? "";
6228
+ }
6229
+ get position() {
6230
+ return this._position ?? 0;
6231
+ }
6232
+ get sources() {
6233
+ return this._sources ?? [];
6234
+ }
6235
+ /** The handbook agent returns no follow-ups. */
6236
+ get suggestedQuestions() {
6237
+ return [];
6238
+ }
6239
+ /** Token accounting is not billed against a handbook thread. */
6240
+ get inputTokens() {
6241
+ return void 0;
6242
+ }
6243
+ get outputTokens() {
6244
+ return void 0;
6245
+ }
6246
+ /** The handbook answers from pages, never from product entities. */
6247
+ get references() {
6248
+ return [];
6249
+ }
6250
+ /** Cited pages travel in `sources`, not as Chunk resources. */
6251
+ get citations() {
6252
+ return [];
6253
+ }
6254
+ /** Set only by `buildLocal`; a rehydrated message is always real. */
6255
+ get isOptimistic() {
6256
+ return this._isOptimistic;
6257
+ }
6258
+ /** There is no operator engine behind the handbook, so never an approval request. */
6259
+ get messageType() {
6260
+ return "text";
6261
+ }
6262
+ get actionId() {
6263
+ return void 0;
6264
+ }
6265
+ rehydrate(data) {
6266
+ super.rehydrate(data);
6267
+ const attributes = data.jsonApi.attributes ?? {};
6268
+ this._role = attributes.role;
6269
+ this._content = attributes.content;
6270
+ this._position = typeof attributes.position === "number" ? attributes.position : Number(attributes.position ?? 0);
6271
+ this._sources = Array.isArray(attributes.sources) ? attributes.sources : [];
6272
+ return this;
6273
+ }
6274
+ /**
6275
+ * The envelope `POST /handbookthreads/:id/handbookthreadmessages` accepts:
6276
+ * only the question. Role and position are derived server-side from the
6277
+ * thread, and there is no client-chosen id for the pair of messages the turn
6278
+ * creates.
6279
+ *
6280
+ * `handbookPageId` rides the same way `question` does, through this method
6281
+ * and never through `overridesJsonApiCreation`. It is written only when the
6282
+ * caller supplied it: the DTO takes it as optional, and sending an explicit
6283
+ * `null` would fail validation rather than mean "the whole manual".
6284
+ */
6285
+ createJsonApi(data) {
6286
+ return {
6287
+ data: {
6288
+ type: Modules.HandbookThreadMessage.name,
6289
+ attributes: {
6290
+ question: data.question,
6291
+ ...data.handbookPageId !== void 0 ? { handbookPageId: data.handbookPageId } : {}
6292
+ }
6293
+ },
6294
+ included: []
6295
+ };
6296
+ }
6297
+ /**
6298
+ * A message that exists only on the client: the optimistic user turn while
6299
+ * the agent runs, and the failure notice when it does not answer. Mirrors
6300
+ * `AssistantMessage.buildLocal`, which the stateless handbook surface used
6301
+ * before threads existed.
6302
+ */
6303
+ static buildLocal(params) {
6304
+ const message = new _HandbookThreadMessage();
6305
+ message.rehydrate({
6306
+ jsonApi: {
6307
+ id: uuidv4(),
6308
+ type: Modules.HandbookThreadMessage.name,
6309
+ attributes: {
6310
+ role: params.role,
6311
+ content: params.content,
6312
+ position: params.position
6313
+ }
6314
+ },
6315
+ included: []
6316
+ });
6317
+ message._isOptimistic = params.isOptimistic ?? false;
6318
+ return message;
6319
+ }
6320
+ };
6321
+
6322
+ // src/features/handbook/HandbookThreadMessageModule.ts
6323
+ var HandbookThreadMessageModule = /* @__PURE__ */ __name((factory) => factory({
6324
+ moduleId: "bef354f2-70e1-4f4f-9953-10d3d74cad0c",
6325
+ name: "handbookthreadmessages",
6326
+ model: HandbookThreadMessage,
6327
+ icon: MessageCircleQuestionIcon,
6328
+ inclusions: {
6329
+ lists: {
6330
+ fields: [createJsonApiInclusion("handbookthreadmessages", ["role", "content", "position", "sources"])]
6331
+ }
6332
+ }
6333
+ }), "HandbookThreadMessageModule");
6334
+
6335
+ // src/features/handbook/HandbookThreadModule.ts
6336
+ import { MessagesSquareIcon } from "lucide-react";
6337
+
6338
+ // src/features/handbook/data/HandbookThread.ts
6339
+ var HandbookThread = class extends AbstractApiData {
6340
+ static {
6341
+ __name(this, "HandbookThread");
6342
+ }
6343
+ _title;
6344
+ _messageCount;
6345
+ _messages;
6346
+ get title() {
6347
+ return this._title ?? "";
6348
+ }
6349
+ get messageCount() {
6350
+ return this._messageCount ?? 0;
6351
+ }
6352
+ /**
6353
+ * The handbook runs one agent and has no engine choice, so nothing routes on
6354
+ * this. It exists because `AssistantInterface` declares it, which is what
6355
+ * lets the shared chat chrome take a handbook thread unchanged.
6356
+ */
6357
+ get engine() {
6358
+ return void 0;
6359
+ }
6360
+ /** A handbook thread is never bound to a product resource. */
6361
+ get boundContentType() {
6362
+ return void 0;
6363
+ }
6364
+ get boundContentId() {
6365
+ return void 0;
6366
+ }
6367
+ get messages() {
6368
+ return this._messages ?? [];
6369
+ }
6370
+ rehydrate(data) {
6371
+ super.rehydrate(data);
6372
+ const attributes = data.jsonApi.attributes ?? {};
6373
+ this._title = attributes.title;
6374
+ const fromMeta = data.jsonApi.meta?.messageCount;
6375
+ this._messageCount = typeof fromMeta === "number" ? fromMeta : typeof attributes.messageCount === "number" ? attributes.messageCount : 0;
6376
+ const messages = this._readIncluded(
6377
+ data,
6378
+ "messages",
6379
+ Modules.HandbookThreadMessage
6380
+ );
6381
+ this._messages = Array.isArray(messages) ? messages : messages ? [messages] : [];
6382
+ if (this._updatedAt === void 0 && attributes.updatedAt !== void 0)
6383
+ this._updatedAt = new Date(attributes.updatedAt);
6384
+ if (this._createdAt === void 0 && attributes.createdAt !== void 0)
6385
+ this._createdAt = new Date(attributes.createdAt);
6386
+ return this;
6387
+ }
6388
+ /**
6389
+ * The envelope `POST /handbookthreads` accepts: the opening question. The
6390
+ * server derives the title from it, so no title is sent and no client id —
6391
+ * the thread's identity is the server's to mint.
6392
+ *
6393
+ * `handbookPageId` rides the same way `question` does, through this method
6394
+ * and never through `overridesJsonApiCreation`. It is written only when the
6395
+ * caller supplied it: the DTO takes it as optional, and sending an explicit
6396
+ * `null` would fail validation rather than mean "the whole manual".
6397
+ */
6398
+ createJsonApi(data) {
6399
+ return {
6400
+ data: {
6401
+ type: Modules.HandbookThread.name,
6402
+ attributes: {
6403
+ question: data.question,
6404
+ ...data.handbookPageId !== void 0 ? { handbookPageId: data.handbookPageId } : {}
6405
+ }
6406
+ },
6407
+ included: []
6408
+ };
6409
+ }
6410
+ /**
6411
+ * The envelope `PATCH /handbookthreads/:id` accepts. A dedicated method
6412
+ * rather than a branch inside `createJsonApi`: the rename sends the title and
6413
+ * nothing else, while a create sends the question and nothing else, and the
6414
+ * service must never hand-build either.
6415
+ */
6416
+ createRenameJsonApi(params) {
6417
+ return {
6418
+ data: {
6419
+ type: Modules.HandbookThread.name,
6420
+ id: params.id,
6421
+ attributes: {
6422
+ title: params.title
6423
+ }
6424
+ },
6425
+ included: []
6426
+ };
6427
+ }
6428
+ };
6429
+
6430
+ // src/features/handbook/HandbookThreadModule.ts
6431
+ var HandbookThreadModule = /* @__PURE__ */ __name((factory) => factory({
6432
+ moduleId: "aea692c4-7163-49bd-9ddc-1052cc06fa14",
6433
+ name: "handbookthreads",
6434
+ model: HandbookThread,
6435
+ icon: MessagesSquareIcon,
6436
+ identifier: ["title"],
6437
+ inclusions: {
6438
+ lists: {
6439
+ fields: [createJsonApiInclusion("handbookthreads", ["title"])]
6440
+ }
6441
+ }
6442
+ }), "HandbookThreadModule");
6443
+
6444
+ // src/features/handbook/data/handbookDisplay.ts
6445
+ function handbookPageTitle(page) {
6446
+ return page.displayTitle ?? page.title;
6447
+ }
6448
+ __name(handbookPageTitle, "handbookPageTitle");
6449
+ function handbookPageSummary(page) {
6450
+ return page.displaySummary ?? page.summary;
6451
+ }
6452
+ __name(handbookPageSummary, "handbookPageSummary");
6453
+ function handbookPageContent(page) {
6454
+ return page.displayContent ?? page.content;
6455
+ }
6456
+ __name(handbookPageContent, "handbookPageContent");
6457
+ function handbookSectionTitle(section) {
6458
+ return section.displayTitle ?? section.title;
6459
+ }
6460
+ __name(handbookSectionTitle, "handbookSectionTitle");
6461
+ function handbookSectionSummary(section) {
6462
+ return section.displaySummary ?? section.summary;
6463
+ }
6464
+ __name(handbookSectionSummary, "handbookSectionSummary");
6465
+
6466
+ // src/features/handbook/data/HandbookPageFields.ts
6467
+ var HandbookPageFields = /* @__PURE__ */ ((HandbookPageFields2) => {
6468
+ HandbookPageFields2["handbookPageId"] = "handbookPageId";
6469
+ HandbookPageFields2["path"] = "path";
6470
+ HandbookPageFields2["title"] = "title";
6471
+ HandbookPageFields2["displayTitle"] = "displayTitle";
6472
+ HandbookPageFields2["section"] = "section";
6473
+ HandbookPageFields2["order"] = "order";
6474
+ HandbookPageFields2["summary"] = "summary";
6475
+ HandbookPageFields2["displaySummary"] = "displaySummary";
6476
+ HandbookPageFields2["displayContent"] = "displayContent";
6477
+ HandbookPageFields2["wordCount"] = "wordCount";
6478
+ HandbookPageFields2["aiStatus"] = "aiStatus";
6479
+ return HandbookPageFields2;
6480
+ })(HandbookPageFields || {});
6481
+
6482
+ // src/features/handbook/data/HandbookPageService.ts
6483
+ var HandbookPageService = class extends AbstractService {
6484
+ static {
6485
+ __name(this, "HandbookPageService");
6486
+ }
6487
+ /**
6488
+ * `next` / `prev` are not optional extras: `useDataListRetriever` drives
6489
+ * pagination by handing the cursor back here, so a findMany that drops them
6490
+ * renders exactly one page and no navigation, however many rows exist.
6491
+ * Mirrors HowToService.findMany.
6492
+ */
6493
+ static async findMany(params = {}) {
6494
+ const endpoint = new EndpointCreator({ endpoint: Modules.HandbookPage });
6495
+ if (params.fetchAll) endpoint.addAdditionalParam("fetchAll", "true");
6496
+ if (params.search) endpoint.addAdditionalParam("search", params.search);
6497
+ if (Modules.HandbookPage.inclusions?.lists?.fields)
6498
+ endpoint.limitToFields(Modules.HandbookPage.inclusions.lists.fields);
6499
+ if (Modules.HandbookPage.inclusions?.lists?.types)
6500
+ endpoint.limitToType(Modules.HandbookPage.inclusions.lists.types);
6501
+ return this.callApi({
6502
+ type: Modules.HandbookPage,
6503
+ method: "GET" /* GET */,
6504
+ endpoint: endpoint.generate(),
6505
+ next: params.next
6506
+ });
6507
+ }
6508
+ static async findOne(params) {
6509
+ return this.callApi({
6510
+ type: Modules.HandbookPage,
6511
+ method: "GET" /* GET */,
6512
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookPage, id: params.id }).generate()
6513
+ });
6514
+ }
6515
+ /** POST /handbookpages/sync — replies 204; the caller refetches the list. */
6516
+ static async sync() {
6517
+ await this.callApi({
6518
+ type: Modules.HandbookPage,
6519
+ method: "POST" /* POST */,
6520
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookPage, id: "sync" }).generate()
6521
+ });
6522
+ }
6523
+ static async delete(params) {
6524
+ await this.callApi({
6525
+ type: Modules.HandbookPage,
6526
+ method: "DELETE" /* DELETE */,
6527
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookPage, id: params.id }).generate()
6528
+ });
6529
+ }
6530
+ };
6531
+
6532
+ // src/features/handbook/data/HandbookSectionService.ts
6533
+ var HandbookSectionService = class extends AbstractService {
6534
+ static {
6535
+ __name(this, "HandbookSectionService");
6536
+ }
6537
+ /**
6538
+ * Every section in one read, always.
6539
+ *
6540
+ * There are as many sections as an application has documentation directories
6541
+ * — ten or so — so this takes no `fetchAll` argument and no cursor: unlike
6542
+ * the page list, nothing here is ever a second page, and a caller that could
6543
+ * ask for one page of sections would only be able to get it wrong.
6544
+ */
6545
+ static async findMany() {
6546
+ const endpoint = new EndpointCreator({ endpoint: Modules.HandbookSection });
6547
+ endpoint.addAdditionalParam("fetchAll", "true");
6548
+ if (Modules.HandbookSection.inclusions?.lists?.fields)
6549
+ endpoint.limitToFields(Modules.HandbookSection.inclusions.lists.fields);
6550
+ return this.callApi({
6551
+ type: Modules.HandbookSection,
6552
+ method: "GET" /* GET */,
6553
+ endpoint: endpoint.generate()
6554
+ });
6555
+ }
6556
+ };
6557
+
6558
+ // src/features/handbook/data/HandbookThreadMessageService.ts
6559
+ var HandbookThreadMessageService = class extends AbstractService {
6560
+ static {
6561
+ __name(this, "HandbookThreadMessageService");
6562
+ }
6563
+ /**
6564
+ * Appends one question to an existing thread and runs the agent turn.
6565
+ *
6566
+ * It returns nothing on purpose: the caller reads the turn back with
6567
+ * `HandbookThreadService.findOne`, which is the one endpoint the contract
6568
+ * guarantees side-loads the full message list. That keeps a single code path
6569
+ * for "load the thread after a mutation" — the same one the sidebar's select
6570
+ * uses — instead of two ways of arriving at the transcript.
6571
+ *
6572
+ * The API answers 400 when the installation has no usable AI configuration
6573
+ * and 403 for a non-administrator; both reach the caller as a thrown error.
6574
+ */
6575
+ static async ask(params) {
6576
+ await this.callApi({
6577
+ type: Modules.HandbookThreadMessage,
6578
+ method: "POST" /* POST */,
6579
+ endpoint: new EndpointCreator({
6580
+ endpoint: Modules.HandbookThread,
6581
+ id: params.threadId,
6582
+ childEndpoint: Modules.HandbookThreadMessage
6583
+ }).generate(),
6584
+ input: { id: params.id, question: params.question, handbookPageId: params.handbookPageId },
6585
+ suppressGlobalError: true
6586
+ });
6587
+ }
6588
+ };
6589
+
6590
+ // src/features/handbook/data/HandbookThreadService.ts
6591
+ var HandbookThreadService = class extends AbstractService {
6592
+ static {
6593
+ __name(this, "HandbookThreadService");
6594
+ }
6595
+ /**
6596
+ * `next` / `prev` are not optional extras: `useDataListRetriever` drives
6597
+ * pagination by handing the cursor back here, so a findMany that drops them
6598
+ * renders exactly one page and no navigation, however many rows exist.
6599
+ * Mirrors HowToService.findMany.
6600
+ */
6601
+ static async findMany(params = {}) {
6602
+ const endpoint = new EndpointCreator({ endpoint: Modules.HandbookThread });
6603
+ if (params.fetchAll) endpoint.addAdditionalParam("fetchAll", "true");
6604
+ if (params.search) endpoint.addAdditionalParam("search", params.search);
6605
+ if (Modules.HandbookThread.inclusions?.lists?.fields)
6606
+ endpoint.limitToFields(Modules.HandbookThread.inclusions.lists.fields);
6607
+ if (Modules.HandbookThread.inclusions?.lists?.types)
6608
+ endpoint.limitToType(Modules.HandbookThread.inclusions.lists.types);
6609
+ return this.callApi({
6610
+ type: Modules.HandbookThread,
6611
+ method: "GET" /* GET */,
6612
+ endpoint: endpoint.generate(),
6613
+ next: params.next
6614
+ });
6615
+ }
6616
+ /** Returns the thread with its messages side-loaded — the sidebar's select. */
6617
+ static async findOne(params) {
6618
+ return this.callApi({
6619
+ type: Modules.HandbookThread,
6620
+ method: "GET" /* GET */,
6621
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookThread, id: params.id }).generate()
6622
+ });
6623
+ }
6624
+ /**
6625
+ * Opens a thread with its first question. The response is the thread (title
6626
+ * included); the messages are read back with `findOne`, because only the
6627
+ * single-resource endpoint side-loads them.
6628
+ *
6629
+ * The API answers 400 when the installation has no usable AI configuration
6630
+ * and 403 for a non-administrator; both reach the caller as a thrown error.
6631
+ *
6632
+ * `HandbookThreadInput.handbookPageId` scopes retrieval to one page. It rides
6633
+ * through the model's `createJsonApi()`, exactly as `question` does — there is
6634
+ * no `overridesJsonApiCreation` on this path.
6635
+ */
6636
+ static async create(params) {
6637
+ return this.callApi({
6638
+ type: Modules.HandbookThread,
6639
+ method: "POST" /* POST */,
6640
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookThread }).generate(),
6641
+ input: params,
6642
+ suppressGlobalError: true
6643
+ });
6644
+ }
6645
+ static async rename(params) {
6646
+ const thread = new HandbookThread();
6647
+ await this.callApi({
6648
+ type: Modules.HandbookThread,
6649
+ method: "PATCH" /* PATCH */,
6650
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookThread, id: params.id }).generate(),
6651
+ input: thread.createRenameJsonApi({ id: params.id, title: params.title }),
6652
+ overridesJsonApiCreation: true
6653
+ });
6654
+ }
6655
+ static async delete(params) {
6656
+ await this.callApi({
6657
+ type: Modules.HandbookThread,
6658
+ method: "DELETE" /* DELETE */,
6659
+ endpoint: new EndpointCreator({ endpoint: Modules.HandbookThread, id: params.id }).generate()
6660
+ });
6661
+ }
6662
+ };
6663
+
5983
6664
  // src/features/assistant/AssistantModule.ts
5984
6665
  import { BotIcon } from "lucide-react";
5985
6666
 
@@ -6033,7 +6714,9 @@ var Assistant = class extends AbstractApiData {
6033
6714
  content: data.contentBlocks !== void 0 ? JSON.stringify(data.contentBlocks) : data.firstMessage,
6034
6715
  ...data.title !== void 0 ? { title: data.title } : {},
6035
6716
  ...data.howToMode !== void 0 ? { howToMode: data.howToMode } : {},
6036
- ...data.limitToHowToId !== void 0 ? { limitToHowToId: data.limitToHowToId } : {}
6717
+ ...data.limitToHowToId !== void 0 ? { limitToHowToId: data.limitToHowToId } : {},
6718
+ ...data.handbookMode !== void 0 ? { handbookMode: data.handbookMode } : {},
6719
+ ...data.limitToHandbookPageId !== void 0 ? { limitToHandbookPageId: data.limitToHandbookPageId } : {}
6037
6720
  },
6038
6721
  ...data.boundContent !== void 0 ? {
6039
6722
  relationships: {
@@ -6062,7 +6745,7 @@ var AssistantModule = /* @__PURE__ */ __name((factory) => factory({
6062
6745
  }), "AssistantModule");
6063
6746
 
6064
6747
  // src/features/assistant-message/data/AssistantMessage.ts
6065
- import { v4 as uuidv4 } from "uuid";
6748
+ import { v4 as uuidv42 } from "uuid";
6066
6749
 
6067
6750
  // src/features/assistant/utils/resolveReferenceableModules.ts
6068
6751
  function resolveReferenceableModules() {
@@ -6184,18 +6867,32 @@ var AssistantMessage = class _AssistantMessage extends AbstractApiData {
6184
6867
  // stored markdown from it.
6185
6868
  content: params.contentBlocks !== void 0 ? JSON.stringify(params.contentBlocks) : params.content,
6186
6869
  ...params.howToMode !== void 0 ? { howToMode: params.howToMode } : {},
6187
- ...params.limitToHowToId !== void 0 ? { limitToHowToId: params.limitToHowToId } : {}
6870
+ ...params.limitToHowToId !== void 0 ? { limitToHowToId: params.limitToHowToId } : {},
6871
+ ...params.handbookMode !== void 0 ? { handbookMode: params.handbookMode } : {},
6872
+ ...params.limitToHandbookPageId !== void 0 ? { limitToHandbookPageId: params.limitToHandbookPageId } : {}
6188
6873
  }
6189
6874
  }
6190
6875
  };
6191
6876
  }
6192
6877
  static buildOptimistic(params) {
6878
+ return _AssistantMessage.buildLocal({ ...params, role: "user", isOptimistic: true });
6879
+ }
6880
+ /**
6881
+ * A message that exists only on the client, for a surface that renders the
6882
+ * chat presentation without persisting a thread.
6883
+ *
6884
+ * `buildOptimistic` is the user-turn case and delegates here. The handbook
6885
+ * ask surface is the other caller: it has no Assistant and no stored
6886
+ * messages, but it renders through MessageList/MessageItem like every other
6887
+ * chat in the product, so it needs both roles.
6888
+ */
6889
+ static buildLocal(params) {
6193
6890
  const msg = new _AssistantMessage();
6194
6891
  const jsonApi = {
6195
- id: uuidv4(),
6892
+ id: uuidv42(),
6196
6893
  type: Modules.AssistantMessage.name,
6197
6894
  attributes: {
6198
- role: "user",
6895
+ role: params.role,
6199
6896
  content: params.content,
6200
6897
  position: params.position
6201
6898
  }
@@ -6206,7 +6903,7 @@ var AssistantMessage = class _AssistantMessage extends AbstractApiData {
6206
6903
  };
6207
6904
  }
6208
6905
  msg.rehydrate({ jsonApi, included: [] });
6209
- msg._isOptimistic = true;
6906
+ msg._isOptimistic = params.isOptimistic ?? false;
6210
6907
  return msg;
6211
6908
  }
6212
6909
  };
@@ -6282,6 +6979,8 @@ var AssistantService = class extends AbstractService {
6282
6979
  content: params.content,
6283
6980
  howToMode: params.howToMode,
6284
6981
  limitToHowToId: params.limitToHowToId,
6982
+ handbookMode: params.handbookMode,
6983
+ limitToHandbookPageId: params.limitToHandbookPageId,
6285
6984
  contentBlocks: params.contentBlocks
6286
6985
  }),
6287
6986
  overridesJsonApiCreation: true
@@ -8911,6 +9610,24 @@ export {
8911
9610
  HowToModule,
8912
9611
  HowToFields,
8913
9612
  HowToService,
9613
+ HandbookPage,
9614
+ HandbookPageModule,
9615
+ HandbookSection,
9616
+ HandbookSectionModule,
9617
+ HandbookThreadMessage,
9618
+ HandbookThreadMessageModule,
9619
+ HandbookThread,
9620
+ HandbookThreadModule,
9621
+ handbookPageTitle,
9622
+ handbookPageSummary,
9623
+ handbookPageContent,
9624
+ handbookSectionTitle,
9625
+ handbookSectionSummary,
9626
+ HandbookPageFields,
9627
+ HandbookPageService,
9628
+ HandbookSectionService,
9629
+ HandbookThreadMessageService,
9630
+ HandbookThreadService,
8914
9631
  Assistant,
8915
9632
  AssistantModule,
8916
9633
  AssistantMessage,
@@ -8984,4 +9701,4 @@ export {
8984
9701
  AuditLogService,
8985
9702
  AuditLogModule
8986
9703
  };
8987
- //# sourceMappingURL=chunk-Q2BREXH3.mjs.map
9704
+ //# sourceMappingURL=chunk-OSFYCSTW.mjs.map