@ggui-ai/protocol-conformance 0.6.3 → 0.8.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 +59 -18
- package/dist/binding-conformance/cases/bind-blueprint-no-contract-none.json +6 -0
- package/dist/binding-conformance/cases/bind-contract-without-tool-names-none.json +18 -0
- package/dist/binding-conformance/cases/bind-declared-gadget.json +13 -0
- package/dist/binding-conformance/cases/bind-declared-wins-over-contract.json +23 -0
- package/dist/binding-conformance/cases/bind-derived-caps-at-sixteen.json +54 -0
- package/dist/binding-conformance/cases/bind-derived-props-and-stream.json +36 -0
- package/dist/binding-conformance/cases/bind-derived-skips-invalid-names.json +40 -0
- package/dist/binding-conformance/cases/bind-derived-union-dedupes.json +38 -0
- package/dist/binding-conformance/cases/bind-gadget-undeclared-none.json +6 -0
- package/dist/binding-conformance/cases/bind-reject-charset.json +9 -0
- package/dist/binding-conformance/cases/bind-reject-duplicate-pair.json +12 -0
- package/dist/binding-conformance/cases/bind-reject-empty-list.json +9 -0
- package/dist/binding-conformance/cases/bind-reject-overlong-name.json +13 -0
- package/dist/binding-conformance/cases/bind-reject-server-charset.json +9 -0
- package/dist/binding-conformance/cases/bind-reject-too-many-entries.json +27 -0
- package/dist/binding-conformance/cases/filter-case-sensitive-server.json +7 -0
- package/dist/binding-conformance/cases/filter-case-sensitive-tool.json +7 -0
- package/dist/binding-conformance/cases/filter-none-passes-bound.json +7 -0
- package/dist/binding-conformance/cases/filter-none-passes-unbound.json +6 -0
- package/dist/binding-conformance/cases/filter-pair-bare-never-matches.json +7 -0
- package/dist/binding-conformance/cases/filter-pair-exact.json +10 -0
- package/dist/binding-conformance/cases/filter-pair-not-cross-entry.json +10 -0
- package/dist/binding-conformance/cases/filter-server-excludes-bare.json +7 -0
- package/dist/binding-conformance/cases/filter-server-match.json +7 -0
- package/dist/binding-conformance/cases/filter-tool-cross-server.json +7 -0
- package/dist/binding-conformance/cases/filter-tool-excludes-unbound.json +6 -0
- package/dist/binding-conformance/cases/filter-tool-matches-bare-entry.json +7 -0
- package/dist/binding-conformance/cases/filter-tool-no-match.json +7 -0
- package/dist/binding-conformance/index.d.ts +214 -0
- package/dist/binding-conformance/index.d.ts.map +1 -0
- package/dist/binding-conformance/index.js +153 -0
- package/dist/fixtures/consume-buffer/index.d.ts.map +1 -1
- package/dist/fixtures/consume-buffer/index.js +4 -1
- package/dist/fixtures/index.d.ts +42 -4
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +42 -4
- package/dist/fixtures/reserved-channel-authority/index.d.ts.map +1 -1
- package/dist/fixtures/reserved-channel-authority/index.js +4 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/match-behavior.d.ts.map +1 -1
- package/dist/match-behavior.js +4 -2
- package/dist/resolution-conformance/cases/resolve-bundle-host-computed.json +3 -3
- package/dist/resolution-conformance/cases/resolve-default-host.json +2 -2
- package/dist/resolution-conformance/cases/resolve-loopback-host-http-scheme.json +2 -2
- package/dist/resource-read-conformance/cases/all-ephemeral-substrate-fuses-like-none.json +29 -0
- package/dist/resource-read-conformance/cases/channel-less-read-mounts-inline.json +24 -0
- package/dist/resource-read-conformance/cases/evicted-row-remints-from-the-durable-record.json +26 -0
- package/dist/resource-read-conformance/cases/half-wired-blueprints-only-substrate-fuses-like-none.json +29 -0
- package/dist/resource-read-conformance/cases/half-wired-identity-only-substrate-fuses-like-none.json +29 -0
- package/dist/resource-read-conformance/cases/live-row-read-returns-mount-material.json +18 -0
- package/dist/resource-read-conformance/cases/malformed-locator-stays-outside-the-typed-set.json +19 -0
- package/dist/resource-read-conformance/cases/read-miss-answers-not-found.json +23 -0
- package/dist/resource-read-conformance/cases/read-on-a-substrate-less-server-answers-not-supported.json +22 -0
- package/dist/resource-read-conformance/cases/read-record-with-purged-blueprint-answers-blueprint-unresolvable.json +29 -0
- package/dist/resource-read-conformance/cases/read-refusal-is-indistinguishable-from-a-miss.json +47 -0
- package/dist/resource-read-conformance/cases/read-without-a-delivery-channel-answers-not-mountable.json +33 -0
- package/dist/resource-read-conformance/cases/registry-match-fuses-on-not-mountable.json +40 -0
- package/dist/resource-read-conformance/cases/substrate-less-fusion-of-refusal-and-miss.json +29 -0
- package/dist/resource-read-conformance/index.d.ts +383 -0
- package/dist/resource-read-conformance/index.d.ts.map +1 -0
- package/dist/resource-read-conformance/index.js +793 -0
- package/package.json +13 -3
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binding-conformance catalog — MCP tool-binding resolution + search
|
|
3
|
+
* filter semantics (SPEC §7.7.4 — tool bindings & discovery).
|
|
4
|
+
*
|
|
5
|
+
* ## Why this is a pure-function catalog
|
|
6
|
+
*
|
|
7
|
+
* Two pure obligations connect a registry artifact to the MCP tools
|
|
8
|
+
* it renders:
|
|
9
|
+
*
|
|
10
|
+
* 1. RESOLUTION — given a manifest, which binding set is
|
|
11
|
+
* effective? A declared `mcpTools` list wins entirely; a
|
|
12
|
+
* blueprint without one derives bare tool names from its
|
|
13
|
+
* contract's lineage fields
|
|
14
|
+
* (`propsSpec.properties[*].sourceTool`,
|
|
15
|
+
* `streamSpec[*].source.tool`); a schema-invalid list rejects
|
|
16
|
+
* with the manifest-validation code. Bindings are search
|
|
17
|
+
* metadata only — they never enter contract canonicalization
|
|
18
|
+
* or any cache identity.
|
|
19
|
+
* 2. FILTERING — given an artifact's stored binding set and a
|
|
20
|
+
* search query's `tool` / `server` params, does the artifact
|
|
21
|
+
* match? Both dimensions are case-sensitive exact and must land
|
|
22
|
+
* on a single entry; a bare entry never satisfies a server
|
|
23
|
+
* dimension; no dimensions given passes everything.
|
|
24
|
+
*
|
|
25
|
+
* Both are deterministic functions — no render, transport, or wire
|
|
26
|
+
* frame — so they get the same treatment as the registry gate
|
|
27
|
+
* (`../registration-conformance`) and bundle-URL resolution
|
|
28
|
+
* (`../resolution-conformance`): catalogs of JSON cases graded
|
|
29
|
+
* against caller-supplied functions.
|
|
30
|
+
*
|
|
31
|
+
* ## Polyglot, decoupled
|
|
32
|
+
*
|
|
33
|
+
* Each case ships as raw JSON under `./cases/`.
|
|
34
|
+
* {@link runBindingResolutionCases} / {@link runBindingFilterCases}
|
|
35
|
+
* take the implementation as a callback — the kit never imports a
|
|
36
|
+
* concrete resolver or search filter, so adopters drive their OWN.
|
|
37
|
+
* The reference binding (`./binding-conformance.test.ts`) restates
|
|
38
|
+
* faithful minimal implementations in-test.
|
|
39
|
+
*/
|
|
40
|
+
import type { DataContract } from "@ggui-ai/protocol";
|
|
41
|
+
/**
|
|
42
|
+
* One MCP tool binding as authored on a manifest / stored on search
|
|
43
|
+
* metadata. `server` carries `serverInfo.name` semantics; a bare
|
|
44
|
+
* entry (no `server`) is server-agnostic.
|
|
45
|
+
*/
|
|
46
|
+
export interface McpToolBindingDecl {
|
|
47
|
+
readonly server?: string;
|
|
48
|
+
readonly tool: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The binding-relevant subset of an artifact manifest the resolver
|
|
52
|
+
* reads. Authored kit-local — decoupled from any shipping manifest
|
|
53
|
+
* schema on purpose; `contract` reuses the protocol's
|
|
54
|
+
* {@link DataContract} type the way `../registration-conformance`
|
|
55
|
+
* does.
|
|
56
|
+
*/
|
|
57
|
+
export interface BindingManifestEntry {
|
|
58
|
+
/** Which manifest kind the entry models. Only blueprints derive. */
|
|
59
|
+
readonly kind: "gadget" | "blueprint";
|
|
60
|
+
/** The `mcpTools` list as authored — possibly invalid. */
|
|
61
|
+
readonly mcpTools?: readonly McpToolBindingDecl[];
|
|
62
|
+
/** The blueprint's contract, when it has one. */
|
|
63
|
+
readonly contract?: DataContract;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The code a schema-invalid `mcpTools` list classifies into.
|
|
67
|
+
* Extensibly-closed `(string & {})` tail so a later protocol
|
|
68
|
+
* revision's code rides through without a kit bump — same
|
|
69
|
+
* discipline as `GadgetGateRejectCode` in
|
|
70
|
+
* `../registration-conformance`.
|
|
71
|
+
*/
|
|
72
|
+
export type BindingRejectCode = "manifest_invalid" | (string & {});
|
|
73
|
+
/**
|
|
74
|
+
* What resolving one manifest's bindings produces: accept with a
|
|
75
|
+
* `source` + `bindings` pair (declared or derived — present together
|
|
76
|
+
* or absent together), accept with NEITHER (the artifact has no
|
|
77
|
+
* bindings and is not findable by tool), or reject with the
|
|
78
|
+
* manifest-validation code.
|
|
79
|
+
*/
|
|
80
|
+
export type BindingResolutionOutcome = {
|
|
81
|
+
readonly outcome: "accept";
|
|
82
|
+
readonly source?: "declared" | "derived";
|
|
83
|
+
readonly bindings?: readonly McpToolBindingDecl[];
|
|
84
|
+
} | {
|
|
85
|
+
readonly outcome: "reject";
|
|
86
|
+
readonly code: BindingRejectCode;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* A search query's tool/server params as one filter input. Both
|
|
90
|
+
* optional — an absent dimension does not constrain. Matching is
|
|
91
|
+
* case-sensitive exact on both dimensions.
|
|
92
|
+
*/
|
|
93
|
+
export interface McpToolFilterDecl {
|
|
94
|
+
readonly tool?: string;
|
|
95
|
+
readonly server?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One binding-resolution case. Authored as JSON under `./cases/`,
|
|
99
|
+
* consumed via {@link bindingResolutionCases}, graded by
|
|
100
|
+
* {@link runBindingResolutionCases}.
|
|
101
|
+
*
|
|
102
|
+
* The shape IS the public API — additive changes only.
|
|
103
|
+
*/
|
|
104
|
+
export interface BindingResolutionCase {
|
|
105
|
+
/** Unique case name. MUST match the JSON filename without `.json`. */
|
|
106
|
+
readonly name: string;
|
|
107
|
+
/** Which binding obligation this case proves. */
|
|
108
|
+
readonly description: string;
|
|
109
|
+
/** The manifest subset fed to the resolver. */
|
|
110
|
+
readonly entry: BindingManifestEntry;
|
|
111
|
+
/**
|
|
112
|
+
* The outcome a spec-conformant resolver MUST produce. Binding
|
|
113
|
+
* lists are compared order-sensitively: declared bindings carry
|
|
114
|
+
* authored order; derived bindings carry first-appearance order
|
|
115
|
+
* (props in declaration order, then stream channels), duplicates
|
|
116
|
+
* collapsed to the first occurrence.
|
|
117
|
+
*/
|
|
118
|
+
readonly expect: BindingResolutionOutcome;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* One filter-semantics case. Authored as JSON under `./cases/`,
|
|
122
|
+
* consumed via {@link bindingFilterCases}, graded by
|
|
123
|
+
* {@link runBindingFilterCases}.
|
|
124
|
+
*
|
|
125
|
+
* The shape IS the public API — additive changes only.
|
|
126
|
+
*/
|
|
127
|
+
export interface BindingFilterCase {
|
|
128
|
+
/** Unique case name. MUST match the JSON filename without `.json`. */
|
|
129
|
+
readonly name: string;
|
|
130
|
+
/** Which filter obligation this case proves. */
|
|
131
|
+
readonly description: string;
|
|
132
|
+
/** The artifact's stored binding set — absent models an unbound artifact. */
|
|
133
|
+
readonly bindings?: readonly McpToolBindingDecl[];
|
|
134
|
+
/** The query's tool/server params — `{}` models neither given. */
|
|
135
|
+
readonly filters: McpToolFilterDecl;
|
|
136
|
+
/** Whether a spec-conformant filter matches the artifact. */
|
|
137
|
+
readonly expect: boolean;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Every binding-resolution case the kit ships, in deterministic
|
|
141
|
+
* order — declared first, then derived, then the no-binding edges,
|
|
142
|
+
* then the schema rejects.
|
|
143
|
+
*/
|
|
144
|
+
export declare const bindingResolutionCases: readonly BindingResolutionCase[];
|
|
145
|
+
/**
|
|
146
|
+
* Every filter-semantics case the kit ships, in deterministic
|
|
147
|
+
* order — tool-dimension, server-dimension, pair, no-filter
|
|
148
|
+
* passthrough, then case-sensitivity.
|
|
149
|
+
*/
|
|
150
|
+
export declare const bindingFilterCases: readonly BindingFilterCase[];
|
|
151
|
+
/** One resolution case the resolver under test graded wrong. */
|
|
152
|
+
export interface BindingResolutionMismatch {
|
|
153
|
+
readonly name: string;
|
|
154
|
+
/** The outcome the catalog says a conformant resolver MUST produce. */
|
|
155
|
+
readonly expected: BindingResolutionOutcome;
|
|
156
|
+
/** The outcome the resolver under test actually produced. */
|
|
157
|
+
readonly actual: BindingResolutionOutcome;
|
|
158
|
+
}
|
|
159
|
+
/** Outcome of grading a resolver against the resolution catalog. */
|
|
160
|
+
export interface BindingResolutionResult {
|
|
161
|
+
/** Names of cases the resolver graded correctly. */
|
|
162
|
+
readonly passed: readonly string[];
|
|
163
|
+
/** Cases the resolver graded wrong — empty iff fully conformant. */
|
|
164
|
+
readonly failed: readonly BindingResolutionMismatch[];
|
|
165
|
+
}
|
|
166
|
+
/** One filter case the predicate under test graded wrong. */
|
|
167
|
+
export interface BindingFilterMismatch {
|
|
168
|
+
readonly name: string;
|
|
169
|
+
/** Whether the catalog says a conformant filter matches. */
|
|
170
|
+
readonly expected: boolean;
|
|
171
|
+
/** What the predicate under test actually returned. */
|
|
172
|
+
readonly actual: boolean;
|
|
173
|
+
}
|
|
174
|
+
/** Outcome of grading a filter predicate against the filter catalog. */
|
|
175
|
+
export interface BindingFilterResult {
|
|
176
|
+
/** Names of cases the predicate graded correctly. */
|
|
177
|
+
readonly passed: readonly string[];
|
|
178
|
+
/** Cases the predicate graded wrong — empty iff fully conformant. */
|
|
179
|
+
readonly failed: readonly BindingFilterMismatch[];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Grade a binding resolver against the resolution catalog.
|
|
183
|
+
*
|
|
184
|
+
* `resolve` MUST be a pure computation of `(entry) →
|
|
185
|
+
* BindingResolutionOutcome` — schema validation of a declared list
|
|
186
|
+
* plus declared-wins/derivation precedence, composed however the
|
|
187
|
+
* implementation likes. The kit deliberately does NOT import a
|
|
188
|
+
* concrete resolver — adopters pass their own (the reference
|
|
189
|
+
* binding uses a faithful in-test implementation; see
|
|
190
|
+
* `./binding-conformance.test.ts`). A conformant resolver produces
|
|
191
|
+
* an empty `failed` array.
|
|
192
|
+
*
|
|
193
|
+
* `resolve` is invoked exactly once per case, in
|
|
194
|
+
* {@link bindingResolutionCases} order; it MUST be pure and MUST
|
|
195
|
+
* NOT throw (a throwing resolver is itself non-conformant — wrap it
|
|
196
|
+
* so a classified rejection becomes a returned outcome).
|
|
197
|
+
*/
|
|
198
|
+
export declare function runBindingResolutionCases(resolve: (entry: BindingManifestEntry) => BindingResolutionOutcome): BindingResolutionResult;
|
|
199
|
+
/**
|
|
200
|
+
* Grade a search filter predicate against the filter catalog.
|
|
201
|
+
*
|
|
202
|
+
* `matches` MUST be a pure computation of `(bindings, filters) →
|
|
203
|
+
* boolean` — the same predicate every storage implementation shares
|
|
204
|
+
* so `tool=` / `server=` behave identically everywhere. The kit
|
|
205
|
+
* deliberately does NOT import a concrete predicate — adopters pass
|
|
206
|
+
* their own. A conformant predicate produces an empty `failed`
|
|
207
|
+
* array.
|
|
208
|
+
*
|
|
209
|
+
* `matches` is invoked exactly once per case, in
|
|
210
|
+
* {@link bindingFilterCases} order; it MUST be pure and MUST NOT
|
|
211
|
+
* throw.
|
|
212
|
+
*/
|
|
213
|
+
export declare function runBindingFilterCases(matches: (bindings: readonly McpToolBindingDecl[] | undefined, filters: McpToolFilterDecl) => boolean): BindingFilterResult;
|
|
214
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding-conformance/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import bindBlueprintNoContractNone from "./cases/bind-blueprint-no-contract-none.json" with { type: "json" };
|
|
2
|
+
import bindContractWithoutToolNamesNone from "./cases/bind-contract-without-tool-names-none.json" with { type: "json" };
|
|
3
|
+
import bindDeclaredGadget from "./cases/bind-declared-gadget.json" with { type: "json" };
|
|
4
|
+
import bindDeclaredWinsOverContract from "./cases/bind-declared-wins-over-contract.json" with { type: "json" };
|
|
5
|
+
import bindDerivedCapsAtSixteen from "./cases/bind-derived-caps-at-sixteen.json" with { type: "json" };
|
|
6
|
+
import bindDerivedPropsAndStream from "./cases/bind-derived-props-and-stream.json" with { type: "json" };
|
|
7
|
+
import bindDerivedSkipsInvalidNames from "./cases/bind-derived-skips-invalid-names.json" with { type: "json" };
|
|
8
|
+
import bindDerivedUnionDedupes from "./cases/bind-derived-union-dedupes.json" with { type: "json" };
|
|
9
|
+
import bindGadgetUndeclaredNone from "./cases/bind-gadget-undeclared-none.json" with { type: "json" };
|
|
10
|
+
import bindRejectCharset from "./cases/bind-reject-charset.json" with { type: "json" };
|
|
11
|
+
import bindRejectDuplicatePair from "./cases/bind-reject-duplicate-pair.json" with { type: "json" };
|
|
12
|
+
import bindRejectEmptyList from "./cases/bind-reject-empty-list.json" with { type: "json" };
|
|
13
|
+
import bindRejectOverlongName from "./cases/bind-reject-overlong-name.json" with { type: "json" };
|
|
14
|
+
import bindRejectServerCharset from "./cases/bind-reject-server-charset.json" with { type: "json" };
|
|
15
|
+
import bindRejectTooManyEntries from "./cases/bind-reject-too-many-entries.json" with { type: "json" };
|
|
16
|
+
import filterCaseSensitiveServer from "./cases/filter-case-sensitive-server.json" with { type: "json" };
|
|
17
|
+
import filterCaseSensitiveTool from "./cases/filter-case-sensitive-tool.json" with { type: "json" };
|
|
18
|
+
import filterNonePassesBound from "./cases/filter-none-passes-bound.json" with { type: "json" };
|
|
19
|
+
import filterNonePassesUnbound from "./cases/filter-none-passes-unbound.json" with { type: "json" };
|
|
20
|
+
import filterPairBareNeverMatches from "./cases/filter-pair-bare-never-matches.json" with { type: "json" };
|
|
21
|
+
import filterPairExact from "./cases/filter-pair-exact.json" with { type: "json" };
|
|
22
|
+
import filterPairNotCrossEntry from "./cases/filter-pair-not-cross-entry.json" with { type: "json" };
|
|
23
|
+
import filterServerExcludesBare from "./cases/filter-server-excludes-bare.json" with { type: "json" };
|
|
24
|
+
import filterServerMatch from "./cases/filter-server-match.json" with { type: "json" };
|
|
25
|
+
import filterToolCrossServer from "./cases/filter-tool-cross-server.json" with { type: "json" };
|
|
26
|
+
import filterToolExcludesUnbound from "./cases/filter-tool-excludes-unbound.json" with { type: "json" };
|
|
27
|
+
import filterToolMatchesBareEntry from "./cases/filter-tool-matches-bare-entry.json" with { type: "json" };
|
|
28
|
+
import filterToolNoMatch from "./cases/filter-tool-no-match.json" with { type: "json" };
|
|
29
|
+
/**
|
|
30
|
+
* Every binding-resolution case the kit ships, in deterministic
|
|
31
|
+
* order — declared first, then derived, then the no-binding edges,
|
|
32
|
+
* then the schema rejects.
|
|
33
|
+
*/
|
|
34
|
+
export const bindingResolutionCases = [
|
|
35
|
+
bindDeclaredGadget,
|
|
36
|
+
bindDeclaredWinsOverContract,
|
|
37
|
+
bindDerivedPropsAndStream,
|
|
38
|
+
bindDerivedUnionDedupes,
|
|
39
|
+
bindDerivedSkipsInvalidNames,
|
|
40
|
+
bindDerivedCapsAtSixteen,
|
|
41
|
+
bindBlueprintNoContractNone,
|
|
42
|
+
bindContractWithoutToolNamesNone,
|
|
43
|
+
bindGadgetUndeclaredNone,
|
|
44
|
+
bindRejectCharset,
|
|
45
|
+
bindRejectServerCharset,
|
|
46
|
+
bindRejectDuplicatePair,
|
|
47
|
+
bindRejectOverlongName,
|
|
48
|
+
bindRejectTooManyEntries,
|
|
49
|
+
bindRejectEmptyList,
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* Every filter-semantics case the kit ships, in deterministic
|
|
53
|
+
* order — tool-dimension, server-dimension, pair, no-filter
|
|
54
|
+
* passthrough, then case-sensitivity.
|
|
55
|
+
*/
|
|
56
|
+
export const bindingFilterCases = [
|
|
57
|
+
filterToolCrossServer,
|
|
58
|
+
filterToolMatchesBareEntry,
|
|
59
|
+
filterToolNoMatch,
|
|
60
|
+
filterServerMatch,
|
|
61
|
+
filterServerExcludesBare,
|
|
62
|
+
filterPairExact,
|
|
63
|
+
filterPairNotCrossEntry,
|
|
64
|
+
filterPairBareNeverMatches,
|
|
65
|
+
filterNonePassesBound,
|
|
66
|
+
filterNonePassesUnbound,
|
|
67
|
+
filterToolExcludesUnbound,
|
|
68
|
+
filterCaseSensitiveTool,
|
|
69
|
+
filterCaseSensitiveServer,
|
|
70
|
+
];
|
|
71
|
+
function bindingListsEqual(a, b) {
|
|
72
|
+
if (a === undefined || b === undefined)
|
|
73
|
+
return a === b;
|
|
74
|
+
if (a.length !== b.length)
|
|
75
|
+
return false;
|
|
76
|
+
return a.every((entry, i) => {
|
|
77
|
+
const other = b[i];
|
|
78
|
+
return other !== undefined && entry.tool === other.tool && entry.server === other.server;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function resolutionOutcomeEquals(a, b) {
|
|
82
|
+
if (a.outcome === "reject" || b.outcome === "reject") {
|
|
83
|
+
return a.outcome === "reject" && b.outcome === "reject" && a.code === b.code;
|
|
84
|
+
}
|
|
85
|
+
return a.source === b.source && bindingListsEqual(a.bindings, b.bindings);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Grade a binding resolver against the resolution catalog.
|
|
89
|
+
*
|
|
90
|
+
* `resolve` MUST be a pure computation of `(entry) →
|
|
91
|
+
* BindingResolutionOutcome` — schema validation of a declared list
|
|
92
|
+
* plus declared-wins/derivation precedence, composed however the
|
|
93
|
+
* implementation likes. The kit deliberately does NOT import a
|
|
94
|
+
* concrete resolver — adopters pass their own (the reference
|
|
95
|
+
* binding uses a faithful in-test implementation; see
|
|
96
|
+
* `./binding-conformance.test.ts`). A conformant resolver produces
|
|
97
|
+
* an empty `failed` array.
|
|
98
|
+
*
|
|
99
|
+
* `resolve` is invoked exactly once per case, in
|
|
100
|
+
* {@link bindingResolutionCases} order; it MUST be pure and MUST
|
|
101
|
+
* NOT throw (a throwing resolver is itself non-conformant — wrap it
|
|
102
|
+
* so a classified rejection becomes a returned outcome).
|
|
103
|
+
*/
|
|
104
|
+
export function runBindingResolutionCases(resolve) {
|
|
105
|
+
const passed = [];
|
|
106
|
+
const failed = [];
|
|
107
|
+
for (const testCase of bindingResolutionCases) {
|
|
108
|
+
const actual = resolve(testCase.entry);
|
|
109
|
+
if (resolutionOutcomeEquals(actual, testCase.expect)) {
|
|
110
|
+
passed.push(testCase.name);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
failed.push({
|
|
114
|
+
name: testCase.name,
|
|
115
|
+
expected: testCase.expect,
|
|
116
|
+
actual,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { passed, failed };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Grade a search filter predicate against the filter catalog.
|
|
124
|
+
*
|
|
125
|
+
* `matches` MUST be a pure computation of `(bindings, filters) →
|
|
126
|
+
* boolean` — the same predicate every storage implementation shares
|
|
127
|
+
* so `tool=` / `server=` behave identically everywhere. The kit
|
|
128
|
+
* deliberately does NOT import a concrete predicate — adopters pass
|
|
129
|
+
* their own. A conformant predicate produces an empty `failed`
|
|
130
|
+
* array.
|
|
131
|
+
*
|
|
132
|
+
* `matches` is invoked exactly once per case, in
|
|
133
|
+
* {@link bindingFilterCases} order; it MUST be pure and MUST NOT
|
|
134
|
+
* throw.
|
|
135
|
+
*/
|
|
136
|
+
export function runBindingFilterCases(matches) {
|
|
137
|
+
const passed = [];
|
|
138
|
+
const failed = [];
|
|
139
|
+
for (const testCase of bindingFilterCases) {
|
|
140
|
+
const actual = matches(testCase.bindings, testCase.filters);
|
|
141
|
+
if (actual === testCase.expect) {
|
|
142
|
+
passed.push(testCase.name);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
failed.push({
|
|
146
|
+
name: testCase.name,
|
|
147
|
+
expected: testCase.expect,
|
|
148
|
+
actual,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { passed, failed };
|
|
153
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/consume-buffer/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/consume-buffer/index.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;gCAEgC;AAChC,eAAO,MAAM,qBAAqB,EAAE,SAAS,QAAQ,EAIpD,CAAC"}
|
|
@@ -20,7 +20,10 @@
|
|
|
20
20
|
*
|
|
21
21
|
* The retrieval half — the agent draining the buffer via
|
|
22
22
|
* `ggui_consume` — is an MCP tool call a WS-only runner cannot drive;
|
|
23
|
-
* that obligation belongs to
|
|
23
|
+
* that obligation belongs to a driver bound to `tools/call`, not this
|
|
24
|
+
* catalog. The kit's `resources/read` driver
|
|
25
|
+
* (`../../resource-read-conformance`) binds a different method and does
|
|
26
|
+
* not close it.
|
|
24
27
|
* Same declared-gap posture for the schema-validity meta-check on the
|
|
25
28
|
* DECLARED schema itself: a malformed authored schema is a fixture-
|
|
26
29
|
* authoring error the runner throws on (validating parse), while a
|
package/dist/fixtures/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* ## Current coverage
|
|
22
22
|
*
|
|
23
|
-
* Six sub-modules with content (12 fixtures). Additional sub-modules
|
|
23
|
+
* Six WebSocket sub-modules with content (12 fixtures). Additional sub-modules
|
|
24
24
|
* (`data-contract`, `tool-name-uniqueness`)
|
|
25
25
|
* are reserved for additive fixture expansion and not yet
|
|
26
26
|
* materialized — adding fixtures there is a kit minor version.
|
|
@@ -36,6 +36,43 @@
|
|
|
36
36
|
* frame to drive — so they do NOT belong in this behavioral fixture
|
|
37
37
|
* catalog.
|
|
38
38
|
*
|
|
39
|
+
* ## An MCP-binding driver EXISTS for `resources/read` — `../resource-read-conformance`
|
|
40
|
+
*
|
|
41
|
+
* This catalog used to declare the MCP-binding driver as missing. It is
|
|
42
|
+
* no longer missing. `../resource-read-conformance` ships a driver
|
|
43
|
+
* bound to the MCP **`resources/read`** method, with its own case
|
|
44
|
+
* shape, its own runner (`runResourceReadConformance`) and its own
|
|
45
|
+
* scenario-driver seam. It grades the typed-failure contract for a
|
|
46
|
+
* render locator (`ui://ggui/render/{sessionId}[/{blueprintKey}]`): the
|
|
47
|
+
* four failure classes on their canonical numbers, the constant
|
|
48
|
+
* `NOT_FOUND` body, the deny-equals-miss byte-identity obligation, and
|
|
49
|
+
* the invariant that any successful result declares a delivery channel.
|
|
50
|
+
*
|
|
51
|
+
* Its cases are NOT registered in the map below, and that is
|
|
52
|
+
* deliberate. Every entry here is driven by `runConformance()` over a
|
|
53
|
+
* live channel, so an MCP case landing in this catalog would be a
|
|
54
|
+
* permanent skip on every WebSocket run — a skip that can never become
|
|
55
|
+
* a pass on that transport, which is exactly the false gate this kit's
|
|
56
|
+
* exact skip-set pinning exists to prevent.
|
|
57
|
+
*
|
|
58
|
+
* ### Precisely what that driver does NOT close
|
|
59
|
+
*
|
|
60
|
+
* It binds ONE MCP method. `tools/call` has no driver, so both of these
|
|
61
|
+
* remain open and neither is addressed by it:
|
|
62
|
+
*
|
|
63
|
+
* - **`stream-delivery-roundtrip`** — see the next section. Needs
|
|
64
|
+
* `ggui_emit`.
|
|
65
|
+
* - **The `ggui_consume` retrieval half of the action loop** —
|
|
66
|
+
* `action-ack-sequence` proves the append half; draining the buffer
|
|
67
|
+
* is `ggui_consume`.
|
|
68
|
+
*
|
|
69
|
+
* `resources/read` and `tools/call` are different methods with
|
|
70
|
+
* different seams: the former is a stateless read of a URI the kit can
|
|
71
|
+
* construct, the latter is an invocation whose arguments and effects
|
|
72
|
+
* are the agent's vocabulary. A driver for one is not a driver for the
|
|
73
|
+
* other, and saying "the kit now has an MCP driver" without that
|
|
74
|
+
* qualifier would read as closing gaps it does not touch.
|
|
75
|
+
*
|
|
39
76
|
* ## What is NOT here — declared Path-A sequencing gap
|
|
40
77
|
*
|
|
41
78
|
* A `stream-delivery-roundtrip` fixture (an `emit-envelope`'d payload
|
|
@@ -52,9 +89,10 @@
|
|
|
52
89
|
* transport, while emission is server-side (the agent's `ggui_emit`
|
|
53
90
|
* MCP tool) — routing a host directive through the wire-frame slot
|
|
54
91
|
* would conflate the two vocabularies. Honest grading needs either a
|
|
55
|
-
* post-subscribe host-directive phase (a runner-mechanism change) or
|
|
56
|
-
*
|
|
57
|
-
*
|
|
92
|
+
* post-subscribe host-directive phase (a runner-mechanism change) or a
|
|
93
|
+
* driver bound to `tools/call`. The `resources/read` driver above is
|
|
94
|
+
* NOT that driver. Declared here rather than papered over with a
|
|
95
|
+
* fixture that fails conformant servers on sequencing alone.
|
|
58
96
|
*/
|
|
59
97
|
export { bootstrapProtocolFixtures } from './bootstrap-protocol/index.js';
|
|
60
98
|
export { consumeBufferFixtures } from './consume-buffer/index.js';
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ5C;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,cAAc,GACd,4BAA4B,GAC5B,0BAA0B,GAC1B,mBAAmB,GACnB,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
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* ## Current coverage
|
|
22
22
|
*
|
|
23
|
-
* Six sub-modules with content (12 fixtures). Additional sub-modules
|
|
23
|
+
* Six WebSocket sub-modules with content (12 fixtures). Additional sub-modules
|
|
24
24
|
* (`data-contract`, `tool-name-uniqueness`)
|
|
25
25
|
* are reserved for additive fixture expansion and not yet
|
|
26
26
|
* materialized — adding fixtures there is a kit minor version.
|
|
@@ -36,6 +36,43 @@
|
|
|
36
36
|
* frame to drive — so they do NOT belong in this behavioral fixture
|
|
37
37
|
* catalog.
|
|
38
38
|
*
|
|
39
|
+
* ## An MCP-binding driver EXISTS for `resources/read` — `../resource-read-conformance`
|
|
40
|
+
*
|
|
41
|
+
* This catalog used to declare the MCP-binding driver as missing. It is
|
|
42
|
+
* no longer missing. `../resource-read-conformance` ships a driver
|
|
43
|
+
* bound to the MCP **`resources/read`** method, with its own case
|
|
44
|
+
* shape, its own runner (`runResourceReadConformance`) and its own
|
|
45
|
+
* scenario-driver seam. It grades the typed-failure contract for a
|
|
46
|
+
* render locator (`ui://ggui/render/{sessionId}[/{blueprintKey}]`): the
|
|
47
|
+
* four failure classes on their canonical numbers, the constant
|
|
48
|
+
* `NOT_FOUND` body, the deny-equals-miss byte-identity obligation, and
|
|
49
|
+
* the invariant that any successful result declares a delivery channel.
|
|
50
|
+
*
|
|
51
|
+
* Its cases are NOT registered in the map below, and that is
|
|
52
|
+
* deliberate. Every entry here is driven by `runConformance()` over a
|
|
53
|
+
* live channel, so an MCP case landing in this catalog would be a
|
|
54
|
+
* permanent skip on every WebSocket run — a skip that can never become
|
|
55
|
+
* a pass on that transport, which is exactly the false gate this kit's
|
|
56
|
+
* exact skip-set pinning exists to prevent.
|
|
57
|
+
*
|
|
58
|
+
* ### Precisely what that driver does NOT close
|
|
59
|
+
*
|
|
60
|
+
* It binds ONE MCP method. `tools/call` has no driver, so both of these
|
|
61
|
+
* remain open and neither is addressed by it:
|
|
62
|
+
*
|
|
63
|
+
* - **`stream-delivery-roundtrip`** — see the next section. Needs
|
|
64
|
+
* `ggui_emit`.
|
|
65
|
+
* - **The `ggui_consume` retrieval half of the action loop** —
|
|
66
|
+
* `action-ack-sequence` proves the append half; draining the buffer
|
|
67
|
+
* is `ggui_consume`.
|
|
68
|
+
*
|
|
69
|
+
* `resources/read` and `tools/call` are different methods with
|
|
70
|
+
* different seams: the former is a stateless read of a URI the kit can
|
|
71
|
+
* construct, the latter is an invocation whose arguments and effects
|
|
72
|
+
* are the agent's vocabulary. A driver for one is not a driver for the
|
|
73
|
+
* other, and saying "the kit now has an MCP driver" without that
|
|
74
|
+
* qualifier would read as closing gaps it does not touch.
|
|
75
|
+
*
|
|
39
76
|
* ## What is NOT here — declared Path-A sequencing gap
|
|
40
77
|
*
|
|
41
78
|
* A `stream-delivery-roundtrip` fixture (an `emit-envelope`'d payload
|
|
@@ -52,9 +89,10 @@
|
|
|
52
89
|
* transport, while emission is server-side (the agent's `ggui_emit`
|
|
53
90
|
* MCP tool) — routing a host directive through the wire-frame slot
|
|
54
91
|
* would conflate the two vocabularies. Honest grading needs either a
|
|
55
|
-
* post-subscribe host-directive phase (a runner-mechanism change) or
|
|
56
|
-
*
|
|
57
|
-
*
|
|
92
|
+
* post-subscribe host-directive phase (a runner-mechanism change) or a
|
|
93
|
+
* driver bound to `tools/call`. The `resources/read` driver above is
|
|
94
|
+
* NOT that driver. Declared here rather than papered over with a
|
|
95
|
+
* fixture that fails conformant servers on sequencing alone.
|
|
58
96
|
*/
|
|
59
97
|
export { bootstrapProtocolFixtures } from './bootstrap-protocol/index.js';
|
|
60
98
|
export { consumeBufferFixtures } from './consume-buffer/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/reserved-channel-authority/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fixtures/reserved-channel-authority/index.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,qEAAqE;AACrE,eAAO,MAAM,gCAAgC,EAAE,SAAS,QAAQ,EAE/D,CAAC"}
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
* are Server→Client only). Agent emission enters through the
|
|
22
22
|
* `ggui_emit` MCP tool, so both the violation and the rejection that
|
|
23
23
|
* grades it are observable only on the MCP binding. That fixture
|
|
24
|
-
* belongs to a future
|
|
25
|
-
*
|
|
24
|
+
* belongs to a future driver bound to `tools/call` — the kit's
|
|
25
|
+
* `resources/read` driver (`../../resource-read-conformance`) binds a
|
|
26
|
+
* different method and does not reach `ggui_emit`. The gap is declared
|
|
27
|
+
* here rather than faked with a frame the wire cannot carry.
|
|
26
28
|
*/
|
|
27
29
|
import propsUpdateRoundtrip from './props-update-roundtrip.json' with { type: 'json' };
|
|
28
30
|
/** All fixtures asserting reserved-channel authority (SPEC §4.4). */
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export { gadgetRegistrationCases, runRegistrationConformance, } from './registra
|
|
|
20
20
|
export type { GadgetGateRejectCode, GateOutcome, RegistrationConformanceCase, RegistrationConformanceMismatch, RegistrationConformanceResult, } from './registration-conformance/index.js';
|
|
21
21
|
export { gadgetResolutionCases, runResolutionConformance, } from './resolution-conformance/index.js';
|
|
22
22
|
export type { GadgetUrlEntry, ResolvedGadgetUrls, ResolutionConformanceCase, ResolutionConformanceMismatch, ResolutionConformanceResult, } from './resolution-conformance/index.js';
|
|
23
|
+
export { bindingFilterCases, bindingResolutionCases, runBindingFilterCases, runBindingResolutionCases, } from './binding-conformance/index.js';
|
|
24
|
+
export type { BindingFilterCase, BindingFilterMismatch, BindingFilterResult, BindingManifestEntry, BindingRejectCode, BindingResolutionCase, BindingResolutionMismatch, BindingResolutionOutcome, BindingResolutionResult, McpToolBindingDecl, McpToolFilterDecl, } from './binding-conformance/index.js';
|
|
25
|
+
export { declaresDeliveryChannel, renderLocatorUri, resourceReadCases, runResourceReadConformance, GGUI_RENDER_RESOURCE_URI, } from './resource-read-conformance/index.js';
|
|
26
|
+
export type { DurableSubstrateWiring, JsonRpcErrorFrame, PreparedResourceReadScenario, ResourceReadCaller, ResourceReadConformanceCase, ResourceReadConformanceFailure, ResourceReadConformanceResult, ResourceReadConformanceSkip, ResourceReadErrorCodeDecl, ResourceReadExpectation, ResourceReadKey, ResourceReadLocator, ResourceReadOutcome, ResourceReadProbe, ResourceReadRenderMeta, ResourceReadScenario, ResourceReadScenarioDriver, ResourceReadSeed, ResourceReadServerShape, RunResourceReadConformanceOptions, } from './resource-read-conformance/index.js';
|
|
23
27
|
export { loadFixture, listFixtures, loadAllFixtures } from './loader.js';
|
|
24
28
|
export { runConformance } from './run-conformance.js';
|
|
25
29
|
export type { RunConformanceConfig, ConformanceResult, ConformanceFailure, SkippedFixture, ConformanceReporter, InputEnvelopeDispatch, HostContextObservedInputEnvelope, } from './run-conformance.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,EACR,qBAAqB,EAErB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,EAChC,gBAAgB,EAEhB,YAAY,EAEZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EAEf,aAAa,EACb,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAMpB,YAAY,EACV,eAAe,EAEf,SAAS,IAAI,aAAa,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,iBAAiB,EAEjB,YAAY,IAAI,gBAAgB,GACjC,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,gCAAgC,EAChC,8BAA8B,EAC9B,wBAAwB,GACzB,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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,18 @@ export { gadgetRegistrationCases, runRegistrationConformance, } from './registra
|
|
|
30
30
|
// compute for a gadget descriptor's transport fields (`bundleHost`
|
|
31
31
|
// precedence, default host, loopback scheme).
|
|
32
32
|
export { gadgetResolutionCases, runResolutionConformance, } from './resolution-conformance/index.js';
|
|
33
|
+
// Binding-conformance — MCP tool-binding resolution (declared wins,
|
|
34
|
+
// contract-lineage derivation, schema-invalid rejects) + the search
|
|
35
|
+
// filter semantics (`tool=` / `server=` case-sensitive exact,
|
|
36
|
+
// AND-composed per entry).
|
|
37
|
+
export { bindingFilterCases, bindingResolutionCases, runBindingFilterCases, runBindingResolutionCases, } from './binding-conformance/index.js';
|
|
38
|
+
// Resource-read conformance — the kit's first MCP-binding driver, and
|
|
39
|
+
// it binds `resources/read` ONLY (`tools/call` has none). A read of a
|
|
40
|
+
// render locator has exactly two exits: a result whose contents
|
|
41
|
+
// declare a delivery channel, or one typed JSON-RPC error.
|
|
42
|
+
// Unlike the three catalogs above this one drives a live server, so
|
|
43
|
+
// the caller supplies a scenario driver rather than a pure function.
|
|
44
|
+
export { declaresDeliveryChannel, renderLocatorUri, resourceReadCases, runResourceReadConformance, GGUI_RENDER_RESOURCE_URI, } from './resource-read-conformance/index.js';
|
|
33
45
|
// Runtime loader — look up a fixture by name from the inlined catalog.
|
|
34
46
|
export { loadFixture, listFixtures, loadAllFixtures } from './loader.js';
|
|
35
47
|
// Runner — drive the catalog against a live implementation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-behavior.d.ts","sourceRoot":"","sources":["../src/match-behavior.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"match-behavior.d.ts","sourceRoot":"","sources":["../src/match-behavior.ts"],"names":[],"mappings":"AA+FA,OAAO,KAAK,EAIV,gBAAgB,EAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,gBAAgB,CAAC,MAAM,CAAC,EAC3D,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,CAAC,GACN,QAAQ,IAAI,OAAO,CAAC,gBAAgB,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAE7D;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,WAAW,CAkDb;AAgRD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAgBzD"}
|
package/dist/match-behavior.js
CHANGED
|
@@ -84,8 +84,10 @@
|
|
|
84
84
|
* `action-ack` proves the append half of the consume-buffer contract.
|
|
85
85
|
* The retrieval half — the agent draining the buffer via
|
|
86
86
|
* `ggui_consume({sessionId})` — is an MCP tool call a WS-only runner
|
|
87
|
-
* cannot drive. Grading it needs
|
|
88
|
-
*
|
|
87
|
+
* cannot drive. Grading it needs a driver bound to `tools/call`. The
|
|
88
|
+
* kit's `resources/read` driver (`../resource-read-conformance`) does
|
|
89
|
+
* NOT reach it: different method, different seam. That gap is declared
|
|
90
|
+
* here rather than papered over with a weaker assertion.
|
|
89
91
|
*/
|
|
90
92
|
import { PROTOCOL_SCHEMA_VERSION } from '@ggui-ai/protocol';
|
|
91
93
|
import { isRecord } from '@ggui-ai/protocol';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resolve-bundle-host-computed",
|
|
3
|
-
"description": "A descriptor with a hostname-only `bundleHost` (no scheme, no path) and no explicit `bundleUrl`. The resolver MUST compute both the bundle and style URLs as `https://<bundleHost>/bundles/<package>/<version>/<file>` — the
|
|
3
|
+
"description": "A descriptor with a hostname-only `bundleHost` (no scheme, no path) and no explicit `bundleUrl`. The resolver MUST compute both the bundle and style URLs as `https://<bundleHost>/bundles/public/<package>/<version>/<file>` — the PUBLIC prefix of `@ggui-ai/registry-core`'s visibility-split `BundleStorage` layout (H1). bundleHost-tier composition is anonymous render-time fetching, which only the public prefix serves; private artifacts reach the iframe via an explicit presigned `bundleUrl`, never via host composition. Keeping the shapes aligned means a bundle published to one registry resolves cleanly from the other.",
|
|
4
4
|
"entry": {
|
|
5
5
|
"package": "@acme/leaflet-wrapper",
|
|
6
6
|
"version": "2.3.1",
|
|
7
7
|
"bundleHost": "cdn.example.com"
|
|
8
8
|
},
|
|
9
9
|
"expect": {
|
|
10
|
-
"bundleUrl": "https://cdn.example.com/bundles/@acme/leaflet-wrapper/2.3.1/bundle.js",
|
|
11
|
-
"styleUrl": "https://cdn.example.com/bundles/@acme/leaflet-wrapper/2.3.1/style.css"
|
|
10
|
+
"bundleUrl": "https://cdn.example.com/bundles/public/@acme/leaflet-wrapper/2.3.1/bundle.js",
|
|
11
|
+
"styleUrl": "https://cdn.example.com/bundles/public/@acme/leaflet-wrapper/2.3.1/style.css"
|
|
12
12
|
}
|
|
13
13
|
}
|