@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.
- package/README.md +23 -15
- package/dist/cli.d.ts +6 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/domain-error-conformance/cases/amend-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/consume-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/emit-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/get-session-unknown-session.json +6 -0
- package/dist/domain-error-conformance/cases/render-unknown-handshake.json +6 -0
- package/dist/domain-error-conformance/cases/update-unknown-session.json +9 -0
- package/dist/domain-error-conformance/index.d.ts +97 -0
- package/dist/domain-error-conformance/index.d.ts.map +1 -0
- package/dist/domain-error-conformance/index.js +97 -0
- package/dist/fixtures/index.d.ts +2 -2
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +3 -3
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/absent-appid-defaults.json +1 -1
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/app-mismatch.json +1 -1
- package/dist/fixtures/subscribe-app-scope/index.d.ts +6 -0
- package/dist/fixtures/subscribe-app-scope/index.d.ts.map +1 -0
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/index.js +5 -5
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/refusal-envelope-conformance/cases/refuse-after-fix-caller.json +3 -3
- package/dist/refusal-envelope-conformance/cases/refuse-non-render-surface.json +4 -4
- package/dist/run-conformance.d.ts +13 -3
- package/dist/run-conformance.d.ts.map +1 -1
- package/dist/run-conformance.js +61 -7
- package/dist/theme-binding-conformance/cases/app-theme-v1-base.json +18 -0
- package/dist/theme-binding-conformance/cases/app-theme-v1-one-palette.json +11 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-accepted.json +18 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-accepted.json +16 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-not-keyframes.json +15 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-label-too-long.json +17 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-missing-dark.json +13 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-no-hash.json +15 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-platform-pin.json +17 -0
- package/dist/theme-binding-conformance/cases/overlay-hash-canonical.json +17 -0
- package/dist/theme-binding-conformance/cases/theme-mode-absence.json +10 -0
- package/dist/theme-binding-conformance/cases/theme-mode-default-when-silent-host.json +10 -0
- package/dist/theme-binding-conformance/cases/theme-mode-order.json +10 -0
- package/dist/theme-binding-conformance/index.d.ts +59 -0
- package/dist/theme-binding-conformance/index.d.ts.map +1 -0
- package/dist/theme-binding-conformance/index.js +110 -0
- package/dist/transport-refusal-conformance/cases/refuse-deprovisioned-endpoint.json +7 -5
- package/dist/transport-refusal-conformance/cases/refuse-render-only-code.json +3 -2
- package/dist/transport-refusal-conformance/index.d.ts +2 -0
- package/dist/transport-refusal-conformance/index.d.ts.map +1 -1
- package/dist/transport-refusal-conformance/index.js +2 -2
- package/dist/types.d.ts +1 -1
- package/package.json +12 -2
- package/dist/fixtures/subscribe-tenancy/index.d.ts +0 -6
- 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
|
|
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
|
|
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
|
|
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
|
|
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 `-
|
|
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
|
|
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.
|
|
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.
|
|
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"}
|