@matterfact/embed 0.9.0 → 0.11.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 +122 -0
- package/dist/{chunk-6EM7T2JV.js → chunk-AANODHBV.js} +217 -15
- package/dist/chunk-AANODHBV.js.map +1 -0
- package/dist/{chunk-URGQBG4I.js → chunk-CTZEDOH7.js} +218 -17
- package/dist/chunk-CTZEDOH7.js.map +1 -0
- package/dist/{chunk-BKKXHSYU.js → chunk-JO3GWFMJ.js} +2 -2
- package/dist/chunk-SKJFF7RD.js +2 -0
- package/dist/chunk-Y7I25VHL.js +3 -0
- package/dist/chunk-Y7I25VHL.js.map +7 -0
- package/dist/context-FR7VFENN.js +3 -0
- package/dist/{context-ACFBWIFH.js.map → context-FR7VFENN.js.map} +1 -1
- package/dist/{context-U2HJJN2S.js → context-IK5MECUW.js} +4 -2
- package/dist/embed.js +1 -1
- package/dist/embed.js.map +3 -3
- package/dist/index.cjs +247 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +302 -15
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +174 -2
- package/dist/react.d.ts +174 -2
- package/dist/react.js +79 -3
- package/dist/react.js.map +1 -1
- package/dist/{snapshot-4GXT6PKZ.js → snapshot-2V5SDSH2.js} +2 -2
- package/dist/{snapshot-Y75SCGCM.js → snapshot-Y5BF2UJR.js} +3 -3
- package/dist/{snapshot-Y75SCGCM.js.map → snapshot-Y5BF2UJR.js.map} +1 -1
- package/examples/embed-demo/README.md +22 -0
- package/examples/embed-demo/src/App.tsx +105 -2
- package/examples/embed-demo/src/styles.css +29 -0
- package/package.json +1 -1
- package/dist/chunk-6EM7T2JV.js.map +0 -1
- package/dist/chunk-FEXG4LQJ.js +0 -3
- package/dist/chunk-FEXG4LQJ.js.map +0 -7
- package/dist/chunk-NWNMS34P.js +0 -2
- package/dist/chunk-URGQBG4I.js.map +0 -1
- package/dist/context-ACFBWIFH.js +0 -3
- /package/dist/{chunk-BKKXHSYU.js.map → chunk-JO3GWFMJ.js.map} +0 -0
- /package/dist/{chunk-NWNMS34P.js.map → chunk-SKJFF7RD.js.map} +0 -0
- /package/dist/{context-U2HJJN2S.js.map → context-IK5MECUW.js.map} +0 -0
- /package/dist/{snapshot-4GXT6PKZ.js.map → snapshot-2V5SDSH2.js.map} +0 -0
package/dist/react.d.cts
CHANGED
|
@@ -61,6 +61,76 @@ interface SiteMapEntry {
|
|
|
61
61
|
content?: ContentClass;
|
|
62
62
|
current?: boolean;
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* A DECLARED artifact grant — the `<MatterfactAgent artifacts>` prop (or
|
|
66
|
+
* `window.matterfact.artifacts`). Same wire shape as a grant discovered by scanning
|
|
67
|
+
* co-embedded `<MatterfactArtifact>` iframes, plus an optional `label`; it feeds the
|
|
68
|
+
* SAME `host.artifactGrants` channel. This is how a host makes a board reachable from
|
|
69
|
+
* a route where its iframe ISN'T mounted, without hidden zero-size iframes smuggling
|
|
70
|
+
* the token into the DOM. The token stays in the grant channel, never in message text.
|
|
71
|
+
*/
|
|
72
|
+
interface DeclaredArtifact {
|
|
73
|
+
slug: string;
|
|
74
|
+
owner: string;
|
|
75
|
+
token: string;
|
|
76
|
+
label?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One host-tool lifecycle event, surfaced to the host via `onToolEvent` (and the dev
|
|
80
|
+
* panel) — the host's own telemetry hook. Fired loader-side; a throwing or slow
|
|
81
|
+
* callback here NEVER blocks or breaks the call path.
|
|
82
|
+
*
|
|
83
|
+
* - `advertise` — the merged tool list changed (fired with the new set's names).
|
|
84
|
+
* - `call` — a tool call is about to run (`args` present).
|
|
85
|
+
* - `result` — the call settled (`ok`/`error`/`ms`).
|
|
86
|
+
*/
|
|
87
|
+
interface ToolEvent {
|
|
88
|
+
phase: 'advertise' | 'call' | 'result';
|
|
89
|
+
name: string;
|
|
90
|
+
toolClass: 'hoist' | 'mf' | 'app';
|
|
91
|
+
args?: unknown;
|
|
92
|
+
ok?: boolean;
|
|
93
|
+
error?: string;
|
|
94
|
+
ms?: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* One embed lifecycle event, surfaced to the host via `onEvent` — the host's single
|
|
98
|
+
* telemetry hook. Fired loader-side (lifecycle) and widget-side (chat); a throwing or
|
|
99
|
+
* slow callback NEVER blocks or breaks the mount/call/auth/run path.
|
|
100
|
+
*
|
|
101
|
+
* - `ready` — the widget connected (protocol handshake done).
|
|
102
|
+
* - `open`/`close` — the corner widget was opened/closed. (Inline has no open event —
|
|
103
|
+
* the host's own panel is the open/close control.)
|
|
104
|
+
* - `navigate` — the agent deeplinked the host to one of its own routes.
|
|
105
|
+
* - `auth` — host-auth passthrough: `required` (widget asked), `granted` (a
|
|
106
|
+
* token was handed over), `failed` (no provider result / the provider threw).
|
|
107
|
+
* - `error` — the widget failed to mount / load.
|
|
108
|
+
* - `chat` — a chat-turn moment. Content-free: phase + opaque chatId only.
|
|
109
|
+
* - `tool` — a host-tool lifecycle event (the `ToolEvent` shape, tagged). Also
|
|
110
|
+
* still delivered untagged to the legacy `onToolEvent` hook for back-compat.
|
|
111
|
+
*/
|
|
112
|
+
type MatterfactEvent = {
|
|
113
|
+
type: 'ready';
|
|
114
|
+
} | {
|
|
115
|
+
type: 'open';
|
|
116
|
+
} | {
|
|
117
|
+
type: 'close';
|
|
118
|
+
} | {
|
|
119
|
+
type: 'navigate';
|
|
120
|
+
href: string;
|
|
121
|
+
} | {
|
|
122
|
+
type: 'auth';
|
|
123
|
+
phase: 'required' | 'granted' | 'failed';
|
|
124
|
+
} | {
|
|
125
|
+
type: 'error';
|
|
126
|
+
message: string;
|
|
127
|
+
} | {
|
|
128
|
+
type: 'chat';
|
|
129
|
+
phase: 'message' | 'response-start' | 'response-end';
|
|
130
|
+
chatId?: string;
|
|
131
|
+
} | ({
|
|
132
|
+
type: 'tool';
|
|
133
|
+
} & ToolEvent);
|
|
64
134
|
|
|
65
135
|
/**
|
|
66
136
|
* The Hoist adapter — a pure transform from a `HoistRuntime` (already read out of
|
|
@@ -83,6 +153,64 @@ interface HoistActionsConfig {
|
|
|
83
153
|
navigate: 'off' | 'confirm' | 'auto';
|
|
84
154
|
}
|
|
85
155
|
|
|
156
|
+
/**
|
|
157
|
+
* The host-tool registry — the ONE place the three tool classes are merged into the
|
|
158
|
+
* single list the widget advertises, and the ONE execution path for calling any of
|
|
159
|
+
* them.
|
|
160
|
+
*
|
|
161
|
+
* Three classes, distinguished by who owns the contract and who runs the code:
|
|
162
|
+
*
|
|
163
|
+
* - `hoist.*` matterfact-defined, matterfact-implemented. The loader adapter runs
|
|
164
|
+
* them (today: `hoist.navigate`). Gated on `window.XH` + the host's
|
|
165
|
+
* `hoist.actions` policy. See `hoist-runtime.ts`.
|
|
166
|
+
* - `mf.*` matterfact-defined, HOST-implemented. WE fix the name, schema and
|
|
167
|
+
* agent semantics (the description is authored HERE, not per
|
|
168
|
+
* integration); the host supplies the function via `resolve.*`. Today:
|
|
169
|
+
* `mf.resolveDocument`, `mf.resolveArtifact`.
|
|
170
|
+
* - `app.*` host-defined, host-implemented. Anything the host advertises via
|
|
171
|
+
* `tools`. Normalised into the `app.` namespace so it can never shadow
|
|
172
|
+
* ours.
|
|
173
|
+
*
|
|
174
|
+
* Everything downstream (the widget's confirm gate, the backend dispatcher) is already
|
|
175
|
+
* generic over "a tool with a name/schema/confirm and a call round-trip" — this module
|
|
176
|
+
* is purely the loader-side composition + dispatch, so `hoist-runtime.ts` stays one
|
|
177
|
+
* adapter rather than the whole surface.
|
|
178
|
+
*
|
|
179
|
+
* SECURITY: `mf.*`/`app.*` handlers are HOST code. Their results and error strings pass
|
|
180
|
+
* through `redact()` before leaving the page, exactly like the hoist adapter's; a
|
|
181
|
+
* handler that throws or hangs becomes a normal `{ok:false}` result, never an exception
|
|
182
|
+
* into `context.ts`. And the SERVER decides which of these an app may actually expose
|
|
183
|
+
* (the `host_tools` policy) — advertising here is necessary but not sufficient.
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
/** A host-supplied resolver: matterfact fixes the contract, the host implements it. */
|
|
187
|
+
interface HostResolvers {
|
|
188
|
+
document?: (args: {
|
|
189
|
+
doctype: string;
|
|
190
|
+
key: string;
|
|
191
|
+
}) => Promise<{
|
|
192
|
+
id: string;
|
|
193
|
+
label: string;
|
|
194
|
+
href?: string;
|
|
195
|
+
}>;
|
|
196
|
+
artifact?: (args: {
|
|
197
|
+
slug: string;
|
|
198
|
+
}) => Promise<{
|
|
199
|
+
id: string;
|
|
200
|
+
owner: string;
|
|
201
|
+
token: string;
|
|
202
|
+
label: string;
|
|
203
|
+
}>;
|
|
204
|
+
}
|
|
205
|
+
/** A host-defined tool (the `tools` prop): a WebMCP-shaped descriptor plus its handler. */
|
|
206
|
+
interface HostToolDef {
|
|
207
|
+
name: string;
|
|
208
|
+
description: string;
|
|
209
|
+
inputSchema?: Record<string, unknown>;
|
|
210
|
+
confirm?: 'auto' | 'required';
|
|
211
|
+
handler: (args: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
212
|
+
}
|
|
213
|
+
|
|
86
214
|
interface MatterfactAgentProps {
|
|
87
215
|
/** Publishable key (`pk_…`) identifying this embed app. Public, origin-scoped. */
|
|
88
216
|
publishableKey: string;
|
|
@@ -156,8 +284,52 @@ interface MatterfactAgentProps {
|
|
|
156
284
|
* on load and on navigation.
|
|
157
285
|
*/
|
|
158
286
|
sitemap?: SiteMapEntry[];
|
|
287
|
+
/**
|
|
288
|
+
* Declared artifact grants — make a board reachable from ANY route, even ones where
|
|
289
|
+
* its `<MatterfactArtifact>` iframe isn't mounted. Replaces the pattern of mounting
|
|
290
|
+
* hidden zero-size iframes purely to smuggle a read token into the DOM. The token
|
|
291
|
+
* rides the grant channel, never message text. Sugar over `window.matterfact.artifacts`.
|
|
292
|
+
*/
|
|
293
|
+
artifacts?: DeclaredArtifact[];
|
|
294
|
+
/**
|
|
295
|
+
* matterfact-defined resolver contracts the HOST implements. matterfact fixes the tool
|
|
296
|
+
* name, schema and agent semantics (so an integration spends no instruction budget on
|
|
297
|
+
* them); you supply the function.
|
|
298
|
+
*
|
|
299
|
+
* - `document({doctype, key})` → `{id, label, href?}` — resolve an off-page matterfact
|
|
300
|
+
* document (dossier/report) to its id, e.g. via your own content-location lookup.
|
|
301
|
+
* - `artifact({slug})` → `{id, owner, token, label}` — resolve an artifact to a read grant.
|
|
302
|
+
*
|
|
303
|
+
* The agent calls these when the site map shows the content lives on another route, and
|
|
304
|
+
* renders the result as an `<MFRef>` chip. Sugar over `window.matterfact.resolve`.
|
|
305
|
+
*/
|
|
306
|
+
resolve?: HostResolvers;
|
|
307
|
+
/**
|
|
308
|
+
* Host-defined tools (`app.*`): your own functions, offered to the agent WebMCP-style.
|
|
309
|
+
* Each is `{name, description, inputSchema?, confirm?, handler}`; the name is normalised
|
|
310
|
+
* into the `app.` namespace. A tool is only actually exposed if this app's server-side
|
|
311
|
+
* policy allows it. Sugar over `window.matterfact.tools`.
|
|
312
|
+
*/
|
|
313
|
+
tools?: HostToolDef[];
|
|
314
|
+
/**
|
|
315
|
+
* Host telemetry hook: fired on every host-tool advertise/call/result so you can pipe
|
|
316
|
+
* calls into your own observability. Never blocks or breaks the call path — a throw here
|
|
317
|
+
* is swallowed. Sugar over `window.matterfact.onToolEvent`.
|
|
318
|
+
*
|
|
319
|
+
* NOTE: this is now a SUBSET of `onEvent` (the tool events only), kept for back-compat.
|
|
320
|
+
* Prefer `onEvent` for new integrations — it delivers these same tool events (tagged
|
|
321
|
+
* `type:'tool'`) alongside the widget's lifecycle and chat events.
|
|
322
|
+
*/
|
|
323
|
+
onToolEvent?: (e: ToolEvent) => void;
|
|
324
|
+
/**
|
|
325
|
+
* UNIFIED host telemetry hook: fired on every embed lifecycle moment — `ready`,
|
|
326
|
+
* `open`/`close`, `navigate`, `auth`, `error`, `chat`, and `tool` — so you can pipe the
|
|
327
|
+
* whole widget into your own observability from one place. Never blocks or breaks the
|
|
328
|
+
* widget; a throw here is swallowed. Sugar over `window.matterfact.onEvent`.
|
|
329
|
+
*/
|
|
330
|
+
onEvent?: (e: MatterfactEvent) => void;
|
|
159
331
|
}
|
|
160
|
-
declare function MatterfactAgent({ publishableKey, widgetOrigin, surface, theme, getAuthToken, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
332
|
+
declare function MatterfactAgent({ publishableKey, widgetOrigin, surface, theme, getAuthToken, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
161
333
|
interface MatterfactArtifactProps {
|
|
162
334
|
/** The artifact's slug/name. */
|
|
163
335
|
slug: string;
|
|
@@ -178,4 +350,4 @@ interface MatterfactArtifactProps {
|
|
|
178
350
|
*/
|
|
179
351
|
declare function MatterfactArtifact({ slug, owner, token, widgetOrigin, theme, className, style, }: MatterfactArtifactProps): react_jsx_runtime.JSX.Element;
|
|
180
352
|
|
|
181
|
-
export { MatterfactAgent, type MatterfactAgentProps, MatterfactArtifact, type MatterfactArtifactProps };
|
|
353
|
+
export { type HostResolvers, type HostToolDef, MatterfactAgent, type MatterfactAgentProps, MatterfactArtifact, type MatterfactArtifactProps };
|
package/dist/react.d.ts
CHANGED
|
@@ -61,6 +61,76 @@ interface SiteMapEntry {
|
|
|
61
61
|
content?: ContentClass;
|
|
62
62
|
current?: boolean;
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* A DECLARED artifact grant — the `<MatterfactAgent artifacts>` prop (or
|
|
66
|
+
* `window.matterfact.artifacts`). Same wire shape as a grant discovered by scanning
|
|
67
|
+
* co-embedded `<MatterfactArtifact>` iframes, plus an optional `label`; it feeds the
|
|
68
|
+
* SAME `host.artifactGrants` channel. This is how a host makes a board reachable from
|
|
69
|
+
* a route where its iframe ISN'T mounted, without hidden zero-size iframes smuggling
|
|
70
|
+
* the token into the DOM. The token stays in the grant channel, never in message text.
|
|
71
|
+
*/
|
|
72
|
+
interface DeclaredArtifact {
|
|
73
|
+
slug: string;
|
|
74
|
+
owner: string;
|
|
75
|
+
token: string;
|
|
76
|
+
label?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One host-tool lifecycle event, surfaced to the host via `onToolEvent` (and the dev
|
|
80
|
+
* panel) — the host's own telemetry hook. Fired loader-side; a throwing or slow
|
|
81
|
+
* callback here NEVER blocks or breaks the call path.
|
|
82
|
+
*
|
|
83
|
+
* - `advertise` — the merged tool list changed (fired with the new set's names).
|
|
84
|
+
* - `call` — a tool call is about to run (`args` present).
|
|
85
|
+
* - `result` — the call settled (`ok`/`error`/`ms`).
|
|
86
|
+
*/
|
|
87
|
+
interface ToolEvent {
|
|
88
|
+
phase: 'advertise' | 'call' | 'result';
|
|
89
|
+
name: string;
|
|
90
|
+
toolClass: 'hoist' | 'mf' | 'app';
|
|
91
|
+
args?: unknown;
|
|
92
|
+
ok?: boolean;
|
|
93
|
+
error?: string;
|
|
94
|
+
ms?: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* One embed lifecycle event, surfaced to the host via `onEvent` — the host's single
|
|
98
|
+
* telemetry hook. Fired loader-side (lifecycle) and widget-side (chat); a throwing or
|
|
99
|
+
* slow callback NEVER blocks or breaks the mount/call/auth/run path.
|
|
100
|
+
*
|
|
101
|
+
* - `ready` — the widget connected (protocol handshake done).
|
|
102
|
+
* - `open`/`close` — the corner widget was opened/closed. (Inline has no open event —
|
|
103
|
+
* the host's own panel is the open/close control.)
|
|
104
|
+
* - `navigate` — the agent deeplinked the host to one of its own routes.
|
|
105
|
+
* - `auth` — host-auth passthrough: `required` (widget asked), `granted` (a
|
|
106
|
+
* token was handed over), `failed` (no provider result / the provider threw).
|
|
107
|
+
* - `error` — the widget failed to mount / load.
|
|
108
|
+
* - `chat` — a chat-turn moment. Content-free: phase + opaque chatId only.
|
|
109
|
+
* - `tool` — a host-tool lifecycle event (the `ToolEvent` shape, tagged). Also
|
|
110
|
+
* still delivered untagged to the legacy `onToolEvent` hook for back-compat.
|
|
111
|
+
*/
|
|
112
|
+
type MatterfactEvent = {
|
|
113
|
+
type: 'ready';
|
|
114
|
+
} | {
|
|
115
|
+
type: 'open';
|
|
116
|
+
} | {
|
|
117
|
+
type: 'close';
|
|
118
|
+
} | {
|
|
119
|
+
type: 'navigate';
|
|
120
|
+
href: string;
|
|
121
|
+
} | {
|
|
122
|
+
type: 'auth';
|
|
123
|
+
phase: 'required' | 'granted' | 'failed';
|
|
124
|
+
} | {
|
|
125
|
+
type: 'error';
|
|
126
|
+
message: string;
|
|
127
|
+
} | {
|
|
128
|
+
type: 'chat';
|
|
129
|
+
phase: 'message' | 'response-start' | 'response-end';
|
|
130
|
+
chatId?: string;
|
|
131
|
+
} | ({
|
|
132
|
+
type: 'tool';
|
|
133
|
+
} & ToolEvent);
|
|
64
134
|
|
|
65
135
|
/**
|
|
66
136
|
* The Hoist adapter — a pure transform from a `HoistRuntime` (already read out of
|
|
@@ -83,6 +153,64 @@ interface HoistActionsConfig {
|
|
|
83
153
|
navigate: 'off' | 'confirm' | 'auto';
|
|
84
154
|
}
|
|
85
155
|
|
|
156
|
+
/**
|
|
157
|
+
* The host-tool registry — the ONE place the three tool classes are merged into the
|
|
158
|
+
* single list the widget advertises, and the ONE execution path for calling any of
|
|
159
|
+
* them.
|
|
160
|
+
*
|
|
161
|
+
* Three classes, distinguished by who owns the contract and who runs the code:
|
|
162
|
+
*
|
|
163
|
+
* - `hoist.*` matterfact-defined, matterfact-implemented. The loader adapter runs
|
|
164
|
+
* them (today: `hoist.navigate`). Gated on `window.XH` + the host's
|
|
165
|
+
* `hoist.actions` policy. See `hoist-runtime.ts`.
|
|
166
|
+
* - `mf.*` matterfact-defined, HOST-implemented. WE fix the name, schema and
|
|
167
|
+
* agent semantics (the description is authored HERE, not per
|
|
168
|
+
* integration); the host supplies the function via `resolve.*`. Today:
|
|
169
|
+
* `mf.resolveDocument`, `mf.resolveArtifact`.
|
|
170
|
+
* - `app.*` host-defined, host-implemented. Anything the host advertises via
|
|
171
|
+
* `tools`. Normalised into the `app.` namespace so it can never shadow
|
|
172
|
+
* ours.
|
|
173
|
+
*
|
|
174
|
+
* Everything downstream (the widget's confirm gate, the backend dispatcher) is already
|
|
175
|
+
* generic over "a tool with a name/schema/confirm and a call round-trip" — this module
|
|
176
|
+
* is purely the loader-side composition + dispatch, so `hoist-runtime.ts` stays one
|
|
177
|
+
* adapter rather than the whole surface.
|
|
178
|
+
*
|
|
179
|
+
* SECURITY: `mf.*`/`app.*` handlers are HOST code. Their results and error strings pass
|
|
180
|
+
* through `redact()` before leaving the page, exactly like the hoist adapter's; a
|
|
181
|
+
* handler that throws or hangs becomes a normal `{ok:false}` result, never an exception
|
|
182
|
+
* into `context.ts`. And the SERVER decides which of these an app may actually expose
|
|
183
|
+
* (the `host_tools` policy) — advertising here is necessary but not sufficient.
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
/** A host-supplied resolver: matterfact fixes the contract, the host implements it. */
|
|
187
|
+
interface HostResolvers {
|
|
188
|
+
document?: (args: {
|
|
189
|
+
doctype: string;
|
|
190
|
+
key: string;
|
|
191
|
+
}) => Promise<{
|
|
192
|
+
id: string;
|
|
193
|
+
label: string;
|
|
194
|
+
href?: string;
|
|
195
|
+
}>;
|
|
196
|
+
artifact?: (args: {
|
|
197
|
+
slug: string;
|
|
198
|
+
}) => Promise<{
|
|
199
|
+
id: string;
|
|
200
|
+
owner: string;
|
|
201
|
+
token: string;
|
|
202
|
+
label: string;
|
|
203
|
+
}>;
|
|
204
|
+
}
|
|
205
|
+
/** A host-defined tool (the `tools` prop): a WebMCP-shaped descriptor plus its handler. */
|
|
206
|
+
interface HostToolDef {
|
|
207
|
+
name: string;
|
|
208
|
+
description: string;
|
|
209
|
+
inputSchema?: Record<string, unknown>;
|
|
210
|
+
confirm?: 'auto' | 'required';
|
|
211
|
+
handler: (args: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
212
|
+
}
|
|
213
|
+
|
|
86
214
|
interface MatterfactAgentProps {
|
|
87
215
|
/** Publishable key (`pk_…`) identifying this embed app. Public, origin-scoped. */
|
|
88
216
|
publishableKey: string;
|
|
@@ -156,8 +284,52 @@ interface MatterfactAgentProps {
|
|
|
156
284
|
* on load and on navigation.
|
|
157
285
|
*/
|
|
158
286
|
sitemap?: SiteMapEntry[];
|
|
287
|
+
/**
|
|
288
|
+
* Declared artifact grants — make a board reachable from ANY route, even ones where
|
|
289
|
+
* its `<MatterfactArtifact>` iframe isn't mounted. Replaces the pattern of mounting
|
|
290
|
+
* hidden zero-size iframes purely to smuggle a read token into the DOM. The token
|
|
291
|
+
* rides the grant channel, never message text. Sugar over `window.matterfact.artifacts`.
|
|
292
|
+
*/
|
|
293
|
+
artifacts?: DeclaredArtifact[];
|
|
294
|
+
/**
|
|
295
|
+
* matterfact-defined resolver contracts the HOST implements. matterfact fixes the tool
|
|
296
|
+
* name, schema and agent semantics (so an integration spends no instruction budget on
|
|
297
|
+
* them); you supply the function.
|
|
298
|
+
*
|
|
299
|
+
* - `document({doctype, key})` → `{id, label, href?}` — resolve an off-page matterfact
|
|
300
|
+
* document (dossier/report) to its id, e.g. via your own content-location lookup.
|
|
301
|
+
* - `artifact({slug})` → `{id, owner, token, label}` — resolve an artifact to a read grant.
|
|
302
|
+
*
|
|
303
|
+
* The agent calls these when the site map shows the content lives on another route, and
|
|
304
|
+
* renders the result as an `<MFRef>` chip. Sugar over `window.matterfact.resolve`.
|
|
305
|
+
*/
|
|
306
|
+
resolve?: HostResolvers;
|
|
307
|
+
/**
|
|
308
|
+
* Host-defined tools (`app.*`): your own functions, offered to the agent WebMCP-style.
|
|
309
|
+
* Each is `{name, description, inputSchema?, confirm?, handler}`; the name is normalised
|
|
310
|
+
* into the `app.` namespace. A tool is only actually exposed if this app's server-side
|
|
311
|
+
* policy allows it. Sugar over `window.matterfact.tools`.
|
|
312
|
+
*/
|
|
313
|
+
tools?: HostToolDef[];
|
|
314
|
+
/**
|
|
315
|
+
* Host telemetry hook: fired on every host-tool advertise/call/result so you can pipe
|
|
316
|
+
* calls into your own observability. Never blocks or breaks the call path — a throw here
|
|
317
|
+
* is swallowed. Sugar over `window.matterfact.onToolEvent`.
|
|
318
|
+
*
|
|
319
|
+
* NOTE: this is now a SUBSET of `onEvent` (the tool events only), kept for back-compat.
|
|
320
|
+
* Prefer `onEvent` for new integrations — it delivers these same tool events (tagged
|
|
321
|
+
* `type:'tool'`) alongside the widget's lifecycle and chat events.
|
|
322
|
+
*/
|
|
323
|
+
onToolEvent?: (e: ToolEvent) => void;
|
|
324
|
+
/**
|
|
325
|
+
* UNIFIED host telemetry hook: fired on every embed lifecycle moment — `ready`,
|
|
326
|
+
* `open`/`close`, `navigate`, `auth`, `error`, `chat`, and `tool` — so you can pipe the
|
|
327
|
+
* whole widget into your own observability from one place. Never blocks or breaks the
|
|
328
|
+
* widget; a throw here is swallowed. Sugar over `window.matterfact.onEvent`.
|
|
329
|
+
*/
|
|
330
|
+
onEvent?: (e: MatterfactEvent) => void;
|
|
159
331
|
}
|
|
160
|
-
declare function MatterfactAgent({ publishableKey, widgetOrigin, surface, theme, getAuthToken, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
332
|
+
declare function MatterfactAgent({ publishableKey, widgetOrigin, surface, theme, getAuthToken, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
161
333
|
interface MatterfactArtifactProps {
|
|
162
334
|
/** The artifact's slug/name. */
|
|
163
335
|
slug: string;
|
|
@@ -178,4 +350,4 @@ interface MatterfactArtifactProps {
|
|
|
178
350
|
*/
|
|
179
351
|
declare function MatterfactArtifact({ slug, owner, token, widgetOrigin, theme, className, style, }: MatterfactArtifactProps): react_jsx_runtime.JSX.Element;
|
|
180
352
|
|
|
181
|
-
export { MatterfactAgent, type MatterfactAgentProps, MatterfactArtifact, type MatterfactArtifactProps };
|
|
353
|
+
export { type HostResolvers, type HostToolDef, MatterfactAgent, type MatterfactAgentProps, MatterfactArtifact, type MatterfactArtifactProps };
|
package/dist/react.js
CHANGED
|
@@ -371,6 +371,21 @@ var EmbedHost = class {
|
|
|
371
371
|
__testHandle(msg) {
|
|
372
372
|
this.handle(msg);
|
|
373
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* The eager stub's own emit-and-swallow for the host's `onEvent` telemetry hook.
|
|
376
|
+
* Deliberately does NOT import the registry's `emitEvent`: pulling the lazy ./context
|
|
377
|
+
* chunk (where the registry lives) into the size-budgeted stub would blow it, so this
|
|
378
|
+
* ~5-line duplication across the bundle boundary is intentional. Host telemetry is
|
|
379
|
+
* host code — a throw here must never break the widget.
|
|
380
|
+
*/
|
|
381
|
+
emit(e) {
|
|
382
|
+
const cb = globalThis.matterfact?.onEvent;
|
|
383
|
+
if (typeof cb !== "function") return;
|
|
384
|
+
try {
|
|
385
|
+
cb(e);
|
|
386
|
+
} catch {
|
|
387
|
+
}
|
|
388
|
+
}
|
|
374
389
|
handle(msg) {
|
|
375
390
|
switch (msg.type) {
|
|
376
391
|
case "widget.ready":
|
|
@@ -383,8 +398,10 @@ var EmbedHost = class {
|
|
|
383
398
|
this.send({ type: "host.theme", mode: this.themeMode() });
|
|
384
399
|
this.flush();
|
|
385
400
|
if (this.inline) void this.loadContext();
|
|
401
|
+
this.emit({ type: "ready" });
|
|
386
402
|
break;
|
|
387
403
|
case "widget.setOpen":
|
|
404
|
+
this.emit({ type: msg.open ? "open" : "close" });
|
|
388
405
|
if (this.inline) break;
|
|
389
406
|
this.open = msg.open;
|
|
390
407
|
this.place();
|
|
@@ -573,11 +590,16 @@ var EmbedHost = class {
|
|
|
573
590
|
if (this.hostEl) this.hostEl.style.display = "none";
|
|
574
591
|
break;
|
|
575
592
|
case "widget.needsAuth":
|
|
593
|
+
this.emit({ type: "auth", phase: "required" });
|
|
576
594
|
void this.provideAuth();
|
|
577
595
|
break;
|
|
578
596
|
case "widget.navigate":
|
|
597
|
+
this.emit({ type: "navigate", href: msg.href });
|
|
579
598
|
void this.loadContext().then((m) => m.navigateHost(msg.href));
|
|
580
599
|
break;
|
|
600
|
+
case "widget.chat":
|
|
601
|
+
this.emit({ type: "chat", phase: msg.phase, chatId: msg.chatId });
|
|
602
|
+
break;
|
|
581
603
|
}
|
|
582
604
|
}
|
|
583
605
|
/**
|
|
@@ -690,11 +712,13 @@ var EmbedHost = class {
|
|
|
690
712
|
try {
|
|
691
713
|
const token = await provider();
|
|
692
714
|
if (token) this.send({ type: "host.auth", token, expiresAt: 0 });
|
|
715
|
+
this.emit({ type: "auth", phase: token ? "granted" : "failed" });
|
|
693
716
|
} catch {
|
|
717
|
+
this.emit({ type: "auth", phase: "failed" });
|
|
694
718
|
}
|
|
695
719
|
}
|
|
696
720
|
loadContext() {
|
|
697
|
-
this.context ?? (this.context = import("./context-
|
|
721
|
+
this.context ?? (this.context = import("./context-IK5MECUW.js").then((m) => {
|
|
698
722
|
m.start(
|
|
699
723
|
this.send,
|
|
700
724
|
this.config.origin,
|
|
@@ -747,6 +771,37 @@ function writeSitemapGlobal(sitemap) {
|
|
|
747
771
|
const w = window;
|
|
748
772
|
(w.matterfact ?? (w.matterfact = {})).sitemap = sitemap;
|
|
749
773
|
}
|
|
774
|
+
function writeToolGlobals(artifacts, resolve, tools, onToolEvent, onEvent) {
|
|
775
|
+
if (typeof window === "undefined") return;
|
|
776
|
+
const mf = window.matterfact ?? (window.matterfact = {});
|
|
777
|
+
mf.artifacts = artifacts ?? [];
|
|
778
|
+
mf.resolve = resolve ?? {};
|
|
779
|
+
mf.tools = tools ?? [];
|
|
780
|
+
mf.onToolEvent = onToolEvent;
|
|
781
|
+
mf.onEvent = onEvent;
|
|
782
|
+
}
|
|
783
|
+
function toolDescriptorKey(artifacts, resolve, tools) {
|
|
784
|
+
return JSON.stringify({
|
|
785
|
+
// Artifact identity is data (slug/owner/label), not a function.
|
|
786
|
+
artifacts: (artifacts ?? []).map((a) => ({
|
|
787
|
+
slug: a.slug,
|
|
788
|
+
owner: a.owner,
|
|
789
|
+
label: a.label
|
|
790
|
+
})),
|
|
791
|
+
// For resolvers, only WHICH contracts are present changes the advertised set.
|
|
792
|
+
resolve: {
|
|
793
|
+
document: typeof resolve?.document === "function",
|
|
794
|
+
artifact: typeof resolve?.artifact === "function"
|
|
795
|
+
},
|
|
796
|
+
// For host tools, the advertised descriptor — never the handler.
|
|
797
|
+
tools: (tools ?? []).map((t) => ({
|
|
798
|
+
name: t.name,
|
|
799
|
+
description: t.description,
|
|
800
|
+
inputSchema: t.inputSchema,
|
|
801
|
+
confirm: t.confirm
|
|
802
|
+
}))
|
|
803
|
+
});
|
|
804
|
+
}
|
|
750
805
|
function MatterfactAgent({
|
|
751
806
|
publishableKey,
|
|
752
807
|
widgetOrigin,
|
|
@@ -760,7 +815,12 @@ function MatterfactAgent({
|
|
|
760
815
|
pageContext,
|
|
761
816
|
dev,
|
|
762
817
|
actions,
|
|
763
|
-
sitemap
|
|
818
|
+
sitemap,
|
|
819
|
+
artifacts,
|
|
820
|
+
resolve,
|
|
821
|
+
tools,
|
|
822
|
+
onToolEvent,
|
|
823
|
+
onEvent
|
|
764
824
|
}) {
|
|
765
825
|
const authRef = useRef(getAuthToken);
|
|
766
826
|
authRef.current = getAuthToken;
|
|
@@ -774,10 +834,15 @@ function MatterfactAgent({
|
|
|
774
834
|
useEffect(() => {
|
|
775
835
|
writeSitemapGlobal(sitemap);
|
|
776
836
|
}, [sitemapKey]);
|
|
837
|
+
useEffect(() => {
|
|
838
|
+
writeToolGlobals(artifacts, resolve, tools, onToolEvent, onEvent);
|
|
839
|
+
});
|
|
840
|
+
const toolsKey = toolDescriptorKey(artifacts, resolve, tools);
|
|
777
841
|
useEffect(() => {
|
|
778
842
|
if (typeof window === "undefined") return;
|
|
779
843
|
if (inline && !slot.current) return;
|
|
780
844
|
writeActionsGlobal(actionsRef.current);
|
|
845
|
+
writeToolGlobals(artifacts, resolve, tools, onToolEvent, onEvent);
|
|
781
846
|
const config = {
|
|
782
847
|
publishableKey,
|
|
783
848
|
origin: widgetOrigin || DEFAULT_ORIGIN,
|
|
@@ -798,6 +863,13 @@ function MatterfactAgent({
|
|
|
798
863
|
host = mount(config);
|
|
799
864
|
} catch (e) {
|
|
800
865
|
console.error("[matterfact] failed to mount the embed widget", e);
|
|
866
|
+
try {
|
|
867
|
+
window.matterfact?.onEvent?.({
|
|
868
|
+
type: "error",
|
|
869
|
+
message: e instanceof Error ? e.message : String(e)
|
|
870
|
+
});
|
|
871
|
+
} catch {
|
|
872
|
+
}
|
|
801
873
|
}
|
|
802
874
|
return () => host?.destroy();
|
|
803
875
|
}, [
|
|
@@ -808,7 +880,11 @@ function MatterfactAgent({
|
|
|
808
880
|
inline,
|
|
809
881
|
pageContext,
|
|
810
882
|
dev,
|
|
811
|
-
actionsKey
|
|
883
|
+
actionsKey,
|
|
884
|
+
// A change to the advertised tool SHAPE remounts so start() re-advertises under it;
|
|
885
|
+
// a change to only a handler body or callback identity does not (see toolDescriptorKey).
|
|
886
|
+
toolsKey
|
|
887
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
812
888
|
]);
|
|
813
889
|
if (!inline) return null;
|
|
814
890
|
return /* @__PURE__ */ jsx(
|