@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,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal stream parser for agent responses.
|
|
3
|
+
*
|
|
4
|
+
* Extracts text from any LLM provider's streaming format (Anthropic, OpenAI,
|
|
5
|
+
* Gemini, Cohere, Mistral, etc.) without hardcoding provider schemas.
|
|
6
|
+
* Uses depth-first search on well-known field names and container structures.
|
|
7
|
+
*
|
|
8
|
+
* Decoupled from any transport (WebSocket, HTTP, etc.) — callers provide
|
|
9
|
+
* callbacks for chunk delivery.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Detect whether a response should be treated as a stream based on headers.
|
|
13
|
+
* Accepts raw header strings so callers aren't coupled to the fetch API.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isStreamingContentType(contentType: string, transferEncoding?: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Depth-first search for a text string in a JSON structure.
|
|
18
|
+
*
|
|
19
|
+
* Search strategy:
|
|
20
|
+
* 1. Check TEXT_FIELDS at current level (string values only)
|
|
21
|
+
* 2. Recurse into CONTAINER_FIELDS
|
|
22
|
+
*
|
|
23
|
+
* Works with any provider because it searches by field-name patterns,
|
|
24
|
+
* not by provider-specific schemas.
|
|
25
|
+
*/
|
|
26
|
+
export declare function deepFindText(obj: unknown, depth?: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* Detect if a streaming JSON event signals end-of-stream.
|
|
29
|
+
*
|
|
30
|
+
* Recognized signals:
|
|
31
|
+
* - type: "done" / "message_stop"
|
|
32
|
+
* - choices[0].finish_reason !== null
|
|
33
|
+
* - (HTTP stream close is handled by the reader, not here)
|
|
34
|
+
*/
|
|
35
|
+
export declare function isStreamDone(data: Record<string, unknown>): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Extract sessionId from a streaming event.
|
|
38
|
+
* Checks for a top-level `sessionId` string — no envelope format required.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractSessionId(data: Record<string, unknown>): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Callbacks for stream consumers. Transport-agnostic — works with WebSocket,
|
|
43
|
+
* HTTP response streaming, file output, or anything else.
|
|
44
|
+
*/
|
|
45
|
+
export interface StreamCallbacks {
|
|
46
|
+
onChunk: (text: string) => Promise<void>;
|
|
47
|
+
onDone: () => Promise<void>;
|
|
48
|
+
onSessionId?: (sessionId: string) => Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read a streaming HTTP response and invoke callbacks for each text chunk.
|
|
52
|
+
*
|
|
53
|
+
* Supports three wire formats:
|
|
54
|
+
* 1. text/event-stream (SSE) — parses `data:` lines
|
|
55
|
+
* 2. application/x-ndjson — one JSON object per line
|
|
56
|
+
* 3. Any other — forwards raw text chunks
|
|
57
|
+
*
|
|
58
|
+
* JSON events (SSE and NDJSON) are parsed with deepFindText for universal
|
|
59
|
+
* text extraction. Non-JSON content is forwarded as raw text.
|
|
60
|
+
*/
|
|
61
|
+
export declare function readStream(body: ReadableStream<Uint8Array>, contentType: string, callbacks: StreamCallbacks): Promise<void>;
|
|
62
|
+
//# sourceMappingURL=stream-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-parser.d.ts","sourceRoot":"","sources":["../../src/stream/stream-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAKT;AAUD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,MAAM,CA0B5D;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAUnE;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAKlF;AAID;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,IAAI,CAAC,CAkFf"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal stream parser for agent responses.
|
|
3
|
+
*
|
|
4
|
+
* Extracts text from any LLM provider's streaming format (Anthropic, OpenAI,
|
|
5
|
+
* Gemini, Cohere, Mistral, etc.) without hardcoding provider schemas.
|
|
6
|
+
* Uses depth-first search on well-known field names and container structures.
|
|
7
|
+
*
|
|
8
|
+
* Decoupled from any transport (WebSocket, HTTP, etc.) — callers provide
|
|
9
|
+
* callbacks for chunk delivery.
|
|
10
|
+
*/
|
|
11
|
+
// ── Detection ──
|
|
12
|
+
/**
|
|
13
|
+
* Detect whether a response should be treated as a stream based on headers.
|
|
14
|
+
* Accepts raw header strings so callers aren't coupled to the fetch API.
|
|
15
|
+
*/
|
|
16
|
+
export function isStreamingContentType(contentType, transferEncoding) {
|
|
17
|
+
if (contentType.includes('text/event-stream'))
|
|
18
|
+
return true;
|
|
19
|
+
if (contentType.includes('application/x-ndjson'))
|
|
20
|
+
return true;
|
|
21
|
+
if (contentType.includes('text/plain') && transferEncoding?.includes('chunked'))
|
|
22
|
+
return true;
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// ── Text extraction ──
|
|
26
|
+
/** Well-known field names that carry streaming text across LLM providers. */
|
|
27
|
+
const TEXT_FIELDS = ['text', 'content', 'chunk', 'message', 'output', 'response'];
|
|
28
|
+
/** Well-known container fields that wrap text in nested structures. */
|
|
29
|
+
const CONTAINER_FIELDS = ['delta', 'choices', 'candidates', 'parts', 'content_block', 'data', 'body'];
|
|
30
|
+
/**
|
|
31
|
+
* Depth-first search for a text string in a JSON structure.
|
|
32
|
+
*
|
|
33
|
+
* Search strategy:
|
|
34
|
+
* 1. Check TEXT_FIELDS at current level (string values only)
|
|
35
|
+
* 2. Recurse into CONTAINER_FIELDS
|
|
36
|
+
*
|
|
37
|
+
* Works with any provider because it searches by field-name patterns,
|
|
38
|
+
* not by provider-specific schemas.
|
|
39
|
+
*/
|
|
40
|
+
export function deepFindText(obj, depth = 0) {
|
|
41
|
+
if (depth > 6)
|
|
42
|
+
return '';
|
|
43
|
+
if (!obj || typeof obj !== 'object')
|
|
44
|
+
return '';
|
|
45
|
+
const record = obj;
|
|
46
|
+
for (const key of TEXT_FIELDS) {
|
|
47
|
+
const val = record[key];
|
|
48
|
+
if (typeof val === 'string' && val.length > 0)
|
|
49
|
+
return val;
|
|
50
|
+
}
|
|
51
|
+
for (const key of CONTAINER_FIELDS) {
|
|
52
|
+
if (!(key in record))
|
|
53
|
+
continue;
|
|
54
|
+
const val = record[key];
|
|
55
|
+
if (Array.isArray(val)) {
|
|
56
|
+
for (const item of val) {
|
|
57
|
+
const found = deepFindText(item, depth + 1);
|
|
58
|
+
if (found)
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const found = deepFindText(val, depth + 1);
|
|
64
|
+
if (found)
|
|
65
|
+
return found;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
// ── Done detection ──
|
|
71
|
+
/**
|
|
72
|
+
* Detect if a streaming JSON event signals end-of-stream.
|
|
73
|
+
*
|
|
74
|
+
* Recognized signals:
|
|
75
|
+
* - type: "done" / "message_stop"
|
|
76
|
+
* - choices[0].finish_reason !== null
|
|
77
|
+
* - (HTTP stream close is handled by the reader, not here)
|
|
78
|
+
*/
|
|
79
|
+
export function isStreamDone(data) {
|
|
80
|
+
const t = data.type;
|
|
81
|
+
if (t === 'done' || t === 'message_stop')
|
|
82
|
+
return true;
|
|
83
|
+
if (Array.isArray(data.choices)) {
|
|
84
|
+
const first = data.choices[0];
|
|
85
|
+
if (first?.finish_reason != null)
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
// ── SessionId extraction ──
|
|
91
|
+
/**
|
|
92
|
+
* Extract sessionId from a streaming event.
|
|
93
|
+
* Checks for a top-level `sessionId` string — no envelope format required.
|
|
94
|
+
*/
|
|
95
|
+
export function extractSessionId(data) {
|
|
96
|
+
if (typeof data.sessionId === 'string' && data.sessionId) {
|
|
97
|
+
return data.sessionId;
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Read a streaming HTTP response and invoke callbacks for each text chunk.
|
|
103
|
+
*
|
|
104
|
+
* Supports three wire formats:
|
|
105
|
+
* 1. text/event-stream (SSE) — parses `data:` lines
|
|
106
|
+
* 2. application/x-ndjson — one JSON object per line
|
|
107
|
+
* 3. Any other — forwards raw text chunks
|
|
108
|
+
*
|
|
109
|
+
* JSON events (SSE and NDJSON) are parsed with deepFindText for universal
|
|
110
|
+
* text extraction. Non-JSON content is forwarded as raw text.
|
|
111
|
+
*/
|
|
112
|
+
export async function readStream(body, contentType, callbacks) {
|
|
113
|
+
const reader = body.getReader();
|
|
114
|
+
const decoder = new TextDecoder();
|
|
115
|
+
const isSSE = contentType.includes('text/event-stream');
|
|
116
|
+
const isNDJSON = contentType.includes('application/x-ndjson');
|
|
117
|
+
let buffer = '';
|
|
118
|
+
let doneSent = false;
|
|
119
|
+
const emitDone = async () => {
|
|
120
|
+
if (doneSent)
|
|
121
|
+
return;
|
|
122
|
+
doneSent = true;
|
|
123
|
+
await callbacks.onDone();
|
|
124
|
+
};
|
|
125
|
+
const processJsonEvent = async (data) => {
|
|
126
|
+
const sid = extractSessionId(data);
|
|
127
|
+
if (sid)
|
|
128
|
+
await callbacks.onSessionId?.(sid);
|
|
129
|
+
if (isStreamDone(data)) {
|
|
130
|
+
await emitDone();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const text = deepFindText(data);
|
|
134
|
+
if (text)
|
|
135
|
+
await callbacks.onChunk(text);
|
|
136
|
+
};
|
|
137
|
+
try {
|
|
138
|
+
for (;;) {
|
|
139
|
+
const { done, value } = await reader.read();
|
|
140
|
+
if (done)
|
|
141
|
+
break;
|
|
142
|
+
buffer += decoder.decode(value, { stream: true });
|
|
143
|
+
if (isSSE) {
|
|
144
|
+
const lines = buffer.split('\n');
|
|
145
|
+
buffer = lines.pop() || '';
|
|
146
|
+
for (const line of lines) {
|
|
147
|
+
if (!line || line.startsWith(':'))
|
|
148
|
+
continue;
|
|
149
|
+
if (!line.startsWith('data: '))
|
|
150
|
+
continue;
|
|
151
|
+
const payload = line.slice(6).trim();
|
|
152
|
+
if (!payload)
|
|
153
|
+
continue;
|
|
154
|
+
if (payload === '[DONE]') {
|
|
155
|
+
await emitDone();
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
await processJsonEvent(JSON.parse(payload));
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Not valid JSON — forward as raw text chunk
|
|
163
|
+
await callbacks.onChunk(payload);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (isNDJSON) {
|
|
168
|
+
const lines = buffer.split('\n');
|
|
169
|
+
buffer = lines.pop() || '';
|
|
170
|
+
for (const line of lines) {
|
|
171
|
+
const trimmed = line.trim();
|
|
172
|
+
if (!trimmed)
|
|
173
|
+
continue;
|
|
174
|
+
try {
|
|
175
|
+
await processJsonEvent(JSON.parse(trimmed));
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Not valid JSON — forward as raw text chunk
|
|
179
|
+
await callbacks.onChunk(trimmed);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
const chunk = buffer;
|
|
185
|
+
buffer = '';
|
|
186
|
+
if (chunk)
|
|
187
|
+
await callbacks.onChunk(chunk);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
await emitDone();
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
console.error('Stream reading error:', err);
|
|
194
|
+
await emitDone().catch(() => { });
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
reader.releaseLock();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket transport envelope — the wire-framing layer for the live channel.
|
|
3
|
+
*
|
|
4
|
+
* The live channel is the live session plane between core-mcp and the
|
|
5
|
+
* user. This file defines HOW that plane is framed on a WebSocket:
|
|
6
|
+
* the dispatch discriminator
|
|
7
|
+
* (`WebSocketMessageType`), the discriminated union envelope
|
|
8
|
+
* (`WebSocketMessage`), and the client-side connection-lifecycle enum
|
|
9
|
+
* (`ConnectionStatus`).
|
|
10
|
+
*
|
|
11
|
+
* The CONTRACT payload shapes (what each variant carries —
|
|
12
|
+
* `SubscribePayload`, `AckPayload`, `StreamEnvelope`, etc.) live in
|
|
13
|
+
* `../types/live-channel`. Renaming the envelope or swapping in an
|
|
14
|
+
* alternate transport (e.g., a binary-framed variant, or SSE fallback)
|
|
15
|
+
* would not change the payload contract; that asymmetry is why the
|
|
16
|
+
* split exists.
|
|
17
|
+
*
|
|
18
|
+
* This module is exported as a subpath — `@ggui-ai/protocol/transport/
|
|
19
|
+
* websocket` — so only transport implementors (hosted Lambda handlers,
|
|
20
|
+
* OSS `/ws` server, web/RN WebSocketManager, connector ws-connection)
|
|
21
|
+
* pay its type/build cost. Consumers that only need contract payloads
|
|
22
|
+
* stay on the root import.
|
|
23
|
+
*/
|
|
24
|
+
import type { ActionEnvelope } from '../types/events';
|
|
25
|
+
import type { JsonObject } from '../types/data-contract';
|
|
26
|
+
import type { SubscribePayload, GeneratePayload, PopPayload, ClosePayload, GetStackPayload, AckPayload, ErrorPayload, PushPayload, StreamEnvelope, StreamPayload, SessionPayload, ProgressPayload, AgentMsgPayload, PropsUpdatePayload, UrlPayload, SystemPayload, InternalProgressPayload, ChannelSubscribePayload, ChannelUnsubscribePayload, ChannelPayloadFrame, ChannelErrorPayload, DrainAckPayload } from '../types/live-channel';
|
|
27
|
+
import type { HostContextObservedPayload } from '../types/host-context';
|
|
28
|
+
/**
|
|
29
|
+
* WebSocket message types for client-server communication.
|
|
30
|
+
* Each type maps to a specific payload shape in the {@link WebSocketMessage} discriminated union.
|
|
31
|
+
*/
|
|
32
|
+
export type WebSocketMessageType = 'action' | 'subscribe' | 'generate' | 'pop' | 'close' | 'get_stack' | 'feedback' | 'ping' | 'pong' | 'ack' | 'error' | 'push' | 'data' | 'stream' | 'session' | 'progress' | 'agent-msg' | 'props_update' | 'url' | 'system' | 'internal:progress' | 'channel_subscribe' | 'channel_unsubscribe' | 'channel_payload' | 'channel_error' | 'drain_ack' | 'host_context_observed' | 'canvas_navigated';
|
|
33
|
+
/** Fields shared by all WebSocket message variants. */
|
|
34
|
+
interface WsMessageBase {
|
|
35
|
+
requestId?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Discriminated union of all WebSocket messages.
|
|
39
|
+
* The `type` field narrows `payload` automatically in switch/if blocks —
|
|
40
|
+
* no type casts needed. Each variant pairs a `WebSocketMessageType` with
|
|
41
|
+
* its corresponding payload interface.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* function handle(msg: WebSocketMessage) {
|
|
46
|
+
* switch (msg.type) {
|
|
47
|
+
* case 'ack':
|
|
48
|
+
* msg.payload.sequence; // AckPayload — auto-narrowed
|
|
49
|
+
* break;
|
|
50
|
+
* case 'error':
|
|
51
|
+
* msg.payload.message; // ErrorPayload — auto-narrowed
|
|
52
|
+
* msg.payload.details; // JsonValue | undefined
|
|
53
|
+
* break;
|
|
54
|
+
* case 'push':
|
|
55
|
+
* msg.payload.stackItem; // PushPayload — auto-narrowed
|
|
56
|
+
* break;
|
|
57
|
+
* case 'data':
|
|
58
|
+
* msg.payload.payload; // StreamEnvelope.payload
|
|
59
|
+
* break;
|
|
60
|
+
* }
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export type WebSocketMessage = (WsMessageBase & {
|
|
65
|
+
type: 'action';
|
|
66
|
+
payload: ActionEnvelope;
|
|
67
|
+
}) | (WsMessageBase & {
|
|
68
|
+
type: 'subscribe';
|
|
69
|
+
payload: SubscribePayload;
|
|
70
|
+
}) | (WsMessageBase & {
|
|
71
|
+
type: 'generate';
|
|
72
|
+
payload: GeneratePayload;
|
|
73
|
+
}) | (WsMessageBase & {
|
|
74
|
+
type: 'pop';
|
|
75
|
+
payload: PopPayload;
|
|
76
|
+
}) | (WsMessageBase & {
|
|
77
|
+
type: 'close';
|
|
78
|
+
payload: ClosePayload;
|
|
79
|
+
}) | (WsMessageBase & {
|
|
80
|
+
type: 'get_stack';
|
|
81
|
+
payload: GetStackPayload;
|
|
82
|
+
}) | (WsMessageBase & {
|
|
83
|
+
type: 'feedback';
|
|
84
|
+
payload: JsonObject;
|
|
85
|
+
}) | (WsMessageBase & {
|
|
86
|
+
type: 'ping';
|
|
87
|
+
payload: JsonObject;
|
|
88
|
+
}) | (WsMessageBase & {
|
|
89
|
+
type: 'pong';
|
|
90
|
+
payload: JsonObject;
|
|
91
|
+
}) | (WsMessageBase & {
|
|
92
|
+
type: 'ack';
|
|
93
|
+
payload: AckPayload;
|
|
94
|
+
}) | (WsMessageBase & {
|
|
95
|
+
type: 'error';
|
|
96
|
+
payload: ErrorPayload;
|
|
97
|
+
}) | (WsMessageBase & {
|
|
98
|
+
type: 'push';
|
|
99
|
+
payload: PushPayload;
|
|
100
|
+
}) | (WsMessageBase & {
|
|
101
|
+
type: 'data';
|
|
102
|
+
payload: StreamEnvelope;
|
|
103
|
+
}) | (WsMessageBase & {
|
|
104
|
+
type: 'stream';
|
|
105
|
+
payload: StreamPayload;
|
|
106
|
+
}) | (WsMessageBase & {
|
|
107
|
+
type: 'session';
|
|
108
|
+
payload: SessionPayload;
|
|
109
|
+
}) | (WsMessageBase & {
|
|
110
|
+
type: 'progress';
|
|
111
|
+
payload: ProgressPayload;
|
|
112
|
+
}) | (WsMessageBase & {
|
|
113
|
+
type: 'agent-msg';
|
|
114
|
+
payload: AgentMsgPayload;
|
|
115
|
+
}) | (WsMessageBase & {
|
|
116
|
+
type: 'props_update';
|
|
117
|
+
payload: PropsUpdatePayload;
|
|
118
|
+
}) | (WsMessageBase & {
|
|
119
|
+
type: 'url';
|
|
120
|
+
payload: UrlPayload;
|
|
121
|
+
}) | (WsMessageBase & {
|
|
122
|
+
type: 'system';
|
|
123
|
+
payload: SystemPayload;
|
|
124
|
+
}) | (WsMessageBase & {
|
|
125
|
+
type: 'internal:progress';
|
|
126
|
+
payload: InternalProgressPayload;
|
|
127
|
+
}) | (WsMessageBase & {
|
|
128
|
+
type: 'channel_subscribe';
|
|
129
|
+
payload: ChannelSubscribePayload;
|
|
130
|
+
}) | (WsMessageBase & {
|
|
131
|
+
type: 'channel_unsubscribe';
|
|
132
|
+
payload: ChannelUnsubscribePayload;
|
|
133
|
+
}) | (WsMessageBase & {
|
|
134
|
+
type: 'channel_payload';
|
|
135
|
+
payload: ChannelPayloadFrame;
|
|
136
|
+
}) | (WsMessageBase & {
|
|
137
|
+
type: 'channel_error';
|
|
138
|
+
payload: ChannelErrorPayload;
|
|
139
|
+
}) | (WsMessageBase & {
|
|
140
|
+
type: 'drain_ack';
|
|
141
|
+
payload: DrainAckPayload;
|
|
142
|
+
}) | (WsMessageBase & {
|
|
143
|
+
type: 'host_context_observed';
|
|
144
|
+
payload: HostContextObservedPayload;
|
|
145
|
+
}) | (WsMessageBase & {
|
|
146
|
+
type: 'canvas_navigated';
|
|
147
|
+
payload: CanvasNavigatedPayload;
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* Payload for the canvas-mode `canvas_navigated` message. Emitted by
|
|
151
|
+
* the iframe-runtime's CanvasShell when the user back-navigates — the
|
|
152
|
+
* server uses `activeItemId` to update `session.activeStackItemId`
|
|
153
|
+
* (for `ggui_consume`'s active-pipe resolution) and
|
|
154
|
+
* `previousActiveItemId` to optionally abort the cold-gen
|
|
155
|
+
* `AbortSignal` keyed on that stack item.
|
|
156
|
+
*/
|
|
157
|
+
export interface CanvasNavigatedPayload {
|
|
158
|
+
/** Tenancy guard — server compares against subscriber binding. */
|
|
159
|
+
readonly sessionId: string;
|
|
160
|
+
/**
|
|
161
|
+
* Stack-item id the canvas had as active immediately BEFORE the
|
|
162
|
+
* navigation. Null when navigating from the empty state (no prior
|
|
163
|
+
* active item).
|
|
164
|
+
*/
|
|
165
|
+
readonly previousActiveItemId: string | null;
|
|
166
|
+
/**
|
|
167
|
+
* Stack-item id the canvas has as active immediately AFTER the
|
|
168
|
+
* navigation. Null when the user popped to an empty navStack.
|
|
169
|
+
*/
|
|
170
|
+
readonly activeItemId: string | null;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* WebSocket connection status. Client-side transport enum describing
|
|
174
|
+
* the browser/Node ws.readyState lifecycle.
|
|
175
|
+
*/
|
|
176
|
+
export type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'reconnecting';
|
|
177
|
+
export {};
|
|
178
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a ggui app surfaces in MCP-Apps-capable hosts (Claude Desktop,
|
|
3
|
+
* claude.ai, future spec-compliant clients).
|
|
4
|
+
*
|
|
5
|
+
* - `'inline'` (default): each `ggui_push` returns its own `ui://`
|
|
6
|
+
* resource; the host mounts one iframe per push as a chat-message
|
|
7
|
+
* widget. Today's behavior.
|
|
8
|
+
* - `'canvas'`: `ggui_new_session` mints a single session-scoped
|
|
9
|
+
* iframe (`ui://ggui/session/<sessionId>`) that persists for the
|
|
10
|
+
* session; `ggui_push` delivers state via WebSocket to that
|
|
11
|
+
* canvas. The canvas owns its own navigation stack + animator
|
|
12
|
+
* chrome.
|
|
13
|
+
*
|
|
14
|
+
* Selecting `'canvas'` does NOT guarantee canvas rendering — the host
|
|
15
|
+
* may not support fullscreen / pip display modes. The canvas degrades
|
|
16
|
+
* gracefully to inline-style rendering when host capability is
|
|
17
|
+
* missing.
|
|
18
|
+
*
|
|
19
|
+
* Distinct from `defaultShellType`. `defaultShellType` controls how
|
|
20
|
+
* the LLM-generated UI adapts to its chrome (chat-card / fullscreen
|
|
21
|
+
* swipe / spatial floating). `defaultMcpAppsMode` controls how the
|
|
22
|
+
* MCP host presents ggui's iframe (one-per-push card / one-per-session
|
|
23
|
+
* canvas). Same app may set `defaultShellType: 'fullscreen'` AND
|
|
24
|
+
* `defaultMcpAppsMode: 'canvas'` — they're orthogonal concerns.
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
export type McpAppsMode = 'inline' | 'canvas';
|
|
29
|
+
/**
|
|
30
|
+
* Public display configuration for a ggui app.
|
|
31
|
+
* Returned by the app config endpoint — no secrets, no auth required.
|
|
32
|
+
*/
|
|
33
|
+
export interface AppDisplayConfig {
|
|
34
|
+
appId: string;
|
|
35
|
+
name: string;
|
|
36
|
+
defaultShellType: 'chat' | 'fullscreen' | 'spatial';
|
|
37
|
+
themeId: string;
|
|
38
|
+
defaultScreenPrompt?: string;
|
|
39
|
+
designSystemPreset?: string;
|
|
40
|
+
userAuthMode: string;
|
|
41
|
+
/**
|
|
42
|
+
* Agent invoke endpoint URL.
|
|
43
|
+
*
|
|
44
|
+
* Consumed by the `useInvoke` hook in `@ggui-ai/ggui-react` /
|
|
45
|
+
* `@ggui-ai/ggui-react-native` — the hook POSTs the user's message +
|
|
46
|
+
* history to `{endpointUrl}/invoke` and streams back the agent's
|
|
47
|
+
* response (Streamable Invoke Protocol). NOT used by the
|
|
48
|
+
* `ggui_handshake` → `ggui_push` mint path, which flows through MCP.
|
|
49
|
+
*
|
|
50
|
+
* Absent for apps without a deployed agent endpoint; `useInvoke`
|
|
51
|
+
* surfaces a clear error in that case.
|
|
52
|
+
*/
|
|
53
|
+
endpointUrl?: string;
|
|
54
|
+
/**
|
|
55
|
+
* How this app surfaces in MCP-Apps-capable hosts. Absent ⇒
|
|
56
|
+
* `'inline'` (100% backward-compatible default). See {@link McpAppsMode}.
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
defaultMcpAppsMode?: McpAppsMode;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=app-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/types/app-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { JsonObject } from './data-contract';
|
|
2
|
+
/**
|
|
3
|
+
* User authentication modes.
|
|
4
|
+
*
|
|
5
|
+
* - `anonymous`: no auth gate, cookie-based pseudonymous identity.
|
|
6
|
+
* - `cognito`: ggui-managed Cognito identity (OAuth/OIDC handled by platform).
|
|
7
|
+
* - `byo`: builder supplies their own JWT/OIDC issuer; platform validates against JWKS.
|
|
8
|
+
*/
|
|
9
|
+
export type UserAuthMode = 'anonymous' | 'cognito' | 'byo';
|
|
10
|
+
/**
|
|
11
|
+
* Scopes requestable from ggui identity
|
|
12
|
+
*/
|
|
13
|
+
export type GguiAuthScope = 'email' | 'name' | 'picture';
|
|
14
|
+
/**
|
|
15
|
+
* User auth config for cognito + byo modes.
|
|
16
|
+
* Matches the backend UserAuthConfig schema.
|
|
17
|
+
*
|
|
18
|
+
* BYO has two flavors:
|
|
19
|
+
* - Render-surface HMAC-JWT shortcut: {@link authUrl} / {@link callbackSecret} /
|
|
20
|
+
* {@link tokenClaimUserId} (`your-app.example/auth/callback`, iframe UIs).
|
|
21
|
+
* - Portal BYO OAuth 2.1 flow: the `oauth*` fields below
|
|
22
|
+
* (`your-app.example/oauth/byo/callback`, native Portal).
|
|
23
|
+
* The `tokenClaim*` fields are reused across both flavors.
|
|
24
|
+
*/
|
|
25
|
+
export interface UserAuthConfig {
|
|
26
|
+
authUrl?: string;
|
|
27
|
+
callbackSecret?: string;
|
|
28
|
+
tokenClaimUserId?: string;
|
|
29
|
+
tokenClaimEmail?: string;
|
|
30
|
+
tokenClaimName?: string;
|
|
31
|
+
oauthAuthorizationUrl?: string;
|
|
32
|
+
oauthTokenUrl?: string;
|
|
33
|
+
oauthJwksUrl?: string;
|
|
34
|
+
oauthIssuer?: string;
|
|
35
|
+
oauthClientIdPublic?: string;
|
|
36
|
+
oauthScopes?: string[];
|
|
37
|
+
oauthRedirectUriAllowlist?: string[];
|
|
38
|
+
requestedScopes?: GguiAuthScope[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Authenticated end-user identity.
|
|
42
|
+
* Attached to sessions and included in events consumed by agents.
|
|
43
|
+
*
|
|
44
|
+
* Extends {@link JsonObject} for direct JSON serialization over WebSocket.
|
|
45
|
+
*/
|
|
46
|
+
export interface EndUserIdentity extends JsonObject {
|
|
47
|
+
userId: string;
|
|
48
|
+
email?: string;
|
|
49
|
+
name?: string;
|
|
50
|
+
picture?: string;
|
|
51
|
+
provider: 'ggui' | 'custom';
|
|
52
|
+
authenticatedAt: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* User auth settings for an app (convenience wrapper)
|
|
56
|
+
*/
|
|
57
|
+
export interface UserAuthSettings {
|
|
58
|
+
mode: UserAuthMode;
|
|
59
|
+
config?: UserAuthConfig;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAE7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IAIrC,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|