@ggui-ai/protocol 0.2.0-alpha.3 → 0.3.0-rc.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 +16 -16
- package/dist/envelope-adapters.d.ts +6 -5
- package/dist/envelope-adapters.d.ts.map +1 -1
- package/dist/envelope-adapters.js +3 -3
- package/dist/envelopes/builders.d.ts +6 -32
- package/dist/envelopes/builders.d.ts.map +1 -1
- package/dist/envelopes/builders.js +3 -25
- package/dist/errors/version-mismatch.d.ts +1 -1
- package/dist/errors/version-mismatch.js +1 -1
- package/dist/gadgets/resolve-app-gadgets.d.ts +10 -0
- package/dist/gadgets/resolve-app-gadgets.d.ts.map +1 -0
- package/dist/gadgets/resolve-app-gadgets.js +19 -0
- package/dist/gadgets/resolve-contract-gadgets.d.ts +6 -6
- package/dist/gadgets/resolve-contract-gadgets.js +5 -5
- package/dist/gadgets/stdlib-gadgets.d.ts +1 -1
- package/dist/gadgets/stdlib-gadgets.d.ts.map +1 -1
- package/dist/gadgets/stdlib-gadgets.js +43 -22
- package/dist/iframe-bridge.d.ts +4 -43
- package/dist/iframe-bridge.d.ts.map +1 -1
- package/dist/iframe-bridge.js +4 -141
- package/dist/index.d.ts +60 -62
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -61
- package/dist/integrations/mcp-apps.d.ts +83 -38
- package/dist/integrations/mcp-apps.d.ts.map +1 -1
- package/dist/integrations/mcp-apps.js +98 -52
- package/dist/recommended-prompts.d.ts +1 -1
- package/dist/recommended-prompts.js +1 -1
- package/dist/registry/blueprint-key.d.ts +3 -0
- package/dist/registry/blueprint-key.d.ts.map +1 -1
- package/dist/registry/blueprint-key.js +9 -0
- package/dist/registry/blueprint-stamp.d.ts +12 -0
- package/dist/registry/blueprint-stamp.d.ts.map +1 -0
- package/dist/registry/blueprint-stamp.js +12 -0
- package/dist/registry/canonicalize-contract.d.ts +31 -2
- package/dist/registry/canonicalize-contract.d.ts.map +1 -1
- package/dist/registry/canonicalize-contract.js +125 -13
- package/dist/registry/portable-blueprint.d.ts +64 -0
- package/dist/registry/portable-blueprint.d.ts.map +1 -0
- package/dist/registry/portable-blueprint.js +103 -0
- package/dist/registry/summarize-contract.d.ts +7 -2
- package/dist/registry/summarize-contract.d.ts.map +1 -1
- package/dist/registry/summarize-contract.js +12 -3
- package/dist/registry/variant-key.d.ts +17 -0
- package/dist/registry/variant-key.d.ts.map +1 -0
- package/dist/registry/variant-key.js +22 -0
- package/dist/schema-learning/derive-contract.d.ts +2 -2
- package/dist/schema-learning/derive-contract.js +2 -2
- package/dist/schema-learning/merge.d.ts.map +1 -1
- package/dist/schema-learning/merge.js +3 -2
- package/dist/schemas/app-theme.d.ts +38 -0
- package/dist/schemas/app-theme.d.ts.map +1 -0
- package/dist/schemas/app-theme.js +43 -0
- package/dist/schemas/blueprint.d.ts +30 -11
- package/dist/schemas/blueprint.d.ts.map +1 -1
- package/dist/schemas/blueprint.js +62 -26
- package/dist/schemas/data-contract.d.ts +28 -30
- package/dist/schemas/data-contract.d.ts.map +1 -1
- package/dist/schemas/data-contract.js +26 -26
- package/dist/schemas/handshake-suggestion.d.ts +2 -4
- package/dist/schemas/handshake-suggestion.d.ts.map +1 -1
- package/dist/schemas/handshake-suggestion.js +5 -14
- package/dist/schemas/mcp.d.ts +240 -58
- package/dist/schemas/mcp.d.ts.map +1 -1
- package/dist/schemas/mcp.js +285 -93
- package/dist/schemas/ops-blueprint.d.ts +12 -12
- package/dist/schemas/ops-blueprint.d.ts.map +1 -1
- package/dist/schemas/ops-blueprint.js +14 -24
- package/dist/screen-blueprints/define.d.ts +2 -2
- package/dist/screen-blueprints/match.d.ts +12 -7
- package/dist/screen-blueprints/match.d.ts.map +1 -1
- package/dist/screen-blueprints/match.js +7 -5
- package/dist/screen-blueprints/types.d.ts +14 -18
- package/dist/screen-blueprints/types.d.ts.map +1 -1
- package/dist/transport/websocket.d.ts +5 -26
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/types/app-config.d.ts +0 -1
- package/dist/types/app-config.d.ts.map +1 -1
- package/dist/types/auth.d.ts +1 -46
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/blueprint-source.d.ts +123 -0
- package/dist/types/blueprint-source.d.ts.map +1 -0
- package/dist/types/blueprint-source.js +126 -0
- package/dist/types/blueprint.d.ts +25 -18
- package/dist/types/blueprint.d.ts.map +1 -1
- package/dist/types/contract-inference.d.ts +2 -43
- package/dist/types/contract-inference.d.ts.map +1 -1
- package/dist/types/data-contract.d.ts +59 -344
- package/dist/types/data-contract.d.ts.map +1 -1
- package/dist/types/data-contract.js +5 -12
- package/dist/types/events.d.ts +31 -69
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/{render-event.d.ts → ggui-session-event.d.ts} +15 -15
- package/dist/types/ggui-session-event.d.ts.map +1 -0
- package/dist/types/{render-event.js → ggui-session-event.js} +5 -5
- package/dist/types/handshake-suggestion.d.ts +60 -40
- package/dist/types/handshake-suggestion.d.ts.map +1 -1
- package/dist/types/host-context.d.ts +8 -8
- package/dist/types/host-context.d.ts.map +1 -1
- package/dist/types/host-context.js +5 -5
- package/dist/types/invoke.d.ts +1 -13
- package/dist/types/invoke.d.ts.map +1 -1
- package/dist/types/{canvas-lifecycle.d.ts → lifecycle.d.ts} +35 -37
- package/dist/types/lifecycle.d.ts.map +1 -0
- package/dist/types/{canvas-lifecycle.js → lifecycle.js} +12 -14
- package/dist/types/live-channel.d.ts +48 -104
- package/dist/types/live-channel.d.ts.map +1 -1
- package/dist/types/llm.d.ts +13 -24
- package/dist/types/llm.d.ts.map +1 -1
- package/dist/types/llm.js +23 -53
- package/dist/types/mcp.d.ts +55 -176
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/mcp.js +2 -2
- package/dist/types/oauth-user-id.d.ts +12 -0
- package/dist/types/oauth-user-id.d.ts.map +1 -0
- package/dist/types/oauth-user-id.js +10 -0
- package/dist/types/portable-blueprint.d.ts +53 -0
- package/dist/types/portable-blueprint.d.ts.map +1 -0
- package/dist/types/portable-blueprint.js +8 -0
- package/dist/types/{session.d.ts → render.d.ts} +51 -53
- package/dist/types/render.d.ts.map +1 -0
- package/dist/types/thread.d.ts.map +1 -1
- package/dist/types/thread.js +3 -3
- package/dist/types/ui-generator.d.ts +5 -46
- package/dist/types/ui-generator.d.ts.map +1 -1
- package/dist/types/ui-generator.js +1 -53
- package/dist/validation/ajv-runtime.d.ts +3 -3
- package/dist/validation/ajv-runtime.d.ts.map +1 -1
- package/dist/validation/ajv-runtime.js +6 -5
- package/dist/validation/contract-validator.d.ts +23 -22
- package/dist/validation/contract-validator.d.ts.map +1 -1
- package/dist/validation/contract-validator.js +28 -26
- package/dist/validation/cross-references.d.ts +3 -3
- package/dist/validation/cross-references.js +3 -3
- package/dist/validation/hygiene-rules.d.ts +13 -10
- package/dist/validation/hygiene-rules.d.ts.map +1 -1
- package/dist/validation/hygiene-rules.js +20 -14
- package/dist/validation/is-record.d.ts +17 -0
- package/dist/validation/is-record.d.ts.map +1 -0
- package/dist/validation/is-record.js +18 -0
- package/dist/validation/lint-contract.d.ts +9 -8
- package/dist/validation/lint-contract.d.ts.map +1 -1
- package/dist/validation/lint-contract.js +89 -26
- package/dist/validation/name-invariants.d.ts +4 -4
- package/dist/validation/name-invariants.js +4 -4
- package/dist/validation/reserved-channels.d.ts +43 -46
- package/dist/validation/reserved-channels.d.ts.map +1 -1
- package/dist/validation/reserved-channels.js +14 -177
- package/dist/validation/resolve-stream-channel.d.ts +3 -9
- package/dist/validation/resolve-stream-channel.d.ts.map +1 -1
- package/dist/validation/resolve-stream-channel.js +3 -4
- package/dist/validation/sanitize-error.d.ts +10 -9
- package/dist/validation/sanitize-error.d.ts.map +1 -1
- package/dist/validation/sanitize-error.js +19 -18
- package/dist/validation/schema-compat-invariants.d.ts +1 -1
- package/dist/validation/schema-compat-invariants.js +3 -3
- package/dist/validation/schema-meta-validation.d.ts +21 -8
- package/dist/validation/schema-meta-validation.d.ts.map +1 -1
- package/dist/validation/schema-meta-validation.js +28 -14
- package/dist/validation/schema-subset.d.ts +9 -8
- package/dist/validation/schema-subset.d.ts.map +1 -1
- package/dist/validation/ui-security.d.ts +0 -17
- package/dist/validation/ui-security.d.ts.map +1 -1
- package/dist/validation/ui-security.js +17 -22
- package/dist/validation/zod-to-json-schema.d.ts +1 -1
- package/dist/validation/zod-to-json-schema.d.ts.map +1 -1
- package/dist/validation/zod-to-json-schema.js +4 -3
- package/dist/version.d.ts +783 -9
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +782 -8
- package/package.json +2 -2
- package/dist/bridge/invoke-agent.d.ts +0 -65
- package/dist/bridge/invoke-agent.d.ts.map +0 -1
- package/dist/bridge/invoke-agent.js +0 -113
- package/dist/stream/stream-parser.d.ts +0 -62
- package/dist/stream/stream-parser.d.ts.map +0 -1
- package/dist/stream/stream-parser.js +0 -199
- package/dist/types/canvas-lifecycle.d.ts.map +0 -1
- package/dist/types/credential.d.ts +0 -41
- package/dist/types/credential.d.ts.map +0 -1
- package/dist/types/credential.js +0 -32
- package/dist/types/data-bindings.d.ts +0 -322
- package/dist/types/data-bindings.d.ts.map +0 -1
- package/dist/types/data-bindings.js +0 -29
- package/dist/types/feedback.d.ts +0 -22
- package/dist/types/feedback.d.ts.map +0 -1
- package/dist/types/feedback.js +0 -7
- package/dist/types/mcp-proxy.d.ts +0 -67
- package/dist/types/mcp-proxy.d.ts.map +0 -1
- package/dist/types/mcp-proxy.js +0 -46
- package/dist/types/openrouter-models.d.ts +0 -23
- package/dist/types/openrouter-models.d.ts.map +0 -1
- package/dist/types/openrouter-models.js +0 -4843
- package/dist/types/region.d.ts +0 -26
- package/dist/types/region.d.ts.map +0 -1
- package/dist/types/region.js +0 -36
- package/dist/types/render-event.d.ts.map +0 -1
- package/dist/types/session.d.ts.map +0 -1
- /package/dist/types/{session.js → render.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-validator.d.ts","sourceRoot":"","sources":["../../src/validation/contract-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEnI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAO3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"contract-validator.d.ts","sourceRoot":"","sources":["../../src/validation/contract-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { deriveContextDefault } from '../types/data-contract.js';
|
|
|
2
2
|
import { compileForValidation, compileValidatorModule, mapAjvErrorsToViolations, prefixViolations, } from './ajv-runtime.js';
|
|
3
3
|
import { checkCrossReferences } from './cross-references.js';
|
|
4
4
|
import { checkNameInvariants } from './name-invariants.js';
|
|
5
|
+
import { isRecord } from './is-record.js';
|
|
5
6
|
import { checkSchemaCompat } from './schema-compat-invariants.js';
|
|
6
7
|
import { BUILTIN_RESERVED_VALIDATORS, RESERVED_CHANNEL_PREFIX, isKnownReservedChannel, isReservedChannelName, } from './reserved-channels.js';
|
|
7
8
|
/**
|
|
@@ -14,7 +15,7 @@ import { BUILTIN_RESERVED_VALIDATORS, RESERVED_CHANNEL_PREFIX, isKnownReservedCh
|
|
|
14
15
|
* pre-injection wrapper.
|
|
15
16
|
*
|
|
16
17
|
* Shared by {@link validatePropsData} (server-side runtime check) and
|
|
17
|
-
* {@link compileContractValidators} (
|
|
18
|
+
* {@link compileContractValidators} (render-time standalone emission) so
|
|
18
19
|
* the precompiled in-iframe validator enforces byte-identical
|
|
19
20
|
* semantics to the runtime validator — one synthesis, no drift.
|
|
20
21
|
*/
|
|
@@ -44,7 +45,7 @@ export function buildPropsWrapperSchema(spec) {
|
|
|
44
45
|
*
|
|
45
46
|
* Load-bearing for `ggui_update kind:'merge'` (RFC 7396): a patch
|
|
46
47
|
* adding a key absent from `propsSpec.properties` would silently
|
|
47
|
-
* land on the
|
|
48
|
+
* land on the render without this gate. Same rule applies to
|
|
48
49
|
* the `done`-vs-declared-`completed` class of bug inside array
|
|
49
50
|
* items — Ajv rejects with the exact path (`todos[0].done`).
|
|
50
51
|
*/
|
|
@@ -89,18 +90,18 @@ export function validatePropsData(props, spec, precompiled) {
|
|
|
89
90
|
* validator for `_ggui:preview`. Consulted FIRST so callers can
|
|
90
91
|
* override or extend built-ins.
|
|
91
92
|
* 2. `BUILTIN_RESERVED_VALIDATORS` — protocol-owned, always active.
|
|
92
|
-
* Ships the {@link
|
|
93
|
-
* `_ggui:
|
|
93
|
+
* Ships the {@link validateGguiLifecyclePayload} for
|
|
94
|
+
* `_ggui:lifecycle`.
|
|
94
95
|
* 3. Fall-through: if no validator is registered for the known
|
|
95
96
|
* reserved channel, return `{valid: true}`. Preserves backward
|
|
96
97
|
* compatibility for any future reserved channel the runtime
|
|
97
98
|
* adds before its validator is authored.
|
|
98
99
|
*
|
|
99
|
-
* Without this structure, a `_ggui:preview` emission into a
|
|
100
|
-
* whose active
|
|
100
|
+
* Without this structure, a `_ggui:preview` emission into a render
|
|
101
|
+
* whose active render carries ANY user streamSpec would
|
|
101
102
|
* synthesize a false "Unknown channel" violation, blocking the
|
|
102
103
|
* provisional preview runtime. Symmetric with the client-side
|
|
103
|
-
* handling in `
|
|
104
|
+
* handling in `GguiRender`.
|
|
104
105
|
*
|
|
105
106
|
* Crucially narrow by design — the known-reserved path is a CLOSED
|
|
106
107
|
* SET, not a prefix check. A typo inside the reserved namespace
|
|
@@ -190,7 +191,7 @@ export function validateContextData(slotName, value, spec, precompiledSlots) {
|
|
|
190
191
|
return { valid: violations.length === 0, violations };
|
|
191
192
|
}
|
|
192
193
|
/**
|
|
193
|
-
* Validate an inbound user-action payload against the
|
|
194
|
+
* Validate an inbound user-action payload against the render's ActionSpec.
|
|
194
195
|
*
|
|
195
196
|
* Symmetric with {@link validatePropsData} / {@link validateStreamData}, but for
|
|
196
197
|
* live-channel INBOUND user → core traffic. Enforces the action contract at the
|
|
@@ -212,7 +213,7 @@ export function validateContextData(slotName, value, spec, precompiledSlots) {
|
|
|
212
213
|
*/
|
|
213
214
|
export function validateActionData(value, spec, precompiledActions) {
|
|
214
215
|
const violations = [];
|
|
215
|
-
if (
|
|
216
|
+
if (!isRecord(value)) {
|
|
216
217
|
violations.push({
|
|
217
218
|
field: 'value',
|
|
218
219
|
message: 'Action payload must be an object with an `action` field',
|
|
@@ -261,24 +262,25 @@ function getJsonType(value) {
|
|
|
261
262
|
return typeof value;
|
|
262
263
|
}
|
|
263
264
|
/**
|
|
264
|
-
* Validate an inbound {@link ActionEnvelope} against the target
|
|
265
|
-
*
|
|
266
|
-
* inbound enforcement — the
|
|
267
|
-
*
|
|
268
|
-
*
|
|
265
|
+
* Validate an inbound {@link ActionEnvelope} against the target
|
|
266
|
+
* render's {@link ActionSpec}. Payload-contract layer of live-channel
|
|
267
|
+
* inbound enforcement — the ONLY gate on inbound actions today (the
|
|
268
|
+
* pre-Phase-B `subscription.events` allowlist gate was deleted with
|
|
269
|
+
* the session-stack collapse).
|
|
269
270
|
*
|
|
270
271
|
* Semantics:
|
|
271
272
|
* - `envelope.type !== 'data:submit'` → `{valid: true, violations: []}`.
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
273
|
+
* {@link EventType} has exactly one member, so a TYPED caller never
|
|
274
|
+
* hits this branch — it is a wire-trust guard: a rogue client's
|
|
275
|
+
* envelope claiming an unknown type string is ledger-only upstream
|
|
276
|
+
* and gets no payload enforcement on this layer.
|
|
277
|
+
* - `spec === undefined` → `{valid: true, violations: []}`. Renders
|
|
278
|
+
* without an actionSpec have no contract; legacy renders keep
|
|
277
279
|
* flowing.
|
|
278
280
|
* - Otherwise `envelope.payload` is validated against `spec` via
|
|
279
281
|
* {@link validateActionData}. Same rules, same output shape.
|
|
280
282
|
*
|
|
281
|
-
* This helper does NOT enforce allowlist,
|
|
283
|
+
* This helper does NOT enforce allowlist, render binding, or render
|
|
282
284
|
* routing — those are ingress-plumbing concerns. Pure payload-shape
|
|
283
285
|
* check; returns `ValidationResult` rather than throwing so callers
|
|
284
286
|
* can decide whether to surface as a wire error, log, etc.
|
|
@@ -298,7 +300,7 @@ export function validateActionEnvelope(envelope, spec, precompiledActions) {
|
|
|
298
300
|
*
|
|
299
301
|
* The renderer iframe runs under a strict CSP with no `'unsafe-eval'`,
|
|
300
302
|
* so it cannot call `ajv.compile()` (which builds validators via
|
|
301
|
-
* `new Function`). Compilation therefore happens server-side at
|
|
303
|
+
* `new Function`). Compilation therefore happens server-side at render
|
|
302
304
|
* time — where the contract schema is fixed and codegen is legal — and
|
|
303
305
|
* the iframe loads each emitted module via a `blob:` dynamic import.
|
|
304
306
|
*
|
|
@@ -369,7 +371,7 @@ export function compileContractValidators(specs) {
|
|
|
369
371
|
* + Node — the producer's iteration order is preserved, so a given
|
|
370
372
|
* contract always serializes to identical bytes. {@link computeContractBundle}
|
|
371
373
|
* leans on that determinism so the resulting hash is stable across
|
|
372
|
-
*
|
|
374
|
+
* renders of the same contract.
|
|
373
375
|
*
|
|
374
376
|
* @public
|
|
375
377
|
*/
|
|
@@ -399,7 +401,7 @@ function canonicalJsonStringify(value) {
|
|
|
399
401
|
if (Array.isArray(value)) {
|
|
400
402
|
return `[${value.map(canonicalJsonStringify).join(',')}]`;
|
|
401
403
|
}
|
|
402
|
-
if (
|
|
404
|
+
if (isRecord(value)) {
|
|
403
405
|
const keys = Object.keys(value).sort();
|
|
404
406
|
const parts = keys.map((k) => `${JSON.stringify(k)}:${canonicalJsonStringify(value[k])}`);
|
|
405
407
|
return `{${parts.join(',')}}`;
|
|
@@ -410,7 +412,7 @@ function canonicalJsonStringify(value) {
|
|
|
410
412
|
/**
|
|
411
413
|
* Convenience over {@link compileContractValidators} +
|
|
412
414
|
* {@link bundleCompiledValidatorsAsModule} + sha256 — produces the
|
|
413
|
-
* `{contractHash, bundleSource, validators}` triple the emitter (
|
|
415
|
+
* `{contractHash, bundleSource, validators}` triple the emitter (render.ts
|
|
414
416
|
* / update.ts in #109 C4) writes to the content-addressable store and
|
|
415
417
|
* emits as `_meta["ai.ggui/contract"] = {contractHash, validatorsUrl}`.
|
|
416
418
|
*
|
|
@@ -573,7 +575,7 @@ export function validateContractStructure(contract) {
|
|
|
573
575
|
* Slot-key identifier check for contextSpec. Slot keys are surfaced
|
|
574
576
|
* as React Context names by the boilerplate generator (`currentStep`
|
|
575
577
|
* → `CurrentStepContext`); a non-identifier here would break the
|
|
576
|
-
* generation step at runtime, so we reject at
|
|
578
|
+
* generation step at runtime, so we reject at render-time instead.
|
|
577
579
|
*/
|
|
578
580
|
const CONTEXT_SLOT_KEY_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
579
581
|
/**
|
|
@@ -582,7 +584,7 @@ const CONTEXT_SLOT_KEY_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
|
582
584
|
* context map (e.g., `obj['__proto__'] = …` in pre-frozen
|
|
583
585
|
* environments would mutate the prototype chain rather than set a
|
|
584
586
|
* slot). Defensive — the runtime uses a frozen spec lookup, but the
|
|
585
|
-
*
|
|
587
|
+
* render-time gate keeps the invariant load-bearing for any future
|
|
586
588
|
* implementation that materializes the spec into a plain object.
|
|
587
589
|
*/
|
|
588
590
|
const CONTEXT_RESERVED_KEYS = new Set([
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* own `agentCapabilities.tools` catalog — same-MCP and cross-MCP both
|
|
14
14
|
* funnel through this single resolution path (the catalog is the
|
|
15
15
|
* declarative source of truth for every referenced tool). Violations
|
|
16
|
-
* are author-recoverable at
|
|
16
|
+
* are author-recoverable at render time.
|
|
17
17
|
*/
|
|
18
18
|
import type { DataContract, ActionSpec, StreamSpec, AgentCapabilitiesSpec } from '../types/data-contract';
|
|
19
19
|
import type { ContractViolation } from './contract-validator';
|
|
@@ -83,7 +83,7 @@ export declare function checkCrossReferences(contract: DataContract): CrossRefer
|
|
|
83
83
|
/**
|
|
84
84
|
* Throwable form of {@link checkCrossReferences}. Use at protocol
|
|
85
85
|
* boundaries where an unresolved cross-reference is a contract bug
|
|
86
|
-
* the caller must fix (
|
|
86
|
+
* the caller must fix (render handler, blueprint registration).
|
|
87
87
|
*
|
|
88
88
|
* Carries the full violation list so error renderers can show every
|
|
89
89
|
* dangling reference in one pass instead of fix-and-retry per-field.
|
|
@@ -97,7 +97,7 @@ export declare class CrossReferenceError extends Error {
|
|
|
97
97
|
* Throw-on-violation wrapper around {@link checkCrossReferences}.
|
|
98
98
|
* No-op when the contract is internally consistent.
|
|
99
99
|
*
|
|
100
|
-
* Invoked at handshake AND
|
|
100
|
+
* Invoked at handshake AND render time: contract-internal mistakes
|
|
101
101
|
* surface at the earliest possible boundary so the agent can fix and
|
|
102
102
|
* retry on the SAME handshakeId.
|
|
103
103
|
*/
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* own `agentCapabilities.tools` catalog — same-MCP and cross-MCP both
|
|
14
14
|
* funnel through this single resolution path (the catalog is the
|
|
15
15
|
* declarative source of truth for every referenced tool). Violations
|
|
16
|
-
* are author-recoverable at
|
|
16
|
+
* are author-recoverable at render time.
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
19
|
* Stable error code emitted when an `actionSpec[*].nextStep` value
|
|
@@ -131,7 +131,7 @@ export function checkCrossReferences(contract) {
|
|
|
131
131
|
/**
|
|
132
132
|
* Throwable form of {@link checkCrossReferences}. Use at protocol
|
|
133
133
|
* boundaries where an unresolved cross-reference is a contract bug
|
|
134
|
-
* the caller must fix (
|
|
134
|
+
* the caller must fix (render handler, blueprint registration).
|
|
135
135
|
*
|
|
136
136
|
* Carries the full violation list so error renderers can show every
|
|
137
137
|
* dangling reference in one pass instead of fix-and-retry per-field.
|
|
@@ -152,7 +152,7 @@ export class CrossReferenceError extends Error {
|
|
|
152
152
|
* Throw-on-violation wrapper around {@link checkCrossReferences}.
|
|
153
153
|
* No-op when the contract is internally consistent.
|
|
154
154
|
*
|
|
155
|
-
* Invoked at handshake AND
|
|
155
|
+
* Invoked at handshake AND render time: contract-internal mistakes
|
|
156
156
|
* surface at the earliest possible boundary so the agent can fix and
|
|
157
157
|
* retry on the SAME handshakeId.
|
|
158
158
|
*/
|
|
@@ -102,7 +102,7 @@ export declare const FATAL_CATALOG_LINT_CODES: ReadonlySet<string>;
|
|
|
102
102
|
* - `broadcast` → `streamSpec[ch].source`
|
|
103
103
|
* - `capabilities` → `agentCapabilities` + `clientCapabilities`
|
|
104
104
|
*
|
|
105
|
-
*
|
|
105
|
+
* Render-gate handlers re-use this list to hard-reject; surfacing it
|
|
106
106
|
* here keeps the wire vocabulary single-sourced.
|
|
107
107
|
*/
|
|
108
108
|
export declare const RETIRED_CONTRACT_FIELDS: Readonly<Record<string, string>>;
|
|
@@ -147,7 +147,7 @@ export declare function checkOrphanAgentTools(contract: DataContract): HygieneWa
|
|
|
147
147
|
* is intentionally NOT linted here: `GadgetExportUse.usage` is an
|
|
148
148
|
* OPTIONAL intent-OVERRIDE, and the SPEC-documented canonical wire
|
|
149
149
|
* form is the bare identity reference `gadgets[<pkg>][<export>] = {}`.
|
|
150
|
-
*
|
|
150
|
+
* Render-time resolution inherits the registered descriptor's `usage`,
|
|
151
151
|
* and the registry-side `lintGadgetCatalog` (via
|
|
152
152
|
* `strictGadgetExportSchema`) already enforces real teaching text at
|
|
153
153
|
* registration time. Flagging an empty wire-side use object would
|
|
@@ -169,7 +169,7 @@ export declare function checkMissingExample(contract: DataContract): HygieneWarn
|
|
|
169
169
|
*
|
|
170
170
|
* Third-party packages (any `package !== DEFAULT_GADGET_PACKAGE`) are
|
|
171
171
|
* NOT checked here — the lint can't know an operator's own hook
|
|
172
|
-
* names. The registry-side {@link lintGadgetCatalog} + the
|
|
172
|
+
* names. The registry-side {@link lintGadgetCatalog} + the render-time
|
|
173
173
|
* {@link assertGadgetsRegistered} gate cover third-party resolution.
|
|
174
174
|
*
|
|
175
175
|
* Permission checks live on the registry-side `lintGadgetCatalog`
|
|
@@ -189,9 +189,9 @@ export declare function checkGadgetHookNames(contract: DataContract): HygieneWar
|
|
|
189
189
|
* imports of the same name — from different packages — produce an
|
|
190
190
|
* unresolvable identifier collision in the generated module scope.
|
|
191
191
|
*
|
|
192
|
-
* Keys on the export name alone, matching the
|
|
192
|
+
* Keys on the export name alone, matching the render-time hard gate
|
|
193
193
|
* `assertNoDuplicateGadgetHooks`. Soft mirror of that gate so
|
|
194
|
-
* authoring tools surface the issue before a
|
|
194
|
+
* authoring tools surface the issue before a render round-trip.
|
|
195
195
|
*/
|
|
196
196
|
export declare function checkDuplicateGadgetHooks(contract: DataContract): HygieneWarning[];
|
|
197
197
|
/**
|
|
@@ -228,21 +228,24 @@ export declare function lintGadgetCatalog(descriptors: readonly GadgetDescriptor
|
|
|
228
228
|
* Find top-level retired-field carriers on the contract. The schema
|
|
229
229
|
* is `.passthrough()`, so a stray `libraries`/`dispatch`/`wiredTools`/
|
|
230
230
|
* `clientTools`/`broadcast`/`capabilities` slips through silently. The
|
|
231
|
-
*
|
|
231
|
+
* render-gate hard-rejects these (see
|
|
232
232
|
* `mcp-server-handlers/.../assert-contract-no-retired-fields.ts`); this
|
|
233
233
|
* lint surface keeps authoring tools symmetric — show the warning before
|
|
234
|
-
* the
|
|
234
|
+
* the render call so the author can fix it without a server round-trip.
|
|
235
235
|
*/
|
|
236
236
|
export declare function checkRetiredContractFields(contract: DataContract): HygieneWarning[];
|
|
237
237
|
/**
|
|
238
238
|
* Run every WIRE-side hygiene rule on a `DataContract`. Aggregates
|
|
239
239
|
* warnings; order is stable (orphans → usage → example → gadget
|
|
240
|
-
* hook-names → duplicate-hook
|
|
241
|
-
*
|
|
240
|
+
* hook-names → duplicate-hook) so authoring tools render a predictable
|
|
241
|
+
* checklist. Retired-field detection is NOT here — it is promoted to an
|
|
242
|
+
* ERROR phase (`phaseRetired` in lint-contract.ts); the detector
|
|
243
|
+
* `checkRetiredContractFields` stays exported for the author-time
|
|
244
|
+
* surface and the render-gate assert.
|
|
242
245
|
*
|
|
243
246
|
* Registry-side gadget lints (`lintGadgetCatalog`) are NOT run here:
|
|
244
247
|
* they need an `App.gadgets` descriptor array, not a contract, and
|
|
245
|
-
* fire at registration time rather than
|
|
248
|
+
* fire at registration time rather than render time.
|
|
246
249
|
* Call {@link lintGadgetCatalog} separately at the registration
|
|
247
250
|
* boundary.
|
|
248
251
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hygiene-rules.d.ts","sourceRoot":"","sources":["../../src/validation/hygiene-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW7E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,uCAAuC,4CACT,CAAC;AAC5C,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAIvD,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3D,CAAC;AAoBX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,0RAoBzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAsB1E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAoCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAkBlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,cAAc,EAAE,CAmB1E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAiBlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAgClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAmBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACvC,cAAc,EAAE,CAoHlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAiBlB;AAED
|
|
1
|
+
{"version":3,"file":"hygiene-rules.d.ts","sourceRoot":"","sources":["../../src/validation/hygiene-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW7E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,uCAAuC,4CACT,CAAC;AAC5C,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAIvD,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3D,CAAC;AAoBX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,0RAoBzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAsB1E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAoCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAkBlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,cAAc,EAAE,CAmB1E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAiBlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAgClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAmBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACvC,cAAc,EAAE,CAoHlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAiBlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CAYlB"}
|
|
@@ -109,7 +109,7 @@ export const FATAL_CATALOG_LINT_CODES = new Set([
|
|
|
109
109
|
* - `broadcast` → `streamSpec[ch].source`
|
|
110
110
|
* - `capabilities` → `agentCapabilities` + `clientCapabilities`
|
|
111
111
|
*
|
|
112
|
-
*
|
|
112
|
+
* Render-gate handlers re-use this list to hard-reject; surfacing it
|
|
113
113
|
* here keeps the wire vocabulary single-sourced.
|
|
114
114
|
*/
|
|
115
115
|
export const RETIRED_CONTRACT_FIELDS = {
|
|
@@ -124,12 +124,12 @@ export const RETIRED_CONTRACT_FIELDS = {
|
|
|
124
124
|
* Sourced from {@link STDLIB_GADGET_HOOKS} — the canonical
|
|
125
125
|
* hook-name set the first-party `@ggui-ai/gadgets` package
|
|
126
126
|
* exports. Local alias keeps existing call sites stable while the
|
|
127
|
-
* source of truth lives in `
|
|
127
|
+
* source of truth lives in `gadgets/stdlib-gadgets.ts`.
|
|
128
128
|
*/
|
|
129
129
|
const KNOWN_STDLIB_HOOKS = STDLIB_GADGET_HOOKS;
|
|
130
130
|
/**
|
|
131
131
|
* Default package for gadget hooks. Sourced from the
|
|
132
|
-
* stdlib-
|
|
132
|
+
* stdlib-gadgets registry — when an entry's `package` is omitted,
|
|
133
133
|
* the hygiene linter assumes it resolves to the first-party
|
|
134
134
|
* `@ggui-ai/gadgets` package and runs hook-registry +
|
|
135
135
|
* permission checks against the stdlib catalog. Third-party packages
|
|
@@ -248,7 +248,7 @@ export function checkOrphanAgentTools(contract) {
|
|
|
248
248
|
* is intentionally NOT linted here: `GadgetExportUse.usage` is an
|
|
249
249
|
* OPTIONAL intent-OVERRIDE, and the SPEC-documented canonical wire
|
|
250
250
|
* form is the bare identity reference `gadgets[<pkg>][<export>] = {}`.
|
|
251
|
-
*
|
|
251
|
+
* Render-time resolution inherits the registered descriptor's `usage`,
|
|
252
252
|
* and the registry-side `lintGadgetCatalog` (via
|
|
253
253
|
* `strictGadgetExportSchema`) already enforces real teaching text at
|
|
254
254
|
* registration time. Flagging an empty wire-side use object would
|
|
@@ -307,7 +307,7 @@ export function checkMissingExample(contract) {
|
|
|
307
307
|
*
|
|
308
308
|
* Third-party packages (any `package !== DEFAULT_GADGET_PACKAGE`) are
|
|
309
309
|
* NOT checked here — the lint can't know an operator's own hook
|
|
310
|
-
* names. The registry-side {@link lintGadgetCatalog} + the
|
|
310
|
+
* names. The registry-side {@link lintGadgetCatalog} + the render-time
|
|
311
311
|
* {@link assertGadgetsRegistered} gate cover third-party resolution.
|
|
312
312
|
*
|
|
313
313
|
* Permission checks live on the registry-side `lintGadgetCatalog`
|
|
@@ -357,9 +357,9 @@ export function checkGadgetHookNames(contract) {
|
|
|
357
357
|
* imports of the same name — from different packages — produce an
|
|
358
358
|
* unresolvable identifier collision in the generated module scope.
|
|
359
359
|
*
|
|
360
|
-
* Keys on the export name alone, matching the
|
|
360
|
+
* Keys on the export name alone, matching the render-time hard gate
|
|
361
361
|
* `assertNoDuplicateGadgetHooks`. Soft mirror of that gate so
|
|
362
|
-
* authoring tools surface the issue before a
|
|
362
|
+
* authoring tools surface the issue before a render round-trip.
|
|
363
363
|
*/
|
|
364
364
|
export function checkDuplicateGadgetHooks(contract) {
|
|
365
365
|
const seen = new Map(); // export name → first package
|
|
@@ -516,10 +516,10 @@ export function lintGadgetCatalog(descriptors) {
|
|
|
516
516
|
* Find top-level retired-field carriers on the contract. The schema
|
|
517
517
|
* is `.passthrough()`, so a stray `libraries`/`dispatch`/`wiredTools`/
|
|
518
518
|
* `clientTools`/`broadcast`/`capabilities` slips through silently. The
|
|
519
|
-
*
|
|
519
|
+
* render-gate hard-rejects these (see
|
|
520
520
|
* `mcp-server-handlers/.../assert-contract-no-retired-fields.ts`); this
|
|
521
521
|
* lint surface keeps authoring tools symmetric — show the warning before
|
|
522
|
-
* the
|
|
522
|
+
* the render call so the author can fix it without a server round-trip.
|
|
523
523
|
*/
|
|
524
524
|
export function checkRetiredContractFields(contract) {
|
|
525
525
|
// Cast to a generic record so we can probe the keys the passthrough
|
|
@@ -534,7 +534,7 @@ export function checkRetiredContractFields(contract) {
|
|
|
534
534
|
warnings.push({
|
|
535
535
|
code: LINT_CONTRACT_RETIRED_FIELD,
|
|
536
536
|
path: retired,
|
|
537
|
-
message: `contract.${retired} is retired. Use ${replacement} instead — the field rides through .passthrough() but the
|
|
537
|
+
message: `contract.${retired} is retired. Use ${replacement} instead — the field rides through .passthrough() but the render gate hard-rejects it as a structural error.`,
|
|
538
538
|
fixHint: `Delete contract.${retired}; move its data to ${replacement}.`,
|
|
539
539
|
});
|
|
540
540
|
}
|
|
@@ -543,12 +543,15 @@ export function checkRetiredContractFields(contract) {
|
|
|
543
543
|
/**
|
|
544
544
|
* Run every WIRE-side hygiene rule on a `DataContract`. Aggregates
|
|
545
545
|
* warnings; order is stable (orphans → usage → example → gadget
|
|
546
|
-
* hook-names → duplicate-hook
|
|
547
|
-
*
|
|
546
|
+
* hook-names → duplicate-hook) so authoring tools render a predictable
|
|
547
|
+
* checklist. Retired-field detection is NOT here — it is promoted to an
|
|
548
|
+
* ERROR phase (`phaseRetired` in lint-contract.ts); the detector
|
|
549
|
+
* `checkRetiredContractFields` stays exported for the author-time
|
|
550
|
+
* surface and the render-gate assert.
|
|
548
551
|
*
|
|
549
552
|
* Registry-side gadget lints (`lintGadgetCatalog`) are NOT run here:
|
|
550
553
|
* they need an `App.gadgets` descriptor array, not a contract, and
|
|
551
|
-
* fire at registration time rather than
|
|
554
|
+
* fire at registration time rather than render time.
|
|
552
555
|
* Call {@link lintGadgetCatalog} separately at the registration
|
|
553
556
|
* boundary.
|
|
554
557
|
*/
|
|
@@ -559,6 +562,9 @@ export function checkHygiene(contract) {
|
|
|
559
562
|
...checkMissingExample(contract),
|
|
560
563
|
...checkGadgetHookNames(contract),
|
|
561
564
|
...checkDuplicateGadgetHooks(contract),
|
|
562
|
-
|
|
565
|
+
// Retired-field detection is promoted to an ERROR phase
|
|
566
|
+
// (`phaseRetired` in lint-contract.ts) — not a hygiene warning.
|
|
567
|
+
// `checkRetiredContractFields` stays exported for the author-time
|
|
568
|
+
// surface + the render-gate assert.
|
|
563
569
|
];
|
|
564
570
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validating narrower for the JSON-object shape: is `value` a
|
|
3
|
+
* non-null, non-array object — the shape every wire frame, request
|
|
4
|
+
* body, and envelope must satisfy before keyed access?
|
|
5
|
+
*
|
|
6
|
+
* One definition for the whole protocol family so every trust
|
|
7
|
+
* boundary narrows with the SAME predicate — no per-package
|
|
8
|
+
* duplicates, no per-site `as Record<string, unknown>` casts. Use it
|
|
9
|
+
* wherever untrusted input (HTTP bodies, wire frames, parsed JSON)
|
|
10
|
+
* needs to become a `Record<string, unknown>` before field reads:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const body: Record<string, unknown> = isRecord(req.body) ? req.body : {};
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
17
|
+
//# sourceMappingURL=is-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-record.d.ts","sourceRoot":"","sources":["../../src/validation/is-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validating narrower for the JSON-object shape: is `value` a
|
|
3
|
+
* non-null, non-array object — the shape every wire frame, request
|
|
4
|
+
* body, and envelope must satisfy before keyed access?
|
|
5
|
+
*
|
|
6
|
+
* One definition for the whole protocol family so every trust
|
|
7
|
+
* boundary narrows with the SAME predicate — no per-package
|
|
8
|
+
* duplicates, no per-site `as Record<string, unknown>` casts. Use it
|
|
9
|
+
* wherever untrusted input (HTTP bodies, wire frames, parsed JSON)
|
|
10
|
+
* needs to become a `Record<string, unknown>` before field reads:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const body: Record<string, unknown> = isRecord(req.body) ? req.body : {};
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function isRecord(value) {
|
|
17
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* - {@link validateContract} — strict; runs phased validation and
|
|
7
7
|
* throws {@link ContractValidationError} on the FIRST phase that
|
|
8
|
-
* produces errors. Used at every protocol boundary (
|
|
8
|
+
* produces errors. Used at every protocol boundary (render handler,
|
|
9
9
|
* blueprint registration, future synth output gate).
|
|
10
10
|
*
|
|
11
11
|
* - {@link lintContract} — graded; runs ALL phases unconditionally
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
*
|
|
18
18
|
* ```
|
|
19
19
|
* phase 1: shape (zod wire-shape validation)
|
|
20
|
-
* phase 2:
|
|
21
|
-
* phase 3: schema
|
|
22
|
-
* phase 4:
|
|
20
|
+
* phase 2: retired (CTR_RETIRED_FIELD — dead top-level fields)
|
|
21
|
+
* phase 3: schema-meta (CTR_SCHEMA_META_INVALID — Ajv strict on inner schemas)
|
|
22
|
+
* phase 4: references (CTR_REF_*, CTR_DUP_NAME, CTR_RESERVED_NAME)
|
|
23
|
+
* phase 5: schema compat (CTR_SCHEMA_INCOMPAT)
|
|
24
|
+
* phase 6: hygiene (LINT_* — graded, warnings only)
|
|
23
25
|
* ```
|
|
24
26
|
*
|
|
25
27
|
* Errors are reported one phase at a time during strict validation so
|
|
@@ -28,7 +30,6 @@
|
|
|
28
30
|
* graded mode emits every issue at once so authoring tools can
|
|
29
31
|
* present a complete checklist.
|
|
30
32
|
*/
|
|
31
|
-
import type { DataContract } from '../types/data-contract';
|
|
32
33
|
/**
|
|
33
34
|
* Severity classification for a {@link ContractIssue}. Strict
|
|
34
35
|
* `validateContract` throws on `'error'`; graded `lintContract`
|
|
@@ -40,7 +41,7 @@ export type ContractIssueSeverity = 'error' | 'warn';
|
|
|
40
41
|
* authoring tools can render issues grouped by phase + drive the
|
|
41
42
|
* "fix one phase at a time" UX.
|
|
42
43
|
*/
|
|
43
|
-
export type ContractLintPhase = 'shape' | 'references' | 'schema-compat' | 'hygiene';
|
|
44
|
+
export type ContractLintPhase = 'shape' | 'retired' | 'schema-meta' | 'references' | 'schema-compat' | 'hygiene';
|
|
44
45
|
/**
|
|
45
46
|
* One observation about a contract from the linter's perspective.
|
|
46
47
|
*
|
|
@@ -114,7 +115,7 @@ export declare class ContractValidationError extends Error {
|
|
|
114
115
|
* Hygiene-only contracts (warnings without errors) pass the strict
|
|
115
116
|
* gate. Use {@link lintContract} when warnings matter.
|
|
116
117
|
*/
|
|
117
|
-
export declare function validateContract(contract:
|
|
118
|
+
export declare function validateContract(contract: unknown): void;
|
|
118
119
|
/**
|
|
119
120
|
* Graded-mode linter. Runs ALL phases unconditionally and returns
|
|
120
121
|
* errors + warnings partitioned. Suitable for authoring tools that
|
|
@@ -126,5 +127,5 @@ export declare function validateContract(contract: DataContract): void;
|
|
|
126
127
|
* author seeing a phase-2 reference error also sees the phase-4
|
|
127
128
|
* hygiene warnings on the same contract.
|
|
128
129
|
*/
|
|
129
|
-
export declare function lintContract(contract:
|
|
130
|
+
export declare function lintContract(contract: unknown): ContractLintResult;
|
|
130
131
|
//# sourceMappingURL=lint-contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint-contract.d.ts","sourceRoot":"","sources":["../../src/validation/lint-contract.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lint-contract.d.ts","sourceRoot":"","sources":["../../src/validation/lint-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAwBH;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB,OAAO,GACP,SAAS,GACT,aAAa,GACb,YAAY,GACZ,eAAe,GACf,SAAS,CAAC;AAEd;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,4BAA4B,CAAU;IACtD,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;gBAE9B,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,aAAa,EAAE;CAOvE;AA4KD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CA2BxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,kBAAkB,CAyBlE"}
|