@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
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ggui-ai/protocol
|
|
2
2
|
|
|
3
|
-
TypeScript source of truth for the ggui protocol — the open wire format between agents and generated user interfaces. Ships the envelope types (`ActionEnvelope`, `StreamEnvelope
|
|
3
|
+
TypeScript source of truth for the ggui protocol — the open wire format between agents and generated user interfaces. Ships the envelope types (`ActionEnvelope`, `StreamEnvelope`), the canonical error-frame codes, the WebSocket + MCP transport bindings, and the DTCG design-token contract.
|
|
4
4
|
|
|
5
5
|
The full normative spec lives at [docs.ggui.ai](https://docs.ggui.ai). This package is what an implementer actually imports.
|
|
6
6
|
|
|
@@ -17,13 +17,13 @@ Here is what happens when a user clicks "Add" on a generated todo UI:
|
|
|
17
17
|
1. **LLM wrote the hook** — `const addTodo = useAction('addTodo');` bound to the button's `onClick`.
|
|
18
18
|
2. **User clicks** — React fires `onClick`, which calls `addTodo(data)`.
|
|
19
19
|
3. **Hook dispatches** — `useAction` (from `@ggui-ai/wire`) sends an `ActionEnvelope` on the live channel.
|
|
20
|
-
4. **WS transport** — the server receives the envelope on the
|
|
21
|
-
5. **
|
|
22
|
-
6. **
|
|
23
|
-
7. **
|
|
24
|
-
8. **UI absorbs the update** — the component's `useStream` callback
|
|
20
|
+
4. **WS transport** — the server receives the envelope on the GguiSession's live-channel WebSocket.
|
|
21
|
+
5. **Server persists a consume event** — the validated envelope is appended to the session's event ledger, stamped with an advisory `tool` hint derived server-side from `actionSpec.addTodo.nextStep === 'todo.add'`.
|
|
22
|
+
6. **Agent consumes** — the agent drains the event via `ggui_consume` on its next turn and calls `todo.add` itself. Actions drive agent turns; no client-side tool dispatch.
|
|
23
|
+
7. **Agent pushes the update** — the agent's update travels back to the UI on the live channel (`props_update`, or a `StreamEnvelope` on a declared stream channel).
|
|
24
|
+
8. **UI absorbs the update** — props or the component's `useStream` callback update state, no regeneration.
|
|
25
25
|
|
|
26
|
-
**No SDK glue.** Every step has a named, typed enforcement layer — schema-subset check at push time, `
|
|
26
|
+
**No SDK glue.** Every step has a named, typed enforcement layer — schema-subset check at push time, `CONTRACT_VIOLATION` error frames on the live channel at runtime, `@ggui-ai/protocol-conformance` at CI time, TypeScript narrowing at author time. Nothing about this pipeline assumes a specific SDK: a third-party implementer honoring the envelope + channel contracts inherits all four enforcement tiers for free.
|
|
27
27
|
|
|
28
28
|
## Implementer guide
|
|
29
29
|
|
|
@@ -31,15 +31,15 @@ Building a third-party MCP host that renders ggui UIs, a non-React viewer, or an
|
|
|
31
31
|
|
|
32
32
|
## What this package exports
|
|
33
33
|
|
|
34
|
-
| Surface | What it is
|
|
35
|
-
| ------------------------------------------- |
|
|
36
|
-
| `@ggui-ai/protocol` | Root barrel — envelope types, `
|
|
37
|
-
| `@ggui-ai/protocol/content-hash` | Deterministic hashing for cache keys
|
|
38
|
-
| `@ggui-ai/protocol/blueprint-key` | Server-only blueprint cache-key derivation (uses `node:crypto`)
|
|
39
|
-
| `@ggui-ai/protocol/transport/websocket` | Live-channel WS binding — subscribe / ack / resume types
|
|
40
|
-
| `@ggui-ai/protocol/integrations/mcp-apps` | MCP Apps host integration types — bootstrap + lifecycle protocol
|
|
41
|
-
| `@ggui-ai/protocol/version` | Protocol version constant + negotiation helpers
|
|
42
|
-
| `@ggui-ai/protocol/errors/version-mismatch` | Typed error for version-negotiation failures
|
|
34
|
+
| Surface | What it is |
|
|
35
|
+
| ------------------------------------------- | ------------------------------------------------------------------ |
|
|
36
|
+
| `@ggui-ai/protocol` | Root barrel — envelope types, `GguiSession`, `StreamSpec`, actions |
|
|
37
|
+
| `@ggui-ai/protocol/content-hash` | Deterministic hashing for cache keys |
|
|
38
|
+
| `@ggui-ai/protocol/blueprint-key` | Server-only blueprint cache-key derivation (uses `node:crypto`) |
|
|
39
|
+
| `@ggui-ai/protocol/transport/websocket` | Live-channel WS binding — subscribe / ack / resume types |
|
|
40
|
+
| `@ggui-ai/protocol/integrations/mcp-apps` | MCP Apps host integration types — bootstrap + lifecycle protocol |
|
|
41
|
+
| `@ggui-ai/protocol/version` | Protocol version constant + negotiation helpers |
|
|
42
|
+
| `@ggui-ai/protocol/errors/version-mismatch` | Typed error for version-negotiation failures |
|
|
43
43
|
|
|
44
44
|
## License
|
|
45
45
|
|
|
@@ -7,15 +7,16 @@
|
|
|
7
7
|
*
|
|
8
8
|
* The only bounded adapter that lives here now is
|
|
9
9
|
* {@link parsePendingEnvelope} — a shape-neutral reader for stored
|
|
10
|
-
* `PendingEvent.envelope` values that may arrive as raw objects
|
|
11
|
-
*
|
|
10
|
+
* `PendingEvent.envelope` values that may arrive as raw objects or as
|
|
11
|
+
* JSON strings, depending on how the deployment's storage layer
|
|
12
|
+
* serializes rows.
|
|
12
13
|
*/
|
|
13
14
|
import type { ConsumeEventEntry } from './types/mcp';
|
|
14
15
|
/**
|
|
15
16
|
* Parse a {@link PendingEvent.envelope} that may arrive as either a raw
|
|
16
|
-
* object
|
|
17
|
-
*
|
|
18
|
-
* already an object.
|
|
17
|
+
* object or a JSON-stringified object, depending on how the
|
|
18
|
+
* deployment's storage layer serializes rows. Returns the parsed entry
|
|
19
|
+
* unchanged when already an object.
|
|
19
20
|
*
|
|
20
21
|
* Throws `SyntaxError` when a string input is malformed JSON. Does NOT
|
|
21
22
|
* validate the entry shape — that's the caller's job.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope-adapters.d.ts","sourceRoot":"","sources":["../src/envelope-adapters.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"envelope-adapters.d.ts","sourceRoot":"","sources":["../src/envelope-adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GACjC,iBAAiB,CAGnB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parse a {@link PendingEvent.envelope} that may arrive as either a raw
|
|
3
|
-
* object
|
|
4
|
-
*
|
|
5
|
-
* already an object.
|
|
3
|
+
* object or a JSON-stringified object, depending on how the
|
|
4
|
+
* deployment's storage layer serializes rows. Returns the parsed entry
|
|
5
|
+
* unchanged when already an object.
|
|
6
6
|
*
|
|
7
7
|
* Throws `SyntaxError` when a string input is malformed JSON. Does NOT
|
|
8
8
|
* validate the entry shape — that's the caller's job.
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* **Why centralize.** The `schemaVersion` forward-compat stamp is
|
|
6
6
|
* emitted from many producer sites (wire helper, React-SDK emit
|
|
7
|
-
* paths, OSS in-memory stream buffer,
|
|
8
|
-
*
|
|
7
|
+
* paths, OSS in-memory stream buffer, hosted server paths).
|
|
8
|
+
* Spreading stamp logic across N sites
|
|
9
9
|
* causes drift — producers silently skip the stamp. These builders
|
|
10
10
|
* remove the drift surface by giving every producer a single function
|
|
11
11
|
* to call; the default stamp happens inside the builder.
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
*/
|
|
47
47
|
import type { ActionEnvelope, EventType } from '../types/events.js';
|
|
48
48
|
import type { ErrorPayload, StreamEnvelope } from '../types/live-channel.js';
|
|
49
|
-
import type {
|
|
49
|
+
import type { JsonValue, StreamChannelMode } from '../types/data-contract.js';
|
|
50
50
|
/** Input type for {@link makeActionEnvelope}. */
|
|
51
51
|
export interface MakeActionEnvelopeInput<TPayload = JsonValue> {
|
|
52
|
-
readonly
|
|
52
|
+
readonly sessionId: string;
|
|
53
53
|
readonly type: EventType;
|
|
54
54
|
readonly payload?: TPayload;
|
|
55
55
|
readonly clientSeq?: number;
|
|
@@ -63,7 +63,7 @@ export interface MakeActionEnvelopeInput<TPayload = JsonValue> {
|
|
|
63
63
|
}
|
|
64
64
|
/** Input type for {@link makeStreamEnvelope}. */
|
|
65
65
|
export interface MakeStreamEnvelopeInput {
|
|
66
|
-
readonly
|
|
66
|
+
readonly sessionId: string;
|
|
67
67
|
readonly channel: string;
|
|
68
68
|
readonly mode: StreamChannelMode;
|
|
69
69
|
readonly payload: JsonValue;
|
|
@@ -78,23 +78,6 @@ export interface MakeErrorPayloadInput {
|
|
|
78
78
|
readonly message: string;
|
|
79
79
|
readonly details?: JsonValue;
|
|
80
80
|
}
|
|
81
|
-
/** Input type for {@link makeContractErrorPayload}. */
|
|
82
|
-
export interface MakeContractErrorPayloadInput {
|
|
83
|
-
readonly toolName: string;
|
|
84
|
-
readonly actionName?: string;
|
|
85
|
-
readonly sourceAction?: {
|
|
86
|
-
readonly type: 'wired-action' | 'refresh-stream' | (string & {});
|
|
87
|
-
readonly dispatchedAt: string;
|
|
88
|
-
};
|
|
89
|
-
readonly error: {
|
|
90
|
-
readonly code: ContractErrorCode;
|
|
91
|
-
readonly message: string;
|
|
92
|
-
readonly causedBy?: string;
|
|
93
|
-
};
|
|
94
|
-
readonly timestamp: string;
|
|
95
|
-
/** See {@link MakeActionEnvelopeInput.schemaVersion}. */
|
|
96
|
-
readonly schemaVersion?: string;
|
|
97
|
-
}
|
|
98
81
|
/**
|
|
99
82
|
* Build an {@link ActionEnvelope} with `schemaVersion` stamped to
|
|
100
83
|
* {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
@@ -119,7 +102,7 @@ export declare function makeStreamEnvelope(parts: MakeStreamEnvelopeInput): Stre
|
|
|
119
102
|
* Does NOT stamp `schemaVersion` — `ErrorPayload` is the wire-level
|
|
120
103
|
* error envelope (free-form `code: string`), not an envelope that
|
|
121
104
|
* opts into the forward-compat stamp (see {@link ActionEnvelope} /
|
|
122
|
-
* {@link StreamEnvelope}
|
|
105
|
+
* {@link StreamEnvelope}). Keeping
|
|
123
106
|
* `ErrorPayload` stamp-free preserves byte-equivalence with every
|
|
124
107
|
* existing server-side error emission that pre-dates the central
|
|
125
108
|
* builders.
|
|
@@ -131,13 +114,4 @@ export declare function makeStreamEnvelope(parts: MakeStreamEnvelopeInput): Stre
|
|
|
131
114
|
* pre-builder `{code, message}` shape byte-for-byte.
|
|
132
115
|
*/
|
|
133
116
|
export declare function makeErrorPayload(parts: MakeErrorPayloadInput): ErrorPayload;
|
|
134
|
-
/**
|
|
135
|
-
* Build a {@link ContractErrorPayload} with `schemaVersion` stamped
|
|
136
|
-
* to {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
137
|
-
*
|
|
138
|
-
* Filters `undefined` optional fields so the emitted payload keeps
|
|
139
|
-
* byte-equivalence with the pre-refactor session-channel router
|
|
140
|
-
* code.
|
|
141
|
-
*/
|
|
142
|
-
export declare function makeContractErrorPayload(parts: MakeContractErrorPayloadInput): ContractErrorPayload;
|
|
143
117
|
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../src/envelopes/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../src/envelopes/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9E,iDAAiD;AACjD,MAAM,WAAW,uBAAuB,CAAC,QAAQ,GAAG,SAAS;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;CAC9B;AAmBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAG,SAAS,EACrD,KAAK,EAAE,uBAAuB,CAAC,QAAQ,CAAC,GACvC,cAAc,CAAC,QAAQ,CAAC,CAU1B;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,cAAc,CAYhB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAO3E"}
|
|
@@ -23,7 +23,7 @@ function resolveSchemaVersion(parts) {
|
|
|
23
23
|
*/
|
|
24
24
|
export function makeActionEnvelope(parts) {
|
|
25
25
|
const envelope = {
|
|
26
|
-
|
|
26
|
+
sessionId: parts.sessionId,
|
|
27
27
|
type: parts.type,
|
|
28
28
|
};
|
|
29
29
|
if (parts.payload !== undefined)
|
|
@@ -45,7 +45,7 @@ export function makeActionEnvelope(parts) {
|
|
|
45
45
|
*/
|
|
46
46
|
export function makeStreamEnvelope(parts) {
|
|
47
47
|
const envelope = {
|
|
48
|
-
|
|
48
|
+
sessionId: parts.sessionId,
|
|
49
49
|
channel: parts.channel,
|
|
50
50
|
mode: parts.mode,
|
|
51
51
|
payload: parts.payload,
|
|
@@ -65,7 +65,7 @@ export function makeStreamEnvelope(parts) {
|
|
|
65
65
|
* Does NOT stamp `schemaVersion` — `ErrorPayload` is the wire-level
|
|
66
66
|
* error envelope (free-form `code: string`), not an envelope that
|
|
67
67
|
* opts into the forward-compat stamp (see {@link ActionEnvelope} /
|
|
68
|
-
* {@link StreamEnvelope}
|
|
68
|
+
* {@link StreamEnvelope}). Keeping
|
|
69
69
|
* `ErrorPayload` stamp-free preserves byte-equivalence with every
|
|
70
70
|
* existing server-side error emission that pre-dates the central
|
|
71
71
|
* builders.
|
|
@@ -85,25 +85,3 @@ export function makeErrorPayload(parts) {
|
|
|
85
85
|
payload.details = parts.details;
|
|
86
86
|
return payload;
|
|
87
87
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Build a {@link ContractErrorPayload} with `schemaVersion` stamped
|
|
90
|
-
* to {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
|
|
91
|
-
*
|
|
92
|
-
* Filters `undefined` optional fields so the emitted payload keeps
|
|
93
|
-
* byte-equivalence with the pre-refactor session-channel router
|
|
94
|
-
* code.
|
|
95
|
-
*/
|
|
96
|
-
export function makeContractErrorPayload(parts) {
|
|
97
|
-
const stamp = resolveSchemaVersion(parts);
|
|
98
|
-
const payload = {
|
|
99
|
-
toolName: parts.toolName,
|
|
100
|
-
error: parts.error,
|
|
101
|
-
timestamp: parts.timestamp,
|
|
102
|
-
...(parts.actionName !== undefined ? { actionName: parts.actionName } : {}),
|
|
103
|
-
...(parts.sourceAction !== undefined
|
|
104
|
-
? { sourceAction: parts.sourceAction }
|
|
105
|
-
: {}),
|
|
106
|
-
...(stamp !== undefined ? { schemaVersion: stamp } : {}),
|
|
107
|
-
};
|
|
108
|
-
return payload;
|
|
109
|
-
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - Client side: on ack receipt, `AckPayload.serverVersion` is
|
|
14
14
|
* present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
|
|
15
15
|
* instantiates this class and surfaces it to the caller via the
|
|
16
|
-
*
|
|
16
|
+
* render's `onError` hook.
|
|
17
17
|
*
|
|
18
18
|
* The class pins `.name === 'UpgradeRequiredError'` and `.code ===
|
|
19
19
|
* UPGRADE_REQUIRED` so consumers can pattern-match without
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - Client side: on ack receipt, `AckPayload.serverVersion` is
|
|
14
14
|
* present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
|
|
15
15
|
* instantiates this class and surfaces it to the caller via the
|
|
16
|
-
*
|
|
16
|
+
* render's `onError` hook.
|
|
17
17
|
*
|
|
18
18
|
* The class pins `.name === 'UpgradeRequiredError'` and `.code ===
|
|
19
19
|
* UPGRADE_REQUIRED` so consumers can pattern-match without
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GadgetDescriptor } from '../types/data-contract';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve an app's effective gadget set: the first-party stdlib package is the
|
|
4
|
+
* structural FLOOR, and `declared` (app-declared extensions) layers on top.
|
|
5
|
+
* Replaces the legacy fallback-when-absent resolution that dropped the stdlib
|
|
6
|
+
* package the moment an app declared any extension. `declared` wins on a
|
|
7
|
+
* `package` collision; absent/empty ⇒ exactly the stdlib set; idempotent.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveAppGadgets(declared?: readonly GadgetDescriptor[] | null): readonly GadgetDescriptor[];
|
|
10
|
+
//# sourceMappingURL=resolve-app-gadgets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-app-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/resolve-app-gadgets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO/D;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,GAC5C,SAAS,gBAAgB,EAAE,CAG7B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { STDLIB_GADGETS } from './stdlib-gadgets.js';
|
|
2
|
+
function dedupeByPackage(list) {
|
|
3
|
+
const m = new Map();
|
|
4
|
+
for (const g of list)
|
|
5
|
+
m.set(g.package, g);
|
|
6
|
+
return [...m.values()];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Resolve an app's effective gadget set: the first-party stdlib package is the
|
|
10
|
+
* structural FLOOR, and `declared` (app-declared extensions) layers on top.
|
|
11
|
+
* Replaces the legacy fallback-when-absent resolution that dropped the stdlib
|
|
12
|
+
* package the moment an app declared any extension. `declared` wins on a
|
|
13
|
+
* `package` collision; absent/empty ⇒ exactly the stdlib set; idempotent.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveAppGadgets(declared) {
|
|
16
|
+
if (!declared || declared.length === 0)
|
|
17
|
+
return STDLIB_GADGETS;
|
|
18
|
+
return dedupeByPackage([...STDLIB_GADGETS, ...declared]);
|
|
19
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* It carries identity only — `(package, export name)` — never
|
|
7
7
|
* `version` or transport metadata. The operator's `App.gadgets`
|
|
8
8
|
* catalog owns those; `filterDescriptorsToContract` snapshots the
|
|
9
|
-
* referenced subset onto `
|
|
9
|
+
* referenced subset onto `ComponentGguiSession.gadgetDescriptors` as a
|
|
10
10
|
* sidecar.
|
|
11
11
|
*/
|
|
12
12
|
import type { DataContract, GadgetDescriptor, GadgetExport, GadgetUse } from '../types/data-contract.js';
|
|
@@ -34,7 +34,7 @@ export declare function gadgetExportName(x: GadgetExport): string;
|
|
|
34
34
|
* Canonical string key for a gadget EXPORT's identity —
|
|
35
35
|
* `(name, package)`. Every site that decides "does this wire ref
|
|
36
36
|
* resolve to that registered export?" MUST key through this helper so
|
|
37
|
-
* the resolver and the
|
|
37
|
+
* the resolver and the render-time gates (`assertGadgetsRegistered`,
|
|
38
38
|
* `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
|
|
39
39
|
* gadget export" means.
|
|
40
40
|
*
|
|
@@ -59,7 +59,7 @@ export declare function gadgetIdentityKey(use: {
|
|
|
59
59
|
/**
|
|
60
60
|
* Flatten the package-keyed `contract.clientCapabilities.gadgets` into
|
|
61
61
|
* a list of `(package, name)` use records — one per export the
|
|
62
|
-
* contract references. The single accessor every consumer (
|
|
62
|
+
* contract references. The single accessor every consumer (render
|
|
63
63
|
* gates, descriptor resolver, code-gen) iterates, so the nested wire
|
|
64
64
|
* shape is walked in exactly one place.
|
|
65
65
|
*
|
|
@@ -76,12 +76,12 @@ export declare function listContractGadgets(contract: DataContract): readonly Ga
|
|
|
76
76
|
* descriptor IS a package, and `App.gadgets` registers at most one
|
|
77
77
|
* descriptor per package, so a package key resolves to exactly one
|
|
78
78
|
* descriptor. The filtered list lands as a sidecar on
|
|
79
|
-
* `
|
|
79
|
+
* `ComponentGguiSession.gadgetDescriptors`.
|
|
80
80
|
*
|
|
81
81
|
* Ordering: descriptors appear in the order their package key first
|
|
82
82
|
* appears on `clientCapabilities.gadgets`. A package absent from
|
|
83
|
-
* `appGadgets` is dropped — the
|
|
84
|
-
* gate rejects the
|
|
83
|
+
* `appGadgets` is dropped — the render-time `assertGadgetsRegistered`
|
|
84
|
+
* gate rejects the render with a precise registration-mismatch code
|
|
85
85
|
* BEFORE this helper runs, so silent drop here is safe in the happy
|
|
86
86
|
* path.
|
|
87
87
|
*
|
|
@@ -28,7 +28,7 @@ export function gadgetExportName(x) {
|
|
|
28
28
|
* Canonical string key for a gadget EXPORT's identity —
|
|
29
29
|
* `(name, package)`. Every site that decides "does this wire ref
|
|
30
30
|
* resolve to that registered export?" MUST key through this helper so
|
|
31
|
-
* the resolver and the
|
|
31
|
+
* the resolver and the render-time gates (`assertGadgetsRegistered`,
|
|
32
32
|
* `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
|
|
33
33
|
* gadget export" means.
|
|
34
34
|
*
|
|
@@ -52,7 +52,7 @@ export function gadgetIdentityKey(use) {
|
|
|
52
52
|
/**
|
|
53
53
|
* Flatten the package-keyed `contract.clientCapabilities.gadgets` into
|
|
54
54
|
* a list of `(package, name)` use records — one per export the
|
|
55
|
-
* contract references. The single accessor every consumer (
|
|
55
|
+
* contract references. The single accessor every consumer (render
|
|
56
56
|
* gates, descriptor resolver, code-gen) iterates, so the nested wire
|
|
57
57
|
* shape is walked in exactly one place.
|
|
58
58
|
*
|
|
@@ -87,12 +87,12 @@ export function listContractGadgets(contract) {
|
|
|
87
87
|
* descriptor IS a package, and `App.gadgets` registers at most one
|
|
88
88
|
* descriptor per package, so a package key resolves to exactly one
|
|
89
89
|
* descriptor. The filtered list lands as a sidecar on
|
|
90
|
-
* `
|
|
90
|
+
* `ComponentGguiSession.gadgetDescriptors`.
|
|
91
91
|
*
|
|
92
92
|
* Ordering: descriptors appear in the order their package key first
|
|
93
93
|
* appears on `clientCapabilities.gadgets`. A package absent from
|
|
94
|
-
* `appGadgets` is dropped — the
|
|
95
|
-
* gate rejects the
|
|
94
|
+
* `appGadgets` is dropped — the render-time `assertGadgetsRegistered`
|
|
95
|
+
* gate rejects the render with a precise registration-mismatch code
|
|
96
96
|
* BEFORE this helper runs, so silent drop here is safe in the happy
|
|
97
97
|
* path.
|
|
98
98
|
*
|
|
@@ -12,7 +12,7 @@ export declare const STDLIB_GADGETS_PACKAGE = "@ggui-ai/gadgets";
|
|
|
12
12
|
* in `@ggui-ai/gadgets` asserts the two stay in sync, so a release-time
|
|
13
13
|
* bump to the runtime package without updating this constant fails CI.
|
|
14
14
|
*/
|
|
15
|
-
export declare const STDLIB_GADGETS_VERSION = "0.
|
|
15
|
+
export declare const STDLIB_GADGETS_VERSION = "0.3.0";
|
|
16
16
|
/**
|
|
17
17
|
* v1 catalog of stdlib gadget descriptors. Every entry's
|
|
18
18
|
* `package` defaults to {@link STDLIB_GADGETS_PACKAGE}; the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdlib-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/stdlib-gadgets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stdlib-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/stdlib-gadgets.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,QAAQ,CAAC,gBAAgB,CAAC,EAkH/D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAUnD,CAAC"}
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
// **Parity guarantee:** `@ggui-ai/gadgets` ships a cross-
|
|
22
22
|
// package contract test (`stdlib-parity.test.ts`) that imports both
|
|
23
23
|
// this list and the actual hook exports, then asserts the hook names
|
|
24
|
-
// match exactly
|
|
25
|
-
//
|
|
26
|
-
//
|
|
24
|
+
// match exactly AND that every `example` block sticks to the real
|
|
25
|
+
// `GadgetHook` contract (statuses from the `GadgetStatus` union,
|
|
26
|
+
// `start()`/`stop()` as the only invokable methods). Drift fails the
|
|
27
|
+
// test on CI; the protocol package cannot ship a stale descriptor
|
|
28
|
+
// list without the runtime side catching it.
|
|
27
29
|
/**
|
|
28
30
|
* The first-party `@ggui-ai/gadgets` package name. Used as
|
|
29
31
|
* the default `package` for every entry in {@link STDLIB_GADGETS}
|
|
@@ -37,7 +39,7 @@ export const STDLIB_GADGETS_PACKAGE = '@ggui-ai/gadgets';
|
|
|
37
39
|
* in `@ggui-ai/gadgets` asserts the two stay in sync, so a release-time
|
|
38
40
|
* bump to the runtime package without updating this constant fails CI.
|
|
39
41
|
*/
|
|
40
|
-
export const STDLIB_GADGETS_VERSION = '0.
|
|
42
|
+
export const STDLIB_GADGETS_VERSION = '0.3.0';
|
|
41
43
|
/**
|
|
42
44
|
* v1 catalog of stdlib gadget descriptors. Every entry's
|
|
43
45
|
* `package` defaults to {@link STDLIB_GADGETS_PACKAGE}; the
|
|
@@ -66,10 +68,15 @@ export const STDLIB_GADGETS = [
|
|
|
66
68
|
description: 'Capture stills or live video from the device camera.',
|
|
67
69
|
usage: 'Mount when the intent names photo capture, QR / barcode scanning, video recording, or anything that requires a camera feed. The hook returns a stream once `start()` resolves; thread the resulting blob or stream URL into a contextSpec slot or an actionSpec payload to surface it to the agent.',
|
|
68
70
|
example: {
|
|
69
|
-
call:
|
|
71
|
+
call: "const cam = useCamera({ facingMode: 'environment' }); // on button click: await cam.start()",
|
|
70
72
|
returns: {
|
|
71
|
-
status: '
|
|
72
|
-
value: {
|
|
73
|
+
status: 'completed',
|
|
74
|
+
value: {
|
|
75
|
+
dataUrl: 'data:image/png;base64,…',
|
|
76
|
+
width: 640,
|
|
77
|
+
height: 480,
|
|
78
|
+
mimeType: 'image/png',
|
|
79
|
+
},
|
|
73
80
|
},
|
|
74
81
|
},
|
|
75
82
|
},
|
|
@@ -79,8 +86,8 @@ export const STDLIB_GADGETS = [
|
|
|
79
86
|
description: 'Read the system clipboard contents on user gesture.',
|
|
80
87
|
usage: 'Mount when the intent involves importing copied content (paste-into-form, paste-image-to-upload, paste-link). The Permissions API requires a user gesture; gate `start()` behind a button click. Returned value lands in a contextSpec slot or an actionSpec payload.',
|
|
81
88
|
example: {
|
|
82
|
-
call: 'const paste = useClipboardPaste();',
|
|
83
|
-
returns: { status: '
|
|
89
|
+
call: 'const paste = useClipboardPaste(); // on button click: await paste.start()',
|
|
90
|
+
returns: { status: 'completed', value: 'pasted clipboard text' },
|
|
84
91
|
},
|
|
85
92
|
},
|
|
86
93
|
{
|
|
@@ -89,8 +96,8 @@ export const STDLIB_GADGETS = [
|
|
|
89
96
|
description: 'Write to the system clipboard on user gesture.',
|
|
90
97
|
usage: 'Mount when the intent includes copying generated text, share links, codes, or transcripts to the system clipboard. Fire an actionSpec event so the agent observes the act (it does not see the written value — that stays component-local).',
|
|
91
98
|
example: {
|
|
92
|
-
call: "const write = useClipboardWrite(); write.
|
|
93
|
-
returns: { status: '
|
|
99
|
+
call: "const write = useClipboardWrite({ text: 'hello' }); // on button click: await write.start()",
|
|
100
|
+
returns: { status: 'completed', value: 'hello' },
|
|
94
101
|
},
|
|
95
102
|
},
|
|
96
103
|
{
|
|
@@ -98,10 +105,19 @@ export const STDLIB_GADGETS = [
|
|
|
98
105
|
description: 'Open the native file picker and read selected files.',
|
|
99
106
|
usage: 'Mount when the intent names file upload, attachment selection, or document import. No permission required. The hook returns the picked files plus metadata; thread file refs / data URLs into a contextSpec slot or actionSpec payload.',
|
|
100
107
|
example: {
|
|
101
|
-
call:
|
|
108
|
+
call: "const picker = useFilePicker({ accept: 'image/*' }); // on button click: await picker.start()",
|
|
102
109
|
returns: {
|
|
103
|
-
status: '
|
|
104
|
-
value:
|
|
110
|
+
status: 'completed',
|
|
111
|
+
value: {
|
|
112
|
+
files: [
|
|
113
|
+
{
|
|
114
|
+
name: 'photo.png',
|
|
115
|
+
type: 'image/png',
|
|
116
|
+
size: 12345,
|
|
117
|
+
_file: '<File>',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
105
121
|
},
|
|
106
122
|
},
|
|
107
123
|
},
|
|
@@ -111,10 +127,15 @@ export const STDLIB_GADGETS = [
|
|
|
111
127
|
description: "Resolve the device's current geolocation.",
|
|
112
128
|
usage: 'Mount when the intent names "current location", maps, nearby search, location-aware UI. Browser prompts the user on `start()`; the hook returns coordinates once granted. Thread the resolved coords into a contextSpec slot so the agent observes the latest fix.',
|
|
113
129
|
example: {
|
|
114
|
-
call: 'const geo = useGeolocation();',
|
|
130
|
+
call: 'const geo = useGeolocation(); // on button click: await geo.start()',
|
|
115
131
|
returns: {
|
|
116
|
-
status: '
|
|
117
|
-
value: {
|
|
132
|
+
status: 'completed',
|
|
133
|
+
value: {
|
|
134
|
+
latitude: 37.7749,
|
|
135
|
+
longitude: -122.4194,
|
|
136
|
+
accuracy: 20,
|
|
137
|
+
timestamp: 1718000000000,
|
|
138
|
+
},
|
|
118
139
|
},
|
|
119
140
|
},
|
|
120
141
|
},
|
|
@@ -124,10 +145,10 @@ export const STDLIB_GADGETS = [
|
|
|
124
145
|
description: 'Capture audio from the device microphone.',
|
|
125
146
|
usage: 'Mount when the intent names voice memos, audio messages, dictation, voice-driven UI. Returns an audio stream / blob; thread it into an actionSpec payload at recording-stop, or into a contextSpec slot for live transcription pipelines.',
|
|
126
147
|
example: {
|
|
127
|
-
call: 'const mic = useMicrophone();',
|
|
148
|
+
call: 'const mic = useMicrophone(); // record on click: await mic.start(); end with mic.stop()',
|
|
128
149
|
returns: {
|
|
129
|
-
status: '
|
|
130
|
-
value: {
|
|
150
|
+
status: 'completed',
|
|
151
|
+
value: { blob: '<Blob>', durationMs: 4200, mimeType: 'audio/webm' },
|
|
131
152
|
},
|
|
132
153
|
},
|
|
133
154
|
},
|
|
@@ -137,8 +158,8 @@ export const STDLIB_GADGETS = [
|
|
|
137
158
|
description: 'Show system / browser notifications to the user.',
|
|
138
159
|
usage: 'Mount when the intent involves alerting the user about something (reminders, completion of long tasks, incoming messages) and the UI may be in the background. Permission is prompted on first `start()`; the agent does NOT see notification dismissal directly — surface it via an actionSpec if needed.',
|
|
139
160
|
example: {
|
|
140
|
-
call: "const notify = useNotifications(
|
|
141
|
-
returns: { status: '
|
|
161
|
+
call: "const notify = useNotifications({ title: 'Done' }); // after the task completes: await notify.start()",
|
|
162
|
+
returns: { status: 'completed', value: { outcome: 'closed' } },
|
|
142
163
|
},
|
|
143
164
|
},
|
|
144
165
|
],
|
package/dist/iframe-bridge.d.ts
CHANGED
|
@@ -4,32 +4,16 @@
|
|
|
4
4
|
* Events prefixed with `ggui-` are `postMessage` types (cross-origin iframe boundary).
|
|
5
5
|
* Events prefixed with `ggui:` are `CustomEvent` names (same-origin, dispatched on `window`).
|
|
6
6
|
*
|
|
7
|
-
* The bridge
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* The bridge is one-directional: **Agent to Component** (inbound) data
|
|
8
|
+
* deliveries. Outbound user interaction does NOT travel over this bridge —
|
|
9
|
+
* generated components emit canonical `data:submit` ActionEnvelopes via the
|
|
10
|
+
* wire-config action hooks (`useAction`) over the live channel.
|
|
11
11
|
*/
|
|
12
12
|
export declare const BRIDGE_EVENTS: {
|
|
13
13
|
/** `postMessage` type for parent-to-iframe data delivery. The parent window posts this type; the iframe bridge script converts it to an `AGENT_DATA` CustomEvent. */
|
|
14
14
|
readonly AGENT_DATA_POST: "ggui-agent-data";
|
|
15
15
|
/** `CustomEvent` name dispatched on `window` when agent data arrives. Components listen for this to receive real-time data from the agent (chat messages, typing indicators, etc.). */
|
|
16
16
|
readonly AGENT_DATA: "ggui:agent-data";
|
|
17
|
-
/** `CustomEvent` name for streaming text chunks from the agent. Fired incrementally as the agent generates a response. */
|
|
18
|
-
readonly AGENT_STREAM: "ggui:agent-stream";
|
|
19
|
-
/** `CustomEvent` name for agent messages. Payload includes `type: 'thinking' | 'chat'`. Thinking messages show what the agent is doing; chat messages are final responses. */
|
|
20
|
-
readonly AGENT_MSG: "ggui:agent-msg";
|
|
21
|
-
/** `CustomEvent` name for UI generation log updates. Debug/devtools only — not displayed to end users. */
|
|
22
|
-
readonly AGENT_LOGS: "ggui:logs";
|
|
23
|
-
/** `postMessage` type for iframe-to-parent user interaction data. Carries form submissions and click events from generated components back to the host. */
|
|
24
|
-
readonly USER_DATA_POST: "ggui-user-data";
|
|
25
|
-
/** `CustomEvent` name dispatched on the parent window when user data arrives from the iframe. The host shell listens for this to forward events to the agent. */
|
|
26
|
-
readonly USER_DATA: "ggui:user-data";
|
|
27
|
-
/** `postMessage` type sent when a component's content size changes. Used by the host to auto-resize the iframe to fit content. */
|
|
28
|
-
readonly RESIZE: "ggui-resize";
|
|
29
|
-
/** `postMessage` type sent when a component renders successfully. The host uses this to hide loading indicators and show the component. */
|
|
30
|
-
readonly RENDER_SUCCESS: "ggui-render-success";
|
|
31
|
-
/** `postMessage` type sent when a component fails to render. The host uses this to show an error state instead of a blank iframe. */
|
|
32
|
-
readonly RENDER_ERROR: "ggui-render-error";
|
|
33
17
|
};
|
|
34
18
|
/**
|
|
35
19
|
* Srcdoc JS snippet: bridge agent data postMessages into CustomEvents inside iframe.
|
|
@@ -37,27 +21,4 @@ export declare const BRIDGE_EVENTS: {
|
|
|
37
21
|
* events when the parent forwards data via postMessage.
|
|
38
22
|
*/
|
|
39
23
|
export declare const SRCDOC_AGENT_DATA_BRIDGE = "\n window.addEventListener(\"message\", function(event) {\n if (event.data && event.data.type === \"ggui-agent-data\") {\n window.dispatchEvent(new CustomEvent(\"ggui:agent-data\", { detail: event.data.payload }));\n }\n });";
|
|
40
|
-
/**
|
|
41
|
-
* Srcdoc JS snippet: auto-report content height changes to parent.
|
|
42
|
-
*
|
|
43
|
-
* Uses a ResizeObserver on <html> to detect layout changes and posts
|
|
44
|
-
* a `ggui-resize` message with the current scrollHeight. Also fires
|
|
45
|
-
* an initial measurement on the next animation frame after injection.
|
|
46
|
-
*
|
|
47
|
-
* Inject this into any srcdoc or rendered page <script> so the parent
|
|
48
|
-
* can auto-size the iframe to fit content without scrollbars.
|
|
49
|
-
*/
|
|
50
|
-
export declare const SRCDOC_RESIZE_BRIDGE: string;
|
|
51
|
-
/**
|
|
52
|
-
* Srcdoc JS snippet: universal interaction bridge inside iframe.
|
|
53
|
-
*
|
|
54
|
-
* Three layers of automatic event capture (no props.onSubmit needed):
|
|
55
|
-
* 1. Form submit intercept — captures <form> submissions with all field data
|
|
56
|
-
* 2. Interactive element clicks — buttons, [role="button"], links, [data-action]
|
|
57
|
-
* 3. Cursor-pointer fallback (approach C) — any styled-clickable div/span/card
|
|
58
|
-
*
|
|
59
|
-
* All layers skip if props.onSubmit already handled the event (__ggui_submitHandled).
|
|
60
|
-
* Click handler uses bubble phase so component handlers run first.
|
|
61
|
-
*/
|
|
62
|
-
export declare const SRCDOC_USER_DATA_BRIDGE = "\n // Dedup: props.onSubmit sets __ggui_submitHandled = true synchronously.\n // Both layers check this. We use a microtask to reset it so it stays\n // true for ALL handlers in the same event cycle (click + submit).\n function __ggui_wasHandled() {\n if (!window.__ggui_submitHandled) return false;\n // Reset via microtask \u2014 stays true for all sync handlers in this tick\n Promise.resolve().then(function() { window.__ggui_submitHandled = false; });\n return true;\n }\n\n // Layer 1: Form submit intercept (bubble phase \u2014 lets component onSubmit run first)\n // Handles: <form> submit via enter key or submit-button click.\n // Uses bubble phase so component's onSubmit (which may call props.onSubmit) fires first.\n document.addEventListener(\"submit\", function(e) {\n e.preventDefault();\n if (__ggui_wasHandled()) return;\n var form = e.target;\n var data = {};\n try { data = Object.fromEntries(new FormData(form)); } catch(_) {}\n parent.postMessage({ type: \"ggui-user-data\", data: data }, \"*\");\n });\n\n // Layers 2+3: Universal click handler (bubble phase \u2014 runs after component handlers)\n // Handles: buttons, [role=\"button\"], links, [data-action], cursor:pointer elements.\n // Does NOT handle submit-type elements inside forms (Layer 1 handles those).\n document.addEventListener(\"click\", function(e) {\n if (__ggui_wasHandled()) return;\n if (!e.target || !e.target.closest) return;\n\n // Layer 2: Find the closest standard interactive element\n var el = e.target.closest(\"button\")\n || e.target.closest(\"[role='button']\")\n || e.target.closest(\"a[href], a[data-action]\")\n || e.target.closest(\"[data-action]\")\n || e.target.closest(\"[data-ggui-action]\");\n\n // Layer 3 (approach C): Fallback \u2014 walk up DOM looking for cursor:pointer\n if (!el) {\n var target = e.target;\n var depth = 0;\n while (target && target !== document.documentElement && depth < 6) {\n if (target.nodeType === 1) {\n try {\n if (window.getComputedStyle(target).cursor === \"pointer\") {\n el = target;\n break;\n }\n } catch(_) {}\n }\n target = target.parentElement;\n depth++;\n }\n }\n if (!el) return;\n\n // Skip submit-type elements inside forms \u2014 Layer 1 handles those.\n // (click fires before submit, so we must yield to avoid double-fire)\n // <button> defaults to type=\"submit\", so el.type === \"submit\" catches both\n // <button> and <button type=\"submit\">. Only <button type=\"button\"> is excluded.\n if (el.closest(\"form\") && el.type === \"submit\") return;\n\n // Skip form control elements \u2014 these are data entry, not actions.\n // Checkboxes, radios, inputs, selects get captured via form submit (Layer 1).\n var tag = el.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\" || tag === \"LABEL\") return;\n\n // For standalone interactive elements, post click event with label + data attributes\n var data = { action: \"click\" };\n var label = el.getAttribute(\"aria-label\")\n || el.getAttribute(\"data-label\")\n || el.innerText\n || el.textContent;\n if (label) data.label = label.trim().substring(0, 200);\n\n // Spread data-* attributes into payload (data-action, data-value, etc.)\n if (el.dataset) {\n for (var key in el.dataset) {\n if (el.dataset.hasOwnProperty(key)) data[key] = el.dataset[key];\n }\n }\n\n parent.postMessage({ type: \"ggui-user-data\", data: data }, \"*\");\n });";
|
|
63
24
|
//# sourceMappingURL=iframe-bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-bridge.d.ts","sourceRoot":"","sources":["../src/iframe-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa;IAExB,qKAAqK;;IAErK,uLAAuL;;
|
|
1
|
+
{"version":3,"file":"iframe-bridge.d.ts","sourceRoot":"","sources":["../src/iframe-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa;IAExB,qKAAqK;;IAErK,uLAAuL;;CAE/K,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,kPAK/B,CAAC"}
|