@nimblebrain/synapse 0.12.1 → 0.13.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.
Files changed (55) hide show
  1. package/README.md +58 -4
  2. package/dist/{chunk-JVKQNMAP.js → chunk-5AR3IROW.js} +11 -6
  3. package/dist/chunk-5AR3IROW.js.map +1 -0
  4. package/dist/{chunk-XGJAADVV.js → chunk-AGN3NDOK.js} +25 -36
  5. package/dist/chunk-AGN3NDOK.js.map +1 -0
  6. package/dist/chunk-DOKVNVTI.js +162 -0
  7. package/dist/chunk-DOKVNVTI.js.map +1 -0
  8. package/dist/chunk-IA2M4GTK.cjs +170 -0
  9. package/dist/chunk-IA2M4GTK.cjs.map +1 -0
  10. package/dist/{chunk-A4ENX6XW.cjs → chunk-QHS7BJLI.cjs} +28 -39
  11. package/dist/chunk-QHS7BJLI.cjs.map +1 -0
  12. package/dist/{chunk-ANUZ7WFQ.cjs → chunk-VMUZMVKW.cjs} +11 -6
  13. package/dist/chunk-VMUZMVKW.cjs.map +1 -0
  14. package/dist/codegen/index.d.cts +1 -1
  15. package/dist/codegen/index.d.ts +1 -1
  16. package/dist/connect.iife.global.js +25 -25
  17. package/dist/{detect-DSnLT-_m.d.ts → detect-C_qmYsh9.d.cts} +6 -0
  18. package/dist/{detect-DSnLT-_m.d.cts → detect-Dfd0upoz.d.ts} +6 -0
  19. package/dist/host/index.cjs +14 -14
  20. package/dist/host/index.d.cts +10 -3
  21. package/dist/host/index.d.ts +10 -3
  22. package/dist/host/index.js +2 -2
  23. package/dist/index.cjs +13 -9
  24. package/dist/index.d.cts +16 -4
  25. package/dist/index.d.ts +16 -4
  26. package/dist/index.js +3 -3
  27. package/dist/react/index.cjs +5 -5
  28. package/dist/react/index.cjs.map +1 -1
  29. package/dist/react/index.d.cts +1 -1
  30. package/dist/react/index.d.ts +1 -1
  31. package/dist/react/index.js +3 -3
  32. package/dist/react/index.js.map +1 -1
  33. package/dist/synapse-runtime.iife.global.js +25 -25
  34. package/dist/synapse-ui.iife.global.js +1 -1
  35. package/dist/{types-C9utGXv_.d.cts → types-BSZasM8q.d.cts} +39 -1
  36. package/dist/{types-C9utGXv_.d.ts → types-BSZasM8q.d.ts} +39 -1
  37. package/dist/ui/index.cjs +34 -1
  38. package/dist/ui/index.cjs.map +1 -1
  39. package/dist/ui/index.js +34 -1
  40. package/dist/ui/index.js.map +1 -1
  41. package/package.json +1 -6
  42. package/dist/chunk-A4ENX6XW.cjs.map +0 -1
  43. package/dist/chunk-ANUZ7WFQ.cjs.map +0 -1
  44. package/dist/chunk-JVKQNMAP.js.map +0 -1
  45. package/dist/chunk-KTXASIFJ.cjs +0 -75
  46. package/dist/chunk-KTXASIFJ.cjs.map +0 -1
  47. package/dist/chunk-VXTMI266.js +0 -73
  48. package/dist/chunk-VXTMI266.js.map +0 -1
  49. package/dist/chunk-XGJAADVV.js.map +0 -1
  50. package/dist/ui/fonts.cjs +0 -19
  51. package/dist/ui/fonts.cjs.map +0 -1
  52. package/dist/ui/fonts.d.cts +0 -30
  53. package/dist/ui/fonts.d.ts +0 -30
  54. package/dist/ui/fonts.js +0 -17
  55. package/dist/ui/fonts.js.map +0 -1
@@ -1 +1 @@
1
- (function(){'use strict';var de={"--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-success":"#059669","--nb-color-warning":"#f59e0b","--nb-color-warm":"#d4620a","--nb-color-warm-light":"#fef5ee","--nb-color-processing":"#7c3aed","--nb-color-processing-light":"#f3eeff","--nb-color-info-light":"#eef4ff"},ue={"--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-success":"#34d399","--nb-color-warning":"#fbbf24","--nb-color-warm":"#fb923c","--nb-color-warm-light":"#3a2a1e","--nb-color-processing":"#a78bfa","--nb-color-processing-light":"#2a2440","--nb-color-info-light":"#1e2a44"},pe={light:de,dark:ue};function N(t,r){if(typeof document>"u")return;let n=document.documentElement.style;for(let[i,l]of Object.entries(pe[t]))n.setProperty(i,l);if(r&&typeof r=="object")for(let[i,l]of Object.entries(r))typeof i=="string"&&typeof l=="string"&&n.setProperty(i,l);}function R(t){typeof document<"u"&&document.documentElement.setAttribute("data-theme",t.mode),N(t.mode,t.tokens);}function C(t){try{if(t?.matchMedia?.("(prefers-color-scheme: dark)").matches)return "dark"}catch{}return "light"}function h(t,r){return t==="light"||t==="dark"?t:r}var b=class extends Error{constructor(r,n){super(`"${r}" is not supported by the "${n}" host`),this.name="HostUnsupportedError";}},A="synapse-ui-data",z="ui-lifecycle-iframe-ready",j="ui-lifecycle-iframe-render-data",G="ui-size-change",K="link",W="prompt",S="openai:set_globals",F="2026-01-26",Z="ui/initialize",q="ui/notifications/initialized",Y="ui/notifications/tool-result",V="ui/notifications/host-context-changed",B="ui/notifications/size-changed",Q="ui/open-link",$="ui/message",X="ui/resource-teardown",J="tools/call";function ee(t,r){let n=()=>t.openai,i=n()?.toolOutput??null,l={mode:h(n()?.theme,"light"),tokens:{}},a=new Set,p=new Set,f=false,m=s=>{if(f)return;let c=s.detail?.globals;if(c){if("toolOutput"in c&&c.toolOutput!=null){i=c.toolOutput;for(let u of a)u(i);}if("theme"in c&&c.theme!=null){let u=h(c.theme,l.mode);if(u!==l.mode){l={mode:u,tokens:{}};for(let P of p)P(l);}}}};return {host:"chatgpt",getData:()=>i,onData(s){return a.add(s),()=>a.delete(s)},getTheme:()=>l,onTheme(s){return p.add(s),()=>p.delete(s)},async callTool(s,c){let u=n()?.callTool;if(!u)throw new b("callTool","chatgpt");return await u(s,c??{})},sendPrompt(s){let c=n();(c?.sendFollowUpMessage??c?.sendFollowupMessage)?.({prompt:s});},openLink(s){let c=n()?.openExternal;c?c({href:s}):t.open(s,"_blank","noopener,noreferrer");},resize(){},capabilities(){let s=n();return {pull:typeof s?.callTool=="function",sendPrompt:typeof s?.sendFollowUpMessage=="function"||typeof s?.sendFollowupMessage=="function",openLink:true}},start(){t.addEventListener(S,m,{passive:true}),i=n()?.toolOutput??i;},destroy(){f||(f=true,t.removeEventListener(S,m),a.clear(),p.clear());}}}function O(t,r){if(!t)return null;let i=t.getElementById(r)?.textContent;if(!i)return null;try{return JSON.parse(i)??null}catch{return null}}function L(t){if(t==null||typeof t!="object")return null;let r=t,n=r.renderData,i=n!=null&&typeof n=="object"?n:r;return i.toolOutput!=null?i.toolOutput:i.structuredContent!=null?i.structuredContent:i}function te(t,r){let n=r.dataElementId??A,i=null,l={mode:C(t),tokens:{}},a=new Set,p=false,f=null,m=s=>{if(p)return;let c=h(s.matches?"dark":"light",l.mode);if(c!==l.mode){l={mode:c,tokens:{}};for(let u of a)u(l);}};return {host:"generic",getData:()=>i,onData(){return ()=>{}},getTheme:()=>l,onTheme(s){return a.add(s),()=>a.delete(s)},async callTool(s){throw new b("callTool","generic")},sendPrompt(){},openLink(s){t.open(s,"_blank","noopener,noreferrer");},resize(){},capabilities(){return {pull:false,sendPrompt:false,openLink:true}},start(){i=O(t.document,n);try{f=t.matchMedia?.("(prefers-color-scheme: dark)")??null,f?.addEventListener?.("change",m);}catch{f=null;}},destroy(){p||(p=true,f?.removeEventListener?.("change",m),f=null,a.clear());}}}var fe=3e4;function ne(t,r){let n=r.dataElementId??A,i=r.autoResize!==false,l=null,a={mode:C(t),tokens:{}},p=new Set,f=new Set,m=false,s=false,c=1,u=new Map,P=-1,v=null,k=null,U=()=>t.parent??t;function I(e){U().postMessage(e,"*");}function _(e){s||I(e);}function x(e,o){I({jsonrpc:"2.0",method:e,params:o??{}});}function w(e,o){let d=c++;return new Promise((g,y)=>{let T=setTimeout(()=>{u.delete(d),y(new Error(`"${e}" timed out`));},fe);u.set(d,{resolve:g,reject:y,timer:T}),I({jsonrpc:"2.0",id:d,method:e,params:o??{}});})}function D(e){if(e!=null){l=e;for(let o of p)o(e);}}function M(e){if(!e||typeof e!="object")return;let{mode:o,tokens:d}=a,g=false;if(e.theme!=null){let T=h(e.theme,o);T!==o&&(o=T,g=true);}let y=e.styles;if(y?.variables&&typeof y.variables=="object"&&(d={...d,...y.variables},g=true),g){a={mode:o,tokens:d};for(let T of f)T(a);}}function E(e){if(m)return;let o=typeof e=="number"?e:Math.ceil(t.document.body.scrollHeight);o!==P&&(P=o,x(B,{height:o}),_({type:G,payload:{height:o}}));}function se(e){let o=Number(e.id),d=u.get(o);if(d)if(u.delete(o),clearTimeout(d.timer),e.error!=null){let g=e.error;d.reject(new Error(g.message??"request failed"));}else d.resolve(e.result);}function ie(e,o){if(e===Y){let d=o.structuredContent;D(d??L(o));}else e===V&&M(o);}function ae(e){e.method===X&&I({jsonrpc:"2.0",id:e.id,result:{}});}function le(e){if(e.type===j||e.type==="renderData"){let{theme:o,...d}=e.payload??{};o!=null&&M({theme:o}),Object.keys(d).length>0&&D(L(d));}}let H=e=>{if(m||e.source&&e.source!==U())return;let o=e.data;if(!(!o||typeof o!="object")){if(o.jsonrpc!=="2.0"){le(o);return}o.id!=null&&("result"in o||"error"in o)?se(o):typeof o.method=="string"&&(o.id!=null?ae(o):ie(o.method,o.params??{}));}};function ce(){k=()=>E(),t.addEventListener("resize",k),typeof t.ResizeObserver<"u"&&(v=new t.ResizeObserver(()=>E()),v.observe(t.document.body));}return {host:"claude",getData:()=>l,onData(e){return p.add(e),()=>p.delete(e)},getTheme:()=>a,onTheme(e){return f.add(e),()=>f.delete(e)},async callTool(e,o){return await w(J,{name:e,arguments:o??{}})},sendPrompt(e){w($,{role:"user",content:[{type:"text",text:e}]}).catch(()=>{}),_({type:W,payload:{prompt:e}});},openLink(e){w(Q,{url:e}).catch(()=>{}),_({type:K,payload:{url:e}});},resize(e){E(e);},capabilities(){return {pull:true,sendPrompt:true,openLink:true}},start(){t.addEventListener("message",H),l=O(t.document,n),i&&ce(),I({type:z}),w(Z,{appInfo:{name:r.name??"synapse-ui",version:r.version??"0.0.0"},appCapabilities:{availableDisplayModes:["inline"]},protocolVersion:F}).then(e=>{m||(s=true,M(e?.hostContext),x(q,{}),P=-1,E());}).catch(()=>{}),E();},destroy(){if(!m){m=true,t.removeEventListener("message",H),k&&t.removeEventListener("resize",k),k=null,v?.disconnect(),v=null;for(let e of u.values())clearTimeout(e.timer),e.reject(new Error("adapter destroyed"));u.clear(),p.clear(),f.clear();}}}}function me(t){if(t.openai!=null)return "chatgpt";try{if(t.parent!=null&&t.parent!==t)return "claude"}catch{return "claude"}return "generic"}function ge(t,r,n){switch(t){case "chatgpt":return ee(r);case "claude":case "nimblebrain":return ne(r,n);default:return te(r,n)}}function oe(t,r){let n=r.host??me(t);return ge(n,t,r)}function re(t={}){let r=t.window??globalThis,n=oe(r,t);R(n.getTheme());let i=n.onTheme(R);n.start();let l=false;return {data:()=>n.getData(),onData:a=>n.onData(a),theme:()=>n.getTheme(),onTheme:a=>n.onTheme(a),callTool:(a,p)=>n.callTool(a,p),sendPrompt:a=>n.sendPrompt(a),openLink:a=>n.openLink(a),resize:a=>n.resize(a),capabilities:()=>n.capabilities(),host:()=>n.host,destroy(){l||(l=true,i(),n.destroy());}}}globalThis.SynapseUI={connect:re};})();
1
+ (function(){'use strict';var he=new Set(["auto","block","swap","fallback","optional"]),Te={"--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-success":"#059669","--nb-color-warning":"#f59e0b","--nb-color-warm":"#d4620a","--nb-color-warm-light":"#fef5ee","--nb-color-processing":"#7c3aed","--nb-color-processing-light":"#f3eeff","--nb-color-info-light":"#eef4ff"},be={"--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-success":"#34d399","--nb-color-warning":"#fbbf24","--nb-color-warm":"#fb923c","--nb-color-warm-light":"#3a2a1e","--nb-color-processing":"#a78bfa","--nb-color-processing-light":"#2a2440","--nb-color-info-light":"#1e2a44"},ke={light:Te,dark:be};function Pe(e,n){if(typeof document>"u")return;let o=document.documentElement.style;for(let[s,a]of Object.entries(ke[e]))o.setProperty(s,a);if(n&&typeof n=="object")for(let[s,a]of Object.entries(n))typeof s=="string"&&typeof a=="string"&&o.setProperty(s,a);}var S=new Set,G="";function A(e){return Array.isArray(e)?JSON.stringify(e.map(n=>[n.family,n.src,n.weight,n.style,n.display])):""}function x(e){if(!Array.isArray(e))return;let n=e.filter(we);if(!(e.length>0&&n.length===0))return n}function Ie(e){let n=x(e);if(n===void 0||typeof document>"u"||!document.fonts||typeof FontFace>"u")return;let o=A(n);if(o!==G){G=o;for(let s of S)try{document.fonts.delete(s);}catch{}S.clear();for(let s of n)try{let a=new FontFace(s.family,s.src,{weight:s.weight,style:s.style,display:s.display&&he.has(s.display)?s.display:"swap"});document.fonts.add(a),S.add(a);}catch{}}}function we(e){if(!e||typeof e!="object")return false;let n=e;return typeof n.family=="string"&&typeof n.src=="string"}function W(e,n,o){Pe(e,n),Ie(o);}function R(e){typeof document<"u"&&document.documentElement.setAttribute("data-theme",e.mode),W(e.mode,e.tokens,e.fontFaces);}function O(e){try{if(e?.matchMedia?.("(prefers-color-scheme: dark)").matches)return "dark"}catch{}return "light"}function h(e,n){return e==="light"||e==="dark"?e:n}var T=class extends Error{constructor(n,o){super(`"${n}" is not supported by the "${o}" host`),this.name="HostUnsupportedError";}},_="synapse-ui-data",V="ui-lifecycle-iframe-ready",Z="ui-lifecycle-iframe-render-data",Y="ui-size-change",q="link",B="prompt",U="openai:set_globals",Q="2026-01-26",X="ui/initialize",$="ui/notifications/initialized",J="ui/notifications/tool-result",ee="ui/notifications/host-context-changed",te="ui/notifications/size-changed",ne="ui/open-link",oe="ui/message",re="ui/resource-teardown",se="tools/call";function ie(e,n){let o=()=>e.openai,s=o()?.toolOutput??null,a={mode:h(o()?.theme,"light"),tokens:{}},c=new Set,u=new Set,f=false,m=i=>{if(f)return;let l=i.detail?.globals;if(l){if("toolOutput"in l&&l.toolOutput!=null){s=l.toolOutput;for(let p of c)p(s);}if("theme"in l&&l.theme!=null){let p=h(l.theme,a.mode);if(p!==a.mode){a={mode:p,tokens:{}};for(let b of u)b(a);}}}};return {host:"chatgpt",getData:()=>s,onData(i){return c.add(i),()=>c.delete(i)},getTheme:()=>a,onTheme(i){return u.add(i),()=>u.delete(i)},async callTool(i,l){let p=o()?.callTool;if(!p)throw new T("callTool","chatgpt");return await p(i,l??{})},sendPrompt(i){let l=o();(l?.sendFollowUpMessage??l?.sendFollowupMessage)?.({prompt:i});},openLink(i){let l=o()?.openExternal;l?l({href:i}):e.open(i,"_blank","noopener,noreferrer");},resize(){},capabilities(){let i=o();return {pull:typeof i?.callTool=="function",sendPrompt:typeof i?.sendFollowUpMessage=="function"||typeof i?.sendFollowupMessage=="function",openLink:true}},start(){e.addEventListener(U,m,{passive:true}),s=o()?.toolOutput??s;},destroy(){f||(f=true,e.removeEventListener(U,m),c.clear(),u.clear());}}}function M(e,n){if(!e)return null;let s=e.getElementById(n)?.textContent;if(!s)return null;try{return JSON.parse(s)??null}catch{return null}}function L(e){if(e==null||typeof e!="object")return null;let n=e,o=n.renderData,s=o!=null&&typeof o=="object"?o:n;return s.toolOutput!=null?s.toolOutput:s.structuredContent!=null?s.structuredContent:s}function ae(e,n){let o=n.dataElementId??_,s=null,a={mode:O(e),tokens:{}},c=new Set,u=false,f=null,m=i=>{if(u)return;let l=h(i.matches?"dark":"light",a.mode);if(l!==a.mode){a={mode:l,tokens:{}};for(let p of c)p(a);}};return {host:"generic",getData:()=>s,onData(){return ()=>{}},getTheme:()=>a,onTheme(i){return c.add(i),()=>c.delete(i)},async callTool(i){throw new T("callTool","generic")},sendPrompt(){},openLink(i){e.open(i,"_blank","noopener,noreferrer");},resize(){},capabilities(){return {pull:false,sendPrompt:false,openLink:true}},start(){s=M(e.document,o);try{f=e.matchMedia?.("(prefers-color-scheme: dark)")??null,f?.addEventListener?.("change",m);}catch{f=null;}},destroy(){u||(u=true,f?.removeEventListener?.("change",m),f=null,c.clear());}}}var Ee="synapse/fontFaces";function Ce(e){return x(e?.[Ee])}function ce(e,n){return Ce(n)??e}var ve=3e4;function le(e,n){let o=n.dataElementId??_,s=n.autoResize!==false,a=null,c={mode:O(e),tokens:{}},u=new Set,f=new Set,m=false,i=false,l=1,p=new Map,b=-1,E=null,k=null,H=()=>e.parent??e;function P(t){H().postMessage(t,"*");}function F(t){i||P(t);}function N(t,r){P({jsonrpc:"2.0",method:t,params:r??{}});}function C(t,r){let d=l++;return new Promise((g,y)=>{let w=setTimeout(()=>{p.delete(d),y(new Error(`"${t}" timed out`));},ve);p.set(d,{resolve:g,reject:y,timer:w}),P({jsonrpc:"2.0",id:d,method:t,params:r??{}});})}function z(t){if(t!=null){a=t;for(let r of u)r(t);}}function D(t){if(!t||typeof t!="object")return;let{mode:r,tokens:d,fontFaces:g}=c,y=false;if(t.theme!=null){let v=h(t.theme,r);v!==r&&(r=v,y=true);}let w=t.styles;w?.variables&&typeof w.variables=="object"&&(d={...d,...w.variables},y=true);let K=ce(g,t);if(A(K)!==A(g)&&(g=K,y=true),y){c={mode:r,tokens:d,...g?{fontFaces:g}:{}};for(let v of f)v(c);}}function I(t){if(m)return;let r=typeof t=="number"?t:Math.ceil(e.document.body.scrollHeight);r!==b&&(b=r,N(te,{height:r}),F({type:Y,payload:{height:r}}));}function ue(t){let r=Number(t.id),d=p.get(r);if(d)if(p.delete(r),clearTimeout(d.timer),t.error!=null){let g=t.error;d.reject(new Error(g.message??"request failed"));}else d.resolve(t.result);}function fe(t,r){if(t===J){let d=r.structuredContent;z(d??L(r));}else t===ee&&D(r);}function me(t){t.method===re&&P({jsonrpc:"2.0",id:t.id,result:{}});}function ge(t){if(t.type===Z||t.type==="renderData"){let{theme:r,...d}=t.payload??{};r!=null&&D({theme:r}),Object.keys(d).length>0&&z(L(d));}}let j=t=>{if(m||t.source&&t.source!==H())return;let r=t.data;if(!(!r||typeof r!="object")){if(r.jsonrpc!=="2.0"){ge(r);return}r.id!=null&&("result"in r||"error"in r)?ue(r):typeof r.method=="string"&&(r.id!=null?me(r):fe(r.method,r.params??{}));}};function ye(){k=()=>I(),e.addEventListener("resize",k),typeof e.ResizeObserver<"u"&&(E=new e.ResizeObserver(()=>I()),E.observe(e.document.body));}return {host:"claude",getData:()=>a,onData(t){return u.add(t),()=>u.delete(t)},getTheme:()=>c,onTheme(t){return f.add(t),()=>f.delete(t)},async callTool(t,r){return await C(se,{name:t,arguments:r??{}})},sendPrompt(t){C(oe,{role:"user",content:[{type:"text",text:t}]}).catch(()=>{}),F({type:B,payload:{prompt:t}});},openLink(t){C(ne,{url:t}).catch(()=>{}),F({type:q,payload:{url:t}});},resize(t){I(t);},capabilities(){return {pull:true,sendPrompt:true,openLink:true}},start(){e.addEventListener("message",j),a=M(e.document,o),s&&ye(),P({type:V}),C(X,{appInfo:{name:n.name??"synapse-ui",version:n.version??"0.0.0"},appCapabilities:{availableDisplayModes:["inline"]},protocolVersion:Q}).then(t=>{m||(i=true,D(t?.hostContext),N($,{}),b=-1,I());}).catch(()=>{}),I();},destroy(){if(!m){m=true,e.removeEventListener("message",j),k&&e.removeEventListener("resize",k),k=null,E?.disconnect(),E=null;for(let t of p.values())clearTimeout(t.timer),t.reject(new Error("adapter destroyed"));p.clear(),u.clear(),f.clear();}}}}function Ae(e){if(e.openai!=null)return "chatgpt";try{if(e.parent!=null&&e.parent!==e)return "claude"}catch{return "claude"}return "generic"}function Oe(e,n,o){switch(e){case "chatgpt":return ie(n);case "claude":case "nimblebrain":return le(n,o);default:return ae(n,o)}}function de(e,n){let o=n.host??Ae(e);return Oe(o,e,n)}function pe(e={}){let n=e.window??globalThis,o=de(n,e);R(o.getTheme());let s=o.onTheme(R);o.start();let a=false;return {data:()=>o.getData(),onData:c=>o.onData(c),theme:()=>o.getTheme(),onTheme:c=>o.onTheme(c),callTool:(c,u)=>o.callTool(c,u),sendPrompt:c=>o.sendPrompt(c),openLink:c=>o.openLink(c),resize:c=>o.resize(c),capabilities:()=>o.capabilities(),host:()=>o.host,destroy(){a||(a=true,s(),o.destroy());}}}globalThis.SynapseUI={connect:pe};})();
@@ -113,10 +113,46 @@ interface SynapseOptions {
113
113
  /** Key combos to forward from iframe to host. Default: all Ctrl/Cmd combos + Escape. */
114
114
  forwardKeys?: KeyForwardConfig[];
115
115
  }
116
+ /**
117
+ * One `@font-face` a host asks the app to load.
118
+ *
119
+ * The token contract can name a font (`--font-sans: 'Hanken Grotesk', system-ui`)
120
+ * but cannot *load* one — a CSS custom property carries a family name, never the
121
+ * `@font-face` rule behind it. An app iframe is its own document and inherits no
122
+ * `@font-face` from the host page, so a host that only sends tokens is naming a
123
+ * family the app has no way to render. This descriptor is the missing half.
124
+ *
125
+ * The SDK ships **no font data** — it applies what the host sends. A host that
126
+ * sends none leaves the web-safe fallbacks in `ui/tokens.ts` in force.
127
+ */
128
+ interface FontFaceDescriptor {
129
+ /** Family name, matching the one used in the host's `--font-*` token value. */
130
+ family: string;
131
+ /**
132
+ * CSS `src` descriptor. Local and absolute URLs work identically —
133
+ * `url('/fonts/x.woff2') format('woff2')` or `url('https://cdn.example/x.woff2')`.
134
+ * Whatever origin this names must satisfy the app iframe's `font-src` CSP.
135
+ */
136
+ src: string;
137
+ /** `font-weight` descriptor — a single weight (`400`) or a variable range (`400 700`). */
138
+ weight?: string;
139
+ /** `font-style` descriptor (`normal`, `italic`, …). */
140
+ style?: string;
141
+ /** `font-display` descriptor. Defaults to `swap` so text paints in the fallback first. */
142
+ display?: FontDisplayValue;
143
+ }
144
+ /** The CSS `font-display` values. Closed set — anything else is ignored. */
145
+ type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional";
116
146
  interface SynapseTheme {
117
147
  mode: "light" | "dark";
118
148
  primaryColor: string;
119
149
  tokens: Record<string, string>;
150
+ /**
151
+ * Font faces the host wants loaded into the app document. Optional — a host
152
+ * that omits them leaves the web-safe fallbacks in force. Arrives over the
153
+ * wire as the `synapse/fontFaces` host-context extension.
154
+ */
155
+ fontFaces?: FontFaceDescriptor[];
120
156
  }
121
157
  interface DataChangedEvent {
122
158
  source: "agent";
@@ -384,6 +420,8 @@ interface ConnectOptions {
384
420
  interface Theme {
385
421
  mode: "light" | "dark";
386
422
  tokens: Record<string, string>;
423
+ /** Font faces the host wants loaded. See {@link FontFaceDescriptor}. */
424
+ fontFaces?: FontFaceDescriptor[];
387
425
  }
388
426
  interface Dimensions {
389
427
  width?: number;
@@ -430,4 +468,4 @@ interface App {
430
468
  destroy(): void;
431
469
  }
432
470
 
433
- export type { App as A, BuiltinActionType as B, ConnectOptions as C, DataChangedEvent as D, FileResult as F, HostInfo as H, KeyForwardConfig as K, NavigatePayload as N, RequestFileOptions as R, SynapseOptions as S, ToolDefinition as T, VisibleState as V, Synapse as a, ActionReducer as b, StoreConfig as c, Store as d, AgentAction as e, AppEventName as f, CallToolAsTaskOptions as g, Dimensions as h, NotifyPayload as i, StateAcknowledgement as j, StoreDispatch as k, SynapseTheme as l, TaskHandle as m, TasksCapability as n, Theme as o, ToolCallResult as p, ToolResultData as q };
471
+ export type { App as A, BuiltinActionType as B, ConnectOptions as C, DataChangedEvent as D, FontFaceDescriptor as F, HostInfo as H, KeyForwardConfig as K, NavigatePayload as N, RequestFileOptions as R, SynapseOptions as S, ToolDefinition as T, VisibleState as V, Synapse as a, ActionReducer as b, StoreConfig as c, Store as d, AgentAction as e, AppEventName as f, CallToolAsTaskOptions as g, Dimensions as h, FileResult as i, FontDisplayValue as j, NotifyPayload as k, StateAcknowledgement as l, StoreDispatch as m, SynapseTheme as n, TaskHandle as o, TasksCapability as p, Theme as q, ToolCallResult as r, ToolResultData as s };
@@ -113,10 +113,46 @@ interface SynapseOptions {
113
113
  /** Key combos to forward from iframe to host. Default: all Ctrl/Cmd combos + Escape. */
114
114
  forwardKeys?: KeyForwardConfig[];
115
115
  }
116
+ /**
117
+ * One `@font-face` a host asks the app to load.
118
+ *
119
+ * The token contract can name a font (`--font-sans: 'Hanken Grotesk', system-ui`)
120
+ * but cannot *load* one — a CSS custom property carries a family name, never the
121
+ * `@font-face` rule behind it. An app iframe is its own document and inherits no
122
+ * `@font-face` from the host page, so a host that only sends tokens is naming a
123
+ * family the app has no way to render. This descriptor is the missing half.
124
+ *
125
+ * The SDK ships **no font data** — it applies what the host sends. A host that
126
+ * sends none leaves the web-safe fallbacks in `ui/tokens.ts` in force.
127
+ */
128
+ interface FontFaceDescriptor {
129
+ /** Family name, matching the one used in the host's `--font-*` token value. */
130
+ family: string;
131
+ /**
132
+ * CSS `src` descriptor. Local and absolute URLs work identically —
133
+ * `url('/fonts/x.woff2') format('woff2')` or `url('https://cdn.example/x.woff2')`.
134
+ * Whatever origin this names must satisfy the app iframe's `font-src` CSP.
135
+ */
136
+ src: string;
137
+ /** `font-weight` descriptor — a single weight (`400`) or a variable range (`400 700`). */
138
+ weight?: string;
139
+ /** `font-style` descriptor (`normal`, `italic`, …). */
140
+ style?: string;
141
+ /** `font-display` descriptor. Defaults to `swap` so text paints in the fallback first. */
142
+ display?: FontDisplayValue;
143
+ }
144
+ /** The CSS `font-display` values. Closed set — anything else is ignored. */
145
+ type FontDisplayValue = "auto" | "block" | "swap" | "fallback" | "optional";
116
146
  interface SynapseTheme {
117
147
  mode: "light" | "dark";
118
148
  primaryColor: string;
119
149
  tokens: Record<string, string>;
150
+ /**
151
+ * Font faces the host wants loaded into the app document. Optional — a host
152
+ * that omits them leaves the web-safe fallbacks in force. Arrives over the
153
+ * wire as the `synapse/fontFaces` host-context extension.
154
+ */
155
+ fontFaces?: FontFaceDescriptor[];
120
156
  }
121
157
  interface DataChangedEvent {
122
158
  source: "agent";
@@ -384,6 +420,8 @@ interface ConnectOptions {
384
420
  interface Theme {
385
421
  mode: "light" | "dark";
386
422
  tokens: Record<string, string>;
423
+ /** Font faces the host wants loaded. See {@link FontFaceDescriptor}. */
424
+ fontFaces?: FontFaceDescriptor[];
387
425
  }
388
426
  interface Dimensions {
389
427
  width?: number;
@@ -430,4 +468,4 @@ interface App {
430
468
  destroy(): void;
431
469
  }
432
470
 
433
- export type { App as A, BuiltinActionType as B, ConnectOptions as C, DataChangedEvent as D, FileResult as F, HostInfo as H, KeyForwardConfig as K, NavigatePayload as N, RequestFileOptions as R, SynapseOptions as S, ToolDefinition as T, VisibleState as V, Synapse as a, ActionReducer as b, StoreConfig as c, Store as d, AgentAction as e, AppEventName as f, CallToolAsTaskOptions as g, Dimensions as h, NotifyPayload as i, StateAcknowledgement as j, StoreDispatch as k, SynapseTheme as l, TaskHandle as m, TasksCapability as n, Theme as o, ToolCallResult as p, ToolResultData as q };
471
+ export type { App as A, BuiltinActionType as B, ConnectOptions as C, DataChangedEvent as D, FontFaceDescriptor as F, HostInfo as H, KeyForwardConfig as K, NavigatePayload as N, RequestFileOptions as R, SynapseOptions as S, ToolDefinition as T, VisibleState as V, Synapse as a, ActionReducer as b, StoreConfig as c, Store as d, AgentAction as e, AppEventName as f, CallToolAsTaskOptions as g, Dimensions as h, FileResult as i, FontDisplayValue as j, NotifyPayload as k, StateAcknowledgement as l, StoreDispatch as m, SynapseTheme as n, TaskHandle as o, TasksCapability as p, Theme as q, ToolCallResult as r, ToolResultData as s };
package/dist/ui/index.cjs CHANGED
@@ -333,6 +333,18 @@ var RULES3 = `
333
333
  .nb-drawer-iconbtn { min-width: 44px; min-height: 44px; }
334
334
  }
335
335
  `;
336
+ function inClosedDetails(el) {
337
+ const details = el.closest("details:not([open])");
338
+ if (!details) return false;
339
+ const summary = details.querySelector("summary");
340
+ return !summary || !summary.contains(el);
341
+ }
342
+ var CANDIDATES = "a[href], button, input, select, textarea, summary, [tabindex]";
343
+ function tabbables(panel) {
344
+ return Array.from(panel.querySelectorAll(CANDIDATES)).filter(
345
+ (el) => el.tabIndex >= 0 && !el.matches(":disabled") && !el.closest("[hidden]") && !inClosedDetails(el) && el.type !== "hidden"
346
+ );
347
+ }
336
348
  var DrawerContext = react.createContext(null);
337
349
  function DrawerRoot({
338
350
  open,
@@ -361,12 +373,33 @@ function DrawerRoot({
361
373
  }, [open, onEscape, onClose]);
362
374
  react.useEffect(() => {
363
375
  if (!open) return;
376
+ const panel = panelRef.current;
364
377
  const previouslyFocused = document.activeElement;
365
- panelRef.current?.focus();
378
+ panel?.focus();
366
379
  const { body } = document;
367
380
  const prevOverflow = body.style.overflow;
368
381
  body.style.overflow = "hidden";
382
+ const onKeyDown = (e) => {
383
+ if (e.key !== "Tab" || !panel) return;
384
+ const focusables = tabbables(panel);
385
+ if (focusables.length === 0) {
386
+ e.preventDefault();
387
+ return;
388
+ }
389
+ const first = focusables[0];
390
+ const last = focusables[focusables.length - 1];
391
+ const active = document.activeElement;
392
+ if (e.shiftKey && (active === first || active === panel)) {
393
+ e.preventDefault();
394
+ last.focus();
395
+ } else if (!e.shiftKey && active === last) {
396
+ e.preventDefault();
397
+ first.focus();
398
+ }
399
+ };
400
+ panel?.addEventListener("keydown", onKeyDown);
369
401
  return () => {
402
+ panel?.removeEventListener("keydown", onKeyDown);
370
403
  body.style.overflow = prevOverflow;
371
404
  previouslyFocused?.focus?.();
372
405
  };