@ggui-ai/protocol 0.1.0-rc.1
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/LICENSE +201 -0
- package/README.md +46 -0
- package/dist/bridge/invoke-agent.d.ts +65 -0
- package/dist/bridge/invoke-agent.d.ts.map +1 -0
- package/dist/bridge/invoke-agent.js +113 -0
- package/dist/envelope-adapters.d.ts +24 -0
- package/dist/envelope-adapters.d.ts.map +1 -0
- package/dist/envelope-adapters.js +14 -0
- package/dist/envelopes/builders.d.ts +145 -0
- package/dist/envelopes/builders.d.ts.map +1 -0
- package/dist/envelopes/builders.js +113 -0
- package/dist/errors/unknown-permission-name.d.ts +12 -0
- package/dist/errors/unknown-permission-name.d.ts.map +1 -0
- package/dist/errors/unknown-permission-name.js +29 -0
- package/dist/errors/version-mismatch.d.ts +55 -0
- package/dist/errors/version-mismatch.d.ts.map +1 -0
- package/dist/errors/version-mismatch.js +52 -0
- package/dist/gadgets/resolve-contract-gadgets.d.ts +93 -0
- package/dist/gadgets/resolve-contract-gadgets.d.ts.map +1 -0
- package/dist/gadgets/resolve-contract-gadgets.js +119 -0
- package/dist/gadgets/stdlib-gadgets.d.ts +43 -0
- package/dist/gadgets/stdlib-gadgets.d.ts.map +1 -0
- package/dist/gadgets/stdlib-gadgets.js +161 -0
- package/dist/iframe-bridge.d.ts +63 -0
- package/dist/iframe-bridge.d.ts.map +1 -0
- package/dist/iframe-bridge.js +166 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/integrations/mcp-apps.d.ts +1218 -0
- package/dist/integrations/mcp-apps.d.ts.map +1 -0
- package/dist/integrations/mcp-apps.js +427 -0
- package/dist/navigation/index.d.ts +3 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +1 -0
- package/dist/navigation/stack-navigation.d.ts +55 -0
- package/dist/navigation/stack-navigation.d.ts.map +1 -0
- package/dist/navigation/stack-navigation.js +80 -0
- package/dist/recommended-prompts.d.ts +56 -0
- package/dist/recommended-prompts.d.ts.map +1 -0
- package/dist/recommended-prompts.js +55 -0
- package/dist/registry/blueprint-key.d.ts +9 -0
- package/dist/registry/blueprint-key.d.ts.map +1 -0
- package/dist/registry/blueprint-key.js +28 -0
- package/dist/registry/canonicalize-contract.d.ts +35 -0
- package/dist/registry/canonicalize-contract.d.ts.map +1 -0
- package/dist/registry/canonicalize-contract.js +166 -0
- package/dist/registry/summarize-contract.d.ts +46 -0
- package/dist/registry/summarize-contract.d.ts.map +1 -0
- package/dist/registry/summarize-contract.js +63 -0
- package/dist/schema-learning/derive-contract.d.ts +67 -0
- package/dist/schema-learning/derive-contract.d.ts.map +1 -0
- package/dist/schema-learning/derive-contract.js +117 -0
- package/dist/schema-learning/merge.d.ts +32 -0
- package/dist/schema-learning/merge.d.ts.map +1 -0
- package/dist/schema-learning/merge.js +146 -0
- package/dist/schemas/blueprint.d.ts +32 -0
- package/dist/schemas/blueprint.d.ts.map +1 -0
- package/dist/schemas/blueprint.js +92 -0
- package/dist/schemas/data-contract.d.ts +750 -0
- package/dist/schemas/data-contract.d.ts.map +1 -0
- package/dist/schemas/data-contract.js +663 -0
- package/dist/schemas/gadget-name-grammar.d.ts +29 -0
- package/dist/schemas/gadget-name-grammar.d.ts.map +1 -0
- package/dist/schemas/gadget-name-grammar.js +28 -0
- package/dist/schemas/handshake-suggestion.d.ts +46 -0
- package/dist/schemas/handshake-suggestion.d.ts.map +1 -0
- package/dist/schemas/handshake-suggestion.js +107 -0
- package/dist/schemas/invoke.d.ts +337 -0
- package/dist/schemas/invoke.d.ts.map +1 -0
- package/dist/schemas/invoke.js +169 -0
- package/dist/schemas/mcp.d.ts +301 -0
- package/dist/schemas/mcp.d.ts.map +1 -0
- package/dist/schemas/mcp.js +373 -0
- package/dist/schemas/ops-blueprint.d.ts +176 -0
- package/dist/schemas/ops-blueprint.d.ts.map +1 -0
- package/dist/schemas/ops-blueprint.js +259 -0
- package/dist/schemas/sync-check.d.ts +11 -0
- package/dist/schemas/sync-check.d.ts.map +1 -0
- package/dist/schemas/sync-check.js +60 -0
- package/dist/screen-blueprints/define.d.ts +22 -0
- package/dist/screen-blueprints/define.d.ts.map +1 -0
- package/dist/screen-blueprints/define.js +3 -0
- package/dist/screen-blueprints/index.d.ts +4 -0
- package/dist/screen-blueprints/index.d.ts.map +1 -0
- package/dist/screen-blueprints/index.js +3 -0
- package/dist/screen-blueprints/match.d.ts +35 -0
- package/dist/screen-blueprints/match.d.ts.map +1 -0
- package/dist/screen-blueprints/match.js +51 -0
- package/dist/screen-blueprints/types.d.ts +164 -0
- package/dist/screen-blueprints/types.d.ts.map +1 -0
- package/dist/screen-blueprints/types.js +1 -0
- package/dist/stream/stream-parser.d.ts +62 -0
- package/dist/stream/stream-parser.d.ts.map +1 -0
- package/dist/stream/stream-parser.js +199 -0
- package/dist/transport/websocket.d.ts +178 -0
- package/dist/transport/websocket.d.ts.map +1 -0
- package/dist/transport/websocket.js +1 -0
- package/dist/types/app-config.d.ts +61 -0
- package/dist/types/app-config.d.ts.map +1 -0
- package/dist/types/app-config.js +1 -0
- package/dist/types/auth.d.ts +61 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +1 -0
- package/dist/types/blueprint.d.ts +206 -0
- package/dist/types/blueprint.d.ts.map +1 -0
- package/dist/types/blueprint.js +1 -0
- package/dist/types/canvas-lifecycle.d.ts +105 -0
- package/dist/types/canvas-lifecycle.d.ts.map +1 -0
- package/dist/types/canvas-lifecycle.js +38 -0
- package/dist/types/capabilities.d.ts +40 -0
- package/dist/types/capabilities.d.ts.map +1 -0
- package/dist/types/capabilities.js +19 -0
- package/dist/types/contract-inference.d.ts +401 -0
- package/dist/types/contract-inference.d.ts.map +1 -0
- package/dist/types/contract-inference.js +44 -0
- package/dist/types/credential.d.ts +41 -0
- package/dist/types/credential.d.ts.map +1 -0
- package/dist/types/credential.js +32 -0
- package/dist/types/data-bindings.d.ts +322 -0
- package/dist/types/data-bindings.d.ts.map +1 -0
- package/dist/types/data-bindings.js +29 -0
- package/dist/types/data-contract.d.ts +1296 -0
- package/dist/types/data-contract.d.ts.map +1 -0
- package/dist/types/data-contract.js +111 -0
- package/dist/types/events.d.ts +182 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +8 -0
- package/dist/types/feedback.d.ts +24 -0
- package/dist/types/feedback.d.ts.map +1 -0
- package/dist/types/feedback.js +7 -0
- package/dist/types/gadget.d.ts +121 -0
- package/dist/types/gadget.d.ts.map +1 -0
- package/dist/types/gadget.js +24 -0
- package/dist/types/handshake-suggestion.d.ts +264 -0
- package/dist/types/handshake-suggestion.d.ts.map +1 -0
- package/dist/types/handshake-suggestion.js +70 -0
- package/dist/types/host-context.d.ts +163 -0
- package/dist/types/host-context.d.ts.map +1 -0
- package/dist/types/host-context.js +142 -0
- package/dist/types/interface-context.d.ts +105 -0
- package/dist/types/interface-context.d.ts.map +1 -0
- package/dist/types/interface-context.js +115 -0
- package/dist/types/invoke.d.ts +28 -0
- package/dist/types/invoke.d.ts.map +1 -0
- package/dist/types/invoke.js +7 -0
- package/dist/types/live-channel.d.ts +613 -0
- package/dist/types/live-channel.d.ts.map +1 -0
- package/dist/types/live-channel.js +1 -0
- package/dist/types/llm.d.ts +61 -0
- package/dist/types/llm.d.ts.map +1 -0
- package/dist/types/llm.js +186 -0
- package/dist/types/mcp-proxy.d.ts +67 -0
- package/dist/types/mcp-proxy.d.ts.map +1 -0
- package/dist/types/mcp-proxy.js +46 -0
- package/dist/types/mcp.d.ts +637 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +30 -0
- package/dist/types/openrouter-models.d.ts +22 -0
- package/dist/types/openrouter-models.d.ts.map +1 -0
- package/dist/types/openrouter-models.js +4843 -0
- package/dist/types/region.d.ts +26 -0
- package/dist/types/region.d.ts.map +1 -0
- package/dist/types/region.js +36 -0
- package/dist/types/session.d.ts +419 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +1 -0
- package/dist/types/thread.d.ts +207 -0
- package/dist/types/thread.d.ts.map +1 -0
- package/dist/types/thread.js +57 -0
- package/dist/types/ui-generator.d.ts +100 -0
- package/dist/types/ui-generator.d.ts.map +1 -0
- package/dist/types/ui-generator.js +53 -0
- package/dist/validation/ajv-runtime.d.ts +140 -0
- package/dist/validation/ajv-runtime.d.ts.map +1 -0
- package/dist/validation/ajv-runtime.js +452 -0
- package/dist/validation/content-hash.d.ts +3 -0
- package/dist/validation/content-hash.d.ts.map +1 -0
- package/dist/validation/content-hash.js +21 -0
- package/dist/validation/contract-validator.d.ts +244 -0
- package/dist/validation/contract-validator.d.ts.map +1 -0
- package/dist/validation/contract-validator.js +711 -0
- package/dist/validation/cross-references.d.ts +105 -0
- package/dist/validation/cross-references.d.ts.map +1 -0
- package/dist/validation/cross-references.js +164 -0
- package/dist/validation/hygiene-rules.d.ts +250 -0
- package/dist/validation/hygiene-rules.d.ts.map +1 -0
- package/dist/validation/hygiene-rules.js +564 -0
- package/dist/validation/lint-contract.d.ts +130 -0
- package/dist/validation/lint-contract.d.ts.map +1 -0
- package/dist/validation/lint-contract.js +225 -0
- package/dist/validation/name-invariants.d.ts +117 -0
- package/dist/validation/name-invariants.d.ts.map +1 -0
- package/dist/validation/name-invariants.js +172 -0
- package/dist/validation/reserved-channels.d.ts +156 -0
- package/dist/validation/reserved-channels.d.ts.map +1 -0
- package/dist/validation/reserved-channels.js +356 -0
- package/dist/validation/resolve-stream-channel.d.ts +78 -0
- package/dist/validation/resolve-stream-channel.d.ts.map +1 -0
- package/dist/validation/resolve-stream-channel.js +64 -0
- package/dist/validation/sanitize-error.d.ts +46 -0
- package/dist/validation/sanitize-error.d.ts.map +1 -0
- package/dist/validation/sanitize-error.js +88 -0
- package/dist/validation/schema-compat-invariants.d.ts +140 -0
- package/dist/validation/schema-compat-invariants.d.ts.map +1 -0
- package/dist/validation/schema-compat-invariants.js +220 -0
- package/dist/validation/schema-meta-validation.d.ts +60 -0
- package/dist/validation/schema-meta-validation.d.ts.map +1 -0
- package/dist/validation/schema-meta-validation.js +131 -0
- package/dist/validation/schema-subset.d.ts +165 -0
- package/dist/validation/schema-subset.d.ts.map +1 -0
- package/dist/validation/schema-subset.js +295 -0
- package/dist/validation/ui-security.d.ts +54 -0
- package/dist/validation/ui-security.d.ts.map +1 -0
- package/dist/validation/ui-security.js +138 -0
- package/dist/validation/zod-to-json-schema.d.ts +63 -0
- package/dist/validation/zod-to-json-schema.d.ts.map +1 -0
- package/dist/validation/zod-to-json-schema.js +126 -0
- package/dist/version.d.ts +1458 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +1459 -0
- package/package.json +113 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-reference invariants for `DataContract`. Validates that every
|
|
3
|
+
* intra-contract pointer resolves to a declared catalog entry on the
|
|
4
|
+
* SAME contract — i.e., the contract is internally consistent.
|
|
5
|
+
*
|
|
6
|
+
* The protocol exposes two such pointers:
|
|
7
|
+
*
|
|
8
|
+
* - `actionSpec[*].nextStep` → `agentCapabilities.tools[*]` key
|
|
9
|
+
* - `streamSpec[*].source.tool` → `agentCapabilities.tools[*]` key
|
|
10
|
+
*
|
|
11
|
+
* These are pure in-contract checks. A contract that declares
|
|
12
|
+
* `nextStep: 'archive_email'` MUST also declare `archive_email` in its
|
|
13
|
+
* own `agentCapabilities.tools` catalog — same-MCP and cross-MCP both
|
|
14
|
+
* funnel through this single resolution path (the catalog is the
|
|
15
|
+
* declarative source of truth for every referenced tool). Violations
|
|
16
|
+
* are author-recoverable at push time.
|
|
17
|
+
*/
|
|
18
|
+
import type { DataContract, ActionSpec, StreamSpec, AgentCapabilitiesSpec } from '../types/data-contract';
|
|
19
|
+
import type { ContractViolation } from './contract-validator';
|
|
20
|
+
/**
|
|
21
|
+
* Stable error code emitted when an `actionSpec[*].nextStep` value
|
|
22
|
+
* does not resolve to a declared `agentCapabilities.tools[*]` key on
|
|
23
|
+
* the same contract.
|
|
24
|
+
*
|
|
25
|
+
* Intended for downstream consumers that switch on the code rather
|
|
26
|
+
* than pattern-matching message strings.
|
|
27
|
+
*/
|
|
28
|
+
export declare const CTR_REF_NEXT_STEP = "CTR_REF_NEXT_STEP";
|
|
29
|
+
/**
|
|
30
|
+
* Stable error code emitted when a `streamSpec[*].source.tool` value
|
|
31
|
+
* does not resolve to a declared `agentCapabilities.tools[*]` key on
|
|
32
|
+
* the same contract.
|
|
33
|
+
*
|
|
34
|
+
* Intended for downstream consumers that switch on the code rather
|
|
35
|
+
* than pattern-matching message strings. Mentioned by name in
|
|
36
|
+
* `packages/protocol/src/types/data-contract.ts` (StreamChannelEntry
|
|
37
|
+
* docstring) — keep in sync.
|
|
38
|
+
*/
|
|
39
|
+
export declare const CTR_REF_STREAM_SOURCE = "CTR_REF_STREAM_SOURCE";
|
|
40
|
+
/**
|
|
41
|
+
* Cross-reference violation — adds a stable `code` field on top of
|
|
42
|
+
* `ContractViolation`. Lives here rather than on the base type so
|
|
43
|
+
* existing structural violations stay code-less; cross-ref violations
|
|
44
|
+
* are designed to be machine-discriminated.
|
|
45
|
+
*/
|
|
46
|
+
export interface CrossReferenceViolation extends ContractViolation {
|
|
47
|
+
code: typeof CTR_REF_NEXT_STEP | typeof CTR_REF_STREAM_SOURCE;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate every `actionSpec[*].nextStep` resolves to a declared
|
|
51
|
+
* `agentCapabilities.tools[*]` key on the same contract. Entries
|
|
52
|
+
* without a `nextStep` are skipped (they're pure event signals — the
|
|
53
|
+
* agent decides unconstrained by author intent).
|
|
54
|
+
*
|
|
55
|
+
* When `agentCapabilities` is undefined but a `nextStep` is declared,
|
|
56
|
+
* the reference still doesn't resolve — a violation surfaces. Authors
|
|
57
|
+
* can fix by adding the referenced tool to `agentCapabilities.tools`
|
|
58
|
+
* or by dropping the `nextStep` hint (no-hint action remains valid).
|
|
59
|
+
*/
|
|
60
|
+
export declare function checkActionNextStepRefs(actionSpec: ActionSpec | undefined, agentCapabilities: AgentCapabilitiesSpec | undefined): CrossReferenceViolation[];
|
|
61
|
+
/**
|
|
62
|
+
* Validate every `streamSpec[*].source.tool` resolves to a declared
|
|
63
|
+
* `agentCapabilities.tools[*]` key on the same contract. Channels
|
|
64
|
+
* without a `source` declaration are skipped (they're agent-written by
|
|
65
|
+
* some other mechanism, or server-owned reserved channels).
|
|
66
|
+
*
|
|
67
|
+
* When `agentCapabilities` is undefined but a `source.tool` is
|
|
68
|
+
* declared, the reference still doesn't resolve — a violation
|
|
69
|
+
* surfaces. Authors fix by adding the referenced tool to
|
|
70
|
+
* `agentCapabilities.tools` or by dropping `source` (channel becomes
|
|
71
|
+
* agent-written rather than tool-sourced).
|
|
72
|
+
*/
|
|
73
|
+
export declare function checkStreamSourceRefs(streamSpec: StreamSpec | undefined, agentCapabilities: AgentCapabilitiesSpec | undefined): CrossReferenceViolation[];
|
|
74
|
+
/**
|
|
75
|
+
* Run every cross-reference invariant. Returns the aggregated
|
|
76
|
+
* violation list — order is stable: `nextStep` invariants first,
|
|
77
|
+
* `stream.source` invariants second.
|
|
78
|
+
*
|
|
79
|
+
* Pure check; doesn't throw. Callers that want fail-fast semantics
|
|
80
|
+
* use {@link assertCrossReferences}.
|
|
81
|
+
*/
|
|
82
|
+
export declare function checkCrossReferences(contract: DataContract): CrossReferenceViolation[];
|
|
83
|
+
/**
|
|
84
|
+
* Throwable form of {@link checkCrossReferences}. Use at protocol
|
|
85
|
+
* boundaries where an unresolved cross-reference is a contract bug
|
|
86
|
+
* the caller must fix (push handler, blueprint registration).
|
|
87
|
+
*
|
|
88
|
+
* Carries the full violation list so error renderers can show every
|
|
89
|
+
* dangling reference in one pass instead of fix-and-retry per-field.
|
|
90
|
+
*/
|
|
91
|
+
export declare class CrossReferenceError extends Error {
|
|
92
|
+
readonly code: "cross_reference_unresolved";
|
|
93
|
+
readonly violations: readonly CrossReferenceViolation[];
|
|
94
|
+
constructor(violations: readonly CrossReferenceViolation[]);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Throw-on-violation wrapper around {@link checkCrossReferences}.
|
|
98
|
+
* No-op when the contract is internally consistent.
|
|
99
|
+
*
|
|
100
|
+
* Invoked at handshake AND push time: contract-internal mistakes
|
|
101
|
+
* surface at the earliest possible boundary so the agent can fix and
|
|
102
|
+
* retry on the SAME handshakeId.
|
|
103
|
+
*/
|
|
104
|
+
export declare function assertCrossReferences(contract: DataContract): void;
|
|
105
|
+
//# sourceMappingURL=cross-references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-references.d.ts","sourceRoot":"","sources":["../../src/validation/cross-references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC1G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,IAAI,EAAE,OAAO,iBAAiB,GAAG,OAAO,qBAAqB,CAAC;CAC/D;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,iBAAiB,EAAE,qBAAqB,GAAG,SAAS,GACnD,uBAAuB,EAAE,CAsB3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,iBAAiB,EAAE,qBAAqB,GAAG,SAAS,GACnD,uBAAuB,EAAE,CAwB3B;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,GACrB,uBAAuB,EAAE,CAK3B;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAG,4BAA4B,CAAU;IACtD,QAAQ,CAAC,UAAU,EAAE,SAAS,uBAAuB,EAAE,CAAC;gBAE5C,UAAU,EAAE,SAAS,uBAAuB,EAAE;CAQ3D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAKlE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-reference invariants for `DataContract`. Validates that every
|
|
3
|
+
* intra-contract pointer resolves to a declared catalog entry on the
|
|
4
|
+
* SAME contract — i.e., the contract is internally consistent.
|
|
5
|
+
*
|
|
6
|
+
* The protocol exposes two such pointers:
|
|
7
|
+
*
|
|
8
|
+
* - `actionSpec[*].nextStep` → `agentCapabilities.tools[*]` key
|
|
9
|
+
* - `streamSpec[*].source.tool` → `agentCapabilities.tools[*]` key
|
|
10
|
+
*
|
|
11
|
+
* These are pure in-contract checks. A contract that declares
|
|
12
|
+
* `nextStep: 'archive_email'` MUST also declare `archive_email` in its
|
|
13
|
+
* own `agentCapabilities.tools` catalog — same-MCP and cross-MCP both
|
|
14
|
+
* funnel through this single resolution path (the catalog is the
|
|
15
|
+
* declarative source of truth for every referenced tool). Violations
|
|
16
|
+
* are author-recoverable at push time.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Stable error code emitted when an `actionSpec[*].nextStep` value
|
|
20
|
+
* does not resolve to a declared `agentCapabilities.tools[*]` key on
|
|
21
|
+
* the same contract.
|
|
22
|
+
*
|
|
23
|
+
* Intended for downstream consumers that switch on the code rather
|
|
24
|
+
* than pattern-matching message strings.
|
|
25
|
+
*/
|
|
26
|
+
export const CTR_REF_NEXT_STEP = 'CTR_REF_NEXT_STEP';
|
|
27
|
+
/**
|
|
28
|
+
* Stable error code emitted when a `streamSpec[*].source.tool` value
|
|
29
|
+
* does not resolve to a declared `agentCapabilities.tools[*]` key on
|
|
30
|
+
* the same contract.
|
|
31
|
+
*
|
|
32
|
+
* Intended for downstream consumers that switch on the code rather
|
|
33
|
+
* than pattern-matching message strings. Mentioned by name in
|
|
34
|
+
* `packages/protocol/src/types/data-contract.ts` (StreamChannelEntry
|
|
35
|
+
* docstring) — keep in sync.
|
|
36
|
+
*/
|
|
37
|
+
export const CTR_REF_STREAM_SOURCE = 'CTR_REF_STREAM_SOURCE';
|
|
38
|
+
function agentToolKeys(spec) {
|
|
39
|
+
if (!spec)
|
|
40
|
+
return [];
|
|
41
|
+
return Object.keys(spec.tools);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate every `actionSpec[*].nextStep` resolves to a declared
|
|
45
|
+
* `agentCapabilities.tools[*]` key on the same contract. Entries
|
|
46
|
+
* without a `nextStep` are skipped (they're pure event signals — the
|
|
47
|
+
* agent decides unconstrained by author intent).
|
|
48
|
+
*
|
|
49
|
+
* When `agentCapabilities` is undefined but a `nextStep` is declared,
|
|
50
|
+
* the reference still doesn't resolve — a violation surfaces. Authors
|
|
51
|
+
* can fix by adding the referenced tool to `agentCapabilities.tools`
|
|
52
|
+
* or by dropping the `nextStep` hint (no-hint action remains valid).
|
|
53
|
+
*/
|
|
54
|
+
export function checkActionNextStepRefs(actionSpec, agentCapabilities) {
|
|
55
|
+
if (!actionSpec)
|
|
56
|
+
return [];
|
|
57
|
+
const violations = [];
|
|
58
|
+
const knownTools = agentToolKeys(agentCapabilities);
|
|
59
|
+
for (const [actionName, entry] of Object.entries(actionSpec)) {
|
|
60
|
+
if (entry === null || typeof entry !== 'object')
|
|
61
|
+
continue;
|
|
62
|
+
const nextStep = entry.nextStep;
|
|
63
|
+
if (nextStep === undefined)
|
|
64
|
+
continue;
|
|
65
|
+
if (knownTools.includes(nextStep))
|
|
66
|
+
continue;
|
|
67
|
+
const known = knownTools.length > 0 ? knownTools.join(', ') : '(none)';
|
|
68
|
+
violations.push({
|
|
69
|
+
code: CTR_REF_NEXT_STEP,
|
|
70
|
+
field: `actionSpec.${actionName}.nextStep`,
|
|
71
|
+
message: `actionSpec.${actionName}.nextStep references '${nextStep}', which is not declared in agentCapabilities.tools. Declared: ${known}.`,
|
|
72
|
+
expected: knownTools.join(' | ') || '(declare in agentCapabilities.tools)',
|
|
73
|
+
received: nextStep,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return violations;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate every `streamSpec[*].source.tool` resolves to a declared
|
|
80
|
+
* `agentCapabilities.tools[*]` key on the same contract. Channels
|
|
81
|
+
* without a `source` declaration are skipped (they're agent-written by
|
|
82
|
+
* some other mechanism, or server-owned reserved channels).
|
|
83
|
+
*
|
|
84
|
+
* When `agentCapabilities` is undefined but a `source.tool` is
|
|
85
|
+
* declared, the reference still doesn't resolve — a violation
|
|
86
|
+
* surfaces. Authors fix by adding the referenced tool to
|
|
87
|
+
* `agentCapabilities.tools` or by dropping `source` (channel becomes
|
|
88
|
+
* agent-written rather than tool-sourced).
|
|
89
|
+
*/
|
|
90
|
+
export function checkStreamSourceRefs(streamSpec, agentCapabilities) {
|
|
91
|
+
if (!streamSpec)
|
|
92
|
+
return [];
|
|
93
|
+
const violations = [];
|
|
94
|
+
const knownTools = agentToolKeys(agentCapabilities);
|
|
95
|
+
for (const [channelName, entry] of Object.entries(streamSpec)) {
|
|
96
|
+
if (entry === null || typeof entry !== 'object')
|
|
97
|
+
continue;
|
|
98
|
+
const source = entry.source;
|
|
99
|
+
if (!source)
|
|
100
|
+
continue;
|
|
101
|
+
const toolName = source.tool;
|
|
102
|
+
if (typeof toolName !== 'string' || toolName.length === 0)
|
|
103
|
+
continue;
|
|
104
|
+
if (knownTools.includes(toolName))
|
|
105
|
+
continue;
|
|
106
|
+
const known = knownTools.length > 0 ? knownTools.join(', ') : '(none)';
|
|
107
|
+
violations.push({
|
|
108
|
+
code: CTR_REF_STREAM_SOURCE,
|
|
109
|
+
field: `streamSpec.${channelName}.source.tool`,
|
|
110
|
+
message: `streamSpec.${channelName}.source.tool references '${toolName}', which is not declared in agentCapabilities.tools. Declared: ${known}.`,
|
|
111
|
+
expected: knownTools.join(' | ') || '(declare in agentCapabilities.tools)',
|
|
112
|
+
received: toolName,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return violations;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Run every cross-reference invariant. Returns the aggregated
|
|
119
|
+
* violation list — order is stable: `nextStep` invariants first,
|
|
120
|
+
* `stream.source` invariants second.
|
|
121
|
+
*
|
|
122
|
+
* Pure check; doesn't throw. Callers that want fail-fast semantics
|
|
123
|
+
* use {@link assertCrossReferences}.
|
|
124
|
+
*/
|
|
125
|
+
export function checkCrossReferences(contract) {
|
|
126
|
+
return [
|
|
127
|
+
...checkActionNextStepRefs(contract.actionSpec, contract.agentCapabilities),
|
|
128
|
+
...checkStreamSourceRefs(contract.streamSpec, contract.agentCapabilities),
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Throwable form of {@link checkCrossReferences}. Use at protocol
|
|
133
|
+
* boundaries where an unresolved cross-reference is a contract bug
|
|
134
|
+
* the caller must fix (push handler, blueprint registration).
|
|
135
|
+
*
|
|
136
|
+
* Carries the full violation list so error renderers can show every
|
|
137
|
+
* dangling reference in one pass instead of fix-and-retry per-field.
|
|
138
|
+
*/
|
|
139
|
+
export class CrossReferenceError extends Error {
|
|
140
|
+
code = 'cross_reference_unresolved';
|
|
141
|
+
violations;
|
|
142
|
+
constructor(violations) {
|
|
143
|
+
const summary = violations
|
|
144
|
+
.map((v) => `[${v.code}] ${v.message}`)
|
|
145
|
+
.join(' | ');
|
|
146
|
+
super(`Contract cross-reference invariants failed: ${summary}`);
|
|
147
|
+
this.name = 'CrossReferenceError';
|
|
148
|
+
this.violations = violations;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Throw-on-violation wrapper around {@link checkCrossReferences}.
|
|
153
|
+
* No-op when the contract is internally consistent.
|
|
154
|
+
*
|
|
155
|
+
* Invoked at handshake AND push time: contract-internal mistakes
|
|
156
|
+
* surface at the earliest possible boundary so the agent can fix and
|
|
157
|
+
* retry on the SAME handshakeId.
|
|
158
|
+
*/
|
|
159
|
+
export function assertCrossReferences(contract) {
|
|
160
|
+
const violations = checkCrossReferences(contract);
|
|
161
|
+
if (violations.length > 0) {
|
|
162
|
+
throw new CrossReferenceError(violations);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authoring-hygiene rules for `DataContract`. Lint rule registry —
|
|
3
|
+
* warnings only, never thrown by {@link validateContract}; surfaced
|
|
4
|
+
* by {@link lintContract} so authoring tools can offer "your contract
|
|
5
|
+
* is technically valid, but here are the polish items" feedback.
|
|
6
|
+
*
|
|
7
|
+
* Ships the most universally applicable subset:
|
|
8
|
+
*
|
|
9
|
+
* - `LINT_ORPHAN_AGENT_TOOL` — `agentCapabilities.tools[X]` is
|
|
10
|
+
* declared but never referenced from any `actionSpec[*].nextStep`
|
|
11
|
+
* or `streamSpec[*].source.tool`. The entry is dead weight — either
|
|
12
|
+
* wire it up or drop it. (Catches the common "agent dropped a
|
|
13
|
+
* reference but left the catalog entry behind" drift.)
|
|
14
|
+
*
|
|
15
|
+
* - `LINT_MISSING_USAGE` — `agentCapabilities.tools[*]` or
|
|
16
|
+
* `clientCapabilities.gadgets[*]` lacks a `usage` field.
|
|
17
|
+
* `usage` is the free-form LLM-targeted prose that bare
|
|
18
|
+
* `description` lacks — when omitted, the agent's reasoning
|
|
19
|
+
* loop loses important context-of-use information.
|
|
20
|
+
*
|
|
21
|
+
* - `LINT_MISSING_EXAMPLE` — `agentCapabilities.tools[*]` lacks an
|
|
22
|
+
* `example`. Examples ground the agent's invocation patterns; a
|
|
23
|
+
* tool without one is harder to use correctly on the first call.
|
|
24
|
+
*
|
|
25
|
+
* - `LINT_GADGET_DUPLICATE_EXPORT` — two `clientCapabilities.gadgets[*]`
|
|
26
|
+
* entries declare the same export name (a `hook` name or a
|
|
27
|
+
* `component` name). The boilerplate generator emits one import
|
|
28
|
+
* per export name; a collision is unresolvable in module scope.
|
|
29
|
+
* Keyed on the export name alone.
|
|
30
|
+
*
|
|
31
|
+
* Gadget lints split by timing into two surfaces:
|
|
32
|
+
*
|
|
33
|
+
* - **Wire-side** ({@link checkHygiene}, input `DataContract`):
|
|
34
|
+
* `checkGadgetHookNames` + `checkDuplicateGadgetHooks`.
|
|
35
|
+
* - **Registry-side** ({@link lintGadgetCatalog}, input
|
|
36
|
+
* `readonly GadgetDescriptor[]`): permission + immutability +
|
|
37
|
+
* duplicate-hook + unscoped-package checks, run at registration
|
|
38
|
+
* time. Some codes are fatal — see {@link FATAL_CATALOG_LINT_CODES}.
|
|
39
|
+
*
|
|
40
|
+
* Pure checks; return violations rather than throwing. The wire-side
|
|
41
|
+
* set is wired into `lintContract` via `phaseHygiene`; consumers that
|
|
42
|
+
* want strict gates layer their own assertions on top.
|
|
43
|
+
*/
|
|
44
|
+
import type { DataContract, GadgetDescriptor } from '../types/data-contract';
|
|
45
|
+
/**
|
|
46
|
+
* Stable codes for hygiene rules. Each is a `LINT_*` rather than a
|
|
47
|
+
* `CTR_*` — the convention: errors are `CTR_*`, warnings are `LINT_*`.
|
|
48
|
+
*
|
|
49
|
+
* The gadget lints split into two timing buckets:
|
|
50
|
+
*
|
|
51
|
+
* - **Wire-side** (run on a `DataContract` by {@link checkHygiene}):
|
|
52
|
+
* `LINT_GADGET_UNKNOWN_HOOK`, `LINT_GADGET_DUPLICATE_EXPORT`.
|
|
53
|
+
* - **Registry-side** (run on an `App.gadgets` catalog at
|
|
54
|
+
* registration time by {@link lintGadgetCatalog}):
|
|
55
|
+
* `LINT_GADGET_MISSING_PERMISSION`, `LINT_GADGET_UNKNOWN_PERMISSION`,
|
|
56
|
+
* `LINT_GADGET_UNSCOPED_PACKAGE`, `LINT_GADGET_IMMUTABLE_MUTATION`,
|
|
57
|
+
* `LINT_GADGET_DUPLICATE_EXPORT_IN_CATALOG`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const LINT_ORPHAN_AGENT_TOOL = "LINT_ORPHAN_AGENT_TOOL";
|
|
60
|
+
export declare const LINT_MISSING_USAGE = "LINT_MISSING_USAGE";
|
|
61
|
+
export declare const LINT_MISSING_EXAMPLE = "LINT_MISSING_EXAMPLE";
|
|
62
|
+
export declare const LINT_GADGET_UNKNOWN_HOOK = "LINT_GADGET_UNKNOWN_HOOK";
|
|
63
|
+
export declare const LINT_GADGET_DUPLICATE_EXPORT = "LINT_GADGET_DUPLICATE_EXPORT";
|
|
64
|
+
export declare const LINT_CONTRACT_RETIRED_FIELD = "LINT_CONTRACT_RETIRED_FIELD";
|
|
65
|
+
export declare const LINT_GADGET_MISSING_PERMISSION = "LINT_GADGET_MISSING_PERMISSION";
|
|
66
|
+
export declare const LINT_GADGET_UNKNOWN_PERMISSION = "LINT_GADGET_UNKNOWN_PERMISSION";
|
|
67
|
+
export declare const LINT_GADGET_UNSCOPED_PACKAGE = "LINT_GADGET_UNSCOPED_PACKAGE";
|
|
68
|
+
export declare const LINT_GADGET_IMMUTABLE_MUTATION = "LINT_GADGET_IMMUTABLE_MUTATION";
|
|
69
|
+
export declare const LINT_GADGET_DUPLICATE_EXPORT_IN_CATALOG = "LINT_GADGET_DUPLICATE_EXPORT_IN_CATALOG";
|
|
70
|
+
export declare const LINT_GADGET_DUPLICATE_PACKAGE = "LINT_GADGET_DUPLICATE_PACKAGE";
|
|
71
|
+
/**
|
|
72
|
+
* Registry-side lint codes that denote a HARD integrity violation —
|
|
73
|
+
* registration handlers MUST reject the catalog (not just warn) when
|
|
74
|
+
* {@link lintGadgetCatalog} emits one of these. The lint function
|
|
75
|
+
* itself stays pure (returns warnings); severity classification is
|
|
76
|
+
* the caller's, so this set is the single source of truth for "which
|
|
77
|
+
* codes are fatal."
|
|
78
|
+
*
|
|
79
|
+
* - `LINT_GADGET_IMMUTABLE_MUTATION` — two descriptors share a
|
|
80
|
+
* `(package, version)` tuple but disagree on `bundleSri`. The
|
|
81
|
+
* same immutable bundle cannot have two hashes; cached blueprints
|
|
82
|
+
* keyed on that version would silently break.
|
|
83
|
+
* - `LINT_GADGET_DUPLICATE_EXPORT_IN_CATALOG` — two descriptors
|
|
84
|
+
* export the same name (a `hook` name or a `component` name). The
|
|
85
|
+
* boilerplate generator emits one
|
|
86
|
+
* `import { <name> } from '<package>'` per export; a name
|
|
87
|
+
* collision in module scope is unresolvable.
|
|
88
|
+
*/
|
|
89
|
+
export declare const FATAL_CATALOG_LINT_CODES: ReadonlySet<string>;
|
|
90
|
+
/**
|
|
91
|
+
* Retired top-level `DataContract` field names. The contract schema
|
|
92
|
+
* is `.passthrough()` at the type system level (forward-compat
|
|
93
|
+
* hedge), but these specific names denote fields that have a known
|
|
94
|
+
* replacement in the current protocol. Carrying one of them is a
|
|
95
|
+
* caller bug — silent pass-through would mask the migration.
|
|
96
|
+
*
|
|
97
|
+
* Replacements (kept here so the lint message can teach the fix):
|
|
98
|
+
* - `libraries` → `clientCapabilities.gadgets`
|
|
99
|
+
* - `dispatch` → `agentCapabilities.tools` + `actionSpec[*].nextStep`
|
|
100
|
+
* - `wiredTools` → `agentCapabilities.tools`
|
|
101
|
+
* - `clientTools` → `clientCapabilities.gadgets`
|
|
102
|
+
* - `broadcast` → `streamSpec[ch].source`
|
|
103
|
+
* - `capabilities` → `agentCapabilities` + `clientCapabilities`
|
|
104
|
+
*
|
|
105
|
+
* Push-gate handlers re-use this list to hard-reject; surfacing it
|
|
106
|
+
* here keeps the wire vocabulary single-sourced.
|
|
107
|
+
*/
|
|
108
|
+
export declare const RETIRED_CONTRACT_FIELDS: Readonly<Record<string, string>>;
|
|
109
|
+
/**
|
|
110
|
+
* Permission strings the Web Permissions API ratifies, plus the
|
|
111
|
+
* MCP Apps `_meta.ui.permissions` enum members for host
|
|
112
|
+
* passthrough.
|
|
113
|
+
*
|
|
114
|
+
* Exported as a tuple + literal-union type so
|
|
115
|
+
* `strictGadgetDescriptorSchema.permission` can use
|
|
116
|
+
* `z.enum(KNOWN_PERMISSION_NAMES)` for a hard reject at parse time:
|
|
117
|
+
* typos (`'geolocaiton'`) and unsupported values fail at the wire
|
|
118
|
+
* boundary instead of being demoted to a soft warning. Forward-compat
|
|
119
|
+
* additions land via a protocol version bump.
|
|
120
|
+
*/
|
|
121
|
+
export declare const KNOWN_PERMISSION_NAMES: readonly ["geolocation", "notifications", "microphone", "camera", "persistent-storage", "midi", "clipboard-read", "clipboard-write", "speaker-selection", "storage-access", "background-sync", "accelerometer", "gyroscope", "magnetometer", "ambient-light-sensor", "screen-wake-lock"];
|
|
122
|
+
export type KnownPermissionName = (typeof KNOWN_PERMISSION_NAMES)[number];
|
|
123
|
+
/**
|
|
124
|
+
* Hygiene-rule warning. Internal — surfaced through `ContractIssue`
|
|
125
|
+
* via the converters in `lint-contract.ts`. Keep the shape minimal:
|
|
126
|
+
* code + path + message + fixHint cover the rendering needs of the
|
|
127
|
+
* authoring tools that consume `lintContract` warnings.
|
|
128
|
+
*/
|
|
129
|
+
export interface HygieneWarning {
|
|
130
|
+
readonly code: string;
|
|
131
|
+
readonly path: string;
|
|
132
|
+
readonly message: string;
|
|
133
|
+
readonly fixHint?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Find agentCapabilities.tools entries that are declared but never
|
|
137
|
+
* referenced from actionSpec or streamSpec. Each orphan is dead
|
|
138
|
+
* weight — either wire it up or drop it from the catalog.
|
|
139
|
+
*/
|
|
140
|
+
export declare function checkOrphanAgentTools(contract: DataContract): HygieneWarning[];
|
|
141
|
+
/**
|
|
142
|
+
* Find `agentCapabilities.tools` entries missing the `usage` field.
|
|
143
|
+
* `usage` is the LLM-targeted "when / why / by-whom" prose; without it
|
|
144
|
+
* the agent's reasoning loop loses context-of-use information.
|
|
145
|
+
*
|
|
146
|
+
* Scope is `agentCapabilities.tools` ONLY. `clientCapabilities.gadgets`
|
|
147
|
+
* is intentionally NOT linted here: `GadgetExportUse.usage` is an
|
|
148
|
+
* OPTIONAL intent-OVERRIDE, and the SPEC-documented canonical wire
|
|
149
|
+
* form is the bare identity reference `gadgets[<pkg>][<export>] = {}`.
|
|
150
|
+
* Push-time resolution inherits the registered descriptor's `usage`,
|
|
151
|
+
* and the registry-side `lintGadgetCatalog` (via
|
|
152
|
+
* `strictGadgetExportSchema`) already enforces real teaching text at
|
|
153
|
+
* registration time. Flagging an empty wire-side use object would
|
|
154
|
+
* false-positive the documented happy path.
|
|
155
|
+
*/
|
|
156
|
+
export declare function checkMissingUsage(contract: DataContract): HygieneWarning[];
|
|
157
|
+
/**
|
|
158
|
+
* Find agentCapabilities.tools entries missing the `example` field.
|
|
159
|
+
* Examples ground the agent's invocation patterns; a tool without
|
|
160
|
+
* one is harder to use correctly on the first call.
|
|
161
|
+
*/
|
|
162
|
+
export declare function checkMissingExample(contract: DataContract): HygieneWarning[];
|
|
163
|
+
/**
|
|
164
|
+
* Wire-side gadget hook-name lint. For every
|
|
165
|
+
* `clientCapabilities.gadgets[*]` whose `package` is the first-party
|
|
166
|
+
* stdlib (`@ggui-ai/gadgets`), the `hook` MUST be one the stdlib
|
|
167
|
+
* actually exports — catches typos (`useGeoLocation`) + stale
|
|
168
|
+
* references against a constant catalog.
|
|
169
|
+
*
|
|
170
|
+
* Third-party packages (any `package !== DEFAULT_GADGET_PACKAGE`) are
|
|
171
|
+
* NOT checked here — the lint can't know an operator's own hook
|
|
172
|
+
* names. The registry-side {@link lintGadgetCatalog} + the push-time
|
|
173
|
+
* {@link assertGadgetsRegistered} gate cover third-party resolution.
|
|
174
|
+
*
|
|
175
|
+
* Permission checks live on the registry-side `lintGadgetCatalog`
|
|
176
|
+
* (the wire gadget reference carries no `permission` field). This
|
|
177
|
+
* function is the pure wire-only residue: a constant-catalog
|
|
178
|
+
* hook-name check.
|
|
179
|
+
*/
|
|
180
|
+
export declare function checkGadgetHookNames(contract: DataContract): HygieneWarning[];
|
|
181
|
+
/**
|
|
182
|
+
* Find `clientCapabilities.gadgets` exports that declare the same
|
|
183
|
+
* export NAME from two different packages.
|
|
184
|
+
*
|
|
185
|
+
* The wire is package-keyed, so the same name cannot repeat WITHIN a
|
|
186
|
+
* package (object-key uniqueness). The hazard is cross-package: two
|
|
187
|
+
* packages each exporting `useCheckout`. The boilerplate generator
|
|
188
|
+
* emits one `import { <name> } from '<package>'` per export; two
|
|
189
|
+
* imports of the same name — from different packages — produce an
|
|
190
|
+
* unresolvable identifier collision in the generated module scope.
|
|
191
|
+
*
|
|
192
|
+
* Keys on the export name alone, matching the push-time hard gate
|
|
193
|
+
* `assertNoDuplicateGadgetHooks`. Soft mirror of that gate so
|
|
194
|
+
* authoring tools surface the issue before a push round-trip.
|
|
195
|
+
*/
|
|
196
|
+
export declare function checkDuplicateGadgetHooks(contract: DataContract): HygieneWarning[];
|
|
197
|
+
/**
|
|
198
|
+
* Registry-side catalog lint — runs on an `App.gadgets` descriptor
|
|
199
|
+
* array at registration time (ggui.json load, `ops_register_gadget`,
|
|
200
|
+
* registry install). Pure function; returns warnings. The caller
|
|
201
|
+
* (registration handler) treats any code in
|
|
202
|
+
* {@link FATAL_CATALOG_LINT_CODES} as a hard reject.
|
|
203
|
+
*
|
|
204
|
+
* Checks:
|
|
205
|
+
*
|
|
206
|
+
* - `LINT_GADGET_DUPLICATE_EXPORT_IN_CATALOG` (fatal) — two
|
|
207
|
+
* descriptors export the same name (a `hook` name or a
|
|
208
|
+
* `component` name). Each export name is unique per app; the
|
|
209
|
+
* boilerplate's per-export import would collide.
|
|
210
|
+
* - `LINT_GADGET_IMMUTABLE_MUTATION` (fatal) — two descriptors
|
|
211
|
+
* carry the same `(package, version)` tuple but different
|
|
212
|
+
* `bundleSri`. The same immutable bundle cannot have two hashes;
|
|
213
|
+
* a cached blueprint pinned to that version would break.
|
|
214
|
+
* - `LINT_GADGET_MISSING_PERMISSION` — a known-permission stdlib
|
|
215
|
+
* hook (geolocation, camera, …) registered without a
|
|
216
|
+
* `permission` field. The agent's reasoning loop reads it to
|
|
217
|
+
* surface "this UI prompts for X."
|
|
218
|
+
* - `LINT_GADGET_UNKNOWN_PERMISSION` — `permission` set to a value
|
|
219
|
+
* outside the Web Permissions API set. (The strict registry
|
|
220
|
+
* schema enum-checks this too; the lint is defence-in-depth for
|
|
221
|
+
* permissively-parsed catalogs.)
|
|
222
|
+
* - `LINT_GADGET_UNSCOPED_PACKAGE` — `package` lacks an `@scope/`
|
|
223
|
+
* prefix. Soft recommendation: scoped names avoid registry
|
|
224
|
+
* squatting + name collisions.
|
|
225
|
+
*/
|
|
226
|
+
export declare function lintGadgetCatalog(descriptors: readonly GadgetDescriptor[]): HygieneWarning[];
|
|
227
|
+
/**
|
|
228
|
+
* Find top-level retired-field carriers on the contract. The schema
|
|
229
|
+
* is `.passthrough()`, so a stray `libraries`/`dispatch`/`wiredTools`/
|
|
230
|
+
* `clientTools`/`broadcast`/`capabilities` slips through silently. The
|
|
231
|
+
* push-gate hard-rejects these (see
|
|
232
|
+
* `mcp-server-handlers/.../assert-contract-no-retired-fields.ts`); this
|
|
233
|
+
* lint surface keeps authoring tools symmetric — show the warning before
|
|
234
|
+
* the push call so the author can fix it without a server round-trip.
|
|
235
|
+
*/
|
|
236
|
+
export declare function checkRetiredContractFields(contract: DataContract): HygieneWarning[];
|
|
237
|
+
/**
|
|
238
|
+
* Run every WIRE-side hygiene rule on a `DataContract`. Aggregates
|
|
239
|
+
* warnings; order is stable (orphans → usage → example → gadget
|
|
240
|
+
* hook-names → duplicate-hook → retired fields) so authoring tools
|
|
241
|
+
* render a predictable checklist.
|
|
242
|
+
*
|
|
243
|
+
* Registry-side gadget lints (`lintGadgetCatalog`) are NOT run here:
|
|
244
|
+
* they need an `App.gadgets` descriptor array, not a contract, and
|
|
245
|
+
* fire at registration time rather than push time.
|
|
246
|
+
* Call {@link lintGadgetCatalog} separately at the registration
|
|
247
|
+
* boundary.
|
|
248
|
+
*/
|
|
249
|
+
export declare function checkHygiene(contract: DataContract): HygieneWarning[];
|
|
250
|
+
//# sourceMappingURL=hygiene-rules.d.ts.map
|
|
@@ -0,0 +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;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,GACrB,cAAc,EAAE,CASlB"}
|