@aglyn/aglyn 1.0.0-beta.217 → 1.0.0-beta.219

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 (348) hide show
  1. package/package.json +14 -14
  2. package/src/lib/app-utils/actions.d.ts +25 -374
  3. package/src/lib/app-utils/actions.js +101 -561
  4. package/src/lib/app-utils/actions.js.map +1 -1
  5. package/src/lib/app-utils/activity-presenter.d.ts +3 -3
  6. package/src/lib/app-utils/activity-presenter.js +36 -52
  7. package/src/lib/app-utils/activity-presenter.js.map +1 -1
  8. package/src/lib/app-utils/admin-audit-index.js +2 -2
  9. package/src/lib/app-utils/admin-audit-index.js.map +1 -1
  10. package/src/lib/app-utils/analytics-events.d.ts +11 -2
  11. package/src/lib/app-utils/analytics-events.js +11 -2
  12. package/src/lib/app-utils/analytics-events.js.map +1 -1
  13. package/src/lib/app-utils/analytics-provider.d.ts +182 -0
  14. package/src/lib/app-utils/analytics-provider.js +133 -0
  15. package/src/lib/app-utils/analytics-provider.js.map +1 -0
  16. package/src/lib/app-utils/api-plugins.d.ts +46 -0
  17. package/src/lib/app-utils/api-plugins.js +19 -0
  18. package/src/lib/app-utils/api-plugins.js.map +1 -1
  19. package/src/lib/app-utils/{marketplace-overrides.d.ts → artifact-overrides.d.ts} +9 -6
  20. package/src/lib/app-utils/{marketplace-overrides.js → artifact-overrides.js} +10 -7
  21. package/src/lib/app-utils/artifact-overrides.js.map +1 -0
  22. package/src/lib/app-utils/{marketplace-provenance.d.ts → artifact-provenance.d.ts} +12 -10
  23. package/src/lib/app-utils/{marketplace-provenance.js → artifact-provenance.js} +9 -7
  24. package/src/lib/app-utils/artifact-provenance.js.map +1 -0
  25. package/src/lib/app-utils/assist-credits.js +2 -1
  26. package/src/lib/app-utils/assist-credits.js.map +1 -1
  27. package/src/lib/app-utils/binding-token-catalog.d.ts +5 -13
  28. package/src/lib/app-utils/binding-token-catalog.js +17 -41
  29. package/src/lib/app-utils/binding-token-catalog.js.map +1 -1
  30. package/src/lib/app-utils/binding-tokens.js +1 -1
  31. package/src/lib/app-utils/binding-tokens.js.map +1 -1
  32. package/src/lib/app-utils/brand-support-line.d.ts +36 -0
  33. package/src/lib/app-utils/brand-support-line.js +38 -0
  34. package/src/lib/app-utils/brand-support-line.js.map +1 -0
  35. package/src/lib/app-utils/campaign-touch.d.ts +5 -5
  36. package/src/lib/app-utils/campaign-touch.js +8 -8
  37. package/src/lib/app-utils/campaign-touch.js.map +1 -1
  38. package/src/lib/app-utils/collection-entries.d.ts +2 -2
  39. package/src/lib/app-utils/collection-entries.js.map +1 -1
  40. package/src/lib/app-utils/consent-group-change.d.ts +4 -0
  41. package/src/lib/app-utils/consent-group-change.js.map +1 -1
  42. package/src/lib/app-utils/console-record-links.d.ts +10 -89
  43. package/src/lib/app-utils/console-record-links.js +3 -107
  44. package/src/lib/app-utils/console-record-links.js.map +1 -1
  45. package/src/lib/app-utils/console-routes.d.ts +16 -7
  46. package/src/lib/app-utils/console-routes.js +9 -3
  47. package/src/lib/app-utils/console-routes.js.map +1 -1
  48. package/src/lib/app-utils/contacts.d.ts +23 -1
  49. package/src/lib/app-utils/contacts.js +21 -5
  50. package/src/lib/app-utils/contacts.js.map +1 -1
  51. package/src/lib/app-utils/cross-pool-desync.d.ts +39 -0
  52. package/src/lib/app-utils/cross-pool-desync.js +47 -0
  53. package/src/lib/app-utils/cross-pool-desync.js.map +1 -0
  54. package/src/lib/app-utils/csv-upload.d.ts +29 -0
  55. package/src/lib/app-utils/csv-upload.js +29 -0
  56. package/src/lib/app-utils/csv-upload.js.map +1 -0
  57. package/src/lib/app-utils/dataset-models.d.ts +5 -5
  58. package/src/lib/app-utils/dataset-models.js +19 -2
  59. package/src/lib/app-utils/dataset-models.js.map +1 -1
  60. package/src/lib/app-utils/datasets.d.ts +65 -11
  61. package/src/lib/app-utils/datasets.js +74 -11
  62. package/src/lib/app-utils/datasets.js.map +1 -1
  63. package/src/lib/app-utils/docs-deflection.d.ts +6 -6
  64. package/src/lib/app-utils/docs-deflection.js.map +1 -1
  65. package/src/lib/app-utils/docs-help.generated.d.ts +12 -6
  66. package/src/lib/app-utils/docs-help.generated.js +21 -6
  67. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  68. package/src/lib/app-utils/docs-index.generated.d.ts +2 -2
  69. package/src/lib/app-utils/docs-index.generated.js +514 -318
  70. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  71. package/src/lib/app-utils/docs-retrieval.d.ts +3 -3
  72. package/src/lib/app-utils/docs-retrieval.js +14 -10
  73. package/src/lib/app-utils/docs-retrieval.js.map +1 -1
  74. package/src/lib/app-utils/duplicate-resource.d.ts +4 -1
  75. package/src/lib/app-utils/duplicate-resource.js +7 -4
  76. package/src/lib/app-utils/duplicate-resource.js.map +1 -1
  77. package/src/lib/app-utils/dynamic-list-rule.d.ts +1 -1
  78. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -1
  79. package/src/lib/app-utils/element-ui.d.ts +1 -1
  80. package/src/lib/app-utils/element-ui.js +1 -1
  81. package/src/lib/app-utils/element-ui.js.map +1 -1
  82. package/src/lib/app-utils/email-starter-policy.js +3 -3
  83. package/src/lib/app-utils/email-starter-policy.js.map +1 -1
  84. package/src/lib/app-utils/entity-picker-context.d.ts +10 -5
  85. package/src/lib/app-utils/entity-picker-context.js.map +1 -1
  86. package/src/lib/app-utils/error-beacon.d.ts +75 -6
  87. package/src/lib/app-utils/error-beacon.js +160 -21
  88. package/src/lib/app-utils/error-beacon.js.map +1 -1
  89. package/src/lib/app-utils/expand-repeatables.d.ts +10 -10
  90. package/src/lib/app-utils/expand-repeatables.js +10 -10
  91. package/src/lib/app-utils/expand-repeatables.js.map +1 -1
  92. package/src/lib/app-utils/host-events.d.ts +82 -0
  93. package/src/lib/app-utils/host-events.js +62 -0
  94. package/src/lib/app-utils/host-events.js.map +1 -0
  95. package/src/lib/app-utils/lockdown.d.ts +33 -1
  96. package/src/lib/app-utils/lockdown.js +45 -4
  97. package/src/lib/app-utils/lockdown.js.map +1 -1
  98. package/src/lib/app-utils/margin-utilization.d.ts +4 -69
  99. package/src/lib/app-utils/margin-utilization.js +82 -69
  100. package/src/lib/app-utils/margin-utilization.js.map +1 -1
  101. package/src/lib/app-utils/node-definition-sanitizer.d.ts +16 -16
  102. package/src/lib/app-utils/node-definition-sanitizer.js +24 -20
  103. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -1
  104. package/src/lib/app-utils/node-interactions.d.ts +7 -7
  105. package/src/lib/app-utils/node-interactions.js.map +1 -1
  106. package/src/lib/app-utils/notifications.d.ts +78 -47
  107. package/src/lib/app-utils/notifications.js +63 -44
  108. package/src/lib/app-utils/notifications.js.map +1 -1
  109. package/src/lib/app-utils/payments-configured.d.ts +8 -21
  110. package/src/lib/app-utils/payments-configured.js +8 -23
  111. package/src/lib/app-utils/payments-configured.js.map +1 -1
  112. package/src/lib/app-utils/plan-entitlements.d.ts +43 -128
  113. package/src/lib/app-utils/plan-entitlements.js +145 -304
  114. package/src/lib/app-utils/plan-entitlements.js.map +1 -1
  115. package/src/lib/app-utils/platform-brand.d.ts +10 -0
  116. package/src/lib/app-utils/platform-brand.js +14 -3
  117. package/src/lib/app-utils/platform-brand.js.map +1 -1
  118. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +7 -1
  119. package/src/lib/app-utils/plugin-api-rate-limit.js +11 -3
  120. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -1
  121. package/src/lib/app-utils/plugin-bundle-checks.js +2 -2
  122. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -1
  123. package/src/lib/app-utils/plugin-host-events.generated.d.ts +12 -0
  124. package/src/lib/app-utils/plugin-host-events.generated.js +169 -0
  125. package/src/lib/app-utils/plugin-host-events.generated.js.map +1 -0
  126. package/src/lib/app-utils/plugin-release-flags.generated.d.ts +12 -0
  127. package/src/lib/app-utils/plugin-release-flags.generated.js +106 -0
  128. package/src/lib/app-utils/plugin-release-flags.generated.js.map +1 -0
  129. package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
  130. package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
  131. package/src/lib/app-utils/release-flags.d.ts +14 -5
  132. package/src/lib/app-utils/release-flags.js +21 -125
  133. package/src/lib/app-utils/release-flags.js.map +1 -1
  134. package/src/lib/app-utils/repeat-sources.d.ts +9 -0
  135. package/src/lib/app-utils/repeat-sources.js.map +1 -1
  136. package/src/lib/app-utils/retained-refusals.d.ts +73 -0
  137. package/src/lib/app-utils/retained-refusals.js +186 -0
  138. package/src/lib/app-utils/retained-refusals.js.map +1 -0
  139. package/src/lib/app-utils/scope-tokens.d.ts +27 -0
  140. package/src/lib/app-utils/scope-tokens.js +61 -0
  141. package/src/lib/app-utils/scope-tokens.js.map +1 -1
  142. package/src/lib/app-utils/screen-link-context.js +3 -3
  143. package/src/lib/app-utils/screen-link-context.js.map +1 -1
  144. package/src/lib/app-utils/screen-route.d.ts +15 -0
  145. package/src/lib/app-utils/screen-route.js +21 -1
  146. package/src/lib/app-utils/screen-route.js.map +1 -1
  147. package/src/lib/app-utils/seo-audit.d.ts +132 -0
  148. package/src/lib/app-utils/seo-audit.js +246 -0
  149. package/src/lib/app-utils/seo-audit.js.map +1 -0
  150. package/src/lib/app-utils/seo-keywords.d.ts +48 -0
  151. package/src/lib/app-utils/seo-keywords.js +60 -0
  152. package/src/lib/app-utils/seo-keywords.js.map +1 -0
  153. package/src/lib/app-utils/seo-page-facts.d.ts +66 -0
  154. package/src/lib/app-utils/seo-page-facts.js +155 -0
  155. package/src/lib/app-utils/seo-page-facts.js.map +1 -0
  156. package/src/lib/app-utils/seo-site-scan.d.ts +126 -0
  157. package/src/lib/app-utils/seo-site-scan.js +162 -0
  158. package/src/lib/app-utils/seo-site-scan.js.map +1 -0
  159. package/src/lib/app-utils/seo-title-variables.js +1 -1
  160. package/src/lib/app-utils/seo-title-variables.js.map +1 -1
  161. package/src/lib/app-utils/server.d.ts +6 -9
  162. package/src/lib/app-utils/server.js +17 -27
  163. package/src/lib/app-utils/server.js.map +1 -1
  164. package/src/lib/app-utils/site-interactions.d.ts +501 -0
  165. package/src/lib/app-utils/site-interactions.js +554 -0
  166. package/src/lib/app-utils/site-interactions.js.map +1 -0
  167. package/src/lib/app-utils/{marketplace-theme.d.ts → site-theme.d.ts} +13 -2
  168. package/src/lib/app-utils/{marketplace-theme.js → site-theme.js} +5 -2
  169. package/src/lib/app-utils/site-theme.js.map +1 -0
  170. package/src/lib/app-utils/sitemap.d.ts +4 -3
  171. package/src/lib/app-utils/sitemap.js +9 -7
  172. package/src/lib/app-utils/sitemap.js.map +1 -1
  173. package/src/lib/app-utils/stale-build-error.d.ts +51 -0
  174. package/src/lib/app-utils/stale-build-error.js +100 -1
  175. package/src/lib/app-utils/stale-build-error.js.map +1 -1
  176. package/src/lib/app-utils/starter-templates.d.ts +20 -0
  177. package/src/lib/app-utils/starter-templates.js +49 -0
  178. package/src/lib/app-utils/starter-templates.js.map +1 -1
  179. package/src/lib/app-utils/tax-jurisdiction-figures.d.ts +118 -0
  180. package/src/lib/app-utils/tax-jurisdiction-figures.js +123 -0
  181. package/src/lib/app-utils/tax-jurisdiction-figures.js.map +1 -0
  182. package/src/lib/app-utils/theme-library.d.ts +10 -3
  183. package/src/lib/app-utils/theme-library.js +13 -4
  184. package/src/lib/app-utils/theme-library.js.map +1 -1
  185. package/src/lib/app-utils/{campaign-attribution.d.ts → utm-attribution.d.ts} +11 -6
  186. package/src/lib/app-utils/{campaign-attribution.js → utm-attribution.js} +13 -8
  187. package/src/lib/app-utils/utm-attribution.js.map +1 -0
  188. package/src/lib/app-utils/{campaign-forwarding.d.ts → utm-forwarding.d.ts} +14 -14
  189. package/src/lib/app-utils/{campaign-forwarding.js → utm-forwarding.js} +26 -26
  190. package/src/lib/app-utils/utm-forwarding.js.map +1 -0
  191. package/src/lib/app-utils/video-object.js +6 -5
  192. package/src/lib/app-utils/video-object.js.map +1 -1
  193. package/src/lib/app-utils/visitor-consent.d.ts +41 -164
  194. package/src/lib/app-utils/visitor-consent.js +66 -277
  195. package/src/lib/app-utils/visitor-consent.js.map +1 -1
  196. package/src/lib/app-utils/web-vitals-rum.d.ts +7 -7
  197. package/src/lib/app-utils/web-vitals-rum.js +31 -63
  198. package/src/lib/app-utils/web-vitals-rum.js.map +1 -1
  199. package/src/lib/app-utils/where-used.d.ts +11 -6
  200. package/src/lib/app-utils/where-used.js +3 -8
  201. package/src/lib/app-utils/where-used.js.map +1 -1
  202. package/src/lib/canvas-manager/canvas-manager.js +3 -3
  203. package/src/lib/canvas-manager/canvas-manager.js.map +1 -1
  204. package/src/lib/foundation/definitions/components.types.d.ts +1 -1
  205. package/src/lib/foundation/definitions/components.types.js +1 -1
  206. package/src/lib/foundation/definitions/components.types.js.map +1 -1
  207. package/src/lib/foundation/definitions/org-billing.types.d.ts +18 -135
  208. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
  209. package/src/lib/foundation/definitions/organization.types.d.ts +6 -3
  210. package/src/lib/foundation/definitions/organization.types.js.map +1 -1
  211. package/src/lib/foundation/definitions/platform.types.d.ts +27 -5
  212. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  213. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +16 -0
  214. package/src/lib/foundation/definitions/write-deny-coverage.util.js +20 -0
  215. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -1
  216. package/src/lib/foundation/index.d.ts +1 -1
  217. package/src/lib/foundation/index.js.map +1 -1
  218. package/src/lib/plugin-manager/besigner-documents.d.ts +96 -0
  219. package/src/lib/plugin-manager/besigner-documents.js +61 -0
  220. package/src/lib/plugin-manager/besigner-documents.js.map +1 -0
  221. package/src/lib/plugin-manager/computed-variables.d.ts +71 -0
  222. package/src/lib/plugin-manager/computed-variables.js +74 -0
  223. package/src/lib/plugin-manager/computed-variables.js.map +1 -0
  224. package/src/lib/plugin-manager/custom-fields.d.ts +29 -2
  225. package/src/lib/plugin-manager/custom-fields.js +47 -1
  226. package/src/lib/plugin-manager/custom-fields.js.map +1 -1
  227. package/src/lib/plugin-manager/feature-plugins.d.ts +292 -20
  228. package/src/lib/plugin-manager/feature-plugins.js +105 -17
  229. package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
  230. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +123 -0
  231. package/src/lib/plugin-manager/first-party-plugins.generated.js +785 -14
  232. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
  233. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +12 -0
  234. package/src/lib/plugin-manager/plugin-activity-actions.js +25 -0
  235. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -1
  236. package/src/lib/plugin-manager/plugin-contributions.d.ts +1 -1
  237. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -1
  238. package/src/lib/plugin-manager/plugin-declarations-repair.d.ts +36 -0
  239. package/src/lib/plugin-manager/plugin-declarations-repair.js +64 -0
  240. package/src/lib/plugin-manager/plugin-declarations-repair.js.map +1 -0
  241. package/src/lib/plugin-manager/plugin-dependents.d.ts +101 -0
  242. package/src/lib/plugin-manager/plugin-dependents.js +75 -0
  243. package/src/lib/plugin-manager/plugin-dependents.js.map +1 -0
  244. package/src/lib/plugin-manager/plugin-distribution.d.ts +55 -0
  245. package/src/lib/plugin-manager/plugin-distribution.js +45 -0
  246. package/src/lib/plugin-manager/plugin-distribution.js.map +1 -0
  247. package/src/lib/plugin-manager/plugin-host-collections.d.ts +17 -0
  248. package/src/lib/plugin-manager/plugin-host-collections.js +6 -0
  249. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -1
  250. package/src/lib/plugin-manager/plugin-host-resources.d.ts +133 -0
  251. package/src/lib/plugin-manager/plugin-host-resources.js +52 -0
  252. package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -0
  253. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +28 -2
  254. package/src/lib/plugin-manager/plugin-org-erasure.js +61 -2
  255. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
  256. package/src/lib/plugin-manager/plugin-plan-entitlements.d.ts +123 -0
  257. package/src/lib/plugin-manager/plugin-plan-entitlements.js +101 -0
  258. package/src/lib/plugin-manager/plugin-plan-entitlements.js.map +1 -0
  259. package/src/lib/plugin-manager/plugin-record-index.d.ts +95 -0
  260. package/src/lib/plugin-manager/plugin-record-index.js +51 -0
  261. package/src/lib/plugin-manager/plugin-record-index.js.map +1 -0
  262. package/src/lib/plugin-manager/plugin-record-written.d.ts +58 -0
  263. package/src/lib/plugin-manager/plugin-record-written.js +42 -0
  264. package/src/lib/plugin-manager/plugin-record-written.js.map +1 -0
  265. package/src/lib/plugin-manager/plugin-revenue-sources.d.ts +213 -0
  266. package/src/lib/plugin-manager/plugin-revenue-sources.js +194 -0
  267. package/src/lib/plugin-manager/plugin-revenue-sources.js.map +1 -0
  268. package/src/lib/plugin-manager/plugin-site-bundle.d.ts +145 -0
  269. package/src/lib/plugin-manager/plugin-site-bundle.js +78 -0
  270. package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -0
  271. package/src/lib/plugin-manager/plugin-site-cache.d.ts +12 -0
  272. package/src/lib/plugin-manager/plugin-site-cache.js.map +1 -1
  273. package/src/lib/plugin-manager/plugin-site-export.d.ts +81 -0
  274. package/src/lib/plugin-manager/plugin-site-export.js +40 -0
  275. package/src/lib/plugin-manager/plugin-site-export.js.map +1 -0
  276. package/src/lib/plugin-manager/plugin-sitemap-sections.d.ts +88 -0
  277. package/src/lib/plugin-manager/plugin-sitemap-sections.js +29 -0
  278. package/src/lib/plugin-manager/plugin-sitemap-sections.js.map +1 -0
  279. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +20 -4
  280. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -1
  281. package/src/lib/plugin-manager/plugin-tax-return-sources.d.ts +255 -0
  282. package/src/lib/plugin-manager/plugin-tax-return-sources.js +191 -0
  283. package/src/lib/plugin-manager/plugin-tax-return-sources.js.map +1 -0
  284. package/src/lib/plugin-manager/plugin-template-sources.d.ts +75 -0
  285. package/src/lib/plugin-manager/plugin-template-sources.js +37 -0
  286. package/src/lib/plugin-manager/plugin-template-sources.js.map +1 -0
  287. package/src/lib/plugin-manager/plugin-usage-axes.d.ts +107 -0
  288. package/src/lib/plugin-manager/plugin-usage-axes.js +107 -0
  289. package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -0
  290. package/src/lib/plugin-manager/plugin-zones.d.ts +4 -5
  291. package/src/lib/plugin-manager/plugin-zones.js.map +1 -1
  292. package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
  293. package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
  294. package/src/lib/plugin-manager/record-captured-contact.d.ts +1 -14
  295. package/src/lib/plugin-manager/record-captured-contact.js +10 -32
  296. package/src/lib/plugin-manager/record-captured-contact.js.map +1 -1
  297. package/src/lib/plugin-manager/repeat-rows.d.ts +124 -0
  298. package/src/lib/plugin-manager/repeat-rows.js +108 -0
  299. package/src/lib/plugin-manager/repeat-rows.js.map +1 -0
  300. package/src/lib/plugin-manager/submission-record-target.d.ts +144 -0
  301. package/src/lib/plugin-manager/submission-record-target.js +125 -0
  302. package/src/lib/plugin-manager/submission-record-target.js.map +1 -0
  303. package/src/lib/plugin-manager/video-embed-provider.d.ts +108 -0
  304. package/src/lib/plugin-manager/video-embed-provider.js +165 -0
  305. package/src/lib/plugin-manager/video-embed-provider.js.map +1 -0
  306. package/src/lib/types/nodes.d.ts +2 -2
  307. package/src/lib/types/nodes.js.map +1 -1
  308. package/src/lib/app-utils/campaign-attribution.js.map +0 -1
  309. package/src/lib/app-utils/campaign-forwarding.js.map +0 -1
  310. package/src/lib/app-utils/contact-holder.d.ts +0 -68
  311. package/src/lib/app-utils/contact-holder.js +0 -129
  312. package/src/lib/app-utils/contact-holder.js.map +0 -1
  313. package/src/lib/app-utils/contact-merge.d.ts +0 -136
  314. package/src/lib/app-utils/contact-merge.js +0 -412
  315. package/src/lib/app-utils/contact-merge.js.map +0 -1
  316. package/src/lib/app-utils/crm-csv.d.ts +0 -239
  317. package/src/lib/app-utils/crm-csv.js +0 -467
  318. package/src/lib/app-utils/crm-csv.js.map +0 -1
  319. package/src/lib/app-utils/crm-digest.d.ts +0 -185
  320. package/src/lib/app-utils/crm-digest.js +0 -272
  321. package/src/lib/app-utils/crm-digest.js.map +0 -1
  322. package/src/lib/app-utils/form-dataset-binding.d.ts +0 -50
  323. package/src/lib/app-utils/form-dataset-binding.js +0 -74
  324. package/src/lib/app-utils/form-dataset-binding.js.map +0 -1
  325. package/src/lib/app-utils/list-import.d.ts +0 -158
  326. package/src/lib/app-utils/list-import.js +0 -332
  327. package/src/lib/app-utils/list-import.js.map +0 -1
  328. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +0 -122
  329. package/src/lib/app-utils/marketplace-listing-visibility.js +0 -147
  330. package/src/lib/app-utils/marketplace-listing-visibility.js.map +0 -1
  331. package/src/lib/app-utils/marketplace-overrides.js.map +0 -1
  332. package/src/lib/app-utils/marketplace-provenance.js.map +0 -1
  333. package/src/lib/app-utils/marketplace-theme.js.map +0 -1
  334. package/src/lib/app-utils/marketplace-update-state.d.ts +0 -119
  335. package/src/lib/app-utils/marketplace-update-state.js +0 -132
  336. package/src/lib/app-utils/marketplace-update-state.js.map +0 -1
  337. package/src/lib/app-utils/publisher-agreement.d.ts +0 -289
  338. package/src/lib/app-utils/publisher-agreement.js +0 -321
  339. package/src/lib/app-utils/publisher-agreement.js.map +0 -1
  340. package/src/lib/app-utils/wistia-embed.d.ts +0 -104
  341. package/src/lib/app-utils/wistia-embed.js +0 -138
  342. package/src/lib/app-utils/wistia-embed.js.map +0 -1
  343. package/src/lib/app-utils/workflows.d.ts +0 -136
  344. package/src/lib/app-utils/workflows.js +0 -346
  345. package/src/lib/app-utils/workflows.js.map +0 -1
  346. package/src/lib/plugin-manager/commerce-zone-props.d.ts +0 -172
  347. package/src/lib/plugin-manager/commerce-zone-props.js +0 -31
  348. package/src/lib/plugin-manager/commerce-zone-props.js.map +0 -1
@@ -14,11 +14,11 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- import { type AssistDocsSection } from './docs-index.generated';
17
+ import { type DocsSection } from './docs-index.generated';
18
18
  /** Lowercase word tokens, stop words removed, length >= 2. */
19
19
  export declare function tokenize(text: string): string[];
20
20
  export interface ScoredSection {
21
- section: AssistDocsSection;
21
+ section: DocsSection;
22
22
  score: number;
23
23
  }
24
24
  /**
@@ -26,7 +26,7 @@ export interface ScoredSection {
26
26
  * nothing scores above zero — the caller then answers without docs grounding
27
27
  * rather than citing an irrelevant page.
28
28
  */
29
- export declare function retrieveDocsSections(question: string, limit?: number, sections?: readonly AssistDocsSection[]): ScoredSection[];
29
+ export declare function retrieveDocsSections(question: string, limit?: number, sections?: readonly DocsSection[]): ScoredSection[];
30
30
  export declare function docsDocumentFrequency(): {
31
31
  frequency: ReadonlyMap<string, number>;
32
32
  sections: number;
@@ -13,14 +13,18 @@
13
13
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
- */ import { ASSIST_DOCS_INDEX } from "./docs-index.generated.js";
16
+ */ import { DOCS_SECTION_INDEX } from "./docs-index.generated.js";
17
17
  import { DOCS_BASE_URL } from "./docs-help.js";
18
18
  /**
19
- * Lexical docs retrieval for Aglyn Assist (AGL-1860, phase 1) — deliberately
20
- * no vector store: a BM25-flavoured term-frequency score over the generated
21
- * docs section index, with title/heading term boosts. Good enough to ground
22
- * "how do I…" answers in the right docs section and cheap enough to run on
23
- * every message inside the API route.
19
+ * Lexical docs search (AGL-1860, phase 1) — deliberately no vector store: a
20
+ * BM25-flavoured term-frequency score over the generated docs section index,
21
+ * with title/heading term boosts. Good enough to find the right docs section
22
+ * for a "how do I…" question and cheap enough to run on every request inside
23
+ * an API route.
24
+ *
25
+ * The platform's, and named so (AGL-3080): the console's issue reports
26
+ * deflect to it with no model involved, and the AI plugin grounds its answers
27
+ * in it — one reader among others, not its owner.
24
28
  */ /** Words too common in this corpus to carry signal. */ const STOP_WORDS = new Set([
25
29
  'a',
26
30
  'an',
@@ -97,12 +101,12 @@ function buildIndex(sections) {
97
101
  * Top-`limit` docs sections for a user question. Returns an empty array when
98
102
  * nothing scores above zero — the caller then answers without docs grounding
99
103
  * rather than citing an irrelevant page.
100
- */ export function retrieveDocsSections(question, limit = 6, sections = ASSIST_DOCS_INDEX) {
104
+ */ export function retrieveDocsSections(question, limit = 6, sections = DOCS_SECTION_INDEX) {
101
105
  const queryTokens = [
102
106
  ...new Set(tokenize(question))
103
107
  ];
104
108
  if (!queryTokens.length) return [];
105
- const index = sections === ASSIST_DOCS_INDEX ? indexed != null ? indexed : indexed = buildIndex(sections) : buildIndex(sections);
109
+ const index = sections === DOCS_SECTION_INDEX ? indexed != null ? indexed : indexed = buildIndex(sections) : buildIndex(sections);
106
110
  return index.map((entry)=>({
107
111
  section: entry.section,
108
112
  score: scoreSection(entry.section, queryTokens, entry.bodyTokenCounts, entry.titleTokens, entry.headingTokens)
@@ -124,7 +128,7 @@ function buildIndex(sections) {
124
128
  */ let documentFrequency = null;
125
129
  export function docsDocumentFrequency() {
126
130
  if (!documentFrequency) {
127
- const index = indexed != null ? indexed : indexed = buildIndex(ASSIST_DOCS_INDEX);
131
+ const index = indexed != null ? indexed : indexed = buildIndex(DOCS_SECTION_INDEX);
128
132
  const frequency = new Map();
129
133
  for (const entry of index){
130
134
  const seen = new Set([
@@ -141,7 +145,7 @@ export function docsDocumentFrequency() {
141
145
  }
142
146
  return {
143
147
  frequency: documentFrequency,
144
- sections: ASSIST_DOCS_INDEX.length
148
+ sections: DOCS_SECTION_INDEX.length
145
149
  };
146
150
  }
147
151
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/docs-retrieval.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 {\n ASSIST_DOCS_INDEX,\n type AssistDocsSection,\n} from './docs-index.generated'\nimport { DOCS_BASE_URL } from './docs-help'\n\n/**\n * Lexical docs retrieval for Aglyn Assist (AGL-1860, phase 1) — deliberately\n * no vector store: a BM25-flavoured term-frequency score over the generated\n * docs section index, with title/heading term boosts. Good enough to ground\n * \"how do I…\" answers in the right docs section and cheap enough to run on\n * every message inside the API route.\n */\n\n/** Words too common in this corpus to carry signal. */\nconst STOP_WORDS = new Set([\n 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'can', 'do', 'does',\n 'for', 'from', 'how', 'i', 'in', 'is', 'it', 'my', 'of', 'on', 'or',\n 'that', 'the', 'this', 'to', 'what', 'when', 'where', 'which', 'why',\n 'with', 'you', 'your',\n])\n\n/** Lowercase word tokens, stop words removed, length >= 2. */\nexport function tokenize(text: string): string[] {\n return (text.toLowerCase().match(/[\\p{L}\\p{N}]{2,}/gu) ?? []).filter(\n (token) => !STOP_WORDS.has(token),\n )\n}\n\nexport interface ScoredSection {\n section: AssistDocsSection\n score: number\n}\n\n/**\n * Score one section against query tokens. Term frequency saturates quickly\n * (BM25-ish k=1.2) so one section mentioning \"domain\" ten times does not\n * drown a section about the actual task; title and heading hits carry\n * dedicated boosts because those are the docs' own statement of topic.\n */\nfunction scoreSection(\n section: AssistDocsSection,\n queryTokens: readonly string[],\n bodyTokenCounts: Map<string, number>,\n titleTokens: Set<string>,\n headingTokens: Set<string>,\n): number {\n let score = 0\n for (const token of queryTokens) {\n const tf = bodyTokenCounts.get(token) ?? 0\n if (tf > 0) score += (tf * 2.2) / (tf + 1.2)\n if (titleTokens.has(token)) score += 2.5\n if (headingTokens.has(token)) score += 2\n }\n return score\n}\n\ninterface IndexedSection {\n section: AssistDocsSection\n bodyTokenCounts: Map<string, number>\n titleTokens: Set<string>\n headingTokens: Set<string>\n}\n\n/** Tokenized once per process — module scope, ~650 sections. */\nlet indexed: IndexedSection[] | null = null\n\nfunction buildIndex(sections: readonly AssistDocsSection[]): IndexedSection[] {\n return sections.map((section) => {\n const bodyTokenCounts = new Map<string, number>()\n for (const token of tokenize(section.text)) {\n bodyTokenCounts.set(token, (bodyTokenCounts.get(token) ?? 0) + 1)\n }\n return {\n section,\n bodyTokenCounts,\n titleTokens: new Set(tokenize(section.title)),\n headingTokens: new Set(tokenize(section.heading)),\n }\n })\n}\n\n/**\n * Top-`limit` docs sections for a user question. Returns an empty array when\n * nothing scores above zero — the caller then answers without docs grounding\n * rather than citing an irrelevant page.\n */\nexport function retrieveDocsSections(\n question: string,\n limit = 6,\n sections: readonly AssistDocsSection[] = ASSIST_DOCS_INDEX,\n): ScoredSection[] {\n const queryTokens = [...new Set(tokenize(question))]\n if (!queryTokens.length) return []\n const index =\n sections === ASSIST_DOCS_INDEX\n ? (indexed ??= buildIndex(sections))\n : buildIndex(sections)\n return index\n .map((entry) => ({\n section: entry.section,\n score: scoreSection(\n entry.section,\n queryTokens,\n entry.bodyTokenCounts,\n entry.titleTokens,\n entry.headingTokens,\n ),\n }))\n .filter((scored) => scored.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n}\n\n/**\n * How many indexed sections each token appears in — the raw material for an\n * IDF weight (AGL-2486).\n *\n * Lives here rather than in the deflection module because the tokenized index\n * is already built here and rebuilding it there would tokenize ~500KB of docs\n * a second time, per process, to reach the same numbers. Memoised alongside\n * `indexed` and derived from it, so the two can never disagree about what a\n * token is.\n *\n * Counts SECTIONS, not pages: a term confined to one page but repeated in\n * every section of it is still a specific term, and page-level counting would\n * flatten exactly the distinction the weight exists to make.\n */\nlet documentFrequency: Map<string, number> | null = null\n\nexport function docsDocumentFrequency(): {\n frequency: ReadonlyMap<string, number>\n sections: number\n} {\n if (!documentFrequency) {\n const index = (indexed ??= buildIndex(ASSIST_DOCS_INDEX))\n const frequency = new Map<string, number>()\n for (const entry of index) {\n const seen = new Set<string>([\n ...entry.bodyTokenCounts.keys(),\n ...entry.titleTokens,\n ...entry.headingTokens,\n ])\n for (const token of seen) {\n frequency.set(token, (frequency.get(token) ?? 0) + 1)\n }\n }\n documentFrequency = frequency\n }\n return { frequency: documentFrequency, sections: ASSIST_DOCS_INDEX.length }\n}\n\n/**\n * Public docs-site origin for deep links the assistant hands the user.\n *\n * Configurable (AGL-2016): a self-hoster who publishes the `apps/docs` site on\n * their own domain otherwise had every Assist citation deep-link into\n * `docs.aglyn.com` — our documentation, describing our deployment's flags and\n * plans, cited as if it were theirs.\n *\n * Unlike the operator CONTACT values this keeps our value as the default, and\n * the difference is deliberate: an unset citation origin degrades to a page\n * that genuinely exists and is genuinely about this software, so it is wrong\n * in the way a stale bookmark is wrong. An unset contact address would\n * misroute a legal notice, which is why that one refuses to guess.\n *\n * ⚠️ RE-EXPORTED FROM `DOCS_BASE_URL` RATHER THAN READ AGAIN HERE (AGL-2014).\n * This module had its own `process.env.NEXT_PUBLIC_DOCS_ORIGIN || 'https://\n * docs.aglyn.com'`, which accepted ONLY the canonical name — while\n * `constants/docs-links.ts` also honours the older `NEXT_PUBLIC_AGLYN_DOCS_URL`.\n * So AGL-2186's own defect survived, inverted, in the one file it did not\n * touch: a deployment configured under the older name retargeted every console\n * and besigner help link and left every ASSIST CITATION pointing at\n * `docs.aglyn.com` — our documentation, cited inside their product as theirs.\n * That is the same \"one value, two env names\" split AGL-733 is the record of.\n * One reader means an operator's docs site cannot be honoured on some surfaces\n * and ignored on others.\n */\nexport const DOCS_SITE_ORIGIN = DOCS_BASE_URL\n\n/**\n * The grounding block injected into the system prompt: the retrieved\n * sections, each with its citable URL, wrapped so the model can quote and\n * link them. Kept AFTER the stable system prefix so prompt caching of the\n * static prefix survives per-question variation.\n */\nexport function docsGroundingBlock(scored: readonly ScoredSection[]): string {\n if (!scored.length) return ''\n const parts = scored.map(({ section }) => {\n const url = `${DOCS_SITE_ORIGIN}${section.path}${section.anchor}`\n const heading = section.heading\n ? `${section.title} — ${section.heading}`\n : section.title\n return `<doc url=\"${url}\" title=\"${heading}\">\\n${section.text}\\n</doc>`\n })\n return `\\n\\nRelevant documentation sections (cite these URLs when they answer the question):\\n${parts.join('\\n')}`\n}\n"],"names":["ASSIST_DOCS_INDEX","DOCS_BASE_URL","STOP_WORDS","Set","tokenize","text","toLowerCase","match","filter","token","has","scoreSection","section","queryTokens","bodyTokenCounts","titleTokens","headingTokens","score","tf","get","indexed","buildIndex","sections","map","Map","set","title","heading","retrieveDocsSections","question","limit","length","index","entry","scored","sort","a","b","slice","documentFrequency","docsDocumentFrequency","frequency","seen","keys","DOCS_SITE_ORIGIN","docsGroundingBlock","parts","url","path","anchor","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/docs-retrieval.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 {\n DOCS_SECTION_INDEX,\n type DocsSection,\n} from './docs-index.generated'\nimport { DOCS_BASE_URL } from './docs-help'\n\n/**\n * Lexical docs search (AGL-1860, phase 1) — deliberately no vector store: a\n * BM25-flavoured term-frequency score over the generated docs section index,\n * with title/heading term boosts. Good enough to find the right docs section\n * for a \"how do I…\" question and cheap enough to run on every request inside\n * an API route.\n *\n * The platform's, and named so (AGL-3080): the console's issue reports\n * deflect to it with no model involved, and the AI plugin grounds its answers\n * in it — one reader among others, not its owner.\n */\n\n/** Words too common in this corpus to carry signal. */\nconst STOP_WORDS = new Set([\n 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'can', 'do', 'does',\n 'for', 'from', 'how', 'i', 'in', 'is', 'it', 'my', 'of', 'on', 'or',\n 'that', 'the', 'this', 'to', 'what', 'when', 'where', 'which', 'why',\n 'with', 'you', 'your',\n])\n\n/** Lowercase word tokens, stop words removed, length >= 2. */\nexport function tokenize(text: string): string[] {\n return (text.toLowerCase().match(/[\\p{L}\\p{N}]{2,}/gu) ?? []).filter(\n (token) => !STOP_WORDS.has(token),\n )\n}\n\nexport interface ScoredSection {\n section: DocsSection\n score: number\n}\n\n/**\n * Score one section against query tokens. Term frequency saturates quickly\n * (BM25-ish k=1.2) so one section mentioning \"domain\" ten times does not\n * drown a section about the actual task; title and heading hits carry\n * dedicated boosts because those are the docs' own statement of topic.\n */\nfunction scoreSection(\n section: DocsSection,\n queryTokens: readonly string[],\n bodyTokenCounts: Map<string, number>,\n titleTokens: Set<string>,\n headingTokens: Set<string>,\n): number {\n let score = 0\n for (const token of queryTokens) {\n const tf = bodyTokenCounts.get(token) ?? 0\n if (tf > 0) score += (tf * 2.2) / (tf + 1.2)\n if (titleTokens.has(token)) score += 2.5\n if (headingTokens.has(token)) score += 2\n }\n return score\n}\n\ninterface IndexedSection {\n section: DocsSection\n bodyTokenCounts: Map<string, number>\n titleTokens: Set<string>\n headingTokens: Set<string>\n}\n\n/** Tokenized once per process — module scope, ~650 sections. */\nlet indexed: IndexedSection[] | null = null\n\nfunction buildIndex(sections: readonly DocsSection[]): IndexedSection[] {\n return sections.map((section) => {\n const bodyTokenCounts = new Map<string, number>()\n for (const token of tokenize(section.text)) {\n bodyTokenCounts.set(token, (bodyTokenCounts.get(token) ?? 0) + 1)\n }\n return {\n section,\n bodyTokenCounts,\n titleTokens: new Set(tokenize(section.title)),\n headingTokens: new Set(tokenize(section.heading)),\n }\n })\n}\n\n/**\n * Top-`limit` docs sections for a user question. Returns an empty array when\n * nothing scores above zero — the caller then answers without docs grounding\n * rather than citing an irrelevant page.\n */\nexport function retrieveDocsSections(\n question: string,\n limit = 6,\n sections: readonly DocsSection[] = DOCS_SECTION_INDEX,\n): ScoredSection[] {\n const queryTokens = [...new Set(tokenize(question))]\n if (!queryTokens.length) return []\n const index =\n sections === DOCS_SECTION_INDEX\n ? (indexed ??= buildIndex(sections))\n : buildIndex(sections)\n return index\n .map((entry) => ({\n section: entry.section,\n score: scoreSection(\n entry.section,\n queryTokens,\n entry.bodyTokenCounts,\n entry.titleTokens,\n entry.headingTokens,\n ),\n }))\n .filter((scored) => scored.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n}\n\n/**\n * How many indexed sections each token appears in — the raw material for an\n * IDF weight (AGL-2486).\n *\n * Lives here rather than in the deflection module because the tokenized index\n * is already built here and rebuilding it there would tokenize ~500KB of docs\n * a second time, per process, to reach the same numbers. Memoised alongside\n * `indexed` and derived from it, so the two can never disagree about what a\n * token is.\n *\n * Counts SECTIONS, not pages: a term confined to one page but repeated in\n * every section of it is still a specific term, and page-level counting would\n * flatten exactly the distinction the weight exists to make.\n */\nlet documentFrequency: Map<string, number> | null = null\n\nexport function docsDocumentFrequency(): {\n frequency: ReadonlyMap<string, number>\n sections: number\n} {\n if (!documentFrequency) {\n const index = (indexed ??= buildIndex(DOCS_SECTION_INDEX))\n const frequency = new Map<string, number>()\n for (const entry of index) {\n const seen = new Set<string>([\n ...entry.bodyTokenCounts.keys(),\n ...entry.titleTokens,\n ...entry.headingTokens,\n ])\n for (const token of seen) {\n frequency.set(token, (frequency.get(token) ?? 0) + 1)\n }\n }\n documentFrequency = frequency\n }\n return { frequency: documentFrequency, sections: DOCS_SECTION_INDEX.length }\n}\n\n/**\n * Public docs-site origin for deep links the assistant hands the user.\n *\n * Configurable (AGL-2016): a self-hoster who publishes the `apps/docs` site on\n * their own domain otherwise had every Assist citation deep-link into\n * `docs.aglyn.com` — our documentation, describing our deployment's flags and\n * plans, cited as if it were theirs.\n *\n * Unlike the operator CONTACT values this keeps our value as the default, and\n * the difference is deliberate: an unset citation origin degrades to a page\n * that genuinely exists and is genuinely about this software, so it is wrong\n * in the way a stale bookmark is wrong. An unset contact address would\n * misroute a legal notice, which is why that one refuses to guess.\n *\n * ⚠️ RE-EXPORTED FROM `DOCS_BASE_URL` RATHER THAN READ AGAIN HERE (AGL-2014).\n * This module had its own `process.env.NEXT_PUBLIC_DOCS_ORIGIN || 'https://\n * docs.aglyn.com'`, which accepted ONLY the canonical name — while\n * `constants/docs-links.ts` also honours the older `NEXT_PUBLIC_AGLYN_DOCS_URL`.\n * So AGL-2186's own defect survived, inverted, in the one file it did not\n * touch: a deployment configured under the older name retargeted every console\n * and besigner help link and left every ASSIST CITATION pointing at\n * `docs.aglyn.com` — our documentation, cited inside their product as theirs.\n * That is the same \"one value, two env names\" split AGL-733 is the record of.\n * One reader means an operator's docs site cannot be honoured on some surfaces\n * and ignored on others.\n */\nexport const DOCS_SITE_ORIGIN = DOCS_BASE_URL\n\n/**\n * The grounding block injected into the system prompt: the retrieved\n * sections, each with its citable URL, wrapped so the model can quote and\n * link them. Kept AFTER the stable system prefix so prompt caching of the\n * static prefix survives per-question variation.\n */\nexport function docsGroundingBlock(scored: readonly ScoredSection[]): string {\n if (!scored.length) return ''\n const parts = scored.map(({ section }) => {\n const url = `${DOCS_SITE_ORIGIN}${section.path}${section.anchor}`\n const heading = section.heading\n ? `${section.title} — ${section.heading}`\n : section.title\n return `<doc url=\"${url}\" title=\"${heading}\">\\n${section.text}\\n</doc>`\n })\n return `\\n\\nRelevant documentation sections (cite these URLs when they answer the question):\\n${parts.join('\\n')}`\n}\n"],"names":["DOCS_SECTION_INDEX","DOCS_BASE_URL","STOP_WORDS","Set","tokenize","text","toLowerCase","match","filter","token","has","scoreSection","section","queryTokens","bodyTokenCounts","titleTokens","headingTokens","score","tf","get","indexed","buildIndex","sections","map","Map","set","title","heading","retrieveDocsSections","question","limit","length","index","entry","scored","sort","a","b","slice","documentFrequency","docsDocumentFrequency","frequency","seen","keys","DOCS_SITE_ORIGIN","docsGroundingBlock","parts","url","path","anchor","join"],"mappings":"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"}
@@ -41,7 +41,10 @@ export type DuplicableResourceKind = (typeof DUPLICABLE_RESOURCE_KINDS)[number];
41
41
  export declare function isDuplicableResourceKind(value: unknown): value is DuplicableResourceKind;
42
42
  /**
43
43
  * The kinds that live under a site and are copied by the core server module;
44
- * the other two belong to the plugins that own their collections.
44
+ * the other two belong to the plugins that own their collections. A copy is
45
+ * made by the platform's own recipe for its kinds, and by the recipe the
46
+ * owning plugin declares beside its collection for the rest (a workflow's,
47
+ * in `plugins.config.json`); a kind here with neither is refused.
45
48
  */
46
49
  export declare const DUPLICABLE_HOST_RESOURCE_KINDS: readonly ["screen", "component", "layout", "template", "form", "emailDesign", "workflow"];
47
50
  export type DuplicableHostResourceKind = (typeof DUPLICABLE_HOST_RESOURCE_KINDS)[number];
@@ -49,7 +49,10 @@ export function isDuplicableResourceKind(value) {
49
49
  }
50
50
  /**
51
51
  * The kinds that live under a site and are copied by the core server module;
52
- * the other two belong to the plugins that own their collections.
52
+ * the other two belong to the plugins that own their collections. A copy is
53
+ * made by the platform's own recipe for its kinds, and by the recipe the
54
+ * owning plugin declares beside its collection for the rest (a workflow's,
55
+ * in `plugins.config.json`); a kind here with neither is refused.
53
56
  */ export const DUPLICABLE_HOST_RESOURCE_KINDS = [
54
57
  'screen',
55
58
  'component',
@@ -64,7 +67,7 @@ export function isDuplicableHostResourceKind(value) {
64
67
  }
65
68
  /** The one-line refusal a client shows when the copy is already being made. */ export const DUPLICATE_BUSY_MESSAGE = 'That copy is still being made';
66
69
  /** What a person calls one of each, in the dialog and the feed. */ export const DUPLICABLE_RESOURCE_NOUNS = {
67
- screen: 'screen',
70
+ screen: 'page',
68
71
  component: 'component',
69
72
  layout: 'layout',
70
73
  template: 'template',
@@ -86,11 +89,11 @@ export function isDuplicableHostResourceKind(value) {
86
89
  component: [
87
90
  'The definition and its properties',
88
91
  'The latest version as a new draft',
89
- 'No instances — screens keep pointing at the original'
92
+ 'No instances — pages keep pointing at the original'
90
93
  ],
91
94
  layout: [
92
95
  'The latest version, with its full element tree and properties',
93
- 'A new draft — no screen uses the copy yet'
96
+ 'A new draft — no page uses the copy yet'
94
97
  ],
95
98
  template: [
96
99
  'The element tree, placeholders and properties',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/duplicate-resource.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\n/**\n * Duplicating a resource whole (AGL-2936): the catalog every surface reads.\n *\n * One list of the kinds that can be copied, what a copy is called, how its\n * name and slug are made unique, and the activity code the copy writes —\n * shared by the row menus and More menus that offer the action, the routes\n * that perform it, the AI tool that exposes it, and the feed that reports\n * it. A kind missing from the catalog cannot be offered anywhere, so the\n * three surfaces cannot disagree about what is duplicable.\n *\n * The activity rows are CODES rather than the prose sentences the rest of\n * the feed stores, for the reason the AI rows are (`ai-activity-actions`):\n * the code names the kind, the feed translates it once, and a reader who\n * filters on \"duplicated\" sees every kind's copies together.\n *\n * A theme is absent on purpose. A site holds exactly one, as fields on its\n * host document rather than as a row in a collection, so there is no list\n * for a second one to appear in: copying a theme means carrying it to\n * another site or saving it into a template, and both of those doors\n * already exist (marketplace install, Save as template).\n */\n\n/** The resource kinds a whole copy can be made of. */\nexport const DUPLICABLE_RESOURCE_KINDS = [\n 'screen',\n 'component',\n 'layout',\n 'template',\n 'form',\n 'emailDesign',\n 'emailTemplate',\n 'campaign',\n 'workflow',\n] as const\n\nexport type DuplicableResourceKind = (typeof DUPLICABLE_RESOURCE_KINDS)[number]\n\nexport function isDuplicableResourceKind(\n value: unknown,\n): value is DuplicableResourceKind {\n return (\n typeof value === 'string' &&\n (DUPLICABLE_RESOURCE_KINDS as readonly string[]).includes(value)\n )\n}\n\n/**\n * The kinds that live under a site and are copied by the core server module;\n * the other two belong to the plugins that own their collections.\n */\nexport const DUPLICABLE_HOST_RESOURCE_KINDS = [\n 'screen',\n 'component',\n 'layout',\n 'template',\n 'form',\n 'emailDesign',\n 'workflow',\n] as const satisfies readonly DuplicableResourceKind[]\n\nexport type DuplicableHostResourceKind =\n (typeof DUPLICABLE_HOST_RESOURCE_KINDS)[number]\n\nexport function isDuplicableHostResourceKind(\n value: unknown,\n): value is DuplicableHostResourceKind {\n return (\n typeof value === 'string' &&\n (DUPLICABLE_HOST_RESOURCE_KINDS as readonly string[]).includes(value)\n )\n}\n\n/** The one-line refusal a client shows when the copy is already being made. */\nexport const DUPLICATE_BUSY_MESSAGE = 'That copy is still being made'\n\n/** What a person calls one of each, in the dialog and the feed. */\nexport const DUPLICABLE_RESOURCE_NOUNS: Record<DuplicableResourceKind, string> = {\n screen: 'screen',\n component: 'component',\n layout: 'layout',\n template: 'template',\n form: 'form',\n emailDesign: 'email design',\n emailTemplate: 'email template',\n campaign: 'campaign',\n workflow: 'workflow',\n}\n\n/**\n * What the copy carries, per kind — the sentence the dialog shows before the\n * copy is made, so nobody is surprised by what came along and what did not.\n */\nexport const DUPLICATE_COPIES: Record<DuplicableResourceKind, readonly string[]> = {\n screen: [\n 'The latest version, with its full element tree and layout values',\n 'Description and SEO fields',\n 'A new draft — the copy is not published and has no address yet',\n ],\n component: [\n 'The definition and its properties',\n 'The latest version as a new draft',\n 'No instances — screens keep pointing at the original',\n ],\n layout: [\n 'The latest version, with its full element tree and properties',\n 'A new draft — no screen uses the copy yet',\n ],\n template: [\n 'The element tree, placeholders and properties',\n 'Description, slug and SEO fields',\n ],\n form: [\n 'The design, fields, validation, consent and routing',\n 'A new form of its own — submissions stay with the original',\n ],\n emailDesign: [\n 'The latest version, with its full element tree',\n 'A new draft — not published',\n ],\n emailTemplate: ['The subject and body, with their merge fields'],\n campaign: [\n 'The subject, message, sender and design',\n 'A new draft — the audience and the send time are cleared',\n ],\n workflow: [\n 'Every step and the return value',\n 'The trigger is cleared, so the copy runs nothing until you arm it',\n ],\n}\n\n/** The action code each copy writes to the activity logs. */\nexport const DUPLICATE_ACTIVITY_ACTIONS: Record<DuplicableResourceKind, string> = {\n screen: 'screen.duplicated',\n component: 'component.duplicated',\n layout: 'layout.duplicated',\n template: 'template.duplicated',\n form: 'form.duplicated',\n emailDesign: 'emailDesign.duplicated',\n emailTemplate: 'emailTemplate.duplicated',\n campaign: 'campaign.duplicated',\n workflow: 'workflow.duplicated',\n}\n\n/** `a screen`, `an email design` — the article the noun takes. */\nconst withArticle = (noun: string): string =>\n `${/^[aeiou]/i.test(noun) ? 'an' : 'a'} ${noun}`\n\n/** What a person reads for each code, in the feed and the actor table. */\nexport const DUPLICATE_ACTIVITY_ACTION_LABELS: Record<string, string> =\n Object.fromEntries(\n DUPLICABLE_RESOURCE_KINDS.map((kind) => [\n DUPLICATE_ACTIVITY_ACTIONS[kind],\n `Duplicated ${withArticle(DUPLICABLE_RESOURCE_NOUNS[kind])}`,\n ]),\n )\n\n/** Whether a stored action is one of the duplicate codes. */\nexport function isDuplicateActivityAction(action: unknown): boolean {\n return typeof action === 'string' && action in DUPLICATE_ACTIVITY_ACTION_LABELS\n}\n\n/** The readable label for a duplicate code; `undefined` for any other action. */\nexport function duplicateActivityActionLabel(action: unknown): string | undefined {\n return isDuplicateActivityAction(action)\n ? DUPLICATE_ACTIVITY_ACTION_LABELS[action as string]\n : undefined\n}\n\n/** The name a copy is offered under before anyone edits it. */\nexport const DUPLICATE_NAME_PREFIX = 'Copy of '\n\n/** The longest name a copy may carry, matching the create drawers' field. */\nexport const DUPLICATE_NAME_MAX = 200\n\n/**\n * The default name for a copy of `sourceName`, before uniqueness.\n *\n * A copy of a copy does not stack prefixes — `Copy of Copy of Home` tells\n * nobody anything — so a name already carrying the prefix keeps it, and the\n * counter {@link uniqueDuplicateName} appends is what tells the two apart.\n */\nexport function duplicateDisplayName(sourceName: string | null | undefined): string {\n const name = String(sourceName ?? '').trim() || 'Untitled'\n const base = name.startsWith(DUPLICATE_NAME_PREFIX)\n ? name\n : `${DUPLICATE_NAME_PREFIX}${name}`\n return base.slice(0, DUPLICATE_NAME_MAX)\n}\n\n/**\n * The first of `requested`, `requested 2`, `requested 3`, … that no sibling\n * already carries, compared case-insensitively so `Home` and `home` are one\n * name. A blank request falls back to the prefix alone, never to an empty\n * name; the counter starts at 2 because the unnumbered name IS the first.\n */\nexport function uniqueDuplicateName(\n requested: string | null | undefined,\n taken: Iterable<string | null | undefined>,\n): string {\n const base =\n String(requested ?? '')\n .trim()\n .slice(0, DUPLICATE_NAME_MAX) || DUPLICATE_NAME_PREFIX.trim()\n const used = new Set<string>()\n for (const name of taken) {\n const key = String(name ?? '').trim().toLowerCase()\n if (key) used.add(key)\n }\n if (!used.has(base.toLowerCase())) return base\n for (let counter = 2; ; counter += 1) {\n const suffix = ` ${counter}`\n const candidate = `${base.slice(0, DUPLICATE_NAME_MAX - suffix.length)}${suffix}`\n if (!used.has(candidate.toLowerCase())) return candidate\n }\n}\n\n/** The suffix a copied slug takes so it never claims the original's address. */\nexport const DUPLICATE_SLUG_SUFFIX = '-copy'\n\n/**\n * `<slug>-copy`, then `<slug>-copy-2`, `<slug>-copy-3`, … — the first the\n * siblings do not carry. A source with no slug yields no slug: the copy is a\n * draft with no address, and inventing one would be a publish decision made\n * by a copy button.\n *\n * A source that is itself a copy (`about-copy`) does not stack suffixes:\n * its base is recovered and numbered instead, so a copy of a copy is\n * `about-copy-2` rather than `about-copy-copy`.\n */\nexport function uniqueDuplicateSlug(\n sourceSlug: string | null | undefined,\n taken: Iterable<string | null | undefined>,\n): string | undefined {\n const slug = String(sourceSlug ?? '').trim()\n if (!slug) return undefined\n const used = new Set<string>()\n for (const value of taken) {\n const key = String(value ?? '').trim().toLowerCase()\n if (key) used.add(key)\n }\n const base = slug.replace(\n new RegExp(`${DUPLICATE_SLUG_SUFFIX}(?:-\\\\d+)?$`),\n '',\n )\n const first = `${base}${DUPLICATE_SLUG_SUFFIX}`\n if (!used.has(first.toLowerCase())) return first\n for (let counter = 2; ; counter += 1) {\n const candidate = `${first}-${counter}`\n if (!used.has(candidate.toLowerCase())) return candidate\n }\n}\n\n/** The note the copy's first version carries: `Duplicated from Home v3`. */\nexport function duplicateVersionNote(\n sourceName: string | null | undefined,\n sourceVersionNumber: number | null | undefined,\n): string {\n const name = String(sourceName ?? '').trim() || 'Untitled'\n const version =\n typeof sourceVersionNumber === 'number' && sourceVersionNumber > 0\n ? ` v${Math.floor(sourceVersionNumber)}`\n : ''\n return `Duplicated from ${name}${version}`\n}\n\n/** The AI runtime tool that opens this door for the planner. */\nexport const DUPLICATE_RESOURCE_TOOL_NAME = 'duplicate_resource'\n"],"names":["DUPLICABLE_RESOURCE_KINDS","isDuplicableResourceKind","value","includes","DUPLICABLE_HOST_RESOURCE_KINDS","isDuplicableHostResourceKind","DUPLICATE_BUSY_MESSAGE","DUPLICABLE_RESOURCE_NOUNS","screen","component","layout","template","form","emailDesign","emailTemplate","campaign","workflow","DUPLICATE_COPIES","DUPLICATE_ACTIVITY_ACTIONS","withArticle","noun","test","DUPLICATE_ACTIVITY_ACTION_LABELS","Object","fromEntries","map","kind","isDuplicateActivityAction","action","duplicateActivityActionLabel","undefined","DUPLICATE_NAME_PREFIX","DUPLICATE_NAME_MAX","duplicateDisplayName","sourceName","name","String","trim","base","startsWith","slice","uniqueDuplicateName","requested","taken","used","Set","key","toLowerCase","add","has","counter","suffix","candidate","length","DUPLICATE_SLUG_SUFFIX","uniqueDuplicateSlug","sourceSlug","slug","replace","RegExp","first","duplicateVersionNote","sourceVersionNumber","version","Math","floor","DUPLICATE_RESOURCE_TOOL_NAME"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/duplicate-resource.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\n/**\n * Duplicating a resource whole (AGL-2936): the catalog every surface reads.\n *\n * One list of the kinds that can be copied, what a copy is called, how its\n * name and slug are made unique, and the activity code the copy writes —\n * shared by the row menus and More menus that offer the action, the routes\n * that perform it, the AI tool that exposes it, and the feed that reports\n * it. A kind missing from the catalog cannot be offered anywhere, so the\n * three surfaces cannot disagree about what is duplicable.\n *\n * The activity rows are CODES rather than the prose sentences the rest of\n * the feed stores, for the reason the AI rows are (`ai-activity-actions`):\n * the code names the kind, the feed translates it once, and a reader who\n * filters on \"duplicated\" sees every kind's copies together.\n *\n * A theme is absent on purpose. A site holds exactly one, as fields on its\n * host document rather than as a row in a collection, so there is no list\n * for a second one to appear in: copying a theme means carrying it to\n * another site or saving it into a template, and both of those doors\n * already exist (marketplace install, Save as template).\n */\n\n/** The resource kinds a whole copy can be made of. */\nexport const DUPLICABLE_RESOURCE_KINDS = [\n 'screen',\n 'component',\n 'layout',\n 'template',\n 'form',\n 'emailDesign',\n 'emailTemplate',\n 'campaign',\n 'workflow',\n] as const\n\nexport type DuplicableResourceKind = (typeof DUPLICABLE_RESOURCE_KINDS)[number]\n\nexport function isDuplicableResourceKind(\n value: unknown,\n): value is DuplicableResourceKind {\n return (\n typeof value === 'string' &&\n (DUPLICABLE_RESOURCE_KINDS as readonly string[]).includes(value)\n )\n}\n\n/**\n * The kinds that live under a site and are copied by the core server module;\n * the other two belong to the plugins that own their collections. A copy is\n * made by the platform's own recipe for its kinds, and by the recipe the\n * owning plugin declares beside its collection for the rest (a workflow's,\n * in `plugins.config.json`); a kind here with neither is refused.\n */\nexport const DUPLICABLE_HOST_RESOURCE_KINDS = [\n 'screen',\n 'component',\n 'layout',\n 'template',\n 'form',\n 'emailDesign',\n 'workflow',\n] as const satisfies readonly DuplicableResourceKind[]\n\nexport type DuplicableHostResourceKind =\n (typeof DUPLICABLE_HOST_RESOURCE_KINDS)[number]\n\nexport function isDuplicableHostResourceKind(\n value: unknown,\n): value is DuplicableHostResourceKind {\n return (\n typeof value === 'string' &&\n (DUPLICABLE_HOST_RESOURCE_KINDS as readonly string[]).includes(value)\n )\n}\n\n/** The one-line refusal a client shows when the copy is already being made. */\nexport const DUPLICATE_BUSY_MESSAGE = 'That copy is still being made'\n\n/** What a person calls one of each, in the dialog and the feed. */\nexport const DUPLICABLE_RESOURCE_NOUNS: Record<DuplicableResourceKind, string> = {\n screen: 'page',\n component: 'component',\n layout: 'layout',\n template: 'template',\n form: 'form',\n emailDesign: 'email design',\n emailTemplate: 'email template',\n campaign: 'campaign',\n workflow: 'workflow',\n}\n\n/**\n * What the copy carries, per kind — the sentence the dialog shows before the\n * copy is made, so nobody is surprised by what came along and what did not.\n */\nexport const DUPLICATE_COPIES: Record<DuplicableResourceKind, readonly string[]> = {\n screen: [\n 'The latest version, with its full element tree and layout values',\n 'Description and SEO fields',\n 'A new draft — the copy is not published and has no address yet',\n ],\n component: [\n 'The definition and its properties',\n 'The latest version as a new draft',\n 'No instances — pages keep pointing at the original',\n ],\n layout: [\n 'The latest version, with its full element tree and properties',\n 'A new draft — no page uses the copy yet',\n ],\n template: [\n 'The element tree, placeholders and properties',\n 'Description, slug and SEO fields',\n ],\n form: [\n 'The design, fields, validation, consent and routing',\n 'A new form of its own — submissions stay with the original',\n ],\n emailDesign: [\n 'The latest version, with its full element tree',\n 'A new draft — not published',\n ],\n emailTemplate: ['The subject and body, with their merge fields'],\n campaign: [\n 'The subject, message, sender and design',\n 'A new draft — the audience and the send time are cleared',\n ],\n workflow: [\n 'Every step and the return value',\n 'The trigger is cleared, so the copy runs nothing until you arm it',\n ],\n}\n\n/** The action code each copy writes to the activity logs. */\nexport const DUPLICATE_ACTIVITY_ACTIONS: Record<DuplicableResourceKind, string> = {\n screen: 'screen.duplicated',\n component: 'component.duplicated',\n layout: 'layout.duplicated',\n template: 'template.duplicated',\n form: 'form.duplicated',\n emailDesign: 'emailDesign.duplicated',\n emailTemplate: 'emailTemplate.duplicated',\n campaign: 'campaign.duplicated',\n workflow: 'workflow.duplicated',\n}\n\n/** `a screen`, `an email design` — the article the noun takes. */\nconst withArticle = (noun: string): string =>\n `${/^[aeiou]/i.test(noun) ? 'an' : 'a'} ${noun}`\n\n/** What a person reads for each code, in the feed and the actor table. */\nexport const DUPLICATE_ACTIVITY_ACTION_LABELS: Record<string, string> =\n Object.fromEntries(\n DUPLICABLE_RESOURCE_KINDS.map((kind) => [\n DUPLICATE_ACTIVITY_ACTIONS[kind],\n `Duplicated ${withArticle(DUPLICABLE_RESOURCE_NOUNS[kind])}`,\n ]),\n )\n\n/** Whether a stored action is one of the duplicate codes. */\nexport function isDuplicateActivityAction(action: unknown): boolean {\n return typeof action === 'string' && action in DUPLICATE_ACTIVITY_ACTION_LABELS\n}\n\n/** The readable label for a duplicate code; `undefined` for any other action. */\nexport function duplicateActivityActionLabel(action: unknown): string | undefined {\n return isDuplicateActivityAction(action)\n ? DUPLICATE_ACTIVITY_ACTION_LABELS[action as string]\n : undefined\n}\n\n/** The name a copy is offered under before anyone edits it. */\nexport const DUPLICATE_NAME_PREFIX = 'Copy of '\n\n/** The longest name a copy may carry, matching the create drawers' field. */\nexport const DUPLICATE_NAME_MAX = 200\n\n/**\n * The default name for a copy of `sourceName`, before uniqueness.\n *\n * A copy of a copy does not stack prefixes — `Copy of Copy of Home` tells\n * nobody anything — so a name already carrying the prefix keeps it, and the\n * counter {@link uniqueDuplicateName} appends is what tells the two apart.\n */\nexport function duplicateDisplayName(sourceName: string | null | undefined): string {\n const name = String(sourceName ?? '').trim() || 'Untitled'\n const base = name.startsWith(DUPLICATE_NAME_PREFIX)\n ? name\n : `${DUPLICATE_NAME_PREFIX}${name}`\n return base.slice(0, DUPLICATE_NAME_MAX)\n}\n\n/**\n * The first of `requested`, `requested 2`, `requested 3`, … that no sibling\n * already carries, compared case-insensitively so `Home` and `home` are one\n * name. A blank request falls back to the prefix alone, never to an empty\n * name; the counter starts at 2 because the unnumbered name IS the first.\n */\nexport function uniqueDuplicateName(\n requested: string | null | undefined,\n taken: Iterable<string | null | undefined>,\n): string {\n const base =\n String(requested ?? '')\n .trim()\n .slice(0, DUPLICATE_NAME_MAX) || DUPLICATE_NAME_PREFIX.trim()\n const used = new Set<string>()\n for (const name of taken) {\n const key = String(name ?? '').trim().toLowerCase()\n if (key) used.add(key)\n }\n if (!used.has(base.toLowerCase())) return base\n for (let counter = 2; ; counter += 1) {\n const suffix = ` ${counter}`\n const candidate = `${base.slice(0, DUPLICATE_NAME_MAX - suffix.length)}${suffix}`\n if (!used.has(candidate.toLowerCase())) return candidate\n }\n}\n\n/** The suffix a copied slug takes so it never claims the original's address. */\nexport const DUPLICATE_SLUG_SUFFIX = '-copy'\n\n/**\n * `<slug>-copy`, then `<slug>-copy-2`, `<slug>-copy-3`, … — the first the\n * siblings do not carry. A source with no slug yields no slug: the copy is a\n * draft with no address, and inventing one would be a publish decision made\n * by a copy button.\n *\n * A source that is itself a copy (`about-copy`) does not stack suffixes:\n * its base is recovered and numbered instead, so a copy of a copy is\n * `about-copy-2` rather than `about-copy-copy`.\n */\nexport function uniqueDuplicateSlug(\n sourceSlug: string | null | undefined,\n taken: Iterable<string | null | undefined>,\n): string | undefined {\n const slug = String(sourceSlug ?? '').trim()\n if (!slug) return undefined\n const used = new Set<string>()\n for (const value of taken) {\n const key = String(value ?? '').trim().toLowerCase()\n if (key) used.add(key)\n }\n const base = slug.replace(\n new RegExp(`${DUPLICATE_SLUG_SUFFIX}(?:-\\\\d+)?$`),\n '',\n )\n const first = `${base}${DUPLICATE_SLUG_SUFFIX}`\n if (!used.has(first.toLowerCase())) return first\n for (let counter = 2; ; counter += 1) {\n const candidate = `${first}-${counter}`\n if (!used.has(candidate.toLowerCase())) return candidate\n }\n}\n\n/** The note the copy's first version carries: `Duplicated from Home v3`. */\nexport function duplicateVersionNote(\n sourceName: string | null | undefined,\n sourceVersionNumber: number | null | undefined,\n): string {\n const name = String(sourceName ?? '').trim() || 'Untitled'\n const version =\n typeof sourceVersionNumber === 'number' && sourceVersionNumber > 0\n ? ` v${Math.floor(sourceVersionNumber)}`\n : ''\n return `Duplicated from ${name}${version}`\n}\n\n/** The AI runtime tool that opens this door for the planner. */\nexport const DUPLICATE_RESOURCE_TOOL_NAME = 'duplicate_resource'\n"],"names":["DUPLICABLE_RESOURCE_KINDS","isDuplicableResourceKind","value","includes","DUPLICABLE_HOST_RESOURCE_KINDS","isDuplicableHostResourceKind","DUPLICATE_BUSY_MESSAGE","DUPLICABLE_RESOURCE_NOUNS","screen","component","layout","template","form","emailDesign","emailTemplate","campaign","workflow","DUPLICATE_COPIES","DUPLICATE_ACTIVITY_ACTIONS","withArticle","noun","test","DUPLICATE_ACTIVITY_ACTION_LABELS","Object","fromEntries","map","kind","isDuplicateActivityAction","action","duplicateActivityActionLabel","undefined","DUPLICATE_NAME_PREFIX","DUPLICATE_NAME_MAX","duplicateDisplayName","sourceName","name","String","trim","base","startsWith","slice","uniqueDuplicateName","requested","taken","used","Set","key","toLowerCase","add","has","counter","suffix","candidate","length","DUPLICATE_SLUG_SUFFIX","uniqueDuplicateSlug","sourceSlug","slug","replace","RegExp","first","duplicateVersionNote","sourceVersionNumber","version","Math","floor","DUPLICATE_RESOURCE_TOOL_NAME"],"mappings":"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"}
@@ -139,7 +139,7 @@ export interface DynamicListDimensions {
139
139
  * attribution record; this says which campaign the merchant FILED the
140
140
  * record under. The two are different facts about different acts and a
141
141
  * single dimension over both would answer neither question — see
142
- * `campaign-attribution.ts` for the other one.
142
+ * `utm-attribution.ts` for the other one.
143
143
  *
144
144
  * ⛔ And membership is not consent. A person selected by this dimension has
145
145
  * opted in to nothing: they are here because a merchant put a form in a