@aglyn/aglyn 1.0.0-beta.143

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 (963) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +11 -0
  3. package/package.json +66 -0
  4. package/src/index.d.ts +25 -0
  5. package/src/index.js +26 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/aglyn.d.ts +31 -0
  8. package/src/lib/aglyn.js +114 -0
  9. package/src/lib/aglyn.js.map +1 -0
  10. package/src/lib/app-utils/abuse-report.d.ts +193 -0
  11. package/src/lib/app-utils/abuse-report.js +321 -0
  12. package/src/lib/app-utils/abuse-report.js.map +1 -0
  13. package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
  14. package/src/lib/app-utils/accept-negotiation.js +266 -0
  15. package/src/lib/app-utils/accept-negotiation.js.map +1 -0
  16. package/src/lib/app-utils/account-emails.d.ts +263 -0
  17. package/src/lib/app-utils/account-emails.js +264 -0
  18. package/src/lib/app-utils/account-emails.js.map +1 -0
  19. package/src/lib/app-utils/actions.d.ts +717 -0
  20. package/src/lib/app-utils/actions.js +1031 -0
  21. package/src/lib/app-utils/actions.js.map +1 -0
  22. package/src/lib/app-utils/activity-presenter.d.ts +152 -0
  23. package/src/lib/app-utils/activity-presenter.js +326 -0
  24. package/src/lib/app-utils/activity-presenter.js.map +1 -0
  25. package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
  26. package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
  27. package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
  28. package/src/lib/app-utils/advertising-tags.d.ts +307 -0
  29. package/src/lib/app-utils/advertising-tags.js +525 -0
  30. package/src/lib/app-utils/advertising-tags.js.map +1 -0
  31. package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
  32. package/src/lib/app-utils/agent-api-catalog.js +106 -0
  33. package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
  34. package/src/lib/app-utils/agent-openapi.d.ts +103 -0
  35. package/src/lib/app-utils/agent-openapi.js +1128 -0
  36. package/src/lib/app-utils/agent-openapi.js.map +1 -0
  37. package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
  38. package/src/lib/app-utils/analytics-beacon.js +152 -0
  39. package/src/lib/app-utils/analytics-beacon.js.map +1 -0
  40. package/src/lib/app-utils/analytics-environment.d.ts +133 -0
  41. package/src/lib/app-utils/analytics-environment.js +152 -0
  42. package/src/lib/app-utils/analytics-environment.js.map +1 -0
  43. package/src/lib/app-utils/analytics-events.d.ts +744 -0
  44. package/src/lib/app-utils/analytics-events.js +650 -0
  45. package/src/lib/app-utils/analytics-events.js.map +1 -0
  46. package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
  47. package/src/lib/app-utils/analytics-link-clicks.js +267 -0
  48. package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
  49. package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
  50. package/src/lib/app-utils/analytics-path-key.js +46 -0
  51. package/src/lib/app-utils/analytics-path-key.js.map +1 -0
  52. package/src/lib/app-utils/api-adapter.d.ts +47 -0
  53. package/src/lib/app-utils/api-adapter.js +367 -0
  54. package/src/lib/app-utils/api-adapter.js.map +1 -0
  55. package/src/lib/app-utils/api-idempotency.d.ts +169 -0
  56. package/src/lib/app-utils/api-idempotency.js +213 -0
  57. package/src/lib/app-utils/api-idempotency.js.map +1 -0
  58. package/src/lib/app-utils/api-plugins.d.ts +210 -0
  59. package/src/lib/app-utils/api-plugins.js +221 -0
  60. package/src/lib/app-utils/api-plugins.js.map +1 -0
  61. package/src/lib/app-utils/assist-credits.d.ts +482 -0
  62. package/src/lib/app-utils/assist-credits.js +509 -0
  63. package/src/lib/app-utils/assist-credits.js.map +1 -0
  64. package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
  65. package/src/lib/app-utils/attribution-attribute.js +34 -0
  66. package/src/lib/app-utils/attribution-attribute.js.map +1 -0
  67. package/src/lib/app-utils/attribution-guard.d.ts +130 -0
  68. package/src/lib/app-utils/attribution-guard.js +410 -0
  69. package/src/lib/app-utils/attribution-guard.js.map +1 -0
  70. package/src/lib/app-utils/author-css.d.ts +123 -0
  71. package/src/lib/app-utils/author-css.js +275 -0
  72. package/src/lib/app-utils/author-css.js.map +1 -0
  73. package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
  74. package/src/lib/app-utils/author-html-markdown.js +497 -0
  75. package/src/lib/app-utils/author-html-markdown.js.map +1 -0
  76. package/src/lib/app-utils/author-html.d.ts +135 -0
  77. package/src/lib/app-utils/author-html.js +1037 -0
  78. package/src/lib/app-utils/author-html.js.map +1 -0
  79. package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
  80. package/src/lib/app-utils/automation-placeholders.js +207 -0
  81. package/src/lib/app-utils/automation-placeholders.js.map +1 -0
  82. package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
  83. package/src/lib/app-utils/bandwidth-cap.js +193 -0
  84. package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
  85. package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
  86. package/src/lib/app-utils/binding-token-catalog.js +293 -0
  87. package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
  88. package/src/lib/app-utils/binding-tokens.d.ts +157 -0
  89. package/src/lib/app-utils/binding-tokens.js +251 -0
  90. package/src/lib/app-utils/binding-tokens.js.map +1 -0
  91. package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
  92. package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
  93. package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
  94. package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
  95. package/src/lib/app-utils/campaign-attribution.js +162 -0
  96. package/src/lib/app-utils/campaign-attribution.js.map +1 -0
  97. package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
  98. package/src/lib/app-utils/campaign-forwarding.js +332 -0
  99. package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
  100. package/src/lib/app-utils/campaign-membership.d.ts +109 -0
  101. package/src/lib/app-utils/campaign-membership.js +176 -0
  102. package/src/lib/app-utils/campaign-membership.js.map +1 -0
  103. package/src/lib/app-utils/campaign-touch.d.ts +206 -0
  104. package/src/lib/app-utils/campaign-touch.js +326 -0
  105. package/src/lib/app-utils/campaign-touch.js.map +1 -0
  106. package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
  107. package/src/lib/app-utils/child-contract-compose.js +140 -0
  108. package/src/lib/app-utils/child-contract-compose.js.map +1 -0
  109. package/src/lib/app-utils/child-contract.d.ts +129 -0
  110. package/src/lib/app-utils/child-contract.js +153 -0
  111. package/src/lib/app-utils/child-contract.js.map +1 -0
  112. package/src/lib/app-utils/collection-delete.d.ts +113 -0
  113. package/src/lib/app-utils/collection-delete.js +120 -0
  114. package/src/lib/app-utils/collection-delete.js.map +1 -0
  115. package/src/lib/app-utils/collection-entries.d.ts +833 -0
  116. package/src/lib/app-utils/collection-entries.js +1285 -0
  117. package/src/lib/app-utils/collection-entries.js.map +1 -0
  118. package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
  119. package/src/lib/app-utils/collection-entry-date.js +183 -0
  120. package/src/lib/app-utils/collection-entry-date.js.map +1 -0
  121. package/src/lib/app-utils/collection-kind.d.ts +55 -0
  122. package/src/lib/app-utils/collection-kind.js +69 -0
  123. package/src/lib/app-utils/collection-kind.js.map +1 -0
  124. package/src/lib/app-utils/collection-slug.d.ts +79 -0
  125. package/src/lib/app-utils/collection-slug.js +70 -0
  126. package/src/lib/app-utils/collection-slug.js.map +1 -0
  127. package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
  128. package/src/lib/app-utils/compose-layout-nodes.js +261 -0
  129. package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
  130. package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
  131. package/src/lib/app-utils/compose-layout-props.js +61 -0
  132. package/src/lib/app-utils/compose-layout-props.js.map +1 -0
  133. package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
  134. package/src/lib/app-utils/compose-reusable-components.js +1366 -0
  135. package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
  136. package/src/lib/app-utils/compress.d.ts +35 -0
  137. package/src/lib/app-utils/compress.js +38 -0
  138. package/src/lib/app-utils/compress.js.map +1 -0
  139. package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
  140. package/src/lib/app-utils/consent-banner-ui.js +583 -0
  141. package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
  142. package/src/lib/app-utils/consent-groups.d.ts +189 -0
  143. package/src/lib/app-utils/consent-groups.js +219 -0
  144. package/src/lib/app-utils/consent-groups.js.map +1 -0
  145. package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
  146. package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
  147. package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
  148. package/src/lib/app-utils/console-record-links.d.ts +163 -0
  149. package/src/lib/app-utils/console-record-links.js +178 -0
  150. package/src/lib/app-utils/console-record-links.js.map +1 -0
  151. package/src/lib/app-utils/console-routes.d.ts +658 -0
  152. package/src/lib/app-utils/console-routes.js +489 -0
  153. package/src/lib/app-utils/console-routes.js.map +1 -0
  154. package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
  155. package/src/lib/app-utils/console-widget-slot-context.js +23 -0
  156. package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
  157. package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
  158. package/src/lib/app-utils/contact-custom-fields.js +349 -0
  159. package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
  160. package/src/lib/app-utils/contact-holder.d.ts +52 -0
  161. package/src/lib/app-utils/contact-holder.js +98 -0
  162. package/src/lib/app-utils/contact-holder.js.map +1 -0
  163. package/src/lib/app-utils/contact-merge.d.ts +136 -0
  164. package/src/lib/app-utils/contact-merge.js +379 -0
  165. package/src/lib/app-utils/contact-merge.js.map +1 -0
  166. package/src/lib/app-utils/contacts.d.ts +554 -0
  167. package/src/lib/app-utils/contacts.js +401 -0
  168. package/src/lib/app-utils/contacts.js.map +1 -0
  169. package/src/lib/app-utils/content-author-profile.d.ts +68 -0
  170. package/src/lib/app-utils/content-author-profile.js +118 -0
  171. package/src/lib/app-utils/content-author-profile.js.map +1 -0
  172. package/src/lib/app-utils/content-authors.d.ts +662 -0
  173. package/src/lib/app-utils/content-authors.js +771 -0
  174. package/src/lib/app-utils/content-authors.js.map +1 -0
  175. package/src/lib/app-utils/content-schema-type.d.ts +81 -0
  176. package/src/lib/app-utils/content-schema-type.js +87 -0
  177. package/src/lib/app-utils/content-schema-type.js.map +1 -0
  178. package/src/lib/app-utils/contexts.d.ts +35 -0
  179. package/src/lib/app-utils/contexts.js +35 -0
  180. package/src/lib/app-utils/contexts.js.map +1 -0
  181. package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
  182. package/src/lib/app-utils/create-resource-uid.js +23 -0
  183. package/src/lib/app-utils/create-resource-uid.js.map +1 -0
  184. package/src/lib/app-utils/crm-booking.d.ts +75 -0
  185. package/src/lib/app-utils/crm-booking.js +133 -0
  186. package/src/lib/app-utils/crm-booking.js.map +1 -0
  187. package/src/lib/app-utils/crm-csv.d.ts +232 -0
  188. package/src/lib/app-utils/crm-csv.js +432 -0
  189. package/src/lib/app-utils/crm-csv.js.map +1 -0
  190. package/src/lib/app-utils/crm-digest.d.ts +179 -0
  191. package/src/lib/app-utils/crm-digest.js +271 -0
  192. package/src/lib/app-utils/crm-digest.js.map +1 -0
  193. package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
  194. package/src/lib/app-utils/crm-email-templates.js +382 -0
  195. package/src/lib/app-utils/crm-email-templates.js.map +1 -0
  196. package/src/lib/app-utils/crm-inbound.d.ts +245 -0
  197. package/src/lib/app-utils/crm-inbound.js +407 -0
  198. package/src/lib/app-utils/crm-inbound.js.map +1 -0
  199. package/src/lib/app-utils/crm-kinds.d.ts +73 -0
  200. package/src/lib/app-utils/crm-kinds.js +92 -0
  201. package/src/lib/app-utils/crm-kinds.js.map +1 -0
  202. package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
  203. package/src/lib/app-utils/crm-next-activity.js +140 -0
  204. package/src/lib/app-utils/crm-next-activity.js.map +1 -0
  205. package/src/lib/app-utils/crm-reports.d.ts +479 -0
  206. package/src/lib/app-utils/crm-reports.js +680 -0
  207. package/src/lib/app-utils/crm-reports.js.map +1 -0
  208. package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
  209. package/src/lib/app-utils/crm-task-reminders.js +139 -0
  210. package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
  211. package/src/lib/app-utils/crm.d.ts +1546 -0
  212. package/src/lib/app-utils/crm.js +1814 -0
  213. package/src/lib/app-utils/crm.js.map +1 -0
  214. package/src/lib/app-utils/csp-report.d.ts +84 -0
  215. package/src/lib/app-utils/csp-report.js +177 -0
  216. package/src/lib/app-utils/csp-report.js.map +1 -0
  217. package/src/lib/app-utils/csv-import.d.ts +192 -0
  218. package/src/lib/app-utils/csv-import.js +279 -0
  219. package/src/lib/app-utils/csv-import.js.map +1 -0
  220. package/src/lib/app-utils/dataset-csv.d.ts +109 -0
  221. package/src/lib/app-utils/dataset-csv.js +235 -0
  222. package/src/lib/app-utils/dataset-csv.js.map +1 -0
  223. package/src/lib/app-utils/dataset-models.d.ts +194 -0
  224. package/src/lib/app-utils/dataset-models.js +409 -0
  225. package/src/lib/app-utils/dataset-models.js.map +1 -0
  226. package/src/lib/app-utils/dataset-query.d.ts +57 -0
  227. package/src/lib/app-utils/dataset-query.js +126 -0
  228. package/src/lib/app-utils/dataset-query.js.map +1 -0
  229. package/src/lib/app-utils/datasets.d.ts +136 -0
  230. package/src/lib/app-utils/datasets.js +177 -0
  231. package/src/lib/app-utils/datasets.js.map +1 -0
  232. package/src/lib/app-utils/decompress.d.ts +36 -0
  233. package/src/lib/app-utils/decompress.js +32 -0
  234. package/src/lib/app-utils/decompress.js.map +1 -0
  235. package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
  236. package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
  237. package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
  238. package/src/lib/app-utils/deferred-image.d.ts +86 -0
  239. package/src/lib/app-utils/deferred-image.js +83 -0
  240. package/src/lib/app-utils/deferred-image.js.map +1 -0
  241. package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
  242. package/src/lib/app-utils/definition-canvas-tree.js +126 -0
  243. package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
  244. package/src/lib/app-utils/deployment-shape.d.ts +167 -0
  245. package/src/lib/app-utils/deployment-shape.js +238 -0
  246. package/src/lib/app-utils/deployment-shape.js.map +1 -0
  247. package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
  248. package/src/lib/app-utils/detect-template-placeholders.js +53 -0
  249. package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
  250. package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
  251. package/src/lib/app-utils/dmca-counter-notice.js +277 -0
  252. package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
  253. package/src/lib/app-utils/docs-deflection.d.ts +156 -0
  254. package/src/lib/app-utils/docs-deflection.js +547 -0
  255. package/src/lib/app-utils/docs-deflection.js.map +1 -0
  256. package/src/lib/app-utils/docs-help.d.ts +57 -0
  257. package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
  258. package/src/lib/app-utils/docs-help.generated.js +867 -0
  259. package/src/lib/app-utils/docs-help.generated.js.map +1 -0
  260. package/src/lib/app-utils/docs-help.js +46 -0
  261. package/src/lib/app-utils/docs-help.js.map +1 -0
  262. package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
  263. package/src/lib/app-utils/docs-index.generated.js +8388 -0
  264. package/src/lib/app-utils/docs-index.generated.js.map +1 -0
  265. package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
  266. package/src/lib/app-utils/docs-retrieval.js +188 -0
  267. package/src/lib/app-utils/docs-retrieval.js.map +1 -0
  268. package/src/lib/app-utils/document-landmark.d.ts +50 -0
  269. package/src/lib/app-utils/document-landmark.js +100 -0
  270. package/src/lib/app-utils/document-landmark.js.map +1 -0
  271. package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
  272. package/src/lib/app-utils/duplicate-resource.js +206 -0
  273. package/src/lib/app-utils/duplicate-resource.js.map +1 -0
  274. package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
  275. package/src/lib/app-utils/dynamic-list-rule.js +914 -0
  276. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
  277. package/src/lib/app-utils/element-animation.d.ts +200 -0
  278. package/src/lib/app-utils/element-animation.js +233 -0
  279. package/src/lib/app-utils/element-animation.js.map +1 -0
  280. package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
  281. package/src/lib/app-utils/element-hidden-style.js +48 -0
  282. package/src/lib/app-utils/element-hidden-style.js.map +1 -0
  283. package/src/lib/app-utils/element-ui.d.ts +243 -0
  284. package/src/lib/app-utils/element-ui.js +459 -0
  285. package/src/lib/app-utils/element-ui.js.map +1 -0
  286. package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
  287. package/src/lib/app-utils/email-starter-policy.js +327 -0
  288. package/src/lib/app-utils/email-starter-policy.js.map +1 -0
  289. package/src/lib/app-utils/email-topics.d.ts +310 -0
  290. package/src/lib/app-utils/email-topics.js +336 -0
  291. package/src/lib/app-utils/email-topics.js.map +1 -0
  292. package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
  293. package/src/lib/app-utils/enabled-plugins-context.js +113 -0
  294. package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
  295. package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
  296. package/src/lib/app-utils/ensure-canvas-root.js +61 -0
  297. package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
  298. package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
  299. package/src/lib/app-utils/entity-picker-context.js +93 -0
  300. package/src/lib/app-utils/entity-picker-context.js.map +1 -0
  301. package/src/lib/app-utils/error-beacon.d.ts +107 -0
  302. package/src/lib/app-utils/error-beacon.js +296 -0
  303. package/src/lib/app-utils/error-beacon.js.map +1 -0
  304. package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
  305. package/src/lib/app-utils/expand-repeatables.js +299 -0
  306. package/src/lib/app-utils/expand-repeatables.js.map +1 -0
  307. package/src/lib/app-utils/foreign-script.d.ts +82 -0
  308. package/src/lib/app-utils/foreign-script.js +102 -0
  309. package/src/lib/app-utils/foreign-script.js.map +1 -0
  310. package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
  311. package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
  312. package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
  313. package/src/lib/app-utils/form-contract.d.ts +198 -0
  314. package/src/lib/app-utils/form-contract.js +282 -0
  315. package/src/lib/app-utils/form-contract.js.map +1 -0
  316. package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
  317. package/src/lib/app-utils/form-dataset-binding.js +74 -0
  318. package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
  319. package/src/lib/app-utils/forms.d.ts +727 -0
  320. package/src/lib/app-utils/forms.js +777 -0
  321. package/src/lib/app-utils/forms.js.map +1 -0
  322. package/src/lib/app-utils/functions.d.ts +188 -0
  323. package/src/lib/app-utils/functions.js +529 -0
  324. package/src/lib/app-utils/functions.js.map +1 -0
  325. package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
  326. package/src/lib/app-utils/guarded-version-save.js +131 -0
  327. package/src/lib/app-utils/guarded-version-save.js.map +1 -0
  328. package/src/lib/app-utils/health-report.d.ts +1766 -0
  329. package/src/lib/app-utils/health-report.js +2072 -0
  330. package/src/lib/app-utils/health-report.js.map +1 -0
  331. package/src/lib/app-utils/host-naming.d.ts +135 -0
  332. package/src/lib/app-utils/host-naming.js +188 -0
  333. package/src/lib/app-utils/host-naming.js.map +1 -0
  334. package/src/lib/app-utils/host-permissions.d.ts +76 -0
  335. package/src/lib/app-utils/host-permissions.js +119 -0
  336. package/src/lib/app-utils/host-permissions.js.map +1 -0
  337. package/src/lib/app-utils/host-tokens.d.ts +228 -0
  338. package/src/lib/app-utils/host-tokens.js +304 -0
  339. package/src/lib/app-utils/host-tokens.js.map +1 -0
  340. package/src/lib/app-utils/idp-profile.d.ts +83 -0
  341. package/src/lib/app-utils/idp-profile.js +268 -0
  342. package/src/lib/app-utils/idp-profile.js.map +1 -0
  343. package/src/lib/app-utils/image-upload-types.d.ts +49 -0
  344. package/src/lib/app-utils/image-upload-types.js +86 -0
  345. package/src/lib/app-utils/image-upload-types.js.map +1 -0
  346. package/src/lib/app-utils/index.d.ts +18 -0
  347. package/src/lib/app-utils/index.js +23 -0
  348. package/src/lib/app-utils/index.js.map +1 -0
  349. package/src/lib/app-utils/internal-traffic.d.ts +197 -0
  350. package/src/lib/app-utils/internal-traffic.js +288 -0
  351. package/src/lib/app-utils/internal-traffic.js.map +1 -0
  352. package/src/lib/app-utils/lineal-order.d.ts +62 -0
  353. package/src/lib/app-utils/lineal-order.js +65 -0
  354. package/src/lib/app-utils/lineal-order.js.map +1 -0
  355. package/src/lib/app-utils/link-references.d.ts +36 -0
  356. package/src/lib/app-utils/link-references.js +89 -0
  357. package/src/lib/app-utils/link-references.js.map +1 -0
  358. package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
  359. package/src/lib/app-utils/link-target-search-context.js +221 -0
  360. package/src/lib/app-utils/link-target-search-context.js.map +1 -0
  361. package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
  362. package/src/lib/app-utils/list-assignment-policy.js +170 -0
  363. package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
  364. package/src/lib/app-utils/list-import.d.ts +158 -0
  365. package/src/lib/app-utils/list-import.js +332 -0
  366. package/src/lib/app-utils/list-import.js.map +1 -0
  367. package/src/lib/app-utils/llms-txt.d.ts +104 -0
  368. package/src/lib/app-utils/llms-txt.js +144 -0
  369. package/src/lib/app-utils/llms-txt.js.map +1 -0
  370. package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
  371. package/src/lib/app-utils/local-storage-budget.js +153 -0
  372. package/src/lib/app-utils/local-storage-budget.js.map +1 -0
  373. package/src/lib/app-utils/lockdown.d.ts +698 -0
  374. package/src/lib/app-utils/lockdown.js +929 -0
  375. package/src/lib/app-utils/lockdown.js.map +1 -0
  376. package/src/lib/app-utils/margin-utilization.d.ts +267 -0
  377. package/src/lib/app-utils/margin-utilization.js +351 -0
  378. package/src/lib/app-utils/margin-utilization.js.map +1 -0
  379. package/src/lib/app-utils/markdown-lite.d.ts +297 -0
  380. package/src/lib/app-utils/markdown-lite.js +705 -0
  381. package/src/lib/app-utils/markdown-lite.js.map +1 -0
  382. package/src/lib/app-utils/marketing-consent.d.ts +704 -0
  383. package/src/lib/app-utils/marketing-consent.js +783 -0
  384. package/src/lib/app-utils/marketing-consent.js.map +1 -0
  385. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
  386. package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
  387. package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
  388. package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
  389. package/src/lib/app-utils/marketplace-overrides.js +462 -0
  390. package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
  391. package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
  392. package/src/lib/app-utils/marketplace-provenance.js +136 -0
  393. package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
  394. package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
  395. package/src/lib/app-utils/marketplace-theme.js +525 -0
  396. package/src/lib/app-utils/marketplace-theme.js.map +1 -0
  397. package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
  398. package/src/lib/app-utils/marketplace-update-state.js +132 -0
  399. package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
  400. package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
  401. package/src/lib/app-utils/marketplace-verification.js +81 -0
  402. package/src/lib/app-utils/marketplace-verification.js.map +1 -0
  403. package/src/lib/app-utils/measure-node-map.d.ts +76 -0
  404. package/src/lib/app-utils/measure-node-map.js +111 -0
  405. package/src/lib/app-utils/measure-node-map.js.map +1 -0
  406. package/src/lib/app-utils/media-alt.d.ts +55 -0
  407. package/src/lib/app-utils/media-alt.js +58 -0
  408. package/src/lib/app-utils/media-alt.js.map +1 -0
  409. package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
  410. package/src/lib/app-utils/media-asset-facts.js +467 -0
  411. package/src/lib/app-utils/media-asset-facts.js.map +1 -0
  412. package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
  413. package/src/lib/app-utils/media-cdn-scope.js +75 -0
  414. package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
  415. package/src/lib/app-utils/media-folders.d.ts +161 -0
  416. package/src/lib/app-utils/media-folders.js +230 -0
  417. package/src/lib/app-utils/media-folders.js.map +1 -0
  418. package/src/lib/app-utils/media-metadata.d.ts +277 -0
  419. package/src/lib/app-utils/media-metadata.js +388 -0
  420. package/src/lib/app-utils/media-metadata.js.map +1 -0
  421. package/src/lib/app-utils/media-picker-context.d.ts +93 -0
  422. package/src/lib/app-utils/media-picker-context.js +26 -0
  423. package/src/lib/app-utils/media-picker-context.js.map +1 -0
  424. package/src/lib/app-utils/media-quarantine.d.ts +247 -0
  425. package/src/lib/app-utils/media-quarantine.js +323 -0
  426. package/src/lib/app-utils/media-quarantine.js.map +1 -0
  427. package/src/lib/app-utils/media-ref.d.ts +661 -0
  428. package/src/lib/app-utils/media-ref.js +1055 -0
  429. package/src/lib/app-utils/media-ref.js.map +1 -0
  430. package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
  431. package/src/lib/app-utils/media-takedown-reach.js +143 -0
  432. package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
  433. package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
  434. package/src/lib/app-utils/member-email-aliases.js +217 -0
  435. package/src/lib/app-utils/member-email-aliases.js.map +1 -0
  436. package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
  437. package/src/lib/app-utils/merge-node-sx.js +123 -0
  438. package/src/lib/app-utils/merge-node-sx.js.map +1 -0
  439. package/src/lib/app-utils/name-match.d.ts +155 -0
  440. package/src/lib/app-utils/name-match.js +175 -0
  441. package/src/lib/app-utils/name-match.js.map +1 -0
  442. package/src/lib/app-utils/name-search.d.ts +117 -0
  443. package/src/lib/app-utils/name-search.js +145 -0
  444. package/src/lib/app-utils/name-search.js.map +1 -0
  445. package/src/lib/app-utils/node-capabilities.d.ts +85 -0
  446. package/src/lib/app-utils/node-capabilities.js +88 -0
  447. package/src/lib/app-utils/node-capabilities.js.map +1 -0
  448. package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
  449. package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
  450. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
  451. package/src/lib/app-utils/node-identity.d.ts +47 -0
  452. package/src/lib/app-utils/node-identity.js +50 -0
  453. package/src/lib/app-utils/node-identity.js.map +1 -0
  454. package/src/lib/app-utils/node-interactions.d.ts +102 -0
  455. package/src/lib/app-utils/node-interactions.js +192 -0
  456. package/src/lib/app-utils/node-interactions.js.map +1 -0
  457. package/src/lib/app-utils/node-url-policy.d.ts +54 -0
  458. package/src/lib/app-utils/node-url-policy.js +72 -0
  459. package/src/lib/app-utils/node-url-policy.js.map +1 -0
  460. package/src/lib/app-utils/notifications.d.ts +71 -0
  461. package/src/lib/app-utils/notifications.js +101 -0
  462. package/src/lib/app-utils/notifications.js.map +1 -0
  463. package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
  464. package/src/lib/app-utils/onboarding-deep-link.js +142 -0
  465. package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
  466. package/src/lib/app-utils/operator-identity.d.ts +207 -0
  467. package/src/lib/app-utils/operator-identity.js +186 -0
  468. package/src/lib/app-utils/operator-identity.js.map +1 -0
  469. package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
  470. package/src/lib/app-utils/org-billing-doc.js +238 -0
  471. package/src/lib/app-utils/org-billing-doc.js.map +1 -0
  472. package/src/lib/app-utils/org-override-reason.d.ts +100 -0
  473. package/src/lib/app-utils/org-override-reason.js +116 -0
  474. package/src/lib/app-utils/org-override-reason.js.map +1 -0
  475. package/src/lib/app-utils/org-permissions.d.ts +194 -0
  476. package/src/lib/app-utils/org-permissions.js +357 -0
  477. package/src/lib/app-utils/org-permissions.js.map +1 -0
  478. package/src/lib/app-utils/org-roles.d.ts +72 -0
  479. package/src/lib/app-utils/org-roles.js +131 -0
  480. package/src/lib/app-utils/org-roles.js.map +1 -0
  481. package/src/lib/app-utils/organizations.d.ts +407 -0
  482. package/src/lib/app-utils/organizations.js +511 -0
  483. package/src/lib/app-utils/organizations.js.map +1 -0
  484. package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
  485. package/src/lib/app-utils/page-header-actions-context.js +58 -0
  486. package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
  487. package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
  488. package/src/lib/app-utils/page-header-record-context.js +64 -0
  489. package/src/lib/app-utils/page-header-record-context.js.map +1 -0
  490. package/src/lib/app-utils/page-markdown.d.ts +103 -0
  491. package/src/lib/app-utils/page-markdown.js +385 -0
  492. package/src/lib/app-utils/page-markdown.js.map +1 -0
  493. package/src/lib/app-utils/paid-media-source.d.ts +90 -0
  494. package/src/lib/app-utils/paid-media-source.js +184 -0
  495. package/src/lib/app-utils/paid-media-source.js.map +1 -0
  496. package/src/lib/app-utils/palette-sx.d.ts +34 -0
  497. package/src/lib/app-utils/palette-sx.js +150 -0
  498. package/src/lib/app-utils/palette-sx.js.map +1 -0
  499. package/src/lib/app-utils/password-policy.d.ts +47 -0
  500. package/src/lib/app-utils/password-policy.js +46 -0
  501. package/src/lib/app-utils/password-policy.js.map +1 -0
  502. package/src/lib/app-utils/payments-configured.d.ts +84 -0
  503. package/src/lib/app-utils/payments-configured.js +88 -0
  504. package/src/lib/app-utils/payments-configured.js.map +1 -0
  505. package/src/lib/app-utils/person-erasure.d.ts +126 -0
  506. package/src/lib/app-utils/person-erasure.js +121 -0
  507. package/src/lib/app-utils/person-erasure.js.map +1 -0
  508. package/src/lib/app-utils/person-key.d.ts +32 -0
  509. package/src/lib/app-utils/person-key.js +62 -0
  510. package/src/lib/app-utils/person-key.js.map +1 -0
  511. package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
  512. package/src/lib/app-utils/plan-entitlements.js +4085 -0
  513. package/src/lib/app-utils/plan-entitlements.js.map +1 -0
  514. package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
  515. package/src/lib/app-utils/platform-ad-conversions.js +174 -0
  516. package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
  517. package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
  518. package/src/lib/app-utils/platform-advertising-tags.js +203 -0
  519. package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
  520. package/src/lib/app-utils/platform-brand.d.ts +151 -0
  521. package/src/lib/app-utils/platform-brand.js +175 -0
  522. package/src/lib/app-utils/platform-brand.js.map +1 -0
  523. package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
  524. package/src/lib/app-utils/platform-consent-default.js +295 -0
  525. package/src/lib/app-utils/platform-consent-default.js.map +1 -0
  526. package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
  527. package/src/lib/app-utils/platform-marketing-consent.js +182 -0
  528. package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
  529. package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
  530. package/src/lib/app-utils/platform-marketing-host.js +97 -0
  531. package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
  532. package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
  533. package/src/lib/app-utils/platform-visitor-consent.js +533 -0
  534. package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
  535. package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
  536. package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
  537. package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
  538. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
  539. package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
  540. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
  541. package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
  542. package/src/lib/app-utils/plugin-artifact-path.js +33 -0
  543. package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
  544. package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
  545. package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
  546. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
  547. package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
  548. package/src/lib/app-utils/plugin-manifest.js +687 -0
  549. package/src/lib/app-utils/plugin-manifest.js.map +1 -0
  550. package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
  551. package/src/lib/app-utils/published-legal-pages.js +90 -0
  552. package/src/lib/app-utils/published-legal-pages.js.map +1 -0
  553. package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
  554. package/src/lib/app-utils/publisher-agreement.js +274 -0
  555. package/src/lib/app-utils/publisher-agreement.js.map +1 -0
  556. package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
  557. package/src/lib/app-utils/publisher-attestation.js +158 -0
  558. package/src/lib/app-utils/publisher-attestation.js.map +1 -0
  559. package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
  560. package/src/lib/app-utils/recipient-email-render.js +221 -0
  561. package/src/lib/app-utils/recipient-email-render.js.map +1 -0
  562. package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
  563. package/src/lib/app-utils/redispatch-caught-error.js +46 -0
  564. package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
  565. package/src/lib/app-utils/registering-plugin.d.ts +19 -0
  566. package/src/lib/app-utils/registering-plugin.js +38 -0
  567. package/src/lib/app-utils/registering-plugin.js.map +1 -0
  568. package/src/lib/app-utils/release-flags.d.ts +283 -0
  569. package/src/lib/app-utils/release-flags.js +518 -0
  570. package/src/lib/app-utils/release-flags.js.map +1 -0
  571. package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
  572. package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
  573. package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
  574. package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
  575. package/src/lib/app-utils/repeat-infringer.js +188 -0
  576. package/src/lib/app-utils/repeat-infringer.js.map +1 -0
  577. package/src/lib/app-utils/repeat-sources.d.ts +115 -0
  578. package/src/lib/app-utils/repeat-sources.js +86 -0
  579. package/src/lib/app-utils/repeat-sources.js.map +1 -0
  580. package/src/lib/app-utils/request-geo.d.ts +114 -0
  581. package/src/lib/app-utils/request-geo.js +247 -0
  582. package/src/lib/app-utils/request-geo.js.map +1 -0
  583. package/src/lib/app-utils/request-ip.d.ts +213 -0
  584. package/src/lib/app-utils/request-ip.js +344 -0
  585. package/src/lib/app-utils/request-ip.js.map +1 -0
  586. package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
  587. package/src/lib/app-utils/resolve-named-tokens.js +59 -0
  588. package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
  589. package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
  590. package/src/lib/app-utils/responsive-typography-sx.js +122 -0
  591. package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
  592. package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
  593. package/src/lib/app-utils/reusable-component-keys.js +140 -0
  594. package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
  595. package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
  596. package/src/lib/app-utils/reusable-prop-values.js +494 -0
  597. package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
  598. package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
  599. package/src/lib/app-utils/safe-json-ld.js +37 -0
  600. package/src/lib/app-utils/safe-json-ld.js.map +1 -0
  601. package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
  602. package/src/lib/app-utils/sanitize-svg.js +460 -0
  603. package/src/lib/app-utils/sanitize-svg.js.map +1 -0
  604. package/src/lib/app-utils/scheme-sx.d.ts +84 -0
  605. package/src/lib/app-utils/scheme-sx.js +148 -0
  606. package/src/lib/app-utils/scheme-sx.js.map +1 -0
  607. package/src/lib/app-utils/scope-tokens.d.ts +249 -0
  608. package/src/lib/app-utils/scope-tokens.js +331 -0
  609. package/src/lib/app-utils/scope-tokens.js.map +1 -0
  610. package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
  611. package/src/lib/app-utils/screen-link-context-value.js +43 -0
  612. package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
  613. package/src/lib/app-utils/screen-link-context.d.ts +185 -0
  614. package/src/lib/app-utils/screen-link-context.js +304 -0
  615. package/src/lib/app-utils/screen-link-context.js.map +1 -0
  616. package/src/lib/app-utils/screen-link-value.d.ts +269 -0
  617. package/src/lib/app-utils/screen-link-value.js +384 -0
  618. package/src/lib/app-utils/screen-link-value.js.map +1 -0
  619. package/src/lib/app-utils/screen-route.d.ts +669 -0
  620. package/src/lib/app-utils/screen-route.js +751 -0
  621. package/src/lib/app-utils/screen-route.js.map +1 -0
  622. package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
  623. package/src/lib/app-utils/screen-seo-fields.js +42 -0
  624. package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
  625. package/src/lib/app-utils/search-indexing.d.ts +162 -0
  626. package/src/lib/app-utils/search-indexing.js +207 -0
  627. package/src/lib/app-utils/search-indexing.js.map +1 -0
  628. package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
  629. package/src/lib/app-utils/seo-listing-fields.js +75 -0
  630. package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
  631. package/src/lib/app-utils/seo-locale.d.ts +119 -0
  632. package/src/lib/app-utils/seo-locale.js +133 -0
  633. package/src/lib/app-utils/seo-locale.js.map +1 -0
  634. package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
  635. package/src/lib/app-utils/seo-title-variables.js +190 -0
  636. package/src/lib/app-utils/seo-title-variables.js.map +1 -0
  637. package/src/lib/app-utils/seo-title.d.ts +70 -0
  638. package/src/lib/app-utils/seo-title.js +117 -0
  639. package/src/lib/app-utils/seo-title.js.map +1 -0
  640. package/src/lib/app-utils/server.d.ts +174 -0
  641. package/src/lib/app-utils/server.js +314 -0
  642. package/src/lib/app-utils/server.js.map +1 -0
  643. package/src/lib/app-utils/site-context.d.ts +106 -0
  644. package/src/lib/app-utils/site-context.js +100 -0
  645. package/src/lib/app-utils/site-context.js.map +1 -0
  646. package/src/lib/app-utils/sitemap.d.ts +117 -0
  647. package/src/lib/app-utils/sitemap.js +183 -0
  648. package/src/lib/app-utils/sitemap.js.map +1 -0
  649. package/src/lib/app-utils/social-image.d.ts +112 -0
  650. package/src/lib/app-utils/social-image.js +191 -0
  651. package/src/lib/app-utils/social-image.js.map +1 -0
  652. package/src/lib/app-utils/starter-templates.d.ts +99 -0
  653. package/src/lib/app-utils/starter-templates.js +579 -0
  654. package/src/lib/app-utils/starter-templates.js.map +1 -0
  655. package/src/lib/app-utils/stored-nodes.d.ts +120 -0
  656. package/src/lib/app-utils/stored-nodes.js +174 -0
  657. package/src/lib/app-utils/stored-nodes.js.map +1 -0
  658. package/src/lib/app-utils/strip-undefined.d.ts +59 -0
  659. package/src/lib/app-utils/strip-undefined.js +95 -0
  660. package/src/lib/app-utils/strip-undefined.js.map +1 -0
  661. package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
  662. package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
  663. package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
  664. package/src/lib/app-utils/support-tiers.d.ts +108 -0
  665. package/src/lib/app-utils/support-tiers.js +201 -0
  666. package/src/lib/app-utils/support-tiers.js.map +1 -0
  667. package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
  668. package/src/lib/app-utils/timezone-geo-hint.js +180 -0
  669. package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
  670. package/src/lib/app-utils/upload-cors.d.ts +155 -0
  671. package/src/lib/app-utils/upload-cors.js +254 -0
  672. package/src/lib/app-utils/upload-cors.js.map +1 -0
  673. package/src/lib/app-utils/upload-inspection.d.ts +159 -0
  674. package/src/lib/app-utils/upload-inspection.js +539 -0
  675. package/src/lib/app-utils/upload-inspection.js.map +1 -0
  676. package/src/lib/app-utils/url-slug.d.ts +40 -0
  677. package/src/lib/app-utils/url-slug.js +42 -0
  678. package/src/lib/app-utils/url-slug.js.map +1 -0
  679. package/src/lib/app-utils/usage-budget.d.ts +429 -0
  680. package/src/lib/app-utils/usage-budget.js +421 -0
  681. package/src/lib/app-utils/usage-budget.js.map +1 -0
  682. package/src/lib/app-utils/variables.d.ts +96 -0
  683. package/src/lib/app-utils/variables.js +233 -0
  684. package/src/lib/app-utils/variables.js.map +1 -0
  685. package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
  686. package/src/lib/app-utils/video-asset-facts.js +70 -0
  687. package/src/lib/app-utils/video-asset-facts.js.map +1 -0
  688. package/src/lib/app-utils/video-object.d.ts +89 -0
  689. package/src/lib/app-utils/video-object.js +245 -0
  690. package/src/lib/app-utils/video-object.js.map +1 -0
  691. package/src/lib/app-utils/visitor-consent.d.ts +757 -0
  692. package/src/lib/app-utils/visitor-consent.js +981 -0
  693. package/src/lib/app-utils/visitor-consent.js.map +1 -0
  694. package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
  695. package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
  696. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
  697. package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
  698. package/src/lib/app-utils/web-vitals-rum.js +278 -0
  699. package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
  700. package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
  701. package/src/lib/app-utils/webhook-delivery.js +413 -0
  702. package/src/lib/app-utils/webhook-delivery.js.map +1 -0
  703. package/src/lib/app-utils/where-used.d.ts +57 -0
  704. package/src/lib/app-utils/where-used.js +59 -0
  705. package/src/lib/app-utils/where-used.js.map +1 -0
  706. package/src/lib/app-utils/wistia-embed.d.ts +86 -0
  707. package/src/lib/app-utils/wistia-embed.js +119 -0
  708. package/src/lib/app-utils/wistia-embed.js.map +1 -0
  709. package/src/lib/app-utils/workflows.d.ts +136 -0
  710. package/src/lib/app-utils/workflows.js +346 -0
  711. package/src/lib/app-utils/workflows.js.map +1 -0
  712. package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
  713. package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
  714. package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
  715. package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
  716. package/src/lib/canvas-manager/canvas-manager.js +1311 -0
  717. package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
  718. package/src/lib/canvas-manager/index.d.ts +20 -0
  719. package/src/lib/canvas-manager/index.js +21 -0
  720. package/src/lib/canvas-manager/index.js.map +1 -0
  721. package/src/lib/canvas-manager/stores/index.d.ts +17 -0
  722. package/src/lib/canvas-manager/stores/index.js +18 -0
  723. package/src/lib/canvas-manager/stores/index.js.map +1 -0
  724. package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
  725. package/src/lib/canvas-manager/stores/node.store.js +45 -0
  726. package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
  727. package/src/lib/components-manager/components-manager.d.ts +56 -0
  728. package/src/lib/components-manager/components-manager.js +191 -0
  729. package/src/lib/components-manager/components-manager.js.map +1 -0
  730. package/src/lib/components-manager/index.d.ts +18 -0
  731. package/src/lib/components-manager/index.js +19 -0
  732. package/src/lib/components-manager/index.js.map +1 -0
  733. package/src/lib/emit-manager/emit-manager.d.ts +56 -0
  734. package/src/lib/emit-manager/emit-manager.js +60 -0
  735. package/src/lib/emit-manager/emit-manager.js.map +1 -0
  736. package/src/lib/emit-manager/index.d.ts +18 -0
  737. package/src/lib/emit-manager/index.js +19 -0
  738. package/src/lib/emit-manager/index.js.map +1 -0
  739. package/src/lib/foundation/constants/_internal.d.ts +18 -0
  740. package/src/lib/foundation/constants/_internal.js +62 -0
  741. package/src/lib/foundation/constants/_internal.js.map +1 -0
  742. package/src/lib/foundation/constants/app.d.ts +23 -0
  743. package/src/lib/foundation/constants/app.js +25 -0
  744. package/src/lib/foundation/constants/app.js.map +1 -0
  745. package/src/lib/foundation/constants/canvas.d.ts +18 -0
  746. package/src/lib/foundation/constants/canvas.js +18 -0
  747. package/src/lib/foundation/constants/canvas.js.map +1 -0
  748. package/src/lib/foundation/constants/components.d.ts +54 -0
  749. package/src/lib/foundation/constants/components.js +61 -0
  750. package/src/lib/foundation/constants/components.js.map +1 -0
  751. package/src/lib/foundation/constants/shared.d.ts +50 -0
  752. package/src/lib/foundation/constants/shared.js +49 -0
  753. package/src/lib/foundation/constants/shared.js.map +1 -0
  754. package/src/lib/foundation/constants/symbol.d.ts +63 -0
  755. package/src/lib/foundation/constants/symbol.js +75 -0
  756. package/src/lib/foundation/constants/symbol.js.map +1 -0
  757. package/src/lib/foundation/definitions/components.types.d.ts +372 -0
  758. package/src/lib/foundation/definitions/components.types.js +180 -0
  759. package/src/lib/foundation/definitions/components.types.js.map +1 -0
  760. package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
  761. package/src/lib/foundation/definitions/contact.types.js +107 -0
  762. package/src/lib/foundation/definitions/contact.types.js.map +1 -0
  763. package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
  764. package/src/lib/foundation/definitions/host-content-collections.js +219 -0
  765. package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
  766. package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
  767. package/src/lib/foundation/definitions/org-billing.types.js +77 -0
  768. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
  769. package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
  770. package/src/lib/foundation/definitions/organization.types.js +42 -0
  771. package/src/lib/foundation/definitions/organization.types.js.map +1 -0
  772. package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
  773. package/src/lib/foundation/definitions/platform.types.js +124 -0
  774. package/src/lib/foundation/definitions/platform.types.js.map +1 -0
  775. package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
  776. package/src/lib/foundation/definitions/property-kinds.js +565 -0
  777. package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
  778. package/src/lib/foundation/definitions/shared.d.ts +23 -0
  779. package/src/lib/foundation/definitions/shared.js +18 -0
  780. package/src/lib/foundation/definitions/shared.js.map +1 -0
  781. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
  782. package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
  783. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
  784. package/src/lib/foundation/index.d.ts +32 -0
  785. package/src/lib/foundation/index.js +67 -0
  786. package/src/lib/foundation/index.js.map +1 -0
  787. package/src/lib/lifecycle.d.ts +24 -0
  788. package/src/lib/lifecycle.js +39 -0
  789. package/src/lib/lifecycle.js.map +1 -0
  790. package/src/lib/mst/common.d.ts +17 -0
  791. package/src/lib/mst/common.js +23 -0
  792. package/src/lib/mst/common.js.map +1 -0
  793. package/src/lib/mst/index.d.ts +19 -0
  794. package/src/lib/mst/index.js +20 -0
  795. package/src/lib/mst/index.js.map +1 -0
  796. package/src/lib/mst/json.d.ts +22 -0
  797. package/src/lib/mst/json.js +23 -0
  798. package/src/lib/mst/json.js.map +1 -0
  799. package/src/lib/mst/types.d.ts +20 -0
  800. package/src/lib/mst/types.js +18 -0
  801. package/src/lib/mst/types.js.map +1 -0
  802. package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
  803. package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
  804. package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
  805. package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
  806. package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
  807. package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
  808. package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
  809. package/src/lib/plugin-manager/custom-fields.js +39 -0
  810. package/src/lib/plugin-manager/custom-fields.js.map +1 -0
  811. package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
  812. package/src/lib/plugin-manager/editor-sessions.js +137 -0
  813. package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
  814. package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
  815. package/src/lib/plugin-manager/enabled-plugins.js +403 -0
  816. package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
  817. package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
  818. package/src/lib/plugin-manager/feature-plugins.js +609 -0
  819. package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
  820. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
  821. package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
  822. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
  823. package/src/lib/plugin-manager/index.d.ts +42 -0
  824. package/src/lib/plugin-manager/index.js +46 -0
  825. package/src/lib/plugin-manager/index.js.map +1 -0
  826. package/src/lib/plugin-manager/install-presets.d.ts +93 -0
  827. package/src/lib/plugin-manager/install-presets.js +86 -0
  828. package/src/lib/plugin-manager/install-presets.js.map +1 -0
  829. package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
  830. package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
  831. package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
  832. package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
  833. package/src/lib/plugin-manager/order-fulfilment.js +104 -0
  834. package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
  835. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
  836. package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
  837. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
  838. package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
  839. package/src/lib/plugin-manager/plugin-bridge.js +154 -0
  840. package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
  841. package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
  842. package/src/lib/plugin-manager/plugin-config.js +228 -0
  843. package/src/lib/plugin-manager/plugin-config.js.map +1 -0
  844. package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
  845. package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
  846. package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
  847. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
  848. package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
  849. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
  850. package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
  851. package/src/lib/plugin-manager/plugin-contributions.js +283 -0
  852. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
  853. package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
  854. package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
  855. package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
  856. package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
  857. package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
  858. package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
  859. package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
  860. package/src/lib/plugin-manager/plugin-events.js +79 -0
  861. package/src/lib/plugin-manager/plugin-events.js.map +1 -0
  862. package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
  863. package/src/lib/plugin-manager/plugin-figures.js +252 -0
  864. package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
  865. package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
  866. package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
  867. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
  868. package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
  869. package/src/lib/plugin-manager/plugin-jobs.js +182 -0
  870. package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
  871. package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
  872. package/src/lib/plugin-manager/plugin-loader.js +223 -0
  873. package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
  874. package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
  875. package/src/lib/plugin-manager/plugin-manager.js +343 -0
  876. package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
  877. package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
  878. package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
  879. package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
  880. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
  881. package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
  882. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
  883. package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
  884. package/src/lib/plugin-manager/plugin-permissions.js +77 -0
  885. package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
  886. package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
  887. package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
  888. package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
  889. package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
  890. package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
  891. package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
  892. package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
  893. package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
  894. package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
  895. package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
  896. package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
  897. package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
  898. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
  899. package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
  900. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
  901. package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
  902. package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
  903. package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
  904. package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
  905. package/src/lib/plugin-manager/plugin-services.js +153 -0
  906. package/src/lib/plugin-manager/plugin-services.js.map +1 -0
  907. package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
  908. package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
  909. package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
  910. package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
  911. package/src/lib/plugin-manager/plugin-styles.js +186 -0
  912. package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
  913. package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
  914. package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
  915. package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
  916. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
  917. package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
  918. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
  919. package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
  920. package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
  921. package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
  922. package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
  923. package/src/lib/plugin-manager/plugin-zones.js +74 -0
  924. package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
  925. package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
  926. package/src/lib/plugin-manager/realm-plugins.js +196 -0
  927. package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
  928. package/src/lib/plugin-manager/realm-server.d.ts +54 -0
  929. package/src/lib/plugin-manager/realm-server.js +88 -0
  930. package/src/lib/plugin-manager/realm-server.js.map +1 -0
  931. package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
  932. package/src/lib/plugin-manager/record-zone-props.js +31 -0
  933. package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
  934. package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
  935. package/src/lib/plugin-manager/site-page-hooks.js +114 -0
  936. package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
  937. package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
  938. package/src/lib/plugin-manager/site-runtime.js +25 -0
  939. package/src/lib/plugin-manager/site-runtime.js.map +1 -0
  940. package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
  941. package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
  942. package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
  943. package/src/lib/types/ast.d.ts +199 -0
  944. package/src/lib/types/ast.js +20 -0
  945. package/src/lib/types/ast.js.map +1 -0
  946. package/src/lib/types/index.d.ts +20 -0
  947. package/src/lib/types/index.js +21 -0
  948. package/src/lib/types/index.js.map +1 -0
  949. package/src/lib/types/nodes.d.ts +608 -0
  950. package/src/lib/types/nodes.js +28 -0
  951. package/src/lib/types/nodes.js.map +1 -0
  952. package/src/lib/types/routing.d.ts +17 -0
  953. package/src/lib/types/routing.js +18 -0
  954. package/src/lib/types/routing.js.map +1 -0
  955. package/src/lib/types/screen.d.ts +23 -0
  956. package/src/lib/types/screen.js +18 -0
  957. package/src/lib/types/screen.js.map +1 -0
  958. package/src/lib/utils.d.ts +25 -0
  959. package/src/lib/utils.js +42 -0
  960. package/src/lib/utils.js.map +1 -0
  961. package/src/server.d.ts +37 -0
  962. package/src/server.js +55 -0
  963. package/src/server.js.map +1 -0
@@ -0,0 +1,547 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { DOCS_SITE_ORIGIN, docsDocumentFrequency, tokenize } from "./docs-retrieval.js";
17
+ /**
18
+ * Retrieval-first answering for Aglyn Assist (AGL-2486) — the deflection gate.
19
+ *
20
+ * Most assist traffic is "how do I X", and the answer to "how do I X" is
21
+ * already written down in `apps/docs/docs`. Sending that question to a model
22
+ * so the model can read the docs section back to the user pays provider money
23
+ * to reformat prose we wrote ourselves. This module decides when retrieval is
24
+ * confident enough to hand the docs straight over, and composes the answer
25
+ * when it is. Escalation to the model is what happens the rest of the time —
26
+ * it is the fallback, not the default.
27
+ *
28
+ * ## The one rule: never fabricate
29
+ *
30
+ * A deflected answer contains exactly two kinds of text:
31
+ *
32
+ * 1. Fixed template strings from this file, which say nothing about the
33
+ * product — they name the page and introduce the quote.
34
+ * 2. Section text copied VERBATIM out of the docs index, with the URL of
35
+ * the page it came from.
36
+ *
37
+ * There is no summarisation, no paraphrase and no stitching of adjacent
38
+ * sections into a claim neither one makes. The spec asserts it by
39
+ * RECONSTRUCTION — "never fabricate — every word is template or verbatim
40
+ * docs" — stripping the template from a composed answer and requiring what is
41
+ * left to be a prefix of a real section's `text`. That property is the whole
42
+ * safety argument, because a wrong retrieval answer is worse than an
43
+ * escalation — it is confidently wrong prose delivered to a paying customer
44
+ * with a citation under it, which is the shape people trust most.
45
+ *
46
+ * ## What "confident" means
47
+ *
48
+ * Seven conditions, ALL of which must hold. Any one failing escalates; there
49
+ * is no partial-credit path where a weak match produces a hedged answer,
50
+ * because a hedged wrong answer is still a wrong answer and it has already
51
+ * cost the user the click.
52
+ *
53
+ * 1. **The question stands on its own.** A follow-up is usually not
54
+ * self-contained: "does that work on the free plan?" retrieves the
55
+ * billing pages beautifully and answers a question nobody asked. The
56
+ * conversation is the missing half and only the model has it.
57
+ *
58
+ * The gate is NOT "no prior turn" (AGL-2486). Not every follow-up leans
59
+ * on the transcript: the second question in a thread is very often a
60
+ * fresh, complete question that happens to be asked second. Refusing all
61
+ * of them means a thread answers its first question from the docs and
62
+ * then escalates forever — and on a deployment with no AI provider
63
+ * key that reads as "Aglyn Assist is not configured",
64
+ * one question in, to a user who just watched it work. A product that
65
+ * answers exactly once per thread is worse than one that never answers,
66
+ * because the second refusal looks like a fault rather than a limit.
67
+ *
68
+ * So the gate now asks whether THIS question stands alone, and holds a
69
+ * raised bar when it does — see {@link questionStandsAlone} and the
70
+ * `FOLLOW_UP_*` constants.
71
+ * 2. **Enough question.** At least {@link MIN_QUESTION_TOKENS} distinct
72
+ * content tokens after stop-word removal. Below that there is not enough
73
+ * of a question to be confident ABOUT.
74
+ * 3. **Not a generative request.** "write me a hero headline" is the copy
75
+ * assistant's job, not a docs lookup, and no docs page answers it.
76
+ * 4. **Not a diagnostic.** "why isn't my domain verifying" has a
77
+ * troubleshooting page, and dumping that page at someone whose actual
78
+ * problem is one of nine listed causes is exactly the confidently-wrong
79
+ * failure. Diagnostics need the workspace's own state, which is the
80
+ * level-2 context only the model gets.
81
+ * 5. **Absolute score.** The top section scores at least
82
+ * {@link MIN_TOP_SCORE}.
83
+ * 6. **Page dominance.** The winning page beats the best RIVAL page by at
84
+ * least {@link MIN_PAGE_MARGIN}. Measured against the runner-up page
85
+ * rather than as a share of the whole retrieved set, because the set is
86
+ * six sections wide: a page that is unambiguously right still holds a
87
+ * minority of a six-way split the moment three neighbouring pages use the
88
+ * same nouns, and a share test reads that dilution as doubt. And the
89
+ * comparison is page-to-page, not section-to-section — sections of ONE
90
+ * page scoring alike is agreement, which a section margin scores as a tie.
91
+ * 7. **Substance.** The winning section carries at least
92
+ * {@link MIN_SECTION_CHARS} of text. A three-word stub under a heading is
93
+ * a pointer, not an answer.
94
+ *
95
+ * Below the bar the request proceeds exactly as it did before this module
96
+ * existed: the same sections are still retrieved and still ground the model's
97
+ * prompt. Deflection removes model calls; it never removes grounding.
98
+ *
99
+ * ## The thresholds are measured, not guessed
100
+ *
101
+ * `docs-deflection.spec.ts` carries a fixed set of realistic questions —
102
+ * positives written in user vocabulary rather than lifted from docs headings,
103
+ * and negatives that MUST escalate — and asserts a floor on the deflection
104
+ * rate and a ceiling of zero on the negatives. Retuning a constant here
105
+ * without rerunning that spec is how a threshold ends up set by whoever
106
+ * touched it last.
107
+ */ /**
108
+ * Distinct content tokens a question needs before it can be answered.
109
+ *
110
+ * Two, not three, and the difference is most of the corpus: "how do I install
111
+ * a plugin", "what are dataset relations" and "how do I cancel my
112
+ * subscription" all reduce to exactly two content tokens once the stop words
113
+ * go, and every one of them is a plain docs lookup. Three excluded them all.
114
+ *
115
+ * Two is safe here only because the gates below are not a checklist a weak
116
+ * question can pass by being short: a two-token question must have BOTH
117
+ * tokens carried by the winning page (the IDF weighting cannot rescue it —
118
+ * there is nothing generic to discount), and the page must still clear the
119
+ * score floor and out-score its rival. "is my site down" has two tokens and
120
+ * fails on dominance, not on length.
121
+ */ const MIN_QUESTION_TOKENS = 2;
122
+ /**
123
+ * Absolute floor on the winning section's retrieval score.
124
+ *
125
+ * The scorer gives 2.5 for a title hit, 2 for a heading hit and up to ~2.2 per
126
+ * body term — about 6.7 for one term landing everywhere at once. 5 is
127
+ * therefore roughly "two question terms landed and at least one of them hit
128
+ * the page's own statement of topic". Below that the match is incidental
129
+ * vocabulary rather than a page about the thing.
130
+ *
131
+ * Measured down from 6, which cost five ordinary lookups scoring 4.4–5.9
132
+ * ("how do I cancel my subscription", "how do I set up sso for my team") and
133
+ * bought nothing: the negative set does not move between the two values,
134
+ * because what actually stops those is coverage and dominance, not the floor.
135
+ */ const MIN_TOP_SCORE = 5;
136
+ /**
137
+ * How far the winning page must out-score the best rival page.
138
+ *
139
+ * 1.3x — the winner needs a visible lead, not a photo finish. Two pages
140
+ * within 30% of each other on the same question means retrieval genuinely
141
+ * does not know which one the user meant, and picking is a coin flip dressed
142
+ * up as an answer.
143
+ *
144
+ * A question that retrieves only ONE page has no rival and passes this gate
145
+ * outright; the score floor and coverage are what bound it there.
146
+ */ const MIN_PAGE_MARGIN = 1.3;
147
+ /**
148
+ * Weighted fraction of the question the winning page must actually contain.
149
+ * Coverage and score answer different questions: score says the page matched
150
+ * strongly, coverage says the page did not IGNORE part of what was asked.
151
+ * "how do I password protect a screen on the free plan" scores highly on the
152
+ * site-protection page while silently dropping "free plan", and the answer
153
+ * that comes back is then wrong in the one way that matters.
154
+ *
155
+ * ⚠️ WEIGHTED BY IDF, and an unweighted version of this test is why nine
156
+ * perfectly ordinary questions escalated in the first measurement. "how do I
157
+ * make a reusable component" covers `reusable` and `component` and misses
158
+ * `make`, because the page says "create" — 2/3, under the bar, escalated. The
159
+ * miss carried no information: `make` appears in a third of the corpus, so
160
+ * its absence from one page says nothing, while `reusable` appearing says
161
+ * almost everything. Counting tokens equally lets the most common words in
162
+ * English veto a match on the rarest. Weighting by how rare a term is in THIS
163
+ * corpus makes the test ask what it always meant to ask — did the page cover
164
+ * the DISTINCTIVE part of the question.
165
+ */ const MIN_COVERAGE = 0.7;
166
+ /**
167
+ * The relaxed coverage floor, reachable ONLY by a page that has also won
168
+ * overwhelmingly ({@link STRONG_PAGE_MARGIN}).
169
+ *
170
+ * Coverage and dominance are evidence about the same thing from opposite
171
+ * directions, and holding both as independent hard floors throws away the
172
+ * cases where one is emphatic. "how do I edit text directly on the canvas"
173
+ * covers 0.68 — a hair under the bar, and the miss is `directly`, which the
174
+ * text-editing page never says — while winning so completely that every
175
+ * retrieved section belongs to it and there is no rival page to divide by.
176
+ * There is no reading of that evidence in which the text-editing page is the
177
+ * wrong page, and escalating it pays a provider to agree.
178
+ *
179
+ * The floor still binds, and it binds on questions that HAVE cleared
180
+ * {@link STRONG_PAGE_MARGIN}: "how do I customise the error screens" wins its
181
+ * page by 4.1x and still escalates at 0.42, because a page that ignores that
182
+ * much of the question is not answering it however clearly it wins. That is
183
+ * the case this pair of numbers is calibrated to keep out.
184
+ *
185
+ * ⚠️ Both figures are measurements over the CURRENT `apps/docs` corpus, and
186
+ * the corpus moves. `docs-deflection.spec.ts` asserts the first one's band
187
+ * rather than only its verdict, so a worked example that drifts out of the
188
+ * band fails there by name instead of going quietly wrong here.
189
+ */ const RELAXED_COVERAGE = 0.6;
190
+ /** The margin that buys {@link RELAXED_COVERAGE}. */ const STRONG_PAGE_MARGIN = 3;
191
+ /**
192
+ * ── The follow-up bar (AGL-2486) ──────────────────────────────────────────
193
+ *
194
+ * A question asked mid-thread is held to a HIGHER standard than the same
195
+ * question asked first, and the asymmetry is the whole idea rather than
196
+ * timidity about a new path.
197
+ *
198
+ * On turn one, a mediocre match costs a mediocre answer to the question that
199
+ * was actually asked, and the closing line invites the user to ask again.
200
+ * Mid-thread, a mediocre match means something else as well: it is EVIDENCE
201
+ * that the words in front of us are not the whole question. A thread is where
202
+ * ellipsis lives, so "retrieval is unsure" and "the missing half is in the
203
+ * transcript" are the same observation seen twice. Only an emphatic match —
204
+ * one where the page is right whatever came before — may be answered without
205
+ * reading the conversation.
206
+ *
207
+ * The calibration case is the second question, "how do I add an
208
+ * element to my page": top score 7.9, and the winning page beats its rival by
209
+ * 1.80 with a coming-soon LAUNCH GUIDE, because that guide happens to say
210
+ * "add", "element" and "page". As a first question that is retrieval doing
211
+ * its honest best. As a follow-up it is a coin flip that also ignores the
212
+ * conversation, and it escalates.
213
+ */ const FOLLOW_UP_MIN_TOP_SCORE = 8;
214
+ /** @see FOLLOW_UP_MIN_TOP_SCORE — 1.3x is a lead; 2x is not arguable. */ const FOLLOW_UP_MIN_PAGE_MARGIN = 2;
215
+ /**
216
+ * A follow-up must ASK something, not merely name a topic.
217
+ *
218
+ * Mid-thread, a bare fragment — "the free plan?", "on mobile" — is the shape
219
+ * ellipsis takes: the verb it belongs to was in the previous turn, and the
220
+ * fragment is a modifier of a question we cannot see. A first turn cannot be
221
+ * elliptical in that way, which is why this cue is required only when
222
+ * something precedes it.
223
+ *
224
+ * The count of tokens was tried here first and thrown away: it excluded "how
225
+ * do I install a plugin" and "how do I create a site" — two content tokens
226
+ * each, and both complete questions that a user asks second as readily as
227
+ * first. Length is not what separates a question from a fragment; a verb is.
228
+ */ const QUESTION_CUES = /\b(how|what|what'?s|where|when|which|who|whose|whom|can|could|do|does|did|is|are|am|was|were|will|would|should|must|may|explain|show|tell|list|need|want)\b/i;
229
+ /**
230
+ * Words and shapes that make a question depend on what came before it.
231
+ *
232
+ * Deliberately BROAD, and the asymmetry of the costs is why: a false positive
233
+ * here escalates a question that could have been answered from the docs — the
234
+ * behaviour that existed for every follow-up until this change, so the worst
235
+ * case is the status quo. A false negative answers a question nobody asked,
236
+ * with a citation under it, in a thread where the user can see we had the
237
+ * context and ignored it. These patterns are only ever consulted for a turn
238
+ * WITH history; a first question may say "that" as much as it likes.
239
+ */ const CONTEXT_DEPENDENT_PATTERNS = [
240
+ // Pronouns and demonstratives standing in for a noun in the transcript.
241
+ // "does IT work on mobile", "how do I move THOSE".
242
+ /\b(it|its|it'?s|they|them|their|theirs|he|him|his|she|her|hers)\b/i,
243
+ /\b(that|this|these|those)\b/i,
244
+ // Naming an item of the previous answer by its position in it.
245
+ /\b(the|either|any|another|each)\s+(other|first|second|third|last|next|same|previous|latter|former)\b/i,
246
+ /\b(other|another|either)\s+one\b/i,
247
+ // Opening by attaching to the previous turn rather than starting a question.
248
+ /^\s*(and|but|so|or|then|also|plus|what about|how about|ok(ay)?|yes|no|yeah|nope|thanks?)\b/i,
249
+ // Elliptical follow-ups that carry the previous turn's verb phrase over.
250
+ /\b(why not|instead|as well|again|neither|both)\b/i
251
+ ];
252
+ /** Minimum characters of section text before a section counts as an answer. */ const MIN_SECTION_CHARS = 200;
253
+ /** Sections of the winning page quoted verbatim, at most. */ const MAX_QUOTED_SECTIONS = 2;
254
+ /** Total verbatim characters in one deflected answer. */ const MAX_ANSWER_CHARS = 2600;
255
+ /**
256
+ * A request is generative when it asks for something to be WRITTEN, not
257
+ * explained. Anchored to the start of a word and paired with the objects
258
+ * people actually name, because "how do I create a redirect" is a docs
259
+ * question and "create a headline for my hero" is not.
260
+ */ const GENERATIVE_PATTERNS = [
261
+ /\b(write|draft|compose|generate|rewrite|reword|rephrase|summari[sz]e|translate|brainstorm|suggest)\b/i,
262
+ /\b(make|build|create|give)\s+(me|us)\b/i,
263
+ /\b(come up with|help me write)\b/i
264
+ ];
265
+ /**
266
+ * A request is diagnostic when it describes something not working. These have
267
+ * docs pages and must still escalate: the page lists every cause, and the
268
+ * user has exactly one of them. Only the model, with the level-2 view context,
269
+ * can narrow it — and when it cannot, saying so is better than quoting nine
270
+ * causes at someone.
271
+ */ const DIAGNOSTIC_PATTERNS = [
272
+ /\bwhy\s+(is|are|isn'?t|aren'?t|does|doesn'?t|did|didn'?t|won'?t|can'?t|cannot|do)\b/i,
273
+ /\b(not working|isn'?t working|doesn'?t work|stopped working|no longer works)\b/i,
274
+ /\b(was|were|is|are|never)\s+not\s+\w+ed\b/i,
275
+ /\b(broken|failing|failed|stuck|blank|missing|502|404|500)\b/i,
276
+ /\b(troubleshoot|debug|diagnose)\b/i,
277
+ // "error" needs a verb of appearance in front of it, within a clause.
278
+ // Bare `\berrors?\b` reads "how do I customise the error screens" as a
279
+ // support ticket — the docs page for error screens is titled with the word,
280
+ // so the one question the pattern must not catch is the one it caught.
281
+ /\b(getting|got|see|seeing|shows?|showing|throws?|returns?|says?|hit)\b[^.?!]{0,40}\berrors?\b/i
282
+ ];
283
+ function refuse(refusal, topScore = 0, pageMargin = 0, coverage = 0) {
284
+ return {
285
+ answered: false,
286
+ refusal,
287
+ answer: '',
288
+ quoted: [],
289
+ page: '',
290
+ topScore,
291
+ pageMargin,
292
+ coverage
293
+ };
294
+ }
295
+ /**
296
+ * Inverse document frequency for one token, over the docs corpus.
297
+ *
298
+ * Smoothed (`+1` inside the log's argument and on the denominator) so a token
299
+ * absent from the index — a product name we have not documented, a typo —
300
+ * gets a large but finite weight rather than a division by zero or an
301
+ * infinity that would swallow every other term in the question.
302
+ */ function tokenWeight(token) {
303
+ var _frequency_get;
304
+ const { frequency, sections } = docsDocumentFrequency();
305
+ const seen = (_frequency_get = frequency.get(token)) != null ? _frequency_get : 0;
306
+ return Math.log(1 + sections / (1 + seen));
307
+ }
308
+ /** The docs-site URL for one section. */ export function sectionUrl(section) {
309
+ return `${DOCS_SITE_ORIGIN}${section.path}${section.anchor}`;
310
+ }
311
+ /** `Title — Heading`, or just the title on a page intro. */ export function sectionLabel(section) {
312
+ return section.heading ? `${section.title} — ${section.heading}` : section.title;
313
+ }
314
+ /**
315
+ * Trim verbatim text to `limit` characters on a sentence boundary, so a quote
316
+ * never ends mid-clause. Returns the text unchanged when it already fits.
317
+ *
318
+ * A truncated quote is still verbatim — it is a PREFIX of the section, which
319
+ * is what the spec's substring check asserts. Cutting on a boundary matters
320
+ * for a different reason: a sentence stopped halfway reads as a broken
321
+ * feature, and the user cannot tell whether the missing half contradicted the
322
+ * visible one.
323
+ */ export function trimToSentence(text, limit) {
324
+ const trimmed = text.trim();
325
+ if (trimmed.length <= limit) return trimmed;
326
+ const window = trimmed.slice(0, limit);
327
+ const lastStop = Math.max(window.lastIndexOf('. '), window.lastIndexOf('! '), window.lastIndexOf('? '));
328
+ // A boundary in the first third would throw most of the quote away; better
329
+ // a hard cut with an ellipsis than an answer reduced to one sentence.
330
+ if (lastStop > limit / 3) return window.slice(0, lastStop + 1);
331
+ return `${window.trimEnd()}…`;
332
+ }
333
+ /** Question intent, ahead of any retrieval work. */ export function questionIsAnswerableFromDocs(question) {
334
+ const tokens = new Set(tokenize(question));
335
+ if (tokens.size < MIN_QUESTION_TOKENS) return 'too-short';
336
+ for (const pattern of GENERATIVE_PATTERNS){
337
+ if (pattern.test(question)) return 'generative';
338
+ }
339
+ for (const pattern of DIAGNOSTIC_PATTERNS){
340
+ if (pattern.test(question)) return 'diagnostic';
341
+ }
342
+ return null;
343
+ }
344
+ /**
345
+ * Whether a question can be read WITHOUT the conversation it was asked in.
346
+ *
347
+ * Only consulted for a turn that has history — see
348
+ * {@link CONTEXT_DEPENDENT_PATTERNS} for why the test errs towards "no", and
349
+ * the class docstring for why the gate is no longer simply "did anything
350
+ * precede this".
351
+ *
352
+ * Purely lexical, and that is a real limit worth naming: "how do I do the
353
+ * same for a blog post" is caught by `the same`, while "how do I change the
354
+ * colour" after a paragraph about buttons is not — nothing in those words
355
+ * says which colour. What saves that case is not this function but the raised
356
+ * evidence bar behind it, which such a question does not clear. The two gates
357
+ * are one argument in two halves: this one reads the question, that one reads
358
+ * the retrieval, and a follow-up must pass both.
359
+ */ export function questionStandsAlone(question) {
360
+ if (!QUESTION_CUES.test(question)) return false;
361
+ for (const pattern of CONTEXT_DEPENDENT_PATTERNS){
362
+ if (pattern.test(question)) return false;
363
+ }
364
+ return true;
365
+ }
366
+ /**
367
+ * Decide whether the retrieved sections answer the question on their own, and
368
+ * compose the answer when they do.
369
+ *
370
+ * `hasHistory` is passed rather than derived because the caller holds the
371
+ * clamped history and this module must not grow an opinion about how history
372
+ * is budgeted. It is not a hard gate any more (AGL-2486): a turn with history
373
+ * must additionally stand on its own words and clear the raised `FOLLOW_UP_*`
374
+ * bar, and escalates when it does not.
375
+ */ export function deflectToDocs(question, scored, hasHistory) {
376
+ if (hasHistory && !questionStandsAlone(question)) return refuse('follow-up');
377
+ const intent = questionIsAnswerableFromDocs(question);
378
+ if (intent) return refuse(intent);
379
+ if (!scored.length) return refuse('low-score');
380
+ const minTopScore = hasHistory ? FOLLOW_UP_MIN_TOP_SCORE : MIN_TOP_SCORE;
381
+ const minPageMargin = hasHistory ? FOLLOW_UP_MIN_PAGE_MARGIN : MIN_PAGE_MARGIN;
382
+ const top = scored[0];
383
+ const topScore = top.score;
384
+ if (!(topScore >= minTopScore)) return refuse('low-score', topScore);
385
+ // Score by PAGE. Sections of one page agreeing is the signal; treating them
386
+ // as rivals is how a strong, unambiguous match reads as a tie.
387
+ const perPage = new Map();
388
+ for (const entry of scored){
389
+ var _perPage_get;
390
+ perPage.set(entry.section.path, ((_perPage_get = perPage.get(entry.section.path)) != null ? _perPage_get : 0) + entry.score);
391
+ }
392
+ // The winning page is the highest-scoring PAGE, not the home of the
393
+ // highest-scoring section — three mid-scoring sections of one page can beat
394
+ // one strong section elsewhere, and when they do, that page is the answer.
395
+ let winner = '';
396
+ let winnerScore = 0;
397
+ let rivalScore = 0;
398
+ for (const [path, score] of perPage){
399
+ if (score > winnerScore) {
400
+ rivalScore = winnerScore;
401
+ winner = path;
402
+ winnerScore = score;
403
+ } else if (score > rivalScore) {
404
+ rivalScore = score;
405
+ }
406
+ }
407
+ // No rival is not a tie — it is the cleanest possible result, one page and
408
+ // nothing else. `Infinity` would be honest but propagates badly through the
409
+ // telemetry, so a lone winner reports its own score as the margin.
410
+ const pageMargin = rivalScore > 0 ? winnerScore / rivalScore : winnerScore;
411
+ if (!(pageMargin >= minPageMargin)) return refuse('ambiguous', topScore, pageMargin);
412
+ const pageSections = scored.filter((entry)=>entry.section.path === winner);
413
+ const pageTokens = new Set();
414
+ for (const entry of pageSections){
415
+ for (const token of tokenize(entry.section.title))pageTokens.add(token);
416
+ for (const token of tokenize(entry.section.heading))pageTokens.add(token);
417
+ for (const token of tokenize(entry.section.text))pageTokens.add(token);
418
+ }
419
+ const questionTokens = [
420
+ ...new Set(tokenize(question))
421
+ ];
422
+ let wanted = 0;
423
+ let covered = 0;
424
+ for (const token of questionTokens){
425
+ const weight = tokenWeight(token);
426
+ wanted += weight;
427
+ if (pageTokens.has(token)) covered += weight;
428
+ }
429
+ const coverage = wanted > 0 ? covered / wanted : 0;
430
+ // The relaxed floor is a FIRST-TURN allowance. It exists because coverage
431
+ // and dominance are evidence about the same thing, so an emphatic winner
432
+ // may carry a coverage miss — but mid-thread a coverage miss has a second
433
+ // reading: the part of the question the page ignored may be the part the
434
+ // conversation supplied. Turn one cannot mean that; a follow-up can, so it
435
+ // pays full coverage.
436
+ const coveredEnough = coverage >= MIN_COVERAGE || !hasHistory && coverage >= RELAXED_COVERAGE && pageMargin >= STRONG_PAGE_MARGIN;
437
+ if (!coveredEnough) {
438
+ return refuse('low-coverage', topScore, pageMargin, coverage);
439
+ }
440
+ const usable = pageSections.filter((entry)=>entry.section.text.trim().length >= MIN_SECTION_CHARS);
441
+ if (!usable.length) return refuse('thin-section', topScore, pageMargin, coverage);
442
+ const quoted = usable.slice(0, MAX_QUOTED_SECTIONS).map((entry)=>entry.section);
443
+ return {
444
+ answered: true,
445
+ refusal: null,
446
+ answer: composeDocsAnswer(quoted),
447
+ quoted,
448
+ page: winner,
449
+ topScore,
450
+ pageMargin,
451
+ coverage
452
+ };
453
+ }
454
+ /**
455
+ * The deflected answer: template + verbatim docs + real links, and nothing
456
+ * else. Kept exported so the spec can assert the reconstruction property
457
+ * against it directly rather than through the route.
458
+ *
459
+ * ⚠️ COMPOSED FOR A SURFACE THAT DOES NOT RENDER MARKDOWN. The Assist panel
460
+ * says so in its own docstring — `renderAssistText` turns `[label](url)` and
461
+ * bare URLs into links and renders everything else literally, under
462
+ * `whiteSpace: 'pre-wrap'`. That is a deliberate phase-1 decision, not a gap.
463
+ *
464
+ * This template shipped once with the heading wrapped in `**…**`, and the * besigner drawer duly showed `**Drag-and-drop hierarchy — Moving an element
465
+ * without dragging**`, asterisks and all. The lesson is not "escape the
466
+ * asterisks" — it is that the composer has to know what renders it.
467
+ *
468
+ * So the heading is a bare `[label](url)` on its own line — a LINK, which is
469
+ * the one markup the panel speaks, and which is why the title in the * screenshot was correctly clickable even while the asterisks around it were
470
+ * not. Everything else is carried by NEWLINES, which `pre-wrap` renders,
471
+ * rather than by markup, which it does not.
472
+ *
473
+ * The link has to live in the TEXT, and that is still true now that the
474
+ * `docs` array on the `done` event IS rendered (AGL-2486, `AssistSources`).
475
+ * It was tempting to treat that array as the structural home for the citation
476
+ * even when nothing rendered it; it is still the wrong home, for a different
477
+ * reason. `docs` carries every section RETRIEVED, whereas this template
478
+ * quotes only the sections it actually used — so the array is a superset, and
479
+ * a citation moved there would credit pages this answer never drew a word
480
+ * from. `AssistSources` drops any url already linked in the text, which means
481
+ * a deflected answer renders exactly as it does below and gains no duplicate
482
+ * list underneath.
483
+ *
484
+ * Three specs in `docs-deflection.spec.ts` hold the line — no emphasis
485
+ * markers, no heading markers, and a link still present.
486
+ *
487
+ * The closing line is not decoration. A user who reads this and finds it did
488
+ * not answer them needs to know that asking again in different words reaches
489
+ * something else — otherwise the cheap path looks like the assistant simply
490
+ * being worse, and the next thing they do is stop using it.
491
+ */ export function composeDocsAnswer(sections) {
492
+ const parts = [];
493
+ let budget = MAX_ANSWER_CHARS;
494
+ for (const section of sections){
495
+ if (budget <= MIN_SECTION_CHARS) break;
496
+ const quote = trimToSentence(section.text, budget);
497
+ budget -= quote.length;
498
+ parts.push(`[${sectionLabel(section)}](${sectionUrl(section)})\n${quote}`);
499
+ }
500
+ parts.push('That is straight from the documentation — the headings above link to the full page. If it did not cover what you meant, ask again with more detail and I will work through it with you.');
501
+ return parts.join('\n\n');
502
+ }
503
+ /** Closest-pages links offered when nothing could be answered outright. */ const MAX_LINKED_SECTIONS = 4;
504
+ /**
505
+ * The graceful degrade: the closest pages we found, and an honest sentence
506
+ * saying why that is all there is (AGL-2486).
507
+ *
508
+ * ## Why this exists
509
+ *
510
+ * A deployment with no AI provider key — which includes every self-hosted
511
+ * one on the day it comes up, and Aglyn's own production today — can answer
512
+ * only what retrieval is confident about. A bare 501 for everything else
513
+ * reaches the panel as "Assist is not configured on this deployment" — and it
514
+ * can arrive on the SECOND question of a thread whose first question was just
515
+ * answered in full. A capability refusal that lands after a working answer
516
+ * reads as a fault, not a limit.
517
+ *
518
+ * The self-host charter says every Aglyn-operated dependency must be
519
+ * configurable AND degrade cleanly. "Degrades cleanly" cannot mean "answers
520
+ * one question per thread and then refuses" — a keyless deployment still has
521
+ * the entire documentation corpus and a retrieval index over it, so the floor
522
+ * is the best pages we found, not nothing.
523
+ *
524
+ * ## What it may and may not say
525
+ *
526
+ * The no-fabrication rule applies here exactly as it does to a deflected
527
+ * answer, and is tighter in one respect: these pages did NOT clear the
528
+ * confidence bar, so this text must not claim they answer the question. It
529
+ * says they are the closest, which is true by construction — they are the
530
+ * top of the retrieval ranking — and every word around them is a fixed
531
+ * template plus a real section label and URL.
532
+ *
533
+ * It also must not name an env var. A user who wanted to read `501` would
534
+ * have opened the network tab; the operator-facing detail stays in the API
535
+ * error body, where an operator looks. This is the plain-English half.
536
+ */ export function composeDocsLinksAnswer(sections) {
537
+ const links = sections.slice(0, MAX_LINKED_SECTIONS).map((section)=>`[${sectionLabel(section)}](${sectionUrl(section)})`);
538
+ if (!links.length) return '';
539
+ return [
540
+ 'I could not find one page in the documentation that clearly answers that, and the part of me that talks a question through with you is not switched on for this deployment yet — an administrator has to finish setting it up.',
541
+ 'These are the closest pages I found:',
542
+ links.join('\n'),
543
+ 'If none of them cover it, asking again in different words often lands somewhere better.'
544
+ ].join('\n\n');
545
+ }
546
+
547
+ //# sourceMappingURL=docs-deflection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/docs-deflection.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { AssistDocsSection } from './docs-index.generated'\nimport {\n DOCS_SITE_ORIGIN,\n docsDocumentFrequency,\n tokenize,\n type ScoredSection,\n} from './docs-retrieval'\n\n/**\n * Retrieval-first answering for Aglyn Assist (AGL-2486) — the deflection gate.\n *\n * Most assist traffic is \"how do I X\", and the answer to \"how do I X\" is\n * already written down in `apps/docs/docs`. Sending that question to a model\n * so the model can read the docs section back to the user pays provider money\n * to reformat prose we wrote ourselves. This module decides when retrieval is\n * confident enough to hand the docs straight over, and composes the answer\n * when it is. Escalation to the model is what happens the rest of the time —\n * it is the fallback, not the default.\n *\n * ## The one rule: never fabricate\n *\n * A deflected answer contains exactly two kinds of text:\n *\n * 1. Fixed template strings from this file, which say nothing about the\n * product — they name the page and introduce the quote.\n * 2. Section text copied VERBATIM out of the docs index, with the URL of\n * the page it came from.\n *\n * There is no summarisation, no paraphrase and no stitching of adjacent\n * sections into a claim neither one makes. The spec asserts it by\n * RECONSTRUCTION — \"never fabricate — every word is template or verbatim\n * docs\" — stripping the template from a composed answer and requiring what is\n * left to be a prefix of a real section's `text`. That property is the whole\n * safety argument, because a wrong retrieval answer is worse than an\n * escalation — it is confidently wrong prose delivered to a paying customer\n * with a citation under it, which is the shape people trust most.\n *\n * ## What \"confident\" means\n *\n * Seven conditions, ALL of which must hold. Any one failing escalates; there\n * is no partial-credit path where a weak match produces a hedged answer,\n * because a hedged wrong answer is still a wrong answer and it has already\n * cost the user the click.\n *\n * 1. **The question stands on its own.** A follow-up is usually not\n * self-contained: \"does that work on the free plan?\" retrieves the\n * billing pages beautifully and answers a question nobody asked. The\n * conversation is the missing half and only the model has it.\n *\n * The gate is NOT \"no prior turn\" (AGL-2486). Not every follow-up leans\n * on the transcript: the second question in a thread is very often a\n * fresh, complete question that happens to be asked second. Refusing all\n * of them means a thread answers its first question from the docs and\n * then escalates forever — and on a deployment with no AI provider\n * key that reads as \"Aglyn Assist is not configured\",\n * one question in, to a user who just watched it work. A product that\n * answers exactly once per thread is worse than one that never answers,\n * because the second refusal looks like a fault rather than a limit.\n *\n * So the gate now asks whether THIS question stands alone, and holds a\n * raised bar when it does — see {@link questionStandsAlone} and the\n * `FOLLOW_UP_*` constants.\n * 2. **Enough question.** At least {@link MIN_QUESTION_TOKENS} distinct\n * content tokens after stop-word removal. Below that there is not enough\n * of a question to be confident ABOUT.\n * 3. **Not a generative request.** \"write me a hero headline\" is the copy\n * assistant's job, not a docs lookup, and no docs page answers it.\n * 4. **Not a diagnostic.** \"why isn't my domain verifying\" has a\n * troubleshooting page, and dumping that page at someone whose actual\n * problem is one of nine listed causes is exactly the confidently-wrong\n * failure. Diagnostics need the workspace's own state, which is the\n * level-2 context only the model gets.\n * 5. **Absolute score.** The top section scores at least\n * {@link MIN_TOP_SCORE}.\n * 6. **Page dominance.** The winning page beats the best RIVAL page by at\n * least {@link MIN_PAGE_MARGIN}. Measured against the runner-up page\n * rather than as a share of the whole retrieved set, because the set is\n * six sections wide: a page that is unambiguously right still holds a\n * minority of a six-way split the moment three neighbouring pages use the\n * same nouns, and a share test reads that dilution as doubt. And the\n * comparison is page-to-page, not section-to-section — sections of ONE\n * page scoring alike is agreement, which a section margin scores as a tie.\n * 7. **Substance.** The winning section carries at least\n * {@link MIN_SECTION_CHARS} of text. A three-word stub under a heading is\n * a pointer, not an answer.\n *\n * Below the bar the request proceeds exactly as it did before this module\n * existed: the same sections are still retrieved and still ground the model's\n * prompt. Deflection removes model calls; it never removes grounding.\n *\n * ## The thresholds are measured, not guessed\n *\n * `docs-deflection.spec.ts` carries a fixed set of realistic questions —\n * positives written in user vocabulary rather than lifted from docs headings,\n * and negatives that MUST escalate — and asserts a floor on the deflection\n * rate and a ceiling of zero on the negatives. Retuning a constant here\n * without rerunning that spec is how a threshold ends up set by whoever\n * touched it last.\n */\n\n/**\n * Distinct content tokens a question needs before it can be answered.\n *\n * Two, not three, and the difference is most of the corpus: \"how do I install\n * a plugin\", \"what are dataset relations\" and \"how do I cancel my\n * subscription\" all reduce to exactly two content tokens once the stop words\n * go, and every one of them is a plain docs lookup. Three excluded them all.\n *\n * Two is safe here only because the gates below are not a checklist a weak\n * question can pass by being short: a two-token question must have BOTH\n * tokens carried by the winning page (the IDF weighting cannot rescue it —\n * there is nothing generic to discount), and the page must still clear the\n * score floor and out-score its rival. \"is my site down\" has two tokens and\n * fails on dominance, not on length.\n */\nconst MIN_QUESTION_TOKENS = 2\n\n/**\n * Absolute floor on the winning section's retrieval score.\n *\n * The scorer gives 2.5 for a title hit, 2 for a heading hit and up to ~2.2 per\n * body term — about 6.7 for one term landing everywhere at once. 5 is\n * therefore roughly \"two question terms landed and at least one of them hit\n * the page's own statement of topic\". Below that the match is incidental\n * vocabulary rather than a page about the thing.\n *\n * Measured down from 6, which cost five ordinary lookups scoring 4.4–5.9\n * (\"how do I cancel my subscription\", \"how do I set up sso for my team\") and\n * bought nothing: the negative set does not move between the two values,\n * because what actually stops those is coverage and dominance, not the floor.\n */\nconst MIN_TOP_SCORE = 5\n\n/**\n * How far the winning page must out-score the best rival page.\n *\n * 1.3x — the winner needs a visible lead, not a photo finish. Two pages\n * within 30% of each other on the same question means retrieval genuinely\n * does not know which one the user meant, and picking is a coin flip dressed\n * up as an answer.\n *\n * A question that retrieves only ONE page has no rival and passes this gate\n * outright; the score floor and coverage are what bound it there.\n */\nconst MIN_PAGE_MARGIN = 1.3\n\n/**\n * Weighted fraction of the question the winning page must actually contain.\n * Coverage and score answer different questions: score says the page matched\n * strongly, coverage says the page did not IGNORE part of what was asked.\n * \"how do I password protect a screen on the free plan\" scores highly on the\n * site-protection page while silently dropping \"free plan\", and the answer\n * that comes back is then wrong in the one way that matters.\n *\n * ⚠️ WEIGHTED BY IDF, and an unweighted version of this test is why nine\n * perfectly ordinary questions escalated in the first measurement. \"how do I\n * make a reusable component\" covers `reusable` and `component` and misses\n * `make`, because the page says \"create\" — 2/3, under the bar, escalated. The\n * miss carried no information: `make` appears in a third of the corpus, so\n * its absence from one page says nothing, while `reusable` appearing says\n * almost everything. Counting tokens equally lets the most common words in\n * English veto a match on the rarest. Weighting by how rare a term is in THIS\n * corpus makes the test ask what it always meant to ask — did the page cover\n * the DISTINCTIVE part of the question.\n */\nconst MIN_COVERAGE = 0.7\n\n/**\n * The relaxed coverage floor, reachable ONLY by a page that has also won\n * overwhelmingly ({@link STRONG_PAGE_MARGIN}).\n *\n * Coverage and dominance are evidence about the same thing from opposite\n * directions, and holding both as independent hard floors throws away the\n * cases where one is emphatic. \"how do I edit text directly on the canvas\"\n * covers 0.68 — a hair under the bar, and the miss is `directly`, which the\n * text-editing page never says — while winning so completely that every\n * retrieved section belongs to it and there is no rival page to divide by.\n * There is no reading of that evidence in which the text-editing page is the\n * wrong page, and escalating it pays a provider to agree.\n *\n * The floor still binds, and it binds on questions that HAVE cleared\n * {@link STRONG_PAGE_MARGIN}: \"how do I customise the error screens\" wins its\n * page by 4.1x and still escalates at 0.42, because a page that ignores that\n * much of the question is not answering it however clearly it wins. That is\n * the case this pair of numbers is calibrated to keep out.\n *\n * ⚠️ Both figures are measurements over the CURRENT `apps/docs` corpus, and\n * the corpus moves. `docs-deflection.spec.ts` asserts the first one's band\n * rather than only its verdict, so a worked example that drifts out of the\n * band fails there by name instead of going quietly wrong here.\n */\nconst RELAXED_COVERAGE = 0.6\n\n/** The margin that buys {@link RELAXED_COVERAGE}. */\nconst STRONG_PAGE_MARGIN = 3\n\n/**\n * ── The follow-up bar (AGL-2486) ──────────────────────────────────────────\n *\n * A question asked mid-thread is held to a HIGHER standard than the same\n * question asked first, and the asymmetry is the whole idea rather than\n * timidity about a new path.\n *\n * On turn one, a mediocre match costs a mediocre answer to the question that\n * was actually asked, and the closing line invites the user to ask again.\n * Mid-thread, a mediocre match means something else as well: it is EVIDENCE\n * that the words in front of us are not the whole question. A thread is where\n * ellipsis lives, so \"retrieval is unsure\" and \"the missing half is in the\n * transcript\" are the same observation seen twice. Only an emphatic match —\n * one where the page is right whatever came before — may be answered without\n * reading the conversation.\n *\n * The calibration case is the second question, \"how do I add an\n * element to my page\": top score 7.9, and the winning page beats its rival by\n * 1.80 with a coming-soon LAUNCH GUIDE, because that guide happens to say\n * \"add\", \"element\" and \"page\". As a first question that is retrieval doing\n * its honest best. As a follow-up it is a coin flip that also ignores the\n * conversation, and it escalates.\n */\nconst FOLLOW_UP_MIN_TOP_SCORE = 8\n\n/** @see FOLLOW_UP_MIN_TOP_SCORE — 1.3x is a lead; 2x is not arguable. */\nconst FOLLOW_UP_MIN_PAGE_MARGIN = 2\n\n/**\n * A follow-up must ASK something, not merely name a topic.\n *\n * Mid-thread, a bare fragment — \"the free plan?\", \"on mobile\" — is the shape\n * ellipsis takes: the verb it belongs to was in the previous turn, and the\n * fragment is a modifier of a question we cannot see. A first turn cannot be\n * elliptical in that way, which is why this cue is required only when\n * something precedes it.\n *\n * The count of tokens was tried here first and thrown away: it excluded \"how\n * do I install a plugin\" and \"how do I create a site\" — two content tokens\n * each, and both complete questions that a user asks second as readily as\n * first. Length is not what separates a question from a fragment; a verb is.\n */\nconst QUESTION_CUES =\n /\\b(how|what|what'?s|where|when|which|who|whose|whom|can|could|do|does|did|is|are|am|was|were|will|would|should|must|may|explain|show|tell|list|need|want)\\b/i\n\n/**\n * Words and shapes that make a question depend on what came before it.\n *\n * Deliberately BROAD, and the asymmetry of the costs is why: a false positive\n * here escalates a question that could have been answered from the docs — the\n * behaviour that existed for every follow-up until this change, so the worst\n * case is the status quo. A false negative answers a question nobody asked,\n * with a citation under it, in a thread where the user can see we had the\n * context and ignored it. These patterns are only ever consulted for a turn\n * WITH history; a first question may say \"that\" as much as it likes.\n */\nconst CONTEXT_DEPENDENT_PATTERNS: readonly RegExp[] = [\n // Pronouns and demonstratives standing in for a noun in the transcript.\n // \"does IT work on mobile\", \"how do I move THOSE\".\n /\\b(it|its|it'?s|they|them|their|theirs|he|him|his|she|her|hers)\\b/i,\n /\\b(that|this|these|those)\\b/i,\n // Naming an item of the previous answer by its position in it.\n /\\b(the|either|any|another|each)\\s+(other|first|second|third|last|next|same|previous|latter|former)\\b/i,\n /\\b(other|another|either)\\s+one\\b/i,\n // Opening by attaching to the previous turn rather than starting a question.\n /^\\s*(and|but|so|or|then|also|plus|what about|how about|ok(ay)?|yes|no|yeah|nope|thanks?)\\b/i,\n // Elliptical follow-ups that carry the previous turn's verb phrase over.\n /\\b(why not|instead|as well|again|neither|both)\\b/i,\n]\n\n/** Minimum characters of section text before a section counts as an answer. */\nconst MIN_SECTION_CHARS = 200\n\n/** Sections of the winning page quoted verbatim, at most. */\nconst MAX_QUOTED_SECTIONS = 2\n\n/** Total verbatim characters in one deflected answer. */\nconst MAX_ANSWER_CHARS = 2600\n\n/**\n * A request is generative when it asks for something to be WRITTEN, not\n * explained. Anchored to the start of a word and paired with the objects\n * people actually name, because \"how do I create a redirect\" is a docs\n * question and \"create a headline for my hero\" is not.\n */\nconst GENERATIVE_PATTERNS: readonly RegExp[] = [\n /\\b(write|draft|compose|generate|rewrite|reword|rephrase|summari[sz]e|translate|brainstorm|suggest)\\b/i,\n /\\b(make|build|create|give)\\s+(me|us)\\b/i,\n /\\b(come up with|help me write)\\b/i,\n]\n\n/**\n * A request is diagnostic when it describes something not working. These have\n * docs pages and must still escalate: the page lists every cause, and the\n * user has exactly one of them. Only the model, with the level-2 view context,\n * can narrow it — and when it cannot, saying so is better than quoting nine\n * causes at someone.\n */\nconst DIAGNOSTIC_PATTERNS: readonly RegExp[] = [\n /\\bwhy\\s+(is|are|isn'?t|aren'?t|does|doesn'?t|did|didn'?t|won'?t|can'?t|cannot|do)\\b/i,\n /\\b(not working|isn'?t working|doesn'?t work|stopped working|no longer works)\\b/i,\n /\\b(was|were|is|are|never)\\s+not\\s+\\w+ed\\b/i,\n /\\b(broken|failing|failed|stuck|blank|missing|502|404|500)\\b/i,\n /\\b(troubleshoot|debug|diagnose)\\b/i,\n // \"error\" needs a verb of appearance in front of it, within a clause.\n // Bare `\\berrors?\\b` reads \"how do I customise the error screens\" as a\n // support ticket — the docs page for error screens is titled with the word,\n // so the one question the pattern must not catch is the one it caught.\n /\\b(getting|got|see|seeing|shows?|showing|throws?|returns?|says?|hit)\\b[^.?!]{0,40}\\berrors?\\b/i,\n]\n\n/** Why a question was not answered from the docs. `null` reason = answered. */\nexport type DeflectionRefusal =\n | 'follow-up'\n | 'too-short'\n | 'generative'\n | 'diagnostic'\n | 'low-score'\n | 'ambiguous'\n | 'low-coverage'\n | 'thin-section'\n\nexport interface DeflectionVerdict {\n /** True when the docs answer this without a model call. */\n answered: boolean\n /** Set when `answered` is false — which gate refused. */\n refusal: DeflectionRefusal | null\n /** The composed answer; `''` unless `answered`. */\n answer: string\n /** Sections quoted in the answer; `[]` unless `answered`. */\n quoted: readonly AssistDocsSection[]\n /** The winning page's path; `''` when nothing won. */\n page: string\n /** Top section's retrieval score. 0 when nothing was retrieved. */\n topScore: number\n /** Winning page's score over the best rival page's. 0 when unscored. */\n pageMargin: number\n /** IDF-weighted share of the question the winning page carries. */\n coverage: number\n}\n\nfunction refuse(\n refusal: DeflectionRefusal,\n topScore = 0,\n pageMargin = 0,\n coverage = 0,\n): DeflectionVerdict {\n return {\n answered: false,\n refusal,\n answer: '',\n quoted: [],\n page: '',\n topScore,\n pageMargin,\n coverage,\n }\n}\n\n/**\n * Inverse document frequency for one token, over the docs corpus.\n *\n * Smoothed (`+1` inside the log's argument and on the denominator) so a token\n * absent from the index — a product name we have not documented, a typo —\n * gets a large but finite weight rather than a division by zero or an\n * infinity that would swallow every other term in the question.\n */\nfunction tokenWeight(token: string): number {\n const { frequency, sections } = docsDocumentFrequency()\n const seen = frequency.get(token) ?? 0\n return Math.log(1 + sections / (1 + seen))\n}\n\n/** The docs-site URL for one section. */\nexport function sectionUrl(section: AssistDocsSection): string {\n return `${DOCS_SITE_ORIGIN}${section.path}${section.anchor}`\n}\n\n/** `Title — Heading`, or just the title on a page intro. */\nexport function sectionLabel(section: AssistDocsSection): string {\n return section.heading ? `${section.title} — ${section.heading}` : section.title\n}\n\n/**\n * Trim verbatim text to `limit` characters on a sentence boundary, so a quote\n * never ends mid-clause. Returns the text unchanged when it already fits.\n *\n * A truncated quote is still verbatim — it is a PREFIX of the section, which\n * is what the spec's substring check asserts. Cutting on a boundary matters\n * for a different reason: a sentence stopped halfway reads as a broken\n * feature, and the user cannot tell whether the missing half contradicted the\n * visible one.\n */\nexport function trimToSentence(text: string, limit: number): string {\n const trimmed = text.trim()\n if (trimmed.length <= limit) return trimmed\n const window = trimmed.slice(0, limit)\n const lastStop = Math.max(\n window.lastIndexOf('. '),\n window.lastIndexOf('! '),\n window.lastIndexOf('? '),\n )\n // A boundary in the first third would throw most of the quote away; better\n // a hard cut with an ellipsis than an answer reduced to one sentence.\n if (lastStop > limit / 3) return window.slice(0, lastStop + 1)\n return `${window.trimEnd()}…`\n}\n\n/** Question intent, ahead of any retrieval work. */\nexport function questionIsAnswerableFromDocs(question: string): DeflectionRefusal | null {\n const tokens = new Set(tokenize(question))\n if (tokens.size < MIN_QUESTION_TOKENS) return 'too-short'\n for (const pattern of GENERATIVE_PATTERNS) {\n if (pattern.test(question)) return 'generative'\n }\n for (const pattern of DIAGNOSTIC_PATTERNS) {\n if (pattern.test(question)) return 'diagnostic'\n }\n return null\n}\n\n/**\n * Whether a question can be read WITHOUT the conversation it was asked in.\n *\n * Only consulted for a turn that has history — see\n * {@link CONTEXT_DEPENDENT_PATTERNS} for why the test errs towards \"no\", and\n * the class docstring for why the gate is no longer simply \"did anything\n * precede this\".\n *\n * Purely lexical, and that is a real limit worth naming: \"how do I do the\n * same for a blog post\" is caught by `the same`, while \"how do I change the\n * colour\" after a paragraph about buttons is not — nothing in those words\n * says which colour. What saves that case is not this function but the raised\n * evidence bar behind it, which such a question does not clear. The two gates\n * are one argument in two halves: this one reads the question, that one reads\n * the retrieval, and a follow-up must pass both.\n */\nexport function questionStandsAlone(question: string): boolean {\n if (!QUESTION_CUES.test(question)) return false\n for (const pattern of CONTEXT_DEPENDENT_PATTERNS) {\n if (pattern.test(question)) return false\n }\n return true\n}\n\n/**\n * Decide whether the retrieved sections answer the question on their own, and\n * compose the answer when they do.\n *\n * `hasHistory` is passed rather than derived because the caller holds the\n * clamped history and this module must not grow an opinion about how history\n * is budgeted. It is not a hard gate any more (AGL-2486): a turn with history\n * must additionally stand on its own words and clear the raised `FOLLOW_UP_*`\n * bar, and escalates when it does not.\n */\nexport function deflectToDocs(\n question: string,\n scored: readonly ScoredSection[],\n hasHistory: boolean,\n): DeflectionVerdict {\n if (hasHistory && !questionStandsAlone(question)) return refuse('follow-up')\n const intent = questionIsAnswerableFromDocs(question)\n if (intent) return refuse(intent)\n if (!scored.length) return refuse('low-score')\n\n const minTopScore = hasHistory ? FOLLOW_UP_MIN_TOP_SCORE : MIN_TOP_SCORE\n const minPageMargin = hasHistory ? FOLLOW_UP_MIN_PAGE_MARGIN : MIN_PAGE_MARGIN\n\n const top = scored[0]\n const topScore = top.score\n if (!(topScore >= minTopScore)) return refuse('low-score', topScore)\n\n // Score by PAGE. Sections of one page agreeing is the signal; treating them\n // as rivals is how a strong, unambiguous match reads as a tie.\n const perPage = new Map<string, number>()\n for (const entry of scored) {\n perPage.set(entry.section.path, (perPage.get(entry.section.path) ?? 0) + entry.score)\n }\n // The winning page is the highest-scoring PAGE, not the home of the\n // highest-scoring section — three mid-scoring sections of one page can beat\n // one strong section elsewhere, and when they do, that page is the answer.\n let winner = ''\n let winnerScore = 0\n let rivalScore = 0\n for (const [path, score] of perPage) {\n if (score > winnerScore) {\n rivalScore = winnerScore\n winner = path\n winnerScore = score\n } else if (score > rivalScore) {\n rivalScore = score\n }\n }\n // No rival is not a tie — it is the cleanest possible result, one page and\n // nothing else. `Infinity` would be honest but propagates badly through the\n // telemetry, so a lone winner reports its own score as the margin.\n const pageMargin = rivalScore > 0 ? winnerScore / rivalScore : winnerScore\n if (!(pageMargin >= minPageMargin)) return refuse('ambiguous', topScore, pageMargin)\n\n const pageSections = scored.filter((entry) => entry.section.path === winner)\n const pageTokens = new Set<string>()\n for (const entry of pageSections) {\n for (const token of tokenize(entry.section.title)) pageTokens.add(token)\n for (const token of tokenize(entry.section.heading)) pageTokens.add(token)\n for (const token of tokenize(entry.section.text)) pageTokens.add(token)\n }\n const questionTokens = [...new Set(tokenize(question))]\n let wanted = 0\n let covered = 0\n for (const token of questionTokens) {\n const weight = tokenWeight(token)\n wanted += weight\n if (pageTokens.has(token)) covered += weight\n }\n const coverage = wanted > 0 ? covered / wanted : 0\n // The relaxed floor is a FIRST-TURN allowance. It exists because coverage\n // and dominance are evidence about the same thing, so an emphatic winner\n // may carry a coverage miss — but mid-thread a coverage miss has a second\n // reading: the part of the question the page ignored may be the part the\n // conversation supplied. Turn one cannot mean that; a follow-up can, so it\n // pays full coverage.\n const coveredEnough =\n coverage >= MIN_COVERAGE ||\n (!hasHistory && coverage >= RELAXED_COVERAGE && pageMargin >= STRONG_PAGE_MARGIN)\n if (!coveredEnough) {\n return refuse('low-coverage', topScore, pageMargin, coverage)\n }\n\n const usable = pageSections.filter(\n (entry) => entry.section.text.trim().length >= MIN_SECTION_CHARS,\n )\n if (!usable.length) return refuse('thin-section', topScore, pageMargin, coverage)\n\n const quoted = usable.slice(0, MAX_QUOTED_SECTIONS).map((entry) => entry.section)\n return {\n answered: true,\n refusal: null,\n answer: composeDocsAnswer(quoted),\n quoted,\n page: winner,\n topScore,\n pageMargin,\n coverage,\n }\n}\n\n/**\n * The deflected answer: template + verbatim docs + real links, and nothing\n * else. Kept exported so the spec can assert the reconstruction property\n * against it directly rather than through the route.\n *\n * ⚠️ COMPOSED FOR A SURFACE THAT DOES NOT RENDER MARKDOWN. The Assist panel\n * says so in its own docstring — `renderAssistText` turns `[label](url)` and\n * bare URLs into links and renders everything else literally, under\n * `whiteSpace: 'pre-wrap'`. That is a deliberate phase-1 decision, not a gap.\n *\n * This template shipped once with the heading wrapped in `**…**`, and the * besigner drawer duly showed `**Drag-and-drop hierarchy — Moving an element\n * without dragging**`, asterisks and all. The lesson is not \"escape the\n * asterisks\" — it is that the composer has to know what renders it.\n *\n * So the heading is a bare `[label](url)` on its own line — a LINK, which is\n * the one markup the panel speaks, and which is why the title in the * screenshot was correctly clickable even while the asterisks around it were\n * not. Everything else is carried by NEWLINES, which `pre-wrap` renders,\n * rather than by markup, which it does not.\n *\n * The link has to live in the TEXT, and that is still true now that the\n * `docs` array on the `done` event IS rendered (AGL-2486, `AssistSources`).\n * It was tempting to treat that array as the structural home for the citation\n * even when nothing rendered it; it is still the wrong home, for a different\n * reason. `docs` carries every section RETRIEVED, whereas this template\n * quotes only the sections it actually used — so the array is a superset, and\n * a citation moved there would credit pages this answer never drew a word\n * from. `AssistSources` drops any url already linked in the text, which means\n * a deflected answer renders exactly as it does below and gains no duplicate\n * list underneath.\n *\n * Three specs in `docs-deflection.spec.ts` hold the line — no emphasis\n * markers, no heading markers, and a link still present.\n *\n * The closing line is not decoration. A user who reads this and finds it did\n * not answer them needs to know that asking again in different words reaches\n * something else — otherwise the cheap path looks like the assistant simply\n * being worse, and the next thing they do is stop using it.\n */\nexport function composeDocsAnswer(sections: readonly AssistDocsSection[]): string {\n const parts: string[] = []\n let budget = MAX_ANSWER_CHARS\n for (const section of sections) {\n if (budget <= MIN_SECTION_CHARS) break\n const quote = trimToSentence(section.text, budget)\n budget -= quote.length\n parts.push(`[${sectionLabel(section)}](${sectionUrl(section)})\\n${quote}`)\n }\n parts.push(\n 'That is straight from the documentation — the headings above link to the full page. If it did not cover what you meant, ask again with more detail and I will work through it with you.',\n )\n return parts.join('\\n\\n')\n}\n\n/** Closest-pages links offered when nothing could be answered outright. */\nconst MAX_LINKED_SECTIONS = 4\n\n/**\n * The graceful degrade: the closest pages we found, and an honest sentence\n * saying why that is all there is (AGL-2486).\n *\n * ## Why this exists\n *\n * A deployment with no AI provider key — which includes every self-hosted\n * one on the day it comes up, and Aglyn's own production today — can answer\n * only what retrieval is confident about. A bare 501 for everything else\n * reaches the panel as \"Assist is not configured on this deployment\" — and it\n * can arrive on the SECOND question of a thread whose first question was just\n * answered in full. A capability refusal that lands after a working answer\n * reads as a fault, not a limit.\n *\n * The self-host charter says every Aglyn-operated dependency must be\n * configurable AND degrade cleanly. \"Degrades cleanly\" cannot mean \"answers\n * one question per thread and then refuses\" — a keyless deployment still has\n * the entire documentation corpus and a retrieval index over it, so the floor\n * is the best pages we found, not nothing.\n *\n * ## What it may and may not say\n *\n * The no-fabrication rule applies here exactly as it does to a deflected\n * answer, and is tighter in one respect: these pages did NOT clear the\n * confidence bar, so this text must not claim they answer the question. It\n * says they are the closest, which is true by construction — they are the\n * top of the retrieval ranking — and every word around them is a fixed\n * template plus a real section label and URL.\n *\n * It also must not name an env var. A user who wanted to read `501` would\n * have opened the network tab; the operator-facing detail stays in the API\n * error body, where an operator looks. This is the plain-English half.\n */\nexport function composeDocsLinksAnswer(\n sections: readonly AssistDocsSection[],\n): string {\n const links = sections\n .slice(0, MAX_LINKED_SECTIONS)\n .map((section) => `[${sectionLabel(section)}](${sectionUrl(section)})`)\n if (!links.length) return ''\n return [\n 'I could not find one page in the documentation that clearly answers that, and the part of me that talks a question through with you is not switched on for this deployment yet — an administrator has to finish setting it up.',\n 'These are the closest pages I found:',\n links.join('\\n'),\n 'If none of them cover it, asking again in different words often lands somewhere better.',\n ].join('\\n\\n')\n}\n"],"names":["DOCS_SITE_ORIGIN","docsDocumentFrequency","tokenize","MIN_QUESTION_TOKENS","MIN_TOP_SCORE","MIN_PAGE_MARGIN","MIN_COVERAGE","RELAXED_COVERAGE","STRONG_PAGE_MARGIN","FOLLOW_UP_MIN_TOP_SCORE","FOLLOW_UP_MIN_PAGE_MARGIN","QUESTION_CUES","CONTEXT_DEPENDENT_PATTERNS","MIN_SECTION_CHARS","MAX_QUOTED_SECTIONS","MAX_ANSWER_CHARS","GENERATIVE_PATTERNS","DIAGNOSTIC_PATTERNS","refuse","refusal","topScore","pageMargin","coverage","answered","answer","quoted","page","tokenWeight","token","frequency","sections","seen","get","Math","log","sectionUrl","section","path","anchor","sectionLabel","heading","title","trimToSentence","text","limit","trimmed","trim","length","window","slice","lastStop","max","lastIndexOf","trimEnd","questionIsAnswerableFromDocs","question","tokens","Set","size","pattern","test","questionStandsAlone","deflectToDocs","scored","hasHistory","intent","minTopScore","minPageMargin","top","score","perPage","Map","entry","set","winner","winnerScore","rivalScore","pageSections","filter","pageTokens","add","questionTokens","wanted","covered","weight","has","coveredEnough","usable","map","composeDocsAnswer","parts","budget","quote","push","join","MAX_LINKED_SECTIONS","composeDocsLinksAnswer","links"],"mappings":"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"}