@vectoriox/iox-ui 5.54.0 → 5.56.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.
@@ -1,4 +1,4 @@
1
- import { DesignChoices, AnimateId } from '@vectoriox/iox-ui/design-core';
1
+ import { DesignChoices, AnimateId, DesignTokenLike } from '@vectoriox/iox-ui/design-core';
2
2
 
3
3
  declare const SPEC_SITE_PLAN_SHAPE: {
4
4
  readonly plan: {
@@ -2331,6 +2331,52 @@ declare class PathIssueCollector<C extends string> {
2331
2331
  unique(values: Array<string | null>, path: (i: number) => string, what: string): void;
2332
2332
  }
2333
2333
 
2334
+ /**
2335
+ * The ONE set of builders every structured-output format is written with (AI plan §3c, M0-5 / M1-1 / M1-3 / M1-5):
2336
+ * the SiteAnalysis, the reading, the Site Plan and the plan edits. Each object is built FROM a documented shape table
2337
+ * (`shape-check`): its keys are the table's keys, the required ones are the table's required ones, each described in
2338
+ * the table's own words — and a builder handed a key list that disagrees with its table THROWS, so a shape that gains
2339
+ * a key cannot ship a format that silently lacks it. The subset is the strictest both providers' native strict modes
2340
+ * accept (Anthropic `output_config.format`, OpenRouter `json_schema` + `strict`): every object closed
2341
+ * (`additionalProperties: false`), unions as `anyOf`, single values as a one-entry `enum`, no length / count / number
2342
+ * bounds, no `$ref`. The format is a hint the provider enforces; the shared validator stays the gate.
2343
+ */
2344
+ type JsonSchema = {
2345
+ [key: string]: unknown;
2346
+ };
2347
+ declare class JsonSchemaShapeError extends Error {
2348
+ }
2349
+ declare const jsonText: () => JsonSchema;
2350
+ declare const jsonBoolean: () => JsonSchema;
2351
+ declare const jsonInteger: () => JsonSchema;
2352
+ declare const jsonOneOf: (values: ReadonlyArray<string>) => JsonSchema;
2353
+ declare const jsonListOf: (items: JsonSchema) => JsonSchema;
2354
+ declare const jsonAnyOf: (options: ReadonlyArray<JsonSchema>) => JsonSchema;
2355
+ /** A closed object with exactly these properties. */
2356
+ declare function jsonClosedObject(properties: Record<string, JsonSchema>, required: ReadonlyArray<string>, description?: string): JsonSchema;
2357
+ /** The table's own words for a key (`key` or `key?`). */
2358
+ declare function describeShapeKey(entry: ShapeEntry, key: string): string;
2359
+ /** An entry's `[name]` keys (the object's own field names) written as ONE list on the wire — no strict mode can say
2360
+ * "any key", so the map travels as `[{ name, value }]` under `key` and the decoder turns it back. */
2361
+ interface DynamicKeysAsList {
2362
+ /** The wire key holding the list. */
2363
+ key: string;
2364
+ /** The list's schema. */
2365
+ schema: JsonSchema;
2366
+ }
2367
+ /**
2368
+ * An object of one shape-table entry: exactly its fixed keys, its required keys required, each described by the
2369
+ * table; an entry's `[name]` keys are not object keys — `dynamic` writes them as one list. Throws when the properties
2370
+ * given are not the table's keys.
2371
+ */
2372
+ declare function jsonShapedObject(entry: ShapeEntry, properties: Record<string, JsonSchema>, name?: string, dynamic?: DynamicKeysAsList): JsonSchema;
2373
+ /** Every keyword a schema uses — what a spec checks against the strict subset. */
2374
+ declare function jsonSchemaKeywords(node: unknown, out?: Set<string>): Set<string>;
2375
+ /** The keywords the strict subset never uses. */
2376
+ declare const JSON_SCHEMA_BANNED_KEYWORDS: ReadonlyArray<string>;
2377
+ /** Every object node of a schema (through properties, items and anyOf). */
2378
+ declare function jsonSchemaObjects(node: unknown, out?: JsonSchema[]): JsonSchema[];
2379
+
2334
2380
  /**
2335
2381
  * The Site Plan validator — the gate in front of the composer. The wizard's plan and (later) the AI's
2336
2382
  * plan go through the SAME checks: an unknown pattern, a slot the pattern does not declare, a source
@@ -2838,6 +2884,8 @@ declare enum BuildStep {
2838
2884
  Preflight = "preflight",
2839
2885
  ContentTypes = "content-types",
2840
2886
  SampleImages = "sample-images",
2887
+ /** I2: the curated stock photos the plan's empty picture slots take, copied into the studio (never hot-linked). */
2888
+ StockPhotos = "stock-photos",
2841
2889
  Items = "items",
2842
2890
  DataSources = "data-sources",
2843
2891
  Pages = "pages",
@@ -2857,6 +2905,8 @@ declare enum CreatedKind {
2857
2905
  /** Fields the build added to a content type it found (types are shared by every organization of a studio). */
2858
2906
  ContentTypeFields = "content-type-fields",
2859
2907
  SampleImage = "sample-image",
2908
+ /** A stock photo copied into the studio's storage (`media/stock/…`), with its assets row. */
2909
+ StockPhoto = "stock-photo",
2860
2910
  Item = "item",
2861
2911
  DataSource = "data-source",
2862
2912
  Page = "page",
@@ -2918,7 +2968,9 @@ declare enum BuildNoticeCode {
2918
2968
  /** Storage is not configured: sample items get the empty image box, and the run says so. */
2919
2969
  NoStorage = "no-storage",
2920
2970
  /** A content type the build reuses is not public in this studio: the site will not show its items. */
2921
- ContentTypeNotPublic = "content-type-not-public"
2971
+ ContentTypeNotPublic = "content-type-not-public",
2972
+ /** The stock library could not be read: the picture slots keep the empty box, and the run says so. */
2973
+ StockUnavailable = "stock-unavailable"
2922
2974
  }
2923
2975
  interface BuildNotice {
2924
2976
  code: string;
@@ -2988,6 +3040,7 @@ declare const buildKeys: {
2988
3040
  readonly contentTypeFields: (name: string) => string;
2989
3041
  readonly item: (contentType: string, n: number) => string;
2990
3042
  readonly sampleImage: (n: number) => string;
3043
+ readonly stockPhoto: (libraryKey: string) => string;
2991
3044
  readonly dataSource: (alias: string) => string;
2992
3045
  readonly page: (key: string) => string;
2993
3046
  readonly global: (nodeId: string) => string;
@@ -3052,6 +3105,8 @@ declare enum AiStep {
3052
3105
  NameStructures = "scanNaming"
3053
3106
  }
3054
3107
  declare const AI_STEPS: ReadonlyArray<AiStep>;
3108
+ /** Each step's name on the wire (the control plane's `label`, the console) — the screens translate their own. */
3109
+ declare const AI_STEP_LABELS: Readonly<Record<AiStep, string>>;
3055
3110
  /** What a model must be able to do for a step to run on it. */
3056
3111
  declare enum AiCapability {
3057
3112
  StructuredOutput = "structuredOutputs",
@@ -3069,6 +3124,8 @@ interface AiTokenCounts {
3069
3124
  cacheWrite: number;
3070
3125
  /** Read from the prompt cache (priced well below input). */
3071
3126
  cacheRead: number;
3127
+ /** Image tokens written (a picture step) — priced at `imageOutput`. */
3128
+ imageOutput?: number;
3072
3129
  }
3073
3130
  /** US dollars per million tokens, per class. A class without a price is priced as input. */
3074
3131
  interface AiTokenPrice {
@@ -3076,6 +3133,8 @@ interface AiTokenPrice {
3076
3133
  output: number;
3077
3134
  cacheWrite?: number;
3078
3135
  cacheRead?: number;
3136
+ /** Image-output tokens; a model without the price is priced at `output`. */
3137
+ imageOutput?: number;
3079
3138
  }
3080
3139
  /** A model of the vetted list (served by the control plane with the entitlements, §3n) — its price travels with it. */
3081
3140
  interface AiModelEntry {
@@ -3173,5 +3232,465 @@ declare enum AiCallStatus {
3173
3232
  Interrupted = "interrupted"
3174
3233
  }
3175
3234
 
3176
- export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_NEEDS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiGenerationStage, AiKeyMode, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CREDITS_PER_USD, CardBindTarget, ComposeError, ComposeIssueCode, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, FACT_KEYS, FINAL_GENERATION_STAGES, GlobalSlot, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PageDataKind, PathIssueCollector, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanDataSourceMode, PlanDataSourceType, PreflightRefusalCode, RelativeOp, SAMPLE_IMAGE_REF, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_FACTS, SPEC_SITE_LIBRARY, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_TEMPLATES, STUDIO_TEMPLATE, SiteBuildKind, SiteBuildStatus, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, StepState, addBarItem, altSourceScopes, assertStyleSlots, assertValidSitePlan, barIconForRoute, blocksPublish, buildKeys, buildStepFacts, builtHomePageId, composeNavHeader, composeSection, composeSite, costUsd, createSerializedNode, creditsOfUsd, describePlanData, entranceAction, entranceInteraction, estimateStepCredits, failedBuildStep, findNavRoot, isActiveBuild, isNonEmptyString, isPlainObject, modelCanDo, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, parseSampleImageRef, pathAt, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, phoneMenuPages, planFromTemplate, planNavShape, releasedLayoutDefaults, removeBarItem, requiredShapeKeys, routeParams, sampleImageRef, sectionEntrances, setStyleProps, shapeKeys, siteNavPages, staggerDelay, validateSitePlan, walkSerialized };
3177
- export type { AddBarItemResult, AiMeter, AiModelEntry, AiRefusal, AiTokenCounts, AiTokenPrice, BarItemsEditResult, BuildNotice, BuildStepError, BuildStepFacts, BuildStepRecord, CmsDataSourcePlan, ComposeContext, ComposeIssue, ComposedDataSource, ComposedItem, ComposedNavHeader, ComposedPage, ComposedPlaceholder, ComposedRoute, ComposedSection, ComposedSite, ContentFieldPlan, ContentSeedPlan, ContentTypePlan, CreateNodeOptions, CreatedRecord, DataSourcePlan, EntranceAction, EntranceInteraction, EntranceSpec, FactKey, NavHeaderInput, NavHeaderOptions, NavPage, NavShapeOptions, NavShapeResult, NodeBaseline, PageData, PageDataLine, PagePlan, PageSectionPlan, PathIssue, PatternNode, PlainObject, PreflightRefusal, RelativeDataSourcePlan, SectionEntrances, SectionInput, SectionOptions, SerializedBinding, SerializedNode, SerializedResponsive, ShapeEntry, ShapeIssueCodes, SiteBuildRun, SiteBusiness, SitePageRef, SitePattern, SitePlan, SitePlanIssue, SitePlanSource, SitePlanValidation, SiteTemplate, TemplatePlanInput, UndoKept, UndoPreview, UndoRecord };
3235
+ /**
3236
+ * The structured-output format a model writes a Site Plan in (AI plan §3d step 4, M1-3) — built from the SAME shape
3237
+ * table `validateSitePlan` reads (`SPEC_SITE_PLAN_SHAPE`) and the SAME pattern library, so the plan a model is told
3238
+ * about is the plan the gate refuses. ONE source: a key the table gains breaks this builder until it is written here.
3239
+ *
3240
+ * Two maps of the shape are written as LISTS on the wire, because no strict mode can say "any key": a section's
3241
+ * `slots` (`[{ slot, text }]`, the slot names closed per pattern) and a seed's field values (`values: [{ field,
3242
+ * value }]`). `sitePlanFromWire` turns them back; nothing else differs. Every section is one `anyOf` branch per
3243
+ * pattern — its id, its declared slots, its optional parts, a binding only when it takes one — and the design, the
3244
+ * source and the version are PINNED to the owner's pick and this run (one-value enums), so the provider cannot let
3245
+ * a model change the look. The gate still checks both (`plan.design` deep-equals the pick).
3246
+ */
3247
+ declare const SITE_PLAN_SCHEMA_NAME = "site_plan";
3248
+ /** The wire keys of the two maps written as lists. */
3249
+ declare enum SitePlanWireKey {
3250
+ SlotName = "slot",
3251
+ SlotText = "text",
3252
+ SeedValues = "values",
3253
+ SeedField = "field",
3254
+ SeedValue = "value"
3255
+ }
3256
+ interface SitePlanSchemaPin {
3257
+ /** The owner's pick, verbatim — every design key becomes a one-value enum. */
3258
+ design: DesignChoices;
3259
+ /** This generation. */
3260
+ source: SitePlanSource;
3261
+ }
3262
+ /** A content type's field. */
3263
+ declare function fieldJsonSchema(): JsonSchema;
3264
+ /** A content type, its seed's field values as a list (`values: [{ field, value }]`). */
3265
+ declare function contentTypeJsonSchema(): JsonSchema;
3266
+ /** A data source: a cms list / single item, or a relative one. */
3267
+ declare function dataSourceJsonSchema(): JsonSchema;
3268
+ /** The patterns a page section may use (every non-global one), in library order. */
3269
+ declare function sectionPatternIds(): string[];
3270
+ /** A page section: one branch per pattern. */
3271
+ declare function sectionJsonSchema(): JsonSchema;
3272
+ /** A page. */
3273
+ declare function pageJsonSchema(): JsonSchema;
3274
+ /** The Site Plan format, pinned to the owner's pick and this run. */
3275
+ declare function sitePlanJsonSchema(pin: SitePlanSchemaPin): JsonSchema;
3276
+ /** A section off the wire: its slots back to a map; a key the pattern has nothing for (`{}`) dropped. */
3277
+ declare function sectionFromWire(section: unknown): unknown;
3278
+ /** A content type off the wire: its seed's `values` list back to field keys. */
3279
+ declare function contentTypeFromWire(type: unknown): unknown;
3280
+ /**
3281
+ * A model's answer → a Site Plan: the two listed maps back to maps, nothing else touched. Never repairs — whatever the
3282
+ * answer got wrong is still wrong, for `validateSitePlan` to refuse with a path.
3283
+ */
3284
+ declare function sitePlanFromWire(wire: unknown): SitePlan | unknown;
3285
+ /** The plan → the wire (what a re-ask shows the model, and what the plan edits' prompt carries). */
3286
+ declare function sitePlanToWire(plan: SitePlan): PlainObject;
3287
+
3288
+ /**
3289
+ * Changing a plan by sentence (AI plan §3d "The Plan prompt box", M1-5; reused by M2 after a build): the CLOSED list
3290
+ * of operations (N-D6) a model may write against the current plan, and the ONE pure `applyPlanEdits` that carries them
3291
+ * out. Nothing is written until Build, so an edit is a plan → plan function; the result goes through
3292
+ * `validateSitePlan` like any plan. Pages are named by `key`, sections by their index on the page. A set of edits is
3293
+ * applied whole or not at all: one edit that cannot apply refuses the set, with a path, and the plan is unchanged.
3294
+ */
3295
+ declare enum PlanEditOp {
3296
+ AddPage = "addPage",
3297
+ RemovePage = "removePage",
3298
+ RenamePage = "renamePage",
3299
+ MergePages = "mergePages",
3300
+ /** Its place in the menu (the plan's page order). */
3301
+ MovePage = "movePage",
3302
+ AddSection = "addSection",
3303
+ RemoveSection = "removeSection",
3304
+ MoveSection = "moveSection",
3305
+ SwapPattern = "swapPattern",
3306
+ SetSlot = "setSlot",
3307
+ AddContentType = "addContentType",
3308
+ AddField = "addField",
3309
+ SetSectionData = "setSectionData"
3310
+ }
3311
+ type PlanEdit = {
3312
+ op: `${PlanEditOp.AddPage}`;
3313
+ page: PagePlan;
3314
+ after?: string;
3315
+ } | {
3316
+ op: `${PlanEditOp.RemovePage}`;
3317
+ page: string;
3318
+ } | {
3319
+ op: `${PlanEditOp.RenamePage}`;
3320
+ page: string;
3321
+ name?: string;
3322
+ route?: string;
3323
+ } | {
3324
+ op: `${PlanEditOp.MergePages}`;
3325
+ into: string;
3326
+ from: string;
3327
+ } | {
3328
+ op: `${PlanEditOp.MovePage}`;
3329
+ page: string;
3330
+ to: number;
3331
+ } | {
3332
+ op: `${PlanEditOp.AddSection}`;
3333
+ page: string;
3334
+ section: PageSectionPlan;
3335
+ at?: number;
3336
+ } | {
3337
+ op: `${PlanEditOp.RemoveSection}`;
3338
+ page: string;
3339
+ index: number;
3340
+ } | {
3341
+ op: `${PlanEditOp.MoveSection}`;
3342
+ page: string;
3343
+ from: number;
3344
+ to: number;
3345
+ } | {
3346
+ op: `${PlanEditOp.SwapPattern}`;
3347
+ page: string;
3348
+ index: number;
3349
+ pattern: string;
3350
+ } | {
3351
+ op: `${PlanEditOp.SetSlot}`;
3352
+ page: string;
3353
+ index: number;
3354
+ slot: string;
3355
+ text: string;
3356
+ } | {
3357
+ op: `${PlanEditOp.AddContentType}`;
3358
+ contentType: ContentTypePlan;
3359
+ dataSources?: DataSourcePlan[];
3360
+ } | {
3361
+ op: `${PlanEditOp.AddField}`;
3362
+ contentType: string;
3363
+ field: ContentFieldPlan;
3364
+ sample?: string | string[];
3365
+ } | {
3366
+ op: `${PlanEditOp.SetSectionData}`;
3367
+ page: string;
3368
+ index: number;
3369
+ binding: string;
3370
+ };
3371
+ /**
3372
+ * Every op's keys, explained — what the format is built from and what `validatePlanEdits` reads (`key?` optional).
3373
+ * A page is named by its `key`; a section by its 0-based `index` on that page.
3374
+ */
3375
+ declare const PLAN_EDIT_SHAPE: Readonly<Record<`${PlanEditOp}`, ShapeEntry>>;
3376
+ declare enum PlanChangeKind {
3377
+ Page = "page",
3378
+ Section = "section",
3379
+ ContentType = "contentType",
3380
+ Field = "field",
3381
+ DataSource = "dataSource"
3382
+ }
3383
+ declare enum PlanChangeAction {
3384
+ Added = "added",
3385
+ Removed = "removed",
3386
+ Changed = "changed",
3387
+ Moved = "moved"
3388
+ }
3389
+ /** What an edit changed — the Plan map marks it. `index` is the section's index in the RESULT (or before, when removed). */
3390
+ interface PlanChange {
3391
+ kind: `${PlanChangeKind}`;
3392
+ action: `${PlanChangeAction}`;
3393
+ page?: string;
3394
+ index?: number;
3395
+ name?: string;
3396
+ }
3397
+ declare enum PlanEditIssueCode {
3398
+ Shape = "shape",
3399
+ UnknownKey = "unknown-key",
3400
+ Duplicate = "duplicate",
3401
+ UnknownOp = "unknown-op",
3402
+ UnknownPage = "unknown-page",
3403
+ UnknownSection = "unknown-section",
3404
+ UnknownPattern = "unknown-pattern",
3405
+ UnknownSlot = "unknown-slot",
3406
+ UnknownContentType = "unknown-content-type",
3407
+ UnknownDataSource = "unknown-data-source",
3408
+ /** The home page stays (a plan has exactly one). */
3409
+ HomePage = "home-page",
3410
+ /** A template page (one item per route) and a plain page cannot be merged. */
3411
+ MergeTemplate = "merge-template"
3412
+ }
3413
+ type PlanEditIssue = PathIssue<PlanEditIssueCode>;
3414
+ interface PlanEditResult {
3415
+ plan: SitePlan;
3416
+ changed: PlanChange[];
3417
+ /** Non-empty: nothing was applied (`plan` is the input). */
3418
+ issues: PlanEditIssue[];
3419
+ }
3420
+ /** The edits' structure: a known op, its keys (`PLAN_EDIT_SHAPE`), integers where an index is. Never repairs. */
3421
+ declare function validatePlanEdits(edits: unknown): {
3422
+ valid: boolean;
3423
+ issues: PlanEditIssue[];
3424
+ };
3425
+ /**
3426
+ * Apply a set of edits to a plan — all of them, or none (any issue refuses the set and returns the plan unchanged). The
3427
+ * sources only removed pages and sections read are dropped with them; sources nothing read before are kept.
3428
+ * The result still has to pass `validateSitePlan`.
3429
+ */
3430
+ declare function applyPlanEdits(plan: SitePlan, edits: ReadonlyArray<PlanEdit>): PlanEditResult;
3431
+ declare const PLAN_EDITS_SCHEMA_NAME = "plan_edits";
3432
+ /** A sentence's answer: the edits, or why the ops cannot say it (one line, in the owner's language). */
3433
+ declare enum PlanEditsOutcome {
3434
+ Edits = "edits",
3435
+ Cannot = "cannot"
3436
+ }
3437
+ interface PlanEditsAnswer {
3438
+ outcome: `${PlanEditsOutcome}`;
3439
+ edits: PlanEdit[];
3440
+ /** `cannot`: the one line the owner reads. `edits`: empty. */
3441
+ reason: string;
3442
+ }
3443
+ /** The answer's own keys, explained. */
3444
+ declare const PLAN_EDITS_ANSWER_SHAPE: ShapeEntry;
3445
+ /** The format a sentence's answer is written in: the outcome, the edits (one `anyOf` branch per op), the reason. */
3446
+ declare function planEditsJsonSchema(): JsonSchema;
3447
+ /** A model's answer → edits (sections and content types off the wire); never repaired. */
3448
+ declare function planEditsFromWire(answer: unknown): PlanEditsAnswer | unknown;
3449
+
3450
+ /**
3451
+ * The plan stage's word checks (AI plan §3d / §3h, M1-3): every text a model WROTE into a plan — the tagline, page
3452
+ * names, section slots, content-type labels, sample values — scanned for the words the owner and their kind of
3453
+ * business must not use (`avoidWords`, the analysis's + the type's `words`), and for a fact the owner never gave
3454
+ * (an email, phone number, price or opening time that is not one of the owner's own facts). A finding is a refusal
3455
+ * with a path — the model rewrites; nothing here repairs a word. Pure.
3456
+ */
3457
+ declare enum PlanWordIssueCode {
3458
+ /** A word the owner (or their kind of business) must not use. */
3459
+ AvoidWord = "avoid-word",
3460
+ /** Something that looks like a fact — an email, phone, price or time — that is not one of the owner's facts. */
3461
+ InventedFact = "invented-fact",
3462
+ /** `business.facts` holds a fact the owner did not give, or not in the owner's words. */
3463
+ FactNotTheOwners = "fact-not-the-owners"
3464
+ }
3465
+ type PlanWordIssue = PathIssue<PlanWordIssueCode>;
3466
+ interface PlanWordContext {
3467
+ avoidWords: ReadonlyArray<string>;
3468
+ /** The owner's own facts (the analysis's, as corrected) — the only ones a plan may carry. */
3469
+ facts: Readonly<Partial<Record<FactKey, string>>>;
3470
+ }
3471
+ /** A text a model wrote, and where. */
3472
+ interface WrittenText {
3473
+ path: string;
3474
+ text: string;
3475
+ }
3476
+ /** Every text in a plan a model writes (never ids, routes, field names or pattern ids). */
3477
+ declare function writtenTexts(plan: SitePlan): WrittenText[];
3478
+ /** A word (or phrase) as a whole-word pattern; Hebrew allows its one-letter prefixes. */
3479
+ declare function wordPattern(word: string): RegExp;
3480
+ /** The words to avoid and the facts never given, in every written text of the plan. */
3481
+ declare function planWordIssues(plan: SitePlan, ctx: PlanWordContext): PlanWordIssue[];
3482
+
3483
+ /**
3484
+ * THE Publishable gate (AI plan §3e, M1-7): ONE pure function over a snapshot of a site — its pages, globals, the
3485
+ * connectors' health, the look's token rows, what a build left to fill — run by the Publish dialog, the builder's
3486
+ * Needs attention and the server on publish (iox-cms refuses with the same findings). Works on any site, generated
3487
+ * or hand-built. Severity is decision D8: an unfilled fact, a policy placeholder or an action that points at nothing
3488
+ * BLOCKS; samples, copy placeholders and stock photos ASK ("Publish anyway"); the rest WARN. Design advice
3489
+ * (harness-core `lintDesign`) is not one of the eight — the caller adds it, and it never blocks.
3490
+ */
3491
+ declare enum SiteCheckId {
3492
+ Navigation = "navigation",
3493
+ Forms = "forms",
3494
+ Consent = "consent",
3495
+ Seo = "seo",
3496
+ Facts = "facts",
3497
+ Accessibility = "accessibility",
3498
+ Tokens = "tokens",
3499
+ Actions = "actions"
3500
+ }
3501
+ /** The eight, in §3e's order. */
3502
+ declare const SITE_CHECKS: ReadonlyArray<SiteCheckId>;
3503
+ declare enum CheckSeverity {
3504
+ Block = "block",
3505
+ Ask = "ask",
3506
+ Warn = "warn"
3507
+ }
3508
+ declare enum SiteFindingCode {
3509
+ NoHeader = "no-header",
3510
+ NoPhoneMenu = "no-phone-menu",
3511
+ FormWithoutId = "form-without-id",
3512
+ EmailNeedsMailer = "email-needs-mailer",
3513
+ TrackerWithoutBanner = "tracker-without-banner",
3514
+ NoTitle = "no-title",
3515
+ NoDescription = "no-description",
3516
+ UnfilledFact = "unfilled-fact",
3517
+ CopyPlaceholder = "copy-placeholder",
3518
+ SampleItems = "sample-items",
3519
+ StockPhoto = "stock-photo",
3520
+ NoPrivacyPage = "no-privacy-page",
3521
+ PrivacyPagePlaceholder = "privacy-page-placeholder",
3522
+ LowContrast = "low-contrast",
3523
+ HeadingOrder = "heading-order",
3524
+ ImageWithoutAlt = "image-without-alt",
3525
+ LiteralColour = "literal-colour",
3526
+ DeadLink = "dead-link",
3527
+ DeadDialogTarget = "dead-dialog-target",
3528
+ ActionNeedsConnector = "action-needs-connector"
3529
+ }
3530
+ /** Each finding's severity — one table (D8), never decided at a call site. */
3531
+ declare const FINDING_SEVERITY: Readonly<Record<SiteFindingCode, CheckSeverity>>;
3532
+ interface SiteFinding {
3533
+ check: SiteCheckId;
3534
+ severity: CheckSeverity;
3535
+ code: SiteFindingCode;
3536
+ /** In plain words, for the screen. */
3537
+ message: string;
3538
+ pageId?: string;
3539
+ nodeId?: string;
3540
+ /** The global slot (`header` / `footer`) when it is in a global. */
3541
+ owner?: string;
3542
+ }
3543
+ interface SiteCheck {
3544
+ id: SiteCheckId;
3545
+ passed: boolean;
3546
+ findings: SiteFinding[];
3547
+ }
3548
+ interface SiteAudit {
3549
+ checks: SiteCheck[];
3550
+ blocking: number;
3551
+ asking: number;
3552
+ }
3553
+ /** A page as the gate reads it. */
3554
+ interface AuditPage {
3555
+ id: string;
3556
+ name: string;
3557
+ route: string;
3558
+ layout: ReadonlyArray<SerializedNode>;
3559
+ seo?: unknown;
3560
+ }
3561
+ /** A placeholder a build left, and whether the node still shows it (the caller compares the node's text). */
3562
+ interface AuditPlaceholder extends ComposedPlaceholder {
3563
+ pageId?: string;
3564
+ filled: boolean;
3565
+ }
3566
+ interface SiteAuditSnapshot {
3567
+ pages: ReadonlyArray<AuditPage>;
3568
+ globals: ReadonlyArray<SerializedNode>;
3569
+ /** Connector type → usable (configured or provided, and healthy). */
3570
+ connectors: Readonly<Record<string, boolean>>;
3571
+ /** Connector types that set a tracker (a consent category) and are configured. */
3572
+ trackers?: ReadonlyArray<string>;
3573
+ /** The look's token rows and the mode(s) the site wears. */
3574
+ design?: {
3575
+ rows: ReadonlyArray<DesignTokenLike>;
3576
+ modes: ReadonlyArray<'light' | 'dark'>;
3577
+ } | null;
3578
+ placeholders?: ReadonlyArray<AuditPlaceholder>;
3579
+ /** Sample items still in the site (`isSample`). */
3580
+ samples?: ReadonlyArray<{
3581
+ contentType: string;
3582
+ id: string;
3583
+ label?: string;
3584
+ }>;
3585
+ /** Stock photos a build placed that are still on the page. */
3586
+ stock?: ReadonlyArray<{
3587
+ nodeId: string;
3588
+ pageId?: string;
3589
+ owner?: string;
3590
+ }>;
3591
+ }
3592
+ interface SiteAuditOptions {
3593
+ /** Audit as if only this page were being published (its own page checks + every site-wide one). */
3594
+ pageId?: string;
3595
+ }
3596
+ /** A route pattern (`/work/:slug`) matches a concrete path (`/work/blue-bowl`). */
3597
+ declare function routeMatches(pattern: string, path: string): boolean;
3598
+ /** Run the eight checks. `pageId` narrows the page checks to the page being published; site-wide ones always run. */
3599
+ declare function auditSite(snapshot: SiteAuditSnapshot, options?: SiteAuditOptions): SiteAudit;
3600
+ /** What a publish request must acknowledge: every ASK finding's code (a BLOCK cannot be acknowledged). */
3601
+ declare function requiredAcknowledgements(audit: SiteAudit): SiteFindingCode[];
3602
+ /** The publish verdict: blocked (never acknowledgeable), needs these acknowledgements, or free to go. */
3603
+ declare function publishVerdict(audit: SiteAudit, acknowledged?: ReadonlyArray<string>): {
3604
+ ok: boolean;
3605
+ blocked: boolean;
3606
+ missing: SiteFindingCode[];
3607
+ };
3608
+
3609
+ /**
3610
+ * Stock photos in a built site (AI plan §3g / §3m, I2): a FREE picture from the platform's curated library, copied
3611
+ * into the studio's own storage (never hot-linked), placed only in an EMPTY picture slot of a section that may show
3612
+ * one — never the owner's work (a collection, a detail page, a gallery: what the nine portfolio types sell is theirs),
3613
+ * never a person (testimonials, the team), never anywhere when the business type says `stock: false`. Its alt text is
3614
+ * the provider's description of what it shows (never a claim), and the credit line its licence requires is placed in
3615
+ * the footer. Pure: the build step does the copying.
3616
+ */
3617
+ /** Where a stock photo comes from (the library's provider). */
3618
+ declare enum StockProviderId {
3619
+ Magnific = "magnific"
3620
+ }
3621
+ /** What a picture's licence asks of the site that shows it. */
3622
+ interface StockCredit {
3623
+ provider: `${StockProviderId}`;
3624
+ /** The provider's id of the picture. */
3625
+ resourceId: string;
3626
+ /** The provider's page for it. */
3627
+ sourceUrl: string;
3628
+ /** The provider's own title — what the picture shows. */
3629
+ title: string;
3630
+ author: string;
3631
+ /** `freemium` — the free licence (premium pictures never enter the library). */
3632
+ licence: string;
3633
+ licenceUrl: string;
3634
+ /** The words the licence requires, and where they link. */
3635
+ line: string;
3636
+ lineUrl: string;
3637
+ }
3638
+ /** One picture of the platform library (`iox-stock/<type>/`), as its manifest lists it. */
3639
+ interface StockPhoto {
3640
+ /** The library key (`spa/12345.jpg`) — the copy's file name is derived from it. */
3641
+ key: string;
3642
+ /** Where the build downloads it from (the platform bucket). */
3643
+ url: string;
3644
+ /** What it shows, in the provider's words — the alt text. Never a claim. */
3645
+ alt: string;
3646
+ width?: number;
3647
+ height?: number;
3648
+ credit: StockCredit;
3649
+ }
3650
+ /** The section families a stock photo may stand in for a picture in. */
3651
+ declare const STOCK_FAMILIES: ReadonlySet<string>;
3652
+ interface StockSlot {
3653
+ /** The Image node the photo goes into. */
3654
+ nodeId: string;
3655
+ /** The page key it lives on. */
3656
+ owner: string;
3657
+ pattern: string;
3658
+ }
3659
+ /** The empty picture slots of a composed site a stock photo may fill, in page and section order. */
3660
+ declare function stockSlots(plan: SitePlan, composed: Pick<ComposedSite, 'pages' | 'placeholders'>): StockSlot[];
3661
+ interface StockPlacement extends StockSlot {
3662
+ photo: StockPhoto;
3663
+ }
3664
+ /** Which photo goes where: the library's photos in order, one per slot, never twice; none when the type says no stock. */
3665
+ declare function planStockPhotos(slots: ReadonlyArray<StockSlot>, photos: ReadonlyArray<StockPhoto>, stockAllowed: boolean): StockPlacement[];
3666
+ /** A placed photo's copy in the studio's storage: the key the build writes it under. */
3667
+ declare function stockCopyKey(photo: Pick<StockPhoto, 'key'>): string;
3668
+ /** Put the studio's copy of each photo into its slot (src + the provider's alt). Returns the nodes changed. */
3669
+ declare function applyStockPhotos(trees: ReadonlyArray<SerializedNode>, placed: ReadonlyArray<{
3670
+ nodeId: string;
3671
+ url: string;
3672
+ alt: string;
3673
+ }>): number;
3674
+ /** The credit lines a set of photos needs — one per distinct line (a free Magnific photo: "Designed by Magnific"). */
3675
+ declare function stockCreditLines(photos: ReadonlyArray<Pick<StockPhoto, 'credit'>>): Array<{
3676
+ line: string;
3677
+ url: string;
3678
+ }>;
3679
+ /** The footer node id of a credit line (stable — a build that runs twice finds it). */
3680
+ declare const stockCreditNodeId: (index: number) => string;
3681
+ /**
3682
+ * The credit line, as the builder would create a Link (a plain node the owner may move or restyle): the licence's words,
3683
+ * linking where it asks, opening in a new tab. Placed at the end of the footer — the place the licence names for a site.
3684
+ */
3685
+ declare function stockCreditNode(index: number, credit: {
3686
+ line: string;
3687
+ url: string;
3688
+ }): SerializedNode;
3689
+ /** Append the credit lines to the footer root (once each). Returns how many it added. */
3690
+ declare function addStockCredits(footer: SerializedNode, credits: ReadonlyArray<{
3691
+ line: string;
3692
+ url: string;
3693
+ }>): number;
3694
+
3695
+ export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiGenerationStage, AiKeyMode, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CREDITS_PER_USD, CardBindTarget, CheckSeverity, ComposeError, ComposeIssueCode, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, FACT_KEYS, FINAL_GENERATION_STAGES, FINDING_SEVERITY, GlobalSlot, JSON_SCHEMA_BANNED_KEYWORDS, JsonSchemaShapeError, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PLAN_EDITS_ANSWER_SHAPE, PLAN_EDITS_SCHEMA_NAME, PLAN_EDIT_SHAPE, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PageDataKind, PathIssueCollector, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanChangeAction, PlanChangeKind, PlanDataSourceMode, PlanDataSourceType, PlanEditIssueCode, PlanEditOp, PlanEditsOutcome, PlanWordIssueCode, PreflightRefusalCode, RelativeOp, SAMPLE_IMAGE_REF, SITE_CHECKS, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_PATTERNS, SITE_PLAN_SCHEMA_NAME, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_FACTS, SPEC_SITE_LIBRARY, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_TEMPLATES, STOCK_FAMILIES, STUDIO_TEMPLATE, SiteBuildKind, SiteBuildStatus, SiteCheckId, SiteFindingCode, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SitePlanWireKey, SiteTemplateError, SiteTemplateId, StepState, StockProviderId, addBarItem, addStockCredits, altSourceScopes, applyPlanEdits, applyStockPhotos, assertStyleSlots, assertValidSitePlan, auditSite, barIconForRoute, blocksPublish, buildKeys, buildStepFacts, builtHomePageId, composeNavHeader, composeSection, composeSite, contentTypeFromWire, contentTypeJsonSchema, costUsd, createSerializedNode, creditsOfUsd, dataSourceJsonSchema, describePlanData, describeShapeKey, entranceAction, entranceInteraction, estimateStepCredits, failedBuildStep, fieldJsonSchema, findNavRoot, isActiveBuild, isNonEmptyString, isPlainObject, jsonAnyOf, jsonBoolean, jsonClosedObject, jsonInteger, jsonListOf, jsonOneOf, jsonSchemaKeywords, jsonSchemaObjects, jsonShapedObject, jsonText, modelCanDo, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, pageJsonSchema, parseSampleImageRef, pathAt, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, phoneMenuPages, planEditsFromWire, planEditsJsonSchema, planFromTemplate, planNavShape, planStockPhotos, planWordIssues, publishVerdict, releasedLayoutDefaults, removeBarItem, requiredAcknowledgements, requiredShapeKeys, routeMatches, routeParams, sampleImageRef, sectionEntrances, sectionFromWire, sectionJsonSchema, sectionPatternIds, setStyleProps, shapeKeys, siteNavPages, sitePlanFromWire, sitePlanJsonSchema, sitePlanToWire, staggerDelay, stockCopyKey, stockCreditLines, stockCreditNode, stockCreditNodeId, stockSlots, validatePlanEdits, validateSitePlan, walkSerialized, wordPattern, writtenTexts };
3696
+ export type { AddBarItemResult, AiMeter, AiModelEntry, AiRefusal, AiTokenCounts, AiTokenPrice, AuditPage, AuditPlaceholder, BarItemsEditResult, BuildNotice, BuildStepError, BuildStepFacts, BuildStepRecord, CmsDataSourcePlan, ComposeContext, ComposeIssue, ComposedDataSource, ComposedItem, ComposedNavHeader, ComposedPage, ComposedPlaceholder, ComposedRoute, ComposedSection, ComposedSite, ContentFieldPlan, ContentSeedPlan, ContentTypePlan, CreateNodeOptions, CreatedRecord, DataSourcePlan, DynamicKeysAsList, EntranceAction, EntranceInteraction, EntranceSpec, FactKey, JsonSchema, NavHeaderInput, NavHeaderOptions, NavPage, NavShapeOptions, NavShapeResult, NodeBaseline, PageData, PageDataLine, PagePlan, PageSectionPlan, PathIssue, PatternNode, PlainObject, PlanChange, PlanEdit, PlanEditIssue, PlanEditResult, PlanEditsAnswer, PlanWordContext, PlanWordIssue, PreflightRefusal, RelativeDataSourcePlan, SectionEntrances, SectionInput, SectionOptions, SerializedBinding, SerializedNode, SerializedResponsive, ShapeEntry, ShapeIssueCodes, SiteAudit, SiteAuditOptions, SiteAuditSnapshot, SiteBuildRun, SiteBusiness, SiteCheck, SiteFinding, SitePageRef, SitePattern, SitePlan, SitePlanIssue, SitePlanSchemaPin, SitePlanSource, SitePlanValidation, SiteTemplate, StockCredit, StockPhoto, StockPlacement, StockSlot, TemplatePlanInput, UndoKept, UndoPreview, UndoRecord, WrittenText };