@touchcastllc/napster-companion-api-dev 1.0.0-alpha.74 → 1.0.0-alpha.75
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/lib/index.css +1 -1
- package/lib/index.d.ts +10 -0
- package/lib/index.esm.js +1 -1
- package/lib/index.js +1 -1
- package/lib/index.standalone.js +1 -1
- package/lib/services/edge-mcp/edge-mcp-bridge.d.ts +20 -0
- package/lib/services/edge-mcp/edge-mcp-discovery.d.ts +13 -6
- package/lib/shell/mount-shell.d.ts +88 -0
- package/lib/types/index.d.ts +13 -0
- package/package.json +1 -1
|
@@ -20,6 +20,14 @@ export interface EdgeMcpBridgeOptions {
|
|
|
20
20
|
* false to manage the agent's function list yourself. Default: `true`.
|
|
21
21
|
*/
|
|
22
22
|
registerInlineFunctions?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Read tools from a same-origin child iframe's `document.modelContext` instead of
|
|
25
|
+
* this window's. Used by the persistent-agent shell: the avatar + bridge live in the
|
|
26
|
+
* top-level document while the SITE (and its tools) live in the wrapped iframe. The
|
|
27
|
+
* bridge re-discovers on each iframe `load` (navigation) and routes tool calls into
|
|
28
|
+
* it (`executeTool` runs in the iframe's realm, so the site operates itself).
|
|
29
|
+
*/
|
|
30
|
+
iframe?: HTMLIFrameElement;
|
|
23
31
|
}
|
|
24
32
|
export declare class EdgeMcpBridge {
|
|
25
33
|
private mc;
|
|
@@ -27,12 +35,15 @@ export declare class EdgeMcpBridge {
|
|
|
27
35
|
private onToolChange;
|
|
28
36
|
private onResourceUpdated;
|
|
29
37
|
private onResourceListChanged;
|
|
38
|
+
private onIframeLoad;
|
|
30
39
|
private readonly seededUris;
|
|
31
40
|
private lastInlineSig;
|
|
32
41
|
private sessionReady;
|
|
33
42
|
private disposed;
|
|
34
43
|
private readonly options;
|
|
35
44
|
constructor(options: EdgeMcpBridgeOptions);
|
|
45
|
+
/** The document whose `modelContext` we read — the target iframe's, or this window's. */
|
|
46
|
+
private targetDoc;
|
|
36
47
|
/**
|
|
37
48
|
* Discover `document.modelContext` in the page, cache its tools, and wire up
|
|
38
49
|
* the `toolchange` / `resourceupdated` listeners. Returns the model context,
|
|
@@ -40,6 +51,15 @@ export declare class EdgeMcpBridge {
|
|
|
40
51
|
* failure is silent and non-fatal.
|
|
41
52
|
*/
|
|
42
53
|
attach(): Promise<EdgeMcpModelContext | null>;
|
|
54
|
+
/** Remove listeners from the current model context and drop the ref (no state reset). */
|
|
55
|
+
private unbind;
|
|
56
|
+
/**
|
|
57
|
+
* Re-discover and re-bind after the target iframe navigated to a NEW document (its old
|
|
58
|
+
* `document.modelContext` is dead). Keeps `sessionReady` (the avatar session in the parent
|
|
59
|
+
* survives), but resets the per-document dedupe so tools + resources re-register for the
|
|
60
|
+
* new page.
|
|
61
|
+
*/
|
|
62
|
+
private reattach;
|
|
43
63
|
/** Attach to a known model context: cache tools and subscribe to events. */
|
|
44
64
|
private bind;
|
|
45
65
|
/**
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import type { EdgeMcpModelContext } from "./edge-mcp-types";
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Read `modelContext` from a document, falling back to the deprecated navigator alias.
|
|
4
|
+
*
|
|
5
|
+
* `doc` defaults to the ambient `document`. Pass a same-origin child frame's
|
|
6
|
+
* `contentDocument` to read ITS surface instead (the shell targets the wrapped
|
|
7
|
+
* iframe this way). Cross-origin access throws — caught and returned as `null`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getModelContext(doc?: Document | null): EdgeMcpModelContext | null;
|
|
4
10
|
/**
|
|
5
11
|
* Discover `document.modelContext`, polling briefly if it is not present yet.
|
|
6
12
|
*
|
|
7
13
|
* Resolves with the model context if found, or `null` after `timeoutMs` if no
|
|
8
14
|
* WebMCP surface shows up. Never rejects.
|
|
9
15
|
*
|
|
10
|
-
* @param timeoutMs How long to wait for a late-installing polyfill. Default
|
|
11
|
-
*
|
|
12
|
-
*
|
|
16
|
+
* @param timeoutMs How long to wait for a late-installing polyfill. Default 1500ms.
|
|
17
|
+
* @param getDoc Optional getter for the document to read (re-evaluated each poll,
|
|
18
|
+
* since a targeted iframe's `contentDocument` changes as it navigates).
|
|
19
|
+
* Omit to use the ambient `document`.
|
|
13
20
|
*/
|
|
14
|
-
export declare function discoverModelContext(timeoutMs?: number): Promise<EdgeMcpModelContext | null>;
|
|
21
|
+
export declare function discoverModelContext(timeoutMs?: number, getDoc?: () => Document | null): Promise<EdgeMcpModelContext | null>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { NapsterCompanionApiConfig, NapsterCompanionApiInstance } from "../types";
|
|
2
|
+
export interface ShellOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Returns a fresh connection token. The site implements this (typically a POST to
|
|
5
|
+
* its own endpoint that mints a token server-side). Required.
|
|
6
|
+
*/
|
|
7
|
+
getToken: () => Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Persist the session across page navigation by wrapping the current page in a
|
|
10
|
+
* same-origin iframe on connect (needed for multi-page apps). Default: `false` —
|
|
11
|
+
* the avatar mounts inline in the current page and a full page navigation ends the
|
|
12
|
+
* session (a normal in-page widget). Turn on only when you need cross-navigation
|
|
13
|
+
* persistence.
|
|
14
|
+
*/
|
|
15
|
+
persist?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The ONLY URLs that break out of the iframe (open at the top window and end the session).
|
|
18
|
+
* A link is opened inside the iframe unless it matches this denylist — use it for URLs that
|
|
19
|
+
* can't be framed, e.g. an identity / SSO subdomain, or same-origin paths that redirect
|
|
20
|
+
* off-site. Everything not listed (including other cross-origin links) navigates in the iframe.
|
|
21
|
+
*/
|
|
22
|
+
persistConfig?: {
|
|
23
|
+
/**
|
|
24
|
+
* Hostnames to force out of the iframe. Matched as the exact host OR a parent domain —
|
|
25
|
+
* e.g. `"napster.com"` also matches `"identity.napster.com"`.
|
|
26
|
+
*/
|
|
27
|
+
domains?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* URLs to force out of the iframe: an absolute `"https://…"` (exact or prefix match), or a
|
|
30
|
+
* same-origin path prefix like `"/signout"`.
|
|
31
|
+
*/
|
|
32
|
+
urls?: string[];
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* SECOND persistence variant (no iframe). When a session is active and the user navigates
|
|
36
|
+
* (a normal full page load), automatically start a NEW session on the next page — so the
|
|
37
|
+
* avatar "follows" the user across pages. Each page is a fresh connection (the backend can
|
|
38
|
+
* resume the conversation by externalClientId). The intent is remembered in sessionStorage
|
|
39
|
+
* and cleared when the user ends the session. Ignored when `persist` (the iframe variant)
|
|
40
|
+
* is on. Default: `false`.
|
|
41
|
+
*/
|
|
42
|
+
reconnectOnNavigation?: boolean;
|
|
43
|
+
/** When `persist` is on, the URL to load in the iframe. Default: the current page (`location.href`). */
|
|
44
|
+
siteUrl?: string;
|
|
45
|
+
/** Element to build the launcher/iframe into. Default: `document.body`. */
|
|
46
|
+
mount?: HTMLElement;
|
|
47
|
+
/** Avatar config forwarded to `init()`. `mountContainer`/`layout` are managed by the shell. */
|
|
48
|
+
avatar?: Partial<NapsterCompanionApiConfig>;
|
|
49
|
+
/** The iframe `allow` attribute (Permissions Policy for the site). Default: `"autoplay; clipboard-write"`. */
|
|
50
|
+
iframeAllow?: string;
|
|
51
|
+
/** Launcher button label. Default: `"Talk to an agent"`. */
|
|
52
|
+
launcherLabel?: string;
|
|
53
|
+
/** Start a session immediately instead of showing a launcher. Default: `false`. */
|
|
54
|
+
autoConnect?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* While a session is active, mirror the iframe's path into the address bar (so inner
|
|
57
|
+
* pages stay shareable/bookmarkable) and follow parent back/forward into the iframe.
|
|
58
|
+
* Same-origin only. Default: `true`.
|
|
59
|
+
*/
|
|
60
|
+
syncHistory?: boolean;
|
|
61
|
+
/** Log shell lifecycle to the console. Default: `false`. */
|
|
62
|
+
debug?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface ShellController {
|
|
65
|
+
/** `true` if this call built the launcher (top-level); `false` if it no-oped (framed content). */
|
|
66
|
+
isShell: boolean;
|
|
67
|
+
/** The live avatar instance once connected, else `null`. */
|
|
68
|
+
getInstance(): NapsterCompanionApiInstance | null;
|
|
69
|
+
/** The site iframe while a session is active, else `null`. */
|
|
70
|
+
getIframe(): HTMLIFrameElement | null;
|
|
71
|
+
/** Start a session: connect the avatar (and, with `persist`, wrap the current page in the iframe). */
|
|
72
|
+
connect(): Promise<void>;
|
|
73
|
+
/** End the session (and, if wrapped, unwrap back to the plain site). */
|
|
74
|
+
disconnect(): void;
|
|
75
|
+
/** Remove the launcher and any active session/iframe. */
|
|
76
|
+
destroy(): void;
|
|
77
|
+
}
|
|
78
|
+
type InitFn = (token: string, config?: Partial<NapsterCompanionApiConfig>) => Promise<NapsterCompanionApiInstance>;
|
|
79
|
+
/**
|
|
80
|
+
* Build the lazy persistent-agent shell. Returns a {@link ShellController}.
|
|
81
|
+
*
|
|
82
|
+
* A no-op (returns a controller with `isShell: false`) when run inside the shell
|
|
83
|
+
* iframe (framed content), so the same snippet is safe to include on every page.
|
|
84
|
+
*
|
|
85
|
+
* `init` is the SDK's `init` method, wired by the SDK.
|
|
86
|
+
*/
|
|
87
|
+
export declare function mountShell(init: InitFn, options: ShellOptions): ShellController;
|
|
88
|
+
export {};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -335,6 +335,13 @@ export interface NapsterCompanionApiConfig {
|
|
|
335
335
|
functions?: CompanionFunction[];
|
|
336
336
|
/** Enable debug logging throughout the SDK. When enabled, detailed logs will be output to the console. */
|
|
337
337
|
debug?: boolean;
|
|
338
|
+
/**
|
|
339
|
+
* Read WebMCP tools from a same-origin child iframe's `document.modelContext` instead of
|
|
340
|
+
* this window's. Set by the persistent-agent shell (`mountShell` with `persist`) so the
|
|
341
|
+
* avatar in the top-level document operates the SITE running inside the wrapped iframe.
|
|
342
|
+
* Leave unset for a normal same-page integration.
|
|
343
|
+
*/
|
|
344
|
+
edgeMcpIframe?: HTMLIFrameElement;
|
|
338
345
|
/** Analytics configuration controls analytics delivery and tracking. */
|
|
339
346
|
analytics?: AnalyticsConfig;
|
|
340
347
|
/** Lifecycle callbacks. All are optional. */
|
|
@@ -456,6 +463,12 @@ export interface NapsterCompanionApiSDK {
|
|
|
456
463
|
* Returns a Promise that resolves to a controllable `NapsterCompanionApiInstance`.
|
|
457
464
|
*/
|
|
458
465
|
init(token: string, config?: Partial<NapsterCompanionApiConfig>): Promise<NapsterCompanionApiInstance>;
|
|
466
|
+
/**
|
|
467
|
+
* Mount a persistent-agent shell for multi-page apps: renders the site in a
|
|
468
|
+
* same-origin iframe with the avatar in the top-level shell, so the agent
|
|
469
|
+
* session survives navigation. No-op when run as the framed content.
|
|
470
|
+
*/
|
|
471
|
+
mountShell(options: import("../shell/mount-shell").ShellOptions): import("../shell/mount-shell").ShellController;
|
|
459
472
|
/** The SDK version string (useful for diagnostics). */
|
|
460
473
|
version: string;
|
|
461
474
|
}
|