@ggui-ai/protocol-conformance 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 (54) hide show
  1. package/README.md +23 -15
  2. package/dist/cli.d.ts +6 -2
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +52 -6
  5. package/dist/domain-error-conformance/cases/amend-unknown-session.json +9 -0
  6. package/dist/domain-error-conformance/cases/consume-unknown-session.json +9 -0
  7. package/dist/domain-error-conformance/cases/emit-unknown-session.json +9 -0
  8. package/dist/domain-error-conformance/cases/get-session-unknown-session.json +6 -0
  9. package/dist/domain-error-conformance/cases/render-unknown-handshake.json +6 -0
  10. package/dist/domain-error-conformance/cases/update-unknown-session.json +9 -0
  11. package/dist/domain-error-conformance/index.d.ts +97 -0
  12. package/dist/domain-error-conformance/index.d.ts.map +1 -0
  13. package/dist/domain-error-conformance/index.js +97 -0
  14. package/dist/fixtures/index.d.ts +2 -2
  15. package/dist/fixtures/index.d.ts.map +1 -1
  16. package/dist/fixtures/index.js +3 -3
  17. package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/absent-appid-defaults.json +1 -1
  18. package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/app-mismatch.json +1 -1
  19. package/dist/fixtures/subscribe-app-scope/index.d.ts +6 -0
  20. package/dist/fixtures/subscribe-app-scope/index.d.ts.map +1 -0
  21. package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/index.js +5 -5
  22. package/dist/index.d.ts +5 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +5 -1
  25. package/dist/refusal-envelope-conformance/cases/refuse-after-fix-caller.json +3 -3
  26. package/dist/refusal-envelope-conformance/cases/refuse-non-render-surface.json +4 -4
  27. package/dist/run-conformance.d.ts +13 -3
  28. package/dist/run-conformance.d.ts.map +1 -1
  29. package/dist/run-conformance.js +61 -7
  30. package/dist/theme-binding-conformance/cases/app-theme-v1-base.json +18 -0
  31. package/dist/theme-binding-conformance/cases/app-theme-v1-one-palette.json +11 -0
  32. package/dist/theme-binding-conformance/cases/app-theme-v2-accepted.json +18 -0
  33. package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-accepted.json +16 -0
  34. package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-not-keyframes.json +15 -0
  35. package/dist/theme-binding-conformance/cases/app-theme-v2-label-too-long.json +17 -0
  36. package/dist/theme-binding-conformance/cases/app-theme-v2-missing-dark.json +13 -0
  37. package/dist/theme-binding-conformance/cases/app-theme-v2-no-hash.json +15 -0
  38. package/dist/theme-binding-conformance/cases/app-theme-v2-platform-pin.json +17 -0
  39. package/dist/theme-binding-conformance/cases/overlay-hash-canonical.json +17 -0
  40. package/dist/theme-binding-conformance/cases/theme-mode-absence.json +10 -0
  41. package/dist/theme-binding-conformance/cases/theme-mode-default-when-silent-host.json +10 -0
  42. package/dist/theme-binding-conformance/cases/theme-mode-order.json +10 -0
  43. package/dist/theme-binding-conformance/index.d.ts +59 -0
  44. package/dist/theme-binding-conformance/index.d.ts.map +1 -0
  45. package/dist/theme-binding-conformance/index.js +110 -0
  46. package/dist/transport-refusal-conformance/cases/refuse-deprovisioned-endpoint.json +7 -5
  47. package/dist/transport-refusal-conformance/cases/refuse-render-only-code.json +3 -2
  48. package/dist/transport-refusal-conformance/index.d.ts +2 -0
  49. package/dist/transport-refusal-conformance/index.d.ts.map +1 -1
  50. package/dist/transport-refusal-conformance/index.js +2 -2
  51. package/dist/types.d.ts +1 -1
  52. package/package.json +12 -2
  53. package/dist/fixtures/subscribe-tenancy/index.d.ts +0 -6
  54. package/dist/fixtures/subscribe-tenancy/index.d.ts.map +0 -1
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Theme-binding conformance — a pure-function catalog (ggui#987).
3
+ *
4
+ * Three contracts the kit grades directly against `@ggui-ai/protocol`, so
5
+ * their breaking-ness is decided by a fixture and not by prose
6
+ * (VERSION-POLICY §2 — the kit is the arbiter):
7
+ *
8
+ * - `theme-mode-*` — the CLIENT projection of the `themeMode` total
9
+ * order, `effectiveThemeMode` (`integrations/theme-binding.ts`): the
10
+ * embedding host owns runtime mode (D4).
11
+ * - `app-theme-*` — which overlay shapes `appThemeSchema` accepts: both
12
+ * projections and the attestation required; the v1 one-palette wire and
13
+ * `base` refused.
14
+ * - `overlay-hash-*` — `canonicalOverlayHash` against an independently
15
+ * computed vector.
16
+ *
17
+ * History (the §1.1 receipt): `theme-mode-order`, `app-theme-v1-one-palette`
18
+ * and `app-theme-v1-base` were promoted from the unit pins at the version
19
+ * BEFORE the revision, passed there, and failed when it landed — that is
20
+ * what named the revision breaking. Like `../refusal-envelope-conformance`,
21
+ * the cases are raw JSON under `./cases/` and are NOT registered in
22
+ * `fixturesByContract`; the entry point is the runner below and its test.
23
+ */
24
+ import { appThemeSchema, canonicalOverlayHash } from '@ggui-ai/protocol';
25
+ import { effectiveThemeMode } from '@ggui-ai/protocol/integrations/theme-binding';
26
+ import appThemeV1Base from './cases/app-theme-v1-base.json' with { type: 'json' };
27
+ import appThemeV1OnePalette from './cases/app-theme-v1-one-palette.json' with { type: 'json' };
28
+ import appThemeV2Accepted from './cases/app-theme-v2-accepted.json' with { type: 'json' };
29
+ import appThemeV2MissingDark from './cases/app-theme-v2-missing-dark.json' with { type: 'json' };
30
+ import appThemeV2LabelTooLong from './cases/app-theme-v2-label-too-long.json' with { type: 'json' };
31
+ import appThemeV2KeyframesAccepted from './cases/app-theme-v2-keyframes-accepted.json' with { type: 'json' };
32
+ import appThemeV2KeyframesNotKeyframes from './cases/app-theme-v2-keyframes-not-keyframes.json' with { type: 'json' };
33
+ import appThemeV2NoHash from './cases/app-theme-v2-no-hash.json' with { type: 'json' };
34
+ import appThemeV2PlatformPin from './cases/app-theme-v2-platform-pin.json' with { type: 'json' };
35
+ import overlayHashCanonical from './cases/overlay-hash-canonical.json' with { type: 'json' };
36
+ import themeModeAbsence from './cases/theme-mode-absence.json' with { type: 'json' };
37
+ import themeModeDefaultWhenSilentHost from './cases/theme-mode-default-when-silent-host.json' with { type: 'json' };
38
+ import themeModeOrder from './cases/theme-mode-order.json' with { type: 'json' };
39
+ const isOpinion = (v) => v === 'light' || v === 'dark';
40
+ const opinionOrNull = (v, where) => {
41
+ if (v === null || isOpinion(v))
42
+ return v;
43
+ throw new Error(`theme-binding case: ${where} must be 'light' | 'dark' | null, got ${JSON.stringify(v)}`);
44
+ };
45
+ const isRecord = (v) => typeof v === 'object' && v !== null;
46
+ const isVarMap = (v) => isRecord(v) && Object.values(v).every((x) => typeof x === 'string');
47
+ function themeModeCase(raw) {
48
+ if (!isRecord(raw) || typeof raw['name'] !== 'string' || typeof raw['description'] !== 'string' || !isRecord(raw['sources']))
49
+ throw new Error('theme-binding case: malformed theme-mode case');
50
+ const src = raw['sources'];
51
+ return {
52
+ name: raw['name'],
53
+ description: raw['description'],
54
+ sources: {
55
+ stamped: opinionOrNull(src['stamped'], 'sources.stamped'),
56
+ sessionSidecar: opinionOrNull(src['sessionSidecar'], 'sources.sessionSidecar'),
57
+ hostAnnounced: opinionOrNull(src['hostAnnounced'], 'sources.hostAnnounced'),
58
+ },
59
+ expect: opinionOrNull(raw['expect'], 'expect'),
60
+ };
61
+ }
62
+ function appThemeCase(raw) {
63
+ if (!isRecord(raw) || typeof raw['name'] !== 'string' || typeof raw['description'] !== 'string' || !('theme' in raw))
64
+ throw new Error('theme-binding case: malformed app-theme case');
65
+ const expect = raw['expect'];
66
+ if (expect !== 'accepted' && expect !== 'refused')
67
+ throw new Error(`theme-binding case: expect must be accepted|refused, got ${JSON.stringify(expect)}`);
68
+ return { name: raw['name'], description: raw['description'], theme: raw['theme'], expect };
69
+ }
70
+ function overlayHashCase(raw) {
71
+ if (!isRecord(raw) || typeof raw['name'] !== 'string' || typeof raw['description'] !== 'string' || typeof raw['expect'] !== 'string' || !isRecord(raw['input']))
72
+ throw new Error('theme-binding case: malformed overlay-hash case');
73
+ const input = raw['input'];
74
+ const overlays = input['overlays'];
75
+ if (!isRecord(overlays) || !isVarMap(overlays['light']) || !isVarMap(overlays['dark']))
76
+ throw new Error('theme-binding case: overlay-hash input needs overlays.light and overlays.dark');
77
+ return {
78
+ name: raw['name'],
79
+ description: raw['description'],
80
+ input: { overlays: { light: overlays['light'], dark: overlays['dark'] } },
81
+ expect: raw['expect'],
82
+ };
83
+ }
84
+ export const THEME_MODE_CASES = [themeModeOrder, themeModeAbsence, themeModeDefaultWhenSilentHost].map(themeModeCase);
85
+ export const APP_THEME_CASES = [appThemeV1OnePalette, appThemeV1Base, appThemeV2Accepted, appThemeV2MissingDark, appThemeV2NoHash, appThemeV2PlatformPin, appThemeV2LabelTooLong, appThemeV2KeyframesAccepted, appThemeV2KeyframesNotKeyframes].map(appThemeCase);
86
+ export const OVERLAY_HASH_CASES = [overlayHashCanonical].map(overlayHashCase);
87
+ const nullable = (v) => (v === null ? undefined : v);
88
+ /** Grade every theme-binding case against the protocol's own functions. */
89
+ export async function runThemeBindingConformance() {
90
+ const results = [];
91
+ for (const c of THEME_MODE_CASES) {
92
+ const got = effectiveThemeMode({
93
+ stamped: nullable(c.sources.stamped),
94
+ sessionSidecar: nullable(c.sources.sessionSidecar),
95
+ hostAnnounced: nullable(c.sources.hostAnnounced),
96
+ });
97
+ const want = nullable(c.expect);
98
+ results.push({ name: c.name, pass: got === want, detail: `effectiveThemeMode(${JSON.stringify(c.sources)}) = ${String(got)}; expected ${String(want)}` });
99
+ }
100
+ for (const c of APP_THEME_CASES) {
101
+ const parsed = appThemeSchema.safeParse(c.theme);
102
+ const got = parsed.success ? 'accepted' : 'refused';
103
+ results.push({ name: c.name, pass: got === c.expect, detail: `appThemeSchema: ${got}; expected ${c.expect}${parsed.success ? '' : ` (${parsed.error.issues.map((i) => i.message).join('; ')})`}` });
104
+ }
105
+ for (const c of OVERLAY_HASH_CASES) {
106
+ const got = await canonicalOverlayHash(c.input);
107
+ results.push({ name: c.name, pass: got === c.expect, detail: `canonicalOverlayHash = ${got}; expected ${c.expect}` });
108
+ }
109
+ return results;
110
+ }
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "refuse-deprovisioned-endpoint",
3
- "description": "A deprovisioned app answers EVERY JSON-RPC request on its per-app MCP endpoint (initialize included) with HTTP 403 and a JSON-RPC error whose data.refusal carries the registry projection \u2014 code, message, fix, retry \u2014 so the client reads app_deprovisioned instead of guessing between a deleted app and a bad credential. error.code is -32003 (APP_NOT_FOUND \u2014 the endpoint no longer serves this app) and error.message is App not found; an untyped authorization failure answers -32001 (UNAUTHORIZED) with no data, so a client can tell the two apart by code and can tell neither from a dropped socket by mistake \u2014 -32000 is the SDK client's ConnectionClosed and a first-party server never chooses it (ggui#836).",
3
+ "description": "A deprovisioned app answers EVERY JSON-RPC request on its per-app MCP endpoint (initialize included) with HTTP 403 and a JSON-RPC error whose data.refusal carries the registry projection — code, message, fix, retry, appId — so the client reads app_deprovisioned instead of guessing between a deleted app and a bad credential. error.code is -32003 (APP_NOT_FOUND — the endpoint no longer serves this app) and error.message is App not found; an untyped authorization failure answers -32007 (UNAUTHORIZED) with no data, so a client can tell the two apart by code and can tell neither from a dropped socket by mistake — -32000 is the SDK client's ConnectionClosed and a first-party server never chooses it (ggui#836).",
4
4
  "refusal": {
5
5
  "code": "app_deprovisioned",
6
- "message": "the app record has no owner claim any more \u2014 the app was deprovisioned",
6
+ "message": "the app record has no owner claim any more — the app was deprovisioned",
7
7
  "fix": "provision the app again; this app id never renders again",
8
- "retry": "never"
8
+ "retry": "never",
9
+ "appId": "app_deprov_1"
9
10
  },
10
11
  "expect": {
11
12
  "httpStatus": 403,
@@ -15,9 +16,10 @@
15
16
  "data": {
16
17
  "refusal": {
17
18
  "code": "app_deprovisioned",
18
- "message": "the app record has no owner claim any more \u2014 the app was deprovisioned",
19
+ "message": "the app record has no owner claim any more — the app was deprovisioned",
19
20
  "fix": "provision the app again; this app id never renders again",
20
- "retry": "never"
21
+ "retry": "never",
22
+ "appId": "app_deprov_1"
21
23
  }
22
24
  }
23
25
  }
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "refuse-render-only-code",
3
- "description": "A REGISTERED code whose surfaces exclude mcp-endpoint has no transport envelope: the per-app endpoint's authorization never speaks it, and a projector that types it anyway would put a render-gate state on a surface the registry does not list. The three auth arms (no issuer, foreign issuer, denied subject) stay the bare 403 by the same rule \u2014 naming any of them would say which is true.",
3
+ "description": "A REGISTERED code whose surfaces exclude mcp-endpoint has no transport envelope: the per-app endpoint's authorization never speaks it, and a projector that types it anyway would put a render-gate state on a surface the registry does not list. The three auth arms (no issuer, foreign issuer, denied subject) stay the bare 403 by the same rule — naming any of them would say which is true.",
4
4
  "refusal": {
5
5
  "code": "insufficient_credit",
6
6
  "message": "the configured allowance for this app is exhausted",
7
7
  "fix": "top up the allowance for this app, then retry",
8
- "retry": "after-fix"
8
+ "retry": "after-fix",
9
+ "appId": "app_live_1"
9
10
  },
10
11
  "expect": null
11
12
  }
@@ -14,6 +14,8 @@ export interface TransportRefusalInput {
14
14
  readonly fix: string;
15
15
  /** Retry class (`after-fix` | `next-period` | `later` | `never`). */
16
16
  readonly retry: string;
17
+ /** The app id the refused endpoint serves — equals the path's `{appId}` (ggui#870). */
18
+ readonly appId: string;
17
19
  }
18
20
  /** What the endpoint answers: the HTTP status and the JSON-RPC error object. */
19
21
  export interface ProjectedTransportRefusal {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport-refusal-conformance/index.ts"],"names":[],"mappings":"AAyBA;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,gFAAgF;AAChF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAA;SAAE,CAAC;KAC5D,CAAC;CACH;AAED,qEAAqE;AACrE,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,qBAAqB,EAAE,SAAS,+BAA+B,EAG3E,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACpD,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,GAAG,MAAM,CAAC;CAC5D;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,yBAAyB,GAAG,IAAI,GAC5E,iCAAiC,CAiBnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport-refusal-conformance/index.ts"],"names":[],"mappings":"AAyBA;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,gFAAgF;AAChF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAA;SAAE,CAAC;KAC5D,CAAC;CACH;AAED,qEAAqE;AACrE,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,qBAAqB,EAAE,SAAS,+BAA+B,EAG3E,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACpD,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,GAAG,MAAM,CAAC;CAC5D;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,yBAAyB,GAAG,IAAI,GAC5E,iCAAiC,CAiBnC"}
@@ -8,8 +8,8 @@
8
8
  * The contract it makes observable: a deprovisioned app answers HTTP 403
9
9
  * with `{ code: -32003, message: "App not found", data: { refusal } }` where
10
10
  * `refusal` is the registry projection without the render-only fields
11
- * (`code`, `message`, `fix`, `retry`); an authorization failure that is
12
- * NOT a registry state answers 403 with `-32001` and no `data` — the untyped
11
+ * (`code`, `message`, `fix`, `retry`, `appId`); an authorization failure that is
12
+ * NOT a registry state answers 403 with `-32007` and no `data` — the untyped
13
13
  * arms deliberately indistinguishable among themselves, so a client never
14
14
  * learns which one it hit (codes ruled in ggui#836).
15
15
  *
package/dist/types.d.ts CHANGED
@@ -167,7 +167,7 @@ export interface CreateGguiSessionStep {
167
167
  /** Opaque render id the host allocates. Downstream steps + the
168
168
  * fixture's `inputEnvelope` reference it by value. */
169
169
  readonly sessionId: string;
170
- /** Optional app (tenant) id the render scopes to. Defaults to the
170
+ /** Optional app id the render scopes to. Defaults to the
171
171
  * host's implementation-defined "default app". */
172
172
  readonly appId?: string;
173
173
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/protocol-conformance",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Conformance test kit for the ggui protocol. Drives a behavioral fixture catalog against a live implementation over WebSocket, a resources/read catalog against a live MCP server, and nine pure-function catalogs (schema, registration, resolution, binding, props-schema, host-helper, refusal-envelope, registry-completeness, transport-refusal) for the gadget, tool-binding, schema-precise-render, host-helper and pre-generation-refusal obligations, reporting a scorecard-style pass / fail / skip. MCP builders adopt this kit to prove their implementation is protocol-conformant.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -51,6 +51,11 @@
51
51
  "import": "./dist/resource-read-conformance/index.js",
52
52
  "default": "./dist/resource-read-conformance/index.js"
53
53
  },
54
+ "./theme-binding-conformance": {
55
+ "types": "./dist/theme-binding-conformance/index.d.ts",
56
+ "import": "./dist/theme-binding-conformance/index.js",
57
+ "default": "./dist/theme-binding-conformance/index.js"
58
+ },
54
59
  "./binding-conformance": {
55
60
  "types": "./dist/binding-conformance/index.d.ts",
56
61
  "import": "./dist/binding-conformance/index.js",
@@ -71,6 +76,11 @@
71
76
  "import": "./dist/refusal-envelope-conformance/index.js",
72
77
  "default": "./dist/refusal-envelope-conformance/index.js"
73
78
  },
79
+ "./domain-error-conformance": {
80
+ "types": "./dist/domain-error-conformance/index.d.ts",
81
+ "import": "./dist/domain-error-conformance/index.js",
82
+ "default": "./dist/domain-error-conformance/index.js"
83
+ },
74
84
  "./registry-completeness": {
75
85
  "types": "./dist/registry-completeness/index.d.ts",
76
86
  "import": "./dist/registry-completeness/index.js",
@@ -84,7 +94,7 @@
84
94
  },
85
95
  "dependencies": {
86
96
  "ws": "^8.20.1",
87
- "@ggui-ai/protocol": "0.15.0"
97
+ "@ggui-ai/protocol": "0.16.0"
88
98
  },
89
99
  "devDependencies": {
90
100
  "@types/node": "^22.0.0",
@@ -1,6 +0,0 @@
1
- import type { TestCase } from '../../types.js';
2
- /** All fixtures asserting subscribe-time tenancy (SPEC §12.2 field
3
- * table — identity-default resolution on absent `appId` — and
4
- * §12.2.3 `APP_MISMATCH`). */
5
- export declare const subscribeTenancyFixtures: readonly TestCase[];
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/subscribe-tenancy/index.ts"],"names":[],"mappings":"AAwDA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;+BAE+B;AAC/B,eAAO,MAAM,wBAAwB,EAAE,SAAS,QAAQ,EAGvD,CAAC"}