@aglyn/plugins-ai 1.0.0-beta.230 → 1.0.0-beta.231
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.
- package/package.json +17 -17
- package/src/lib/components/ai-assist-provider-on-host.component.d.ts +66 -0
- package/src/lib/components/ai-assist-provider-on-host.component.js +78 -0
- package/src/lib/components/ai-assist-provider-on-host.component.js.map +1 -0
- package/src/lib/components/ai-assist-provider.component.js +9 -10
- package/src/lib/components/ai-assist-provider.component.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.js +3 -1
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-permissions-on-host.component.d.ts +3 -46
- package/src/lib/components/ai-permissions-on-host.component.js +5 -53
- package/src/lib/components/ai-permissions-on-host.component.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +20 -8
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/jobs/ai-build-unit-outcome.js +4 -2
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -1
- package/src/lib/jobs/ai-job-auto-confirm.d.ts +8 -0
- package/src/lib/jobs/ai-job-auto-confirm.js +30 -6
- package/src/lib/jobs/ai-job-auto-confirm.js.map +1 -1
- package/src/lib/jobs/ai-job-build-step.js +11 -0
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-generation.d.ts +8 -0
- package/src/lib/jobs/ai-job-generation.js +13 -2
- package/src/lib/jobs/ai-job-generation.js.map +1 -1
- package/src/lib/jobs/ai-job-insight-step.js +8 -1
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +73 -0
- package/src/lib/jobs/ai-job-layout-language.js +194 -0
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-site-pages.d.ts +13 -2
- package/src/lib/jobs/ai-job-layout-site-pages.js +18 -2
- package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.d.ts +5 -0
- package/src/lib/jobs/ai-job-layout-step.js +105 -5
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +149 -0
- package/src/lib/jobs/ai-job-page-language.js +355 -0
- package/src/lib/jobs/ai-job-page-language.js.map +1 -0
- package/src/lib/jobs/ai-job-page-sections.d.ts +37 -1
- package/src/lib/jobs/ai-job-page-sections.js +93 -11
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.d.ts +4 -4
- package/src/lib/jobs/ai-job-page-step.js +105 -14
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +1 -1
- package/src/lib/jobs/ai-job-plan-step.js +8 -2
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +4 -0
- package/src/lib/jobs/ai-job-site-step.js +20 -3
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.js +2 -2
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +1 -1
- package/src/lib/jobs/ai-jobs.js +17 -8
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-layout-full-height.d.ts +40 -0
- package/src/lib/jobs/ai-layout-full-height.js +82 -0
- package/src/lib/jobs/ai-layout-full-height.js.map +1 -0
- package/src/lib/jobs/ai-layout-site-facts.d.ts +54 -0
- package/src/lib/jobs/ai-layout-site-facts.js +153 -0
- package/src/lib/jobs/ai-layout-site-facts.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.d.ts +145 -0
- package/src/lib/layout-language/ai-layout-compiler.js +1148 -0
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -0
- package/src/lib/layout-language/ai-layout-copy.d.ts +73 -0
- package/src/lib/layout-language/ai-layout-copy.js +137 -0
- package/src/lib/layout-language/ai-layout-copy.js.map +1 -0
- package/src/lib/layout-language/ai-layout-frame.d.ts +52 -0
- package/src/lib/layout-language/ai-layout-frame.js +457 -0
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -0
- package/src/lib/layout-language/ai-layout-gaps.d.ts +63 -0
- package/src/lib/layout-language/ai-layout-gaps.js +345 -0
- package/src/lib/layout-language/ai-layout-gaps.js.map +1 -0
- package/src/lib/layout-language/ai-layout-language.d.ts +161 -0
- package/src/lib/layout-language/ai-layout-language.js +446 -0
- package/src/lib/layout-language/ai-layout-language.js.map +1 -0
- package/src/lib/layout-language/ai-layout-links.d.ts +80 -0
- package/src/lib/layout-language/ai-layout-links.js +109 -0
- package/src/lib/layout-language/ai-layout-links.js.map +1 -0
- package/src/lib/layout-language/ai-layout-store.d.ts +39 -0
- package/src/lib/layout-language/ai-layout-store.js +69 -0
- package/src/lib/layout-language/ai-layout-store.js.map +1 -0
- package/src/lib/layout-language/ai-layout-tree.d.ts +59 -0
- package/src/lib/layout-language/ai-layout-tree.js +84 -0
- package/src/lib/layout-language/ai-layout-tree.js.map +1 -0
- package/src/lib/lazy-widget.d.ts +45 -0
- package/src/lib/lazy-widget.js +53 -0
- package/src/lib/lazy-widget.js.map +1 -0
- package/src/lib/model/ai-build-job.js +2 -1
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +20 -3
- package/src/lib/model/ai-build-progress.js +48 -6
- package/src/lib/model/ai-build-progress.js.map +1 -1
- package/src/lib/model/ai-host-publish-context.d.ts +51 -0
- package/src/lib/model/ai-host-publish-context.js +104 -0
- package/src/lib/model/ai-host-publish-context.js.map +1 -0
- package/src/lib/model/ai-job-activity.d.ts +22 -0
- package/src/lib/model/ai-job-activity.js +22 -1
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-job-failure-copy.d.ts +38 -1
- package/src/lib/model/ai-job-failure-copy.js +56 -1
- package/src/lib/model/ai-job-failure-copy.js.map +1 -1
- package/src/lib/model/ai-job-notice.d.ts +3 -1
- package/src/lib/model/ai-job-notice.js +31 -9
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +19 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-site-build-progress.d.ts +5 -1
- package/src/lib/model/ai-site-build-progress.js +27 -4
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-job.d.ts +8 -0
- package/src/lib/model/ai-site-job.js +9 -0
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-start-seo.d.ts +1 -1
- package/src/lib/model/ai-site-start.d.ts +5 -2
- package/src/lib/model/ai-site-start.js +5 -2
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/plugin.js +79 -47
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +1 -1
- package/src/lib/providers/catalog.js +3 -3
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +82 -0
- package/src/lib/runtime/ai-doctrine-validators.js +436 -4
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +12 -3
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-icon-library.d.ts +257 -0
- package/src/lib/runtime/ai-icon-library.js +254 -0
- package/src/lib/runtime/ai-icon-library.js.map +1 -0
- package/src/lib/runtime/ai-node-tree.d.ts +9 -0
- package/src/lib/runtime/ai-node-tree.js +30 -4
- package/src/lib/runtime/ai-node-tree.js.map +1 -1
- package/src/lib/runtime/ai-palette.d.ts +6 -0
- package/src/lib/runtime/ai-palette.generated.js +70 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/ai-palette.js.map +1 -1
- package/src/lib/tools/ai-workflow-tool.d.ts +6 -2
- package/src/lib/tools/ai-workflow-tool.js +16 -14
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
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 { aiPageLinkSection } from "../runtime/ai-page-links.js";
|
|
17
|
+
/** The words of a label or a name, as they are compared. */ function wordsOf(text) {
|
|
18
|
+
return text.toLowerCase().split(RegExp("[^\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]+", "u")).filter(Boolean);
|
|
19
|
+
}
|
|
20
|
+
function slugOf(slug) {
|
|
21
|
+
return `/${slug.replace(/^\/+|\/+$/g, '')}`.toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
const HOME_WORDS = /\bhome(?:\s?page)?\b/i;
|
|
24
|
+
/** Words that ask a visitor to get in touch, which the site's form answers. */ const CONTACT_WORDS = /\b(?:contact|book|booking|call|quote|estimate|appointment|schedule|reserve|reservation|get in touch|request|visit|enquire|inquire|enquiry|inquiry|message|talk|consult|consultation|order|sign up|join|apply|start)\b/i;
|
|
25
|
+
/** The page a word names: an id, a label or an address. */ function pageNamed(word, targets) {
|
|
26
|
+
var _targets_pages_find, _targets_pages_find1;
|
|
27
|
+
const value = word.trim();
|
|
28
|
+
if (!value) return null;
|
|
29
|
+
const byId = targets.pages.find((page)=>page.id === value);
|
|
30
|
+
if (byId) return byId;
|
|
31
|
+
const lower = value.toLowerCase();
|
|
32
|
+
if (lower.startsWith('/')) return (_targets_pages_find = targets.pages.find((page)=>slugOf(page.slug) === slugOf(lower))) != null ? _targets_pages_find : null;
|
|
33
|
+
const words = wordsOf(value).join(' ');
|
|
34
|
+
return (_targets_pages_find1 = targets.pages.find((page)=>wordsOf(page.label).join(' ') === words)) != null ? _targets_pages_find1 : null;
|
|
35
|
+
}
|
|
36
|
+
/** A destination rule 10 admits, from the page it names, for the words a link shows. */ function pageDestination(page, label, targets) {
|
|
37
|
+
if (!page || page.id === targets.pageId) return null;
|
|
38
|
+
if (targets.homeIds.includes(page.id) && !HOME_WORDS.test(label) && !isHomeSlug(page.slug)) return null;
|
|
39
|
+
if (isHomeSlug(page.slug) && !HOME_WORDS.test(label)) return null;
|
|
40
|
+
return {
|
|
41
|
+
kind: 'page',
|
|
42
|
+
screenId: page.id
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function isHomeSlug(slug) {
|
|
46
|
+
return slugOf(slug) === '/';
|
|
47
|
+
}
|
|
48
|
+
/** Where the site's form is: a section of this page, else the page that places it. */ function formDestination(scope, targets) {
|
|
49
|
+
if (scope.formSection !== null && scope.formSection !== scope.from) return {
|
|
50
|
+
kind: 'section',
|
|
51
|
+
index: scope.formSection
|
|
52
|
+
};
|
|
53
|
+
if (targets.formPageId && targets.formPageId !== targets.pageId) {
|
|
54
|
+
return {
|
|
55
|
+
kind: 'page',
|
|
56
|
+
screenId: targets.formPageId
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Where a link goes: the destination its `to` names, read the language's
|
|
63
|
+
* way; failing that, for words that ask a visitor to get in touch, the site's
|
|
64
|
+
* form; failing that, a page whose name the words say. `null` is a link with
|
|
65
|
+
* nowhere to go, which is left out.
|
|
66
|
+
*/ export function aiLayoutResolveLink(to, label, scope, targets) {
|
|
67
|
+
const named = to ? resolveNamed(to.trim(), label, scope, targets) : null;
|
|
68
|
+
if (named) return named;
|
|
69
|
+
if (CONTACT_WORDS.test(label)) {
|
|
70
|
+
const form = formDestination(scope, targets);
|
|
71
|
+
if (form) return form;
|
|
72
|
+
const contact = targets.pages.find((page)=>page.id !== targets.pageId && !isHomeSlug(page.slug) && CONTACT_WORDS.test(page.label));
|
|
73
|
+
if (contact) return {
|
|
74
|
+
kind: 'page',
|
|
75
|
+
screenId: contact.id
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const labelWords = new Set(wordsOf(label));
|
|
79
|
+
const said = targets.pages.filter((page)=>page.id !== targets.pageId && !isHomeSlug(page.slug) && wordsOf(page.label).length > 0 && wordsOf(page.label).every((word)=>labelWords.has(word)));
|
|
80
|
+
return said.length === 1 ? {
|
|
81
|
+
kind: 'page',
|
|
82
|
+
screenId: said[0].id
|
|
83
|
+
} : null;
|
|
84
|
+
}
|
|
85
|
+
function resolveNamed(to, label, scope, targets) {
|
|
86
|
+
const lower = to.toLowerCase();
|
|
87
|
+
if (lower === 'form' || lower.startsWith('form:') || targets.forms.some((form)=>form.id === to)) {
|
|
88
|
+
return formDestination(scope, targets);
|
|
89
|
+
}
|
|
90
|
+
if (lower.startsWith('https://')) {
|
|
91
|
+
return targets.facts.includes(to) ? {
|
|
92
|
+
kind: 'href',
|
|
93
|
+
href: to
|
|
94
|
+
} : null;
|
|
95
|
+
}
|
|
96
|
+
const section = lower.startsWith('#') ? to.slice(1) : lower.startsWith('section:') ? to.slice(8) : null;
|
|
97
|
+
if (section !== null) {
|
|
98
|
+
const number = Number(section.trim());
|
|
99
|
+
const index = Number.isInteger(number) && number >= 1 && number <= scope.sections.length ? number - 1 : aiPageLinkSection(section, scope.sections);
|
|
100
|
+
return index !== null && index !== scope.from ? {
|
|
101
|
+
kind: 'section',
|
|
102
|
+
index
|
|
103
|
+
} : null;
|
|
104
|
+
}
|
|
105
|
+
const page = pageNamed(lower.startsWith('page:') ? to.slice(5) : to, targets);
|
|
106
|
+
return pageDestination(page, label, targets);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=ai-layout-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/layout-language/ai-layout-links.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 { aiPageLinkSection } from '../runtime/ai-page-links'\n\n/**\n * Where a link the layout language names goes (AGL-3660), resolved by code to\n * a destination rule 10 admits: a page of this site by its id, a section of\n * this page by the platform's Scroll to element interaction, or an `https:`\n * address the brief itself gave. A destination that resolves to nothing, or\n * to the home page under words that do not say home, is no destination, and\n * the compiler leaves the button out rather than shipping a dead control.\n */\n\n/** A page of the site a link may go to: built, or minted on a guided start's plan. */\nexport interface AiLayoutPage {\n id: string\n label: string\n slug: string\n}\n\n/** Everything a page's links resolve against. */\nexport interface AiLayoutTargets {\n /** The page being built, which no link of its own goes to. */\n pageId?: string | null\n /** The site's pages a link may go to. */\n pages: readonly AiLayoutPage[]\n /** The site's home pages, which only words that say home link (rule 10). */\n homeIds: readonly string[]\n /** The saved forms a page may place. */\n forms: readonly { id: string; name: string }[]\n /** The page that places the site's form, where that is another page. */\n formPageId?: string | null\n /** The reusable components a page may place, with the props each fills. */\n components: readonly {\n id: string\n name: string\n props: Record<string, string>\n }[]\n /** Every word the job was given: the brief, the site's answers, its profile. */\n facts: string\n}\n\n/** Where a link resolved to. */\nexport type AiLayoutDestination =\n | { kind: 'page'; screenId: string }\n | { kind: 'section'; index: number }\n | { kind: 'href'; href: string }\n\n/** The words of a label or a name, as they are compared. */\nfunction wordsOf(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^\\p{L}\\p{N}]+/u)\n .filter(Boolean)\n}\n\nfunction slugOf(slug: string): string {\n return `/${slug.replace(/^\\/+|\\/+$/g, '')}`.toLowerCase()\n}\n\nconst HOME_WORDS = /\\bhome(?:\\s?page)?\\b/i\n\n/** Words that ask a visitor to get in touch, which the site's form answers. */\nconst CONTACT_WORDS =\n /\\b(?:contact|book|booking|call|quote|estimate|appointment|schedule|reserve|reservation|get in touch|request|visit|enquire|inquire|enquiry|inquiry|message|talk|consult|consultation|order|sign up|join|apply|start)\\b/i\n\nexport interface AiLayoutLinkScope {\n /** The page's section names in plan order. */\n sections: readonly string[]\n /** The section the link sits in, which it does not scroll to. */\n from: number\n /** The section of this page that places the site's form, if one does. */\n formSection: number | null\n}\n\n/** The page a word names: an id, a label or an address. */\nfunction pageNamed(\n word: string,\n targets: AiLayoutTargets,\n): AiLayoutPage | null {\n const value = word.trim()\n if (!value) return null\n const byId = targets.pages.find((page) => page.id === value)\n if (byId) return byId\n const lower = value.toLowerCase()\n if (lower.startsWith('/'))\n return (\n targets.pages.find((page) => slugOf(page.slug) === slugOf(lower)) ?? null\n )\n const words = wordsOf(value).join(' ')\n return (\n targets.pages.find((page) => wordsOf(page.label).join(' ') === words) ??\n null\n )\n}\n\n/** A destination rule 10 admits, from the page it names, for the words a link shows. */\nfunction pageDestination(\n page: AiLayoutPage | null,\n label: string,\n targets: AiLayoutTargets,\n): AiLayoutDestination | null {\n if (!page || page.id === targets.pageId) return null\n if (\n targets.homeIds.includes(page.id) &&\n !HOME_WORDS.test(label) &&\n !isHomeSlug(page.slug)\n )\n return null\n if (isHomeSlug(page.slug) && !HOME_WORDS.test(label)) return null\n return { kind: 'page', screenId: page.id }\n}\n\nfunction isHomeSlug(slug: string): boolean {\n return slugOf(slug) === '/'\n}\n\n/** Where the site's form is: a section of this page, else the page that places it. */\nfunction formDestination(\n scope: AiLayoutLinkScope,\n targets: AiLayoutTargets,\n): AiLayoutDestination | null {\n if (scope.formSection !== null && scope.formSection !== scope.from)\n return { kind: 'section', index: scope.formSection }\n if (targets.formPageId && targets.formPageId !== targets.pageId) {\n return { kind: 'page', screenId: targets.formPageId }\n }\n return null\n}\n\n/**\n * Where a link goes: the destination its `to` names, read the language's\n * way; failing that, for words that ask a visitor to get in touch, the site's\n * form; failing that, a page whose name the words say. `null` is a link with\n * nowhere to go, which is left out.\n */\nexport function aiLayoutResolveLink(\n to: string | undefined,\n label: string,\n scope: AiLayoutLinkScope,\n targets: AiLayoutTargets,\n): AiLayoutDestination | null {\n const named = to ? resolveNamed(to.trim(), label, scope, targets) : null\n if (named) return named\n if (CONTACT_WORDS.test(label)) {\n const form = formDestination(scope, targets)\n if (form) return form\n const contact = targets.pages.find(\n (page) =>\n page.id !== targets.pageId &&\n !isHomeSlug(page.slug) &&\n CONTACT_WORDS.test(page.label),\n )\n if (contact) return { kind: 'page', screenId: contact.id }\n }\n const labelWords = new Set(wordsOf(label))\n const said = targets.pages.filter(\n (page) =>\n page.id !== targets.pageId &&\n !isHomeSlug(page.slug) &&\n wordsOf(page.label).length > 0 &&\n wordsOf(page.label).every((word) => labelWords.has(word)),\n )\n return said.length === 1 ? { kind: 'page', screenId: said[0].id } : null\n}\n\nfunction resolveNamed(\n to: string,\n label: string,\n scope: AiLayoutLinkScope,\n targets: AiLayoutTargets,\n): AiLayoutDestination | null {\n const lower = to.toLowerCase()\n if (\n lower === 'form' ||\n lower.startsWith('form:') ||\n targets.forms.some((form) => form.id === to)\n ) {\n return formDestination(scope, targets)\n }\n if (lower.startsWith('https://')) {\n return targets.facts.includes(to) ? { kind: 'href', href: to } : null\n }\n const section = lower.startsWith('#')\n ? to.slice(1)\n : lower.startsWith('section:')\n ? to.slice(8)\n : null\n if (section !== null) {\n const number = Number(section.trim())\n const index =\n Number.isInteger(number) && number >= 1 && number <= scope.sections.length\n ? number - 1\n : aiPageLinkSection(section, scope.sections)\n return index !== null && index !== scope.from\n ? { kind: 'section', index }\n : null\n }\n const page = pageNamed(lower.startsWith('page:') ? to.slice(5) : to, targets)\n return pageDestination(page, label, targets)\n}\n"],"names":["aiPageLinkSection","wordsOf","text","toLowerCase","split","filter","Boolean","slugOf","slug","replace","HOME_WORDS","CONTACT_WORDS","pageNamed","word","targets","value","trim","byId","pages","find","page","id","lower","startsWith","words","join","label","pageDestination","pageId","homeIds","includes","test","isHomeSlug","kind","screenId","formDestination","scope","formSection","from","index","formPageId","aiLayoutResolveLink","to","named","resolveNamed","form","contact","labelWords","Set","said","length","every","has","forms","some","facts","href","section","slice","number","Number","isInteger","sections"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
*/
|
|
17
|
+
import type { NodesMap } from '@aglyn/aglyn/types/nodes';
|
|
18
|
+
import { type AiNodeTreeContext } from '../runtime/ai-node-tree';
|
|
19
|
+
import type { AiSurface } from '../runtime/ai-palette';
|
|
20
|
+
import type { AiLayoutRawTree } from './ai-layout-tree';
|
|
21
|
+
/**
|
|
22
|
+
* A compiled tree as a document stores it (AGL-3660): read by the same
|
|
23
|
+
* palette validator every generated tree passes, as a code-built tree, so
|
|
24
|
+
* what is stored is exactly what any other generated document would store.
|
|
25
|
+
* The validator mints fresh ids; the ids a caller names (a page's section
|
|
26
|
+
* roots, which its plan minted) keep their own, and the interactions code
|
|
27
|
+
* wrote — which the validator strips from anything it stores — are carried
|
|
28
|
+
* over onto the stored nodes.
|
|
29
|
+
*/
|
|
30
|
+
export type AiLayoutStored = {
|
|
31
|
+
ok: true;
|
|
32
|
+
nodes: NodesMap;
|
|
33
|
+
rootId: string;
|
|
34
|
+
repairs: string[];
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function aiLayoutStoredTree(compiled: AiLayoutRawTree, surface: AiSurface, context: AiNodeTreeContext, keepIds?: readonly string[]): AiLayoutStored;
|
|
@@ -0,0 +1,69 @@
|
|
|
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 { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
18
|
+
import { validateAiNodeTree } from "../runtime/ai-node-tree.js";
|
|
19
|
+
export function aiLayoutStoredTree(compiled, surface, context, keepIds = []) {
|
|
20
|
+
// The interactions are code's, carried over below; the validator is shown the rest.
|
|
21
|
+
const bare = {
|
|
22
|
+
rootId: compiled.rootId,
|
|
23
|
+
nodes: Object.fromEntries(Object.entries(compiled.nodes).map((_0)=>{
|
|
24
|
+
let [id, _ref] = _0, { interactions: _interactions } = _ref, node = _object_without_properties_loose(_ref, [
|
|
25
|
+
"interactions"
|
|
26
|
+
]);
|
|
27
|
+
return [
|
|
28
|
+
id,
|
|
29
|
+
node
|
|
30
|
+
];
|
|
31
|
+
}))
|
|
32
|
+
};
|
|
33
|
+
const validated = validateAiNodeTree(bare, surface, _extends({}, context, {
|
|
34
|
+
codeBuilt: true
|
|
35
|
+
}));
|
|
36
|
+
if (validated.ok === false) return {
|
|
37
|
+
ok: false,
|
|
38
|
+
error: validated.error
|
|
39
|
+
};
|
|
40
|
+
const keep = new Set(keepIds);
|
|
41
|
+
// Minted → the id it is stored under: its own, or the one the caller keeps.
|
|
42
|
+
const storedId = (minted)=>{
|
|
43
|
+
const source = validated.sourceIds[minted];
|
|
44
|
+
return source && keep.has(source) ? source : minted;
|
|
45
|
+
};
|
|
46
|
+
const nodes = {};
|
|
47
|
+
for (const [minted, raw] of Object.entries(validated.nodes)){
|
|
48
|
+
var _validated_sourceIds_minted;
|
|
49
|
+
var _source_interactions;
|
|
50
|
+
const id = storedId(minted);
|
|
51
|
+
const source = compiled.nodes[(_validated_sourceIds_minted = validated.sourceIds[minted]) != null ? _validated_sourceIds_minted : ''];
|
|
52
|
+
nodes[id] = _extends({}, raw, {
|
|
53
|
+
$id: id,
|
|
54
|
+
parentId: raw.parentId === null ? null : storedId(raw.parentId)
|
|
55
|
+
}, Array.isArray(raw.nodes) ? {
|
|
56
|
+
nodes: raw.nodes.map(storedId)
|
|
57
|
+
} : {}, (source == null ? void 0 : (_source_interactions = source.interactions) == null ? void 0 : _source_interactions.length) ? {
|
|
58
|
+
interactions: source.interactions
|
|
59
|
+
} : {});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
nodes: nodes,
|
|
64
|
+
rootId: storedId(validated.rootId),
|
|
65
|
+
repairs: validated.repairs
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=ai-layout-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/layout-language/ai-layout-store.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 { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport {\n validateAiNodeTree,\n type AiNodeTreeContext,\n} from '../runtime/ai-node-tree'\nimport type { AiSurface } from '../runtime/ai-palette'\nimport type { AiLayoutRawTree } from './ai-layout-tree'\n\n/**\n * A compiled tree as a document stores it (AGL-3660): read by the same\n * palette validator every generated tree passes, as a code-built tree, so\n * what is stored is exactly what any other generated document would store.\n * The validator mints fresh ids; the ids a caller names (a page's section\n * roots, which its plan minted) keep their own, and the interactions code\n * wrote — which the validator strips from anything it stores — are carried\n * over onto the stored nodes.\n */\n\nexport type AiLayoutStored =\n | { ok: true; nodes: NodesMap; rootId: string; repairs: string[] }\n | { ok: false; error: string }\n\ntype StoredNode = Record<string, unknown> & {\n $id: string\n parentId: string | null\n nodes?: string[]\n}\n\nexport function aiLayoutStoredTree(\n compiled: AiLayoutRawTree,\n surface: AiSurface,\n context: AiNodeTreeContext,\n keepIds: readonly string[] = [],\n): AiLayoutStored {\n // The interactions are code's, carried over below; the validator is shown the rest.\n const bare = {\n rootId: compiled.rootId,\n nodes: Object.fromEntries(\n Object.entries(compiled.nodes).map(\n ([id, { interactions: _interactions, ...node }]) => [id, node],\n ),\n ),\n }\n const validated = validateAiNodeTree(bare, surface, {\n ...context,\n codeBuilt: true,\n })\n if (validated.ok === false) return { ok: false, error: validated.error }\n const keep = new Set(keepIds)\n // Minted → the id it is stored under: its own, or the one the caller keeps.\n const storedId = (minted: string): string => {\n const source = validated.sourceIds[minted]\n return source && keep.has(source) ? source : minted\n }\n const nodes: Record<string, StoredNode> = {}\n for (const [minted, raw] of Object.entries(\n validated.nodes as unknown as Record<string, StoredNode>,\n )) {\n const id = storedId(minted)\n const source = compiled.nodes[validated.sourceIds[minted] ?? '']\n nodes[id] = {\n ...raw,\n $id: id,\n parentId: raw.parentId === null ? null : storedId(raw.parentId),\n ...(Array.isArray(raw.nodes) ? { nodes: raw.nodes.map(storedId) } : {}),\n ...(source?.interactions?.length\n ? { interactions: source.interactions }\n : {}),\n }\n }\n return {\n ok: true,\n nodes: nodes as unknown as NodesMap,\n rootId: storedId(validated.rootId),\n repairs: validated.repairs,\n }\n}\n"],"names":["validateAiNodeTree","aiLayoutStoredTree","compiled","surface","context","keepIds","bare","rootId","nodes","Object","fromEntries","entries","map","id","interactions","_interactions","node","validated","codeBuilt","ok","error","keep","Set","storedId","minted","source","sourceIds","has","raw","$id","parentId","Array","isArray","length","repairs"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC;;AAGD,SACEA,kBAAkB,QAEb,6BAAyB;AAwBhC,OAAO,SAASC,mBACdC,QAAyB,EACzBC,OAAkB,EAClBC,OAA0B,EAC1BC,UAA6B,EAAE;IAE/B,oFAAoF;IACpF,MAAMC,OAAO;QACXC,QAAQL,SAASK,MAAM;QACvBC,OAAOC,OAAOC,WAAW,CACvBD,OAAOE,OAAO,CAACT,SAASM,KAAK,EAAEI,GAAG,CAChC;gBAAC,CAACC,SAA6C,OAAzC,EAAEC,cAAcC,aAAa,EAAW,SAANC;;;mBAAY;gBAACH;gBAAIG;aAAK;;IAGpE;IACA,MAAMC,YAAYjB,mBAAmBM,MAAMH,SAAS,aAC/CC;QACHc,WAAW;;IAEb,IAAID,UAAUE,EAAE,KAAK,OAAO,OAAO;QAAEA,IAAI;QAAOC,OAAOH,UAAUG,KAAK;IAAC;IACvE,MAAMC,OAAO,IAAIC,IAAIjB;IACrB,4EAA4E;IAC5E,MAAMkB,WAAW,CAACC;QAChB,MAAMC,SAASR,UAAUS,SAAS,CAACF,OAAO;QAC1C,OAAOC,UAAUJ,KAAKM,GAAG,CAACF,UAAUA,SAASD;IAC/C;IACA,MAAMhB,QAAoC,CAAC;IAC3C,KAAK,MAAM,CAACgB,QAAQI,IAAI,IAAInB,OAAOE,OAAO,CACxCM,UAAUT,KAAK,EACd;YAE6BS;YAMxBQ;QAPN,MAAMZ,KAAKU,SAASC;QACpB,MAAMC,SAASvB,SAASM,KAAK,EAACS,8BAAAA,UAAUS,SAAS,CAACF,OAAO,YAA3BP,8BAA+B,GAAG;QAChET,KAAK,CAACK,GAAG,GAAG,aACPe;YACHC,KAAKhB;YACLiB,UAAUF,IAAIE,QAAQ,KAAK,OAAO,OAAOP,SAASK,IAAIE,QAAQ;WAC1DC,MAAMC,OAAO,CAACJ,IAAIpB,KAAK,IAAI;YAAEA,OAAOoB,IAAIpB,KAAK,CAACI,GAAG,CAACW;QAAU,IAAI,CAAC,GACjEE,CAAAA,2BAAAA,uBAAAA,OAAQX,YAAY,qBAApBW,qBAAsBQ,MAAM,IAC5B;YAAEnB,cAAcW,OAAOX,YAAY;QAAC,IACpC,CAAC;IAET;IACA,OAAO;QACLK,IAAI;QACJX,OAAOA;QACPD,QAAQgB,SAASN,UAAUV,MAAM;QACjC2B,SAASjB,UAAUiB,OAAO;IAC5B;AACF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The node map the layout language compiler writes (AGL-3660), in the shape a
|
|
19
|
+
* model's answer arrives in — `{ rootId, nodes: { id: { componentId, props,
|
|
20
|
+
* sx, nodes } } }` — so the palette validator and the doctrine read it exactly
|
|
21
|
+
* as they read any other tree, and nothing downstream knows code wrote it.
|
|
22
|
+
*/
|
|
23
|
+
export interface AiLayoutRawNode {
|
|
24
|
+
componentId: string;
|
|
25
|
+
props?: Record<string, unknown>;
|
|
26
|
+
sx?: Record<string, unknown>;
|
|
27
|
+
nodes?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* The platform's interactions, written by code: a link to a section of its
|
|
30
|
+
* page scrolls there (AGL-3097). The palette validator strips every
|
|
31
|
+
* interaction from what it stores, so the page step carries these over
|
|
32
|
+
* onto the stored nodes after it.
|
|
33
|
+
*/
|
|
34
|
+
interactions?: unknown[];
|
|
35
|
+
}
|
|
36
|
+
export interface AiLayoutRawTree {
|
|
37
|
+
rootId: string;
|
|
38
|
+
nodes: Record<string, AiLayoutRawNode>;
|
|
39
|
+
}
|
|
40
|
+
/** Elements that only frame what they hold, and so mean nothing empty. */
|
|
41
|
+
export declare const AI_LAYOUT_FRAMES: ReadonlySet<string>;
|
|
42
|
+
/** A node map built in document order, with ids that read in a review: `ll3-heading`. */
|
|
43
|
+
export declare class AiLayoutTreeBuilder {
|
|
44
|
+
private readonly prefix;
|
|
45
|
+
readonly nodes: Record<string, AiLayoutRawNode>;
|
|
46
|
+
private count;
|
|
47
|
+
constructor(prefix?: string);
|
|
48
|
+
/** A node, with only the props, styles and children it was given; returns its id. */
|
|
49
|
+
add(componentId: string, props?: Record<string, unknown> | null, sx?: Record<string, unknown> | null, children?: readonly (string | null | undefined)[] | null, role?: string, fixedId?: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Takes out every frame left holding nothing — a card whose words were all
|
|
52
|
+
* filler, the cell that held it — from the leaves up, so no element meant
|
|
53
|
+
* to hold content is stored empty (rule 16). `keep` names the ones that
|
|
54
|
+
* stay whatever they hold.
|
|
55
|
+
*/
|
|
56
|
+
prune(rootId: string, keep?: ReadonlySet<string>): void;
|
|
57
|
+
/** The tree rooted at `rootId`. */
|
|
58
|
+
tree(rootId: string): AiLayoutRawTree;
|
|
59
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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
|
+
*/ /**
|
|
17
|
+
* The node map the layout language compiler writes (AGL-3660), in the shape a
|
|
18
|
+
* model's answer arrives in — `{ rootId, nodes: { id: { componentId, props,
|
|
19
|
+
* sx, nodes } } }` — so the palette validator and the doctrine read it exactly
|
|
20
|
+
* as they read any other tree, and nothing downstream knows code wrote it.
|
|
21
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
22
|
+
/** Elements that only frame what they hold, and so mean nothing empty. */ export const AI_LAYOUT_FRAMES = new Set([
|
|
23
|
+
'muiStack',
|
|
24
|
+
'muiBox',
|
|
25
|
+
'muiGrid',
|
|
26
|
+
'muiCard',
|
|
27
|
+
'muiCardContent',
|
|
28
|
+
'muiContainer',
|
|
29
|
+
'muiList',
|
|
30
|
+
'muiListItem',
|
|
31
|
+
'muiAccordion',
|
|
32
|
+
'muiAccordionDetails',
|
|
33
|
+
'muiDrawer',
|
|
34
|
+
'section'
|
|
35
|
+
]);
|
|
36
|
+
/** A node map built in document order, with ids that read in a review: `ll3-heading`. */ export class AiLayoutTreeBuilder {
|
|
37
|
+
/** A node, with only the props, styles and children it was given; returns its id. */ add(componentId, props, sx, children, role = componentId, fixedId) {
|
|
38
|
+
this.count += 1;
|
|
39
|
+
const id = fixedId != null ? fixedId : `${this.prefix}${this.count}-${role.replace(/[^A-Za-z0-9]/g, '').slice(0, 16)}`;
|
|
40
|
+
const node = {
|
|
41
|
+
componentId
|
|
42
|
+
};
|
|
43
|
+
const kept = props ? Object.fromEntries(Object.entries(props).filter(([, value])=>value !== undefined)) : {};
|
|
44
|
+
if (Object.keys(kept).length) node.props = kept;
|
|
45
|
+
if (sx && Object.keys(sx).length) node.sx = _extends({}, sx);
|
|
46
|
+
const list = (children != null ? children : []).filter((child)=>typeof child === 'string');
|
|
47
|
+
if (list.length) node.nodes = list;
|
|
48
|
+
this.nodes[id] = node;
|
|
49
|
+
return id;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Takes out every frame left holding nothing — a card whose words were all
|
|
53
|
+
* filler, the cell that held it — from the leaves up, so no element meant
|
|
54
|
+
* to hold content is stored empty (rule 16). `keep` names the ones that
|
|
55
|
+
* stay whatever they hold.
|
|
56
|
+
*/ prune(rootId, keep = new Set()) {
|
|
57
|
+
const visit = (id)=>{
|
|
58
|
+
var _node_nodes;
|
|
59
|
+
const node = this.nodes[id];
|
|
60
|
+
if (!node) return false;
|
|
61
|
+
if (node.nodes) {
|
|
62
|
+
node.nodes = node.nodes.filter(visit);
|
|
63
|
+
if (!node.nodes.length) delete node.nodes;
|
|
64
|
+
}
|
|
65
|
+
if (id === rootId || keep.has(id) || ((_node_nodes = node.nodes) == null ? void 0 : _node_nodes.length) || !AI_LAYOUT_FRAMES.has(node.componentId)) return true;
|
|
66
|
+
delete this.nodes[id];
|
|
67
|
+
return false;
|
|
68
|
+
};
|
|
69
|
+
visit(rootId);
|
|
70
|
+
}
|
|
71
|
+
/** The tree rooted at `rootId`. */ tree(rootId) {
|
|
72
|
+
return {
|
|
73
|
+
rootId,
|
|
74
|
+
nodes: this.nodes
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
constructor(prefix = 'll'){
|
|
78
|
+
this.prefix = prefix;
|
|
79
|
+
this.nodes = {};
|
|
80
|
+
this.count = 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=ai-layout-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/layout-language/ai-layout-tree.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 * The node map the layout language compiler writes (AGL-3660), in the shape a\n * model's answer arrives in — `{ rootId, nodes: { id: { componentId, props,\n * sx, nodes } } }` — so the palette validator and the doctrine read it exactly\n * as they read any other tree, and nothing downstream knows code wrote it.\n */\n\nexport interface AiLayoutRawNode {\n componentId: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: string[]\n /**\n * The platform's interactions, written by code: a link to a section of its\n * page scrolls there (AGL-3097). The palette validator strips every\n * interaction from what it stores, so the page step carries these over\n * onto the stored nodes after it.\n */\n interactions?: unknown[]\n}\n\nexport interface AiLayoutRawTree {\n rootId: string\n nodes: Record<string, AiLayoutRawNode>\n}\n\n/** Elements that only frame what they hold, and so mean nothing empty. */\nexport const AI_LAYOUT_FRAMES: ReadonlySet<string> = new Set([\n 'muiStack',\n 'muiBox',\n 'muiGrid',\n 'muiCard',\n 'muiCardContent',\n 'muiContainer',\n 'muiList',\n 'muiListItem',\n 'muiAccordion',\n 'muiAccordionDetails',\n 'muiDrawer',\n 'section',\n])\n\n/** A node map built in document order, with ids that read in a review: `ll3-heading`. */\nexport class AiLayoutTreeBuilder {\n readonly nodes: Record<string, AiLayoutRawNode> = {}\n private count = 0\n\n constructor(private readonly prefix = 'll') {}\n\n /** A node, with only the props, styles and children it was given; returns its id. */\n add(\n componentId: string,\n props?: Record<string, unknown> | null,\n sx?: Record<string, unknown> | null,\n children?: readonly (string | null | undefined)[] | null,\n role = componentId,\n fixedId?: string,\n ): string {\n this.count += 1\n const id =\n fixedId ??\n `${this.prefix}${this.count}-${role.replace(/[^A-Za-z0-9]/g, '').slice(0, 16)}`\n const node: AiLayoutRawNode = { componentId }\n const kept = props\n ? Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n )\n : {}\n if (Object.keys(kept).length) node.props = kept\n if (sx && Object.keys(sx).length) node.sx = { ...sx }\n const list = (children ?? []).filter(\n (child): child is string => typeof child === 'string',\n )\n if (list.length) node.nodes = list\n this.nodes[id] = node\n return id\n }\n\n /**\n * Takes out every frame left holding nothing — a card whose words were all\n * filler, the cell that held it — from the leaves up, so no element meant\n * to hold content is stored empty (rule 16). `keep` names the ones that\n * stay whatever they hold.\n */\n prune(rootId: string, keep: ReadonlySet<string> = new Set()): void {\n const visit = (id: string): boolean => {\n const node = this.nodes[id]\n if (!node) return false\n if (node.nodes) {\n node.nodes = node.nodes.filter(visit)\n if (!node.nodes.length) delete node.nodes\n }\n if (\n id === rootId ||\n keep.has(id) ||\n node.nodes?.length ||\n !AI_LAYOUT_FRAMES.has(node.componentId)\n )\n return true\n delete this.nodes[id]\n return false\n }\n visit(rootId)\n }\n\n /** The tree rooted at `rootId`. */\n tree(rootId: string): AiLayoutRawTree {\n return { rootId, nodes: this.nodes }\n }\n}\n"],"names":["AI_LAYOUT_FRAMES","Set","AiLayoutTreeBuilder","add","componentId","props","sx","children","role","fixedId","count","id","prefix","replace","slice","node","kept","Object","fromEntries","entries","filter","value","undefined","keys","length","list","child","nodes","prune","rootId","keep","visit","has","tree"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;CAKC;AAqBD,wEAAwE,GACxE,OAAO,MAAMA,mBAAwC,IAAIC,IAAI;IAC3D;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,EAAC;AAEF,uFAAuF,GACvF,OAAO,MAAMC;IAMX,mFAAmF,GACnFC,IACEC,WAAmB,EACnBC,KAAsC,EACtCC,EAAmC,EACnCC,QAAwD,EACxDC,OAAOJ,WAAW,EAClBK,OAAgB,EACR;QACR,IAAI,CAACC,KAAK,IAAI;QACd,MAAMC,KACJF,kBAAAA,UACA,GAAG,IAAI,CAACG,MAAM,GAAG,IAAI,CAACF,KAAK,CAAC,CAAC,EAAEF,KAAKK,OAAO,CAAC,iBAAiB,IAAIC,KAAK,CAAC,GAAG,KAAK;QACjF,MAAMC,OAAwB;YAAEX;QAAY;QAC5C,MAAMY,OAAOX,QACTY,OAAOC,WAAW,CAChBD,OAAOE,OAAO,CAACd,OAAOe,MAAM,CAAC,CAAC,GAAGC,MAAM,GAAKA,UAAUC,cAExD,CAAC;QACL,IAAIL,OAAOM,IAAI,CAACP,MAAMQ,MAAM,EAAET,KAAKV,KAAK,GAAGW;QAC3C,IAAIV,MAAMW,OAAOM,IAAI,CAACjB,IAAIkB,MAAM,EAAET,KAAKT,EAAE,GAAG,aAAKA;QACjD,MAAMmB,OAAO,CAAClB,mBAAAA,WAAY,EAAE,EAAEa,MAAM,CAClC,CAACM,QAA2B,OAAOA,UAAU;QAE/C,IAAID,KAAKD,MAAM,EAAET,KAAKY,KAAK,GAAGF;QAC9B,IAAI,CAACE,KAAK,CAAChB,GAAG,GAAGI;QACjB,OAAOJ;IACT;IAEA;;;;;GAKC,GACDiB,MAAMC,MAAc,EAAEC,OAA4B,IAAI7B,KAAK,EAAQ;QACjE,MAAM8B,QAAQ,CAACpB;gBAUXI;YATF,MAAMA,OAAO,IAAI,CAACY,KAAK,CAAChB,GAAG;YAC3B,IAAI,CAACI,MAAM,OAAO;YAClB,IAAIA,KAAKY,KAAK,EAAE;gBACdZ,KAAKY,KAAK,GAAGZ,KAAKY,KAAK,CAACP,MAAM,CAACW;gBAC/B,IAAI,CAAChB,KAAKY,KAAK,CAACH,MAAM,EAAE,OAAOT,KAAKY,KAAK;YAC3C;YACA,IACEhB,OAAOkB,UACPC,KAAKE,GAAG,CAACrB,SACTI,cAAAA,KAAKY,KAAK,qBAAVZ,YAAYS,MAAM,KAClB,CAACxB,iBAAiBgC,GAAG,CAACjB,KAAKX,WAAW,GAEtC,OAAO;YACT,OAAO,IAAI,CAACuB,KAAK,CAAChB,GAAG;YACrB,OAAO;QACT;QACAoB,MAAMF;IACR;IAEA,iCAAiC,GACjCI,KAAKJ,MAAc,EAAmB;QACpC,OAAO;YAAEA;YAAQF,OAAO,IAAI,CAACA,KAAK;QAAC;IACrC;IA7DA,YAAY,AAAiBf,SAAS,IAAI,CAAE;aAAfA,SAAAA;aAHpBe,QAAyC,CAAC;aAC3CjB,QAAQ;IAE6B;AA8D/C"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
*/
|
|
17
|
+
import { type ComponentType, type ReactNode } from 'react';
|
|
18
|
+
/**
|
|
19
|
+
* A component registered by name whose code loads the first time it is
|
|
20
|
+
* drawn. `load` resolves to the component itself — the module's export —
|
|
21
|
+
* so a spec can hold a registration to the component it stands for.
|
|
22
|
+
*/
|
|
23
|
+
export type LazyWidget<P = any> = ComponentType<P> & {
|
|
24
|
+
load: () => Promise<ComponentType<P>>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Registers a component without loading it (AGL-3649).
|
|
28
|
+
*
|
|
29
|
+
* The console loads this plugin on every screen, because it fills the dock
|
|
30
|
+
* and the top bar, so anything `plugin.ts` imports statically is downloaded
|
|
31
|
+
* by every reader of every page, whichever card it is. A registration needs
|
|
32
|
+
* only a name and a component to call; this hands the registry a small
|
|
33
|
+
* stand-in that imports the real one when the shell first draws it.
|
|
34
|
+
*
|
|
35
|
+
* The stand-in carries its own `Suspense`. The shell's zones draw widgets
|
|
36
|
+
* with no boundary of their own, and the dock and the top bar sit above every
|
|
37
|
+
* route's boundary, so a bare `React.lazy` there would suspend the shell
|
|
38
|
+
* itself while one card's code arrived. Here the wait is the card's alone:
|
|
39
|
+
* it draws `fallback` (nothing, unless the caller says otherwise) in its own
|
|
40
|
+
* place, which is what a widget held by a gate already draws.
|
|
41
|
+
*
|
|
42
|
+
* Every gate stays on the registration — feature flag, permission, release
|
|
43
|
+
* flag — so a widget the shell withholds is never drawn and never loaded.
|
|
44
|
+
*/
|
|
45
|
+
export declare function lazyWidget<P extends object>(name: string, load: () => Promise<ComponentType<P>>, fallback?: ReactNode): LazyWidget<P>;
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
19
|
+
import { Suspense, lazy } from "react";
|
|
20
|
+
/**
|
|
21
|
+
* Registers a component without loading it (AGL-3649).
|
|
22
|
+
*
|
|
23
|
+
* The console loads this plugin on every screen, because it fills the dock
|
|
24
|
+
* and the top bar, so anything `plugin.ts` imports statically is downloaded
|
|
25
|
+
* by every reader of every page, whichever card it is. A registration needs
|
|
26
|
+
* only a name and a component to call; this hands the registry a small
|
|
27
|
+
* stand-in that imports the real one when the shell first draws it.
|
|
28
|
+
*
|
|
29
|
+
* The stand-in carries its own `Suspense`. The shell's zones draw widgets
|
|
30
|
+
* with no boundary of their own, and the dock and the top bar sit above every
|
|
31
|
+
* route's boundary, so a bare `React.lazy` there would suspend the shell
|
|
32
|
+
* itself while one card's code arrived. Here the wait is the card's alone:
|
|
33
|
+
* it draws `fallback` (nothing, unless the caller says otherwise) in its own
|
|
34
|
+
* place, which is what a widget held by a gate already draws.
|
|
35
|
+
*
|
|
36
|
+
* Every gate stays on the registration — feature flag, permission, release
|
|
37
|
+
* flag — so a widget the shell withholds is never drawn and never loaded.
|
|
38
|
+
*/ export function lazyWidget(name, load, fallback = null) {
|
|
39
|
+
let loading;
|
|
40
|
+
const loadOnce = ()=>loading != null ? loading : loading = load();
|
|
41
|
+
const Loaded = /*#__PURE__*/ lazy(()=>loadOnce().then((Component)=>({
|
|
42
|
+
default: Component
|
|
43
|
+
})));
|
|
44
|
+
const Widget = (props)=>/*#__PURE__*/ _jsx(Suspense, {
|
|
45
|
+
fallback: fallback,
|
|
46
|
+
children: /*#__PURE__*/ _jsx(Loaded, _extends({}, props))
|
|
47
|
+
});
|
|
48
|
+
Widget.displayName = name;
|
|
49
|
+
Widget.load = loadOnce;
|
|
50
|
+
return Widget;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=lazy-widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/ai/src/lib/lazy-widget.tsx"],"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'use client'\n\nimport { Suspense, lazy, type ComponentType, type ReactNode } from 'react'\n\n/**\n * A component registered by name whose code loads the first time it is\n * drawn. `load` resolves to the component itself — the module's export —\n * so a spec can hold a registration to the component it stands for.\n */\nexport type LazyWidget<P = any> = ComponentType<P> & {\n load: () => Promise<ComponentType<P>>\n}\n\n/**\n * Registers a component without loading it (AGL-3649).\n *\n * The console loads this plugin on every screen, because it fills the dock\n * and the top bar, so anything `plugin.ts` imports statically is downloaded\n * by every reader of every page, whichever card it is. A registration needs\n * only a name and a component to call; this hands the registry a small\n * stand-in that imports the real one when the shell first draws it.\n *\n * The stand-in carries its own `Suspense`. The shell's zones draw widgets\n * with no boundary of their own, and the dock and the top bar sit above every\n * route's boundary, so a bare `React.lazy` there would suspend the shell\n * itself while one card's code arrived. Here the wait is the card's alone:\n * it draws `fallback` (nothing, unless the caller says otherwise) in its own\n * place, which is what a widget held by a gate already draws.\n *\n * Every gate stays on the registration — feature flag, permission, release\n * flag — so a widget the shell withholds is never drawn and never loaded.\n */\nexport function lazyWidget<P extends object>(\n name: string,\n load: () => Promise<ComponentType<P>>,\n fallback: ReactNode = null,\n): LazyWidget<P> {\n let loading: Promise<ComponentType<P>> | undefined\n const loadOnce = () => (loading ??= load())\n const Loaded = lazy(() =>\n loadOnce().then((Component) => ({ default: Component })),\n )\n const Widget = (props: P) => (\n <Suspense fallback={fallback}>\n <Loaded {...(props as any)} />\n </Suspense>\n )\n Widget.displayName = name\n Widget.load = loadOnce\n return Widget\n}\n"],"names":["Suspense","lazy","lazyWidget","name","load","fallback","loading","loadOnce","Loaded","then","Component","default","Widget","props","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;AAEA,SAASA,QAAQ,EAAEC,IAAI,QAA4C,QAAO;AAW1E;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,WACdC,IAAY,EACZC,IAAqC,EACrCC,WAAsB,IAAI;IAE1B,IAAIC;IACJ,MAAMC,WAAW,IAAOD,kBAAAA,UAAAA,UAAYF;IACpC,MAAMI,uBAASP,KAAK,IAClBM,WAAWE,IAAI,CAAC,CAACC,YAAe,CAAA;gBAAEC,SAASD;YAAU,CAAA;IAEvD,MAAME,SAAS,CAACC,sBACd,KAACb;YAASK,UAAUA;sBAClB,cAAA,KAACG,qBAAYK;;IAGjBD,OAAOE,WAAW,GAAGX;IACrBS,OAAOR,IAAI,GAAGG;IACd,OAAOK;AACT"}
|