@ggui-ai/protocol 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/errors/domain-error.d.ts +70 -0
  2. package/dist/errors/domain-error.d.ts.map +1 -0
  3. package/dist/errors/domain-error.js +118 -0
  4. package/dist/gadgets/stdlib-gadgets.d.ts +1 -1
  5. package/dist/gadgets/stdlib-gadgets.js +1 -1
  6. package/dist/index.d.ts +5 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +11 -4
  9. package/dist/integrations/mcp-apps.d.ts +48 -8
  10. package/dist/integrations/mcp-apps.d.ts.map +1 -1
  11. package/dist/integrations/mcp-apps.js +29 -23
  12. package/dist/integrations/overlay-hash.d.ts +19 -0
  13. package/dist/integrations/overlay-hash.d.ts.map +1 -0
  14. package/dist/integrations/overlay-hash.js +29 -0
  15. package/dist/integrations/theme-binding.d.ts +14 -12
  16. package/dist/integrations/theme-binding.d.ts.map +1 -1
  17. package/dist/integrations/theme-binding.js +10 -6
  18. package/dist/registry/blueprint-key.d.ts.map +1 -1
  19. package/dist/registry/blueprint-key.js +4 -3
  20. package/dist/schemas/app-generation-profile.d.ts +139 -0
  21. package/dist/schemas/app-generation-profile.d.ts.map +1 -0
  22. package/dist/schemas/app-generation-profile.js +121 -0
  23. package/dist/schemas/app-theme.d.ts +235 -9
  24. package/dist/schemas/app-theme.d.ts.map +1 -1
  25. package/dist/schemas/app-theme.js +218 -40
  26. package/dist/schemas/blueprint.d.ts +2 -1
  27. package/dist/schemas/blueprint.d.ts.map +1 -1
  28. package/dist/schemas/blueprint.js +15 -3
  29. package/dist/schemas/data-contract.d.ts +1 -1
  30. package/dist/schemas/data-contract.js +1 -1
  31. package/dist/schemas/handshake-suggestion.d.ts.map +1 -1
  32. package/dist/schemas/handshake-suggestion.js +8 -1
  33. package/dist/schemas/mcp.d.ts +62 -27
  34. package/dist/schemas/mcp.d.ts.map +1 -1
  35. package/dist/schemas/mcp.js +59 -21
  36. package/dist/schemas/ops-blueprint.d.ts +11 -4
  37. package/dist/schemas/ops-blueprint.d.ts.map +1 -1
  38. package/dist/schemas/ops-blueprint.js +25 -8
  39. package/dist/schemas/render-input-envelope.js +1 -1
  40. package/dist/schemas/rendering-context.d.ts +48 -0
  41. package/dist/schemas/rendering-context.d.ts.map +1 -0
  42. package/dist/schemas/rendering-context.js +39 -0
  43. package/dist/types/blueprint-source.d.ts +27 -7
  44. package/dist/types/blueprint-source.d.ts.map +1 -1
  45. package/dist/types/blueprint-source.js +19 -3
  46. package/dist/types/blueprint.d.ts +2 -2
  47. package/dist/types/blueprint.d.ts.map +1 -1
  48. package/dist/types/data-contract.d.ts +3 -3
  49. package/dist/types/domain-error-codes.d.ts +167 -0
  50. package/dist/types/domain-error-codes.d.ts.map +1 -0
  51. package/dist/types/domain-error-codes.js +170 -0
  52. package/dist/types/handshake-suggestion.d.ts +2 -2
  53. package/dist/types/live-channel.d.ts +1 -1
  54. package/dist/types/llm-route.d.ts +59 -2
  55. package/dist/types/llm-route.d.ts.map +1 -1
  56. package/dist/types/llm-route.js +62 -16
  57. package/dist/types/llm.d.ts +22 -2
  58. package/dist/types/llm.d.ts.map +1 -1
  59. package/dist/types/llm.js +29 -2
  60. package/dist/types/mcp.d.ts +31 -39
  61. package/dist/types/mcp.d.ts.map +1 -1
  62. package/dist/types/mcp.js +22 -10
  63. package/dist/types/refusal-codes.d.ts +31 -93
  64. package/dist/types/refusal-codes.d.ts.map +1 -1
  65. package/dist/types/refusal-codes.js +41 -96
  66. package/dist/types/render.d.ts +6 -5
  67. package/dist/types/render.d.ts.map +1 -1
  68. package/dist/validation/contract-validator.d.ts +8 -2
  69. package/dist/validation/contract-validator.d.ts.map +1 -1
  70. package/dist/validation/contract-validator.js +12 -4
  71. package/dist/validation/lint-contract.d.ts +2 -2
  72. package/dist/validation/lint-contract.d.ts.map +1 -1
  73. package/dist/validation/lint-contract.js +6 -4
  74. package/dist/validation/schema-subset.d.ts +3 -3
  75. package/dist/version.d.ts +445 -6
  76. package/dist/version.d.ts.map +1 -1
  77. package/dist/version.js +444 -5
  78. package/package.json +1 -1
  79. package/dist/envelope-adapters.d.ts +0 -12
  80. package/dist/envelope-adapters.d.ts.map +0 -1
  81. package/dist/envelope-adapters.js +0 -30
@@ -7,8 +7,8 @@
7
7
  * ## The normative total order
8
8
  *
9
9
  * ```
10
- * themeMode: consolePick > staticConfig > sessionSidecar > hostAnnounced
11
- * themeId: consolePick > renderOverride > staticConfig > sidecarName
10
+ * themeMode: hostAnnounced > consolePick > staticConfig > sessionSidecar
11
+ * themeId: consolePick > renderOverride > staticConfig
12
12
  * ```
13
13
  *
14
14
  * - `consolePick` — the live operator pick (console theme provider).
@@ -17,8 +17,12 @@
17
17
  * - `sessionSidecar` — the per-app `App.theme` sidecar snapshotted at
18
18
  * render-commit: its `mode` (for `themeMode`) / its `name` (for
19
19
  * `themeId`, the registered-theme base-ladder binding).
20
- * - `hostAnnounced` — the embedding host's `hostContext.theme`
21
- * (mode only; hosts announce no theme id).
20
+ * - `hostAnnounced` — the embedding host's `hostContext.theme` (mode
21
+ * only; hosts announce no theme id). HIGHEST rank since ggui#987 (D4):
22
+ * the embedding host owns runtime mode; every other layer is a default
23
+ * the host's announce overrides. A one-palette sidecar can no longer
24
+ * exist (`appThemeSchema` requires both projections), so following the
25
+ * host never paints the wrong palette.
22
26
  *
23
27
  * An unresolved fact is `undefined` — NEVER defaulted to `'light'`.
24
28
  * Absence is load-bearing: it is the signal that lets the next layer
@@ -72,7 +76,7 @@ export interface ThemeModeEffectiveSources {
72
76
  readonly stamped?: ThemeModeOpinion | undefined;
73
77
  /** The slice theme OBJECT's own `mode` (the sidecar, read directly). */
74
78
  readonly sessionSidecar?: ThemeModeOpinion | undefined;
75
- /** The embedding host's `hostContext.theme` announce — final fallback. */
79
+ /** The embedding host's `hostContext.theme` announce — HIGHEST rank (ggui#987). */
76
80
  readonly hostAnnounced?: ThemeModeOpinion | undefined;
77
81
  }
78
82
  /** Server projection of the `themeMode` total order → the stamped field. */
@@ -88,16 +92,14 @@ export interface ThemeIdStampSources {
88
92
  /** Static `ggui.json#theme` deps. */
89
93
  readonly staticConfig?: string | undefined;
90
94
  }
91
- /** Client-visible `themeId` layers, highest rank first. */
95
+ /**
96
+ * Client-visible `themeId` layers. Since ggui#987 (D2 = B, the registration
97
+ * tier is gone) the sidecar's `name` is a label and never a binding: the
98
+ * only client-visible layer is the stamp.
99
+ */
92
100
  export interface ThemeIdEffectiveSources {
93
101
  /** The slice's stamped top-level `themeId`. */
94
102
  readonly stamped?: string | undefined;
95
- /**
96
- * The slice theme OBJECT's `name` — the registered-theme base-ladder
97
- * binding (ggui#589 ask 3): an unregistered name is harmless by
98
- * construction (renderer falls back to the default ladder).
99
- */
100
- readonly sidecarName?: string | undefined;
101
103
  }
102
104
  /** Server projection of the `themeId` total order → the stamped field. */
103
105
  export declare function stampThemeId(s: ThemeIdStampSources): string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"theme-binding.d.ts","sourceRoot":"","sources":["../../src/integrations/theme-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpD,qCAAqC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrD,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACxD;AAED,6DAA6D;AAC7D,MAAM,WAAW,yBAAyB;IACxC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAChD,wEAAwE;IACxE,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvD,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACvD;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAC5B,CAAC,EAAE,qBAAqB,GACvB,gBAAgB,GAAG,SAAS,CAE9B;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,yBAAyB,GAC3B,gBAAgB,GAAG,SAAS,CAE9B;AAED,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,qCAAqC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAE/E"}
1
+ {"version":3,"file":"theme-binding.d.ts","sourceRoot":"","sources":["../../src/integrations/theme-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpD,qCAAqC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrD,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACxD;AAED,6DAA6D;AAC7D,MAAM,WAAW,yBAAyB;IACxC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAChD,wEAAwE;IACxE,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvD,mFAAmF;IACnF,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACvD;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAC5B,CAAC,EAAE,qBAAqB,GACvB,gBAAgB,GAAG,SAAS,CAE9B;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,yBAAyB,GAC3B,gBAAgB,GAAG,SAAS,CAE9B;AAED,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,qCAAqC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAE/E"}
@@ -7,8 +7,8 @@
7
7
  * ## The normative total order
8
8
  *
9
9
  * ```
10
- * themeMode: consolePick > staticConfig > sessionSidecar > hostAnnounced
11
- * themeId: consolePick > renderOverride > staticConfig > sidecarName
10
+ * themeMode: hostAnnounced > consolePick > staticConfig > sessionSidecar
11
+ * themeId: consolePick > renderOverride > staticConfig
12
12
  * ```
13
13
  *
14
14
  * - `consolePick` — the live operator pick (console theme provider).
@@ -17,8 +17,12 @@
17
17
  * - `sessionSidecar` — the per-app `App.theme` sidecar snapshotted at
18
18
  * render-commit: its `mode` (for `themeMode`) / its `name` (for
19
19
  * `themeId`, the registered-theme base-ladder binding).
20
- * - `hostAnnounced` — the embedding host's `hostContext.theme`
21
- * (mode only; hosts announce no theme id).
20
+ * - `hostAnnounced` — the embedding host's `hostContext.theme` (mode
21
+ * only; hosts announce no theme id). HIGHEST rank since ggui#987 (D4):
22
+ * the embedding host owns runtime mode; every other layer is a default
23
+ * the host's announce overrides. A one-palette sidecar can no longer
24
+ * exist (`appThemeSchema` requires both projections), so following the
25
+ * host never paints the wrong palette.
22
26
  *
23
27
  * An unresolved fact is `undefined` — NEVER defaulted to `'light'`.
24
28
  * Absence is load-bearing: it is the signal that lets the next layer
@@ -61,7 +65,7 @@ export function stampThemeMode(s) {
61
65
  }
62
66
  /** Client projection of the `themeMode` total order → the effective mode. */
63
67
  export function effectiveThemeMode(s) {
64
- return s.stamped ?? s.sessionSidecar ?? s.hostAnnounced;
68
+ return s.hostAnnounced ?? s.stamped ?? s.sessionSidecar;
65
69
  }
66
70
  /** Server projection of the `themeId` total order → the stamped field. */
67
71
  export function stampThemeId(s) {
@@ -69,5 +73,5 @@ export function stampThemeId(s) {
69
73
  }
70
74
  /** Client projection of the `themeId` total order → the effective id. */
71
75
  export function effectiveThemeId(s) {
72
- return s.stamped ?? s.sidecarName;
76
+ return s.stamped;
73
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"blueprint-key.d.ts","sourceRoot":"","sources":["../../src/registry/blueprint-key.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAGvE;AAMD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iCAAiC,EACjC,+BAA+B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,GACnC,MAAM,yBAAyB,CAAC;AAIjC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"blueprint-key.d.ts","sourceRoot":"","sources":["../../src/registry/blueprint-key.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAGvE;AAMD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iCAAiC,EACjC,+BAA+B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,GACnC,MAAM,yBAAyB,CAAC;AAIjC,cAAc,sBAAsB,CAAC"}
@@ -10,9 +10,10 @@
10
10
  * 16-character sha256 prefix — matches the existing `blueprintHash`
11
11
  * shape in `cache-trace-sink` and `generation-cache.ts`. Collision
12
12
  * probability for 100s-of-thousands of distinct contract is ~10^-6
13
- * (birthday-bound on 2^64), well below the budget for the OSS
14
- * single-tenant scope. Hosted multi-tenant deployments scope keys
15
- * by appId so the bound is per-tenant, never global.
13
+ * (birthday-bound on 2^64), well below the budget for a single
14
+ * deployment's key space. A deployment that serves many apps scopes
15
+ * keys by `appId`, so the bound holds per app, never across the whole
16
+ * store.
16
17
  */
17
18
  import { createHash } from 'node:crypto';
18
19
  import { canonicalizeContracts } from './canonicalize-contract.js';
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The generator PROFILE slot on an app's `generation` section (ggui#991;
4
+ * the D7 mechanism of ggui#987 — "chosen at generation time, like layout").
5
+ *
6
+ * Four members of free text the app's operator writes and the generator
7
+ * reads when it composes a component: `styling` is the brief (voice,
8
+ * mood, references), `density` and `layout` are one line each, and
9
+ * `direction` (2026-09-11, ggui#1027 follower) is the COMPOSITION
10
+ * direction of one variant — what leads (a hero panel, rows with arrows,
11
+ * a compact row of chips, a split panel), what is left out (icons,
12
+ * helper text, status lines), motion or none — one short paragraph, so
13
+ * a family of variants is one draft under one judge with the direction
14
+ * as the only arm. The slot
15
+ * is a GENERATION-TIME input: it is not a theme-document field, not a
16
+ * consumed token, and MUST never be projected into the `--ggui-*`
17
+ * vocabulary the card reads. An absent or empty profile MUST leave the
18
+ * generator's prompts byte-identical to today's.
19
+ *
20
+ * Parties and obligations:
21
+ * - WRITERS (an operator console, `ggui deploy`) send the object below
22
+ * through the app-config write door; the door trims, bounds each
23
+ * member at {@link APP_GENERATION_PROFILE_BOUNDS} and refuses control
24
+ * characters other than tab, newline and carriage return, answering
25
+ * `invalid_app_config` with {@link appGenerationProfileRefusalBodySchema}
26
+ * in the transport's refusal slot (REST 422 body, AppSync `errorInfo`,
27
+ * MCP `structuredContent`).
28
+ * - READERS (`@ggui-ai/ui-gen` behind the server's render path) cap
29
+ * defensively at the SAME numbers — a value over the bound is a door
30
+ * defect, never a second rule — and treat absent and empty alike.
31
+ *
32
+ * Observable violation: a profile that reaches the generator unbounded, or
33
+ * a profile name surfacing as a `--ggui-*` token, is non-conformant.
34
+ */
35
+ export declare const APP_GENERATION_PROFILE_BOUNDS: {
36
+ readonly styling: 2000;
37
+ readonly density: 200;
38
+ readonly layout: 200;
39
+ readonly direction: 600;
40
+ };
41
+ export type AppGenerationProfileMember = keyof typeof APP_GENERATION_PROFILE_BOUNDS;
42
+ /**
43
+ * The effort level (ggui#1058, founder's A2): ONE name over the reader's
44
+ * dials (model tier × turn cap × eval rounds × visual bar × judge model).
45
+ * The wire carries only the name; the name → dials table is the reader's
46
+ * (versioned by it), so a price line can move without a wire change.
47
+ * Absent ⇒ the deployment's default level, which MUST equal today's fixed
48
+ * options. A level the deployment has not enabled is REFUSED at the write
49
+ * door (`{ profile: { effort: 'unavailable' } }`) — never downgraded.
50
+ */
51
+ export declare const APP_GENERATION_PROFILE_EFFORTS: readonly ["low", "medium", "high", "xhigh", "ultra"];
52
+ export type AppGenerationProfileEffort = (typeof APP_GENERATION_PROFILE_EFFORTS)[number];
53
+ /** Catalogue entry ids are slugs: trace-line and path safe, 2–64 chars. */
54
+ export declare const APP_GENERATION_AESTHETIC_ID_RE: RegExp;
55
+ /** A preset content version: no whitespace, ≤ 32 chars. */
56
+ export declare const APP_GENERATION_AESTHETIC_VERSION_RE: RegExp;
57
+ /**
58
+ * A reference INTO the aesthetic/variance catalogue (data, kept by the
59
+ * deployment, never inside the generator): `id` is the catalogue entry — the
60
+ * same slug a draft carries as its variance `aesthetic` when both are
61
+ * present — and `version` pins the preset's content so a preset can be
62
+ * re-authored without re-keying served takes. The door validates GRAMMAR
63
+ * only; resolution happens at read, and an unresolvable reference is
64
+ * NON-FATAL: the generator proceeds without the aesthetic section and
65
+ * reports `profile_aesthetic_unresolved`.
66
+ */
67
+ export declare const appGenerationAestheticRefSchema: z.ZodObject<{
68
+ id: z.ZodString;
69
+ version: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strict>;
71
+ export type AppGenerationAestheticRef = z.infer<typeof appGenerationAestheticRefSchema>;
72
+ export declare const appGenerationProfileSchema: z.ZodObject<{
73
+ styling: z.ZodOptional<z.ZodString>;
74
+ density: z.ZodOptional<z.ZodString>;
75
+ layout: z.ZodOptional<z.ZodString>;
76
+ direction: z.ZodOptional<z.ZodString>;
77
+ effort: z.ZodOptional<z.ZodEnum<{
78
+ low: "low";
79
+ medium: "medium";
80
+ high: "high";
81
+ xhigh: "xhigh";
82
+ ultra: "ultra";
83
+ }>>;
84
+ aesthetic: z.ZodOptional<z.ZodObject<{
85
+ id: z.ZodString;
86
+ version: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strict>>;
88
+ }, z.core.$strict>;
89
+ export type AppGenerationProfile = z.infer<typeof appGenerationProfileSchema>;
90
+ /** Why the door refused one member — one reason per member, at least one member named. */
91
+ export declare const appGenerationProfileRefusalReasonSchema: z.ZodEnum<{
92
+ "too-long": "too-long";
93
+ "not-text": "not-text";
94
+ "control-chars": "control-chars";
95
+ unavailable: "unavailable";
96
+ }>;
97
+ export type AppGenerationProfileRefusalReason = z.infer<typeof appGenerationProfileRefusalReasonSchema>;
98
+ export declare const appGenerationProfileRefusalBodySchema: z.ZodObject<{
99
+ profile: z.ZodObject<{
100
+ styling: z.ZodOptional<z.ZodEnum<{
101
+ "too-long": "too-long";
102
+ "not-text": "not-text";
103
+ "control-chars": "control-chars";
104
+ unavailable: "unavailable";
105
+ }>>;
106
+ density: z.ZodOptional<z.ZodEnum<{
107
+ "too-long": "too-long";
108
+ "not-text": "not-text";
109
+ "control-chars": "control-chars";
110
+ unavailable: "unavailable";
111
+ }>>;
112
+ layout: z.ZodOptional<z.ZodEnum<{
113
+ "too-long": "too-long";
114
+ "not-text": "not-text";
115
+ "control-chars": "control-chars";
116
+ unavailable: "unavailable";
117
+ }>>;
118
+ direction: z.ZodOptional<z.ZodEnum<{
119
+ "too-long": "too-long";
120
+ "not-text": "not-text";
121
+ "control-chars": "control-chars";
122
+ unavailable: "unavailable";
123
+ }>>;
124
+ effort: z.ZodOptional<z.ZodEnum<{
125
+ "too-long": "too-long";
126
+ "not-text": "not-text";
127
+ "control-chars": "control-chars";
128
+ unavailable: "unavailable";
129
+ }>>;
130
+ aesthetic: z.ZodOptional<z.ZodEnum<{
131
+ "too-long": "too-long";
132
+ "not-text": "not-text";
133
+ "control-chars": "control-chars";
134
+ unavailable: "unavailable";
135
+ }>>;
136
+ }, z.core.$strict>;
137
+ }, z.core.$strict>;
138
+ export type AppGenerationProfileRefusalBody = z.infer<typeof appGenerationProfileRefusalBodySchema>;
139
+ //# sourceMappingURL=app-generation-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-generation-profile.d.ts","sourceRoot":"","sources":["../../src/schemas/app-generation-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,6BAA6B;;;;;CAKhC,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,MAAM,OAAO,6BAA6B,CAAC;AA0BpF;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,sDAAuD,CAAC;AACnG,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzF,2EAA2E;AAC3E,eAAO,MAAM,8BAA8B,QAA8B,CAAC;AAC1E,2DAA2D;AAC3D,eAAO,MAAM,mCAAmC,QAA2B,CAAC;AAE5E;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;kBAS5B,CAAC;AAEZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,0FAA0F;AAC1F,eAAO,MAAM,uCAAuC;;;;;EAAmE,CAAC;AACxH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC;AAExG,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAcvC,CAAC;AAEZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC"}
@@ -0,0 +1,121 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The generator PROFILE slot on an app's `generation` section (ggui#991;
4
+ * the D7 mechanism of ggui#987 — "chosen at generation time, like layout").
5
+ *
6
+ * Four members of free text the app's operator writes and the generator
7
+ * reads when it composes a component: `styling` is the brief (voice,
8
+ * mood, references), `density` and `layout` are one line each, and
9
+ * `direction` (2026-09-11, ggui#1027 follower) is the COMPOSITION
10
+ * direction of one variant — what leads (a hero panel, rows with arrows,
11
+ * a compact row of chips, a split panel), what is left out (icons,
12
+ * helper text, status lines), motion or none — one short paragraph, so
13
+ * a family of variants is one draft under one judge with the direction
14
+ * as the only arm. The slot
15
+ * is a GENERATION-TIME input: it is not a theme-document field, not a
16
+ * consumed token, and MUST never be projected into the `--ggui-*`
17
+ * vocabulary the card reads. An absent or empty profile MUST leave the
18
+ * generator's prompts byte-identical to today's.
19
+ *
20
+ * Parties and obligations:
21
+ * - WRITERS (an operator console, `ggui deploy`) send the object below
22
+ * through the app-config write door; the door trims, bounds each
23
+ * member at {@link APP_GENERATION_PROFILE_BOUNDS} and refuses control
24
+ * characters other than tab, newline and carriage return, answering
25
+ * `invalid_app_config` with {@link appGenerationProfileRefusalBodySchema}
26
+ * in the transport's refusal slot (REST 422 body, AppSync `errorInfo`,
27
+ * MCP `structuredContent`).
28
+ * - READERS (`@ggui-ai/ui-gen` behind the server's render path) cap
29
+ * defensively at the SAME numbers — a value over the bound is a door
30
+ * defect, never a second rule — and treat absent and empty alike.
31
+ *
32
+ * Observable violation: a profile that reaches the generator unbounded, or
33
+ * a profile name surfacing as a `--ggui-*` token, is non-conformant.
34
+ */
35
+ export const APP_GENERATION_PROFILE_BOUNDS = {
36
+ styling: 2000,
37
+ density: 200,
38
+ layout: 200,
39
+ direction: 600,
40
+ };
41
+ /**
42
+ * True when the text carries a C0 control character other than tab (0x09),
43
+ * newline (0x0A) or carriage return (0x0D), or DEL (0x7F). Written as a
44
+ * code-point walk on purpose: the intent is explicit, and no control
45
+ * character has to appear in source.
46
+ */
47
+ function hasForbiddenControlChars(text) {
48
+ for (const ch of text) {
49
+ const c = ch.codePointAt(0) ?? 0;
50
+ if (c === 0x7f)
51
+ return true;
52
+ if (c < 0x20 && c !== 0x09 && c !== 0x0a && c !== 0x0d)
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function profileText(member) {
58
+ const max = APP_GENERATION_PROFILE_BOUNDS[member];
59
+ return z
60
+ .string()
61
+ .trim()
62
+ .max(max, `generation.profile.${member} exceeds ${max} characters`)
63
+ .refine((s) => !hasForbiddenControlChars(s), `generation.profile.${member} contains control characters`);
64
+ }
65
+ /**
66
+ * The effort level (ggui#1058, founder's A2): ONE name over the reader's
67
+ * dials (model tier × turn cap × eval rounds × visual bar × judge model).
68
+ * The wire carries only the name; the name → dials table is the reader's
69
+ * (versioned by it), so a price line can move without a wire change.
70
+ * Absent ⇒ the deployment's default level, which MUST equal today's fixed
71
+ * options. A level the deployment has not enabled is REFUSED at the write
72
+ * door (`{ profile: { effort: 'unavailable' } }`) — never downgraded.
73
+ */
74
+ export const APP_GENERATION_PROFILE_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'ultra'];
75
+ /** Catalogue entry ids are slugs: trace-line and path safe, 2–64 chars. */
76
+ export const APP_GENERATION_AESTHETIC_ID_RE = /^[a-z0-9][a-z0-9-]{1,63}$/;
77
+ /** A preset content version: no whitespace, ≤ 32 chars. */
78
+ export const APP_GENERATION_AESTHETIC_VERSION_RE = /^[A-Za-z0-9._-]{1,32}$/;
79
+ /**
80
+ * A reference INTO the aesthetic/variance catalogue (data, kept by the
81
+ * deployment, never inside the generator): `id` is the catalogue entry — the
82
+ * same slug a draft carries as its variance `aesthetic` when both are
83
+ * present — and `version` pins the preset's content so a preset can be
84
+ * re-authored without re-keying served takes. The door validates GRAMMAR
85
+ * only; resolution happens at read, and an unresolvable reference is
86
+ * NON-FATAL: the generator proceeds without the aesthetic section and
87
+ * reports `profile_aesthetic_unresolved`.
88
+ */
89
+ export const appGenerationAestheticRefSchema = z
90
+ .object({
91
+ id: z.string().regex(APP_GENERATION_AESTHETIC_ID_RE, 'aesthetic id must be a slug (2–64 chars, lowercase, digits, dashes)'),
92
+ version: z.string().regex(APP_GENERATION_AESTHETIC_VERSION_RE, 'aesthetic version: 1–32 chars, no whitespace').optional(),
93
+ })
94
+ .strict();
95
+ export const appGenerationProfileSchema = z
96
+ .object({
97
+ styling: profileText('styling').optional(),
98
+ density: profileText('density').optional(),
99
+ layout: profileText('layout').optional(),
100
+ direction: profileText('direction').optional(),
101
+ effort: z.enum(APP_GENERATION_PROFILE_EFFORTS).optional(),
102
+ aesthetic: appGenerationAestheticRefSchema.optional(),
103
+ })
104
+ .strict();
105
+ /** Why the door refused one member — one reason per member, at least one member named. */
106
+ export const appGenerationProfileRefusalReasonSchema = z.enum(['too-long', 'not-text', 'control-chars', 'unavailable']);
107
+ export const appGenerationProfileRefusalBodySchema = z
108
+ .object({
109
+ profile: z
110
+ .object({
111
+ styling: appGenerationProfileRefusalReasonSchema.optional(),
112
+ density: appGenerationProfileRefusalReasonSchema.optional(),
113
+ layout: appGenerationProfileRefusalReasonSchema.optional(),
114
+ direction: appGenerationProfileRefusalReasonSchema.optional(),
115
+ effort: appGenerationProfileRefusalReasonSchema.optional(),
116
+ aesthetic: appGenerationProfileRefusalReasonSchema.optional(),
117
+ })
118
+ .strict()
119
+ .refine((p) => Object.keys(p).length > 0, 'a profile refusal names at least one member'),
120
+ })
121
+ .strict();
@@ -26,23 +26,249 @@ export declare const GGUI_CSS_VAR_KEY_RE: RegExp;
26
26
  * bare regex on its own.
27
27
  */
28
28
  export declare const CSS_VALUE_SAFE_RE: RegExp;
29
+ /**
30
+ * The grammar a per-mode `keyframes` string MUST satisfy (ggui#987 §3.4,
31
+ * follower D). The renderer injects the text verbatim into the card's
32
+ * `<style>` after the variables, so the text is bounded to what that slot
33
+ * is FOR: zero or more `@keyframes <ident> { <frame-selectors> { <declarations> } … }`
34
+ * blocks and nothing else — no other at-rule (`@import`, `@font-face`,
35
+ * `@media`, …), no `<` / `>`, braces balanced and nested exactly one level
36
+ * inside a block. Comments (`/* … *\/`) are stripped before the walk and are
37
+ * therefore allowed, as `cssVariableMap` values allow `url(`; the deny-list
38
+ * on values (`;{}<>@`) cannot apply verbatim here because `;`, `{`, `}` and
39
+ * the one `@` ARE the grammar. Same principal, same slot, one rule.
40
+ */
41
+ export declare const KEYFRAMES_NAME_RE: RegExp;
42
+ export declare function isKeyframesText(text: string): boolean;
43
+ /**
44
+ * One declared font face (ggui#987 §5; lifted here for ggui#1093 / #990 so the
45
+ * theme DOCUMENT's `typography.faces` and the AppTheme WIRE's `fonts` share
46
+ * ONE grammar — `@ggui-ai/project-config` imports this schema for the
47
+ * document door). `src` MUST be `https:` with a well-formed host; the face is
48
+ * DECLARED, never fetched by any door: the render host unions the origin into
49
+ * its `font-src`, the shell renders the `@font-face` rule, and a face that
50
+ * fails to load in the browser falls back down the family's stack.
51
+ */
52
+ export declare const fontFaceDeclarationSchema: z.ZodObject<{
53
+ family: z.ZodString;
54
+ src: z.ZodString;
55
+ weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
56
+ style: z.ZodOptional<z.ZodString>;
57
+ display: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strict>;
59
+ export type FontFaceDeclaration = z.infer<typeof fontFaceDeclarationSchema>;
60
+ /** The most faces one theme may declare on the wire — a CSP and a `<style>` block stay bounded. */
61
+ export declare const APP_THEME_FONTS_MAX = 16;
62
+ /** The imagery slots a theme may fill (ggui#1093): a brand mark, a hero image, a repeating pattern. */
63
+ export declare const APP_THEME_IMAGERY_KINDS: readonly ["mark", "hero", "pattern"];
64
+ export type AppThemeImageryKind = (typeof APP_THEME_IMAGERY_KINDS)[number];
65
+ /**
66
+ * One image asset: https-only `src` (never fetched by a door), an optional
67
+ * `alt` (≤ 200) and an optional `tone` — the image's own tonality (`light` /
68
+ * `dark`), so a composer can place ink over it without sampling pixels.
69
+ */
70
+ export declare const appThemeImageAssetSchema: z.ZodObject<{
71
+ src: z.ZodString;
72
+ alt: z.ZodOptional<z.ZodString>;
73
+ tone: z.ZodOptional<z.ZodEnum<{
74
+ light: "light";
75
+ dark: "dark";
76
+ }>>;
77
+ }, z.core.$strict>;
78
+ export type AppThemeImageAsset = z.infer<typeof appThemeImageAssetSchema>;
79
+ /**
80
+ * The host's imagery, by slot (ggui#1093, #1075 Track C (a)). Parties: a
81
+ * WRITER (an operator's design tooling, or a harvest of the host page) declares; the WRITE door
82
+ * validates this grammar and nothing more; the render host unions every
83
+ * `src` origin into its `img-src`; the composer reads the slots through
84
+ * the design primitives. Absent ⇒ no imagery, today's card.
85
+ */
86
+ export declare const appThemeImagerySchema: z.ZodObject<{
87
+ mark: z.ZodOptional<z.ZodObject<{
88
+ src: z.ZodString;
89
+ alt: z.ZodOptional<z.ZodString>;
90
+ tone: z.ZodOptional<z.ZodEnum<{
91
+ light: "light";
92
+ dark: "dark";
93
+ }>>;
94
+ }, z.core.$strict>>;
95
+ hero: z.ZodOptional<z.ZodObject<{
96
+ src: z.ZodString;
97
+ alt: z.ZodOptional<z.ZodString>;
98
+ tone: z.ZodOptional<z.ZodEnum<{
99
+ light: "light";
100
+ dark: "dark";
101
+ }>>;
102
+ }, z.core.$strict>>;
103
+ pattern: z.ZodOptional<z.ZodObject<{
104
+ src: z.ZodString;
105
+ alt: z.ZodOptional<z.ZodString>;
106
+ tone: z.ZodOptional<z.ZodEnum<{
107
+ light: "light";
108
+ dark: "dark";
109
+ }>>;
110
+ }, z.core.$strict>>;
111
+ }, z.core.$strict>;
112
+ export type AppThemeImagery = z.infer<typeof appThemeImagerySchema>;
29
113
  export declare const appThemeSchema: z.ZodObject<{
30
- mode: z.ZodEnum<{
114
+ mode: z.ZodOptional<z.ZodEnum<{
31
115
  light: "light";
32
116
  dark: "dark";
33
- }>;
34
- cssVariables: z.ZodRecord<z.ZodString, z.ZodString>;
117
+ }>>;
35
118
  name: z.ZodOptional<z.ZodString>;
36
- base: z.ZodOptional<z.ZodObject<{
37
- documentHash: z.ZodString;
119
+ overlayHash: z.ZodString;
120
+ overlays: z.ZodObject<{
38
121
  light: z.ZodRecord<z.ZodString, z.ZodString>;
39
122
  dark: z.ZodRecord<z.ZodString, z.ZodString>;
40
- keyframes: z.ZodOptional<z.ZodObject<{
41
- light: z.ZodOptional<z.ZodString>;
42
- dark: z.ZodOptional<z.ZodString>;
123
+ }, z.core.$strict>;
124
+ cssVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
125
+ keyframes: z.ZodOptional<z.ZodObject<{
126
+ light: z.ZodOptional<z.ZodString>;
127
+ dark: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strict>>;
129
+ frameless: z.ZodOptional<z.ZodBoolean>;
130
+ fonts: z.ZodOptional<z.ZodArray<z.ZodObject<{
131
+ family: z.ZodString;
132
+ src: z.ZodString;
133
+ weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
134
+ style: z.ZodOptional<z.ZodString>;
135
+ display: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$strict>>>;
137
+ imagery: z.ZodOptional<z.ZodObject<{
138
+ mark: z.ZodOptional<z.ZodObject<{
139
+ src: z.ZodString;
140
+ alt: z.ZodOptional<z.ZodString>;
141
+ tone: z.ZodOptional<z.ZodEnum<{
142
+ light: "light";
143
+ dark: "dark";
144
+ }>>;
145
+ }, z.core.$strict>>;
146
+ hero: z.ZodOptional<z.ZodObject<{
147
+ src: z.ZodString;
148
+ alt: z.ZodOptional<z.ZodString>;
149
+ tone: z.ZodOptional<z.ZodEnum<{
150
+ light: "light";
151
+ dark: "dark";
152
+ }>>;
153
+ }, z.core.$strict>>;
154
+ pattern: z.ZodOptional<z.ZodObject<{
155
+ src: z.ZodString;
156
+ alt: z.ZodOptional<z.ZodString>;
157
+ tone: z.ZodOptional<z.ZodEnum<{
158
+ light: "light";
159
+ dark: "dark";
160
+ }>>;
43
161
  }, z.core.$strict>>;
44
- frameless: z.ZodOptional<z.ZodBoolean>;
45
162
  }, z.core.$strict>>;
46
163
  }, z.core.$strict>;
47
164
  export type AppTheme = z.infer<typeof appThemeSchema>;
165
+ /**
166
+ * The READ-door posture (ggui#1093 belt, 2026-09-15; VERSION-POLICY §3.6).
167
+ *
168
+ * `appThemeSchema` is the WRITE door: strict, an unknown top-level member is
169
+ * refused (`invalid_app_config`). A READ door — a stored row turned into
170
+ * paint, a carried `_meta["ai.ggui/render"].theme` slice — parses with THIS
171
+ * schema instead: an unknown TOP-LEVEL member is stripped, the overlays are
172
+ * kept, and the caller reports what it stripped (one line per read, keys
173
+ * only, never theme content). Everything below the top level is unchanged —
174
+ * nested objects stay strict, token grammar and value safety still refuse,
175
+ * the v1 shape still refuses — and the attestation is untouched because
176
+ * `overlayHash` covers `{ overlays, cssVariables, keyframes }` only.
177
+ *
178
+ * Why: a reader on release N−1 meeting a member release N added would
179
+ * otherwise drop the WHOLE theme — colours and all — until it rolled
180
+ * (guuey#1266's class). Parties: every read door of an `AppTheme` MUST use
181
+ * this variant (or {@link parseAppThemeAtReadDoor}); every write door MUST
182
+ * stay on `appThemeSchema`. Observable violation: a read door dropping a
183
+ * theme whose overlays are valid because of an unknown top-level member —
184
+ * the kit's `n1-compat` forward case grades it.
185
+ */
186
+ export declare const appThemeReadSchema: z.ZodObject<{
187
+ mode: z.ZodOptional<z.ZodEnum<{
188
+ light: "light";
189
+ dark: "dark";
190
+ }>>;
191
+ name: z.ZodOptional<z.ZodString>;
192
+ overlayHash: z.ZodString;
193
+ overlays: z.ZodObject<{
194
+ light: z.ZodRecord<z.ZodString, z.ZodString>;
195
+ dark: z.ZodRecord<z.ZodString, z.ZodString>;
196
+ }, z.core.$strict>;
197
+ cssVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
198
+ keyframes: z.ZodOptional<z.ZodObject<{
199
+ light: z.ZodOptional<z.ZodString>;
200
+ dark: z.ZodOptional<z.ZodString>;
201
+ }, z.core.$strict>>;
202
+ frameless: z.ZodOptional<z.ZodBoolean>;
203
+ fonts: z.ZodOptional<z.ZodArray<z.ZodObject<{
204
+ family: z.ZodString;
205
+ src: z.ZodString;
206
+ weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
207
+ style: z.ZodOptional<z.ZodString>;
208
+ display: z.ZodOptional<z.ZodString>;
209
+ }, z.core.$strict>>>;
210
+ imagery: z.ZodOptional<z.ZodObject<{
211
+ mark: z.ZodOptional<z.ZodObject<{
212
+ src: z.ZodString;
213
+ alt: z.ZodOptional<z.ZodString>;
214
+ tone: z.ZodOptional<z.ZodEnum<{
215
+ light: "light";
216
+ dark: "dark";
217
+ }>>;
218
+ }, z.core.$strict>>;
219
+ hero: z.ZodOptional<z.ZodObject<{
220
+ src: z.ZodString;
221
+ alt: z.ZodOptional<z.ZodString>;
222
+ tone: z.ZodOptional<z.ZodEnum<{
223
+ light: "light";
224
+ dark: "dark";
225
+ }>>;
226
+ }, z.core.$strict>>;
227
+ pattern: z.ZodOptional<z.ZodObject<{
228
+ src: z.ZodString;
229
+ alt: z.ZodOptional<z.ZodString>;
230
+ tone: z.ZodOptional<z.ZodEnum<{
231
+ light: "light";
232
+ dark: "dark";
233
+ }>>;
234
+ }, z.core.$strict>>;
235
+ }, z.core.$strict>>;
236
+ }, z.core.$strip>;
237
+ export type AppThemeReadDoorResult = {
238
+ readonly ok: true;
239
+ readonly theme: AppTheme;
240
+ readonly stripped: readonly string[];
241
+ } | {
242
+ readonly ok: false;
243
+ readonly issues: readonly string[];
244
+ };
245
+ /**
246
+ * Parse a stored or carried theme at a READ door: `ok` with the theme and
247
+ * the top-level members that were stripped (payload order, `[]` when none),
248
+ * or the issues in `path: message` form when the theme is refused for a
249
+ * reason the write door would also refuse.
250
+ */
251
+ export declare function parseAppThemeAtReadDoor(input: unknown): AppThemeReadDoorResult;
252
+ /**
253
+ * The ONE refusal body every write door returns for an overlay it will not
254
+ * store (ggui#987 §3.4): REST 422 `invalid_app_config`, the AppSync
255
+ * `errorInfo`, the MCP ops door's `{ ok: false }` structured content. A
256
+ * discriminated union by key — exactly one of the four.
257
+ */
258
+ export declare const appThemeRefusalBodySchema: z.ZodUnion<readonly [z.ZodObject<{
259
+ uncovered: z.ZodObject<{
260
+ light: z.ZodArray<z.ZodString>;
261
+ dark: z.ZodArray<z.ZodString>;
262
+ }, z.core.$strict>;
263
+ }, z.core.$strict>, z.ZodObject<{
264
+ unknown: z.ZodObject<{
265
+ light: z.ZodArray<z.ZodString>;
266
+ dark: z.ZodArray<z.ZodString>;
267
+ }, z.core.$strict>;
268
+ }, z.core.$strict>, z.ZodObject<{
269
+ overlayHash: z.ZodLiteral<"mismatch">;
270
+ }, z.core.$strict>, z.ZodObject<{
271
+ refused: z.ZodLiteral<"v1 shape">;
272
+ }, z.core.$strict>]>;
273
+ export type AppThemeRefusalBody = z.infer<typeof appThemeRefusalBodySchema>;
48
274
  //# sourceMappingURL=app-theme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-theme.d.ts","sourceRoot":"","sources":["../../src/schemas/app-theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAA2B,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAahD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;kBAkDhB,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"app-theme.d.ts","sourceRoot":"","sources":["../../src/schemas/app-theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAA2B,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAahD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAE9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAoCrD;AAwBD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB;;;;;;kBAMpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,mGAAmG;AACnG,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,uGAAuG;AACvG,eAAO,MAAM,uBAAuB,sCAAuC,CAAC;AAC5E,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;;;;;;kBAInC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;kBAIhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoDhB,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAiC,CAAC;AAEjE,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAW9E;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;oBAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}