@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,113 @@
|
|
|
1
|
+
import { PROTOCOL_SCHEMA_VERSION } from '../version.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the stamp decision for the three semantic paths. Returns
|
|
4
|
+
* `undefined` when the field should be omitted entirely; returns a
|
|
5
|
+
* string when it should be stamped.
|
|
6
|
+
*/
|
|
7
|
+
function resolveSchemaVersion(parts) {
|
|
8
|
+
if ('schemaVersion' in parts) {
|
|
9
|
+
// Caller wrote the key — trust their decision (string OR explicit
|
|
10
|
+
// undefined-to-omit).
|
|
11
|
+
return parts.schemaVersion;
|
|
12
|
+
}
|
|
13
|
+
// Key absent — default stamp.
|
|
14
|
+
return PROTOCOL_SCHEMA_VERSION;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build an {@link ActionEnvelope} with `schemaVersion` stamped to
|
|
18
|
+
* {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
19
|
+
*
|
|
20
|
+
* Filters `undefined` optional fields so the serialized wire message
|
|
21
|
+
* omits them (matches the producer convention that "absent field =
|
|
22
|
+
* default").
|
|
23
|
+
*/
|
|
24
|
+
export function makeActionEnvelope(parts) {
|
|
25
|
+
const envelope = {
|
|
26
|
+
sessionId: parts.sessionId,
|
|
27
|
+
type: parts.type,
|
|
28
|
+
};
|
|
29
|
+
if (parts.payload !== undefined)
|
|
30
|
+
envelope.payload = parts.payload;
|
|
31
|
+
if (parts.stackIndex !== undefined)
|
|
32
|
+
envelope.stackIndex = parts.stackIndex;
|
|
33
|
+
if (parts.stackItemId !== undefined)
|
|
34
|
+
envelope.stackItemId = parts.stackItemId;
|
|
35
|
+
if (parts.clientSeq !== undefined)
|
|
36
|
+
envelope.clientSeq = parts.clientSeq;
|
|
37
|
+
const stamp = resolveSchemaVersion(parts);
|
|
38
|
+
if (stamp !== undefined)
|
|
39
|
+
envelope.schemaVersion = stamp;
|
|
40
|
+
return envelope;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a {@link StreamEnvelope} with `schemaVersion` stamped to
|
|
44
|
+
* {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
45
|
+
*
|
|
46
|
+
* Filters `undefined` optional fields (`complete`, `seq`) so the
|
|
47
|
+
* serialized wire message omits them. `seq` is server-assigned in
|
|
48
|
+
* practice — callers pass the value the buffer hands them.
|
|
49
|
+
*/
|
|
50
|
+
export function makeStreamEnvelope(parts) {
|
|
51
|
+
const envelope = {
|
|
52
|
+
sessionId: parts.sessionId,
|
|
53
|
+
channel: parts.channel,
|
|
54
|
+
mode: parts.mode,
|
|
55
|
+
payload: parts.payload,
|
|
56
|
+
};
|
|
57
|
+
if (parts.complete !== undefined)
|
|
58
|
+
envelope.complete = parts.complete;
|
|
59
|
+
if (parts.seq !== undefined)
|
|
60
|
+
envelope.seq = parts.seq;
|
|
61
|
+
const stamp = resolveSchemaVersion(parts);
|
|
62
|
+
if (stamp !== undefined)
|
|
63
|
+
envelope.schemaVersion = stamp;
|
|
64
|
+
return envelope;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build an {@link ErrorPayload} for the `{type: 'error'}` wire frame.
|
|
68
|
+
*
|
|
69
|
+
* Does NOT stamp `schemaVersion` — `ErrorPayload` is the wire-level
|
|
70
|
+
* error envelope (free-form `code: string`), not an envelope that
|
|
71
|
+
* opts into the forward-compat stamp (see {@link ActionEnvelope} /
|
|
72
|
+
* {@link StreamEnvelope} / {@link ContractErrorPayload}). Keeping
|
|
73
|
+
* `ErrorPayload` stamp-free preserves byte-equivalence with every
|
|
74
|
+
* existing server-side error emission that pre-dates the central
|
|
75
|
+
* builders.
|
|
76
|
+
*
|
|
77
|
+
* The builder exists so first-party subscribe / handshake paths emit
|
|
78
|
+
* canonical codes (e.g. `UPGRADE_REQUIRED`) via a single helper
|
|
79
|
+
* instead of spreading `{code, message}` object literals. `details`
|
|
80
|
+
* is filtered when `undefined` so the serialized frame matches the
|
|
81
|
+
* pre-builder `{code, message}` shape byte-for-byte.
|
|
82
|
+
*/
|
|
83
|
+
export function makeErrorPayload(parts) {
|
|
84
|
+
const payload = {
|
|
85
|
+
code: parts.code,
|
|
86
|
+
message: parts.message,
|
|
87
|
+
};
|
|
88
|
+
if (parts.details !== undefined)
|
|
89
|
+
payload.details = parts.details;
|
|
90
|
+
return payload;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build a {@link ContractErrorPayload} with `schemaVersion` stamped
|
|
94
|
+
* to {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
95
|
+
*
|
|
96
|
+
* Filters `undefined` optional fields so the emitted payload keeps
|
|
97
|
+
* byte-equivalence with the pre-refactor session-channel router
|
|
98
|
+
* code.
|
|
99
|
+
*/
|
|
100
|
+
export function makeContractErrorPayload(parts) {
|
|
101
|
+
const stamp = resolveSchemaVersion(parts);
|
|
102
|
+
const payload = {
|
|
103
|
+
toolName: parts.toolName,
|
|
104
|
+
error: parts.error,
|
|
105
|
+
timestamp: parts.timestamp,
|
|
106
|
+
...(parts.actionName !== undefined ? { actionName: parts.actionName } : {}),
|
|
107
|
+
...(parts.sourceAction !== undefined
|
|
108
|
+
? { sourceAction: parts.sourceAction }
|
|
109
|
+
: {}),
|
|
110
|
+
...(stamp !== undefined ? { schemaVersion: stamp } : {}),
|
|
111
|
+
};
|
|
112
|
+
return payload;
|
|
113
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface UnknownPermissionNameErrorOptions {
|
|
2
|
+
/** The name the SDK caller passed to `requestPermission`. */
|
|
3
|
+
readonly observedName: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class UnknownPermissionNameError extends Error {
|
|
6
|
+
/** The name the SDK caller passed. */
|
|
7
|
+
readonly observedName: string;
|
|
8
|
+
/** Accepted permission-name enum (Web Permissions API + MCP Apps mirror). */
|
|
9
|
+
readonly acceptedNames: readonly string[];
|
|
10
|
+
constructor(opts: UnknownPermissionNameErrorOptions);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=unknown-permission-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-permission-name.d.ts","sourceRoot":"","sources":["../../src/errors/unknown-permission-name.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,iCAAiC;IAChD,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,sCAAsC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAA0B;gBAEvD,IAAI,EAAE,iCAAiC;CAUpD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error surface for SDK `requestPermission(name)` calls that pass
|
|
3
|
+
* a permission name outside the Web Permissions API enum
|
|
4
|
+
* (`KNOWN_PERMISSION_NAMES`).
|
|
5
|
+
*
|
|
6
|
+
* Background: the grant model lives on
|
|
7
|
+
* `clientCapabilities.gadgets[*].permission`. Without a validation
|
|
8
|
+
* gate, SDK callers (and LLM-generated component code) could request
|
|
9
|
+
* arbitrary permission strings, including typos like `'geolocaiton'`
|
|
10
|
+
* or unsupported names. This error is that gate.
|
|
11
|
+
*
|
|
12
|
+
* The class pins `.name === 'UnknownPermissionNameError'` so consumers
|
|
13
|
+
* can pattern-match without sniffing the message string. Carries the
|
|
14
|
+
* observed name + the accepted enum so operators can diagnose without
|
|
15
|
+
* additional context.
|
|
16
|
+
*/
|
|
17
|
+
import { KNOWN_PERMISSION_NAMES } from '../validation/hygiene-rules.js';
|
|
18
|
+
export class UnknownPermissionNameError extends Error {
|
|
19
|
+
/** The name the SDK caller passed. */
|
|
20
|
+
observedName;
|
|
21
|
+
/** Accepted permission-name enum (Web Permissions API + MCP Apps mirror). */
|
|
22
|
+
acceptedNames = KNOWN_PERMISSION_NAMES;
|
|
23
|
+
constructor(opts) {
|
|
24
|
+
super(`Unknown permission name '${opts.observedName}'. ` +
|
|
25
|
+
`Pick a name from the Web Permissions API enum: [${KNOWN_PERMISSION_NAMES.join(', ')}].`);
|
|
26
|
+
this.name = 'UnknownPermissionNameError';
|
|
27
|
+
this.observedName = opts.observedName;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error surface for the protocol-version handshake.
|
|
3
|
+
*
|
|
4
|
+
* Raised by first-party clients + servers when the handshake observes
|
|
5
|
+
* a version mismatch:
|
|
6
|
+
*
|
|
7
|
+
* - Server side: `SubscribePayload.supportedVersions` is present AND
|
|
8
|
+
* does not contain the server's `PROTOCOL_SCHEMA_VERSION`. The
|
|
9
|
+
* server emits an `{type: 'error'}` frame with `code:
|
|
10
|
+
* UPGRADE_REQUIRED`; first-party servers also surface this class
|
|
11
|
+
* to their own observability path so operators see the
|
|
12
|
+
* unsatisfied subscribe locally.
|
|
13
|
+
* - Client side: on ack receipt, `AckPayload.serverVersion` is
|
|
14
|
+
* present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
|
|
15
|
+
* instantiates this class and surfaces it to the caller via the
|
|
16
|
+
* session's `onError` hook.
|
|
17
|
+
*
|
|
18
|
+
* The class pins `.name === 'UpgradeRequiredError'` and `.code ===
|
|
19
|
+
* UPGRADE_REQUIRED` so consumers can pattern-match without
|
|
20
|
+
* string-sniffing the message — `UPGRADE_REQUIRED` is reachable via
|
|
21
|
+
* a typed protocol-error surface, not just via raw string compares.
|
|
22
|
+
*
|
|
23
|
+
* Wire-shape coupling: the class carries the observed version(s) +
|
|
24
|
+
* the receiver's known-accepted set so operators can diagnose without
|
|
25
|
+
* additional context. The `code` property matches the wire value
|
|
26
|
+
* emitted in `ErrorPayload.code` — symmetric by design.
|
|
27
|
+
*/
|
|
28
|
+
import { UPGRADE_REQUIRED } from '../version.js';
|
|
29
|
+
export interface UpgradeRequiredErrorOptions {
|
|
30
|
+
/**
|
|
31
|
+
* The version the peer declared on the wire. Server-side: the
|
|
32
|
+
* client's `supportedVersions` entry or the full list. Client-side:
|
|
33
|
+
* `AckPayload.serverVersion`.
|
|
34
|
+
*/
|
|
35
|
+
readonly observedVersion?: string | readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* The receiver's accepted-versions set. Server-side: a singleton
|
|
38
|
+
* `[PROTOCOL_SCHEMA_VERSION]`. Client-side: `CLIENT_SUPPORTED_VERSIONS`.
|
|
39
|
+
*/
|
|
40
|
+
readonly acceptedVersions: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Which side observed the mismatch. Server-side emission sets
|
|
43
|
+
* `'server'`; client-side surface sets `'client'`.
|
|
44
|
+
*/
|
|
45
|
+
readonly observedBy: 'server' | 'client';
|
|
46
|
+
}
|
|
47
|
+
export declare class UpgradeRequiredError extends Error {
|
|
48
|
+
/** Canonical `ErrorPayload.code` value. Symmetric with wire shape. */
|
|
49
|
+
readonly code: typeof UPGRADE_REQUIRED;
|
|
50
|
+
readonly observedVersion?: string | readonly string[];
|
|
51
|
+
readonly acceptedVersions: readonly string[];
|
|
52
|
+
readonly observedBy: 'server' | 'client';
|
|
53
|
+
constructor(opts: UpgradeRequiredErrorOptions);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=version-mismatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-mismatch.d.ts","sourceRoot":"","sources":["../../src/errors/version-mismatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC1C;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,gBAAgB,CAAoB;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;gBAE7B,IAAI,EAAE,2BAA2B;CAoB9C"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error surface for the protocol-version handshake.
|
|
3
|
+
*
|
|
4
|
+
* Raised by first-party clients + servers when the handshake observes
|
|
5
|
+
* a version mismatch:
|
|
6
|
+
*
|
|
7
|
+
* - Server side: `SubscribePayload.supportedVersions` is present AND
|
|
8
|
+
* does not contain the server's `PROTOCOL_SCHEMA_VERSION`. The
|
|
9
|
+
* server emits an `{type: 'error'}` frame with `code:
|
|
10
|
+
* UPGRADE_REQUIRED`; first-party servers also surface this class
|
|
11
|
+
* to their own observability path so operators see the
|
|
12
|
+
* unsatisfied subscribe locally.
|
|
13
|
+
* - Client side: on ack receipt, `AckPayload.serverVersion` is
|
|
14
|
+
* present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
|
|
15
|
+
* instantiates this class and surfaces it to the caller via the
|
|
16
|
+
* session's `onError` hook.
|
|
17
|
+
*
|
|
18
|
+
* The class pins `.name === 'UpgradeRequiredError'` and `.code ===
|
|
19
|
+
* UPGRADE_REQUIRED` so consumers can pattern-match without
|
|
20
|
+
* string-sniffing the message — `UPGRADE_REQUIRED` is reachable via
|
|
21
|
+
* a typed protocol-error surface, not just via raw string compares.
|
|
22
|
+
*
|
|
23
|
+
* Wire-shape coupling: the class carries the observed version(s) +
|
|
24
|
+
* the receiver's known-accepted set so operators can diagnose without
|
|
25
|
+
* additional context. The `code` property matches the wire value
|
|
26
|
+
* emitted in `ErrorPayload.code` — symmetric by design.
|
|
27
|
+
*/
|
|
28
|
+
import { UPGRADE_REQUIRED } from '../version.js';
|
|
29
|
+
export class UpgradeRequiredError extends Error {
|
|
30
|
+
/** Canonical `ErrorPayload.code` value. Symmetric with wire shape. */
|
|
31
|
+
code = UPGRADE_REQUIRED;
|
|
32
|
+
observedVersion;
|
|
33
|
+
acceptedVersions;
|
|
34
|
+
observedBy;
|
|
35
|
+
constructor(opts) {
|
|
36
|
+
const observed = opts.observedVersion === undefined
|
|
37
|
+
? 'unknown'
|
|
38
|
+
: Array.isArray(opts.observedVersion)
|
|
39
|
+
? opts.observedVersion.join(', ')
|
|
40
|
+
: String(opts.observedVersion);
|
|
41
|
+
const accepted = opts.acceptedVersions.join(', ');
|
|
42
|
+
super(`UPGRADE_REQUIRED: ${opts.observedBy === 'server' ? 'client' : 'server'} ` +
|
|
43
|
+
`speaks version '${observed}' which is not in the ${opts.observedBy === 'server' ? 'server' : 'client'}'s ` +
|
|
44
|
+
`accepted set [${accepted}].`);
|
|
45
|
+
this.name = 'UpgradeRequiredError';
|
|
46
|
+
if (opts.observedVersion !== undefined) {
|
|
47
|
+
this.observedVersion = opts.observedVersion;
|
|
48
|
+
}
|
|
49
|
+
this.acceptedVersions = opts.acceptedVersions;
|
|
50
|
+
this.observedBy = opts.observedBy;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract → descriptor resolution helpers.
|
|
3
|
+
*
|
|
4
|
+
* The wire side (`contract.clientCapabilities.gadgets`) is
|
|
5
|
+
* PACKAGE-KEYED two-level: `Record<package, Record<exportName, …>>`.
|
|
6
|
+
* It carries identity only — `(package, export name)` — never
|
|
7
|
+
* `version` or transport metadata. The operator's `App.gadgets`
|
|
8
|
+
* catalog owns those; `filterDescriptorsToContract` snapshots the
|
|
9
|
+
* referenced subset onto `SessionStackEntry.gadgetDescriptors` as a
|
|
10
|
+
* sidecar.
|
|
11
|
+
*/
|
|
12
|
+
import type { DataContract, GadgetDescriptor, GadgetExport, GadgetUse } from '../types/data-contract.js';
|
|
13
|
+
/**
|
|
14
|
+
* The export name a {@link GadgetExport} carries — the `hook` field
|
|
15
|
+
* for a hook export, the `component` field for a component export.
|
|
16
|
+
* Discrimination is by field presence; there is no `kind` field. The
|
|
17
|
+
* single accessor so callers never re-spell the field-presence check.
|
|
18
|
+
*
|
|
19
|
+
* Total over the union: it checks BOTH fields explicitly and throws
|
|
20
|
+
* on a malformed member rather than assuming `component` in the else
|
|
21
|
+
* branch (which silently returned `undefined` for a both-fields-
|
|
22
|
+
* absent object). The `GadgetHookExport.component?: never` /
|
|
23
|
+
* `GadgetComponentExport.hook?: never` exclusivity markers (F1) make
|
|
24
|
+
* `hook` / `component` OPTIONAL keys of the opposite member, so `'k' in
|
|
25
|
+
* x` no longer narrows — discrimination is by VALUE presence
|
|
26
|
+
* (`!== undefined`). A future third union member that carries neither
|
|
27
|
+
* field falls through to the throw rather than silently mistyping.
|
|
28
|
+
*
|
|
29
|
+
* Wire-side use records ({@link GadgetUse}) carry the export name as a
|
|
30
|
+
* plain `name` field — no accessor needed there.
|
|
31
|
+
*/
|
|
32
|
+
export declare function gadgetExportName(x: GadgetExport): string;
|
|
33
|
+
/**
|
|
34
|
+
* Canonical string key for a gadget EXPORT's identity —
|
|
35
|
+
* `(name, package)`. Every site that decides "does this wire ref
|
|
36
|
+
* resolve to that registered export?" MUST key through this helper so
|
|
37
|
+
* the resolver and the push-time gates (`assertGadgetsRegistered`,
|
|
38
|
+
* `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
|
|
39
|
+
* gadget export" means.
|
|
40
|
+
*
|
|
41
|
+
* `version` is NOT part of the key — it is not on the wire. An App's
|
|
42
|
+
* `App.gadgets` catalog registers at most one descriptor per package
|
|
43
|
+
* (enforced by the catalog lint), so `(name, package)` resolves to
|
|
44
|
+
* exactly one registered export.
|
|
45
|
+
*
|
|
46
|
+
* The export name is itself kind-disambiguating: `use`-prefixed hook
|
|
47
|
+
* names (`HOOK_NAME_RE`) and PascalCase component names
|
|
48
|
+
* (`COMPONENT_NAME_RE`) are grammar-disjoint, so a hook and a
|
|
49
|
+
* component can never collide on name.
|
|
50
|
+
*
|
|
51
|
+
* Separator `\t`: the hook / component name grammars and
|
|
52
|
+
* `NPM_PACKAGE_NAME_RE` all exclude tab, so no field value can smuggle
|
|
53
|
+
* a separator.
|
|
54
|
+
*/
|
|
55
|
+
export declare function gadgetIdentityKey(use: {
|
|
56
|
+
name: string;
|
|
57
|
+
package: string;
|
|
58
|
+
}): string;
|
|
59
|
+
/**
|
|
60
|
+
* Flatten the package-keyed `contract.clientCapabilities.gadgets` into
|
|
61
|
+
* a list of `(package, name)` use records — one per export the
|
|
62
|
+
* contract references. The single accessor every consumer (push
|
|
63
|
+
* gates, descriptor resolver, code-gen) iterates, so the nested wire
|
|
64
|
+
* shape is walked in exactly one place.
|
|
65
|
+
*
|
|
66
|
+
* Returns an empty array when the contract declares no
|
|
67
|
+
* `clientCapabilities.gadgets`. Pure function. No I/O.
|
|
68
|
+
*/
|
|
69
|
+
export declare function listContractGadgets(contract: DataContract): readonly GadgetUse[];
|
|
70
|
+
/**
|
|
71
|
+
* Given a wire-side {@link DataContract} and the operator's
|
|
72
|
+
* `App.gadgets` catalog, return the subset of package descriptors the
|
|
73
|
+
* contract references via `clientCapabilities.gadgets`.
|
|
74
|
+
*
|
|
75
|
+
* Matching key is the npm PACKAGE name — the wire map's own key. A
|
|
76
|
+
* descriptor IS a package, and `App.gadgets` registers at most one
|
|
77
|
+
* descriptor per package, so a package key resolves to exactly one
|
|
78
|
+
* descriptor. The filtered list lands as a sidecar on
|
|
79
|
+
* `SessionStackEntry.gadgetDescriptors`.
|
|
80
|
+
*
|
|
81
|
+
* Ordering: descriptors appear in the order their package key first
|
|
82
|
+
* appears on `clientCapabilities.gadgets`. A package absent from
|
|
83
|
+
* `appGadgets` is dropped — the push-time `assertGadgetsRegistered`
|
|
84
|
+
* gate rejects the push with a precise registration-mismatch code
|
|
85
|
+
* BEFORE this helper runs, so silent drop here is safe in the happy
|
|
86
|
+
* path.
|
|
87
|
+
*
|
|
88
|
+
* Pure function. No I/O. Returns an empty array when the contract has
|
|
89
|
+
* no `clientCapabilities.gadgets`, `appGadgets` is empty, or no
|
|
90
|
+
* package resolves to a registered descriptor.
|
|
91
|
+
*/
|
|
92
|
+
export declare function filterDescriptorsToContract(contract: DataContract, appGadgets: readonly GadgetDescriptor[]): readonly GadgetDescriptor[];
|
|
93
|
+
//# sourceMappingURL=resolve-contract-gadgets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-contract-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/resolve-contract-gadgets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAET;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GACrB,SAAS,SAAS,EAAE,CAiBtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,gBAAgB,EAAE,GACtC,SAAS,gBAAgB,EAAE,CAiB7B"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The export name a {@link GadgetExport} carries — the `hook` field
|
|
3
|
+
* for a hook export, the `component` field for a component export.
|
|
4
|
+
* Discrimination is by field presence; there is no `kind` field. The
|
|
5
|
+
* single accessor so callers never re-spell the field-presence check.
|
|
6
|
+
*
|
|
7
|
+
* Total over the union: it checks BOTH fields explicitly and throws
|
|
8
|
+
* on a malformed member rather than assuming `component` in the else
|
|
9
|
+
* branch (which silently returned `undefined` for a both-fields-
|
|
10
|
+
* absent object). The `GadgetHookExport.component?: never` /
|
|
11
|
+
* `GadgetComponentExport.hook?: never` exclusivity markers (F1) make
|
|
12
|
+
* `hook` / `component` OPTIONAL keys of the opposite member, so `'k' in
|
|
13
|
+
* x` no longer narrows — discrimination is by VALUE presence
|
|
14
|
+
* (`!== undefined`). A future third union member that carries neither
|
|
15
|
+
* field falls through to the throw rather than silently mistyping.
|
|
16
|
+
*
|
|
17
|
+
* Wire-side use records ({@link GadgetUse}) carry the export name as a
|
|
18
|
+
* plain `name` field — no accessor needed there.
|
|
19
|
+
*/
|
|
20
|
+
export function gadgetExportName(x) {
|
|
21
|
+
if (x.hook !== undefined)
|
|
22
|
+
return x.hook;
|
|
23
|
+
if (x.component !== undefined)
|
|
24
|
+
return x.component;
|
|
25
|
+
throw new Error('gadgetExportName: malformed GadgetExport — neither hook nor component field present');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Canonical string key for a gadget EXPORT's identity —
|
|
29
|
+
* `(name, package)`. Every site that decides "does this wire ref
|
|
30
|
+
* resolve to that registered export?" MUST key through this helper so
|
|
31
|
+
* the resolver and the push-time gates (`assertGadgetsRegistered`,
|
|
32
|
+
* `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
|
|
33
|
+
* gadget export" means.
|
|
34
|
+
*
|
|
35
|
+
* `version` is NOT part of the key — it is not on the wire. An App's
|
|
36
|
+
* `App.gadgets` catalog registers at most one descriptor per package
|
|
37
|
+
* (enforced by the catalog lint), so `(name, package)` resolves to
|
|
38
|
+
* exactly one registered export.
|
|
39
|
+
*
|
|
40
|
+
* The export name is itself kind-disambiguating: `use`-prefixed hook
|
|
41
|
+
* names (`HOOK_NAME_RE`) and PascalCase component names
|
|
42
|
+
* (`COMPONENT_NAME_RE`) are grammar-disjoint, so a hook and a
|
|
43
|
+
* component can never collide on name.
|
|
44
|
+
*
|
|
45
|
+
* Separator `\t`: the hook / component name grammars and
|
|
46
|
+
* `NPM_PACKAGE_NAME_RE` all exclude tab, so no field value can smuggle
|
|
47
|
+
* a separator.
|
|
48
|
+
*/
|
|
49
|
+
export function gadgetIdentityKey(use) {
|
|
50
|
+
return `${use.name}\t${use.package}`;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Flatten the package-keyed `contract.clientCapabilities.gadgets` into
|
|
54
|
+
* a list of `(package, name)` use records — one per export the
|
|
55
|
+
* contract references. The single accessor every consumer (push
|
|
56
|
+
* gates, descriptor resolver, code-gen) iterates, so the nested wire
|
|
57
|
+
* shape is walked in exactly one place.
|
|
58
|
+
*
|
|
59
|
+
* Returns an empty array when the contract declares no
|
|
60
|
+
* `clientCapabilities.gadgets`. Pure function. No I/O.
|
|
61
|
+
*/
|
|
62
|
+
export function listContractGadgets(contract) {
|
|
63
|
+
const declared = contract.clientCapabilities?.gadgets;
|
|
64
|
+
if (!declared)
|
|
65
|
+
return [];
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const [pkg, exports] of Object.entries(declared)) {
|
|
68
|
+
for (const [name, meta] of Object.entries(exports)) {
|
|
69
|
+
out.push({
|
|
70
|
+
package: pkg,
|
|
71
|
+
name,
|
|
72
|
+
...(meta.description !== undefined
|
|
73
|
+
? { description: meta.description }
|
|
74
|
+
: {}),
|
|
75
|
+
...(meta.usage !== undefined ? { usage: meta.usage } : {}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Given a wire-side {@link DataContract} and the operator's
|
|
83
|
+
* `App.gadgets` catalog, return the subset of package descriptors the
|
|
84
|
+
* contract references via `clientCapabilities.gadgets`.
|
|
85
|
+
*
|
|
86
|
+
* Matching key is the npm PACKAGE name — the wire map's own key. A
|
|
87
|
+
* descriptor IS a package, and `App.gadgets` registers at most one
|
|
88
|
+
* descriptor per package, so a package key resolves to exactly one
|
|
89
|
+
* descriptor. The filtered list lands as a sidecar on
|
|
90
|
+
* `SessionStackEntry.gadgetDescriptors`.
|
|
91
|
+
*
|
|
92
|
+
* Ordering: descriptors appear in the order their package key first
|
|
93
|
+
* appears on `clientCapabilities.gadgets`. A package absent from
|
|
94
|
+
* `appGadgets` is dropped — the push-time `assertGadgetsRegistered`
|
|
95
|
+
* gate rejects the push with a precise registration-mismatch code
|
|
96
|
+
* BEFORE this helper runs, so silent drop here is safe in the happy
|
|
97
|
+
* path.
|
|
98
|
+
*
|
|
99
|
+
* Pure function. No I/O. Returns an empty array when the contract has
|
|
100
|
+
* no `clientCapabilities.gadgets`, `appGadgets` is empty, or no
|
|
101
|
+
* package resolves to a registered descriptor.
|
|
102
|
+
*/
|
|
103
|
+
export function filterDescriptorsToContract(contract, appGadgets) {
|
|
104
|
+
const declared = contract.clientCapabilities?.gadgets;
|
|
105
|
+
if (!declared || appGadgets.length === 0) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
const byPackage = new Map();
|
|
109
|
+
for (const descriptor of appGadgets) {
|
|
110
|
+
byPackage.set(descriptor.package, descriptor);
|
|
111
|
+
}
|
|
112
|
+
const out = [];
|
|
113
|
+
for (const pkg of Object.keys(declared)) {
|
|
114
|
+
const descriptor = byPackage.get(pkg);
|
|
115
|
+
if (descriptor)
|
|
116
|
+
out.push(descriptor);
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { GadgetDescriptor } from '../types/data-contract';
|
|
2
|
+
/**
|
|
3
|
+
* The first-party `@ggui-ai/gadgets` package name. Used as
|
|
4
|
+
* the default `package` for every entry in {@link STDLIB_GADGETS}
|
|
5
|
+
* and as the `DEFAULT_GADGET_PACKAGE` literal in the hygiene linter.
|
|
6
|
+
*/
|
|
7
|
+
export declare const STDLIB_GADGETS_PACKAGE = "@ggui-ai/gadgets";
|
|
8
|
+
/**
|
|
9
|
+
* Pinned semver of the stdlib gadgets every descriptor declares on
|
|
10
|
+
* its `version` field. Mirrors
|
|
11
|
+
* `packages/gadgets/package.json#version`; a cross-package parity test
|
|
12
|
+
* in `@ggui-ai/gadgets` asserts the two stay in sync, so a release-time
|
|
13
|
+
* bump to the runtime package without updating this constant fails CI.
|
|
14
|
+
*/
|
|
15
|
+
export declare const STDLIB_GADGETS_VERSION = "0.1.0-rc.1";
|
|
16
|
+
/**
|
|
17
|
+
* v1 catalog of stdlib gadget descriptors. Every entry's
|
|
18
|
+
* `package` defaults to {@link STDLIB_GADGETS_PACKAGE}; the
|
|
19
|
+
* `permission` field, where present, mirrors the Web Permissions API
|
|
20
|
+
* name and lines up with the hygiene linter's
|
|
21
|
+
* `KNOWN_PERMISSION_HOOKS` table.
|
|
22
|
+
*
|
|
23
|
+
* **Ordering:** alphabetical by hook name. Stable so consumers can
|
|
24
|
+
* diff the list across protocol minor bumps without false positives
|
|
25
|
+
* from re-ordering.
|
|
26
|
+
*
|
|
27
|
+
* **Shape note:** entries are typed `Readonly<GadgetDescriptor>` so
|
|
28
|
+
* downstream consumers (App.gadgets default-on-read, the LLM
|
|
29
|
+
* generator's catalog, the `ggui_list_gadgets` handler)
|
|
30
|
+
* can structurally clone without mutating the source. Callers that
|
|
31
|
+
* need a mutable copy should `structuredClone` explicitly.
|
|
32
|
+
*/
|
|
33
|
+
export declare const STDLIB_GADGETS: readonly Readonly<GadgetDescriptor>[];
|
|
34
|
+
/**
|
|
35
|
+
* Hook-name index over {@link STDLIB_GADGETS}. Lazily
|
|
36
|
+
* constructed for callers that need O(1) "is hook X part of the
|
|
37
|
+
* stdlib?" checks (the hygiene linter, the per-app gadget validator,
|
|
38
|
+
* the `ggui_list_gadgets` handler).
|
|
39
|
+
*
|
|
40
|
+
* Frozen so accidental mutation is loud, not silent.
|
|
41
|
+
*/
|
|
42
|
+
export declare const STDLIB_GADGET_HOOKS: ReadonlySet<string>;
|
|
43
|
+
//# sourceMappingURL=stdlib-gadgets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdlib-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/stdlib-gadgets.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,QAAQ,CAAC,gBAAgB,CAAC,EA+F/D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAUnD,CAAC"}
|