@tryvitris/website-harness 0.1.0-beta.7 → 1.0.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 (75) hide show
  1. package/README.md +49 -117
  2. package/agent/graph.yaml +12 -6
  3. package/agent/refs/admin.md +11 -0
  4. package/agent/refs/analytics.md +17 -0
  5. package/agent/refs/launch.md +15 -11
  6. package/agent/refs/performance.md +1 -1
  7. package/bin/api/agent/evaluate.js +5 -5
  8. package/bin/api/agent/grade.js +5 -5
  9. package/bin/api/cli/api.js +15 -13
  10. package/bin/api/cli.js +15 -15
  11. package/bin/api/engine.js +6 -6
  12. package/bin/api/hosting.js +9 -7
  13. package/bin/api/index.js +2 -2
  14. package/bin/api/render.js +1 -1
  15. package/bin/chunks/{chunk-ZIROO2U4.js → chunk-37F7XIMH.js} +4 -3
  16. package/bin/chunks/{chunk-TTAUU3AZ.js → chunk-3OKR5AZJ.js} +1 -1
  17. package/bin/chunks/{chunk-PGFFKPK6.js → chunk-A2XMAPVW.js} +2 -2
  18. package/bin/chunks/{chunk-O55LAQ2C.js → chunk-FGSQE3DU.js} +2 -2
  19. package/bin/chunks/{chunk-VTI32UGJ.js → chunk-H3BS2EBR.js} +2 -2
  20. package/bin/chunks/{chunk-DSS2U2OM.js → chunk-KVMZSQ3D.js} +8 -2
  21. package/bin/chunks/{chunk-4MFPATAB.js → chunk-L44ZTNDM.js} +12 -5
  22. package/bin/chunks/{chunk-7V3OKLKH.js → chunk-LZC37OJZ.js} +4 -4
  23. package/bin/chunks/{chunk-5YSPWKFF.js → chunk-PYCRUMCT.js} +1 -1
  24. package/bin/chunks/{chunk-QRWGFLUU.js → chunk-R2WRQDVE.js} +2 -2
  25. package/bin/chunks/{chunk-YZWEXHT4.js → chunk-SEMH6MCV.js} +129 -21
  26. package/bin/chunks/{chunk-H7Y72HXC.js → chunk-UFTVWTEZ.js} +26 -7
  27. package/bin/chunks/{chunk-P56ZDMX7.js → chunk-WMJVLMU2.js} +16 -4
  28. package/bin/chunks/{chunk-FRABKM65.js → chunk-XY73ZLHB.js} +12 -9
  29. package/bin/chunks/{chunk-ZWFG4GPG.js → chunk-YXJAQYDE.js} +69 -53
  30. package/bin/chunks/{design-context-store-DCZOAK56.js → design-context-store-W3VTZ4HA.js} +5 -5
  31. package/bin/chunks/{packets-QOLWPRNV.js → packets-LBMDIFPO.js} +5 -5
  32. package/bin/chunks/{preparation-T2IOD5SJ.js → preparation-AV4PDQY6.js} +5 -5
  33. package/bin/chunks/{template-gallery-ET76ERZQ.js → template-gallery-H2SVYNRD.js} +1 -1
  34. package/bin/cloudflare/backend.js +144 -62
  35. package/bin/types/src/admin/connection.d.ts +3 -0
  36. package/bin/types/src/cli/admin.d.ts +21 -0
  37. package/bin/types/src/cli/api.d.ts +1 -1
  38. package/bin/types/src/cli/deploy.d.ts +2 -0
  39. package/bin/types/src/cli/doctor.d.ts +1 -0
  40. package/bin/types/src/cli/site-create.d.ts +2 -0
  41. package/bin/types/src/compile/site.d.ts +1 -1
  42. package/bin/types/src/integrations/hosting.d.ts +2 -0
  43. package/bin/vitris-art.js +5 -5
  44. package/bin/vitris-build.js +3 -3
  45. package/bin/vitris-create-site.js +9 -7
  46. package/bin/vitris-cursor-hook.js +5 -5
  47. package/bin/vitris-eval.js +7 -7
  48. package/bin/vitris-go.js +7 -7
  49. package/bin/vitris-harvest.js +6 -6
  50. package/bin/vitris-knowledge.js +6 -6
  51. package/bin/vitris-launch-preflight.js +5 -5
  52. package/bin/vitris-motion-view.js +5 -5
  53. package/bin/vitris-references.js +3 -3
  54. package/bin/vitris-refresh.js +6 -6
  55. package/bin/vitris-stock.js +1 -1
  56. package/bin/vitris-templates.js +1 -1
  57. package/bin/vitris-themes.js +5 -5
  58. package/bin/vitris-upgrade.js +6 -6
  59. package/bin/vitris-verify-browser.js +5 -5
  60. package/bin/vitris-verify-performance.js +3 -3
  61. package/bin/vitris.js +15 -15
  62. package/docs/ADMIN.md +85 -0
  63. package/docs/CLI.md +14 -6
  64. package/docs/CLOUDFLARE.md +27 -2
  65. package/docs/DISTRIBUTION.md +5 -3
  66. package/docs/ENGINE.md +6 -0
  67. package/docs/PRESERVE.md +1 -1
  68. package/docs/SECURITY.md +2 -2
  69. package/package.json +28 -23
  70. package/templates/site/AGENTS.md +4 -2
  71. package/templates/site/README.md +8 -3
  72. package/templates/site/deployment/README.md +24 -0
  73. package/templates/site/{.github/workflows/deploy.yml → deployment/github-actions.yml.example} +5 -6
  74. package/templates/site/gitignore +3 -0
  75. package/templates/site/package.json +3 -1
@@ -881,67 +881,6 @@ async function handleInboundEmail(message, env) {
881
881
  });
882
882
  }
883
883
 
884
- // src/html.ts
885
- function escapeHtml(value) {
886
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
887
- }
888
- function escapeAttr(value) {
889
- return escapeHtml(value);
890
- }
891
-
892
- // src/types.ts
893
- var defaultTheme = {
894
- colorBg: "#F7F4EF",
895
- colorText: "#1A1714",
896
- colorMuted: "#5C574F",
897
- colorAccent: "#B44A2C",
898
- colorAccentText: "#FFFFFF",
899
- colorSurface: "#FFFFFF",
900
- colorSurface2: "#EFEAE3",
901
- colorBorder: "#E4DDD2",
902
- colorFocus: "#B44A2C",
903
- fontBody: 'ui-sans-serif, system-ui, "Segoe UI", sans-serif',
904
- fontDisplay: "ui-serif, Georgia, 'Times New Roman', serif",
905
- radius: "8px",
906
- radiusLg: "16px",
907
- radiusPill: "999px",
908
- maxWidth: "1120px"
909
- };
910
-
911
- // src/worker/tenant.ts
912
- async function tenantBySlug(env, slug) {
913
- return env.DB.prepare("SELECT * FROM tenants WHERE slug = ?").bind(slug).first();
914
- }
915
- async function tenantById(env, id) {
916
- return env.DB.prepare("SELECT * FROM tenants WHERE id = ?").bind(id).first();
917
- }
918
- async function tenantByHostname(env, hostname) {
919
- const cached = await env.KV.get(`host:${hostname}`);
920
- if (cached) return tenantById(env, cached);
921
- const row = await env.DB.prepare(
922
- `SELECT tenants.* FROM tenants JOIN hostnames ON hostnames.tenant_id = tenants.id WHERE hostnames.hostname = ?`
923
- ).bind(hostname.toLowerCase()).first();
924
- if (row) await env.KV.put(`host:${hostname}`, row.id, { expirationTtl: 3600 });
925
- return row;
926
- }
927
- async function loadSiteSnapshot(env, tenantId) {
928
- const siteRow = await env.DB.prepare("SELECT json FROM site_config WHERE tenant_id = ?").bind(tenantId).first();
929
- const contentRow = await env.DB.prepare("SELECT json FROM content WHERE tenant_id = ?").bind(tenantId).first();
930
- const themeRow = await env.DB.prepare("SELECT json FROM theme WHERE tenant_id = ?").bind(tenantId).first();
931
- if (!siteRow || !contentRow || !themeRow) return null;
932
- return {
933
- site: JSON.parse(siteRow.json),
934
- content: JSON.parse(contentRow.json),
935
- theme: { ...defaultTheme, ...JSON.parse(themeRow.json) }
936
- };
937
- }
938
- async function bumpVersion(env, tenantId) {
939
- const row = await env.DB.prepare(
940
- "UPDATE tenants SET content_version = content_version + 1 WHERE id = ? RETURNING content_version"
941
- ).bind(tenantId).first();
942
- return row?.content_version ?? 1;
943
- }
944
-
945
884
  // src/forms/config.ts
946
885
  var safeId = (s) => typeof s === "string" && /^[a-zA-Z0-9_-]{1,80}$/.test(s);
947
886
  var safeEmail = (s) => {
@@ -977,6 +916,14 @@ function validateFormConfig(value) {
977
916
  return c2;
978
917
  }
979
918
 
919
+ // src/html.ts
920
+ function escapeHtml(value) {
921
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
922
+ }
923
+ function escapeAttr(value) {
924
+ return escapeHtml(value);
925
+ }
926
+
980
927
  // src/worker/forms.ts
981
928
  var MAX_BODY = 32768;
982
929
  function sandboxMailReadiness(env) {
@@ -1220,6 +1167,140 @@ async function handleFormsAdmin(env, request) {
1220
1167
  }
1221
1168
  }
1222
1169
 
1170
+ // src/worker/admin.ts
1171
+ var scopes = ["leads:read", "analytics:read", "leads:write"];
1172
+ var json2 = (data, status = 200) => Response.json(data, { status, headers: { "cache-control": "no-store", "x-content-type-options": "nosniff" } });
1173
+ async function handleAdmin(env, request) {
1174
+ const url = new URL(request.url);
1175
+ const match = url.pathname.match(/^\/api\/admin\/v1\/([a-zA-Z0-9_-]{1,100})\/(status|leads|analytics|leads\/status)$/);
1176
+ if (!match) return json2({ error: "Not found" }, 404);
1177
+ const [, tenant, resource] = match;
1178
+ if (request.headers.has("origin")) return json2({ error: "Server credential required" }, 403);
1179
+ const installationId = request.headers.get("x-vitris-installation") || "";
1180
+ const token = request.headers.get("authorization")?.match(/^Bearer ([a-zA-Z0-9_-]{32,200})$/)?.[1];
1181
+ let grant;
1182
+ try {
1183
+ const map = JSON.parse(env.ADMIN_CONNECTIONS || "{}");
1184
+ if (map && typeof map === "object" && !Array.isArray(map) && Object.hasOwn(map, installationId)) grant = map[installationId];
1185
+ } catch {
1186
+ }
1187
+ if (!grant || !token || !/^[a-f0-9]{64}$/.test(grant.tokenHash) || await digest(token) !== grant.tokenHash) return json2({ error: "Unauthorized" }, 401);
1188
+ if (grant.tenantId !== tenant || grant.siteOrigin !== request.headers.get("x-vitris-site-origin") || !Array.isArray(grant.scopes) || grant.scopes.some((s) => !scopes.includes(s))) return json2({ error: "Forbidden" }, 403);
1189
+ if (!await env.DB.prepare("SELECT id FROM tenants WHERE id=?").bind(tenant).first()) return json2({ error: "Forbidden" }, 403);
1190
+ const identity = { schemaVersion: 1, installationId, tenantId: tenant, siteOrigin: grant.siteOrigin };
1191
+ const required = resource === "analytics" ? "analytics:read" : resource === "leads/status" ? "leads:write" : resource === "leads" ? "leads:read" : void 0;
1192
+ if (required && !grant.scopes.includes(required)) return json2({ error: "Forbidden" }, 403);
1193
+ if (request.method !== (resource === "leads/status" ? "POST" : "GET")) return json2({ error: "Method not allowed" }, 405);
1194
+ if (resource === "status") return json2({ ...identity, scopes: grant.scopes, capabilities: { leads: grant.scopes.includes("leads:read"), testSubmissions: grant.scopes.includes("leads:read"), analytics: grant.scopes.includes("analytics:read"), leadStatus: grant.scopes.includes("leads:write") } });
1195
+ if (resource === "leads/status") {
1196
+ if (url.searchParams.has("mode")) return json2({ error: "Test submissions are read-only" }, 400);
1197
+ if (!request.headers.get("content-type")?.startsWith("application/json")) return json2({ error: "JSON required" }, 400);
1198
+ const reader = request.body?.getReader();
1199
+ let body = "";
1200
+ let size = 0;
1201
+ if (reader) for (; ; ) {
1202
+ const { done, value } = await reader.read();
1203
+ if (done) break;
1204
+ size += value.length;
1205
+ if (size > 2048) {
1206
+ await reader.cancel();
1207
+ return json2({ error: "Body too large" }, 413);
1208
+ }
1209
+ body += new TextDecoder().decode(value);
1210
+ }
1211
+ let data;
1212
+ try {
1213
+ data = JSON.parse(body);
1214
+ } catch {
1215
+ return json2({ error: "Invalid JSON" }, 400);
1216
+ }
1217
+ if (!data || typeof data.id !== "string" || data.id.length > 200 || !["new", "contacted", "closed"].includes(data.status)) return json2({ error: "Invalid lead status" }, 400);
1218
+ const result = await env.DB.prepare("UPDATE leads SET status=? WHERE id=? AND tenant_id=? RETURNING id").bind(data.status, data.id, tenant).first();
1219
+ return result ? json2({ ok: true }) : json2({ error: "Lead not found" }, 404);
1220
+ }
1221
+ if (resource === "leads") {
1222
+ const mode = url.searchParams.get("mode") || "live";
1223
+ if (!["live", "test"].includes(mode)) return json2({ error: "Invalid mode" }, 400);
1224
+ const sql = mode === "test" ? `SELECT s.id,s.name,s.email,s.phone,s.message,s.page_path,s.created_at,s.fields_json,'test' AS status,s.form_id,'test' AS mode,o.status AS notification_status,o.last_error AS notification_error,o.test_output
1225
+ FROM form_submissions s LEFT JOIN form_outbox o ON o.id=s.id AND o.tenant_id=s.tenant_id WHERE s.tenant_id=? AND s.mode='test' ORDER BY s.created_at DESC,s.id DESC LIMIT 200` : `SELECT l.id,l.name,l.email,l.phone,l.message,l.page_path,l.status,l.created_at,s.fields_json,o.status AS notification_status,o.last_error AS notification_error
1226
+ FROM leads l LEFT JOIN form_submissions s ON s.id=l.id AND s.tenant_id=l.tenant_id AND s.mode='live'
1227
+ LEFT JOIN form_outbox o ON o.id=s.id AND o.tenant_id=l.tenant_id WHERE l.tenant_id=? ORDER BY l.created_at DESC,l.id DESC LIMIT 200`;
1228
+ const stored = (await env.DB.prepare(sql).bind(tenant).all()).results;
1229
+ const rows2 = [];
1230
+ let size = 0;
1231
+ for (const row of stored) {
1232
+ size += new TextEncoder().encode(JSON.stringify(row)).length;
1233
+ if (size > 35e5) break;
1234
+ rows2.push(row);
1235
+ }
1236
+ return json2({ ...identity, source: "connected", mode: mode === "live" ? "production" : "test", writable: mode !== "test" && grant.scopes.includes("leads:write"), truncated: rows2.length < stored.length || stored.length === 200, rows: rows2 });
1237
+ }
1238
+ const days = Number(url.searchParams.get("days") || "30");
1239
+ if (!Number.isInteger(days) || days < 1 || days > 90) return json2({ error: "days must be 1\u201390" }, 400);
1240
+ const rows = (await env.DB.prepare(`WITH days AS (
1241
+ SELECT day FROM analytics_events WHERE tenant_id=? AND (src IS NULL OR src='' OR src='live')
1242
+ UNION SELECT substr(created_at,1,10) FROM leads WHERE tenant_id=?
1243
+ ) SELECT day,
1244
+ (SELECT COUNT(*) FROM analytics_events e WHERE e.tenant_id=? AND e.day=days.day AND e.kind='pageview' AND (e.src IS NULL OR e.src='' OR e.src='live')) AS views,
1245
+ (SELECT COUNT(DISTINCT vid) FROM analytics_events e WHERE e.tenant_id=? AND e.day=days.day AND e.kind='pageview' AND (e.src IS NULL OR e.src='' OR e.src='live')) AS visitors,
1246
+ (SELECT COUNT(*) FROM leads l WHERE l.tenant_id=? AND substr(l.created_at,1,10)=days.day) AS enquiries
1247
+ FROM days WHERE day>=date('now',?) AND day<=date('now') ORDER BY day`).bind(tenant, tenant, tenant, tenant, tenant, `-${days - 1} days`).all()).results;
1248
+ return json2({ ...identity, source: "connected", rows });
1249
+ }
1250
+
1251
+ // src/types.ts
1252
+ var defaultTheme = {
1253
+ colorBg: "#F7F4EF",
1254
+ colorText: "#1A1714",
1255
+ colorMuted: "#5C574F",
1256
+ colorAccent: "#B44A2C",
1257
+ colorAccentText: "#FFFFFF",
1258
+ colorSurface: "#FFFFFF",
1259
+ colorSurface2: "#EFEAE3",
1260
+ colorBorder: "#E4DDD2",
1261
+ colorFocus: "#B44A2C",
1262
+ fontBody: 'ui-sans-serif, system-ui, "Segoe UI", sans-serif',
1263
+ fontDisplay: "ui-serif, Georgia, 'Times New Roman', serif",
1264
+ radius: "8px",
1265
+ radiusLg: "16px",
1266
+ radiusPill: "999px",
1267
+ maxWidth: "1120px"
1268
+ };
1269
+
1270
+ // src/worker/tenant.ts
1271
+ async function tenantBySlug(env, slug) {
1272
+ return env.DB.prepare("SELECT * FROM tenants WHERE slug = ?").bind(slug).first();
1273
+ }
1274
+ async function tenantById(env, id) {
1275
+ return env.DB.prepare("SELECT * FROM tenants WHERE id = ?").bind(id).first();
1276
+ }
1277
+ async function tenantByHostname(env, hostname) {
1278
+ const cached = await env.KV.get(`host:${hostname}`);
1279
+ if (cached) return tenantById(env, cached);
1280
+ const row = await env.DB.prepare(
1281
+ `SELECT tenants.* FROM tenants JOIN hostnames ON hostnames.tenant_id = tenants.id WHERE hostnames.hostname = ?`
1282
+ ).bind(hostname.toLowerCase()).first();
1283
+ if (row) await env.KV.put(`host:${hostname}`, row.id, { expirationTtl: 3600 });
1284
+ return row;
1285
+ }
1286
+ async function loadSiteSnapshot(env, tenantId) {
1287
+ const siteRow = await env.DB.prepare("SELECT json FROM site_config WHERE tenant_id = ?").bind(tenantId).first();
1288
+ const contentRow = await env.DB.prepare("SELECT json FROM content WHERE tenant_id = ?").bind(tenantId).first();
1289
+ const themeRow = await env.DB.prepare("SELECT json FROM theme WHERE tenant_id = ?").bind(tenantId).first();
1290
+ if (!siteRow || !contentRow || !themeRow) return null;
1291
+ return {
1292
+ site: JSON.parse(siteRow.json),
1293
+ content: JSON.parse(contentRow.json),
1294
+ theme: { ...defaultTheme, ...JSON.parse(themeRow.json) }
1295
+ };
1296
+ }
1297
+ async function bumpVersion(env, tenantId) {
1298
+ const row = await env.DB.prepare(
1299
+ "UPDATE tenants SET content_version = content_version + 1 WHERE id = ? RETURNING content_version"
1300
+ ).bind(tenantId).first();
1301
+ return row?.content_version ?? 1;
1302
+ }
1303
+
1223
1304
  // src/worker/surfaces/api.ts
1224
1305
  var KINDS = /* @__PURE__ */ new Set(["pageview", "leave", "convert", "engage", "ping"]);
1225
1306
  var GOALS = /* @__PURE__ */ new Set(["form", "tel", "mailto", "maps"]);
@@ -23603,7 +23684,7 @@ async function renderPreview(env, request) {
23603
23684
  kernelOrigin: origin,
23604
23685
  themeHref: `${prefix}/theme.css`,
23605
23686
  assetsPrefix: prefix,
23606
- islandsHref: islands ? "/islands.js" : null
23687
+ islandsHref: null
23607
23688
  }) : renderDocument({
23608
23689
  site: bundle.site,
23609
23690
  page: page2,
@@ -23687,6 +23768,7 @@ async function route(env, request) {
23687
23768
  const path = url.pathname;
23688
23769
  if (isPreviewHost(env, request)) return handlePreview(env, request);
23689
23770
  if (path.startsWith("/preview/")) return previewHandoff(env, request);
23771
+ if (path.startsWith("/api/admin/")) return handleAdmin(env, request);
23690
23772
  const approve = await handleApproveReject(env, request);
23691
23773
  if (approve) return approve;
23692
23774
  const updatesApi = await handleUpdatesApi(env, request);
@@ -0,0 +1,3 @@
1
+ import type { AdminManifest } from '@tryvitris/website-admin-contracts';
2
+ /** Identity and response requirements of the published alpha adapter. */
3
+ export declare function readConnection(manifest: AdminManifest, token: string, resource: 'status' | 'leads' | 'analytics', test?: boolean, transport?: typeof fetch): Promise<any>;
@@ -0,0 +1,21 @@
1
+ import { type CommandResult } from './types.ts';
2
+ export declare const ADMIN_VERSION = "0.1.0-alpha.1";
3
+ export type AdminOptions = {
4
+ site?: string;
5
+ dir?: string;
6
+ domain?: string;
7
+ website?: string;
8
+ tenant?: string;
9
+ backendOrigin?: string;
10
+ plan?: boolean;
11
+ apply?: boolean;
12
+ leadWrite?: boolean;
13
+ dryRun?: boolean;
14
+ grants?: string;
15
+ out?: string;
16
+ };
17
+ /** Merge the operator's COMPLETE map, never replace unrelated installations. */
18
+ export declare function mergeAdminGrant(existing: unknown, addition: unknown): {
19
+ [x: string]: unknown;
20
+ };
21
+ export declare function adminCommand(command: string, options: AdminOptions): Promise<CommandResult>;
@@ -13,5 +13,5 @@ export { EXIT_CODES, type ExitCode, type CommandResult, type OutputMode, type Vi
13
13
  export { migrateSite } from "./site-migrate.ts";
14
14
  export { inspectSite, prepareChange, applyOperations, buildSiteDraft, verifyChange, discardChange } from "../engine/index.ts";
15
15
  export { upgradeSite, type UpgradeOptions } from "./upgrade.ts";
16
- export { prepareVerifiedRelease, deployVerifiedArtifact } from "../integrations/hosting.ts";
16
+ export { prepareVerifiedRelease, prepareQuickRelease, deployVerifiedArtifact } from "../integrations/hosting.ts";
17
17
  export { runPreserve } from "./preserve.ts";
@@ -5,6 +5,7 @@ export type DeployOptions = {
5
5
  environment?: "preview" | "production";
6
6
  branch?: string;
7
7
  dryRun?: boolean;
8
+ quick?: boolean;
8
9
  signal?: AbortSignal;
9
10
  onLog?: (line: string) => void;
10
11
  };
@@ -17,5 +18,6 @@ export type DeployResultData = {
17
18
  status: number;
18
19
  message: string;
19
20
  };
21
+ verification: "full" | "build-only";
20
22
  };
21
23
  export declare function deploySite(opts?: DeployOptions): Promise<CommandResult<DeployResultData>>;
@@ -1,4 +1,5 @@
1
1
  import { type CommandResult } from "./types.ts";
2
+ export declare function hasAuthenticatedWranglerSession(status: number | null, stdout: string): boolean;
2
3
  export type DoctorOptions = {
3
4
  site?: string;
4
5
  provider?: string;
@@ -4,6 +4,8 @@ export type CreateSiteOptions = SiteInputOptions & {
4
4
  dir: string;
5
5
  slug: string;
6
6
  name?: string;
7
+ /** Opt-in instructions only; never provision during site creation. */
8
+ admin?: boolean;
7
9
  from?: string;
8
10
  mode?: "redesign" | "preserve";
9
11
  blank?: boolean;
@@ -32,7 +32,7 @@ export declare function compileSite(opts: {
32
32
  js: string | null;
33
33
  }>;
34
34
  webAnalyticsToken?: string;
35
- }): {
35
+ }, preparedPages?: CompiledPage[]): {
36
36
  path: string;
37
37
  html: string;
38
38
  }[];
@@ -27,6 +27,8 @@ export interface HostingAdapter {
27
27
  rollback?(deploymentId: string): Promise<DeploymentReceipt>;
28
28
  }
29
29
  export declare function prepareVerifiedRelease(siteRoot: string, environment?: "preview" | "production"): Promise<VerifiedArtifact>;
30
+ /** Explicit build-only release: policyId records that review gates were skipped. */
31
+ export declare function prepareQuickRelease(siteRoot: string, environment?: "preview" | "production"): Promise<VerifiedArtifact>;
30
32
  export declare function deployVerifiedArtifact(siteRoot: string, artifact: VerifiedArtifact, adapter: HostingAdapter): Promise<{
31
33
  release: ReleaseRecord;
32
34
  deployment: DeploymentReceipt;
package/bin/vitris-art.js CHANGED
@@ -12,8 +12,8 @@ import {
12
12
  retireProducedAsset,
13
13
  validateAssetProduction,
14
14
  withMutationLock
15
- } from "./chunks/chunk-FRABKM65.js";
16
- import "./chunks/chunk-DSS2U2OM.js";
15
+ } from "./chunks/chunk-XY73ZLHB.js";
16
+ import "./chunks/chunk-KVMZSQ3D.js";
17
17
  import "./chunks/chunk-WOORR67N.js";
18
18
  import "./chunks/chunk-PRLL7B63.js";
19
19
  import "./chunks/chunk-5JTBC6UK.js";
@@ -33,9 +33,9 @@ import "./chunks/chunk-IKNMBGGD.js";
33
33
  import "./chunks/chunk-WEFDVXFX.js";
34
34
  import {
35
35
  findHarnessRoot
36
- } from "./chunks/chunk-VTI32UGJ.js";
37
- import "./chunks/chunk-4MFPATAB.js";
38
- import "./chunks/chunk-ZIROO2U4.js";
36
+ } from "./chunks/chunk-H3BS2EBR.js";
37
+ import "./chunks/chunk-L44ZTNDM.js";
38
+ import "./chunks/chunk-37F7XIMH.js";
39
39
  import "./chunks/chunk-LKN75JGA.js";
40
40
  import "./chunks/chunk-YYPYYOEV.js";
41
41
  import "./chunks/chunk-GZDLXYZV.js";
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildVerified
4
- } from "./chunks/chunk-VTI32UGJ.js";
5
- import "./chunks/chunk-4MFPATAB.js";
6
- import "./chunks/chunk-ZIROO2U4.js";
4
+ } from "./chunks/chunk-H3BS2EBR.js";
5
+ import "./chunks/chunk-L44ZTNDM.js";
6
+ import "./chunks/chunk-37F7XIMH.js";
7
7
  import "./chunks/chunk-LKN75JGA.js";
8
8
  import "./chunks/chunk-YYPYYOEV.js";
9
9
  import "./chunks/chunk-GZDLXYZV.js";
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createSite
4
- } from "./chunks/chunk-H7Y72HXC.js";
4
+ } from "./chunks/chunk-UFTVWTEZ.js";
5
5
  import "./chunks/chunk-34H54KEY.js";
6
6
  import "./chunks/chunk-JCRGE6AL.js";
7
7
  import {
8
8
  promptSourceUrl
9
- } from "./chunks/chunk-5YSPWKFF.js";
9
+ } from "./chunks/chunk-PYCRUMCT.js";
10
10
  import "./chunks/chunk-XGTHGWPW.js";
11
11
  import {
12
12
  siteInputsFromArgv
13
- } from "./chunks/chunk-FRABKM65.js";
14
- import "./chunks/chunk-DSS2U2OM.js";
13
+ } from "./chunks/chunk-XY73ZLHB.js";
14
+ import "./chunks/chunk-KVMZSQ3D.js";
15
15
  import "./chunks/chunk-WOORR67N.js";
16
16
  import "./chunks/chunk-PRLL7B63.js";
17
17
  import "./chunks/chunk-5JTBC6UK.js";
@@ -24,9 +24,9 @@ import "./chunks/chunk-AUO5I56E.js";
24
24
  import "./chunks/chunk-BIEDSEL2.js";
25
25
  import "./chunks/chunk-IKNMBGGD.js";
26
26
  import "./chunks/chunk-WEFDVXFX.js";
27
- import "./chunks/chunk-VTI32UGJ.js";
28
- import "./chunks/chunk-4MFPATAB.js";
29
- import "./chunks/chunk-ZIROO2U4.js";
27
+ import "./chunks/chunk-H3BS2EBR.js";
28
+ import "./chunks/chunk-L44ZTNDM.js";
29
+ import "./chunks/chunk-37F7XIMH.js";
30
30
  import "./chunks/chunk-LKN75JGA.js";
31
31
  import "./chunks/chunk-YYPYYOEV.js";
32
32
  import "./chunks/chunk-GZDLXYZV.js";
@@ -41,6 +41,7 @@ var arg = (flag) => {
41
41
  };
42
42
  var usage = `Usage: vitris-create-site --dir ../acme --slug acme [--name "Acme Shop"] [--from URL | --blank]
43
43
  --owner EMAIL Owner login email
44
+ --admin Prepare optional sibling admin instructions (no cloud writes)
44
45
  --template ID Catalog ID, name, or hosted template URL; continue automatically
45
46
  --template-release R Optional catalog revision
46
47
  --content TEXT Additional business content or instructions
@@ -67,6 +68,7 @@ async function main() {
67
68
  blank,
68
69
  ...siteInputsFromArgv(process.argv),
69
70
  mode: arg("--mode"),
71
+ admin: process.argv.includes("--admin"),
70
72
  owner: arg("--owner"),
71
73
  backendOrigin: arg("--backend-origin") || arg("--kernel-origin"),
72
74
  harnessSpec: arg("--harness") || arg("--kernel")
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleCursorHook
4
- } from "./chunks/chunk-FRABKM65.js";
5
- import "./chunks/chunk-DSS2U2OM.js";
4
+ } from "./chunks/chunk-XY73ZLHB.js";
5
+ import "./chunks/chunk-KVMZSQ3D.js";
6
6
  import "./chunks/chunk-WOORR67N.js";
7
7
  import "./chunks/chunk-PRLL7B63.js";
8
8
  import "./chunks/chunk-5JTBC6UK.js";
@@ -15,9 +15,9 @@ import "./chunks/chunk-AUO5I56E.js";
15
15
  import "./chunks/chunk-BIEDSEL2.js";
16
16
  import "./chunks/chunk-IKNMBGGD.js";
17
17
  import "./chunks/chunk-WEFDVXFX.js";
18
- import "./chunks/chunk-VTI32UGJ.js";
19
- import "./chunks/chunk-4MFPATAB.js";
20
- import "./chunks/chunk-ZIROO2U4.js";
18
+ import "./chunks/chunk-H3BS2EBR.js";
19
+ import "./chunks/chunk-L44ZTNDM.js";
20
+ import "./chunks/chunk-37F7XIMH.js";
21
21
  import "./chunks/chunk-LKN75JGA.js";
22
22
  import "./chunks/chunk-YYPYYOEV.js";
23
23
  import "./chunks/chunk-GZDLXYZV.js";
@@ -3,8 +3,8 @@ import {
3
3
  gradeAll,
4
4
  gradeNode,
5
5
  reviewSubject
6
- } from "./chunks/chunk-FRABKM65.js";
7
- import "./chunks/chunk-DSS2U2OM.js";
6
+ } from "./chunks/chunk-XY73ZLHB.js";
7
+ import "./chunks/chunk-KVMZSQ3D.js";
8
8
  import "./chunks/chunk-WOORR67N.js";
9
9
  import "./chunks/chunk-PRLL7B63.js";
10
10
  import "./chunks/chunk-5JTBC6UK.js";
@@ -17,9 +17,9 @@ import "./chunks/chunk-AUO5I56E.js";
17
17
  import "./chunks/chunk-BIEDSEL2.js";
18
18
  import "./chunks/chunk-IKNMBGGD.js";
19
19
  import "./chunks/chunk-WEFDVXFX.js";
20
- import "./chunks/chunk-VTI32UGJ.js";
21
- import "./chunks/chunk-4MFPATAB.js";
22
- import "./chunks/chunk-ZIROO2U4.js";
20
+ import "./chunks/chunk-H3BS2EBR.js";
21
+ import "./chunks/chunk-L44ZTNDM.js";
22
+ import "./chunks/chunk-37F7XIMH.js";
23
23
  import "./chunks/chunk-LKN75JGA.js";
24
24
  import "./chunks/chunk-YYPYYOEV.js";
25
25
  import "./chunks/chunk-GZDLXYZV.js";
@@ -44,7 +44,7 @@ if (paths.length) {
44
44
  } else if (process.argv.includes("--expand-packet")) {
45
45
  const expId = arg("--expand-packet");
46
46
  const manifestHash = arg("--manifest-hash");
47
- const { expandPacketItem } = await import("./chunks/packets-QOLWPRNV.js");
47
+ const { expandPacketItem } = await import("./chunks/packets-LBMDIFPO.js");
48
48
  console.log(expandPacketItem(root, node || "business-review", expId, manifestHash));
49
49
  } else if (process.argv.includes("--expand-design-context")) {
50
50
  const preparationId = arg("--preparation");
@@ -52,7 +52,7 @@ if (paths.length) {
52
52
  if (!preparationId || !expansionId || expansionId.startsWith("--")) {
53
53
  throw new Error("Use --expand-design-context <ID> --preparation <PREP_ID> [--site PATH]");
54
54
  }
55
- const { expandDesignContextForPreparation } = await import("./chunks/design-context-store-DCZOAK56.js");
55
+ const { expandDesignContextForPreparation } = await import("./chunks/design-context-store-W3VTZ4HA.js");
56
56
  const result = expandDesignContextForPreparation(root, preparationId, expansionId);
57
57
  if (!result.ok) {
58
58
  console.error(result.reason);
package/bin/vitris-go.js CHANGED
@@ -7,8 +7,8 @@ import {
7
7
  runCreativeProfile,
8
8
  runSite,
9
9
  statusSite
10
- } from "./chunks/chunk-7V3OKLKH.js";
11
- import "./chunks/chunk-QRWGFLUU.js";
10
+ } from "./chunks/chunk-LZC37OJZ.js";
11
+ import "./chunks/chunk-R2WRQDVE.js";
12
12
  import "./chunks/chunk-34H54KEY.js";
13
13
  import "./chunks/chunk-JCRGE6AL.js";
14
14
  import "./chunks/chunk-XL2DRAYI.js";
@@ -19,8 +19,8 @@ import {
19
19
  resolveSiteInputsLive,
20
20
  runWorkflow,
21
21
  siteInputsFromArgv
22
- } from "./chunks/chunk-FRABKM65.js";
23
- import "./chunks/chunk-DSS2U2OM.js";
22
+ } from "./chunks/chunk-XY73ZLHB.js";
23
+ import "./chunks/chunk-KVMZSQ3D.js";
24
24
  import "./chunks/chunk-WOORR67N.js";
25
25
  import "./chunks/chunk-PRLL7B63.js";
26
26
  import "./chunks/chunk-5JTBC6UK.js";
@@ -35,9 +35,9 @@ import "./chunks/chunk-IKNMBGGD.js";
35
35
  import "./chunks/chunk-WEFDVXFX.js";
36
36
  import {
37
37
  isPreserveSite
38
- } from "./chunks/chunk-VTI32UGJ.js";
39
- import "./chunks/chunk-4MFPATAB.js";
40
- import "./chunks/chunk-ZIROO2U4.js";
38
+ } from "./chunks/chunk-H3BS2EBR.js";
39
+ import "./chunks/chunk-L44ZTNDM.js";
40
+ import "./chunks/chunk-37F7XIMH.js";
41
41
  import "./chunks/chunk-LKN75JGA.js";
42
42
  import "./chunks/chunk-YYPYYOEV.js";
43
43
  import "./chunks/chunk-GZDLXYZV.js";
@@ -3,14 +3,14 @@ import {
3
3
  gatherOnboard,
4
4
  normalizeSourceUrl,
5
5
  persistOnboard
6
- } from "./chunks/chunk-5YSPWKFF.js";
6
+ } from "./chunks/chunk-PYCRUMCT.js";
7
7
  import {
8
8
  loadDevVars
9
9
  } from "./chunks/chunk-XGTHGWPW.js";
10
10
  import {
11
11
  gradeHarvest
12
- } from "./chunks/chunk-FRABKM65.js";
13
- import "./chunks/chunk-DSS2U2OM.js";
12
+ } from "./chunks/chunk-XY73ZLHB.js";
13
+ import "./chunks/chunk-KVMZSQ3D.js";
14
14
  import "./chunks/chunk-WOORR67N.js";
15
15
  import "./chunks/chunk-PRLL7B63.js";
16
16
  import "./chunks/chunk-5JTBC6UK.js";
@@ -23,9 +23,9 @@ import "./chunks/chunk-AUO5I56E.js";
23
23
  import "./chunks/chunk-BIEDSEL2.js";
24
24
  import "./chunks/chunk-IKNMBGGD.js";
25
25
  import "./chunks/chunk-WEFDVXFX.js";
26
- import "./chunks/chunk-VTI32UGJ.js";
27
- import "./chunks/chunk-4MFPATAB.js";
28
- import "./chunks/chunk-ZIROO2U4.js";
26
+ import "./chunks/chunk-H3BS2EBR.js";
27
+ import "./chunks/chunk-L44ZTNDM.js";
28
+ import "./chunks/chunk-37F7XIMH.js";
29
29
  import "./chunks/chunk-LKN75JGA.js";
30
30
  import "./chunks/chunk-YYPYYOEV.js";
31
31
  import "./chunks/chunk-GZDLXYZV.js";
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  explainStage
4
- } from "./chunks/chunk-TTAUU3AZ.js";
5
- import "./chunks/chunk-FRABKM65.js";
6
- import "./chunks/chunk-DSS2U2OM.js";
4
+ } from "./chunks/chunk-3OKR5AZJ.js";
5
+ import "./chunks/chunk-XY73ZLHB.js";
6
+ import "./chunks/chunk-KVMZSQ3D.js";
7
7
  import "./chunks/chunk-WOORR67N.js";
8
8
  import "./chunks/chunk-PRLL7B63.js";
9
9
  import "./chunks/chunk-5JTBC6UK.js";
@@ -16,9 +16,9 @@ import "./chunks/chunk-AUO5I56E.js";
16
16
  import "./chunks/chunk-BIEDSEL2.js";
17
17
  import "./chunks/chunk-IKNMBGGD.js";
18
18
  import "./chunks/chunk-WEFDVXFX.js";
19
- import "./chunks/chunk-VTI32UGJ.js";
20
- import "./chunks/chunk-4MFPATAB.js";
21
- import "./chunks/chunk-ZIROO2U4.js";
19
+ import "./chunks/chunk-H3BS2EBR.js";
20
+ import "./chunks/chunk-L44ZTNDM.js";
21
+ import "./chunks/chunk-37F7XIMH.js";
22
22
  import "./chunks/chunk-LKN75JGA.js";
23
23
  import "./chunks/chunk-YYPYYOEV.js";
24
24
  import "./chunks/chunk-GZDLXYZV.js";
@@ -10,8 +10,8 @@ import {
10
10
  } from "./chunks/chunk-XL2DRAYI.js";
11
11
  import {
12
12
  templateAdaptationFailures
13
- } from "./chunks/chunk-FRABKM65.js";
14
- import "./chunks/chunk-DSS2U2OM.js";
13
+ } from "./chunks/chunk-XY73ZLHB.js";
14
+ import "./chunks/chunk-KVMZSQ3D.js";
15
15
  import "./chunks/chunk-WOORR67N.js";
16
16
  import "./chunks/chunk-PRLL7B63.js";
17
17
  import "./chunks/chunk-5JTBC6UK.js";
@@ -30,12 +30,12 @@ import {
30
30
  performancePolicy
31
31
  } from "./chunks/chunk-IKNMBGGD.js";
32
32
  import "./chunks/chunk-WEFDVXFX.js";
33
- import "./chunks/chunk-VTI32UGJ.js";
34
- import "./chunks/chunk-4MFPATAB.js";
33
+ import "./chunks/chunk-H3BS2EBR.js";
34
+ import "./chunks/chunk-L44ZTNDM.js";
35
35
  import {
36
36
  COOKIE_COMPLIANCE_PATH,
37
37
  parseFrontmatter
38
- } from "./chunks/chunk-ZIROO2U4.js";
38
+ } from "./chunks/chunk-37F7XIMH.js";
39
39
  import "./chunks/chunk-LKN75JGA.js";
40
40
  import "./chunks/chunk-YYPYYOEV.js";
41
41
  import "./chunks/chunk-GZDLXYZV.js";
@@ -3,8 +3,8 @@ import {
3
3
  TEMPLATE_MOTION_PATH,
4
4
  currentSelectionHash,
5
5
  templateMotionHash
6
- } from "./chunks/chunk-FRABKM65.js";
7
- import "./chunks/chunk-DSS2U2OM.js";
6
+ } from "./chunks/chunk-XY73ZLHB.js";
7
+ import "./chunks/chunk-KVMZSQ3D.js";
8
8
  import "./chunks/chunk-WOORR67N.js";
9
9
  import "./chunks/chunk-PRLL7B63.js";
10
10
  import "./chunks/chunk-5JTBC6UK.js";
@@ -19,9 +19,9 @@ import "./chunks/chunk-IKNMBGGD.js";
19
19
  import {
20
20
  previewServer
21
21
  } from "./chunks/chunk-WEFDVXFX.js";
22
- import "./chunks/chunk-VTI32UGJ.js";
23
- import "./chunks/chunk-4MFPATAB.js";
24
- import "./chunks/chunk-ZIROO2U4.js";
22
+ import "./chunks/chunk-H3BS2EBR.js";
23
+ import "./chunks/chunk-L44ZTNDM.js";
24
+ import "./chunks/chunk-37F7XIMH.js";
25
25
  import "./chunks/chunk-LKN75JGA.js";
26
26
  import "./chunks/chunk-YYPYYOEV.js";
27
27
  import "./chunks/chunk-GZDLXYZV.js";
@@ -17,9 +17,9 @@ import {
17
17
  } from "./chunks/chunk-WEFDVXFX.js";
18
18
  import {
19
19
  buildVerified
20
- } from "./chunks/chunk-VTI32UGJ.js";
21
- import "./chunks/chunk-4MFPATAB.js";
22
- import "./chunks/chunk-ZIROO2U4.js";
20
+ } from "./chunks/chunk-H3BS2EBR.js";
21
+ import "./chunks/chunk-L44ZTNDM.js";
22
+ import "./chunks/chunk-37F7XIMH.js";
23
23
  import "./chunks/chunk-LKN75JGA.js";
24
24
  import "./chunks/chunk-YYPYYOEV.js";
25
25
  import "./chunks/chunk-GZDLXYZV.js";