@nimblebrain/synapse 0.19.0 → 0.21.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 +20 -25
- package/dist/check-QMTOCTRS.js +474 -0
- package/dist/check-QMTOCTRS.js.map +1 -0
- package/dist/check-VK4SOAUU.cjs +480 -0
- package/dist/check-VK4SOAUU.cjs.map +1 -0
- package/dist/{chunk-RU64F5RS.cjs → chunk-BNF352SA.cjs} +57 -146
- package/dist/chunk-BNF352SA.cjs.map +1 -0
- package/dist/{chunk-DRLVEHCD.js → chunk-DJS2FKBN.js} +21 -79
- package/dist/chunk-DJS2FKBN.js.map +1 -0
- package/dist/chunk-H3INUKA3.js +32 -0
- package/dist/chunk-H3INUKA3.js.map +1 -0
- package/dist/chunk-HQLSVUOR.cjs +667 -0
- package/dist/chunk-HQLSVUOR.cjs.map +1 -0
- package/dist/{chunk-NP7ROSH2.cjs → chunk-ISV6HFQE.cjs} +14 -7
- package/dist/chunk-ISV6HFQE.cjs.map +1 -0
- package/dist/chunk-TR2YNWZ5.js +658 -0
- package/dist/chunk-TR2YNWZ5.js.map +1 -0
- package/dist/{chunk-OYLZ5OCK.js → chunk-UKP4W6DI.js} +57 -146
- package/dist/chunk-UKP4W6DI.js.map +1 -0
- package/dist/{chunk-SZWHFTXV.cjs → chunk-YSL7KJNU.cjs} +21 -81
- package/dist/chunk-YSL7KJNU.cjs.map +1 -0
- package/dist/codegen/cli.cjs +41 -4
- package/dist/codegen/cli.cjs.map +1 -1
- package/dist/codegen/cli.js +41 -4
- package/dist/codegen/cli.js.map +1 -1
- package/dist/codegen/index.cjs +0 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.js +0 -1
- package/dist/connect.iife.global.js +34 -34
- package/dist/{detect-DZMJsyvZ.d.cts → detect-DVGaL2bH.d.cts} +39 -33
- package/dist/{detect-DBwc8a21.d.ts → detect-DVGaL2bH.d.ts} +39 -33
- package/dist/host/index.cjs +17 -18
- package/dist/host/index.d.cts +11 -27
- package/dist/host/index.d.ts +11 -27
- package/dist/host/index.js +2 -3
- package/dist/index.cjs +30 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -26
- package/dist/index.d.ts +72 -26
- package/dist/index.js +8 -9
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +9 -10
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +36 -8
- package/dist/react/index.d.ts +36 -8
- package/dist/react/index.js +3 -4
- package/dist/react/index.js.map +1 -1
- package/dist/schema-reader-776246MJ.js +3 -0
- package/dist/{schema-reader-GM4A4L44.js.map → schema-reader-776246MJ.js.map} +1 -1
- package/dist/{schema-reader-MWBRQ2TQ.cjs → schema-reader-B6LTGBMJ.cjs} +2 -3
- package/dist/{schema-reader-MWBRQ2TQ.cjs.map → schema-reader-B6LTGBMJ.cjs.map} +1 -1
- package/dist/{server-LR6T6C44.cjs → server-BR5MNFOB.cjs} +13 -14
- package/dist/server-BR5MNFOB.cjs.map +1 -0
- package/dist/{server-UHPEE55X.js → server-OOEEWAEG.js} +13 -14
- package/dist/server-OOEEWAEG.js.map +1 -0
- package/dist/synapse-runtime.iife.global.js +34 -34
- package/dist/synapse-ui.iife.global.js +4 -4
- package/dist/type-generator-MZ4X4DE5.js +3 -0
- package/dist/{type-generator-ZYSVFK3X.js.map → type-generator-MZ4X4DE5.js.map} +1 -1
- package/dist/{type-generator-YTPFWLVG.cjs → type-generator-UA3L4OIA.cjs} +2 -3
- package/dist/{type-generator-YTPFWLVG.cjs.map → type-generator-UA3L4OIA.cjs.map} +1 -1
- package/dist/{types-CG08aO82.d.cts → types-BxPfGHKO.d.cts} +35 -43
- package/dist/{types-CG08aO82.d.ts → types-BxPfGHKO.d.ts} +35 -43
- package/dist/ui/base.cjs +0 -1
- package/dist/ui/base.cjs.map +1 -1
- package/dist/ui/base.js +0 -1
- package/dist/ui/base.js.map +1 -1
- package/dist/ui/index.cjs +0 -1
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +0 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/vite/index.cjs +10 -10
- package/dist/vite/index.cjs.map +1 -1
- package/dist/vite/index.js +6 -6
- package/dist/vite/index.js.map +1 -1
- package/dist/{writer-HDRCQSX2.cjs → writer-NDK4U6C5.cjs} +3 -3
- package/dist/{writer-HDRCQSX2.cjs.map → writer-NDK4U6C5.cjs.map} +1 -1
- package/dist/{writer-QNDPMEYD.js → writer-ZNBXYUYC.js} +3 -3
- package/dist/{writer-QNDPMEYD.js.map → writer-ZNBXYUYC.js.map} +1 -1
- package/package.json +6 -3
- package/dist/chunk-54W6IAHM.js +0 -24
- package/dist/chunk-54W6IAHM.js.map +0 -1
- package/dist/chunk-DRLVEHCD.js.map +0 -1
- package/dist/chunk-NP7ROSH2.cjs.map +0 -1
- package/dist/chunk-OYLZ5OCK.js.map +0 -1
- package/dist/chunk-P5DBJFSQ.js +0 -8459
- package/dist/chunk-P5DBJFSQ.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -9
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-Q7SFCCGT.cjs +0 -11
- package/dist/chunk-Q7SFCCGT.cjs.map +0 -1
- package/dist/chunk-QXDCA7QW.cjs +0 -8466
- package/dist/chunk-QXDCA7QW.cjs.map +0 -1
- package/dist/chunk-RU64F5RS.cjs.map +0 -1
- package/dist/chunk-SZWHFTXV.cjs.map +0 -1
- package/dist/schema-reader-GM4A4L44.js +0 -4
- package/dist/server-LR6T6C44.cjs.map +0 -1
- package/dist/server-UHPEE55X.js.map +0 -1
- package/dist/type-generator-ZYSVFK3X.js +0 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(){'use strict';
|
|
2
|
-
`),
|
|
1
|
+
(function(){'use strict';function v(e,n){if(!e)return null;let a=e.getElementById(n)?.textContent;if(!a)return null;try{return JSON.parse(a)??null}catch{return null}}var ce={"--color-background-primary":"#ffffff","--color-background-secondary":"#fafafa","--color-background-tertiary":"#f3f4f6","--color-text-primary":"#111827","--color-text-secondary":"#6b7280","--color-text-tertiary":"#9ca3af","--color-text-accent":"#2563eb","--nb-color-accent-foreground":"#ffffff","--color-border-primary":"#e5e7eb","--color-border-secondary":"#d1d5db","--color-ring-primary":"#2563eb","--nb-color-danger":"#dc2626","--nb-color-danger-foreground":"#ffffff","--nb-color-success":"#059669","--nb-color-warning":"#f59e0b","--nb-color-processing":"#7c3aed","--nb-color-processing-light":"#f3eeff","--nb-color-info-light":"#eef4ff"},de={"--color-background-primary":"#18181b","--color-background-secondary":"#27272a","--color-background-tertiary":"#2f2f34","--color-text-primary":"#fafafa","--color-text-secondary":"#a1a1aa","--color-text-tertiary":"#71717a","--color-text-accent":"#818cf8","--nb-color-accent-foreground":"#ffffff","--color-border-primary":"#3f3f46","--color-border-secondary":"#52525b","--color-ring-primary":"#818cf8","--nb-color-danger":"#f87171","--nb-color-danger-foreground":"#18181b","--nb-color-success":"#34d399","--nb-color-warning":"#fbbf24","--nb-color-processing":"#a78bfa","--nb-color-processing-light":"#2a2440","--nb-color-info-light":"#1e2a44"},le={light:ce,dark:de},ue="synapse-defaults",D="synapse-theme-defaults",U=new Set;function pe(){return typeof document<"u"&&typeof document.getElementById=="function"&&typeof document.createElement=="function"&&typeof document.head?.prepend=="function"}function fe(e){if(!pe())return;let n=Object.entries(le[e]).map(([s,l])=>` ${s}: ${l};`).join(`
|
|
2
|
+
`),o=`@layer ${ue} {
|
|
3
3
|
:root {
|
|
4
|
-
${
|
|
4
|
+
${n}
|
|
5
5
|
}
|
|
6
|
-
}`,
|
|
6
|
+
}`,a=document.getElementById(D);if(a){a.textContent!==o&&(a.textContent=o);return}let i=document.createElement("style");i.id=D,i.textContent=o,document.head.prepend(i);}function me(e,n){if(typeof document>"u")return;fe(e);let o={};if(n&&typeof n=="object")for(let[i,s]of Object.entries(n))typeof i=="string"&&typeof s=="string"&&(o[i]=s);let a=document.documentElement.style;if(typeof a.removeProperty=="function")for(let i of U)i in o||a.removeProperty(i);for(let[i,s]of Object.entries(o))a.setProperty(i,s);U=new Set(Object.keys(o));}function N(e,n){me(e,n);}function O(e){typeof document<"u"&&document.documentElement.setAttribute("data-theme",e.mode),N(e.mode,e.tokens);}var z="__mcp-host-fonts";function j(e){if(typeof document>"u"||document.getElementById(z))return;let n=document.createElement("style");n.id=z,n.textContent=e,document.head.appendChild(n);}function I(e){try{if(e?.matchMedia?.("(prefers-color-scheme: dark)").matches)return "dark"}catch{}return "light"}function C(e,n){return e==="light"||e==="dark"?e:n}var A=class extends Error{constructor(n,o){super(`"${n}" is not supported by the "${o}" host`),this.name="HostUnsupportedError";}},x=class extends Error{result;constructor(n,o){super(ge(o)??`tool "${n}" returned an error`),this.name="ToolCallError",this.result=o;}};function ge(e){let n=e?.content;if(Array.isArray(n))for(let o of n){let a=o;if(a?.type==="text"&&typeof a.text=="string"&&a.text!=="")return a.text}}function K(e){return e!=null&&typeof e=="object"&&e.isError===true}var w="synapse-ui-data",W="2026-01-26",F="ui/initialize",$="ui/notifications/initialized",G="ui/notifications/tool-result",Y="ui/notifications/host-context-changed",Z="ui/notifications/size-changed",q="ui/open-link",B="ui/message",Q="ui/resource-teardown",V="tools/call";function X(e,n){let o=n.dataElementId??w,a=null,i={mode:I(e),tokens:{}},s=new Set,l=false,d=null,p=u=>{if(l)return;let T=C(u.matches?"dark":"light",i.mode);if(T!==i.mode){i={mode:T,tokens:{}};for(let f of s)f(i);}};return {host:"generic",getData:()=>a,onData(){return ()=>{}},getTheme:()=>i,onTheme(u){return s.add(u),()=>s.delete(u)},async callTool(u){throw new A("callTool","generic")},sendPrompt(){},openLink(u){e.open(u,"_blank","noopener,noreferrer");},resize(){},capabilities(){return {pull:false,sendPrompt:false,openLink:true}},start(){a=v(e.document,o);try{d=e.matchMedia?.("(prefers-color-scheme: dark)")??null,d?.addEventListener?.("change",p);}catch{d=null;}},destroy(){l||(l=true,d?.removeEventListener?.("change",p),d=null,s.clear());}}}function J(e){let n=e?.styles?.css?.fonts;return typeof n=="string"&&n!==""?n:void 0}var ye=3e4;function ee(e,n){let o=n.dataElementId??w,a=n.autoResize!==false,i=null,s={mode:I(e),tokens:{}},l=new Set,d=new Set,p=false,u=false,T=1,f=new Map,S=-1,b=null,y=null,M=()=>e.parent??e;function _(t){M().postMessage(t,"*");}function R(t,r){_({jsonrpc:"2.0",method:t,params:r??{}});}function k(t,r){let c=T++;return new Promise((m,g)=>{let h=setTimeout(()=>{f.delete(c),g(new Error(`"${t}" timed out`));},ye);f.set(c,{resolve:m,reject:g,timer:h}),_({jsonrpc:"2.0",id:c,method:t,params:r??{}});})}function oe(t){if(t!=null){i=t;for(let r of l)r(t);}}function L(t){if(!t||typeof t!="object")return;let r=J(t);r!==void 0&&j(r);let{mode:c,tokens:m}=s,g=false;if(t.theme!=null){let P=C(t.theme,c);P!==c&&(c=P,g=true);}let h=t.styles;if(h?.variables&&typeof h.variables=="object"&&(m={...m,...h.variables},g=true),g){s={mode:c,tokens:m};for(let P of d)P(s);}}function E(t){if(p||!u)return;let r=typeof t=="number"?t:Math.ceil(e.document.body.scrollHeight);r!==S&&(S=r,R(Z,{height:r}));}function re(t){let r=Number(t.id),c=f.get(r);if(c)if(f.delete(r),clearTimeout(c.timer),t.error!=null){let m=t.error;c.reject(new Error(m.message??"request failed"));}else c.resolve(t.result);}function se(t,r){if(t===G){let c=r.structuredContent;oe(c??r);}else t===Y&&L(r);}function ie(t){t.method===Q&&_({jsonrpc:"2.0",id:t.id,result:{}});}let H=t=>{if(p||t.source&&t.source!==M())return;let r=t.data;!r||typeof r!="object"||r.jsonrpc!=="2.0"||(r.id!=null&&("result"in r||"error"in r)?re(r):typeof r.method=="string"&&(r.id!=null?ie(r):se(r.method,r.params??{})));};function ae(){y=()=>E(),e.addEventListener("resize",y),typeof e.ResizeObserver<"u"&&(b=new e.ResizeObserver(()=>E()),b.observe(e.document.body));}return {host:"mcp-apps",getData:()=>i,onData(t){return l.add(t),()=>l.delete(t)},getTheme:()=>s,onTheme(t){return d.add(t),()=>d.delete(t)},async callTool(t,r){return await k(V,{name:t,arguments:r??{}})},sendPrompt(t){k(B,{role:"user",content:[{type:"text",text:t}]}).catch(()=>{});},openLink(t){k(q,{url:t}).catch(()=>{});},resize(t){E(t);},capabilities(){return {pull:true,sendPrompt:true,openLink:true}},start(){e.addEventListener("message",H),i=v(e.document,o),a&&ae(),k(F,{appInfo:{name:n.name??"synapse-ui",version:n.version??"0.0.0"},appCapabilities:{availableDisplayModes:["inline"]},protocolVersion:W}).then(t=>{p||(L(t?.hostContext),R($,{}),u=true,E());}).catch(()=>{});},destroy(){if(!p){p=true,e.removeEventListener("message",H),y&&e.removeEventListener("resize",y),y=null,b?.disconnect(),b=null;for(let t of f.values())clearTimeout(t.timer),t.reject(new Error("adapter destroyed"));f.clear(),l.clear(),d.clear();}}}}function he(e){try{if(e.parent!=null&&e.parent!==e)return "mcp-apps"}catch{return "mcp-apps"}return "generic"}function Te(e,n,o){if(e==="mcp-apps")return ee(n,o);if(e==="generic")return X(n,o);throw new TypeError(`unknown host "${String(e)}": expected "mcp-apps" or "generic"`)}function te(e,n){let o=n.host??he(e);return Te(o,e,n)}function ne(e={}){let n=e.window??globalThis,o=te(n,e);O(o.getTheme());let a=o.onTheme(O);o.start();let i=false;return {data:()=>o.getData(),onData:s=>o.onData(s),theme:()=>o.getTheme(),onTheme:s=>o.onTheme(s),async callTool(s,l){let d=await o.callTool(s,l);if(K(d))throw new x(s,d);return d},sendPrompt:s=>o.sendPrompt(s),openLink:s=>o.openLink(s),resize:s=>o.resize(s),capabilities:()=>o.capabilities(),host:()=>o.host,destroy(){i||(i=true,a(),o.destroy());}}}globalThis.SynapseUI={connect:ne};})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"type-generator-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"type-generator-MZ4X4DE5.js"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkHLT5UBJF_cjs = require('./chunk-HLT5UBJF.cjs');
|
|
4
|
-
require('./chunk-Q7SFCCGT.cjs');
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
|
|
@@ -9,5 +8,5 @@ Object.defineProperty(exports, "generateTypes", {
|
|
|
9
8
|
enumerable: true,
|
|
10
9
|
get: function () { return chunkHLT5UBJF_cjs.generateTypes; }
|
|
11
10
|
});
|
|
12
|
-
//# sourceMappingURL=type-generator-
|
|
13
|
-
//# sourceMappingURL=type-generator-
|
|
11
|
+
//# sourceMappingURL=type-generator-UA3L4OIA.cjs.map
|
|
12
|
+
//# sourceMappingURL=type-generator-UA3L4OIA.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"type-generator-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"type-generator-UA3L4OIA.cjs"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpUiHostContext } from '@modelcontextprotocol/ext-apps';
|
|
1
|
+
import { McpUiHostContext, McpUiHostCapabilities } from '@modelcontextprotocol/ext-apps';
|
|
2
2
|
import { ReadResourceRequest, ReadResourceResult, Task } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -94,45 +94,9 @@ interface TaskHandle<TOutput = unknown> {
|
|
|
94
94
|
onStatus(cb: (task: Task) => void): () => void;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* One `@font-face` a host asks the app to load.
|
|
99
|
-
*
|
|
100
|
-
* The token contract can name a font (`--font-sans: 'Hanken Grotesk', system-ui`)
|
|
101
|
-
* but cannot *load* one — a CSS custom property carries a family name, never the
|
|
102
|
-
* `@font-face` rule behind it. An app iframe is its own document and inherits no
|
|
103
|
-
* `@font-face` from the host page, so a host that only sends tokens is naming a
|
|
104
|
-
* family the app has no way to render. This descriptor is the missing half.
|
|
105
|
-
*
|
|
106
|
-
* The SDK ships **no font data** — it applies what the host sends. A host that
|
|
107
|
-
* sends none leaves the web-safe fallbacks in `ui/tokens.ts` in force.
|
|
108
|
-
*/
|
|
109
|
-
interface FontFaceDescriptor {
|
|
110
|
-
/** Family name, matching the one used in the host's `--font-*` token value. */
|
|
111
|
-
family: string;
|
|
112
|
-
/**
|
|
113
|
-
* CSS `src` descriptor. Local and absolute URLs work identically —
|
|
114
|
-
* `url('/fonts/x.woff2') format('woff2')` or `url('https://cdn.example/x.woff2')`.
|
|
115
|
-
* Whatever origin this names must satisfy the app iframe's `font-src` CSP.
|
|
116
|
-
*/
|
|
117
|
-
src: string;
|
|
118
|
-
/** `font-weight` descriptor — a single weight (`400`) or a variable range (`400 700`). */
|
|
119
|
-
weight?: string;
|
|
120
|
-
/** `font-style` descriptor (`normal`, `italic`, …). */
|
|
121
|
-
style?: string;
|
|
122
|
-
/** `font-display` descriptor. Defaults to `swap` so text paints in the fallback first. */
|
|
123
|
-
display?: FontDisplayValue;
|
|
124
|
-
}
|
|
125
|
-
/** The CSS `font-display` values. Closed set — anything else is ignored. */
|
|
126
|
-
type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional";
|
|
127
97
|
interface Theme {
|
|
128
98
|
mode: "light" | "dark";
|
|
129
99
|
tokens: Record<string, string>;
|
|
130
|
-
/**
|
|
131
|
-
* Font faces the host wants loaded into the app document. Optional — a host
|
|
132
|
-
* that omits them leaves the web-safe fallbacks in force. Arrives over the
|
|
133
|
-
* wire as the `synapse/fontFaces` host-context extension.
|
|
134
|
-
*/
|
|
135
|
-
fontFaces?: FontFaceDescriptor[];
|
|
136
100
|
}
|
|
137
101
|
interface ToolCallResult<T = unknown> {
|
|
138
102
|
data: T;
|
|
@@ -215,8 +179,8 @@ interface ConnectOptions {
|
|
|
215
179
|
* the clipboard keys the browser must handle itself); an array forwards
|
|
216
180
|
* exactly the listed combos. Absent means no forwarding.
|
|
217
181
|
*
|
|
218
|
-
*
|
|
219
|
-
* off everywhere else — a `preventDefault` on a host that does nothing with
|
|
182
|
+
* Forwarding is on only where the host declares `ai.nimblebrain/keydown`, and
|
|
183
|
+
* stays off everywhere else — a `preventDefault` on a host that does nothing with
|
|
220
184
|
* the key would swallow it for no one's benefit.
|
|
221
185
|
*/
|
|
222
186
|
forwardKeys?: boolean | KeyForwardConfig[];
|
|
@@ -264,7 +228,20 @@ interface App {
|
|
|
264
228
|
* host-specific fields as optional; another host will not send them.
|
|
265
229
|
*/
|
|
266
230
|
readonly hostContext: McpUiHostContext;
|
|
267
|
-
/**
|
|
231
|
+
/**
|
|
232
|
+
* What the host declared it supports, from the `ui/initialize` result. Every
|
|
233
|
+
* method here and every helper beside it checks this before it sends, and
|
|
234
|
+
* degrades in a documented way when the capability is absent. Read it to
|
|
235
|
+
* decide what to offer at all, rather than to find out from a no-op or an
|
|
236
|
+
* exception. NimbleBrain extensions are declared under `experimental`; see
|
|
237
|
+
* `hostSupports`.
|
|
238
|
+
*/
|
|
239
|
+
readonly hostCapabilities: McpUiHostCapabilities;
|
|
240
|
+
/**
|
|
241
|
+
* True when the host identified itself as NimbleBrain in the handshake.
|
|
242
|
+
* Identity, not capability: nothing is gated on it except the NimbleBrain
|
|
243
|
+
* chat context on `sendMessage` (`_meta["ai.nimblebrain/context"]`), which other hosts ignore.
|
|
244
|
+
*/
|
|
268
245
|
readonly isNimbleBrainHost: boolean;
|
|
269
246
|
/** True after `destroy()` has been called. */
|
|
270
247
|
readonly destroyed: boolean;
|
|
@@ -286,7 +263,12 @@ interface App {
|
|
|
286
263
|
on(event: "host-context-changed", handler: (ctx: McpUiHostContext) => void): () => void;
|
|
287
264
|
on(event: "teardown", handler: () => void): () => void;
|
|
288
265
|
on(event: string, handler: (params: any) => void): () => void;
|
|
266
|
+
/** Report the frame's size (`ui/notifications/size-changed`). Every host accepts it. */
|
|
289
267
|
resize(width?: number, height?: number): void;
|
|
268
|
+
/**
|
|
269
|
+
* Open a URL through the host (`ui/open-link`). Without `openLinks`, or when
|
|
270
|
+
* the host refuses, opens it with `window.open` instead.
|
|
271
|
+
*/
|
|
290
272
|
openLink(url: string): void;
|
|
291
273
|
/**
|
|
292
274
|
* Push the app's visible state to the agent (ext-apps
|
|
@@ -294,7 +276,8 @@ interface App {
|
|
|
294
276
|
* `state` rides along as `structuredContent` for tools that need the ids.
|
|
295
277
|
*
|
|
296
278
|
* Sends immediately. Callers that push on every keystroke or selection
|
|
297
|
-
* change want `useModelContext`, which debounces.
|
|
279
|
+
* change want `useModelContext`, which debounces. A no-op when the host did
|
|
280
|
+
* not declare `updateModelContext`.
|
|
298
281
|
*/
|
|
299
282
|
updateModelContext(state: Record<string, unknown>, summary?: string): void;
|
|
300
283
|
/**
|
|
@@ -304,15 +287,24 @@ interface App {
|
|
|
304
287
|
* to the server that mounted the app, so there is no target to name and no
|
|
305
288
|
* option to pass — cross-source work belongs to the agent, which can call
|
|
306
289
|
* two servers and hand one's result to the other.
|
|
290
|
+
*
|
|
291
|
+
* Rejects with `HostCapabilityError`, without sending, when the host did not
|
|
292
|
+
* declare `serverTools`.
|
|
307
293
|
*/
|
|
308
294
|
callTool<TOutput = unknown>(name: string, args?: Record<string, unknown>): Promise<ToolCallResult<TOutput>>;
|
|
309
295
|
/**
|
|
310
296
|
* Read an MCP resource from the originating server via the host bridge
|
|
311
297
|
* (ext-apps `resources/read`). Named to mirror the ext-apps spec's
|
|
312
298
|
* `App.readServerResource`.
|
|
299
|
+
*
|
|
300
|
+
* Rejects with `HostCapabilityError`, without sending, when the host did not
|
|
301
|
+
* declare `serverResources`.
|
|
313
302
|
*/
|
|
314
303
|
readServerResource(params: ReadResourceRequest["params"]): Promise<ReadResourceResult>;
|
|
315
|
-
/**
|
|
304
|
+
/**
|
|
305
|
+
* Send a user message into the agent conversation (ext-apps `ui/message`).
|
|
306
|
+
* A no-op when the host did not declare `message`.
|
|
307
|
+
*/
|
|
316
308
|
sendMessage(text: string, context?: {
|
|
317
309
|
action?: string;
|
|
318
310
|
entity?: string;
|
|
@@ -320,4 +312,4 @@ interface App {
|
|
|
320
312
|
destroy(): void;
|
|
321
313
|
}
|
|
322
314
|
|
|
323
|
-
export type { App as A, ConnectOptions as C, Dimensions as D, FileResult as F, KeyForwardConfig as K, ModelContext as M, RequestFileOptions as R, TaskHandle as T, CallToolAsTaskOptions as a, ToolCallResult as b, Theme as c, ToolResultData as d, ToolDefinition as e,
|
|
315
|
+
export type { App as A, ConnectOptions as C, Dimensions as D, FileResult as F, KeyForwardConfig as K, ModelContext as M, RequestFileOptions as R, TaskHandle as T, CallToolAsTaskOptions as a, ToolCallResult as b, Theme as c, ToolResultData as d, ToolDefinition as e, AppEventName as f, TasksCapability as g };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpUiHostContext } from '@modelcontextprotocol/ext-apps';
|
|
1
|
+
import { McpUiHostContext, McpUiHostCapabilities } from '@modelcontextprotocol/ext-apps';
|
|
2
2
|
import { ReadResourceRequest, ReadResourceResult, Task } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -94,45 +94,9 @@ interface TaskHandle<TOutput = unknown> {
|
|
|
94
94
|
onStatus(cb: (task: Task) => void): () => void;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* One `@font-face` a host asks the app to load.
|
|
99
|
-
*
|
|
100
|
-
* The token contract can name a font (`--font-sans: 'Hanken Grotesk', system-ui`)
|
|
101
|
-
* but cannot *load* one — a CSS custom property carries a family name, never the
|
|
102
|
-
* `@font-face` rule behind it. An app iframe is its own document and inherits no
|
|
103
|
-
* `@font-face` from the host page, so a host that only sends tokens is naming a
|
|
104
|
-
* family the app has no way to render. This descriptor is the missing half.
|
|
105
|
-
*
|
|
106
|
-
* The SDK ships **no font data** — it applies what the host sends. A host that
|
|
107
|
-
* sends none leaves the web-safe fallbacks in `ui/tokens.ts` in force.
|
|
108
|
-
*/
|
|
109
|
-
interface FontFaceDescriptor {
|
|
110
|
-
/** Family name, matching the one used in the host's `--font-*` token value. */
|
|
111
|
-
family: string;
|
|
112
|
-
/**
|
|
113
|
-
* CSS `src` descriptor. Local and absolute URLs work identically —
|
|
114
|
-
* `url('/fonts/x.woff2') format('woff2')` or `url('https://cdn.example/x.woff2')`.
|
|
115
|
-
* Whatever origin this names must satisfy the app iframe's `font-src` CSP.
|
|
116
|
-
*/
|
|
117
|
-
src: string;
|
|
118
|
-
/** `font-weight` descriptor — a single weight (`400`) or a variable range (`400 700`). */
|
|
119
|
-
weight?: string;
|
|
120
|
-
/** `font-style` descriptor (`normal`, `italic`, …). */
|
|
121
|
-
style?: string;
|
|
122
|
-
/** `font-display` descriptor. Defaults to `swap` so text paints in the fallback first. */
|
|
123
|
-
display?: FontDisplayValue;
|
|
124
|
-
}
|
|
125
|
-
/** The CSS `font-display` values. Closed set — anything else is ignored. */
|
|
126
|
-
type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional";
|
|
127
97
|
interface Theme {
|
|
128
98
|
mode: "light" | "dark";
|
|
129
99
|
tokens: Record<string, string>;
|
|
130
|
-
/**
|
|
131
|
-
* Font faces the host wants loaded into the app document. Optional — a host
|
|
132
|
-
* that omits them leaves the web-safe fallbacks in force. Arrives over the
|
|
133
|
-
* wire as the `synapse/fontFaces` host-context extension.
|
|
134
|
-
*/
|
|
135
|
-
fontFaces?: FontFaceDescriptor[];
|
|
136
100
|
}
|
|
137
101
|
interface ToolCallResult<T = unknown> {
|
|
138
102
|
data: T;
|
|
@@ -215,8 +179,8 @@ interface ConnectOptions {
|
|
|
215
179
|
* the clipboard keys the browser must handle itself); an array forwards
|
|
216
180
|
* exactly the listed combos. Absent means no forwarding.
|
|
217
181
|
*
|
|
218
|
-
*
|
|
219
|
-
* off everywhere else — a `preventDefault` on a host that does nothing with
|
|
182
|
+
* Forwarding is on only where the host declares `ai.nimblebrain/keydown`, and
|
|
183
|
+
* stays off everywhere else — a `preventDefault` on a host that does nothing with
|
|
220
184
|
* the key would swallow it for no one's benefit.
|
|
221
185
|
*/
|
|
222
186
|
forwardKeys?: boolean | KeyForwardConfig[];
|
|
@@ -264,7 +228,20 @@ interface App {
|
|
|
264
228
|
* host-specific fields as optional; another host will not send them.
|
|
265
229
|
*/
|
|
266
230
|
readonly hostContext: McpUiHostContext;
|
|
267
|
-
/**
|
|
231
|
+
/**
|
|
232
|
+
* What the host declared it supports, from the `ui/initialize` result. Every
|
|
233
|
+
* method here and every helper beside it checks this before it sends, and
|
|
234
|
+
* degrades in a documented way when the capability is absent. Read it to
|
|
235
|
+
* decide what to offer at all, rather than to find out from a no-op or an
|
|
236
|
+
* exception. NimbleBrain extensions are declared under `experimental`; see
|
|
237
|
+
* `hostSupports`.
|
|
238
|
+
*/
|
|
239
|
+
readonly hostCapabilities: McpUiHostCapabilities;
|
|
240
|
+
/**
|
|
241
|
+
* True when the host identified itself as NimbleBrain in the handshake.
|
|
242
|
+
* Identity, not capability: nothing is gated on it except the NimbleBrain
|
|
243
|
+
* chat context on `sendMessage` (`_meta["ai.nimblebrain/context"]`), which other hosts ignore.
|
|
244
|
+
*/
|
|
268
245
|
readonly isNimbleBrainHost: boolean;
|
|
269
246
|
/** True after `destroy()` has been called. */
|
|
270
247
|
readonly destroyed: boolean;
|
|
@@ -286,7 +263,12 @@ interface App {
|
|
|
286
263
|
on(event: "host-context-changed", handler: (ctx: McpUiHostContext) => void): () => void;
|
|
287
264
|
on(event: "teardown", handler: () => void): () => void;
|
|
288
265
|
on(event: string, handler: (params: any) => void): () => void;
|
|
266
|
+
/** Report the frame's size (`ui/notifications/size-changed`). Every host accepts it. */
|
|
289
267
|
resize(width?: number, height?: number): void;
|
|
268
|
+
/**
|
|
269
|
+
* Open a URL through the host (`ui/open-link`). Without `openLinks`, or when
|
|
270
|
+
* the host refuses, opens it with `window.open` instead.
|
|
271
|
+
*/
|
|
290
272
|
openLink(url: string): void;
|
|
291
273
|
/**
|
|
292
274
|
* Push the app's visible state to the agent (ext-apps
|
|
@@ -294,7 +276,8 @@ interface App {
|
|
|
294
276
|
* `state` rides along as `structuredContent` for tools that need the ids.
|
|
295
277
|
*
|
|
296
278
|
* Sends immediately. Callers that push on every keystroke or selection
|
|
297
|
-
* change want `useModelContext`, which debounces.
|
|
279
|
+
* change want `useModelContext`, which debounces. A no-op when the host did
|
|
280
|
+
* not declare `updateModelContext`.
|
|
298
281
|
*/
|
|
299
282
|
updateModelContext(state: Record<string, unknown>, summary?: string): void;
|
|
300
283
|
/**
|
|
@@ -304,15 +287,24 @@ interface App {
|
|
|
304
287
|
* to the server that mounted the app, so there is no target to name and no
|
|
305
288
|
* option to pass — cross-source work belongs to the agent, which can call
|
|
306
289
|
* two servers and hand one's result to the other.
|
|
290
|
+
*
|
|
291
|
+
* Rejects with `HostCapabilityError`, without sending, when the host did not
|
|
292
|
+
* declare `serverTools`.
|
|
307
293
|
*/
|
|
308
294
|
callTool<TOutput = unknown>(name: string, args?: Record<string, unknown>): Promise<ToolCallResult<TOutput>>;
|
|
309
295
|
/**
|
|
310
296
|
* Read an MCP resource from the originating server via the host bridge
|
|
311
297
|
* (ext-apps `resources/read`). Named to mirror the ext-apps spec's
|
|
312
298
|
* `App.readServerResource`.
|
|
299
|
+
*
|
|
300
|
+
* Rejects with `HostCapabilityError`, without sending, when the host did not
|
|
301
|
+
* declare `serverResources`.
|
|
313
302
|
*/
|
|
314
303
|
readServerResource(params: ReadResourceRequest["params"]): Promise<ReadResourceResult>;
|
|
315
|
-
/**
|
|
304
|
+
/**
|
|
305
|
+
* Send a user message into the agent conversation (ext-apps `ui/message`).
|
|
306
|
+
* A no-op when the host did not declare `message`.
|
|
307
|
+
*/
|
|
316
308
|
sendMessage(text: string, context?: {
|
|
317
309
|
action?: string;
|
|
318
310
|
entity?: string;
|
|
@@ -320,4 +312,4 @@ interface App {
|
|
|
320
312
|
destroy(): void;
|
|
321
313
|
}
|
|
322
314
|
|
|
323
|
-
export type { App as A, ConnectOptions as C, Dimensions as D, FileResult as F, KeyForwardConfig as K, ModelContext as M, RequestFileOptions as R, TaskHandle as T, CallToolAsTaskOptions as a, ToolCallResult as b, Theme as c, ToolResultData as d, ToolDefinition as e,
|
|
315
|
+
export type { App as A, ConnectOptions as C, Dimensions as D, FileResult as F, KeyForwardConfig as K, ModelContext as M, RequestFileOptions as R, TaskHandle as T, CallToolAsTaskOptions as a, ToolCallResult as b, Theme as c, ToolResultData as d, ToolDefinition as e, AppEventName as f, TasksCapability as g };
|
package/dist/ui/base.cjs
CHANGED
package/dist/ui/base.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/base.ts"],"names":["injectBaseReset"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/ui/base.ts"],"names":["injectBaseReset"],"mappings":";;;;;AAqBAA,iCAAA,EAAgB","file":"base.cjs","sourcesContent":["/**\n * Establishes the root-height chain a full-pane Synapse app needs. Import for\n * the side effect:\n *\n * ```ts\n * import \"@nimblebrain/synapse/ui/base\";\n * ```\n *\n * This injects `html, body, #root { height: 100% }` (so a `height: 100%` app\n * shell resolves against the iframe's allocated pane) and `body { margin: 0 }`\n * (so the pane has no UA-margin gap). See `./internal/base-reset.ts` for why a\n * percentage chain — not a viewport unit — is the correct mechanism.\n *\n * `AppFrame` already calls `injectBaseReset()` on render, so apps built on it\n * get the chain automatically. Import this module explicitly to establish the\n * chain *before* React mounts — avoiding a first-paint layout jump — or for an\n * app that renders a full-pane root without `AppFrame`.\n */\n\nimport { injectBaseReset } from \"./internal/base-reset.js\";\n\ninjectBaseReset();\n\nexport { injectBaseReset };\n"]}
|
package/dist/ui/base.js
CHANGED
package/dist/ui/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/base.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/ui/base.ts"],"names":[],"mappings":";;;;AAqBA,eAAA,EAAgB","file":"base.js","sourcesContent":["/**\n * Establishes the root-height chain a full-pane Synapse app needs. Import for\n * the side effect:\n *\n * ```ts\n * import \"@nimblebrain/synapse/ui/base\";\n * ```\n *\n * This injects `html, body, #root { height: 100% }` (so a `height: 100%` app\n * shell resolves against the iframe's allocated pane) and `body { margin: 0 }`\n * (so the pane has no UA-margin gap). See `./internal/base-reset.ts` for why a\n * percentage chain — not a viewport unit — is the correct mechanism.\n *\n * `AppFrame` already calls `injectBaseReset()` on render, so apps built on it\n * get the chain automatically. Import this module explicitly to establish the\n * chain *before* React mounts — avoiding a first-paint layout jump — or for an\n * app that renders a full-pane root without `AppFrame`.\n */\n\nimport { injectBaseReset } from \"./internal/base-reset.js\";\n\ninjectBaseReset();\n\nexport { injectBaseReset };\n"]}
|