@vectoriox/iox-ui 5.56.1 → 5.57.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.
@@ -3205,6 +3205,24 @@ interface AiMeter {
3205
3205
  periodStart: string;
3206
3206
  periodEnd: string;
3207
3207
  }
3208
+ /** The plan entitlements AI reads (the control plane's `features` / `limits` keys) — ONE spelling. */
3209
+ declare enum AiFeature {
3210
+ SiteGeneration = "aiSiteGeneration"
3211
+ }
3212
+ declare enum AiLimit {
3213
+ CreditsPerMonth = "aiCreditsPerMonth",
3214
+ CreditsPerGeneration = "aiCreditsPerGeneration"
3215
+ }
3216
+ /** `GET …/ai/entitlements` — the plan as the studio last heard it (`known: false` = never), its features, the credits. */
3217
+ interface AiEntitlementsView {
3218
+ known: boolean;
3219
+ /** Where the answer came from (the control plane, last known, or local development). */
3220
+ source?: string;
3221
+ planName?: string;
3222
+ features?: Record<string, boolean>;
3223
+ limits?: Record<string, number>;
3224
+ meter: AiMeter | null;
3225
+ }
3208
3226
  /** A generation's stages (§3d). The runner works while `task` is set; otherwise the owner has the next move. */
3209
3227
  declare enum AiGenerationStage {
3210
3228
  Reading = "reading",
@@ -3597,8 +3615,26 @@ interface SiteAuditOptions {
3597
3615
  declare function routeMatches(pattern: string, path: string): boolean;
3598
3616
  /** Run the eight checks. `pageId` narrows the page checks to the page being published; site-wide ones always run. */
3599
3617
  declare function auditSite(snapshot: SiteAuditSnapshot, options?: SiteAuditOptions): SiteAudit;
3618
+ /** Why the server refused a publish (409) — the dialog the client opens from the findings it carries. */
3619
+ declare enum PublishRefusalCode {
3620
+ /** A block nothing lifts (a blank fact, a policy placeholder, a dead action). */
3621
+ Blocked = "site.publishBlocked",
3622
+ /** Asks the request must acknowledge, by code (`publishAcknowledged`). */
3623
+ NeedsAck = "site.publishNeedsAck"
3624
+ }
3625
+ /** The body of a refused publish. */
3626
+ interface PublishRefusal {
3627
+ code: `${PublishRefusalCode}`;
3628
+ message: string;
3629
+ /** The findings the refusal is about (blocks, or the asks still unacknowledged). */
3630
+ findings: SiteFinding[];
3631
+ /** For `needsAck`: the codes the request must acknowledge. */
3632
+ missing?: SiteFindingCode[];
3633
+ }
3600
3634
  /** What a publish request must acknowledge: every ASK finding's code (a BLOCK cannot be acknowledged). */
3601
3635
  declare function requiredAcknowledgements(audit: SiteAudit): SiteFindingCode[];
3636
+ /** The refusal a publish gets for an audit and its acknowledgements — or null: it may go (the server's ONE rule). */
3637
+ declare function publishRefusal(audit: SiteAudit, acknowledged?: ReadonlyArray<string>): PublishRefusal | null;
3602
3638
  /** The publish verdict: blocked (never acknowledgeable), needs these acknowledgements, or free to go. */
3603
3639
  declare function publishVerdict(audit: SiteAudit, acknowledged?: ReadonlyArray<string>): {
3604
3640
  ok: boolean;
@@ -3692,5 +3728,5 @@ declare function addStockCredits(footer: SerializedNode, credits: ReadonlyArray<
3692
3728
  url: string;
3693
3729
  }>): number;
3694
3730
 
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 };
3731
+ export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiFeature, AiGenerationStage, AiKeyMode, AiLimit, 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, PublishRefusalCode, 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, publishRefusal, 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 };
3732
+ export type { AddBarItemResult, AiEntitlementsView, 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, PublishRefusal, 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 };
@@ -1,5 +1,5 @@
1
1
  import { MotionId, MoodId, TintId, DensityId, DesignMotion, DesignChoices, DesignMode, StylePreset, ShapeId, AnimateId } from '@vectoriox/iox-ui/design-core';
2
- import { FactKey, PathIssue, JsonSchema, SiteTemplate, ShapeEntry, AiGenerationStage, AiStep, SitePlan, PlanEdit, PlanChange } from '@vectoriox/iox-ui/generation-core';
2
+ import { FactKey, PathIssue, JsonSchema, SiteTemplate, ShapeEntry, AiGenerationStage, AiStep, SitePlan, PlanEdit, PlanChange, SiteAudit } from '@vectoriox/iox-ui/generation-core';
3
3
  export { JsonSchema } from '@vectoriox/iox-ui/generation-core';
4
4
 
5
5
  declare const SPEC_HARNESS_SOURCE: {
@@ -2738,6 +2738,8 @@ interface ReferenceSeed {
2738
2738
  used: boolean;
2739
2739
  /** The modes the reference colour failed in (empty when used, or when there is no reference). */
2740
2740
  failsIn: Array<'light' | 'dark'>;
2741
+ /** Information only: the RAW reference colour against the style's page ground (its first mode); null without one. */
2742
+ rawRatio: number | null;
2741
2743
  }
2742
2744
  /** Every mode `presetId` offers passes the audit with `seed`. */
2743
2745
  declare function seedPassesPreset(presetId: string, seed: string): {
@@ -2961,7 +2963,11 @@ declare const GENERATION_LIMITS: {
2961
2963
  * references — the best-ranked style with the reference colour as its seed when that colour passes AA in every mode
2962
2964
  * the style offers (`referenceSeed`). Pure.
2963
2965
  */
2964
- /** A preset for this business: its choices, Motion from the business (`motionFor`), what the owner already set kept. */
2966
+ /**
2967
+ * A preset for this business: its choices, Motion from the business (`motionFor`), the references' colour as its seed
2968
+ * when that colour passes AA in every mode the preset offers (`referenceSeed` — judged as used), and what the owner
2969
+ * already set kept. The ONE rule for a Look pick and for Build with these.
2970
+ */
2965
2971
  declare function presetDesign(presetId: string, input: MotionInput | string | null, kept?: Partial<Pick<DesignChoices, 'scroll' | 'animate' | 'between' | 'motion'>>, read?: StyleRead | null): DesignChoices | null;
2966
2972
  interface StartingDesign {
2967
2973
  presetId: string;
@@ -2972,5 +2978,14 @@ interface StartingDesign {
2972
2978
  /** The look a business starts from: its best-ranked style (with the references' boost), at its defaults. */
2973
2979
  declare function startingDesign(input: (RankInput & MotionInput) | string | null, read?: StyleRead | null): StartingDesign | null;
2974
2980
 
2981
+ /**
2982
+ * `GET …/webbuilder/site-audit?page=` (AI plan §3e, M1-7): the eight checks (generation-core `auditSite`) and the design
2983
+ * advice beside them (`lintDesign` — never blocks, "Keep it" dismisses). ONE definition: iox-cms answers it, the Publish
2984
+ * dialog and Needs attention read it.
2985
+ */
2986
+ type SiteAuditView = SiteAudit & {
2987
+ advice: LintFinding[];
2988
+ };
2989
+
2975
2990
  export { ANIMATE_ADVICE_STEPS, AnalysisIssueCode, AnalysisLocale, AvoidCheck, BUSINESS_TYPES, BUSINESS_TYPE_IDS, BookingNeed, COPY_LENGTH_ORDER, CopyLength, GENERATION_LIMITS, HARNESS_SOURCE, LITTLE_MOVEMENT_AVOID, LITTLE_MOVEMENT_CAP, LintKind, MAX_ANALYSIS_MOODS, MAX_PIXEL_SAMPLES, MAX_READ_PICTURES, NEEDS, NEED_IDS, NeedSource, PALETTE_SIZE, PALETTE_THRESHOLDS, PictureRole, PlanChangeOutcome, PresetFit, RANK_WEIGHTS, READING_SHAPE, READ_ANIMATE, READ_WEIGHTS, RankReason, ReaderState, ReadingIssueCode, SITE_ANALYSIS_SCHEMA_NAME, SITE_READING_SCHEMA_NAME, SPEC_ANALYSIS_SHAPE, SPEC_BUSINESS_TYPES, SPEC_HARNESS_EXAMPLES, SPEC_HARNESS_SOURCE, SPEC_NEEDS, SPEC_STRUCTURES, SPEC_USER_AVOIDS, STRUCTURES, SiteReadRefusal, StyleReadGround, StyleReadHeadings, StyleReadMotion, StyleReadSourceKind, USER_AVOID_IDS, VoiceFormality, VoicePerson, addressesIn, analysisPromptContext, businessTypeById, calmerChoice, decodeSiteReading, inferNeeds, isLookRule, lintDesign, lookMatches, mapStyleRead, matchBusinessType, matchBusinessTypes, measurePalette, mergeStyleReads, motionAdvice, motionFor, normalizeAddress, oklchHue, paletteBrand, paletteGround, paletteSamples, pictureStyleRead, pixelSamples, presetDesign, presetHasSerifHeadings, presetLook, presetReason, rankStylePresets, rankWithReferences, readPalette, referenceSeed, seedPassesPreset, siteAnalysisJsonSchema, siteReadingJsonSchema, startingDesign, structureFor, userAvoidRule, validateSiteAnalysis, validateSiteReading, withoutAddress };
2976
- export type { AiGenerationView, AnalysisContext, AnalysisIssue, AnalysisValidation, AvoidRule, BusinessType, BusinessTypeMatch, CheckRule, ColourSample, FactRead, GenerationFileView, GenerationReadersView, GenerationStartRequest, GoodFit, LintFinding, LintSite, LookCondition, LookDesign, LookRule, MeasuredPicture, MotionBasis, MotionInput, MotionStart, NeedDef, NeedId, PaletteColour, PaletteReading, PictureStyle, PlanRevisionView, PromptContext, PromptContextOptions, PromptSection, RankInput, RankedPreset, ReadingIssue, ReferenceSeed, SiteAnalysis, SiteNeed, SiteReaderView, SiteReading, StartingDesign, StructureChoice, StructureId, StyleHints, StyleRead, UserAvoidId };
2991
+ export type { AiGenerationView, AnalysisContext, AnalysisIssue, AnalysisValidation, AvoidRule, BusinessType, BusinessTypeMatch, CheckRule, ColourSample, FactRead, GenerationFileView, GenerationReadersView, GenerationStartRequest, GoodFit, LintFinding, LintSite, LookCondition, LookDesign, LookRule, MeasuredPicture, MotionBasis, MotionInput, MotionStart, NeedDef, NeedId, PaletteColour, PaletteReading, PictureStyle, PlanRevisionView, PromptContext, PromptContextOptions, PromptSection, RankInput, RankedPreset, ReadingIssue, ReferenceSeed, SiteAnalysis, SiteAuditView, SiteNeed, SiteReaderView, SiteReading, StartingDesign, StructureChoice, StructureId, StyleHints, StyleRead, UserAvoidId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectoriox/iox-ui",
3
- "version": "5.56.1",
3
+ "version": "5.57.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=20.0.0",
6
6
  "@angular/core": ">=20.0.0",
@@ -194,6 +194,27 @@ export interface AiMeter {
194
194
  periodEnd: string;
195
195
  }
196
196
 
197
+ /** The plan entitlements AI reads (the control plane's `features` / `limits` keys) — ONE spelling. */
198
+ export enum AiFeature {
199
+ SiteGeneration = 'aiSiteGeneration',
200
+ }
201
+
202
+ export enum AiLimit {
203
+ CreditsPerMonth = 'aiCreditsPerMonth',
204
+ CreditsPerGeneration = 'aiCreditsPerGeneration',
205
+ }
206
+
207
+ /** `GET …/ai/entitlements` — the plan as the studio last heard it (`known: false` = never), its features, the credits. */
208
+ export interface AiEntitlementsView {
209
+ known: boolean;
210
+ /** Where the answer came from (the control plane, last known, or local development). */
211
+ source?: string;
212
+ planName?: string;
213
+ features?: Record<string, boolean>;
214
+ limits?: Record<string, number>;
215
+ meter: AiMeter | null;
216
+ }
217
+
197
218
  /** A generation's stages (§3d). The runner works while `task` is set; otherwise the owner has the next move. */
198
219
  export enum AiGenerationStage {
199
220
  Reading = 'reading',
@@ -373,11 +373,43 @@ export function auditSite(snapshot: SiteAuditSnapshot, options: SiteAuditOptions
373
373
  };
374
374
  }
375
375
 
376
+ /** Why the server refused a publish (409) — the dialog the client opens from the findings it carries. */
377
+ export enum PublishRefusalCode {
378
+ /** A block nothing lifts (a blank fact, a policy placeholder, a dead action). */
379
+ Blocked = 'site.publishBlocked',
380
+ /** Asks the request must acknowledge, by code (`publishAcknowledged`). */
381
+ NeedsAck = 'site.publishNeedsAck',
382
+ }
383
+
384
+ /** The body of a refused publish. */
385
+ export interface PublishRefusal {
386
+ code: `${PublishRefusalCode}`;
387
+ message: string;
388
+ /** The findings the refusal is about (blocks, or the asks still unacknowledged). */
389
+ findings: SiteFinding[];
390
+ /** For `needsAck`: the codes the request must acknowledge. */
391
+ missing?: SiteFindingCode[];
392
+ }
393
+
376
394
  /** What a publish request must acknowledge: every ASK finding's code (a BLOCK cannot be acknowledged). */
377
395
  export function requiredAcknowledgements(audit: SiteAudit): SiteFindingCode[] {
378
396
  return [...new Set(audit.checks.flatMap(c => c.findings).filter(f => f.severity === CheckSeverity.Ask).map(f => f.code))];
379
397
  }
380
398
 
399
+ /** The refusal a publish gets for an audit and its acknowledgements — or null: it may go (the server's ONE rule). */
400
+ export function publishRefusal(audit: SiteAudit, acknowledged: ReadonlyArray<string> = []): PublishRefusal | null {
401
+ const verdict = publishVerdict(audit, acknowledged);
402
+ if (verdict.ok) return null;
403
+ const findings = audit.checks.flatMap(c => c.findings);
404
+ if (verdict.blocked) {
405
+ return { code: PublishRefusalCode.Blocked, message: 'This page cannot go live yet — fill in what is marked first', findings: findings.filter(f => f.severity === CheckSeverity.Block) };
406
+ }
407
+ return {
408
+ code: PublishRefusalCode.NeedsAck, message: 'Publish anyway? Some parts are still samples or placeholders',
409
+ findings: findings.filter(f => f.severity === CheckSeverity.Ask && verdict.missing.includes(f.code)), missing: verdict.missing,
410
+ };
411
+ }
412
+
381
413
  /** The publish verdict: blocked (never acknowledgeable), needs these acknowledgements, or free to go. */
382
414
  export function publishVerdict(audit: SiteAudit, acknowledged: ReadonlyArray<string> = []): { ok: boolean; blocked: boolean; missing: SiteFindingCode[] } {
383
415
  const missing = requiredAcknowledgements(audit).filter(code => !acknowledged.includes(code));
@@ -23,3 +23,4 @@ export * from './reference-colour';
23
23
  export * from './site-reading';
24
24
  export * from './generation-view';
25
25
  export * from './starting-design';
26
+ export * from './site-audit-view';
@@ -1,4 +1,4 @@
1
- import { auditDesignContrast, designTokenRows, parseHexColor, presetChoices, stylePresetById } from '@vectoriox/iox-ui/design-core';
1
+ import { auditDesignContrast, designTokenRows, parseHexColor, presetChoices, resolveTokenValues, stylePresetById, wcagContrastRatio } from '@vectoriox/iox-ui/design-core';
2
2
  import type { DesignChoices } from '@vectoriox/iox-ui/design-core';
3
3
 
4
4
  import { StyleRead } from './rank';
@@ -21,6 +21,17 @@ export interface ReferenceSeed {
21
21
  used: boolean;
22
22
  /** The modes the reference colour failed in (empty when used, or when there is no reference). */
23
23
  failsIn: Array<'light' | 'dark'>;
24
+ /** Information only: the RAW reference colour against the style's page ground (its first mode); null without one. */
25
+ rawRatio: number | null;
26
+ }
27
+
28
+ /** The raw colour's ratio against the preset's own page ground, in its first mode — shown, never decisive. */
29
+ function rawRatioOf(presetId: string, hex: string): number | null {
30
+ const preset = stylePresetById(presetId);
31
+ const choices = preset ? presetChoices(preset.id, preset.modes[0]) : null;
32
+ if (!preset || !choices) return null;
33
+ const ground = resolveTokenValues(designTokenRows(choices), preset.modes[0])['page-bg'];
34
+ return ground && parseHexColor(ground) ? Math.round(wcagContrastRatio(hex, ground) * 100) / 100 : null;
24
35
  }
25
36
 
26
37
  /** Every mode `presetId` offers passes the audit with `seed`. */
@@ -39,7 +50,8 @@ export function referenceSeed(read: Pick<StyleRead, 'brand'> | null | undefined,
39
50
  const preset = stylePresetById(presetId);
40
51
  if (!preset) return null;
41
52
  const reference = read?.brand && parseHexColor(read.brand) ? read.brand : null;
42
- if (!reference) return { seed: preset.seed, reference: null, used: false, failsIn: [] };
53
+ if (!reference) return { seed: preset.seed, reference: null, used: false, failsIn: [], rawRatio: null };
43
54
  const { passes, failsIn } = seedPassesPreset(preset.id, reference);
44
- return passes ? { seed: reference, reference, used: true, failsIn: [] } : { seed: preset.seed, reference, used: false, failsIn };
55
+ const rawRatio = rawRatioOf(preset.id, reference);
56
+ return passes ? { seed: reference, reference, used: true, failsIn: [], rawRatio } : { seed: preset.seed, reference, used: false, failsIn, rawRatio };
45
57
  }
@@ -0,0 +1,10 @@
1
+ import type { SiteAudit } from '@vectoriox/iox-ui/generation-core';
2
+
3
+ import type { LintFinding } from './lint';
4
+
5
+ /**
6
+ * `GET …/webbuilder/site-audit?page=` (AI plan §3e, M1-7): the eight checks (generation-core `auditSite`) and the design
7
+ * advice beside them (`lintDesign` — never blocks, "Keep it" dismisses). ONE definition: iox-cms answers it, the Publish
8
+ * dialog and Needs attention read it.
9
+ */
10
+ export type SiteAuditView = SiteAudit & { advice: LintFinding[] };
@@ -12,7 +12,11 @@ import { referenceSeed } from './reference-colour';
12
12
  * the style offers (`referenceSeed`). Pure.
13
13
  */
14
14
 
15
- /** A preset for this business: its choices, Motion from the business (`motionFor`), what the owner already set kept. */
15
+ /**
16
+ * A preset for this business: its choices, Motion from the business (`motionFor`), the references' colour as its seed
17
+ * when that colour passes AA in every mode the preset offers (`referenceSeed` — judged as used), and what the owner
18
+ * already set kept. The ONE rule for a Look pick and for Build with these.
19
+ */
16
20
  export function presetDesign(
17
21
  presetId: string,
18
22
  input: MotionInput | string | null,
@@ -23,7 +27,8 @@ export function presetDesign(
23
27
  if (!base) return null;
24
28
  const motionInput: MotionInput = typeof input === 'object' && input !== null ? input : { businessType: input as string | null };
25
29
  const start = motionFor(motionInput, presetId, read);
26
- return { ...base, scroll: start.scroll, animate: start.animate, between: start.between, ...kept };
30
+ const seed = referenceSeed(read, presetId);
31
+ return { ...base, ...(seed?.used ? { seed: seed.seed } : {}), scroll: start.scroll, animate: start.animate, between: start.between, ...kept };
27
32
  }
28
33
 
29
34
  export interface StartingDesign {
@@ -39,6 +44,5 @@ export function startingDesign(input: (RankInput & MotionInput) | string | null,
39
44
  const top = rankWithReferences(rankInput, read)[0];
40
45
  const design = top ? presetDesign(top.id, rankInput, {}, read) : null;
41
46
  if (!top || !design) return null;
42
- const seed = referenceSeed(read, top.id);
43
- return seed?.used ? { presetId: top.id, design: { ...design, seed: seed.seed }, referenceColour: true } : { presetId: top.id, design, referenceColour: false };
47
+ return { presetId: top.id, design, referenceColour: !!referenceSeed(read, top.id)?.used };
44
48
  }