@aglyn/plugins-ai 1.0.0-beta.242 → 1.0.0-beta.244
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/jobs/ai-job-layout-language.js +11 -6
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +3 -1
- package/src/lib/jobs/ai-job-page-language.js +17 -5
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +11 -4
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.js +22 -8
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +52 -8
- package/src/lib/jobs/ai-layout-stock-photos.js +351 -72
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/ai-site-publish.d.ts +14 -0
- package/src/lib/jobs/ai-site-publish.js +28 -3
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-stock-photo-tidewater-recordings.d.ts +27 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-tidewater-recordings.js +261 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-tidewater-recordings.js.map +1 -0
- package/src/lib/layout-language/ai-layout-links.js +5 -2
- package/src/lib/layout-language/ai-layout-links.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +42 -1
- package/src/lib/runtime/ai-doctrine-validators.js +98 -11
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/usage/ai-quota-checks.d.ts +13 -3
- package/src/lib/usage/ai-quota-checks.js +46 -8
- package/src/lib/usage/ai-quota-checks.js.map +1 -1
|
@@ -130,6 +130,14 @@ export interface AiDoctrineTreeContext extends AiNodeTreeContext {
|
|
|
130
130
|
* to when the site has none for what it promises. Absent: none is known.
|
|
131
131
|
*/
|
|
132
132
|
homeScreenIds?: readonly string[];
|
|
133
|
+
/**
|
|
134
|
+
* The site's pages that place its form, by id (AGL-3729): where a link whose
|
|
135
|
+
* words ask a visitor to get in touch (`aiAsksToGetInTouch`) does what it
|
|
136
|
+
* says, even when that page is home. A guided start's café put its
|
|
137
|
+
* pre-order form on Home, and its Menu page's "Request weekend pickup"
|
|
138
|
+
* links there. Absent: none is known, and a link home is held to its words.
|
|
139
|
+
*/
|
|
140
|
+
formScreenIds?: readonly string[];
|
|
133
141
|
/**
|
|
134
142
|
* The node as the model wrote it, by the id the checked tree gives it
|
|
135
143
|
* (AGL-3078), for a tree that was stored before it is checked: a page
|
|
@@ -472,6 +480,39 @@ export declare function isAiLinkElement(componentId: unknown): boolean;
|
|
|
472
480
|
* a re-ask to inherit the band's contrast text or to set it.
|
|
473
481
|
*/
|
|
474
482
|
export declare function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[];
|
|
483
|
+
/**
|
|
484
|
+
* Whether a link's words ask a visitor to get in touch — contact, book, quote,
|
|
485
|
+
* request, order, pre-order, enquire — which the site's form answers
|
|
486
|
+
* (AGL-3729). The layout language sends such a link to the form.
|
|
487
|
+
*/
|
|
488
|
+
export declare function aiAsksToGetInTouch(label: string): boolean;
|
|
489
|
+
/**
|
|
490
|
+
* RULE 10'S LINK SENT HOME, REPAIRED IN CODE (AGL-3729).
|
|
491
|
+
*
|
|
492
|
+
* The rule's own advice is "link the page that does, or leave the link out",
|
|
493
|
+
* and both halves are something code can do once it knows where the site's
|
|
494
|
+
* form is. A Free guided start's café (beta.243, 2026-10-12) put its contact
|
|
495
|
+
* and pre-order form on Home; its Menu page's "Request weekend pickup" was
|
|
496
|
+
* sent to Home, and the page was refused on every answer, since the
|
|
497
|
+
* destination was the compiler's, not the model's. So, before the check reads
|
|
498
|
+
* the tree, each link `detectUnrelatedScreenLinks` would refuse is:
|
|
499
|
+
*
|
|
500
|
+
* - repointed to the page that places the site's form, when its words ask a
|
|
501
|
+
* visitor to get in touch and the site has such a page that is not the page
|
|
502
|
+
* being checked (`formScreenIds`, `ownScreenIds`). The platform reaches a
|
|
503
|
+
* section of another page by no anchor (AGL-2867), so the link names the
|
|
504
|
+
* page; a link to a section of its own page is the Scroll to element
|
|
505
|
+
* interaction, which this never writes;
|
|
506
|
+
* - otherwise left out: the node and everything under it are taken off the
|
|
507
|
+
* page, and out of its parent's children.
|
|
508
|
+
*
|
|
509
|
+
* The root is never taken out. A tree with nothing to repair comes back as
|
|
510
|
+
* the same object; a node that is changed is copied, never edited in place.
|
|
511
|
+
*/
|
|
512
|
+
export declare function aiSettleUnrelatedScreenLinks<T extends AiDoctrineTree>(tree: T, outputKind: AiOutputKind, context?: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds'> & {
|
|
513
|
+
/** The page being checked, by every id it goes by: a link never goes to itself. */
|
|
514
|
+
ownScreenIds?: readonly string[];
|
|
515
|
+
}): T;
|
|
475
516
|
/**
|
|
476
517
|
* Rule 10, for a link sent where the site has nothing for it (AGL-3056). A
|
|
477
518
|
* link whose purpose the site has no screen for is left out; it never goes to
|
|
@@ -483,7 +524,7 @@ export declare function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: A
|
|
|
483
524
|
* not say home is refused, with a re-ask to link the screen that does what it
|
|
484
525
|
* says, or to leave the link out.
|
|
485
526
|
*/
|
|
486
|
-
export declare function detectUnrelatedScreenLinks(tree: AiDoctrineTree, outputKind: AiOutputKind, context?: Pick<AiDoctrineTreeContext, 'homeScreenIds'>): AiDoctrineViolation[];
|
|
527
|
+
export declare function detectUnrelatedScreenLinks(tree: AiDoctrineTree, outputKind: AiOutputKind, context?: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds'>): AiDoctrineViolation[];
|
|
487
528
|
/**
|
|
488
529
|
* Rule 10, for a link that goes nowhere (AGL-3072). A Button or a Screen Link
|
|
489
530
|
* goes where its `screenId` or its `href` says, and those are the only
|
|
@@ -1841,20 +1841,23 @@ const GRID = 'muiGrid';
|
|
|
1841
1841
|
];
|
|
1842
1842
|
}
|
|
1843
1843
|
/** A link's words that say it goes home. */ const HOME_WORDS = /\bhome(?:\s?page)?\b/i;
|
|
1844
|
+
/** Words that ask a visitor to get in touch, which the site's form answers. */ const GET_IN_TOUCH_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|pre-?order|sign up|join|apply|start)\b/i;
|
|
1844
1845
|
/**
|
|
1845
|
-
*
|
|
1846
|
-
*
|
|
1847
|
-
*
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
*
|
|
1853
|
-
*
|
|
1854
|
-
|
|
1855
|
-
|
|
1846
|
+
* Whether a link's words ask a visitor to get in touch — contact, book, quote,
|
|
1847
|
+
* request, order, pre-order, enquire — which the site's form answers
|
|
1848
|
+
* (AGL-3729). The layout language sends such a link to the form.
|
|
1849
|
+
*/ export function aiAsksToGetInTouch(label) {
|
|
1850
|
+
return GET_IN_TOUCH_WORDS.test(label);
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* The links rule 10 refuses as sent home for nothing (`detectUnrelatedScreenLinks`),
|
|
1854
|
+
* in document order. A link whose words ask a visitor to get in touch, sent to
|
|
1855
|
+
* a home page that places the site's form, does what it says (AGL-3729).
|
|
1856
|
+
*/ function unrelatedScreenLinks(tree, outputKind, context) {
|
|
1857
|
+
var _context_homeScreenIds, _context_formScreenIds;
|
|
1856
1858
|
if (outputKind === 'email' || outputKind === 'form') return [];
|
|
1857
1859
|
const home = new Set((_context_homeScreenIds = context.homeScreenIds) != null ? _context_homeScreenIds : []);
|
|
1860
|
+
const forms = new Set((_context_formScreenIds = context.formScreenIds) != null ? _context_formScreenIds : []);
|
|
1858
1861
|
const sent = [];
|
|
1859
1862
|
for (const visit of walkTree(tree)){
|
|
1860
1863
|
var _node_props, _node_props1, _node_props2;
|
|
@@ -1864,6 +1867,8 @@ const GRID = 'muiGrid';
|
|
|
1864
1867
|
const linksHome = typeof screenId === 'string' && home.has(screenId) || ((_node_props1 = node.props) == null ? void 0 : _node_props1['href']) === '/';
|
|
1865
1868
|
const label = typeof ((_node_props2 = node.props) == null ? void 0 : _node_props2['children']) === 'string' ? node.props['children'].trim() : '';
|
|
1866
1869
|
if (!linksHome || !label || HOME_WORDS.test(label)) continue;
|
|
1870
|
+
// Home holds the site's form, and the words ask for what it does (AGL-3729).
|
|
1871
|
+
if (typeof screenId === 'string' && forms.has(screenId) && aiAsksToGetInTouch(label)) continue;
|
|
1867
1872
|
// The header and the navigation link home by name and by the site's own brand.
|
|
1868
1873
|
const inNavigation = hasAncestor(tree, visit, (ancestor)=>ancestor.componentId === 'muiAppBar' || [
|
|
1869
1874
|
'header',
|
|
@@ -1874,6 +1879,88 @@ const GRID = 'muiGrid';
|
|
|
1874
1879
|
label
|
|
1875
1880
|
});
|
|
1876
1881
|
}
|
|
1882
|
+
return sent;
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* RULE 10'S LINK SENT HOME, REPAIRED IN CODE (AGL-3729).
|
|
1886
|
+
*
|
|
1887
|
+
* The rule's own advice is "link the page that does, or leave the link out",
|
|
1888
|
+
* and both halves are something code can do once it knows where the site's
|
|
1889
|
+
* form is. A Free guided start's café (beta.243, 2026-10-12) put its contact
|
|
1890
|
+
* and pre-order form on Home; its Menu page's "Request weekend pickup" was
|
|
1891
|
+
* sent to Home, and the page was refused on every answer, since the
|
|
1892
|
+
* destination was the compiler's, not the model's. So, before the check reads
|
|
1893
|
+
* the tree, each link `detectUnrelatedScreenLinks` would refuse is:
|
|
1894
|
+
*
|
|
1895
|
+
* - repointed to the page that places the site's form, when its words ask a
|
|
1896
|
+
* visitor to get in touch and the site has such a page that is not the page
|
|
1897
|
+
* being checked (`formScreenIds`, `ownScreenIds`). The platform reaches a
|
|
1898
|
+
* section of another page by no anchor (AGL-2867), so the link names the
|
|
1899
|
+
* page; a link to a section of its own page is the Scroll to element
|
|
1900
|
+
* interaction, which this never writes;
|
|
1901
|
+
* - otherwise left out: the node and everything under it are taken off the
|
|
1902
|
+
* page, and out of its parent's children.
|
|
1903
|
+
*
|
|
1904
|
+
* The root is never taken out. A tree with nothing to repair comes back as
|
|
1905
|
+
* the same object; a node that is changed is copied, never edited in place.
|
|
1906
|
+
*/ export function aiSettleUnrelatedScreenLinks(tree, outputKind, context = {}) {
|
|
1907
|
+
var _context_ownScreenIds, _find, _context_formScreenIds;
|
|
1908
|
+
const sent = unrelatedScreenLinks(tree, outputKind, context);
|
|
1909
|
+
if (!sent.length) return tree;
|
|
1910
|
+
const own = new Set((_context_ownScreenIds = context.ownScreenIds) != null ? _context_ownScreenIds : []);
|
|
1911
|
+
const formScreen = (_find = ((_context_formScreenIds = context.formScreenIds) != null ? _context_formScreenIds : []).find((id)=>!own.has(id))) != null ? _find : null;
|
|
1912
|
+
const nodes = _extends({}, tree.nodes);
|
|
1913
|
+
const parents = new Map();
|
|
1914
|
+
for (const visit of walkTree(tree)){
|
|
1915
|
+
const parent = visit.ancestors[visit.ancestors.length - 1];
|
|
1916
|
+
if (parent !== undefined) parents.set(visit.id, parent);
|
|
1917
|
+
}
|
|
1918
|
+
for (const { id, label } of sent){
|
|
1919
|
+
var _nodes_parent_nodes;
|
|
1920
|
+
if (!nodes[id]) continue;
|
|
1921
|
+
if (formScreen && aiAsksToGetInTouch(label)) {
|
|
1922
|
+
var _nodes_id_props;
|
|
1923
|
+
const props = _extends({}, (_nodes_id_props = nodes[id].props) != null ? _nodes_id_props : {}, {
|
|
1924
|
+
screenId: formScreen
|
|
1925
|
+
});
|
|
1926
|
+
delete props['href'];
|
|
1927
|
+
nodes[id] = _extends({}, nodes[id], {
|
|
1928
|
+
props
|
|
1929
|
+
});
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
const parent = parents.get(id);
|
|
1933
|
+
if (parent === undefined || !nodes[parent]) continue;
|
|
1934
|
+
nodes[parent] = _extends({}, nodes[parent], {
|
|
1935
|
+
nodes: ((_nodes_parent_nodes = nodes[parent].nodes) != null ? _nodes_parent_nodes : []).filter((child)=>child !== id)
|
|
1936
|
+
});
|
|
1937
|
+
const stack = [
|
|
1938
|
+
id
|
|
1939
|
+
];
|
|
1940
|
+
while(stack.length){
|
|
1941
|
+
var _ref;
|
|
1942
|
+
var _nodes_next;
|
|
1943
|
+
const next = stack.pop();
|
|
1944
|
+
stack.push(...(_ref = (_nodes_next = nodes[next]) == null ? void 0 : _nodes_next.nodes) != null ? _ref : []);
|
|
1945
|
+
delete nodes[next];
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
return _extends({}, tree, {
|
|
1949
|
+
nodes
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
/**
|
|
1953
|
+
* Rule 10, for a link sent where the site has nothing for it (AGL-3056). A
|
|
1954
|
+
* link whose purpose the site has no screen for is left out; it never goes to
|
|
1955
|
+
* a screen that does something else. The site inventory cannot say what each
|
|
1956
|
+
* screen is for, but it can name the one a model falls back to: a live About
|
|
1957
|
+
* page's footer sent "Request a Consultation" to the home screen, because the
|
|
1958
|
+
* site had no consultation screen. So a Screen Link or a Button, outside the
|
|
1959
|
+
* header and the navigation, that links the home screen with words that do
|
|
1960
|
+
* not say home is refused, with a re-ask to link the screen that does what it
|
|
1961
|
+
* says, or to leave the link out.
|
|
1962
|
+
*/ export function detectUnrelatedScreenLinks(tree, outputKind, context = {}) {
|
|
1963
|
+
const sent = unrelatedScreenLinks(tree, outputKind, context);
|
|
1877
1964
|
if (!sent.length) return [];
|
|
1878
1965
|
return [
|
|
1879
1966
|
{
|