@tryvitris/website-harness 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +76 -74
  2. package/agent/graph.yaml +769 -756
  3. package/agent/refs/admin.md +11 -11
  4. package/agent/refs/browser.md +6 -2
  5. package/agent/refs/business.md +20 -9
  6. package/agent/refs/compose.md +2 -0
  7. package/agent/refs/design-quality.md +2 -0
  8. package/agent/refs/direction.md +2 -0
  9. package/agent/refs/implement.md +8 -4
  10. package/agent/refs/scheduling.md +13 -0
  11. package/agent/refs/template-adaptation.md +2 -0
  12. package/agent/refs/template-library.md +2 -0
  13. package/agent/refs/typography.md +15 -0
  14. package/bin/api/agent/evaluate.js +7 -6
  15. package/bin/api/agent/grade.js +7 -6
  16. package/bin/api/cli/api.js +15 -14
  17. package/bin/api/cli.js +17 -16
  18. package/bin/api/engine.js +8 -7
  19. package/bin/api/hosting.js +9 -8
  20. package/bin/api/index.js +4 -3
  21. package/bin/api/render.js +2 -1
  22. package/bin/api/theme.js +2 -1
  23. package/bin/chunks/{chunk-M72KKZIB.js → chunk-5KRJQKHB.js} +4 -3
  24. package/bin/chunks/{chunk-72Y4YMTV.js → chunk-AD7WAHW2.js} +2 -2
  25. package/bin/chunks/{chunk-RE4GOHSU.js → chunk-AS74YXGM.js} +3 -3
  26. package/bin/chunks/{chunk-AUO5I56E.js → chunk-C3F7XQD2.js} +194 -1
  27. package/bin/chunks/{chunk-445FZZEC.js → chunk-DDJ3QCRR.js} +9 -9
  28. package/bin/chunks/{chunk-LKN75JGA.js → chunk-GE6UUEG2.js} +13 -8
  29. package/bin/chunks/chunk-GPS3SAGQ.js +1020 -0
  30. package/bin/chunks/{chunk-37F7XIMH.js → chunk-JTXFTNEA.js} +6 -1
  31. package/bin/chunks/{chunk-JBSGJR7X.js → chunk-KR5ZUZV2.js} +2 -2
  32. package/bin/chunks/{chunk-65LRZIBP.js → chunk-MAPY3YVE.js} +2 -2
  33. package/bin/chunks/{chunk-VKU5TY5C.js → chunk-MYX4FET4.js} +1 -1
  34. package/bin/chunks/{chunk-54QPYUM2.js → chunk-OZD7ZWDX.js} +1 -1
  35. package/bin/chunks/chunk-S2XVNTQP.js +90 -0
  36. package/bin/chunks/{chunk-UR4NWYVW.js → chunk-SBOUSO3S.js} +3 -3
  37. package/bin/chunks/{chunk-KIWEFRNG.js → chunk-SXPLCCO7.js} +6 -6
  38. package/bin/chunks/{chunk-H3BS2EBR.js → chunk-WIT6364Y.js} +4 -4
  39. package/bin/chunks/{chunk-GQPUILFR.js → chunk-WK7HJI5H.js} +1301 -1252
  40. package/bin/chunks/{design-context-store-ETVS4N6W.js → design-context-store-PGXCHUOF.js} +7 -6
  41. package/bin/chunks/{packets-XFXKHSEY.js → packets-B7MCJ42T.js} +7 -6
  42. package/bin/chunks/{preparation-3OR7LVPQ.js → preparation-MVKICQPD.js} +7 -6
  43. package/bin/cloudflare/backend.js +90 -11
  44. package/bin/types/src/agent/browser-typography.d.ts +33 -0
  45. package/bin/types/src/agent/theme-suite-identity.d.ts +1 -0
  46. package/bin/types/src/agent/typography-policy.d.ts +6 -0
  47. package/bin/types/src/build/index.d.ts +2 -0
  48. package/bin/types/src/cli/admin.d.ts +1 -1
  49. package/bin/types/src/compile/site.d.ts +1 -1
  50. package/bin/types/src/scheduling/config.d.ts +11 -0
  51. package/bin/types/src/scheduling/management.d.ts +2 -0
  52. package/bin/types/src/scheduling/styles.d.ts +1 -0
  53. package/bin/types/src/scheduling/widget.d.ts +2 -0
  54. package/bin/types/src/theme.d.ts +3 -1
  55. package/bin/types/src/types.d.ts +6 -1
  56. package/bin/types/src/typography.d.ts +27 -0
  57. package/bin/vitris-art.js +7 -6
  58. package/bin/vitris-build.js +5 -4
  59. package/bin/vitris-create-site.js +9 -8
  60. package/bin/vitris-cursor-hook.js +7 -6
  61. package/bin/vitris-eval.js +9 -8
  62. package/bin/vitris-go.js +9 -8
  63. package/bin/vitris-harvest.js +8 -7
  64. package/bin/vitris-knowledge.js +8 -7
  65. package/bin/vitris-launch-preflight.js +7 -6
  66. package/bin/vitris-motion-view.js +7 -6
  67. package/bin/vitris-references.js +5 -4
  68. package/bin/vitris-refresh.js +8 -7
  69. package/bin/vitris-stock.js +1 -1
  70. package/bin/vitris-templates.js +91 -1
  71. package/bin/vitris-themes.js +7 -6
  72. package/bin/vitris-upgrade.js +8 -7
  73. package/bin/vitris-verify-browser.js +33 -8
  74. package/bin/vitris-verify-performance.js +5 -4
  75. package/bin/vitris.js +17 -16
  76. package/design-system/MASTER.md +4 -0
  77. package/docs/ADMIN.md +85 -85
  78. package/docs/CLI.md +314 -308
  79. package/docs/SCHEDULING.md +67 -0
  80. package/package.json +5 -4
  81. package/templates/site/site.json +1 -0
  82. package/templates/site/theme/defaults.json +78 -17
  83. package/bin/chunks/chunk-L44ZTNDM.js +0 -332
@@ -1,3 +1,7 @@
1
+ import {
2
+ typographyCss,
3
+ typographyEnabled
4
+ } from "./chunk-S2XVNTQP.js";
1
5
  import {
2
6
  iconCss,
3
7
  renderIcon
@@ -2573,8 +2577,9 @@ function usedComponents(pages) {
2573
2577
  }
2574
2578
  return [...names];
2575
2579
  }
2576
- function siteCss(pages, catalog) {
2580
+ function siteCss(pages, catalog, site) {
2577
2581
  const chunks = [baseCss, primitivesCss];
2582
+ if (typographyEnabled(site)) chunks.push(typographyCss());
2578
2583
  if (pages.some((page) => page.bodyHtml.includes("data-vitris-icon="))) chunks.push(iconCss);
2579
2584
  for (const name of usedComponents(pages)) {
2580
2585
  const css = catalog[name]?.css;
@@ -6,10 +6,10 @@ import {
6
6
  planKitUpgrade,
7
7
  recoverKitUpgrade,
8
8
  rollbackKitUpgrade
9
- } from "./chunk-GQPUILFR.js";
9
+ } from "./chunk-WK7HJI5H.js";
10
10
  import {
11
11
  findHarnessRoot
12
- } from "./chunk-H3BS2EBR.js";
12
+ } from "./chunk-WIT6364Y.js";
13
13
  import {
14
14
  json,
15
15
  save
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-XL2DRAYI.js";
4
4
  import {
5
5
  sourceRevision
6
- } from "./chunk-GQPUILFR.js";
6
+ } from "./chunk-WK7HJI5H.js";
7
7
  import {
8
8
  previewServer
9
9
  } from "./chunk-WEFDVXFX.js";
@@ -22,7 +22,7 @@ import {
22
22
  providerConsoleWarning,
23
23
  readOnlyEmbedProvider,
24
24
  unresolvedCaptureBlockers
25
- } from "./chunk-H3BS2EBR.js";
25
+ } from "./chunk-WIT6364Y.js";
26
26
  import {
27
27
  save,
28
28
  within
@@ -6,7 +6,7 @@ import {
6
6
  selectStageKnowledge,
7
7
  signalsFromSite,
8
8
  siteWidgets
9
- } from "./chunk-GQPUILFR.js";
9
+ } from "./chunk-WK7HJI5H.js";
10
10
  import {
11
11
  coverageReport,
12
12
  loadKnowledgeV2
@@ -13,7 +13,7 @@ import {
13
13
  formatExclusion,
14
14
  isErrorPage,
15
15
  isPlaywrightLaunchFailure
16
- } from "./chunk-GQPUILFR.js";
16
+ } from "./chunk-WK7HJI5H.js";
17
17
  import {
18
18
  json,
19
19
  save
@@ -0,0 +1,90 @@
1
+ // src/typography.ts
2
+ var TYPE_ROLES = ["display", "section", "subheading", "card-title", "body", "ui", "caption", "label"];
3
+ var MINIMUM_TYPE_PX = 12;
4
+ var DEFAULT_TYPE_ROLES = {
5
+ display: { size: "clamp(2.75rem, 1.8rem + 4vw, 5rem)", weight: 600, lineHeight: "1.08", tracking: "-0.03em", font: "display" },
6
+ section: { size: "clamp(2rem, 1.5rem + 2vw, 3.5rem)", weight: 600, lineHeight: "1.15", tracking: "-0.025em", font: "display" },
7
+ subheading: { size: "clamp(1.5rem, 1.3rem + 0.8vw, 2rem)", weight: 600, lineHeight: "1.25", tracking: "-0.015em", font: "display" },
8
+ "card-title": { size: "1.5rem", weight: 600, lineHeight: "1.3", tracking: "-0.01em", font: "display" },
9
+ body: { size: "1.125rem", weight: 400, lineHeight: "1.6", tracking: "normal", font: "body" },
10
+ ui: { size: "1rem", weight: 600, lineHeight: "1.5", tracking: "normal", font: "body" },
11
+ caption: { size: "0.875rem", weight: 400, lineHeight: "1.5", tracking: "normal", font: "body" },
12
+ label: { size: "0.875rem", weight: 600, lineHeight: "1.5", tracking: "0.02em", font: "body" }
13
+ };
14
+ var TYPE_SELECTORS = {
15
+ display: ["h1"],
16
+ section: ["h2", ".stat__value", ".stat--sm .stat__value", ".price__amount"],
17
+ subheading: ["h3", ".card__body > h3"],
18
+ "card-title": ["h4", ".card__body > h4", ".brand", ".quote", ".quote--lg", ".quote--card"],
19
+ body: ["body", ".lede", ".section__head .lede", ".lede--lg", ".list-check li", ".rating"],
20
+ ui: ["h5", "h6", "button", "input", "select", "textarea", "nav a", ".nav-links a", "summary", ".accordion summary", ".btn", ".btn-outline", ".btn-ghost", ".btn-arrow", ".skip-link", ".c-cookie-banner__title", ".c-cookie-banner__more", ".announcement a"],
21
+ caption: ["small", "figcaption", "sub", "sup", ".stat__label", ".price__period", ".byline", ".quote cite", ".quote footer", ".announcement", ".c-cookie-banner__text"],
22
+ label: ["label", ".eyebrow", ".badge", ".table th", ".chips > legend", ".chips__label", ".chips span"]
23
+ };
24
+ function typographyEnabled(site) {
25
+ if (site?.typography && site.typography.version !== 1) throw Error("Unsupported typography policy version");
26
+ return site?.typography?.version === 1;
27
+ }
28
+ function resolvedTypography(theme = {}) {
29
+ return Object.fromEntries(TYPE_ROLES.map((role) => [role, { ...DEFAULT_TYPE_ROLES[role], ...theme.typography?.roles?.[role] }]));
30
+ }
31
+ function validateTypography(value, requireRoles = false) {
32
+ const errors = [];
33
+ if (!value || typeof value !== "object" || Array.isArray(value)) return ["Typography requires a shared roles object in theme/defaults.json"];
34
+ const system = value;
35
+ if (!system.roles || typeof system.roles !== "object" || Array.isArray(system.roles)) return ["Typography roles must be an object"];
36
+ if (requireRoles) {
37
+ for (const role of TYPE_ROLES) if (!system.roles[role] || typeof system.roles[role] !== "object" || Object.keys(DEFAULT_TYPE_ROLES[role]).some((key) => !(key in system.roles[role]))) errors.push(`Typography role ${role} must declare size, weight, lineHeight, tracking and font`);
38
+ }
39
+ const check = (style, name) => {
40
+ if (!style || typeof style !== "object" || Array.isArray(style)) {
41
+ errors.push(`Invalid typography style: ${name}`);
42
+ return;
43
+ }
44
+ for (const key of ["size", "lineHeight", "tracking"]) if (style[key] !== void 0 && (typeof style[key] !== "string" || !style[key].trim() || /[;{}<>]/.test(style[key]))) errors.push(`Invalid typography ${name}.${key}`);
45
+ if (style.weight !== void 0 && (!Number.isFinite(style.weight) || style.weight < 1 || style.weight > 1e3)) errors.push(`Invalid typography ${name}.weight`);
46
+ if (style.font !== void 0 && !["body", "display"].includes(style.font)) errors.push(`Invalid typography ${name}.font`);
47
+ for (const key of Object.keys(style)) if (!["size", "weight", "lineHeight", "tracking", "font", "role", "reason"].includes(key)) errors.push(`Unknown typography property ${name}.${key}`);
48
+ };
49
+ for (const [role, style] of Object.entries(system.roles)) {
50
+ if (!TYPE_ROLES.includes(role)) errors.push(`Unknown typography role: ${role}`);
51
+ check(style, role);
52
+ }
53
+ if (system.variants !== void 0 && (!system.variants || typeof system.variants !== "object" || Array.isArray(system.variants))) errors.push("Typography variants must be an object");
54
+ else for (const [name, variant] of Object.entries(system.variants || {})) {
55
+ if (!/^[a-z][a-z0-9-]*$/.test(name) || !variant || !TYPE_ROLES.includes(variant.role) || typeof variant.reason !== "string" || !variant.reason.trim()) errors.push(`Typography variant ${name} needs a known role and reason`);
56
+ check(variant, name);
57
+ }
58
+ return errors;
59
+ }
60
+ function typographyVariables(theme) {
61
+ const errors = theme.typography ? validateTypography(theme.typography) : [];
62
+ if (errors.length) throw Error(errors.join("\n"));
63
+ const roles = resolvedTypography(theme);
64
+ const values = (prefix, style) => ` --type-${prefix}-size: ${style.size};
65
+ --type-${prefix}-weight: ${style.weight};
66
+ --type-${prefix}-leading: ${style.lineHeight};
67
+ --type-${prefix}-tracking: ${style.tracking};
68
+ --type-${prefix}-font: var(--font-${style.font});`;
69
+ return [...TYPE_ROLES.map((role) => values(role, roles[role])), ...Object.entries(theme.typography?.variants || {}).map(([name, variant]) => values(`variant-${name}`, { ...roles[variant.role], ...variant }))].join("\n");
70
+ }
71
+ function typographyCss() {
72
+ const declarations = (name) => `font-size:var(--type-${name}-size);font-weight:var(--type-${name}-weight);line-height:var(--type-${name}-leading);letter-spacing:var(--type-${name}-tracking);font-family:var(--type-${name}-font);font-synthesis:none`;
73
+ return [...TYPE_ROLES.map((role) => `${TYPE_SELECTORS[role].join(",")}{${declarations(role)}}`), ...TYPE_ROLES.map((role) => `[data-type-role="${role}"][data-type-role]{${declarations(role)}}`)].join("\n");
74
+ }
75
+ function typographyVariantCss(theme) {
76
+ return Object.keys(theme.typography?.variants || {}).map((name) => `[data-type-variant="${name}"][data-type-variant][data-type-variant]{font-size:var(--type-variant-${name}-size);font-weight:var(--type-variant-${name}-weight);line-height:var(--type-variant-${name}-leading);letter-spacing:var(--type-variant-${name}-tracking);font-family:var(--type-variant-${name}-font)}`).join("\n");
77
+ }
78
+
79
+ export {
80
+ TYPE_ROLES,
81
+ MINIMUM_TYPE_PX,
82
+ DEFAULT_TYPE_ROLES,
83
+ TYPE_SELECTORS,
84
+ typographyEnabled,
85
+ resolvedTypography,
86
+ validateTypography,
87
+ typographyVariables,
88
+ typographyCss,
89
+ typographyVariantCss
90
+ };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2NW7KSPA.js";
4
4
  import {
5
5
  verifyPreservedSite
6
- } from "./chunk-65LRZIBP.js";
6
+ } from "./chunk-MAPY3YVE.js";
7
7
  import {
8
8
  EXIT_CODES
9
9
  } from "./chunk-JCRGE6AL.js";
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  gradeAll,
15
15
  sourceRevision
16
- } from "./chunk-GQPUILFR.js";
16
+ } from "./chunk-WK7HJI5H.js";
17
17
  import {
18
18
  parseReleaseRecord
19
19
  } from "./chunk-M4LNHYYR.js";
@@ -21,7 +21,7 @@ import {
21
21
  buildVerified,
22
22
  findHarnessRoot,
23
23
  isPreserveSite
24
- } from "./chunk-H3BS2EBR.js";
24
+ } from "./chunk-WIT6364Y.js";
25
25
  import {
26
26
  json,
27
27
  save
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  prepareChange,
3
3
  verifyChange
4
- } from "./chunk-72Y4YMTV.js";
4
+ } from "./chunk-AD7WAHW2.js";
5
5
  import {
6
6
  deployVerifiedArtifact,
7
7
  prepareQuickRelease,
8
8
  prepareVerifiedRelease
9
- } from "./chunk-UR4NWYVW.js";
9
+ } from "./chunk-SBOUSO3S.js";
10
10
  import {
11
11
  creativeRunStatus,
12
12
  currentRunId,
@@ -14,10 +14,10 @@ import {
14
14
  runCreativeProfile,
15
15
  startDesignReview,
16
16
  submitFeedback
17
- } from "./chunk-RE4GOHSU.js";
17
+ } from "./chunk-AS74YXGM.js";
18
18
  import {
19
19
  verifyPreservedSite
20
- } from "./chunk-65LRZIBP.js";
20
+ } from "./chunk-MAPY3YVE.js";
21
21
  import {
22
22
  EXIT_CODES
23
23
  } from "./chunk-JCRGE6AL.js";
@@ -35,7 +35,7 @@ import {
35
35
  prepareRefine,
36
36
  runWorkflow,
37
37
  verifyRefine
38
- } from "./chunk-GQPUILFR.js";
38
+ } from "./chunk-WK7HJI5H.js";
39
39
  import {
40
40
  parseGraphYaml
41
41
  } from "./chunk-BBV7PMFC.js";
@@ -49,7 +49,7 @@ import {
49
49
  buildVerified,
50
50
  findKernelRoot,
51
51
  isPreserveSite
52
- } from "./chunk-H3BS2EBR.js";
52
+ } from "./chunk-WIT6364Y.js";
53
53
  import {
54
54
  recoverPendingTransactions,
55
55
  save
@@ -2,10 +2,10 @@ import {
2
2
  buildSite,
3
3
  connectForms,
4
4
  loadSiteDir
5
- } from "./chunk-L44ZTNDM.js";
5
+ } from "./chunk-GPS3SAGQ.js";
6
6
  import {
7
7
  leadsJs
8
- } from "./chunk-37F7XIMH.js";
8
+ } from "./chunk-JTXFTNEA.js";
9
9
  import {
10
10
  acquirePathLock,
11
11
  files,
@@ -686,7 +686,7 @@ async function buildVerified(siteRoot, output = join8(siteRoot, "dist"), origin,
686
686
  const local = await loadSiteDir(root);
687
687
  if (slug) local.site = { ...local.site, slug };
688
688
  const launch = existsSync8(join8(root, "launch.json")) ? json(join8(root, "launch.json")) : {};
689
- await buildSite({ ...local, webAnalyticsToken: launch.webAnalyticsToken, forms: launch.forms, kernelOrigin: origin || process.env.VITRIS_BACKEND_ORIGIN || process.env.KERNEL_ORIGIN || launch.backendOrigin || launch.kernelOrigin || "", publicOrigin: process.env.VITRIS_PUBLIC_ORIGIN || launch.publicOrigin, outDir: stage });
689
+ await buildSite({ ...local, webAnalyticsToken: launch.webAnalyticsToken, scheduling: launch.scheduling, forms: launch.forms, kernelOrigin: origin || process.env.VITRIS_BACKEND_ORIGIN || process.env.KERNEL_ORIGIN || launch.backendOrigin || launch.kernelOrigin || "", publicOrigin: process.env.VITRIS_PUBLIC_ORIGIN || launch.publicOrigin, outDir: stage });
690
690
  for (const path of ["media", "public"]) {
691
691
  const source = within(root, path);
692
692
  if (!existsSync8(source)) continue;
@@ -734,7 +734,7 @@ ${from} ${route.target} 301`;
734
734
  save(join8(stage, "package-manifest.json"), { slug: local.site.slug || "", site: local.site });
735
735
  const kernelParent = resolve3(import.meta.dirname, "..");
736
736
  const kernelSource = existsSync8(join8(kernelParent, "compile")) ? kernelParent : join8(kernelParent, "src");
737
- save(join8(stage, "build-evidence.json"), { version: 2, sourceHash: sourceHash(root), compilerHash: fingerprint(kernelSource, ["compile", "build", "runtime", "forms", "theme.ts"]) });
737
+ save(join8(stage, "build-evidence.json"), { version: 2, sourceHash: sourceHash(root), compilerHash: fingerprint(kernelSource, ["compile", "build", "runtime", "forms", "scheduling", "theme.ts", "typography.ts"]) });
738
738
  const previous = out + `.previous-${Date.now()}-${process.pid}`;
739
739
  if (existsSync8(out)) replacePath(out, previous);
740
740
  try {