@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.
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +1279 -55
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs +477 -30
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs.map +1 -1
- package/generation-core/index.d.ts +523 -4
- package/harness-core/index.d.ts +315 -16
- package/package.json +1 -1
- package/src/generation-core/ai-run.ts +17 -2
- package/src/generation-core/audit-site.ts +386 -0
- package/src/generation-core/json-schema.ts +97 -0
- package/src/generation-core/plan-edits.ts +428 -0
- package/src/generation-core/plan-words.ts +114 -0
- package/src/generation-core/public-api.ts +6 -0
- package/src/generation-core/site-build-run.ts +7 -0
- package/src/generation-core/site-plan-schema.ts +239 -0
- package/src/generation-core/stock-photos.ts +137 -0
- package/src/harness-core/generation-view.ts +115 -0
- package/src/harness-core/palette.ts +198 -0
- package/src/harness-core/public-api.ts +5 -0
- package/src/harness-core/reference-colour.ts +45 -0
- package/src/harness-core/site-analysis.ts +8 -29
- package/src/harness-core/site-reading.ts +214 -0
- package/src/harness-core/starting-design.ts +44 -0
|
@@ -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
|
-
|
|
3177
|
-
|
|
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 };
|