@ggui-ai/protocol-conformance 0.1.0-rc.3 → 0.2.0-alpha.3
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 +1 -1
- package/dist/conformance-host.d.ts +6 -10
- package/dist/conformance-host.d.ts.map +1 -1
- package/dist/fixtures/bootstrap-protocol/bootstrap-bundle-fetch-failed.json +5 -6
- package/dist/fixtures/bootstrap-protocol/bootstrap-meta-missing.json +5 -6
- package/dist/fixtures/bootstrap-protocol/bootstrap-success.json +5 -6
- package/dist/fixtures/bootstrap-protocol/index.d.ts +1 -1
- package/dist/fixtures/bootstrap-protocol/index.d.ts.map +1 -1
- package/dist/fixtures/bootstrap-protocol/index.js +3 -3
- package/dist/fixtures/index.d.ts +2 -11
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +1 -12
- package/dist/fixtures/observability-events/observability-contract-error-emitted.json +3 -4
- package/dist/fixtures/observability-events/observability-wired-tool-invoked.json +3 -4
- package/dist/fixtures/refresh-semantics/stream-refresh-success.json +3 -4
- package/dist/fixtures/reserved-channel-authority/props-update-roundtrip.json +4 -5
- package/dist/fixtures/reserved-channel-authority/stream-schema-violation.json +3 -4
- package/dist/fixtures/schema-version-handshake/version-match.json +3 -4
- package/dist/fixtures/schema-version-handshake/version-mismatch.json +5 -6
- package/dist/fixtures/wired-action-dispatch/wired-action-success.json +3 -4
- package/dist/fixtures/wired-action-dispatch/wired-action-tool-not-found.json +4 -5
- package/dist/fixtures/wired-action-dispatch/wired-action-tool-threw.json +4 -5
- package/dist/fixtures/wired-action-dispatch/wired-action-tool-timeout.json +4 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/match-behavior.js +2 -2
- package/dist/registration-conformance/index.d.ts +1 -1
- package/dist/resolution-conformance/index.js +1 -1
- package/dist/run-conformance.js +14 -14
- package/dist/schema-conformance/index.js +1 -1
- package/dist/types.d.ts +17 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/ws-transport.d.ts +1 -1
- package/dist/ws-transport.js +2 -2
- package/package.json +2 -2
- package/dist/fixtures/canvas-mode-wire-shapes/canvas-bootstrap-mutual-exclusion.json +0 -25
- package/dist/fixtures/canvas-mode-wire-shapes/canvas-lifecycle-channel-emits-handshake-started.json +0 -30
- package/dist/fixtures/canvas-mode-wire-shapes/canvas-navigated-updates-active-stack-item.json +0 -30
- package/dist/fixtures/canvas-mode-wire-shapes/host-context-observed-persists.json +0 -22
- package/dist/fixtures/canvas-mode-wire-shapes/index.d.ts +0 -5
- package/dist/fixtures/canvas-mode-wire-shapes/index.d.ts.map +0 -1
- package/dist/fixtures/canvas-mode-wire-shapes/index.js +0 -47
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ The partition is intentional: Path-A FAILs are vendor-neutrality bugs the server
|
|
|
33
33
|
|
|
34
34
|
## Pure-function conformance catalogs
|
|
35
35
|
|
|
36
|
-
The behavioral fixture catalog above asserts what an implementation _does_ over the wire. Some protocol obligations aren't transport-observable at all — they are deterministic _validation functions_: given an input, accept or reject it. SPEC §7.7.2's gadget obligations are exactly this. Modeling them as WebSocket fixtures would mean faking wire frames the protocol never emits; instead the kit ships **pure-function catalogs** — accept/reject cases graded against a caller-supplied function, with no host,
|
|
36
|
+
The behavioral fixture catalog above asserts what an implementation _does_ over the wire. Some protocol obligations aren't transport-observable at all — they are deterministic _validation functions_: given an input, accept or reject it. SPEC §7.7.2's gadget obligations are exactly this. Modeling them as WebSocket fixtures would mean faking wire frames the protocol never emits; instead the kit ships **pure-function catalogs** — accept/reject cases graded against a caller-supplied function, with no host, render, or transport.
|
|
37
37
|
|
|
38
38
|
Each catalog ships its cases as raw JSON so a non-TypeScript implementer can grade their own implementation, and each runner takes the implementation as a callback — the kit never hard-binds a concrete one. Three catalogs ship today:
|
|
39
39
|
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
* so the runner records the fixture as SKIPPED with that reason —
|
|
52
52
|
* never silently succeed.
|
|
53
53
|
*/
|
|
54
|
-
export type SetupStep =
|
|
55
|
-
export interface
|
|
56
|
-
readonly kind: 'create-
|
|
57
|
-
readonly
|
|
54
|
+
export type SetupStep = CreateRenderSetup | RegisterToolSetup | RegisterActionSpecSetup | EmitEnvelopeSetup | RendererUrlOverrideSetup | UiInitializeResponseOverrideSetup | ServerVersionOverrideSetup | UnknownSetupStep;
|
|
55
|
+
export interface CreateRenderSetup {
|
|
56
|
+
readonly kind: 'create-render';
|
|
57
|
+
readonly renderId: string;
|
|
58
58
|
readonly appId?: string;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Register a tool on the
|
|
61
|
+
* Register a tool on the render by symbolic handler name. Known
|
|
62
62
|
* handlers the reference implementation supports:
|
|
63
63
|
* - `'echo'` — returns `{received: args}`.
|
|
64
64
|
* - `'throw'` — rejects with `Error('tool_threw_for_fixture')`.
|
|
@@ -101,11 +101,7 @@ export interface ServerVersionOverrideSetup {
|
|
|
101
101
|
export type UnknownSetupStep = Record<string, unknown> & {
|
|
102
102
|
readonly kind: string & {};
|
|
103
103
|
};
|
|
104
|
-
export type TeardownStep =
|
|
105
|
-
export interface CloseSessionTeardown {
|
|
106
|
-
readonly kind: 'close-session';
|
|
107
|
-
readonly sessionId: string;
|
|
108
|
-
}
|
|
104
|
+
export type TeardownStep = UnregisterToolTeardown | UnknownTeardownStep;
|
|
109
105
|
export interface UnregisterToolTeardown {
|
|
110
106
|
readonly kind: 'unregister-tool';
|
|
111
107
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-host.d.ts","sourceRoot":"","sources":["../src/conformance-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAMH;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GACjB,
|
|
1
|
+
{"version":3,"file":"conformance-host.d.ts","sourceRoot":"","sources":["../src/conformance-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAMH;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,uBAAuB,GACvB,iBAAiB,GACjB,wBAAwB,GACxB,iCAAiC,GACjC,0BAA0B,GAC1B,gBAAgB,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,iCAAiC,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC;CAC5B,CAAC;AAMF,MAAM,MAAM,YAAY,GACpB,sBAAsB,GACtB,mBAAmB,CAAC;AAExB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC;CAC5B,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
|
|
@@ -3,24 +3,23 @@
|
|
|
3
3
|
"description": "Thin shell reads a valid `_meta.ggui.bootstrap.runtimeUrl` but the `<script src>` errors (network failure / 404 / CSP reject). Shell emits `postMessage({type:'ggui:bootstrap-failed', reason:'BUNDLE_FETCH_FAILED', message})` to the parent. No WS opens.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-bundle-fetch-failed-1" },
|
|
7
7
|
{
|
|
8
8
|
"type": "renderer-url-override",
|
|
9
|
-
"
|
|
9
|
+
"renderId": "ck-bundle-fetch-failed-1",
|
|
10
10
|
"url": "http://127.0.0.1:1/does-not-exist.js"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"inputEnvelope": {
|
|
14
14
|
"type": "render",
|
|
15
|
-
"
|
|
15
|
+
"renderId": "ck-bundle-fetch-failed-1",
|
|
16
16
|
"resource": {
|
|
17
|
-
"uri": "ui://ggui/
|
|
17
|
+
"uri": "ui://ggui/render"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"expectedBehavior": {
|
|
21
21
|
"kind": "bootstrap-failure",
|
|
22
22
|
"reason": "BUNDLE_FETCH_FAILED",
|
|
23
23
|
"messageContains": "Runtime bundle failed to load"
|
|
24
|
-
}
|
|
25
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-bundle-fetch-failed-1" }]
|
|
24
|
+
}
|
|
26
25
|
}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"description": "Host's `ui/initialize` response returns a tool-output without `_meta.ggui.bootstrap` (or missing the `runtimeUrl` field). Thin shell emits `postMessage({type:'ggui:bootstrap-failed', reason:'BOOTSTRAP_META_MISSING', message})` to the parent. No WS connection opens — live-channel envelopes are out of scope pre-handshake.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-bootstrap-meta-missing-1" },
|
|
7
7
|
{
|
|
8
8
|
"type": "ui-initialize-response-override",
|
|
9
|
-
"
|
|
9
|
+
"renderId": "ck-bootstrap-meta-missing-1",
|
|
10
10
|
"override": {
|
|
11
11
|
"toolOutput": {
|
|
12
12
|
"_meta": {
|
|
@@ -18,15 +18,14 @@
|
|
|
18
18
|
],
|
|
19
19
|
"inputEnvelope": {
|
|
20
20
|
"type": "render",
|
|
21
|
-
"
|
|
21
|
+
"renderId": "ck-bootstrap-meta-missing-1",
|
|
22
22
|
"resource": {
|
|
23
|
-
"uri": "ui://ggui/
|
|
23
|
+
"uri": "ui://ggui/render"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"expectedBehavior": {
|
|
27
27
|
"kind": "bootstrap-failure",
|
|
28
28
|
"reason": "BOOTSTRAP_META_MISSING",
|
|
29
29
|
"messageContains": "_meta.ggui.bootstrap"
|
|
30
|
-
}
|
|
31
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-bootstrap-meta-missing-1" }]
|
|
30
|
+
}
|
|
32
31
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bootstrap-success",
|
|
3
|
-
"description": "Happy-path boot: host reads `_meta.ui.resourceUri`, fetches `ui://ggui/
|
|
3
|
+
"description": "Happy-path boot: host reads `_meta.ui.resourceUri`, fetches `ui://ggui/render`, the thin shell loads the renderer bundle, `ui/initialize` returns valid `_meta.ggui.bootstrap.{wsUrl, token, renderId, appId, runtimeUrl}`, WS handshake succeeds, the render mounts with `data-ggui-code-ready=\"true\"`. No bootstrap-failed postMessage, no contract-error, no upgrade-required.",
|
|
4
4
|
"skipReason": null,
|
|
5
|
-
"setup": [{ "type": "create-
|
|
5
|
+
"setup": [{ "type": "create-render", "renderId": "ck-bootstrap-success-1" }],
|
|
6
6
|
"inputEnvelope": {
|
|
7
7
|
"type": "render",
|
|
8
|
-
"
|
|
8
|
+
"renderId": "ck-bootstrap-success-1",
|
|
9
9
|
"resource": {
|
|
10
|
-
"uri": "ui://ggui/
|
|
10
|
+
"uri": "ui://ggui/render"
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"expectedBehavior": {
|
|
14
14
|
"kind": "bootstrap-success"
|
|
15
|
-
}
|
|
16
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-bootstrap-success-1" }]
|
|
15
|
+
}
|
|
17
16
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TestCase } from '../../types.js';
|
|
2
2
|
/** All fixtures asserting the bootstrap contract (Protocol #5 — named
|
|
3
|
-
* failure modes + SPEC §8 `
|
|
3
|
+
* failure modes + SPEC §8 `McpAppAiGguiMeta`). */
|
|
4
4
|
export declare const bootstrapProtocolFixtures: readonly TestCase[];
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/bootstrap-protocol/index.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/bootstrap-protocol/index.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;mDACmD;AACnD,eAAO,MAAM,yBAAyB,EAAE,SAAS,QAAQ,EAIxD,CAAC"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* `bootstrap-protocol` fixture sub-module.
|
|
3
3
|
*
|
|
4
4
|
* Exercises the MCP Apps bootstrap contract (SPEC §8):
|
|
5
|
-
* - `ui/initialize` tool-result must stamp
|
|
6
|
-
* with a well-formed
|
|
5
|
+
* - `ui/initialize` tool-result must stamp the per-window
|
|
6
|
+
* `_meta["ai.ggui/render"]` slice with a well-formed payload.
|
|
7
7
|
* - Renderer-bundle fetch must succeed (or surface a typed
|
|
8
8
|
* `BOOTSTRAP_FAILURE` protocol error).
|
|
9
9
|
* - Happy-path boot reaches `data-ggui-code-ready="true"` with no
|
|
@@ -16,7 +16,7 @@ import bootstrapBundleFetchFailed from './bootstrap-bundle-fetch-failed.json' wi
|
|
|
16
16
|
import bootstrapMetaMissing from './bootstrap-meta-missing.json' with { type: 'json' };
|
|
17
17
|
import bootstrapSuccess from './bootstrap-success.json' with { type: 'json' };
|
|
18
18
|
/** All fixtures asserting the bootstrap contract (Protocol #5 — named
|
|
19
|
-
* failure modes + SPEC §8 `
|
|
19
|
+
* failure modes + SPEC §8 `McpAppAiGguiMeta`). */
|
|
20
20
|
export const bootstrapProtocolFixtures = [
|
|
21
21
|
bootstrapBundleFetchFailed,
|
|
22
22
|
bootstrapMetaMissing,
|
package/dist/fixtures/index.d.ts
CHANGED
|
@@ -26,14 +26,6 @@
|
|
|
26
26
|
* expansion and not yet materialized — adding fixtures there is a
|
|
27
27
|
* kit minor version.
|
|
28
28
|
*
|
|
29
|
-
* `canvas-mode-wire-shapes` (4 fixtures) ships the canvas-mode wire
|
|
30
|
-
* contract intent: `canvasMode` bootstrap discriminator,
|
|
31
|
-
* `_ggui:lifecycle` channel + payload, `canvas_navigated` +
|
|
32
|
-
* `host_context_observed` C→S WS messages. Runner activation is a
|
|
33
|
-
* follow-up kit minor once the reference `ConformanceHost` exposes
|
|
34
|
-
* `set-app-mode` + `assert-session-field` + `assert-channel-envelope`
|
|
35
|
-
* directives.
|
|
36
|
-
*
|
|
37
29
|
* ## What is NOT here — the gadget pure-function obligations
|
|
38
30
|
*
|
|
39
31
|
* SPEC §7.7.2's gadget obligations are pure-function obligations, not
|
|
@@ -41,12 +33,11 @@
|
|
|
41
33
|
* a parser accepts (`../schema-conformance`) and which `(contract,
|
|
42
34
|
* appGadgets)` pairs the push-time registry gate accepts / rejects
|
|
43
35
|
* (`../registration-conformance`). They are graded against a
|
|
44
|
-
* caller-supplied function — there is no
|
|
36
|
+
* caller-supplied function — there is no render, transport, or wire
|
|
45
37
|
* frame to drive — so they do NOT belong in this behavioral fixture
|
|
46
38
|
* catalog.
|
|
47
39
|
*/
|
|
48
40
|
export { bootstrapProtocolFixtures } from './bootstrap-protocol/index.js';
|
|
49
|
-
export { canvasModeWireShapesFixtures } from './canvas-mode-wire-shapes/index.js';
|
|
50
41
|
export { observabilityEventsFixtures } from './observability-events/index.js';
|
|
51
42
|
export { refreshSemanticsFixtures } from './refresh-semantics/index.js';
|
|
52
43
|
export { reservedChannelAuthorityFixtures } from './reserved-channel-authority/index.js';
|
|
@@ -59,7 +50,7 @@ import type { TestCase } from '../types.js';
|
|
|
59
50
|
* Extensibly-closed via `(string & {})` so additive sub-modules
|
|
60
51
|
* register without an API break.
|
|
61
52
|
*/
|
|
62
|
-
export type ContractSlug = 'bootstrap-protocol' | '
|
|
53
|
+
export type ContractSlug = 'bootstrap-protocol' | 'observability-events' | 'refresh-semantics' | 'reserved-channel-authority' | 'schema-version-handshake' | 'wired-action-dispatch' | (string & {});
|
|
63
54
|
/**
|
|
64
55
|
* Every fixture the kit ships, grouped by the contract it exercises.
|
|
65
56
|
* Order within each group matches the sub-module's `export` order.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ5C;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,4BAA4B,GAC5B,0BAA0B,GAC1B,uBAAuB,GACvB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,QAAQ,EAAE,CAAC,CAOlF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,QAAQ,EAGwB,CAAC"}
|
package/dist/fixtures/index.js
CHANGED
|
@@ -26,14 +26,6 @@
|
|
|
26
26
|
* expansion and not yet materialized — adding fixtures there is a
|
|
27
27
|
* kit minor version.
|
|
28
28
|
*
|
|
29
|
-
* `canvas-mode-wire-shapes` (4 fixtures) ships the canvas-mode wire
|
|
30
|
-
* contract intent: `canvasMode` bootstrap discriminator,
|
|
31
|
-
* `_ggui:lifecycle` channel + payload, `canvas_navigated` +
|
|
32
|
-
* `host_context_observed` C→S WS messages. Runner activation is a
|
|
33
|
-
* follow-up kit minor once the reference `ConformanceHost` exposes
|
|
34
|
-
* `set-app-mode` + `assert-session-field` + `assert-channel-envelope`
|
|
35
|
-
* directives.
|
|
36
|
-
*
|
|
37
29
|
* ## What is NOT here — the gadget pure-function obligations
|
|
38
30
|
*
|
|
39
31
|
* SPEC §7.7.2's gadget obligations are pure-function obligations, not
|
|
@@ -41,19 +33,17 @@
|
|
|
41
33
|
* a parser accepts (`../schema-conformance`) and which `(contract,
|
|
42
34
|
* appGadgets)` pairs the push-time registry gate accepts / rejects
|
|
43
35
|
* (`../registration-conformance`). They are graded against a
|
|
44
|
-
* caller-supplied function — there is no
|
|
36
|
+
* caller-supplied function — there is no render, transport, or wire
|
|
45
37
|
* frame to drive — so they do NOT belong in this behavioral fixture
|
|
46
38
|
* catalog.
|
|
47
39
|
*/
|
|
48
40
|
export { bootstrapProtocolFixtures } from './bootstrap-protocol/index.js';
|
|
49
|
-
export { canvasModeWireShapesFixtures } from './canvas-mode-wire-shapes/index.js';
|
|
50
41
|
export { observabilityEventsFixtures } from './observability-events/index.js';
|
|
51
42
|
export { refreshSemanticsFixtures } from './refresh-semantics/index.js';
|
|
52
43
|
export { reservedChannelAuthorityFixtures } from './reserved-channel-authority/index.js';
|
|
53
44
|
export { schemaVersionHandshakeFixtures } from './schema-version-handshake/index.js';
|
|
54
45
|
export { wiredActionDispatchFixtures } from './wired-action-dispatch/index.js';
|
|
55
46
|
import { bootstrapProtocolFixtures } from './bootstrap-protocol/index.js';
|
|
56
|
-
import { canvasModeWireShapesFixtures } from './canvas-mode-wire-shapes/index.js';
|
|
57
47
|
import { observabilityEventsFixtures } from './observability-events/index.js';
|
|
58
48
|
import { refreshSemanticsFixtures } from './refresh-semantics/index.js';
|
|
59
49
|
import { reservedChannelAuthorityFixtures } from './reserved-channel-authority/index.js';
|
|
@@ -69,7 +59,6 @@ import { wiredActionDispatchFixtures } from './wired-action-dispatch/index.js';
|
|
|
69
59
|
*/
|
|
70
60
|
export const fixturesByContract = {
|
|
71
61
|
'bootstrap-protocol': bootstrapProtocolFixtures,
|
|
72
|
-
'canvas-mode-wire-shapes': canvasModeWireShapesFixtures,
|
|
73
62
|
'observability-events': observabilityEventsFixtures,
|
|
74
63
|
'refresh-semantics': refreshSemanticsFixtures,
|
|
75
64
|
'reserved-channel-authority': reservedChannelAuthorityFixtures,
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"description": "Standalone `contract-error-emitted` observability row. Every `_ggui:contract-error` envelope the server emits on the live channel MUST be mirrored as a `contract-error-emitted` observability event for host-side inspection without requiring the host to parse live-channel frames. Asserts the mirror-emission contract directly on the observability envelope.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-obs-ce-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "broken_tool", "handler": "throw" },
|
|
8
8
|
{ "type": "register-actionspec", "name": "triggerBroken", "tool": "broken_tool" }
|
|
9
9
|
],
|
|
10
10
|
"inputEnvelope": {
|
|
11
11
|
"type": "action",
|
|
12
12
|
"channel": 0,
|
|
13
|
-
"
|
|
13
|
+
"renderId": "ck-obs-ce-1",
|
|
14
14
|
"action": {
|
|
15
15
|
"name": "triggerBroken",
|
|
16
16
|
"data": {}
|
|
@@ -24,6 +24,5 @@
|
|
|
24
24
|
"toolName": "broken_tool",
|
|
25
25
|
"actionName": "triggerBroken"
|
|
26
26
|
}
|
|
27
|
-
}
|
|
28
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-obs-ce-1" }]
|
|
27
|
+
}
|
|
29
28
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"description": "Standalone `wired-tool-invoked` observability row. Distinct from `wired-action-success`'s DOM-level assertion — asserts directly on the postMessage observability envelope shape so Phase 3.1 can assert wire-byte equality without DOM observation.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-obs-wired-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "tasks_complete", "handler": "echo" },
|
|
8
8
|
{ "type": "register-actionspec", "name": "toggleTask", "tool": "tasks_complete" }
|
|
9
9
|
],
|
|
10
10
|
"inputEnvelope": {
|
|
11
11
|
"type": "action",
|
|
12
12
|
"channel": 0,
|
|
13
|
-
"
|
|
13
|
+
"renderId": "ck-obs-wired-1",
|
|
14
14
|
"action": {
|
|
15
15
|
"name": "toggleTask",
|
|
16
16
|
"data": { "id": "seed-1" }
|
|
@@ -23,6 +23,5 @@
|
|
|
23
23
|
"toolName": "tasks_complete",
|
|
24
24
|
"actionName": "toggleTask"
|
|
25
25
|
}
|
|
26
|
-
}
|
|
27
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-obs-wired-1" }]
|
|
26
|
+
}
|
|
28
27
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Happy-path refresh: a wired action succeeds, the declared `streamSpec[channel].tool` refresh tool fires, and the channel's next stream-update reflects the new snapshot. Proves the refresh-after-action contract is observable on the wire (not only on the DOM).",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-refresh-success-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "tasks_create", "handler": "echo" },
|
|
8
8
|
{ "type": "register-tool", "toolName": "tasks_list", "handler": "list-snapshot" },
|
|
9
9
|
{ "type": "register-actionspec", "name": "createTask", "tool": "tasks_create" },
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"inputEnvelope": {
|
|
13
13
|
"type": "action",
|
|
14
14
|
"channel": 0,
|
|
15
|
-
"
|
|
15
|
+
"renderId": "ck-refresh-success-1",
|
|
16
16
|
"action": {
|
|
17
17
|
"name": "createTask",
|
|
18
18
|
"data": { "title": "ck-refresh" }
|
|
@@ -35,6 +35,5 @@
|
|
|
35
35
|
"kind": "wired-tool-invoked",
|
|
36
36
|
"toolName": "tasks_list"
|
|
37
37
|
}
|
|
38
|
-
]
|
|
39
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-refresh-success-1" }]
|
|
38
|
+
]
|
|
40
39
|
}
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"description": "Host delivers a `props_update` envelope on channel 0 with a new props payload. The iframe's DOM reflects the new props within `timeoutMs` — evidence on a stamped data-attribute. Proves the host -> iframe props channel is live-wired, complementing the wired-action (iframe -> host) path.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-props-update-1" },
|
|
7
7
|
{
|
|
8
8
|
"type": "emit-envelope",
|
|
9
9
|
"channel": "_ggui:props",
|
|
10
10
|
"payload": {
|
|
11
11
|
"type": "props_update",
|
|
12
|
-
"
|
|
12
|
+
"renderId": "ck-props-update-1",
|
|
13
13
|
"props": { "greeting": "initial" }
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"inputEnvelope": {
|
|
18
18
|
"type": "props-update",
|
|
19
19
|
"channel": 0,
|
|
20
|
-
"
|
|
20
|
+
"renderId": "ck-props-update-1",
|
|
21
21
|
"props": { "greeting": "updated-by-host" }
|
|
22
22
|
},
|
|
23
23
|
"expectedBehavior": {
|
|
@@ -29,6 +29,5 @@
|
|
|
29
29
|
"attribute": "data-ggui-greeting",
|
|
30
30
|
"expected": "updated-by-host"
|
|
31
31
|
}
|
|
32
|
-
}
|
|
33
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-props-update-1" }]
|
|
32
|
+
}
|
|
34
33
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Refresh-stream tool returns a shape that violates the declared channel schema. `assertStreamContract` rejects the payload BEFORE fanOut, emits `_ggui:contract-error` with code SCHEMA_VIOLATION + sourceAction `refresh-stream`. Channel's previous state is preserved — subscribers never see the corruption. Matches `runtime-contract.spec.ts::schema-violation-on-refresh`.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-schema-violation-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "tasks_list", "handler": "echo" },
|
|
8
8
|
{
|
|
9
9
|
"type": "register-tool",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"inputEnvelope": {
|
|
25
25
|
"type": "action",
|
|
26
26
|
"channel": 0,
|
|
27
|
-
"
|
|
27
|
+
"renderId": "ck-schema-violation-1",
|
|
28
28
|
"action": {
|
|
29
29
|
"name": "triggerMalformedRefresh",
|
|
30
30
|
"data": {}
|
|
@@ -40,6 +40,5 @@
|
|
|
40
40
|
"code": "SCHEMA_VIOLATION",
|
|
41
41
|
"toolName": "tasks_malformed_list"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
44
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-schema-violation-1" }]
|
|
43
|
+
}
|
|
45
44
|
}
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
"name": "version-match",
|
|
3
3
|
"description": "Happy-path version handshake: server advertises a schemaVersion the client supports (same as current canonical). Renderer completes the handshake without emitting `ggui:upgrade-required`. Baseline for `version-mismatch`'s negative assertion — proves the handshake path itself is observable.",
|
|
4
4
|
"skipReason": null,
|
|
5
|
-
"setup": [{ "type": "create-
|
|
5
|
+
"setup": [{ "type": "create-render", "renderId": "ck-version-match-1" }],
|
|
6
6
|
"inputEnvelope": {
|
|
7
7
|
"type": "handshake",
|
|
8
|
-
"
|
|
8
|
+
"renderId": "ck-version-match-1",
|
|
9
9
|
"clientAccepts": ["1.1"]
|
|
10
10
|
},
|
|
11
11
|
"expectedBehavior": {
|
|
12
12
|
"kind": "bootstrap-success",
|
|
13
13
|
"observabilitySequence": []
|
|
14
|
-
}
|
|
15
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-version-match-1" }]
|
|
14
|
+
}
|
|
16
15
|
}
|
|
@@ -3,24 +3,23 @@
|
|
|
3
3
|
"description": "Server advertises a protocol schemaVersion outside the client's accepted set. Renderer emits `{type:'ggui:upgrade-required', server, client}` to the parent host + a matching `ProtocolError{kind:'version'}`. Host SHOULD render an inline upgrade prompt — NOT treat this as a terminal failure.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-version-mismatch-1" },
|
|
7
7
|
{
|
|
8
8
|
"type": "server-version-override",
|
|
9
|
-
"
|
|
9
|
+
"renderId": "ck-version-mismatch-1",
|
|
10
10
|
"advertiseVersion": "99.99-unsupported"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"inputEnvelope": {
|
|
14
14
|
"type": "render",
|
|
15
|
-
"
|
|
15
|
+
"renderId": "ck-version-mismatch-1",
|
|
16
16
|
"resource": {
|
|
17
|
-
"uri": "ui://ggui/
|
|
17
|
+
"uri": "ui://ggui/render"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"expectedBehavior": {
|
|
21
21
|
"kind": "version-mismatch",
|
|
22
22
|
"serverVersion": "99.99-unsupported",
|
|
23
23
|
"clientAccepts": ["1.1"]
|
|
24
|
-
}
|
|
25
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-version-mismatch-1" }]
|
|
24
|
+
}
|
|
26
25
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Happy-path wired-action dispatch. A declared action tool fires, the refresh-stream tool follows, and the renderer emits a `wired-tool-invoked` observability event for each invocation. Baseline proof that the protocol's declare+wire+no-agent-code claim works end-to-end.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-wired-success-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "tasks_complete", "handler": "echo" },
|
|
8
8
|
{ "type": "register-tool", "toolName": "tasks_list", "handler": "echo" },
|
|
9
9
|
{ "type": "register-actionspec", "name": "toggleTask", "tool": "tasks_complete" }
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"inputEnvelope": {
|
|
12
12
|
"type": "action",
|
|
13
13
|
"channel": 0,
|
|
14
|
-
"
|
|
14
|
+
"renderId": "ck-wired-success-1",
|
|
15
15
|
"action": {
|
|
16
16
|
"name": "toggleTask",
|
|
17
17
|
"data": { "id": "seed-1" }
|
|
@@ -31,6 +31,5 @@
|
|
|
31
31
|
"toolName": "tasks_complete",
|
|
32
32
|
"actionName": "toggleTask"
|
|
33
33
|
}
|
|
34
|
-
]
|
|
35
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-wired-success-1" }]
|
|
34
|
+
]
|
|
36
35
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wired-action-tool-not-found",
|
|
3
|
-
"description": "Wired-action dispatch names an action whose declared tool is not registered on the
|
|
3
|
+
"description": "Wired-action dispatch names an action whose declared tool is not registered on the render. The router MUST emit a `_ggui:contract-error` envelope with code TOOL_NOT_FOUND and a matching `contract-error-emitted` observability event. Render stays alive.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-tool-not-found-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "known-tool", "handler": "echo" }
|
|
8
8
|
],
|
|
9
9
|
"inputEnvelope": {
|
|
10
10
|
"type": "action",
|
|
11
11
|
"channel": 0,
|
|
12
|
-
"
|
|
12
|
+
"renderId": "ck-tool-not-found-1",
|
|
13
13
|
"action": {
|
|
14
14
|
"name": "doesNotExist",
|
|
15
15
|
"data": {}
|
|
@@ -26,6 +26,5 @@
|
|
|
26
26
|
"code": "TOOL_NOT_FOUND",
|
|
27
27
|
"toolName": "doesNotExist"
|
|
28
28
|
}
|
|
29
|
-
}
|
|
30
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-tool-not-found-1" }]
|
|
29
|
+
}
|
|
31
30
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wired-action-tool-threw",
|
|
3
|
-
"description": "Wired-action tool throws synchronously (or rejects). Router catches, emits `_ggui:contract-error` with code TOOL_THREW + sanitized causedBy.
|
|
3
|
+
"description": "Wired-action tool throws synchronously (or rejects). Router catches, emits `_ggui:contract-error` with code TOOL_THREW + sanitized causedBy. Render survives — the probe UI stays interactive. Matches `runtime-contract.spec.ts::tool-throws`.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-tool-threw-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "tasks_broken", "handler": "throw" },
|
|
8
8
|
{ "type": "register-actionspec", "name": "triggerBroken", "tool": "tasks_broken" }
|
|
9
9
|
],
|
|
10
10
|
"inputEnvelope": {
|
|
11
11
|
"type": "action",
|
|
12
12
|
"channel": 0,
|
|
13
|
-
"
|
|
13
|
+
"renderId": "ck-tool-threw-1",
|
|
14
14
|
"action": {
|
|
15
15
|
"name": "triggerBroken",
|
|
16
16
|
"data": {}
|
|
@@ -27,6 +27,5 @@
|
|
|
27
27
|
"code": "TOOL_THREW",
|
|
28
28
|
"toolName": "tasks_broken"
|
|
29
29
|
}
|
|
30
|
-
}
|
|
31
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-tool-threw-1" }]
|
|
30
|
+
}
|
|
32
31
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wired-action-tool-timeout",
|
|
3
|
-
"description": "Wired-action tool exceeds the router's configured timeout. Router emits `_ggui:contract-error` with code TOOL_TIMEOUT + sourceAction `wired-action` + a matching `contract-error-emitted` observability event.
|
|
3
|
+
"description": "Wired-action tool exceeds the router's configured timeout. Router emits `_ggui:contract-error` with code TOOL_TIMEOUT + sourceAction `wired-action` + a matching `contract-error-emitted` observability event. Render survives; no stream update fires.",
|
|
4
4
|
"skipReason": null,
|
|
5
5
|
"setup": [
|
|
6
|
-
{ "type": "create-
|
|
6
|
+
{ "type": "create-render", "renderId": "ck-tool-timeout-1" },
|
|
7
7
|
{ "type": "register-tool", "toolName": "hanging_tool", "handler": "timeout" },
|
|
8
8
|
{ "type": "register-actionspec", "name": "triggerTimeout", "tool": "hanging_tool" }
|
|
9
9
|
],
|
|
10
10
|
"inputEnvelope": {
|
|
11
11
|
"type": "action",
|
|
12
12
|
"channel": 0,
|
|
13
|
-
"
|
|
13
|
+
"renderId": "ck-tool-timeout-1",
|
|
14
14
|
"action": {
|
|
15
15
|
"name": "triggerTimeout",
|
|
16
16
|
"data": {}
|
|
@@ -27,6 +27,5 @@
|
|
|
27
27
|
"code": "TOOL_TIMEOUT",
|
|
28
28
|
"toolName": "hanging_tool"
|
|
29
29
|
}
|
|
30
|
-
}
|
|
31
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-tool-timeout-1" }]
|
|
30
|
+
}
|
|
32
31
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* its assertions and `@ggui-ai/protocol`'s types is the canonical
|
|
11
11
|
* bug.
|
|
12
12
|
*/
|
|
13
|
-
export type { TransportConfig, WebSocketTransportConfig, UnknownTransportConfig, AuthConfig, TestCase, SetupStep,
|
|
14
|
-
export type { ConformanceHost, SetupStep as HostSetupStep,
|
|
15
|
-
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures,
|
|
13
|
+
export type { TransportConfig, WebSocketTransportConfig, UnknownTransportConfig, AuthConfig, TestCase, SetupStep, CreateRenderStep, RegisterToolStep, EmitEnvelopeStep, SeedChannelStep, UnknownSetupStep, TeardownStep, UnregisterToolStep, UnknownTeardownStep, ExpectedBehavior, ContractErrorBehavior, StreamUpdateBehavior, ObservabilityBehavior, BootstrapFailureBehavior, BootstrapSuccessBehavior, VersionMismatchBehavior, PropsUpdateBehavior, NoOpBehavior, UnknownBehavior, ExpectedObservabilityEvent, ProtocolError, BootstrapFailureReason, ContractErrorCode, } from './types.js';
|
|
14
|
+
export type { ConformanceHost, SetupStep as HostSetupStep, CreateRenderSetup, RegisterToolSetup, RegisterActionSpecSetup, EmitEnvelopeSetup, RendererUrlOverrideSetup, UiInitializeResponseOverrideSetup, ServerVersionOverrideSetup, UnknownSetupStep as HostUnknownSetupStep, TeardownStep as HostTeardownStep, UnregisterToolTeardown, UnknownTeardownStep as HostUnknownTeardownStep, } from './conformance-host.js';
|
|
15
|
+
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, observabilityEventsFixtures, refreshSemanticsFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures, wiredActionDispatchFixtures, } from './fixtures/index.js';
|
|
16
16
|
export type { ContractSlug } from './fixtures/index.js';
|
|
17
17
|
export { gadgetWireSchemaCases, runSchemaConformance, } from './schema-conformance/index.js';
|
|
18
18
|
export type { SchemaConformanceCase, SchemaConformanceMismatch, SchemaConformanceResult, } from './schema-conformance/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,YAAY,EAEV,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,UAAU,EAEV,QAAQ,EAER,SAAS,EACT,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,YAAY,EAEV,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,UAAU,EAEV,QAAQ,EAER,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAEhB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EAEnB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,0BAA0B,EAE1B,aAAa,EACb,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAMpB,YAAY,EACV,eAAe,EAEf,SAAS,IAAI,aAAa,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,wBAAwB,EACxB,iCAAiC,EACjC,0BAA0B,EAC1B,gBAAgB,IAAI,oBAAoB,EAExC,YAAY,IAAI,gBAAgB,EAChC,sBAAsB,EACtB,mBAAmB,IAAI,uBAAuB,GAC/C,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASxD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EACL,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,2BAA2B,EAC3B,+BAA+B,EAC/B,6BAA6B,GAC9B,MAAM,qCAAqC,CAAC;AAK7C,OAAO,EACL,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
// Fixture catalog — every authored conformance case, classified by
|
|
14
14
|
// contract. Third-party runners + the kit's own `runConformance()`
|
|
15
15
|
// consume this surface.
|
|
16
|
-
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures,
|
|
16
|
+
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, observabilityEventsFixtures, refreshSemanticsFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures, wiredActionDispatchFixtures, } from './fixtures/index.js';
|
|
17
17
|
// Pure-function conformance catalogs — SPEC §7.7.2's gadget
|
|
18
18
|
// obligations are deterministic validation functions, not transport-
|
|
19
19
|
// observable behaviors. Each catalog grades a caller-supplied function
|
|
20
|
-
// against authored accept/reject cases; no host,
|
|
20
|
+
// against authored accept/reject cases; no host, render, or wire.
|
|
21
21
|
//
|
|
22
22
|
// Schema-conformance — which `DataContract.clientCapabilities`
|
|
23
23
|
// payloads a conformant parser MUST accept / reject.
|
package/dist/match-behavior.js
CHANGED
|
@@ -21,7 +21,7 @@ export function matchBehavior(behavior, frames) {
|
|
|
21
21
|
if (behavior.kind === 'bootstrap-failure') {
|
|
22
22
|
return {
|
|
23
23
|
kind: 'unmatchable-on-ws',
|
|
24
|
-
reason: 'bootstrap-failure is a Path-B (browser-host) claim — the fault surface is the host\'s bootstrap-fetch + `ui/initialize` postMessage round-trip, not a WS frame the server emits. The `renderer-url-override` / `ui-initialize-response-override` setup directives are MCP-Apps-host concerns; the reference server\'s host adapter throws "out of scope" on them by design. Drive these fixtures via a Path-B browser-host harness (today:
|
|
24
|
+
reason: 'bootstrap-failure is a Path-B (browser-host) claim — the fault surface is the host\'s bootstrap-fetch + `ui/initialize` postMessage round-trip, not a WS frame the server emits. The `renderer-url-override` / `ui-initialize-response-override` setup directives are MCP-Apps-host concerns; the reference server\'s host adapter throws "out of scope" on them by design. Drive these fixtures via a Path-B browser-host harness (today: PENDING a new driver; future: packaged Phase-3.2 adapter inside the kit).',
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
if (behavior.kind === 'observability-event') {
|
|
@@ -30,7 +30,7 @@ export function matchBehavior(behavior, frames) {
|
|
|
30
30
|
if (behavior.kind === 'props-update') {
|
|
31
31
|
return {
|
|
32
32
|
kind: 'unmatchable-on-ws',
|
|
33
|
-
reason: 'props-update is a Path-B (browser-host) claim — the assertion is on rendered DOM (selector + attribute/text), not on the `_ggui:props` WS frame in isolation. Matchable on WS only as "frame was emitted"; the fixture vocabulary asserts "DOM reflects the update". Drive via a Path-B browser-host harness
|
|
33
|
+
reason: 'props-update is a Path-B (browser-host) claim — the assertion is on rendered DOM (selector + attribute/text), not on the `_ggui:props` WS frame in isolation. Matchable on WS only as "frame was emitted"; the fixture vocabulary asserts "DOM reflects the update". Drive via a Path-B browser-host harness; future: packaged Phase-3.2 adapter inside the kit.',
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
// Extensibly-closed union catch — unknown `kind` = new fixture
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* The push-time gadget gate answers a pure question: given a contract
|
|
8
8
|
* and the app's registered `App.gadgets` catalog, does every
|
|
9
9
|
* `(package, export)` the contract references resolve — and if not,
|
|
10
|
-
* which precise reject code applies? There is no
|
|
10
|
+
* which precise reject code applies? There is no render, no
|
|
11
11
|
* transport, no wire frame in that question — it is a deterministic
|
|
12
12
|
* classification, exactly like the `clientCapabilities` schema check
|
|
13
13
|
* in `../schema-conformance`.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Given a gadget descriptor's transport fields, the server computes
|
|
8
8
|
* the bundle + style URLs the iframe sees in
|
|
9
9
|
* `_meta.ggui.bootstrap.gadgets[*]`. That computation is a pure,
|
|
10
|
-
* deterministic function — no
|
|
10
|
+
* deterministic function — no render, transport, or wire frame — so
|
|
11
11
|
* it gets the same treatment as the wire schema (`../schema-conformance`)
|
|
12
12
|
* and the registry gate (`../registration-conformance`): a catalog of
|
|
13
13
|
* cases graded against a caller-supplied resolver.
|
package/dist/run-conformance.js
CHANGED
|
@@ -108,11 +108,11 @@ async function runOneFixture(fixture, config, _reporter) {
|
|
|
108
108
|
try {
|
|
109
109
|
const wsUrl = deriveWsUrl(config.serverUrl);
|
|
110
110
|
transport = await openWsTransport({ kind: 'ws', url: wsUrl, auth: config.auth });
|
|
111
|
-
const
|
|
111
|
+
const renderId = extractRenderId(fixture);
|
|
112
112
|
transport.send({
|
|
113
113
|
type: 'subscribe',
|
|
114
114
|
payload: {
|
|
115
|
-
|
|
115
|
+
renderId,
|
|
116
116
|
appId: 'conformance',
|
|
117
117
|
role: 'user',
|
|
118
118
|
...(maybeSupportedVersions(fixture.expectedBehavior) ?? {}),
|
|
@@ -128,7 +128,7 @@ async function runOneFixture(fixture, config, _reporter) {
|
|
|
128
128
|
const match = matchBehavior(fixture.expectedBehavior, frames);
|
|
129
129
|
// Dispatch teardown regardless of match outcome. Failures in
|
|
130
130
|
// teardown surface as warnings; they do not flip pass → fail.
|
|
131
|
-
if (config.host !== undefined) {
|
|
131
|
+
if (config.host !== undefined && fixture.teardown !== undefined) {
|
|
132
132
|
for (const step of fixture.teardown) {
|
|
133
133
|
try {
|
|
134
134
|
await config.host.dispatchTeardown(narrowTeardownStep(step));
|
|
@@ -194,22 +194,22 @@ function deriveWsUrl(serverUrl) {
|
|
|
194
194
|
// No scheme provided — assume plain ws.
|
|
195
195
|
return `ws://${trimmed}/ws`;
|
|
196
196
|
}
|
|
197
|
-
function
|
|
198
|
-
// Prefer a
|
|
199
|
-
// this is the fixture's declared
|
|
200
|
-
// inputEnvelope.
|
|
197
|
+
function extractRenderId(fixture) {
|
|
198
|
+
// Prefer a renderId from the first `create-render` setup step —
|
|
199
|
+
// this is the fixture's declared render identity. Fall back to
|
|
200
|
+
// inputEnvelope.renderId, then to the fixture name.
|
|
201
201
|
for (const step of fixture.setup) {
|
|
202
|
-
if (step.type === 'create-
|
|
203
|
-
typeof step.
|
|
204
|
-
return step.
|
|
202
|
+
if (step.type === 'create-render' &&
|
|
203
|
+
typeof step.renderId === 'string') {
|
|
204
|
+
return step.renderId;
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
const envelope = fixture.inputEnvelope;
|
|
208
208
|
if (envelope !== null &&
|
|
209
209
|
typeof envelope === 'object' &&
|
|
210
|
-
'
|
|
211
|
-
typeof envelope.
|
|
212
|
-
return envelope.
|
|
210
|
+
'renderId' in envelope &&
|
|
211
|
+
typeof envelope.renderId === 'string') {
|
|
212
|
+
return envelope.renderId;
|
|
213
213
|
}
|
|
214
214
|
return fixture.name;
|
|
215
215
|
}
|
|
@@ -224,7 +224,7 @@ function shouldDispatchInputEnvelope(fixture) {
|
|
|
224
224
|
if (envelope === null || typeof envelope !== 'object')
|
|
225
225
|
return false;
|
|
226
226
|
const type = envelope.type;
|
|
227
|
-
return type === 'action'
|
|
227
|
+
return type === 'action';
|
|
228
228
|
}
|
|
229
229
|
function maybeSupportedVersions(behavior) {
|
|
230
230
|
if (behavior.kind === 'version-mismatch') {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* This catalog asserts a *structural* obligation: which
|
|
14
14
|
* `clientCapabilities` payloads a spec-conformant parser MUST accept
|
|
15
15
|
* and which it MUST reject — a property of the schema alone, with no
|
|
16
|
-
*
|
|
16
|
+
* render, no transport, no host. Folding it into the behavioral
|
|
17
17
|
* fixture shape (`TestCase`) would mean inventing a no-op
|
|
18
18
|
* `inputEnvelope` and a fake behavior kind for every case. Keeping it
|
|
19
19
|
* a distinct, smaller artifact is the honest modeling.
|
package/dist/types.d.ts
CHANGED
|
@@ -113,13 +113,13 @@ export type AuthConfig = {
|
|
|
113
113
|
* fixture with a warning rather than erroring. Third-party hosts MAY
|
|
114
114
|
* extend the setup vocabulary without a kit version bump.
|
|
115
115
|
*/
|
|
116
|
-
export type SetupStep =
|
|
117
|
-
export interface
|
|
118
|
-
readonly type: 'create-
|
|
119
|
-
/** Opaque
|
|
116
|
+
export type SetupStep = CreateRenderStep | RegisterToolStep | EmitEnvelopeStep | SeedChannelStep | UnknownSetupStep;
|
|
117
|
+
export interface CreateRenderStep {
|
|
118
|
+
readonly type: 'create-render';
|
|
119
|
+
/** Opaque render id the host allocates. Downstream steps + the
|
|
120
120
|
* fixture's `inputEnvelope` reference it by value. */
|
|
121
|
-
readonly
|
|
122
|
-
/** Optional app (tenant) id the
|
|
121
|
+
readonly renderId: string;
|
|
122
|
+
/** Optional app (tenant) id the render scopes to. Defaults to the
|
|
123
123
|
* host's implementation-defined "default app". */
|
|
124
124
|
readonly appId?: string;
|
|
125
125
|
}
|
|
@@ -149,7 +149,7 @@ export interface EmitEnvelopeStep {
|
|
|
149
149
|
}
|
|
150
150
|
export interface SeedChannelStep {
|
|
151
151
|
readonly type: 'seed-channel';
|
|
152
|
-
readonly
|
|
152
|
+
readonly renderId: string;
|
|
153
153
|
readonly channel: string;
|
|
154
154
|
readonly value: unknown;
|
|
155
155
|
}
|
|
@@ -165,11 +165,7 @@ export interface UnknownSetupStep {
|
|
|
165
165
|
* Teardown directive — mirrors {@link SetupStep}'s vocabulary, scoped
|
|
166
166
|
* to cleanup.
|
|
167
167
|
*/
|
|
168
|
-
export type TeardownStep =
|
|
169
|
-
export interface CloseSessionStep {
|
|
170
|
-
readonly type: 'close-session';
|
|
171
|
-
readonly sessionId: string;
|
|
172
|
-
}
|
|
168
|
+
export type TeardownStep = UnregisterToolStep | UnknownTeardownStep;
|
|
173
169
|
export interface UnregisterToolStep {
|
|
174
170
|
readonly type: 'unregister-tool';
|
|
175
171
|
readonly toolName: string;
|
|
@@ -333,9 +329,9 @@ export interface TestCase {
|
|
|
333
329
|
* shape — the runner passes it verbatim to the host's transport.
|
|
334
330
|
*
|
|
335
331
|
* Typically an object like
|
|
336
|
-
* `{type: 'action', channel: 0,
|
|
332
|
+
* `{type: 'action', channel: 0, renderId: 'test-r1', action: {…}}`
|
|
337
333
|
* (channel 0 = wired-action dispatch) or
|
|
338
|
-
* `{type: 'render',
|
|
334
|
+
* `{type: 'render', renderId: 'test-r1', resource: {…}}` for
|
|
339
335
|
* bootstrap-path fixtures.
|
|
340
336
|
*
|
|
341
337
|
* `unknown` rather than a typed union because the kit may drive
|
|
@@ -352,8 +348,13 @@ export interface TestCase {
|
|
|
352
348
|
* this field SHOULD be omitted — the nested one is canonical.
|
|
353
349
|
*/
|
|
354
350
|
readonly expectedObservability?: readonly ExpectedObservabilityEvent[];
|
|
355
|
-
/**
|
|
356
|
-
|
|
351
|
+
/**
|
|
352
|
+
* Cleanup directives the host executes AFTER the assertion. Optional —
|
|
353
|
+
* most fixtures need no teardown post the `close-render` drop (renders
|
|
354
|
+
* decay via TTL); `unregister-tool` is the only remaining kind, used
|
|
355
|
+
* by fixtures that mutate the tool registry.
|
|
356
|
+
*/
|
|
357
|
+
readonly teardown?: readonly TeardownStep[];
|
|
357
358
|
}
|
|
358
359
|
/**
|
|
359
360
|
* Canonical contract-error codes. Mirrors `@ggui-ai/protocol`'s
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAMH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GACvB,wBAAwB,GACxB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,oEAAoE;IACpE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC;IAC3B,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMjE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,SAAS,GACjB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ws-transport.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type ObservedFrame = {
|
|
|
16
16
|
/**
|
|
17
17
|
* Opaque handle returned by {@link openWsTransport}. Closed explicitly
|
|
18
18
|
* via {@link WsTransport.close} — the runner closes after each
|
|
19
|
-
* fixture so
|
|
19
|
+
* fixture so renders don't leak between cases.
|
|
20
20
|
*/
|
|
21
21
|
export interface WsTransport {
|
|
22
22
|
/** Send one frame over the wire. Serializes `frame` as JSON. */
|
package/dist/ws-transport.js
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* land as sibling modules with the same `Transport` shape. The
|
|
12
12
|
* transport is NOT a full MCP client — it does not try to be
|
|
13
13
|
* compatible with the MCP SDK, and it does not implement stack
|
|
14
|
-
* management. The kit runs against an already-provisioned
|
|
15
|
-
* (the host's `create-
|
|
14
|
+
* management. The kit runs against an already-provisioned render
|
|
15
|
+
* (the host's `create-render` setup step ran first) and treats the
|
|
16
16
|
* wire as opaque after that.
|
|
17
17
|
*
|
|
18
18
|
* Auth:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/protocol-conformance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-alpha.3",
|
|
4
4
|
"description": "Conformance test kit for the ggui protocol. Drives a behavioral fixture catalog against a live implementation over WebSocket, plus three pure-function catalogs (schema, registration, resolution) for the gadget obligations, and reports 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": [
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"ws": "^8.20.1",
|
|
52
|
-
"@ggui-ai/protocol": "0.
|
|
52
|
+
"@ggui-ai/protocol": "0.2.0-alpha.3"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/node": "^22.0.0",
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "canvas-bootstrap-mutual-exclusion",
|
|
3
|
-
"description": "Bootstrap with both `canvasMode: true` AND `stackItemId` is malformed — canvas iframes are session-scoped (no pinned stack item). Defensive parsers SHOULD reject; the protocol does not require them to. Reference parser (`@ggui-ai/iframe-runtime` `validateBootstrapMeta`) currently accepts the combination but the field-pair has no defined consumer semantics. This fixture pins the contract intent so future parsers can opt into strict rejection without surprise.",
|
|
4
|
-
"skipReason": null,
|
|
5
|
-
"setup": [
|
|
6
|
-
{ "type": "create-session", "sessionId": "ck-canvas-bootstrap-exclusion-1" },
|
|
7
|
-
{
|
|
8
|
-
"type": "set-app-mode",
|
|
9
|
-
"appId": "ck-canvas-bootstrap-exclusion-app",
|
|
10
|
-
"defaultMcpAppsMode": "canvas"
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"inputEnvelope": {
|
|
14
|
-
"type": "render",
|
|
15
|
-
"sessionId": "ck-canvas-bootstrap-exclusion-1",
|
|
16
|
-
"resource": {
|
|
17
|
-
"uri": "ui://ggui/session/ck-canvas-bootstrap-exclusion-1"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"expectedBehavior": {
|
|
21
|
-
"kind": "bootstrap-success",
|
|
22
|
-
"observabilitySequence": []
|
|
23
|
-
},
|
|
24
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-canvas-bootstrap-exclusion-1" }]
|
|
25
|
-
}
|
package/dist/fixtures/canvas-mode-wire-shapes/canvas-lifecycle-channel-emits-handshake-started.json
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "canvas-lifecycle-channel-emits-handshake-started",
|
|
3
|
-
"description": "When a canvas-mode session (`mcpAppsMode === 'canvas'`) enters `ggui_handshake`, the server publishes a `_ggui:lifecycle` envelope with `CanvasLifecyclePayload {kind: 'handshake_started', handshakeId, intent}` BEFORE the handshake completes. Animator pill state machine advances on receipt. Discriminator-narrowing: payload's `kind` field is the union tag; unknown `kind` values drop with a no-op on the iframe side. Fire-and-forget on the server: failure to publish degrades the animator (no pill state change) but MUST NOT abort the handshake's primary result.",
|
|
4
|
-
"skipReason": null,
|
|
5
|
-
"setup": [
|
|
6
|
-
{ "type": "create-session", "sessionId": "ck-canvas-lifecycle-handshake-1" },
|
|
7
|
-
{
|
|
8
|
-
"type": "set-app-mode",
|
|
9
|
-
"appId": "ck-canvas-lifecycle-handshake-app",
|
|
10
|
-
"defaultMcpAppsMode": "canvas"
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"inputEnvelope": {
|
|
14
|
-
"type": "action",
|
|
15
|
-
"channel": 0,
|
|
16
|
-
"sessionId": "ck-canvas-lifecycle-handshake-1",
|
|
17
|
-
"action": {
|
|
18
|
-
"name": "ggui_handshake",
|
|
19
|
-
"data": { "intent": "test" }
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"expectedBehavior": {
|
|
23
|
-
"kind": "stream-update",
|
|
24
|
-
"channel": "_ggui:lifecycle",
|
|
25
|
-
"value": {
|
|
26
|
-
"kind": "handshake_started"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-canvas-lifecycle-handshake-1" }]
|
|
30
|
-
}
|
package/dist/fixtures/canvas-mode-wire-shapes/canvas-navigated-updates-active-stack-item.json
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "canvas-navigated-updates-active-stack-item",
|
|
3
|
-
"description": "Client emits a `canvas_navigated` WS message (Client→Server) carrying `{sessionId, previousActiveItemId, activeItemId}`. Server updates `Session.activeStackItemId` to `activeItemId` (or null when the user popped to empty). Subsequent `ggui_consume` calls observe the new active pipe. Payload omits `appId` — the subscriber binding is the authoritative scope; an inbound message scoped to a wrong session is rejected with `SESSION_MISMATCH` rather than implicit reroute.",
|
|
4
|
-
"skipReason": null,
|
|
5
|
-
"setup": [
|
|
6
|
-
{ "type": "create-session", "sessionId": "ck-canvas-navigated-1" },
|
|
7
|
-
{
|
|
8
|
-
"type": "seed-channel",
|
|
9
|
-
"sessionId": "ck-canvas-navigated-1",
|
|
10
|
-
"channel": "_internal:stack",
|
|
11
|
-
"value": [
|
|
12
|
-
{ "id": "item-a", "type": "component" },
|
|
13
|
-
{ "id": "item-b", "type": "component" }
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
|
-
"inputEnvelope": {
|
|
18
|
-
"type": "canvas_navigated",
|
|
19
|
-
"payload": {
|
|
20
|
-
"sessionId": "ck-canvas-navigated-1",
|
|
21
|
-
"previousActiveItemId": "item-b",
|
|
22
|
-
"activeItemId": "item-a"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"expectedBehavior": {
|
|
26
|
-
"kind": "no-op",
|
|
27
|
-
"reason": "canvas_navigated has no synchronous response envelope — the side effect is a Session field mutation observed via subsequent ggui_consume / handshake output."
|
|
28
|
-
},
|
|
29
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-canvas-navigated-1" }]
|
|
30
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "host-context-observed-persists",
|
|
3
|
-
"description": "Client iframe echoes the `McpUiHostContext` it received from `ui/initialize` via `host_context_observed` WS message (Client→Server). Server projects to `HostContextProjection` and persists on `Session.hostContext`. Persisted projection is observable via subsequent `ggui_handshake` and `ggui_consume` output. Field shape: `availableDisplayModes`, `displayMode`, `theme` — sourced verbatim from the spec-compliant host's `_meta.ui.host` projection. Stale-snapshot guard: a later `host_context_observed` overwrites earlier values.",
|
|
4
|
-
"skipReason": null,
|
|
5
|
-
"setup": [{ "type": "create-session", "sessionId": "ck-host-context-observed-1" }],
|
|
6
|
-
"inputEnvelope": {
|
|
7
|
-
"type": "host_context_observed",
|
|
8
|
-
"payload": {
|
|
9
|
-
"sessionId": "ck-host-context-observed-1",
|
|
10
|
-
"hostContext": {
|
|
11
|
-
"availableDisplayModes": ["inline", "pip", "fullscreen"],
|
|
12
|
-
"displayMode": "inline",
|
|
13
|
-
"theme": "light"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"expectedBehavior": {
|
|
18
|
-
"kind": "no-op",
|
|
19
|
-
"reason": "host_context_observed has no synchronous response — the side effect is `Session.hostContext` mutation observable via subsequent ggui_consume / handshake output."
|
|
20
|
-
},
|
|
21
|
-
"teardown": [{ "type": "close-session", "sessionId": "ck-host-context-observed-1" }]
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/canvas-mode-wire-shapes/index.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;yBACyB;AACzB,eAAO,MAAM,4BAA4B,EAAE,SAAS,QAAQ,EAK3D,CAAC"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `canvas-mode-wire-shapes` fixture sub-module.
|
|
3
|
-
*
|
|
4
|
-
* Exercises the canvas-mode wire additions (protocol draft-2026-05-17):
|
|
5
|
-
*
|
|
6
|
-
* - `GguiBootstrapMeta.canvasMode` — discriminator + mutual-exclusion
|
|
7
|
-
* with `stackItemId`. Canvas iframes are session-scoped; no pinned
|
|
8
|
-
* item.
|
|
9
|
-
* - `_ggui:lifecycle` reserved channel + `CanvasLifecyclePayload`
|
|
10
|
-
* discriminated union (`handshake_started` / `handshake_completed` /
|
|
11
|
-
* `push_started` / `consume_polling`). Server fires fire-and-forget;
|
|
12
|
-
* iframe animator advances state machine on each kind.
|
|
13
|
-
* - `canvas_navigated` C→S WS message — user back-navigated; server
|
|
14
|
-
* updates `Session.activeStackItemId`. Payload omits `appId` —
|
|
15
|
-
* subscriber binding is authoritative scope.
|
|
16
|
-
* - `host_context_observed` C→S WS message — iframe echoes
|
|
17
|
-
* `McpUiHostContext` so server persists `HostContextProjection` on
|
|
18
|
-
* the session.
|
|
19
|
-
*
|
|
20
|
-
* All four fixtures ship with `skipReason: null`: the kit does not
|
|
21
|
-
* JSON-gate skip behavior. The runner dispatches every fixture and
|
|
22
|
-
* per-fixture skips emerge at RUNTIME from the host adapter throwing
|
|
23
|
-
* on an unimplemented setup directive (`set-app-mode`,
|
|
24
|
-
* `assert-session-field`, `assert-channel-envelope`) or from
|
|
25
|
-
* `match-behavior.ts` returning `unmatchable-on-ws`. Runner
|
|
26
|
-
* activation against the reference `ConformanceHost` is a follow-up
|
|
27
|
-
* kit minor once those directives land.
|
|
28
|
-
*
|
|
29
|
-
* Rationale: per the kit's drift discipline (see `../../types.ts`
|
|
30
|
-
* "Authored protocol vocabulary"), fixtures freeze the contract intent
|
|
31
|
-
* at the time the wire shape lands — not when the runner catches up.
|
|
32
|
-
* Third-party host implementers can read these JSONs directly to
|
|
33
|
-
* understand canvas-mode obligations without waiting for the reference
|
|
34
|
-
* host's directive coverage.
|
|
35
|
-
*/
|
|
36
|
-
import canvasBootstrapMutualExclusion from './canvas-bootstrap-mutual-exclusion.json' with { type: 'json' };
|
|
37
|
-
import canvasLifecycleChannelEmitsHandshakeStarted from './canvas-lifecycle-channel-emits-handshake-started.json' with { type: 'json' };
|
|
38
|
-
import canvasNavigatedUpdatesActiveStackItem from './canvas-navigated-updates-active-stack-item.json' with { type: 'json' };
|
|
39
|
-
import hostContextObservedPersists from './host-context-observed-persists.json' with { type: 'json' };
|
|
40
|
-
/** All fixtures asserting canvas-mode wire shapes (protocol
|
|
41
|
-
* draft-2026-05-17). */
|
|
42
|
-
export const canvasModeWireShapesFixtures = [
|
|
43
|
-
canvasBootstrapMutualExclusion,
|
|
44
|
-
canvasLifecycleChannelEmitsHandshakeStarted,
|
|
45
|
-
canvasNavigatedUpdatesActiveStackItem,
|
|
46
|
-
hostContextObservedPersists,
|
|
47
|
-
];
|