@ggui-ai/mcp-server-handlers 0.15.0 → 0.16.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 (143) hide show
  1. package/dist/app-discovery/errors.d.ts +2 -2
  2. package/dist/app-discovery/errors.js +2 -2
  3. package/dist/app-discovery/list-gadgets.d.ts +2 -2
  4. package/dist/app-discovery/list-gadgets.js +3 -3
  5. package/dist/app-discovery/list-themes.d.ts +1 -1
  6. package/dist/app-discovery/list-themes.js +2 -2
  7. package/dist/credits/get-credit-balance.d.ts +3 -3
  8. package/dist/credits/get-credit-balance.js +6 -6
  9. package/dist/credits/list-credit-transactions.d.ts +5 -6
  10. package/dist/credits/list-credit-transactions.d.ts.map +1 -1
  11. package/dist/credits/list-credit-transactions.js +4 -4
  12. package/dist/ops-apps/delete-app.d.ts +2 -2
  13. package/dist/ops-apps/delete-app.js +4 -4
  14. package/dist/ops-apps/identity.d.ts +1 -1
  15. package/dist/ops-apps/index.d.ts +2 -2
  16. package/dist/ops-apps/index.d.ts.map +1 -1
  17. package/dist/ops-apps/index.js +1 -1
  18. package/dist/ops-apps/list-apps.d.ts +3 -3
  19. package/dist/ops-apps/list-apps.js +3 -3
  20. package/dist/ops-apps/set-app-theme.d.ts +183 -62
  21. package/dist/ops-apps/set-app-theme.d.ts.map +1 -1
  22. package/dist/ops-apps/set-app-theme.js +99 -58
  23. package/dist/ops-apps/set-default-app.d.ts +1 -1
  24. package/dist/ops-apps/set-default-app.js +2 -2
  25. package/dist/ops-apps/types.d.ts +7 -7
  26. package/dist/ops-apps/types.d.ts.map +1 -1
  27. package/dist/ops-apps/types.js +1 -1
  28. package/dist/ops-apps/update-app.d.ts +3 -3
  29. package/dist/ops-apps/update-app.js +4 -4
  30. package/dist/ops-blueprint/delete.d.ts +3 -3
  31. package/dist/ops-blueprint/delete.js +5 -5
  32. package/dist/ops-blueprint/errors.d.ts +2 -2
  33. package/dist/ops-blueprint/errors.js +2 -2
  34. package/dist/ops-blueprint/register.d.ts +1 -1
  35. package/dist/ops-blueprint/register.js +1 -1
  36. package/dist/ops-blueprint/update.d.ts +4 -4
  37. package/dist/ops-blueprint/update.js +5 -5
  38. package/dist/ops-connector-keys/types.d.ts +2 -3
  39. package/dist/ops-connector-keys/types.d.ts.map +1 -1
  40. package/dist/ops-coupon/types.d.ts +2 -2
  41. package/dist/ops-orgs/list-orgs.d.ts +2 -2
  42. package/dist/ops-orgs/list-orgs.js +2 -2
  43. package/dist/ops-orgs/types.d.ts +1 -1
  44. package/dist/provider-keys/list-provider-keys.d.ts +5 -5
  45. package/dist/provider-keys/list-provider-keys.js +3 -3
  46. package/dist/provider-keys/remove-provider-key.d.ts +2 -2
  47. package/dist/provider-keys/set-provider-key.d.ts +3 -3
  48. package/dist/provider-keys/types.d.ts +4 -4
  49. package/dist/renders/apply-ggui-session-patch.d.ts +2 -2
  50. package/dist/renders/assert-gadgets.d.ts +3 -4
  51. package/dist/renders/assert-gadgets.d.ts.map +1 -1
  52. package/dist/renders/assert-gadgets.js +5 -8
  53. package/dist/renders/assert-no-duplicate-gadget-hooks.d.ts +2 -2
  54. package/dist/renders/assert-no-duplicate-gadget-hooks.d.ts.map +1 -1
  55. package/dist/renders/assert-no-duplicate-gadget-hooks.js +3 -4
  56. package/dist/renders/assert-public-env.d.ts +2 -2
  57. package/dist/renders/assert-public-env.d.ts.map +1 -1
  58. package/dist/renders/assert-public-env.js +3 -4
  59. package/dist/renders/blueprint-registry.d.ts +3 -3
  60. package/dist/renders/blueprint-registry.d.ts.map +1 -1
  61. package/dist/renders/blueprint-registry.js +6 -7
  62. package/dist/renders/cache-trace-sink.d.ts +1 -1
  63. package/dist/renders/cache-trace-sink.d.ts.map +1 -1
  64. package/dist/renders/consume.d.ts +87 -7
  65. package/dist/renders/consume.d.ts.map +1 -1
  66. package/dist/renders/consume.js +85 -76
  67. package/dist/renders/errors.d.ts +7 -7
  68. package/dist/renders/errors.d.ts.map +1 -1
  69. package/dist/renders/errors.js +10 -13
  70. package/dist/renders/fetch-gadget-types.d.ts +2 -2
  71. package/dist/renders/fetch-gadget-types.d.ts.map +1 -1
  72. package/dist/renders/fetch-gadget-types.js +3 -4
  73. package/dist/renders/generation-cache.d.ts +1 -1
  74. package/dist/renders/generation-cache.js +1 -1
  75. package/dist/renders/get-render-source.d.ts +3 -3
  76. package/dist/renders/get-render-source.js +5 -5
  77. package/dist/renders/get-session.d.ts +1 -1
  78. package/dist/renders/get-session.js +4 -4
  79. package/dist/renders/handshake.d.ts +6 -5
  80. package/dist/renders/handshake.d.ts.map +1 -1
  81. package/dist/renders/handshake.js +4 -5
  82. package/dist/renders/import-gate.d.ts +1 -1
  83. package/dist/renders/index.d.ts +3 -3
  84. package/dist/renders/index.d.ts.map +1 -1
  85. package/dist/renders/index.js +2 -2
  86. package/dist/renders/installed-blueprints-provider.js +0 -0
  87. package/dist/renders/list-sessions.d.ts +2 -2
  88. package/dist/renders/list-sessions.js +1 -1
  89. package/dist/renders/match-precision/pairs.js +1 -1
  90. package/dist/renders/payload-trace-sink.d.ts +1 -1
  91. package/dist/renders/payload-trace-sink.d.ts.map +1 -1
  92. package/dist/renders/props-mutation-core.js +3 -3
  93. package/dist/renders/provisional-preview.d.ts +4 -4
  94. package/dist/renders/provisional-preview.js +3 -3
  95. package/dist/renders/refresh-ws-token.d.ts +3 -3
  96. package/dist/renders/refresh-ws-token.js +2 -2
  97. package/dist/renders/render-identity.d.ts +1 -1
  98. package/dist/renders/render-source-envelope.d.ts +2 -2
  99. package/dist/renders/{tenancy.d.ts → render-visibility.d.ts} +3 -3
  100. package/dist/renders/render-visibility.d.ts.map +1 -0
  101. package/dist/renders/{tenancy.js → render-visibility.js} +1 -1
  102. package/dist/renders/render.d.ts +41 -25
  103. package/dist/renders/render.d.ts.map +1 -1
  104. package/dist/renders/render.js +91 -38
  105. package/dist/renders/runtime-pull.d.ts +6 -6
  106. package/dist/renders/runtime-pull.js +7 -7
  107. package/dist/renders/runtime-telemetry.d.ts +2 -2
  108. package/dist/renders/runtime-telemetry.js +1 -1
  109. package/dist/renders/slice-meta-derivation.d.ts +6 -35
  110. package/dist/renders/slice-meta-derivation.d.ts.map +1 -1
  111. package/dist/renders/slice-meta-derivation.js +13 -28
  112. package/dist/renders/stream-replay-ops.d.ts +2 -2
  113. package/dist/renders/stream-replay-ops.js +1 -1
  114. package/dist/renders/stream.d.ts +1 -1
  115. package/dist/renders/stream.js +2 -2
  116. package/dist/renders/submit-action.d.ts +1 -1
  117. package/dist/renders/submit-action.d.ts.map +1 -1
  118. package/dist/renders/submit-action.js +8 -4
  119. package/dist/renders/sync-context.js +1 -1
  120. package/dist/renders/tool-identity-catalog-store.d.ts +1 -1
  121. package/dist/renders/tool-identity-catalog-store.js +1 -1
  122. package/dist/renders/update.d.ts +3 -3
  123. package/dist/renders/update.d.ts.map +1 -1
  124. package/dist/renders/update.js +6 -6
  125. package/dist/types.d.ts +6 -6
  126. package/dist/types.js +2 -2
  127. package/package.json +8 -12
  128. package/dist/ops-themes/delete-theme.d.ts +0 -32
  129. package/dist/ops-themes/delete-theme.d.ts.map +0 -1
  130. package/dist/ops-themes/delete-theme.js +0 -42
  131. package/dist/ops-themes/index.d.ts +0 -9
  132. package/dist/ops-themes/index.d.ts.map +0 -1
  133. package/dist/ops-themes/index.js +0 -8
  134. package/dist/ops-themes/list-themes.d.ts +0 -43
  135. package/dist/ops-themes/list-themes.d.ts.map +0 -1
  136. package/dist/ops-themes/list-themes.js +0 -52
  137. package/dist/ops-themes/register-theme.d.ts +0 -65
  138. package/dist/ops-themes/register-theme.d.ts.map +0 -1
  139. package/dist/ops-themes/register-theme.js +0 -145
  140. package/dist/ops-themes/types.d.ts +0 -63
  141. package/dist/ops-themes/types.d.ts.map +0 -1
  142. package/dist/ops-themes/types.js +0 -50
  143. package/dist/renders/tenancy.d.ts.map +0 -1
@@ -6,10 +6,10 @@
6
6
  * handler-flow diagnostics, not contract-shape violations.
7
7
  */
8
8
  /**
9
- * Thrown by `ggui_list_gadgets` (and any future tenant-
9
+ * Thrown by `ggui_list_gadgets` (and any future app-
10
10
  * scoped app-discovery tool) when the caller supplies an explicit
11
11
  * `appId` that does NOT match `ctx.appId` resolved by the upstream
12
- * auth adapter. Cross-tenant probes get a uniform error so the
12
+ * auth adapter. Cross-app probes get a uniform error so the
13
13
  * existence of an alternate `appId` is not leaked.
14
14
  *
15
15
  * Recovery: omit `appId` to default to `ctx.appId`, or call from a
@@ -6,10 +6,10 @@
6
6
  * handler-flow diagnostics, not contract-shape violations.
7
7
  */
8
8
  /**
9
- * Thrown by `ggui_list_gadgets` (and any future tenant-
9
+ * Thrown by `ggui_list_gadgets` (and any future app-
10
10
  * scoped app-discovery tool) when the caller supplies an explicit
11
11
  * `appId` that does NOT match `ctx.appId` resolved by the upstream
12
- * auth adapter. Cross-tenant probes get a uniform error so the
12
+ * auth adapter. Cross-app probes get a uniform error so the
13
13
  * existence of an alternate `appId` is not leaked.
14
14
  *
15
15
  * Recovery: omit `appId` to default to `ctx.appId`, or call from a
@@ -14,7 +14,7 @@
14
14
  * `appId` defaults to `ctx.appId` resolved by the upstream auth
15
15
  * adapter.
16
16
  * 2. When `appId` is supplied explicitly, asserts it matches
17
- * `ctx.appId`; cross-tenant requests fail with
17
+ * `ctx.appId`; cross-app requests fail with
18
18
  * {@link AppAccessDeniedError}.
19
19
  * 3. Reads `app.gadgets` from the bound {@link AppMetadataStore}
20
20
  * and resolves the effective catalog via `resolveAppGadgets`
@@ -22,7 +22,7 @@
22
22
  * `null` (app not registered — common for OSS sandbox apps that
23
23
  * bypass an explicit register call) the resolution yields
24
24
  * exactly `STDLIB_GADGETS`, so callers always get a meaningful
25
- * catalog. This is a permitted-error path, not a tenancy
25
+ * catalog. This is a permitted-error path, not an app-scope
26
26
  * escape — `ctx.appId` was already proved by the auth adapter;
27
27
  * the absence of a registry row just means the deployment runs
28
28
  * default-seeded.
@@ -14,7 +14,7 @@
14
14
  * `appId` defaults to `ctx.appId` resolved by the upstream auth
15
15
  * adapter.
16
16
  * 2. When `appId` is supplied explicitly, asserts it matches
17
- * `ctx.appId`; cross-tenant requests fail with
17
+ * `ctx.appId`; cross-app requests fail with
18
18
  * {@link AppAccessDeniedError}.
19
19
  * 3. Reads `app.gadgets` from the bound {@link AppMetadataStore}
20
20
  * and resolves the effective catalog via `resolveAppGadgets`
@@ -22,7 +22,7 @@
22
22
  * `null` (app not registered — common for OSS sandbox apps that
23
23
  * bypass an explicit register call) the resolution yields
24
24
  * exactly `STDLIB_GADGETS`, so callers always get a meaningful
25
- * catalog. This is a permitted-error path, not a tenancy
25
+ * catalog. This is a permitted-error path, not an app-scope
26
26
  * escape — `ctx.appId` was already proved by the auth adapter;
27
27
  * the absence of a registry row just means the deployment runs
28
28
  * default-seeded.
@@ -50,7 +50,7 @@ const inputSchema = {
50
50
  .string()
51
51
  .min(1)
52
52
  .optional()
53
- .describe('The app id whose gadget catalog to return. Defaults to the caller-resolved app id from the auth header. Cross-tenant requests fail with app_access_denied.'),
53
+ .describe('The app id whose gadget catalog to return. Defaults to the caller-resolved app id from the auth header. Cross-app requests fail with app_access_denied.'),
54
54
  };
55
55
  /**
56
56
  * Output wire schema for one catalog entry. The handler returns
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * ## Behavior
11
11
  *
12
- * 1. Validates input shape (`{appId?: string}`). Cross-tenant
12
+ * 1. Validates input shape (`{appId?: string}`). Cross-app
13
13
  * access protected the same way as `ggui_list_gadgets`.
14
14
  * 2. Reads the global theme catalog via the bound `themes` dep
15
15
  * (a `() => readonly ThemeCatalogEntry[]` resolver — keeps the
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * ## Behavior
11
11
  *
12
- * 1. Validates input shape (`{appId?: string}`). Cross-tenant
12
+ * 1. Validates input shape (`{appId?: string}`). Cross-app
13
13
  * access protected the same way as `ggui_list_gadgets`.
14
14
  * 2. Reads the global theme catalog via the bound `themes` dep
15
15
  * (a `() => readonly ThemeCatalogEntry[]` resolver — keeps the
@@ -31,7 +31,7 @@ const inputSchema = {
31
31
  .string()
32
32
  .min(1)
33
33
  .optional()
34
- .describe('App id whose theme catalog to return. Defaults to the caller-resolved app id from the auth header. Cross-tenant requests fail with app_access_denied.'),
34
+ .describe('App id whose theme catalog to return. Defaults to the caller-resolved app id from the auth header. Cross-app requests fail with app_access_denied.'),
35
35
  };
36
36
  /**
37
37
  * Wire shape for a single theme entry. Mirrors `@ggui-ai/design`'s
@@ -11,13 +11,13 @@
11
11
  *
12
12
  * Identity scope: credit rows are keyed by USER identity, so the
13
13
  * handler reads `ctx.userId` when the host's auth layer resolves a
14
- * distinct per-user identity (multi-tenant hosts where `ctx.appId`
14
+ * distinct per-user identity (multi-app hosts where `ctx.appId`
15
15
  * names the caller's active app, not the caller), and falls back to
16
- * `ctx.appId` for single-tenant hosts whose auth adapter folds the
16
+ * `ctx.appId` for single-app hosts whose auth adapter folds the
17
17
  * user into the app slot (`appId = workspaceId ?? userId` — see
18
18
  * `packages/mcp-server/src/auth.ts#defaultAppIdFromIdentity`).
19
19
  * Reading `ctx.appId` alone silently returns the zero-row fallback
20
- * for every multi-tenant caller — an app id never keys a credit row.
20
+ * for every multi-app caller — an app id never keys a credit row.
21
21
  * The tool is registered on every deployment kind; callers without a
22
22
  * credit account (e.g. agent-builder identities) get the zero-row
23
23
  * fallback.
@@ -11,13 +11,13 @@
11
11
  *
12
12
  * Identity scope: credit rows are keyed by USER identity, so the
13
13
  * handler reads `ctx.userId` when the host's auth layer resolves a
14
- * distinct per-user identity (multi-tenant hosts where `ctx.appId`
14
+ * distinct per-user identity (multi-app hosts where `ctx.appId`
15
15
  * names the caller's active app, not the caller), and falls back to
16
- * `ctx.appId` for single-tenant hosts whose auth adapter folds the
16
+ * `ctx.appId` for single-app hosts whose auth adapter folds the
17
17
  * user into the app slot (`appId = workspaceId ?? userId` — see
18
18
  * `packages/mcp-server/src/auth.ts#defaultAppIdFromIdentity`).
19
19
  * Reading `ctx.appId` alone silently returns the zero-row fallback
20
- * for every multi-tenant caller — an app id never keys a credit row.
20
+ * for every multi-app caller — an app id never keys a credit row.
21
21
  * The tool is registered on every deployment kind; callers without a
22
22
  * credit account (e.g. agent-builder identities) get the zero-row
23
23
  * fallback.
@@ -43,13 +43,13 @@ export function createGetCreditBalanceHandler(deps) {
43
43
  description: "Returns the calling user's prepaid Anthropic-pool credit balance. Surfaces balanceCents (current spendable), lifetimeGrantedCents (total received including the $5 welcome credit), and lifetimeSpentCents (cumulative charges). For non-Anthropic providers, configure a BYOK key at console.ggui.ai/keys/providers — credit doesn't apply. Composing blueprints in Claude Desktop bypasses credits entirely.",
44
44
  inputSchema,
45
45
  outputSchema,
46
- // No `allowedFor` — same toolset on every pod kind. Callers
46
+ // No `allowedFor` — same toolset on every deployment kind. Callers
47
47
  // without a credit account get the zero-row fallback below; no
48
48
  // separate "tool not registered" UX needed.
49
49
  async handler(_input, ctx) {
50
- // USER identity first — on multi-tenant hosts `ctx.appId` is the
50
+ // USER identity first — on multi-app hosts `ctx.appId` is the
51
51
  // caller's active app, which never keys a credit row (see the
52
- // module docstring). Single-tenant hosts leave `ctx.userId`
52
+ // module docstring). Single-app hosts leave `ctx.userId`
53
53
  // unset and fold the user into the app slot.
54
54
  const userId = ctx.userId ?? ctx.appId;
55
55
  if (!userId) {
@@ -12,15 +12,14 @@
12
12
  *
13
13
  * Identity scope mirrors get-credit-balance: `ctx.userId` when the
14
14
  * host resolves a distinct per-user identity, else `ctx.appId` (the
15
- * single-tenant fold) — see that module's docstring for why reading
16
- * `ctx.appId` alone loses every multi-tenant caller.
15
+ * single-app fold) — see that module's docstring for why reading
16
+ * `ctx.appId` alone loses every multi-app caller.
17
17
  */
18
18
  import { z } from 'zod';
19
19
  /**
20
- * Read-only seam for the credit-transaction ledger. The pod's
21
- * `DdbCreditStore.listTransactions` (in
22
- * `mcp-servers/ggui-protocol/src/adapters/credit-store.ts`) implements
23
- * this directly via raw DDB Query.
20
+ * Read-only seam for the credit-transaction ledger. A production deployment
21
+ * implements this against its own ledger store; tests use in-memory
22
+ * state.
24
23
  */
25
24
  export interface CreditTransactionSource {
26
25
  list(args: {
@@ -1 +1 @@
1
- {"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,eAAe,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AAyBD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;IA5BhC,2BAA2B;;IAE3B,kEAAkE;;;;;;;;;;;;;;;;;IAgBlE,oFAAoF;;;;;GAgDrF"}
1
+ {"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,eAAe,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AAyBD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;IA5BhC,2BAA2B;;IAE3B,kEAAkE;;;;;;;;;;;;;;;;;IAgBlE,oFAAoF;;;;;GAgDrF"}
@@ -12,8 +12,8 @@
12
12
  *
13
13
  * Identity scope mirrors get-credit-balance: `ctx.userId` when the
14
14
  * host resolves a distinct per-user identity, else `ctx.appId` (the
15
- * single-tenant fold) — see that module's docstring for why reading
16
- * `ctx.appId` alone loses every multi-tenant caller.
15
+ * single-app fold) — see that module's docstring for why reading
16
+ * `ctx.appId` alone loses every multi-app caller.
17
17
  */
18
18
  import { z } from 'zod';
19
19
  import { defineHandler } from '../types.js';
@@ -44,11 +44,11 @@ export function createListCreditTransactionsHandler(deps) {
44
44
  description: "Returns the calling user's credit transaction ledger, newest-first. Each row carries kind ('free_credit' | 'render_charge' | 'topup' | 'refund'), deltaCents (signed — positive for grants/topups, negative for charges), balanceAfterCents (snapshot at time of write), reason (human-readable), and optional relatedSessionId for render_charge rows. Default limit 20, cap 100; pass `cursor` from the previous response's `nextCursor` for paging.",
45
45
  inputSchema,
46
46
  outputSchema,
47
- // No `allowedFor` — same toolset on every pod kind. Callers
47
+ // No `allowedFor` — same toolset on every deployment kind. Callers
48
48
  // without a credit account see an empty ledger.
49
49
  async handler(rawInput, ctx) {
50
50
  // USER identity first — `ctx.appId` is the active app on
51
- // multi-tenant hosts and never keys a ledger row (see
51
+ // multi-app hosts and never keys a ledger row (see
52
52
  // get-credit-balance's module docstring).
53
53
  const userId = ctx.userId ?? ctx.appId;
54
54
  if (!userId) {
@@ -2,7 +2,7 @@
2
2
  * `ggui_ops_delete_app` — hard-delete an app record owned by the
3
3
  * caller.
4
4
  *
5
- * Tenancy: cross-tenant probes return the success shape WITHOUT
5
+ * Ownership: cross-user probes return the success shape WITHOUT
6
6
  * touching the row (uniform shape; no existence leak). Idempotent —
7
7
  * a second delete of the same id resolves cleanly.
8
8
  *
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * The check runs AFTER the ownership read. `getDefault(ownerSub)`
14
14
  * only ever reads the caller's own row, so ordering is not what keeps
15
- * another tenant's default secret — nothing here could read it under
15
+ * another owner's default secret — nothing here could read it under
16
16
  * any ordering. What ordering buys is SHAPE UNIFORMITY in the one
17
17
  * state where the two branches disagree: the caller's own default
18
18
  * naming an app the caller does not own. Ownership first answers that
@@ -2,7 +2,7 @@
2
2
  * `ggui_ops_delete_app` — hard-delete an app record owned by the
3
3
  * caller.
4
4
  *
5
- * Tenancy: cross-tenant probes return the success shape WITHOUT
5
+ * Ownership: cross-user probes return the success shape WITHOUT
6
6
  * touching the row (uniform shape; no existence leak). Idempotent —
7
7
  * a second delete of the same id resolves cleanly.
8
8
  *
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * The check runs AFTER the ownership read. `getDefault(ownerSub)`
14
14
  * only ever reads the caller's own row, so ordering is not what keeps
15
- * another tenant's default secret — nothing here could read it under
15
+ * another owner's default secret — nothing here could read it under
16
16
  * any ordering. What ordering buys is SHAPE UNIFORMITY in the one
17
17
  * state where the two branches disagree: the caller's own default
18
18
  * naming an app the caller does not own. Ownership first answers that
@@ -48,7 +48,7 @@ export function createDeleteAppHandler(deps) {
48
48
  name: 'ggui_ops_delete_app',
49
49
  title: 'Delete app',
50
50
  audience: ['ops'],
51
- description: "Hard-delete an app owned by the calling user. Removes the APP RECORD only — data other stores hold for that app (saved blueprints, per-app provider keys, marketplace installs, issued keys) is not removed by this call, and whether the deployment cleans it up separately is the deployment's own policy. Idempotent — a second delete returns `{deleted: true}`. Cross-tenant probes return the same shape without touching foreign rows (no existence leak). Throws `default_app_delete_blocked` when the target is the caller's default app — set a different default first.",
51
+ description: "Hard-delete an app owned by the calling user. Removes the APP RECORD only — data other stores hold for that app (saved blueprints, per-app provider keys, marketplace installs, issued keys) is not removed by this call, and whether the deployment cleans it up separately is the deployment's own policy. Idempotent — a second delete returns `{deleted: true}`. Probes at an app owned by another user return the same shape without touching foreign rows (no existence leak). Throws `default_app_delete_blocked` when the target is the caller's default app — set a different default first.",
52
52
  inputSchema,
53
53
  outputSchema,
54
54
  async handler(rawInput, ctx) {
@@ -62,7 +62,7 @@ export function createDeleteAppHandler(deps) {
62
62
  // Either the row doesn't exist or it lives under a different
63
63
  // owner. Either way: return the success shape without
64
64
  // touching the store. Uniform across "missing" and
65
- // "cross-tenant" prevents id-existence leak.
65
+ // "cross-user" prevents id-existence leak.
66
66
  return { deleted: true };
67
67
  }
68
68
  // AFTER the ownership read, so a caller whose own default names
@@ -2,7 +2,7 @@
2
2
  * Per-call identity resolution for `ops-apps` handlers. The console
3
3
  * surfaces these tools call against `kind: 'user'` identities — the
4
4
  * upstream `AuthAdapter` populates `ctx.userId` directly. OSS
5
- * single-tenant mode (where the auth adapter collapses `appId =
5
+ * single-app mode (where the auth adapter collapses `appId =
6
6
  * workspaceId ?? userId`) leaves `ctx.userId` undefined and the same
7
7
  * value sits on `ctx.appId`. Read whichever is set; fail when neither
8
8
  * is.
@@ -21,8 +21,8 @@ export { createCreateAppHandler } from './create-app.js';
21
21
  export type { CreateAppDeps, CreateAppOutput } from './create-app.js';
22
22
  export { createUpdateAppHandler } from './update-app.js';
23
23
  export type { UpdateAppDeps, UpdateAppOutput } from './update-app.js';
24
- export { createSetAppThemeHandler } from './set-app-theme.js';
25
- export type { SetAppThemeDeps, SetAppThemeOutput, } from './set-app-theme.js';
24
+ export { createSetAppThemeHandler, admitAppTheme } from './set-app-theme.js';
25
+ export type { SetAppThemeDeps, SetAppThemeOutput, OverlayCoverageValidator, AppThemeAdmission, } from './set-app-theme.js';
26
26
  export { createDeleteAppHandler } from './delete-app.js';
27
27
  export type { DeleteAppDeps, DeleteAppOutput } from './delete-app.js';
28
28
  export { createSetDefaultAppHandler } from './set-default-app.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ops-apps/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,YAAY,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ops-apps/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,YAAY,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7E,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC"}
@@ -17,6 +17,6 @@ export { AppNotFoundError, DefaultAppDeleteBlockedError, OpsAppsAccessDeniedErro
17
17
  export { createListAppsHandler } from './list-apps.js';
18
18
  export { createCreateAppHandler } from './create-app.js';
19
19
  export { createUpdateAppHandler } from './update-app.js';
20
- export { createSetAppThemeHandler } from './set-app-theme.js';
20
+ export { createSetAppThemeHandler, admitAppTheme } from './set-app-theme.js';
21
21
  export { createDeleteAppHandler } from './delete-app.js';
22
22
  export { createSetDefaultAppHandler } from './set-default-app.js';
@@ -2,12 +2,12 @@
2
2
  * `ggui_ops_list_apps` — enumerate the calling user's `GguiApp` rows.
3
3
  *
4
4
  * Sibling of the console's Apps section (`apps/console/src/.../apps/`)
5
- * — same data, MCP surface. Pure over the {@link AppsSource} seam; the
6
- * cloud pod binds an AppSync-backed implementation, tests bind an
5
+ * — same data, MCP surface. Pure over the {@link AppsSource} seam; a
6
+ * production deployment binds its own implementation, tests bind an
7
7
  * in-memory Map.
8
8
  *
9
9
  * Identity scope: caller's Cognito sub from `ctx.userId` (or
10
- * `ctx.appId` in OSS single-tenant mode). Cross-user list is impossible
10
+ * `ctx.appId` in OSS single-app mode). Cross-user list is impossible
11
11
  * by construction — `AppsSource.list` only returns rows whose
12
12
  * `ownerSub` matches.
13
13
  */
@@ -2,12 +2,12 @@
2
2
  * `ggui_ops_list_apps` — enumerate the calling user's `GguiApp` rows.
3
3
  *
4
4
  * Sibling of the console's Apps section (`apps/console/src/.../apps/`)
5
- * — same data, MCP surface. Pure over the {@link AppsSource} seam; the
6
- * cloud pod binds an AppSync-backed implementation, tests bind an
5
+ * — same data, MCP surface. Pure over the {@link AppsSource} seam; a
6
+ * production deployment binds its own implementation, tests bind an
7
7
  * in-memory Map.
8
8
  *
9
9
  * Identity scope: caller's Cognito sub from `ctx.userId` (or
10
- * `ctx.appId` in OSS single-tenant mode). Cross-user list is impossible
10
+ * `ctx.appId` in OSS single-app mode). Cross-user list is impossible
11
11
  * by construction — `AppsSource.list` only returns rows whose
12
12
  * `ownerSub` matches.
13
13
  */
@@ -1,95 +1,216 @@
1
1
  /**
2
2
  * `ggui_ops_set_app_theme` — replace the theme on a `GguiApp` row the
3
- * caller owns.
3
+ * caller owns. The MCP write door for the per-app theme (ggui#987
4
+ * §3.4).
4
5
  *
5
- * The theme payload is validated with the protocol's canonical
6
- * {@link appThemeSchema} — the SAME validator every other write
7
- * surface for `GguiApp.theme` runs — so no surface can persist a
8
- * theme another surface would reject: `--ggui-*` CSS-variable keys
9
- * only, value-level breakout characters forbidden, ≤200 variables.
6
+ * A theme is the PROJECTION: both modes' derived `--ggui-*` sets plus
7
+ * the attestation that names them. The door admits it in three
8
+ * checks, the SAME three every other write door for `GguiApp.theme`
9
+ * runs, so no surface can persist a theme another surface would
10
+ * refuse:
10
11
  *
11
- * Tenancy: `AppsSource.get` first (scoped by `ownerSub`); cross-user
12
+ * 1. shape — protocol's `appThemeSchema` (v2, `.strict()`); the
13
+ * retired one-palette body is named as such (`refused: 'v1
14
+ * shape'`) rather than failing as a pile of missing fields;
15
+ * 2. attestation — `overlayHash` is recomputed with
16
+ * `canonicalOverlayHash` and a mismatch is refused;
17
+ * 3. coverage — the injected overlay validator judges each mode's
18
+ * set against the consumed-token manifest: a key outside the
19
+ * manifest (`unknown`) or a consumed token left unset
20
+ * (`uncovered`) is refused, per mode.
21
+ *
22
+ * A refusal is a schema-conformant `{ ok: false, code:
23
+ * 'invalid_app_config', refusal }` RESULT (not a thrown error): the
24
+ * body is one of the four the protocol names
25
+ * (`appThemeRefusalBodySchema`), so a client reads the same refusal
26
+ * from REST, AppSync and this door.
27
+ *
28
+ * Ownership: `AppsSource.get` first (scoped by `ownerSub`); cross-user
12
29
  * probes return the uniform "not found" shape. The store scopes the
13
30
  * write itself to the owner as well.
14
31
  *
15
- * Pure over the {@link AppsSource} seam.
32
+ * Pure over the {@link AppsSource} seam + the injected validator.
16
33
  */
17
- import { appThemeSchema } from '@ggui-ai/protocol';
34
+ import { type AppTheme, type AppThemeRefusalBody } from '@ggui-ai/protocol';
18
35
  import { z } from 'zod';
36
+ import { type SharedHandlerResult } from '../types.js';
19
37
  import type { AppsSource } from './types.js';
20
- export interface SetAppThemeOutput {
21
- readonly appId: string;
22
- readonly theme: z.infer<typeof appThemeSchema>;
23
- readonly updatedAt: string;
24
- readonly warning?: string;
25
- }
38
+ /**
39
+ * The coverage judgement over ONE mode's overlay, as `@ggui-ai/design`'s
40
+ * `validateOverlayCoverage` reports it. Injected rather than imported:
41
+ * the manifest is the design package's, and the composer binds it.
42
+ */
43
+ export type OverlayCoverageValidator = (overlay: Readonly<Record<string, string>>) => {
44
+ readonly uncovered: readonly string[];
45
+ readonly unknown: readonly string[];
46
+ readonly warnings: readonly string[];
47
+ };
48
+ declare const outputSchema: {
49
+ readonly ok: z.ZodBoolean;
50
+ readonly appId: z.ZodOptional<z.ZodString>;
51
+ readonly theme: z.ZodOptional<z.ZodObject<{
52
+ mode: z.ZodOptional<z.ZodEnum<{
53
+ light: "light";
54
+ dark: "dark";
55
+ }>>;
56
+ name: z.ZodOptional<z.ZodString>;
57
+ overlayHash: z.ZodString;
58
+ overlays: z.ZodObject<{
59
+ light: z.ZodRecord<z.ZodString, z.ZodString>;
60
+ dark: z.ZodRecord<z.ZodString, z.ZodString>;
61
+ }, z.core.$strict>;
62
+ cssVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
63
+ keyframes: z.ZodOptional<z.ZodObject<{
64
+ light: z.ZodOptional<z.ZodString>;
65
+ dark: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strict>>;
67
+ frameless: z.ZodOptional<z.ZodBoolean>;
68
+ }, z.core.$strict>>;
69
+ readonly updatedAt: z.ZodOptional<z.ZodString>;
70
+ /** Present on a refusal: the one refusal class this door emits. */
71
+ readonly code: z.ZodOptional<z.ZodLiteral<"invalid_app_config">>;
72
+ /** Present on a coverage / attestation / v1-shape refusal — one of the four protocol-named bodies. */
73
+ readonly refusal: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
74
+ uncovered: z.ZodObject<{
75
+ light: z.ZodArray<z.ZodString>;
76
+ dark: z.ZodArray<z.ZodString>;
77
+ }, z.core.$strict>;
78
+ }, z.core.$strict>, z.ZodObject<{
79
+ unknown: z.ZodObject<{
80
+ light: z.ZodArray<z.ZodString>;
81
+ dark: z.ZodArray<z.ZodString>;
82
+ }, z.core.$strict>;
83
+ }, z.core.$strict>, z.ZodObject<{
84
+ overlayHash: z.ZodLiteral<"mismatch">;
85
+ }, z.core.$strict>, z.ZodObject<{
86
+ refused: z.ZodLiteral<"v1 shape">;
87
+ }, z.core.$strict>]>>;
88
+ /** Present on a shape refusal the schema itself raised — its messages, one per issue. */
89
+ readonly issues: z.ZodOptional<z.ZodArray<z.ZodString>>;
90
+ };
91
+ /** Derived from the output schema — one shape, never a hand mirror. */
92
+ export type SetAppThemeOutput = z.infer<z.ZodObject<typeof outputSchema>>;
26
93
  export interface SetAppThemeDeps {
27
94
  readonly apps: AppsSource;
28
- /**
29
- * Known theme ids (built-in presets + registered) for the
30
- * brand-shaped-overlay WARN's name resolution. Absent = names cannot
31
- * be resolved, so brand-scale coverage always draws the nudge.
32
- */
33
- readonly knownThemeIds?: readonly string[];
95
+ /** Coverage judgement per mode — bind to `validateOverlayCoverage` from `@ggui-ai/design`. */
96
+ readonly overlayCoverage: OverlayCoverageValidator;
34
97
  }
98
+ /** The door's verdict on a raw body: the theme to persist, or why not. */
99
+ export type AppThemeAdmission = {
100
+ readonly ok: true;
101
+ readonly theme: AppTheme;
102
+ } | {
103
+ readonly ok: false;
104
+ readonly refusal: AppThemeRefusalBody;
105
+ } | {
106
+ readonly ok: false;
107
+ readonly issues: readonly string[];
108
+ };
35
109
  /**
36
- * Detect a BRAND-SHAPED overlay (ggui#598 slice 3): ≥3 distinct color
37
- * families in the variable map while the overlay's `name` resolves to
38
- * no known theme. A brand living in the accent tier is the round-3
39
- * mechanism — the overlay inherits every unmapped token from someone
40
- * else's ladder. The WARN names the registration path; it never
41
- * blocks. Exported for its unit pins.
42
- *
43
- * @internal
110
+ * Admit a raw theme body: shape, attestation, coverage — in that order,
111
+ * first failure wins; `unknown` outranks `uncovered` because a key the
112
+ * manifest does not name is the more fundamental disagreement. Exported
113
+ * so any other in-process door runs exactly these checks.
44
114
  */
45
- export declare function detectBrandShapedOverlay(theme: z.infer<typeof appThemeSchema>, deps: Pick<SetAppThemeDeps, 'knownThemeIds'>): string | undefined;
115
+ export declare function admitAppTheme(raw: unknown, overlayCoverage: OverlayCoverageValidator): Promise<AppThemeAdmission>;
46
116
  export declare function createSetAppThemeHandler(deps: SetAppThemeDeps): import("../types.js").SharedHandler<{
47
117
  readonly appId: z.ZodString;
48
118
  readonly theme: z.ZodObject<{
49
- mode: z.ZodEnum<{
119
+ mode: z.ZodOptional<z.ZodEnum<{
50
120
  light: "light";
51
121
  dark: "dark";
52
- }>;
53
- cssVariables: z.ZodRecord<z.ZodString, z.ZodString>;
122
+ }>>;
54
123
  name: z.ZodOptional<z.ZodString>;
55
- base: z.ZodOptional<z.ZodObject<{
56
- documentHash: z.ZodString;
124
+ overlayHash: z.ZodString;
125
+ overlays: z.ZodObject<{
57
126
  light: z.ZodRecord<z.ZodString, z.ZodString>;
58
127
  dark: z.ZodRecord<z.ZodString, z.ZodString>;
59
- keyframes: z.ZodOptional<z.ZodObject<{
60
- light: z.ZodOptional<z.ZodString>;
61
- dark: z.ZodOptional<z.ZodString>;
62
- }, z.core.$strict>>;
63
- frameless: z.ZodOptional<z.ZodBoolean>;
128
+ }, z.core.$strict>;
129
+ cssVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
130
+ keyframes: z.ZodOptional<z.ZodObject<{
131
+ light: z.ZodOptional<z.ZodString>;
132
+ dark: z.ZodOptional<z.ZodString>;
64
133
  }, z.core.$strict>>;
134
+ frameless: z.ZodOptional<z.ZodBoolean>;
65
135
  }, z.core.$strict>;
66
136
  }, {
67
- readonly appId: z.ZodString;
68
- readonly theme: z.ZodObject<{
69
- mode: z.ZodEnum<{
137
+ readonly ok: z.ZodBoolean;
138
+ readonly appId: z.ZodOptional<z.ZodString>;
139
+ readonly theme: z.ZodOptional<z.ZodObject<{
140
+ mode: z.ZodOptional<z.ZodEnum<{
70
141
  light: "light";
71
142
  dark: "dark";
72
- }>;
73
- cssVariables: z.ZodRecord<z.ZodString, z.ZodString>;
143
+ }>>;
74
144
  name: z.ZodOptional<z.ZodString>;
75
- base: z.ZodOptional<z.ZodObject<{
76
- documentHash: z.ZodString;
145
+ overlayHash: z.ZodString;
146
+ overlays: z.ZodObject<{
77
147
  light: z.ZodRecord<z.ZodString, z.ZodString>;
78
148
  dark: z.ZodRecord<z.ZodString, z.ZodString>;
79
- keyframes: z.ZodOptional<z.ZodObject<{
80
- light: z.ZodOptional<z.ZodString>;
81
- dark: z.ZodOptional<z.ZodString>;
82
- }, z.core.$strict>>;
83
- frameless: z.ZodOptional<z.ZodBoolean>;
149
+ }, z.core.$strict>;
150
+ cssVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
151
+ keyframes: z.ZodOptional<z.ZodObject<{
152
+ light: z.ZodOptional<z.ZodString>;
153
+ dark: z.ZodOptional<z.ZodString>;
84
154
  }, z.core.$strict>>;
85
- }, z.core.$strict>;
86
- readonly updatedAt: z.ZodString;
87
- /**
88
- * Migration nudge (ggui#598 slice 3): present when the overlay is
89
- * BRAND-SHAPED — ≥3 color families over a name that resolves to no
90
- * registered theme. The write still succeeds (overlays stay legal);
91
- * the tier just stops being silent about brands living in it.
92
- */
93
- readonly warning: z.ZodOptional<z.ZodString>;
94
- }, SetAppThemeOutput>;
155
+ frameless: z.ZodOptional<z.ZodBoolean>;
156
+ }, z.core.$strict>>;
157
+ readonly updatedAt: z.ZodOptional<z.ZodString>;
158
+ /** Present on a refusal: the one refusal class this door emits. */
159
+ readonly code: z.ZodOptional<z.ZodLiteral<"invalid_app_config">>;
160
+ /** Present on a coverage / attestation / v1-shape refusal — one of the four protocol-named bodies. */
161
+ readonly refusal: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
162
+ uncovered: z.ZodObject<{
163
+ light: z.ZodArray<z.ZodString>;
164
+ dark: z.ZodArray<z.ZodString>;
165
+ }, z.core.$strict>;
166
+ }, z.core.$strict>, z.ZodObject<{
167
+ unknown: z.ZodObject<{
168
+ light: z.ZodArray<z.ZodString>;
169
+ dark: z.ZodArray<z.ZodString>;
170
+ }, z.core.$strict>;
171
+ }, z.core.$strict>, z.ZodObject<{
172
+ overlayHash: z.ZodLiteral<"mismatch">;
173
+ }, z.core.$strict>, z.ZodObject<{
174
+ refused: z.ZodLiteral<"v1 shape">;
175
+ }, z.core.$strict>]>>;
176
+ /** Present on a shape refusal the schema itself raised — its messages, one per issue. */
177
+ readonly issues: z.ZodOptional<z.ZodArray<z.ZodString>>;
178
+ }, SharedHandlerResult<{
179
+ ok: boolean;
180
+ appId?: string | undefined;
181
+ theme?: {
182
+ overlayHash: string;
183
+ overlays: {
184
+ light: Record<string, string>;
185
+ dark: Record<string, string>;
186
+ };
187
+ mode?: "light" | "dark" | undefined;
188
+ name?: string | undefined;
189
+ cssVariables?: Record<string, string> | undefined;
190
+ keyframes?: {
191
+ light?: string | undefined;
192
+ dark?: string | undefined;
193
+ } | undefined;
194
+ frameless?: boolean | undefined;
195
+ } | undefined;
196
+ updatedAt?: string | undefined;
197
+ code?: "invalid_app_config" | undefined;
198
+ refusal?: {
199
+ uncovered: {
200
+ light: string[];
201
+ dark: string[];
202
+ };
203
+ } | {
204
+ unknown: {
205
+ light: string[];
206
+ dark: string[];
207
+ };
208
+ } | {
209
+ overlayHash: "mismatch";
210
+ } | {
211
+ refused: "v1 shape";
212
+ } | undefined;
213
+ issues?: string[] | undefined;
214
+ }>>;
215
+ export {};
95
216
  //# sourceMappingURL=set-app-theme.d.ts.map