@fork-api/chat-sdk 0.1.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +29 -0
- package/README.md +21 -0
- package/dist/index.cjs +52 -0
- package/dist/index.d.cts +251 -0
- package/dist/index.d.ts +251 -0
- package/dist/index.js +52 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Copyright (c) 2026 Fork. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software and associated files (the "Software") are proprietary. The
|
|
4
|
+
Software is made available solely for use with the Fork service, subject to
|
|
5
|
+
the Fork Terms of Service available at https://withfork.co/terms.
|
|
6
|
+
|
|
7
|
+
Permitted use:
|
|
8
|
+
- Installing the Software from the npm registry as a dependency of an
|
|
9
|
+
application that integrates with the Fork service.
|
|
10
|
+
- Executing the Software in the course of using the Fork service.
|
|
11
|
+
|
|
12
|
+
The following are NOT permitted without prior written consent from the
|
|
13
|
+
copyright holder:
|
|
14
|
+
- Redistribution of the Software, in source or compiled form, outside of
|
|
15
|
+
the official npm registry listing.
|
|
16
|
+
- Modification, adaptation, or creation of derivative works based on the
|
|
17
|
+
Software.
|
|
18
|
+
- Reverse engineering, decompilation, or disassembly of the Software,
|
|
19
|
+
except to the extent such activity is expressly permitted by applicable
|
|
20
|
+
law notwithstanding this limitation.
|
|
21
|
+
- Use of the Software independently of the Fork service.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
|
|
27
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF,
|
|
28
|
+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @fork-api/chat-sdk
|
|
2
|
+
|
|
3
|
+
React SDK for [Fork](https://withfork.co) — let your users customize your UI with AI.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @fork-api/chat-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
Documentation: [withfork.co/d/f7k9x2m3](https://withfork.co/d/f7k9x2m3)
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- React 18+
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
Proprietary. See `LICENSE` for terms.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';var Be=require('react'),Ut=require('react-dom'),Dt=require('react/jsx-runtime'),It=require('react/jsx-dev-runtime'),lucideReact=require('lucide-react');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Be__namespace=/*#__PURE__*/_interopNamespace(Be);var Ut__namespace=/*#__PURE__*/_interopNamespace(Ut);var Dt__namespace=/*#__PURE__*/_interopNamespace(Dt);var It__namespace=/*#__PURE__*/_interopNamespace(It);var ee="__FORK_SHARED__";function Pe(){var t,r,o,n;let e=globalThis;return e[ee]||(e[ee]={}),(t=e[ee]).react||(t.react=Be__namespace),(r=e[ee])["react-dom"]||(r["react-dom"]=Ut__namespace),(o=e[ee])["react/jsx-runtime"]||(o["react/jsx-runtime"]=Dt__namespace),(n=e[ee])["react/jsx-dev-runtime"]||(n["react/jsx-dev-runtime"]=It__namespace),e[ee]}function Me(e){return Object.assign(Pe(),e)}var tt=Be.createContext(null);function et(e,t){if(!t)return t;try{return new URL(t,`${e.replace(/\/+$/,"")}/`).toString()}catch{return t}}function Wt(e,t){let r={};for(let[o,n]of Object.entries(t.boundaries||{}))r[o]={...n,moduleUrl:et(e,n.moduleUrl),cssUrls:Array.isArray(n.cssUrls)?n.cssUrls.map(i=>et(e,i)):[]};return r}function Kt(e){let{apiKey:t,baseUrl:r,children:o,appId:n,shared:i}=e,s="userId"in e?e.userId:void 0,a="authUrl"in e?e.authUrl:void 0,[k,u]=Be.useState({}),[m,S]=Be.useState(s?{userId:s,userHash:void 0}:null),[_,v]=Be.useState(!!s),[y,c]=Be.useState({}),[x,A]=Be.useState(!n),[$,M]=Be.useState(0),E=Be.useRef(new Map),h=Be.useRef(new Map),[R,f]=Be.useState(0),l=Be.useRef(new Set),F=Be.useRef(new Map),b=Be.useRef(void 0);Pe(),i&&b.current!==i&&(Me(i),b.current=i),Be.useEffect(()=>{a&&(v(false),fetch(a,{credentials:"include"}).then(w=>{if(!w.ok)throw new Error(`Auth endpoint returned ${w.status}`);return w.json()}).then(w=>{if(!w.userId||typeof w.userId!="string")throw new Error("authUrl response must include userId");S({userId:w.userId,userHash:w.userHash});}).catch(w=>{console.error("[ForkProvider] Failed to fetch user identity from authUrl:",w.message);}).finally(()=>{v(true);}));},[a]),Be.useEffect(()=>{!a&&s&&(S({userId:s,userHash:void 0}),v(true));},[s,a]);let d=m?.userId??"",g=m?.userHash,p=!!n,L=Be.useCallback(async()=>{if(!p){c({}),A(true),M(C=>C+1);return}if(!_){A(false);return}if(!d||!n){c({}),A(true),M(C=>C+1);return}let w=new URLSearchParams({appId:n,userId:d});g&&w.set("userHash",g),A(false);try{let C=await fetch(`${r}/api/v1/boundaries/manifest?${w.toString()}`,{headers:{Authorization:`Bearer ${t}`}});if(!C.ok)throw new Error(`${C.status}`);let O=await C.json();c(Wt(r,O));}catch(C){console.error("[ForkProvider] Failed to fetch module override manifest:",C.message),c({});}finally{M(C=>C+1),A(true);}},[t,n,r,_,p,g,d]);Be.useEffect(()=>{if(!d)return;let w=new URLSearchParams({userId:d});g&&w.set("userHash",g),fetch(`${r}/api/v1/forks/active?${w.toString()}`,{headers:{Authorization:`Bearer ${t}`}}).then(C=>{if(!C.ok)throw new Error(`${C.status}`);return C.json()}).then(C=>{C&&typeof C=="object"&&u(C);}).catch(()=>{});},[t,d,g,r]),Be.useEffect(()=>{L();},[L]);let I=Be.useCallback((w,C)=>{u(O=>({...O,[w]:C}));},[]),W=Be.useCallback(w=>{u(C=>{let O={...C};return delete O[w],O});},[]),X=Be.useCallback(w=>{l.current.add(w);},[]),q=Be.useCallback(w=>l.current.has(w)?(l.current.delete(w),true):false,[]),J=Be.useCallback((w,C)=>{F.current.set(w,C);},[]),N=Be.useCallback((w,C)=>F.current.get(w)!==C?false:(F.current.delete(w),true),[]),K=Be.useCallback(w=>{if(!n)return;let C=JSON.stringify(w);E.current.get(w.id)===C||h.current.get(w.id)?.signature===C||(h.current.set(w.id,{boundary:w,signature:C}),f(j=>j+1));},[n]);Be.useEffect(()=>{if(!n||h.current.size===0)return;let w=setTimeout(()=>{let C=Array.from(h.current.values());C.length!==0&&fetch(`${r}/api/v1/boundaries`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({appId:n,boundaries:C.map(O=>O.boundary)})}).then(O=>{if(!O.ok)throw new Error(`${O.status}`)}).then(()=>{for(let O of C)h.current.get(O.boundary.id)?.signature===O.signature&&(h.current.delete(O.boundary.id),E.current.set(O.boundary.id,O.signature));}).catch(O=>{console.error("[ForkProvider] Failed to register module boundaries:",O.message);});},50);return ()=>{clearTimeout(w);}},[t,n,r,R]);let G=Be.useCallback(w=>y[w],[y]),V=Be.useCallback(async()=>{if(!g)throw new Error("Reset requires verified user identity (provide authUrl / userHash).");let w=new URLSearchParams({userId:d,userHash:g}),C=await fetch(`${r}/api/v1/forks/all?${w.toString()}`,{method:"DELETE",headers:{Authorization:`Bearer ${t}`}});if(!C.ok){let j=await C.json().catch(()=>({}));throw new Error(j.error||`API error: ${C.status}`)}let O=await C.json().catch(()=>({}));u({}),c({}),A(true),M(j=>j+1),l.current.clear(),F.current.clear();try{for(let j=sessionStorage.length-1;j>=0;j-=1){let ne=sessionStorage.key(j);ne&&ne.startsWith("__fork_animated_")&&sessionStorage.removeItem(ne);}}catch{}return O},[t,r,g,d]);return Dt.jsx(tt.Provider,{value:{apiKey:t,userId:d,userHash:g,baseUrl:r,appId:n,forks:k,moduleOverridesEnabled:p,moduleManifestReady:x,moduleManifestVersion:$,setSlotFork:I,clearSlotFork:W,skipAnimationForSlot:X,shouldSkipAnimation:q,queueBoundaryAnimation:J,consumeBoundaryAnimation:N,registerBoundary:K,getBoundaryOverride:G,refreshModuleManifest:L,resetAllForks:V},children:o})}function z(){let e=Be.useContext(tt);if(!e)throw new Error("useForkContext must be used within <ForkProvider>");return e}function be(e){return z().forks[e]}var ue=class{constructor(t){this.values=new Map;this.snapshots=new Map;this.listeners=new Map;this.eventHandlers=new Map;this.slotId=t,window.__FORK_BRIDGE__||(window.__FORK_BRIDGE__={}),window.__FORK_BRIDGE__[t]=this;}set(t,r){let o=this.values.get(t);if(Object.is(o,r))return;if(o!==void 0&&r!==null&&o!==null&&typeof o=="object"&&typeof r=="object")try{if(JSON.stringify(o)===JSON.stringify(r))return}catch{}this.values.set(t,r),this.snapshots.set(t,r);let n=this.listeners.get(t);n&&n.forEach(i=>i());}get(t){return this.values.get(t)}getSnapshot(t){return this.snapshots.get(t)}subscribe(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>{this.listeners.get(t)?.delete(r);}}useValue(t){let r=window.__FORK_REACT__;return r?.useSyncExternalStore?r.useSyncExternalStore(o=>this.subscribe(t,o),()=>this.getSnapshot(t)):(console.warn("[ForkBridge] React.useSyncExternalStore not available, returning static value"),this.values.get(t))}emit(t,...r){let o=this.eventHandlers.get(t);o&&o.forEach(n=>n(...r));}on(t,r){return this.eventHandlers.has(t)||this.eventHandlers.set(t,new Set),this.eventHandlers.get(t).add(r),()=>{this.eventHandlers.get(t)?.delete(r);}}destroy(){this.listeners.clear(),this.eventHandlers.clear(),this.values.clear(),this.snapshots.clear();let t=window.__FORK_BRIDGE__;t&&delete t[this.slotId];}};function Oe(e,t){let r;try{r=Be.Children.only(e);}catch{let n=Be.Children.count(e);throw new Error(`<ForkSlot slotId="${t}"> must wrap exactly one React component, got ${n} children. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`)}let o=r.type;if(typeof o=="string")throw new Error(`<ForkSlot slotId="${t}"> child must be a React component (function or class), not an HTML element <${o}>. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`);if(typeof o=="symbol")throw new Error(`<ForkSlot slotId="${t}"> child must be a single React component, not a fragment or special React element. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`);return r}var ot=new Set;function nt(e){let t=[],r=e.querySelectorAll("*");for(let o of r){if(!(o instanceof HTMLElement))continue;let n=o.getBoundingClientRect();if(n.width<10||n.height<10||["SCRIPT","STYLE","META","LINK"].includes(o.tagName))continue;let i=getComputedStyle(o),s=parseFloat(i.borderTopLeftRadius)||0;t.push({tag:o.tagName,className:o.className||"",text:(o.textContent||"").slice(0,50).trim(),rect:n,borderRadius:s});}return t}function Yt(e,t){let r=[];for(let o of t)if(!e.find(i=>i.tag===o.tag&&i.className===o.className&&Math.abs(i.rect.top-o.rect.top)<20&&Math.abs(i.rect.left-o.rect.left)<20)&&!r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom)){for(let s=r.length-1;s>=0;s--){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Xt(e,t){let r=[];for(let o of e)if(!t.find(i=>i.tag===o.tag&&i.className===o.className&&Math.abs(i.rect.top-o.rect.top)<20&&Math.abs(i.rect.left-o.rect.left)<20)&&!r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom)){for(let s=r.length-1;s>=0;s--){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function it(e,t,r,o,n){return n=Math.max(0,Math.min(n,r/2,o/2)),n===0?`M ${e} ${t} L ${e+r} ${t} L ${e+r} ${t+o} L ${e} ${t+o} Z`:[`M ${e+n} ${t}`,`L ${e+r-n} ${t}`,`A ${n} ${n} 0 0 1 ${e+r} ${t+n}`,`L ${e+r} ${t+o-n}`,`A ${n} ${n} 0 0 1 ${e+r-n} ${t+o}`,`L ${e+n} ${t+o}`,`A ${n} ${n} 0 0 1 ${e} ${t+o-n}`,`L ${e} ${t+n}`,`A ${n} ${n} 0 0 1 ${e+n} ${t}`,"Z"].join(" ")}function st(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-highlights","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs");o.appendChild(n);let i=[];for(let m=0;m<e.length;m++){let{rect:S,borderRadius:_}=e[m],v=S.left-.5,y=S.top-.5,c=S.width+1,x=S.height+1,A=Math.min(_+.5,c/2,x/2),$=it(v,y,c,x,A),M=`__fork-glow-${m}`,E=document.createElementNS(t,"filter");E.setAttribute("id",M),E.setAttribute("x","-100%"),E.setAttribute("y","-100%"),E.setAttribute("width","300%"),E.setAttribute("height","300%");let h=document.createElementNS(t,"feGaussianBlur");h.setAttribute("in","SourceGraphic"),h.setAttribute("stdDeviation","8"),E.appendChild(h),n.appendChild(E);let R=`__fork-mask-${m}`,f=document.createElementNS(t,"mask");f.setAttribute("id",R),f.setAttribute("maskUnits","userSpaceOnUse"),f.setAttribute("x",String(v-200)),f.setAttribute("y",String(y-200)),f.setAttribute("width",String(c+400)),f.setAttribute("height",String(x+400));let l=document.createElementNS(t,"rect");l.setAttribute("x",String(v-200)),l.setAttribute("y",String(y-200)),l.setAttribute("width",String(c+400)),l.setAttribute("height",String(x+400)),l.setAttribute("fill","white"),f.appendChild(l);let F=document.createElementNS(t,"path");F.setAttribute("d",$),F.setAttribute("fill","black"),f.appendChild(F),n.appendChild(f);let b=document.createElementNS(t,"g");b.setAttribute("mask",`url(#${R})`),b.setAttribute("opacity","0");let d=document.createElementNS(t,"g");d.setAttribute("filter",`url(#${M})`);let g=document.createElementNS(t,"path");g.setAttribute("d",$),g.setAttribute("fill","none"),g.setAttribute("stroke","rgba(150, 185, 220, 0.6)"),g.setAttribute("stroke-width","6"),g.setAttribute("stroke-linecap","round"),d.appendChild(g),b.appendChild(d),o.appendChild(b);let p=document.createElementNS(t,"path");p.setAttribute("d",$),p.setAttribute("fill","none"),p.setAttribute("stroke","rgba(150, 185, 220, 0.35)"),p.setAttribute("stroke-width","2"),p.setAttribute("stroke-linecap","round"),p.setAttribute("opacity","0"),o.appendChild(p),i.push(g,p),g.__group=b;}r.appendChild(o),document.body.appendChild(r);let s=[];for(let m=0;m<i.length;m+=2){let S=i[m],_=i[m+1],v=S.__group,y=_.getTotalLength(),c=S.getTotalLength();if(y<=0)continue;let x=y*.35;_.setAttribute("stroke-dasharray",`${x} ${y-x}`),_.setAttribute("stroke-dashoffset","0"),s.push(_.animate([{strokeDashoffset:0,opacity:0,offset:0},{strokeDashoffset:-0.2*y,opacity:.92,offset:.06},{strokeDashoffset:-2*y,opacity:.92,offset:.92},{strokeDashoffset:-2.25*y,opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));let A=c*.35;S.setAttribute("stroke-dasharray",`${A} ${c-A}`),S.setAttribute("stroke-dashoffset","0"),s.push(S.animate([{strokeDashoffset:0,offset:0},{strokeDashoffset:-0.2*c,offset:.06},{strokeDashoffset:-2*c,offset:.92},{strokeDashoffset:-2.25*c,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"})),s.push(v.animate([{opacity:0,offset:0},{opacity:.92,offset:.06},{opacity:.92,offset:.92},{opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));}let a=false,k=()=>{if(a)return;a=true,clearTimeout(u);for(let S of s)try{S.cancel();}catch{}let m=r.animate([{opacity:1},{opacity:0}],{duration:400,fill:"forwards"});m.onfinish=()=>r.remove(),window.removeEventListener("click",k);},u=setTimeout(k,14500);return setTimeout(()=>{a||window.addEventListener("click",k);},500),k}function Zt(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-removed","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs"),i=document.createElementNS(t,"filter");i.setAttribute("id","__fork-removed-shadow"),i.setAttribute("x","-10%"),i.setAttribute("y","-10%"),i.setAttribute("width","120%"),i.setAttribute("height","120%");let s=document.createElementNS(t,"feDropShadow");s.setAttribute("dx","0"),s.setAttribute("dy","1"),s.setAttribute("stdDeviation","2"),s.setAttribute("flood-color","rgba(0,0,0,0.15)"),i.appendChild(s),n.appendChild(i),o.appendChild(n);for(let{rect:a,borderRadius:k}of e){let u=a.left,m=a.top,S=a.width,_=a.height,v=Math.min(k,S/2,_/2),y=it(u,m,S,_,v),c=document.createElementNS(t,"path");c.setAttribute("d",y),c.setAttribute("fill","none"),c.setAttribute("stroke","rgba(120, 125, 135, 0.6)"),c.setAttribute("stroke-width","1.5"),c.setAttribute("stroke-dasharray","8 4"),c.setAttribute("stroke-linecap","round"),c.setAttribute("filter","url(#__fork-removed-shadow)"),c.setAttribute("opacity","0"),o.appendChild(c),c.animate([{opacity:0,offset:0},{opacity:.6,offset:.08},{opacity:.05,offset:.45},{opacity:.6,offset:.85},{opacity:.05,offset:1}],{duration:5e3,easing:"ease-in-out",fill:"forwards"});}return r.appendChild(o),document.body.appendChild(r),r}function Qt(e,t){if(e===t)return true;let r=Object.keys(e);if(r.length!==Object.keys(t).length)return false;for(let o of r)if(!Object.is(e[o],t[o]))return false;return true}var er=Be__namespace.default.memo(function({component:t,containerRef:r,wrapperStyle:o,hostProps:n}){return Dt.jsx("div",{ref:r,style:o,children:Dt.jsx(t,{...n})})},(e,t)=>e.component===t.component&&Qt(e.hostProps,t.hostProps)),Le=class extends Be__namespace.default.Component{constructor(t){super(t),this.state={hasError:false};}static getDerivedStateFromError(){return {hasError:true}}componentDidCatch(t){console.error(`[Fork:${this.props.slotId}] fork render failed`,t);}componentDidUpdate(t){t.resetKey!==this.props.resetKey&&this.state.hasError&&this.setState({hasError:false});}render(){return this.state.hasError?this.props.fallback:this.props.children}};function at({slotId:e,children:t,githubRepo:r,shared:o,events:n}){Oe(t,e);let i=be(e),{baseUrl:s,apiKey:a,appId:k,shouldSkipAnimation:u}=z(),[m,S]=Be.useState(null),_=Be.useRef(null),v=Be.useRef(null),y=Be.useRef(null),c=Be.useRef(false),x=Be.useRef(null),A=Be.useRef(null),$=!!(o||n),M=Be.useRef(null);$&&!M.current&&(M.current=new ue(e));let E=Be.useRef(n);if(E.current=n,Be.useEffect(()=>{if($)return ()=>{M.current?.destroy(),M.current=null;}},[$,e]),$&&M.current&&o)for(let[F,b]of Object.entries(o))M.current.set(F,b);Be.useEffect(()=>{if(!$)return;M.current||(M.current=new ue(e));let F=M.current,b=Object.keys(E.current||{}).map(d=>F.on(d,(...g)=>E.current?.[d]?.(...g)));return ()=>b.forEach(d=>d())},[$,e]),Be.useEffect(()=>{if(ot.has(e))return;ot.add(e);let F={id:e,appId:k,label:e,eventsShape:"{ navigate?: string }",currentLayout:"",githubRepo:r,mode:"direct",sharedKeys:o?Object.keys(o):[],eventNames:n?Object.keys(n):[],propsShape:"",callbackNames:[]};fetch(`${s}/api/v1/slots`,{method:"POST",headers:{Authorization:`Bearer ${a}`,"Content-Type":"application/json"},body:JSON.stringify(F)}).catch(()=>{});},[e,s,a,r,k]);let h=i?.id||null;Be.useEffect(()=>{if(i?.bundleUrl,_.current,v.current,!i?.bundleUrl||!h){return}let F=`${s}${i.bundleUrl.replace("bundle.js","component.js")}`,b=`__fork_animated_${e}`,d=sessionStorage.getItem(b),g=u(e),p=!g&&d!==h;if(g&&h&&sessionStorage.setItem(b,h),p&&v.current){let q=nt(v.current);y.current=q,c.current=true,`${e}${q.length}`;}window.__FORK_REACT__=Be__namespace.default,window.__FORK_REACT_DOM__=Ut__namespace,window.__FORK_REACT_JSX__=Dt__namespace;let L=Date.now(),I=`${s}${i.bundleUrl.replace("bundle.js","component.css")}?t=${L}`,W=document.createElement("link");W.rel="stylesheet",W.href=I,W.dataset.forkSlot=e,document.head.appendChild(W);let X=document.createElement("script");return X.src=F+"?t="+L,X.onload=()=>{let q=window.__FORK_EXPORT__;if(q?.default){if(v.current&&y.current&&c.current){let J=v.current.getBoundingClientRect(),N=v.current.cloneNode(true);N.style.position="fixed",N.style.top=`${J.top}px`,N.style.left=`${J.left}px`,N.style.width=`${J.width}px`,N.style.height=`${J.height}px`,N.style.flex="none",N.style.minHeight="auto",N.style.zIndex="9998",N.style.pointerEvents="none",N.style.overflow="hidden";let K=getComputedStyle(v.current).backgroundColor;N.style.backgroundColor=K&&K!=="rgba(0, 0, 0, 0)"&&K!=="transparent"?K:getComputedStyle(document.body).backgroundColor||"#ffffff",document.body.appendChild(N);let G=v.current.querySelectorAll("*"),V=N.querySelectorAll("*");for(let w=0;w<G.length;w++)G[w].scrollTop!==0&&(V[w].scrollTop=G[w].scrollTop),G[w].scrollLeft!==0&&(V[w].scrollLeft=G[w].scrollLeft);x.current=N;}S(()=>q.default),_.current=h;}else console.error(`[Fork:${e}] component.js loaded but no default export found`);window.__FORK_EXPORT__=void 0;},X.onerror=()=>{console.error(`[Fork:${e}] failed to load component.js`);},document.head.appendChild(X),()=>{X.remove(),W.remove(),A.current&&(clearTimeout(A.current),A.current=null),x.current&&(x.current.remove(),x.current=null);}},[h,s,e]),Be.useEffect(()=>{if(!c.current||!m||!v.current){`${e}${c.current}`,v.current;return}let F=y.current;if(!F){return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(!v.current)return;let b=nt(v.current),d=Yt(F,b),g=Xt(F,b),p=x.current;if(`${e}${d.length}${g.length}`,g.length>0&&p){let L=Zt(g);A.current=setTimeout(()=>{A.current=null;let I=400;p.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),L.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),setTimeout(()=>{p.remove(),L.remove(),x.current=null,d.length>0&&(st(d));},I);},3500);}else p&&(p.remove(),x.current=null),d.length>0&&(st(d));y.current=null,c.current=false,h&&(sessionStorage.setItem(`__fork_animated_${e}`,h),`${e}`);});});},[m]);let R={flex:1,minHeight:0,display:"flex",flexDirection:"column"};if(!i||i.status!=="complete"||!i.bundleUrl)return Dt.jsx("div",{ref:v,style:R,children:t});if(!m)return Dt.jsx("div",{ref:v,style:R,children:t});let l=t?.props??{};return Dt.jsx(Le,{slotId:e,resetKey:h,fallback:Dt.jsx("div",{ref:v,style:R,children:t}),children:Dt.jsx(er,{component:m,containerRef:v,wrapperStyle:R,hostProps:l})})}var ct=new Set;function or(e){return `{ ${Object.entries(e).map(([r,o])=>o==null?`${r}: unknown`:Array.isArray(o)?`${r}: ${o.length>0?typeof o[0]:"unknown"}[]`:`${r}: ${typeof o}`).join("; ")} }`}function ut(e,t=new Set){return Be.Children.forEach(e,r=>{if(!Be.isValidElement(r))return;let o=r.props;for(let[n,i]of Object.entries(o))typeof i=="function"&&/^on[A-Z]/.test(n)&&t.add(n);o.children&&ut(o.children,t);}),t}function nr({slotId:e,props:t,children:r,allowedFetches:o,githubRepo:n,callbacks:i,mode:s="iframe",shared:a,events:k}){if(Oe(r,e),s==="direct")return Dt.jsx(at,{slotId:e,githubRepo:n,shared:a,events:k,children:r});let u=be(e),{baseUrl:m,apiKey:S,appId:_}=z(),v=Be.useRef(null),y=Be.useRef(false),c=Be.useRef(null),x=Be.useRef(i);x.current=i;let A=Be.useRef(t);A.current=t;let $=Be.useRef(o);$.current=o,Be.useEffect(()=>{if(typeof process<"u")return;let R=ut(r),f=new Set(i?Object.keys(i):[]),l=[...R].filter(F=>!f.has(F));l.length>0&&console.error(`[ForkSlot:${e}] Missing bridged callbacks! The following callback props are used by children but not passed to ForkSlot's \`callbacks\` prop:
|
|
2
|
+
`+l.map(F=>` - ${F}`).join(`
|
|
3
|
+
`)+"\n\nThe forked component will not be able to call these. Add them to the `callbacks` prop of <ForkSlot>.");},[e,r,i]),Be.useEffect(()=>{ct.has(e)||(ct.add(e),fetch(`${m}/api/v1/slots`,{method:"POST",headers:{Authorization:`Bearer ${S}`,"Content-Type":"application/json"},body:JSON.stringify({id:e,appId:_,label:e,propsShape:t?or(t):"",eventsShape:"{ navigate?: string }",currentLayout:"",githubRepo:n,callbackNames:i?Object.keys(i):[],mode:s||"iframe"})}).catch(()=>{}));},[e,m,S,n,_]);let M=Be.useCallback(R=>{let f=v.current;if(f?.contentWindow&&y.current){let l=x.current?Object.keys(x.current):[];f.contentWindow.postMessage({type:"slot:props",props:R,callbackNames:l},"*"),c.current=null;}else c.current=R;},[]),E=Be.useCallback((R,f)=>{let l=$.current;return !l||l.length===0?false:l.some(F=>{let[b,d]=F.split(" "),g=f.split("?")[0];return R.toUpperCase()===b.toUpperCase()&&g.startsWith(d)})},[]);if(Be.useEffect(()=>{if(!u?.bundleUrl)return;let R=async f=>{if(f.source===v.current?.contentWindow){if(f.data?.type==="slot:ready")y.current=true,v.current?.contentWindow?.postMessage({type:"slot:allowed-fetches",paths:$.current||[]},"*"),$.current,c.current?M(c.current):M(A.current||{});else if(f.data?.type==="slot:event"){let l=f.data.event;l?.navigate&&(window.location.hash=l.navigate);}else if(f.data?.type==="slot:clipboard-write")navigator.clipboard.writeText(f.data.text).catch(l=>{console.warn(`[ForkSlot:${e}] clipboard write failed:`,l.message);});else if(f.data?.type==="slot:callback"){let{name:l,args:F}=f.data,b=x.current?.[l];b?(b(...F||[])):console.warn(`[ForkSlot:${e}] unknown callback: ${l}`);}else if(f.data?.type==="slot:fetch"){let{id:l,method:F,url:b,body:d}=f.data,g=v.current?.contentWindow;if(!g)return;let p=F||"GET";if(!E(p,b)){console.warn(`[ForkSlot:${e}] BLOCKED fetch #${l}: ${p} ${b} \u2014 not in allowedFetches`),g.postMessage({type:"slot:fetch-response",id:l,error:`Fetch not allowed: ${p} ${b}`},"*");return}try{let L={method:p};d&&p!=="GET"&&(L.headers={"Content-Type":"application/json"},L.body=JSON.stringify(d));let I=await fetch(b,L),W=await I.json();`${e}${l}${I.status}`,g.postMessage({type:"slot:fetch-response",id:l,data:W,status:I.status},"*");}catch(L){console.error(`[ForkSlot:${e}] fetch #${l} failed:`,L.message),g.postMessage({type:"slot:fetch-response",id:l,error:L.message},"*");}}}};return window.addEventListener("message",R),()=>{window.removeEventListener("message",R),y.current=false;}},[u?.bundleUrl,e,M,E]),Be.useEffect(()=>{u?.bundleUrl&&y.current&&M(t||{});},[t,u?.bundleUrl,M]),!u||u.status!=="complete"||!u.bundleUrl)return `${e}${u?.status||"none"}${u?.bundleUrl||"none"}`,Dt.jsx(Dt.Fragment,{children:r});`${e}${u.bundleUrl}`;let h=`${m}${u.bundleUrl.replace("/bundle.js","/host")}`;return Dt.jsx("iframe",{ref:v,src:h,sandbox:"allow-scripts allow-same-origin allow-forms allow-clipboard-write",title:`Forked ${e}`,style:{width:"100%",border:"none",flex:1,minHeight:0}})}function ve({style:e={width:20,height:20},...t}){return Dt.jsxs("svg",{viewBox:"320 95 270 345",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:e,...t,children:[Dt.jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M357.789 145.428c0-16.186 13.121-29.307 29.307-29.307 7.773 0 15.227 3.088 20.723 8.584 5.496 5.496 8.584 12.95 8.584 20.723 0 16.186-13.121 29.307-29.307 29.307s-29.307-13.121-29.307-29.307z"}),Dt.jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M387.096 174.735v188"}),Dt.jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M357.789 394.572c0-16.186 13.121-29.307 29.307-29.307 7.773 0 15.227 3.088 20.723 8.584 5.496 5.496 8.584 12.95 8.584 20.723 0 16.186-13.121 29.307-29.307 29.307s-29.307-13.121-29.307-29.307z"}),Dt.jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M388.739 319c10.168-6.317 43.997-26.932 61.009-37.9 17.012-10.968 31.758-19.978 41.064-27.91 9.305-7.931 11.782-14.213 14.767-19.679 2.985-5.465 3.014-8.99 3.141-13.114.128-4.124-.999-8.178-2.377-11.632-1.378-3.454-3.563-6.55-5.889-9.094-2.326-2.543-4.98-4.679-8.066-6.167-3.085-1.488-6.624-2.601-10.448-2.76-3.823-.159-8.624.2-12.495 1.806-3.871 1.607-8.047 4.68-10.732 7.835-2.685 3.156-4.446 7.448-5.378 11.099-.932 3.651-.742 7.485-.213 10.807.528 3.322 1.864 6.46 3.386 9.123 1.523 2.663 3.543 4.843 5.75 6.854 2.207 2.011 4.38 3.914 7.491 5.214 3.111 1.3 6.57 2.808 11.178 2.584 4.607-.225 9.363-.471 16.466-3.932 7.103-3.46 16.076-5.382 26.154-16.831 10.077-11.449 28.593-43.219 34.312-51.862"}),Dt.jsx("path",{fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round",d:"M527.117 162.547L570.487 134.368Q577.196 130.009 577.624 137.997L580.39 189.69Q580.818 197.678 573.69 194.047L527.536 170.538Q520.408 166.907 527.117 162.547Z"})]})}function Ne({onClick:e}){let[t,r]=Be.useState(false),[o,n]=Be.useState(false),i=t?48:40;return Dt.jsx("button",{onClick:e,onMouseEnter:()=>r(true),onMouseLeave:()=>{r(false),n(false);},onMouseDown:()=>n(true),onMouseUp:()=>n(false),style:{position:"fixed",bottom:24,right:24,zIndex:40,width:i,height:i,borderRadius:"50%",backgroundColor:t?"rgba(255, 255, 255, 1)":"rgba(255, 255, 255, 0.3)",border:t?"1px solid rgba(156, 163, 175, 1)":"1px solid rgba(156, 163, 175, 0.3)",display:"flex",alignItems:"center",justifyContent:"center",color:t?"#1c4587":"rgba(28, 69, 135, 0.5)",boxShadow:t?"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)":"0 1px 2px 0 rgba(0, 0, 0, 0.05)",transform:o?"scale(0.95)":"scale(1)",transition:"all 300ms",cursor:"pointer",padding:0,margin:0,outline:"none",boxSizing:"border-box"},title:"Fork this app",children:Dt.jsx(ve,{style:{width:24,height:24}})})}var mr={status:lucideReact.Loader2,agent_message:lucideReact.MessageSquare,tool_use:lucideReact.Wrench,build_start:lucideReact.Package,build_complete:lucideReact.Check,build_error:lucideReact.AlertCircle,complete:lucideReact.Sparkles,error:lucideReact.AlertCircle},gr={status:"#60a5fa",agent_message:"#a0a0a0",tool_use:"#fbbf24",build_start:"#c084fc",build_complete:"#6b7280",build_error:"#f87171",complete:"#6b7280",error:"#f87171"},hr={read:lucideReact.FileSearch,write:lucideReact.Pencil,search:lucideReact.FileSearch,shell:lucideReact.Terminal,build:lucideReact.Package},yr={read:"#60a5fa",write:"#fbbf24",search:"#60a5fa",shell:"#a78bfa",build:"#c084fc"};function De(e){let t=e.data;switch(e.type){case "status":return `${t.message||t.status||"..."}`;case "agent_message":{let r=String(t.content||"");return /failed:/i.test(r)&&(r.includes("ENOENT")||r.includes("{")||r.includes("/Users/"))?"Adapting approach...":r}case "tool_use":return String(t.label||"Working on it");case "build_start":return "Bundling your component...";case "build_complete":return "Build complete!";case "build_error":return `Build failed: ${t.error}`;case "complete":return "Your fork is ready!";case "error":return `Error: ${t.error}`;default:return JSON.stringify(t)}}function bt({events:e}){let t=Be.useRef(null);return Be.useEffect(()=>{t.current&&(t.current.scrollTop=t.current.scrollHeight);},[e]),Dt.jsxs(Dt.Fragment,{children:[Dt.jsx("style",{children:`
|
|
4
|
+
@keyframes __fork-spin {
|
|
5
|
+
from { transform: rotate(0deg); }
|
|
6
|
+
to { transform: rotate(360deg); }
|
|
7
|
+
}
|
|
8
|
+
.__fork-stream::-webkit-scrollbar {
|
|
9
|
+
width: 4px;
|
|
10
|
+
}
|
|
11
|
+
.__fork-stream::-webkit-scrollbar-track {
|
|
12
|
+
background: transparent;
|
|
13
|
+
}
|
|
14
|
+
.__fork-stream::-webkit-scrollbar-thumb {
|
|
15
|
+
background: rgba(255, 255, 255, 0.15);
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
}
|
|
18
|
+
.__fork-stream::-webkit-scrollbar-thumb:hover {
|
|
19
|
+
background: rgba(255, 255, 255, 0.3);
|
|
20
|
+
}
|
|
21
|
+
`}),Dt.jsxs("div",{className:"__fork-stream",ref:t,style:{scrollbarWidth:"thin",scrollbarColor:"rgba(255, 255, 255, 0.15) transparent",backgroundColor:"#1a1a2e",borderRadius:"8px",padding:"12px",fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:"11px",maxHeight:"300px",overflowY:"auto",boxSizing:"border-box"},children:[e.length===0&&Dt.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",color:"#6b7280",fontSize:"11px"},children:[Dt.jsx(lucideReact.Loader2,{style:{width:"12px",height:"12px",animation:"__fork-spin 1s linear infinite",flexShrink:0}}),"Connecting to agent..."]}),e.map((r,o)=>{let n=o===e.length-1,i=r.type==="complete"||r.type==="error"||r.type==="build_complete"||r.type==="build_error",s=n&&!i&&(r.type==="status"||r.type==="tool_use"||r.type==="build_start"),a=mr[r.type]||lucideReact.Code,k=gr[r.type]||"#9ca3af";if(r.type==="tool_use"){let u=String(r.data.category||"");a=hr[u]||lucideReact.Wrench,k=yr[u]||"#fbbf24";}return s?a=lucideReact.Loader2:!n&&r.type==="status"&&(a=lucideReact.Check,k="#4ade80"),Dt.jsxs("div",{style:{display:"flex",gap:"6px",marginBottom:"6px",lineHeight:1.625},children:[Dt.jsx(a,{style:{width:"12px",height:"12px",marginTop:"2px",flexShrink:0,color:k,...s?{animation:"__fork-spin 1s linear infinite"}:{}}}),Dt.jsx("span",{style:{color:n&&!i?"#d1d5db":"#6b7280",wordBreak:"break-all"},children:De(r)})]},o)})]})]})}var Er=["Dark mode redesign","New workflow for adding to this page","Data-dense analytics view"],vt=35,$r="Working on Feature",Ar="Built Custom Feature";function Cr(e){return e.length<=vt?e:e.slice(0,vt-3).trimEnd()+"..."}function Tr({events:e}){let[t,r]=Be.useState("Setting up environment..."),[o,n]=Be.useState(true),i=Be.useRef(t),s=Be.useRef(false);return Be.useEffect(()=>{if(!s.current){for(let k of e)if(k.type==="status"&&String(k.data.message||"").includes("Agent started")){s.current=true;break}}let a="Setting up environment...";if(s.current)for(let k=e.length-1;k>=0;k--){let u=e[k];if(u.type==="tool_use"||u.type==="build_start"||u.type==="build_complete"){a=Cr(De(u));break}}if(a!==i.current){n(false);let k=setTimeout(()=>{r(a),i.current=a,n(true);},200);return ()=>clearTimeout(k)}},[e]),Dt.jsx("span",{style:{fontSize:11,color:"#d1d5db",fontWeight:500,opacity:o?1:0,transition:"opacity 0.2s ease",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",minWidth:0},children:t})}function Ie({state:e,fork:t,events:r,error:o,slotId:n,targetId:i,targetLabel:s,historyMode:a="slot",examplePrompts:k=Er,onSubmit:u,onUndo:m,onClose:S,baseUrl:_,apiKey:v,userId:y,userHash:c,appId:x}){let[A,$]=Be.useState(""),[M,E]=Be.useState(false),[h,R]=Be.useState([]),[f,l]=Be.useState(false),[F,b]=Be.useState(false),[d,g]=Be.useState(false),[p,L]=Be.useState(false),[I,W]=Be.useState(false),[X,q]=Be.useState(false),[J,N]=Be.useState(null),[K,G]=Be.useState(false),[V,w]=Be.useState(false),[C,O]=Be.useState(false),[j,ne]=Be.useState(false),[Ce,Ye]=Be.useState(null),[Lt,Xe]=Be.useState(false),ge=Be.useRef(null),he=Be.useRef(null),{resetAllForks:Bt}=z(),Z=i??n??"",Te=(s||Z).replace(/[-_]+/g," ").replace(/\b\w/g,P=>P.toUpperCase()),_e=Be.useRef(""),Ot=r.find(P=>{let B=P.data;return P.type==="status"&&B.summary})?.data?.summary||t?.summary||$r;Be.useEffect(()=>{if(a==="none"){l(true);return}if(!_||!v||!y||!Z||f)return;let P=new URLSearchParams({userId:y});if(c&&P.set("userHash",c),a==="slot")P.set("slotId",Z);else if(a==="boundary"){if(!x){l(true);return}P.set("boundaryId",Z),P.set("appId",x);}fetch(`${_}/api/v1/forks/history?${P.toString()}`,{headers:{Authorization:`Bearer ${v}`}}).then(B=>B.ok?B.json():[]).then(B=>{let H=[];for(let ye of B)ye.role==="user"?H.push({type:"user",text:ye.content}):H.push({type:"applied",text:ye.content});H.length>0&&R(H),l(true);}).catch(()=>l(true));},[v,x,_,f,a,Z,c,y]),Be.useEffect(()=>{e==="complete"&&(w(false),G(false));},[e]),Be.useEffect(()=>{let P=requestAnimationFrame(()=>b(true));return ()=>cancelAnimationFrame(P)},[]),Be.useEffect(()=>{if(F&&!d&&(e==="prompting"||e==="complete")){let P=setTimeout(()=>ge.current?.focus(),450);return ()=>clearTimeout(P)}},[F,d,e]),Be.useEffect(()=>{if(e==="complete"&&_e.current){let B=r.find(H=>H.type==="complete")?.data?.summary||t?.summary||Ar;R(H=>H[H.length-1]?.type==="applied"?H:[...H,{type:"applied",text:B}]),$(""),setTimeout(()=>ge.current?.focus(),200);}},[e,Te,r,t?.summary]),Be.useEffect(()=>{he.current&&(he.current.scrollTop=he.current.scrollHeight);},[h,e]);let Ze=()=>{A.trim()&&(_e.current=A.trim(),R(P=>[...P,{type:"user",text:A.trim()}]),u(A.trim(),Z),$(""));},Ht=async()=>{if(!(!m||j||!Z)){ne(true);try{let P=await m(Z);R(B=>{let H=[...B];return H.length>=2&&H[H.length-1]?.type==="applied"?H.splice(-2,2):H.length>=1&&H[H.length-1]?.type==="applied"&&H.splice(-1,1),H}),P?.removed&&R([]);}catch{}finally{ne(false);}}},Qe=()=>{g(true),b(false),setTimeout(()=>S(),350);},se=F&&!d;return Dt.jsxs(Dt.Fragment,{children:[Dt.jsx("style",{children:`
|
|
22
|
+
@keyframes __fork-pulse {
|
|
23
|
+
0%, 100% { opacity: 1; }
|
|
24
|
+
50% { opacity: 0.5; }
|
|
25
|
+
}
|
|
26
|
+
@keyframes __fork-spin {
|
|
27
|
+
from { transform: rotate(0deg); }
|
|
28
|
+
to { transform: rotate(360deg); }
|
|
29
|
+
}
|
|
30
|
+
@keyframes __fork-fade-in {
|
|
31
|
+
from { opacity: 0; }
|
|
32
|
+
to { opacity: 1; }
|
|
33
|
+
}
|
|
34
|
+
.__fork-panel ::-webkit-scrollbar {
|
|
35
|
+
width: 2px;
|
|
36
|
+
}
|
|
37
|
+
.__fork-panel ::-webkit-scrollbar-track {
|
|
38
|
+
background: transparent;
|
|
39
|
+
}
|
|
40
|
+
.__fork-panel ::-webkit-scrollbar-thumb {
|
|
41
|
+
background: rgba(0, 0, 0, 0.12);
|
|
42
|
+
border-radius: 2px;
|
|
43
|
+
}
|
|
44
|
+
.__fork-panel ::-webkit-scrollbar-thumb:hover {
|
|
45
|
+
background: rgba(0, 0, 0, 0.22);
|
|
46
|
+
}
|
|
47
|
+
.__fork-panel {
|
|
48
|
+
scrollbar-width: thin;
|
|
49
|
+
scrollbar-color: rgba(0, 0, 0, 0.12) transparent;
|
|
50
|
+
}
|
|
51
|
+
`}),Dt.jsx("div",{className:"__fork-panel",onMouseEnter:()=>E(true),onMouseLeave:()=>E(false),style:{position:"fixed",bottom:24,right:24,zIndex:50,width:V?"auto":320,transformOrigin:"bottom right",transform:se?"scale(1)":"scale(0)",opacity:se?1:0,borderRadius:se?16:200,background:"rgba(255, 255, 255, 0.95)",backdropFilter:"blur(24px) saturate(1.6)",WebkitBackdropFilter:"blur(24px) saturate(1.6)",boxShadow:se?"0 24px 80px -12px rgba(0, 0, 0, 0.25), 0 8px 24px -8px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.06)":"0 2px 12px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.08)",border:"1px solid rgba(0, 0, 0, 0.08)",transition:"transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), border-radius 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease, opacity 0.3s ease, width 0.3s ease",overflow:"hidden",boxSizing:"border-box",fontFamily:'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'},children:Dt.jsxs("div",{style:{display:"flex",flexDirection:"column",opacity:se?1:0,transition:se?"opacity 0.25s ease 0.15s":"opacity 0.15s ease"},children:[Dt.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 16px"},children:[Dt.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,cursor:V?"pointer":"default",minWidth:0,flex:1},onClick:V?()=>w(false):void 0,children:[Dt.jsx(ve,{style:{width:14,height:14,color:"#1c4587",cursor:"pointer"},onDoubleClick:async P=>{if(P.stopPropagation(),!Lt&&confirm("Reset all forks? This will remove all forked components.")){Xe(true);try{let B=await Bt();`${B?.deleted??0}`,R([]),$(""),G(!1),w(!1),g(!0),b(!1),setTimeout(()=>S(),350);}catch(B){console.error("[Fork] Reset failed:",B);}finally{Xe(false);}}}}),Dt.jsx("span",{style:{fontSize:12,fontWeight:600,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},children:e==="running"?Ot:`Fork ${Te}`}),e==="running"&&V&&Dt.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"#1c4587",strokeWidth:"2.5",strokeLinecap:"round",style:{animation:"__fork-spin 2s linear infinite",flexShrink:0},children:Dt.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),e==="complete"&&Dt.jsx("div",{style:{height:6,width:6,backgroundColor:"#1c4587",borderRadius:"50%",flexShrink:0}})]}),Dt.jsxs("div",{style:{display:"flex",alignItems:"center",gap:2},children:[e==="running"&&!V&&Dt.jsx("button",{onClick:()=>w(true),onMouseEnter:()=>O(true),onMouseLeave:()=>O(false),style:{padding:4,borderRadius:6,color:C?"#4b5563":"#9ca3af",backgroundColor:C?"#f3f4f6":"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.15s, color 0.15s"},children:Dt.jsx(lucideReact.Minus,{style:{width:14,height:14}})}),Dt.jsx("button",{onClick:Qe,onMouseEnter:()=>L(true),onMouseLeave:()=>L(false),style:{padding:4,borderRadius:6,color:p?"#4b5563":"#9ca3af",backgroundColor:p?"#f3f4f6":"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.15s, color 0.15s"},children:Dt.jsx(lucideReact.X,{style:{width:14,height:14}})})]})]}),!V&&Dt.jsxs(Dt.Fragment,{children:[Dt.jsx("div",{style:{height:1,backgroundColor:"rgba(229, 231, 235, 0.6)"}}),Dt.jsxs("div",{ref:he,style:{overflowY:"visible"},children:[e==="prompting"&&h.length===0&&Dt.jsxs("div",{style:{padding:"20px 16px",textAlign:"center"},children:[Dt.jsx("p",{style:{fontSize:12,color:"#6b7280",marginBottom:12,lineHeight:1.625,margin:"0 0 12px 0"},children:"Describe the feature you want to build."}),Dt.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:6,justifyContent:"center"},children:k.map((P,B)=>Dt.jsx("button",{onClick:()=>{$(P),ge.current?.focus();},onMouseEnter:()=>N(B),onMouseLeave:()=>N(null),style:{fontSize:11,padding:"4px 10px",borderRadius:9999,color:J===B?"#1f2937":"#6b7280",backgroundColor:J===B?"#f9fafb":"transparent",border:J===B?"1px solid #d1d5db":"1px solid #e5e7eb",cursor:"pointer",transition:"color 0.15s, background-color 0.15s, border-color 0.15s",fontFamily:"inherit"},children:P},P))})]}),h.length>0&&Dt.jsx("div",{style:{padding:"12px 12px 0 12px"},children:h.map((P,B)=>Dt.jsx("div",{style:{marginBottom:B<h.length-1?8:0},children:P.type==="user"?Dt.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8,flexDirection:"row-reverse"},children:[Dt.jsx("div",{style:{width:20,height:20,borderRadius:"50%",backgroundColor:"#e5e7eb",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,marginTop:2},children:Dt.jsx(lucideReact.User,{style:{width:12,height:12,color:"#6b7280"}})}),Dt.jsx("div",{style:{backgroundColor:"#f3f4f6",borderRadius:"12px 4px 12px 12px",padding:"6px 12px",fontSize:12,color:"#374151",lineHeight:1.5},children:P.text})]}):Dt.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8},children:[Dt.jsx("div",{style:{width:20,height:20,borderRadius:"50%",backgroundColor:"#f0fdf4",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,marginTop:2},children:Dt.jsx(lucideReact.Check,{style:{width:12,height:12,color:"#9ca3af"}})}),Dt.jsxs("div",{style:{backgroundColor:"#f9fafb",borderRadius:"4px 12px 12px 12px",padding:"6px 12px",fontSize:12,color:"#6b7280",fontWeight:500,display:"flex",alignItems:"center",gap:6},children:[Dt.jsx("span",{style:{flex:1},children:P.text}),m&&B===h.length-1&&e!=="running"&&Dt.jsxs("button",{onClick:H=>{H.stopPropagation(),Ht();},onMouseEnter:()=>Ye(B),onMouseLeave:()=>Ye(null),disabled:j,style:{position:"relative",padding:2,borderRadius:4,border:"none",background:Ce===B?"rgba(0,0,0,0.06)":"transparent",color:Ce===B?"#6b7280":"#d1d5db",cursor:j?"default":"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.15s, background 0.15s",opacity:j?.4:1,flexShrink:0},children:[Dt.jsx(lucideReact.Undo2,{style:{width:11,height:11}}),Ce===B&&Dt.jsx("span",{style:{position:"absolute",bottom:"calc(100% + 4px)",right:0,fontSize:10,fontWeight:500,color:"#fff",background:"#374151",borderRadius:4,padding:"2px 6px",whiteSpace:"nowrap",pointerEvents:"none",lineHeight:"16px"},children:"Undo"})]})]})]})},B))}),e==="running"&&Dt.jsx("div",{style:{padding:12},children:Dt.jsxs("div",{onClick:()=>G(!K),style:{backgroundColor:"#1a1a2e",borderRadius:12,overflow:"hidden",cursor:"pointer",transition:"all 0.3s cubic-bezier(0.22, 1, 0.36, 1)"},children:[Dt.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 14px"},children:[Dt.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,minWidth:0},children:[Dt.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"#6b7280",strokeWidth:"2.5",strokeLinecap:"round",style:{animation:"__fork-spin 2s linear infinite",flexShrink:0},children:Dt.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),Dt.jsx(Tr,{events:r})]}),Dt.jsx("div",{style:{color:"#6b7280",flexShrink:0,marginLeft:8,transition:"transform 0.2s ease",transform:K?"rotate(180deg)":"rotate(0deg)"},children:Dt.jsx(lucideReact.ChevronDown,{style:{width:14,height:14}})})]}),Dt.jsx("div",{style:{maxHeight:K?300:0,opacity:K?1:0,transition:"max-height 0.35s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.25s ease",overflow:"hidden"},children:Dt.jsx("div",{style:{borderTop:"1px solid rgba(255,255,255,0.08)",maxHeight:300,overflowY:"auto"},children:Dt.jsx(bt,{events:r})})})]})}),e==="error"&&Dt.jsxs("div",{style:{padding:"16px",textAlign:"center"},children:[Dt.jsx("div",{style:{width:32,height:32,backgroundColor:"#fef2f2",borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 8px auto"},children:Dt.jsx(lucideReact.X,{style:{width:16,height:16,color:"#ef4444"}})}),Dt.jsx("p",{style:{fontSize:11,color:"#6b7280",marginBottom:8,maxWidth:260,margin:"0 auto 8px auto"},children:o}),Dt.jsxs("button",{onClick:()=>{let P=t?.prompt||_e.current;P&&u(P,Z);},onMouseEnter:()=>q(true),onMouseLeave:()=>q(false),style:{display:"inline-flex",alignItems:"center",gap:6,padding:"6px 12px",borderRadius:8,fontSize:11,fontWeight:500,color:"#4f46e5",backgroundColor:X?"#e0e7ff":"#eef2ff",border:"none",cursor:"pointer",transition:"background-color 0.15s",fontFamily:"inherit"},children:[Dt.jsx(lucideReact.RotateCcw,{style:{width:12,height:12}})," Try Again"]})]})]}),e!=="running"&&Dt.jsx("div",{style:{padding:"4px 8px 8px 8px"},children:Dt.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,borderRadius:12,padding:"6px 8px 6px 12px",background:"rgba(0, 0, 0, 0.04)",border:"1px solid rgba(0, 0, 0, 0.06)"},children:[Dt.jsx("textarea",{ref:ge,value:A,onChange:P=>{$(P.target.value),P.target.style.height="auto",P.target.style.height=Math.min(P.target.scrollHeight,120)+"px";},onKeyDown:P=>{P.key==="Enter"&&!P.shiftKey&&(P.preventDefault(),Ze()),P.key==="Escape"&&Qe();},placeholder:h.length>0?"Ask for another change...":`Describe your ideal ${Te.toLowerCase()}...`,rows:1,style:{flex:1,backgroundColor:"transparent",fontSize:12,color:"#111827",border:"none",outline:"none",padding:"0 4px 0 0",fontFamily:"inherit",resize:"none",lineHeight:1.5,maxHeight:120,overflow:"auto"}}),Dt.jsx("button",{onClick:Ze,disabled:!A.trim(),onMouseEnter:()=>W(true),onMouseLeave:()=>W(false),style:{width:24,height:24,borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",color:"#ffffff",opacity:A.trim()?1:.25,transform:I&&A.trim()?"scale(1.1)":"scale(1)",background:A.trim()?"#1c4587":"rgba(0,0,0,0.12)",border:"none",cursor:A.trim()?"pointer":"default",flexShrink:0,alignSelf:"flex-end",transition:"transform 0.15s, opacity 0.15s",padding:0,marginBottom:2},children:Dt.jsx(lucideReact.ArrowUp,{style:{width:12,height:12}})})]})})]})]})})]})}function St(e){if("target"in e&&e.target)return e.target;if("boundaryId"in e&&e.boundaryId)return {type:"boundary",id:e.boundaryId,title:e.title};if("slotId"in e&&e.slotId)return {type:"slot",id:e.slotId,title:e.title??e.slotLabel};throw new Error("Fork chat target requires either target, slotId, or boundaryId.")}function je(e){let{apiKey:t,userId:r,userHash:o,baseUrl:n,appId:i,refreshModuleManifest:s,queueBoundaryAnimation:a}=z(),[k,u]=Be.useState("idle"),[m,S]=Be.useState(null),[_,v]=Be.useState([]),[y,c]=Be.useState(null),x=Be.useRef(null),A=Be.useCallback(()=>{u("prompting"),v([]),c(null),S(null);},[]),$=Be.useCallback(()=>{u("idle"),x.current&&(x.current.close(),x.current=null);},[]),M=Be.useCallback(async h=>{try{if(!i)throw new Error("ForkProvider requires appId for module boundary prompts.");u("running"),v([]),c(null);let R={userId:r,prompt:h,boundaryId:e,appId:i};o&&(R.userHash=o);let f=await fetch(`${n}/api/v1/forks`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(R)});if(!f.ok){let d=await f.json().catch(()=>({}));throw new Error(d.error||`API error: ${f.status}`)}let l=await f.json();S(l);let F=new URLSearchParams({key:t});o&&(F.set("userId",r),F.set("userHash",o));let b=new EventSource(`${n}/api/v1/forks/${l.id}/events?${F.toString()}`);x.current=b,b.onmessage=d=>{try{let g=JSON.parse(d.data);if(v(p=>[...p,g]),g.type==="complete"){let p=g.data;a(e,l.id),s().catch(()=>{}).finally(()=>{let L={...l,status:"complete",moduleUrl:p.moduleUrl,cssUrls:p.cssUrls,summary:p.summary,completedAt:new Date().toISOString()};S(L),u("complete"),b.close();});}else if(g.type==="error"){let p=g.data;c(p.error||"Unknown error"),u("error"),b.close();}}catch{}},b.onerror=()=>{fetch(`${n}/api/v1/forks/${l.id}`,{headers:{Authorization:`Bearer ${t}`}}).then(d=>d.json()).then(d=>{S(d),d.status==="complete"?(a(e,d.id),s().catch(()=>{}),u("complete")):d.status==="error"&&(c(d.error||"Fork generation failed"),u("error"));}).catch(()=>{c("Connection lost"),u("error");}),b.close();};}catch(R){c(R.message),u("error");}},[t,i,n,e,a,s,o,r]),E=Be.useCallback(async()=>{try{if(!i)throw new Error("ForkProvider requires appId for boundary undo.");let h={userId:r,boundaryId:e,appId:i};o&&(h.userHash=o);let R=await fetch(`${n}/api/v1/forks/undo`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(h)});if(!R.ok){let l=await R.json().catch(()=>({}));throw new Error(l.error||`API error: ${R.status}`)}let f=await R.json();return await s().catch(()=>{}),f.removed?(S(null),u("prompting")):f.fork&&(S(f.fork),u("complete")),f}catch(h){throw c(h.message),h}},[t,i,n,e,s,o,r]);return {state:k,fork:m,events:_,error:y,open:A,close:$,startFork:M,undoFork:E}}function Ft(e){let{state:t,fork:r,events:o,error:n,open:i,close:s,startFork:a,undoFork:k}=je(e);return {state:t,fork:r,events:o,error:n,isOpen:t!=="idle",open:i,close:s,submit:a,undo:k}}function ze(){let{apiKey:e,userId:t,userHash:r,baseUrl:o,setSlotFork:n,clearSlotFork:i,skipAnimationForSlot:s}=z(),[a,k]=Be.useState("idle"),[u,m]=Be.useState(null),[S,_]=Be.useState([]),[v,y]=Be.useState(null),c=Be.useRef(null),x=Be.useCallback(()=>{k("prompting"),_([]),y(null),m(null);},[]),A=Be.useCallback(()=>{k("idle"),c.current&&(c.current.close(),c.current=null);},[]),$=Be.useCallback(async(E,h)=>{try{k("running"),_([]),y(null);let R={userId:t,prompt:E};h&&(R.slotId=h),r&&(R.userHash=r);let f=await fetch(`${o}/api/v1/forks`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(R)});if(!f.ok){let d=await f.json().catch(()=>({}));throw new Error(d.error||`API error: ${f.status}`)}let l=await f.json();m(l);let F=new URLSearchParams({key:e});r&&(F.set("userId",t),F.set("userHash",r));let b=new EventSource(`${o}/api/v1/forks/${l.id}/events?${F.toString()}`);c.current=b,b.onmessage=d=>{try{let g=JSON.parse(d.data);if(_(p=>[...p,g]),g.type==="complete"){let p=g.data,L={...l,status:"complete",bundleUrl:p.bundleUrl,summary:p.summary,completedAt:new Date().toISOString()};m(L),k("complete"),h&&p.bundleUrl&&n(h,L),b.close();}else if(g.type==="error"){let p=g.data;y(p.error||"Unknown error"),k("error"),b.close();}}catch{}},b.onerror=()=>{fetch(`${o}/api/v1/forks/${l.id}`,{headers:{Authorization:`Bearer ${e}`}}).then(d=>d.json()).then(d=>{m(d),d.status==="complete"?(k("complete"),h&&d.bundleUrl&&n(h,d)):d.status==="error"&&(y(d.error||"Fork generation failed"),k("error"));}).catch(()=>{y("Connection lost"),k("error");}),b.close();};}catch(R){y(R.message),k("error");}},[e,t,r,o,n]),M=Be.useCallback(async E=>{try{let h={userId:t,slotId:E};r&&(h.userHash=r);let R=await fetch(`${o}/api/v1/forks/undo`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(h)});if(!R.ok){let l=await R.json().catch(()=>({}));throw new Error(l.error||`API error: ${R.status}`)}let f=await R.json();return s(E),f.removed?(i(E),m(null),k("prompting")):f.fork&&(n(E,f.fork),m(f.fork)),f}catch(h){throw y(h.message),h}},[e,t,r,o,i,n]);return {state:a,fork:u,events:S,error:v,open:x,close:A,startFork:$,undoFork:M}}function Rt(){let{state:e,fork:t,events:r,error:o,open:n,close:i,startFork:s,undoFork:a}=ze();return {state:e,fork:t,events:r,error:o,isOpen:e!=="idle",open:n,close:i,submit:s,undo:a}}function We(e){let t=St(e),r=Rt(),o=Ft(t.type==="boundary"?t.id:""),{baseUrl:n,apiKey:i,userId:s,userHash:a,appId:k}=z(),u=t.type==="slot"?r:o,m=t.type==="slot"?"slot":"boundary",S=t.id,_=t.title,v=Be.useCallback((c,x)=>t.type==="slot"?r.submit(c,x??t.id):o.submit(c),[o,r,t]),y=Be.useCallback(c=>t.type==="slot"?r.undo(c??t.id):o.undo(),[o,r,t]);return {...u,target:t,targetId:S,targetLabel:_,historyMode:m,submit:v,undo:y,buttonProps:{onClick:u.open},panelProps:{state:u.state,fork:u.fork,events:u.events,error:u.error,...t.type==="slot"?{slotId:S,targetLabel:_,historyMode:m}:{targetId:S,targetLabel:_,historyMode:m},onSubmit:v,onUndo:y,onClose:u.close,baseUrl:n,apiKey:i,userId:s,userHash:a,appId:k}}}function me(e){let{examplePrompts:t}=e,r=We(e);return r.isOpen?Dt.jsx(Ie,{...r.panelProps,examplePrompts:t}):Dt.jsx(Ne,{...r.buttonProps})}function Mr({boundaryId:e,title:t,examplePrompts:r}){return Dt.jsx(me,{boundaryId:e,title:t,examplePrompts:r})}function Ke(e){let t=Array.from(e.children).filter(o=>o instanceof HTMLElement);return t.length===1?t[0]:getComputedStyle(e).display==="contents"?null:e}function $t(e){let t=e.getBoundingClientRect(),r=e.cloneNode(true);r.style.position="fixed",r.style.top=`${t.top}px`,r.style.left=`${t.left}px`,r.style.width=`${t.width}px`,r.style.height=`${t.height}px`,r.style.flex="none",r.style.minHeight="auto",r.style.zIndex="9998",r.style.pointerEvents="none",r.style.overflow="hidden";let o=getComputedStyle(e).backgroundColor;r.style.backgroundColor=o&&o!=="rgba(0, 0, 0, 0)"&&o!=="transparent"?o:getComputedStyle(document.body).backgroundColor||"#ffffff",document.body.appendChild(r);let n=e.querySelectorAll("*"),i=r.querySelectorAll("*");for(let s=0;s<n.length;s+=1)n[s].scrollTop!==0&&(i[s].scrollTop=n[s].scrollTop),n[s].scrollLeft!==0&&(i[s].scrollLeft=n[s].scrollLeft);return r}function Ge(e){let t=[],r=e.querySelectorAll("*");for(let o of r){if(!(o instanceof HTMLElement))continue;let n=o.getBoundingClientRect();if(n.width<10||n.height<10||["SCRIPT","STYLE","META","LINK"].includes(o.tagName))continue;let i=getComputedStyle(o),s=parseFloat(i.borderTopLeftRadius)||0;t.push({tag:o.tagName,className:o.className||"",text:(o.textContent||"").slice(0,50).trim(),rect:n,borderRadius:s});}return t}function At(e,t){let r=[];for(let o of t)if(!(e.find(s=>s.tag===o.tag&&s.className===o.className&&Math.abs(s.rect.top-o.rect.top)<20&&Math.abs(s.rect.left-o.rect.left)<20)||r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom))){for(let s=r.length-1;s>=0;s-=1){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Ct(e,t){let r=[];for(let o of e)if(!(t.find(s=>s.tag===o.tag&&s.className===o.className&&Math.abs(s.rect.top-o.rect.top)<20&&Math.abs(s.rect.left-o.rect.left)<20)||r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom))){for(let s=r.length-1;s>=0;s-=1){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Tt(e,t,r,o,n){let i=Math.max(0,Math.min(n,r/2,o/2));return i===0?`M ${e} ${t} L ${e+r} ${t} L ${e+r} ${t+o} L ${e} ${t+o} Z`:[`M ${e+i} ${t}`,`L ${e+r-i} ${t}`,`A ${i} ${i} 0 0 1 ${e+r} ${t+i}`,`L ${e+r} ${t+o-i}`,`A ${i} ${i} 0 0 1 ${e+r-i} ${t+o}`,`L ${e+i} ${t+o}`,`A ${i} ${i} 0 0 1 ${e} ${t+o-i}`,`L ${e} ${t+i}`,`A ${i} ${i} 0 0 1 ${e+i} ${t}`,"Z"].join(" ")}function Ve(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-highlights","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs");o.appendChild(n);let i=[];for(let m=0;m<e.length;m+=1){let{rect:S,borderRadius:_}=e[m],v=S.left-.5,y=S.top-.5,c=S.width+1,x=S.height+1,A=Math.min(_+.5,c/2,x/2),$=Tt(v,y,c,x,A),M=`__fork-glow-${m}`,E=document.createElementNS(t,"filter");E.setAttribute("id",M),E.setAttribute("x","-100%"),E.setAttribute("y","-100%"),E.setAttribute("width","300%"),E.setAttribute("height","300%");let h=document.createElementNS(t,"feGaussianBlur");h.setAttribute("in","SourceGraphic"),h.setAttribute("stdDeviation","8"),E.appendChild(h),n.appendChild(E);let R=`__fork-mask-${m}`,f=document.createElementNS(t,"mask");f.setAttribute("id",R),f.setAttribute("maskUnits","userSpaceOnUse"),f.setAttribute("x",String(v-200)),f.setAttribute("y",String(y-200)),f.setAttribute("width",String(c+400)),f.setAttribute("height",String(x+400));let l=document.createElementNS(t,"rect");l.setAttribute("x",String(v-200)),l.setAttribute("y",String(y-200)),l.setAttribute("width",String(c+400)),l.setAttribute("height",String(x+400)),l.setAttribute("fill","white"),f.appendChild(l);let F=document.createElementNS(t,"path");F.setAttribute("d",$),F.setAttribute("fill","black"),f.appendChild(F),n.appendChild(f);let b=document.createElementNS(t,"g");b.setAttribute("mask",`url(#${R})`),b.setAttribute("opacity","0");let d=document.createElementNS(t,"g");d.setAttribute("filter",`url(#${M})`);let g=document.createElementNS(t,"path");g.setAttribute("d",$),g.setAttribute("fill","none"),g.setAttribute("stroke","rgba(150, 185, 220, 0.6)"),g.setAttribute("stroke-width","6"),g.setAttribute("stroke-linecap","round"),d.appendChild(g),b.appendChild(d),o.appendChild(b);let p=document.createElementNS(t,"path");p.setAttribute("d",$),p.setAttribute("fill","none"),p.setAttribute("stroke","rgba(150, 185, 220, 0.35)"),p.setAttribute("stroke-width","2"),p.setAttribute("stroke-linecap","round"),p.setAttribute("opacity","0"),o.appendChild(p),i.push(g,p),g.__group=b;}r.appendChild(o),document.body.appendChild(r);let s=[];for(let m=0;m<i.length;m+=2){let S=i[m],_=i[m+1],v=S.__group;if(!v)continue;let y=_.getTotalLength(),c=S.getTotalLength();if(y<=0)continue;let x=y*.35;_.setAttribute("stroke-dasharray",`${x} ${y-x}`),_.setAttribute("stroke-dashoffset","0"),s.push(_.animate([{strokeDashoffset:0,opacity:0,offset:0},{strokeDashoffset:-0.2*y,opacity:.92,offset:.06},{strokeDashoffset:-2*y,opacity:.92,offset:.92},{strokeDashoffset:-2.25*y,opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));let A=c*.35;S.setAttribute("stroke-dasharray",`${A} ${c-A}`),S.setAttribute("stroke-dashoffset","0"),s.push(S.animate([{strokeDashoffset:0,offset:0},{strokeDashoffset:-0.2*c,offset:.06},{strokeDashoffset:-2*c,offset:.92},{strokeDashoffset:-2.25*c,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"})),s.push(v.animate([{opacity:0,offset:0},{opacity:.92,offset:.06},{opacity:.92,offset:.92},{opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));}let a=false,k=()=>{if(a)return;a=true,clearTimeout(u);for(let S of s)try{S.cancel();}catch{}let m=r.animate([{opacity:1},{opacity:0}],{duration:400,fill:"forwards"});m.onfinish=()=>r.remove(),window.removeEventListener("click",k);},u=setTimeout(k,14500);return setTimeout(()=>{a||window.addEventListener("click",k);},500),k}function _t(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-removed","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs"),i=document.createElementNS(t,"filter");i.setAttribute("id","__fork-removed-shadow"),i.setAttribute("x","-10%"),i.setAttribute("y","-10%"),i.setAttribute("width","120%"),i.setAttribute("height","120%");let s=document.createElementNS(t,"feDropShadow");s.setAttribute("dx","0"),s.setAttribute("dy","1"),s.setAttribute("stdDeviation","2"),s.setAttribute("flood-color","rgba(0,0,0,0.15)"),i.appendChild(s),n.appendChild(i),o.appendChild(n);for(let{rect:a,borderRadius:k}of e){let u=document.createElementNS(t,"path");u.setAttribute("d",Tt(a.left,a.top,a.width,a.height,k)),u.setAttribute("fill","none"),u.setAttribute("stroke","rgba(120, 125, 135, 0.6)"),u.setAttribute("stroke-width","1.5"),u.setAttribute("stroke-dasharray","8 4"),u.setAttribute("stroke-linecap","round"),u.setAttribute("filter","url(#__fork-removed-shadow)"),u.setAttribute("opacity","0"),o.appendChild(u),u.animate([{opacity:0,offset:0},{opacity:.6,offset:.08},{opacity:.05,offset:.45},{opacity:.6,offset:.85},{opacity:.05,offset:1}],{duration:5e3,easing:"ease-in-out",fill:"forwards"});}return r.appendChild(o),document.body.appendChild(r),r}var Ae=new Map,qe=new Map;function Or(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown module override error")}function Mt(e,t){let r=(t?e[t]:void 0)??e.default;if(typeof r!="function"){let o=t||"default";throw new Error(`Fork boundary module is missing a React component export: ${o}`)}return r}function Hr(e){if(!e||typeof document>"u")return Promise.resolve();let t=Ae.get(e);if(t)return t;let r=document.querySelector(`link[data-fork-override-href="${e}"]`);if(r instanceof HTMLLinkElement){let n=r.sheet?Promise.resolve():new Promise((i,s)=>{let a=()=>{r.removeEventListener("load",a),r.removeEventListener("error",k),i();},k=()=>{r.removeEventListener("load",a),r.removeEventListener("error",k),s(new Error(`Failed to load boundary stylesheet: ${e}`));};r.addEventListener("load",a,{once:true}),r.addEventListener("error",k,{once:true});});return Ae.set(e,n),n}let o=new Promise((n,i)=>{let s=document.createElement("link");s.rel="stylesheet",s.href=e,s.setAttribute("data-fork-override-href",e),s.onload=()=>n(),s.onerror=()=>{s.remove(),i(new Error(`Failed to load boundary stylesheet: ${e}`));},document.head.appendChild(s);}).catch(n=>{throw Ae.delete(e),n});return Ae.set(e,o),o}function Nr(e){let t=qe.get(e);if(t)return t;let r=import(e).catch(o=>{throw qe.delete(e),o});return qe.set(e,r),r}async function Ur(e,t,r){if(e)try{await Promise.all(e.cssUrls.map(i=>Hr(i)));let n=await Nr(e.moduleUrl);return Mt(n,r)}catch(n){console.error(`[Fork] Failed to load override for boundary "${e.boundaryId}", falling back to original module.`,n);}let o=await t();return Mt(o,r)}function Dr(e){function t(r){let{appId:o,moduleOverridesEnabled:n,moduleManifestReady:i,moduleManifestVersion:s,registerBoundary:a,getBoundaryOverride:k,consumeBoundaryAnimation:u}=z(),[m,S]=Be.useState(null),[_,v]=Be.useState(null),y=Be.useRef(null),c=Be.useRef(null),x=Be.useRef(null),A=Be.useRef(false),$=Be.useRef(null),M=Be.useRef(null),E=k(e.id),h=E?`override:${E.id}`:"original",R=e.editorMetadata?JSON.stringify(e.editorMetadata):void 0;if(Be.useEffect(()=>()=>{M.current&&(clearTimeout(M.current),M.current=null),$.current&&($.current.remove(),$.current=null);},[]),Be.useEffect(()=>{a({id:e.id,exportName:e.exportName,editorMetadata:e.editorMetadata});},[o,a,e.id,e.exportName,R]),Be.useEffect(()=>{if(n&&!i&&!m||c.current===h&&m)return;let f=false;return v(null),Ur(E,e.original,e.exportName).then(l=>{if(!f){if(E?.id&&u(e.id,E.id)&&y.current){let F=Ke(y.current);if(F){let b=Ge(F);b.length>0&&(x.current=b,A.current=true,M.current&&(clearTimeout(M.current),M.current=null),$.current&&$.current.remove(),$.current=$t(F));}}c.current=h,Be.startTransition(()=>{S(()=>l);});}}).catch(l=>{f||v(Or(l));}),()=>{f=true;}},[u,h,n,i,s,E?.id,E?.moduleUrl,E?.integrity,E?.cssUrls.join("|"),e.exportName,e.original,m]),Be.useEffect(()=>{if(!A.current||!m||!y.current)return;let f=false;return requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(f||!y.current)return;let l=x.current,F=Ke(y.current);if(x.current=null,A.current=false,!l||!F){$.current&&($.current.remove(),$.current=null);return}let b=Ge(F),d=At(l,b),g=Ct(l,b),p=$.current;if(g.length>0&&p){let L=_t(g);M.current=setTimeout(()=>{M.current=null;let I=400;p.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),L.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),setTimeout(()=>{p.remove(),L.remove(),$.current===p&&($.current=null),d.length>0&&Ve(d);},I);},3500);}else p&&(p.remove(),$.current===p&&($.current=null)),d.length>0&&Ve(d);});}),()=>{f=true;}},[m]),_)throw _;return m?Dt.jsx("div",{ref:y,style:{display:"contents"},children:Dt.jsx(m,{...r})}):Dt.jsx(Dt.Fragment,{children:e.loading??null})}return t.displayName=`ForkBoundary(${e.id})`,t}function jr({slotId:e,title:t,slotLabel:r,examplePrompts:o}){return Dt.jsx(me,{slotId:e,title:t,slotLabel:r,examplePrompts:o})}
|
|
52
|
+
exports.ForkBoundaryUI=Mr;exports.ForkButton=Ne;exports.ForkChatInterface=me;exports.ForkPanel=Ie;exports.ForkProvider=Kt;exports.ForkSlot=nr;exports.ForkUI=jr;exports.forkable=Dr;exports.registerForkShared=Me;exports.useBoundaryFork=je;exports.useFork=ze;exports.useForkChatPanel=We;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode, ReactElement, ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
interface Fork {
|
|
5
|
+
id: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
prompt: string;
|
|
8
|
+
status: "pending" | "running" | "building" | "complete" | "error";
|
|
9
|
+
slotId?: string;
|
|
10
|
+
boundaryId?: string;
|
|
11
|
+
appId?: string;
|
|
12
|
+
bundleUrl?: string;
|
|
13
|
+
moduleUrl?: string;
|
|
14
|
+
cssUrls?: string[];
|
|
15
|
+
summary?: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
completedAt?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
interface ForkEvent {
|
|
21
|
+
type: "status" | "agent_message" | "tool_use" | "build_start" | "build_complete" | "build_error" | "complete" | "error";
|
|
22
|
+
data: unknown;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
interface ForkProviderBase {
|
|
26
|
+
apiKey: string;
|
|
27
|
+
baseUrl: string;
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
appId?: string;
|
|
30
|
+
shared?: ForkSharedRegistry;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* User identity — provide EITHER userId OR authUrl:
|
|
34
|
+
*
|
|
35
|
+
* - `userId`: Client-asserted, no server verification (dev/testing only).
|
|
36
|
+
* - `authUrl`: URL on your backend that returns `{ userId, userHash }`.
|
|
37
|
+
* The SDK calls this on mount (same-origin, cookies sent automatically).
|
|
38
|
+
* Your backend computes: userHash = HMAC-SHA256(sk_fork_key, userId).
|
|
39
|
+
* This provides verified per-user fork isolation.
|
|
40
|
+
*/
|
|
41
|
+
type ForkProviderProps = ForkProviderBase & ({
|
|
42
|
+
userId: string;
|
|
43
|
+
authUrl?: never;
|
|
44
|
+
} | {
|
|
45
|
+
authUrl: string;
|
|
46
|
+
userId?: never;
|
|
47
|
+
});
|
|
48
|
+
interface ForkBoundaryRegistration {
|
|
49
|
+
id: string;
|
|
50
|
+
exportName?: string;
|
|
51
|
+
editorMetadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
interface ForkBoundaryDefinition<TProps extends object> extends ForkBoundaryRegistration {
|
|
54
|
+
original: () => Promise<Record<string, unknown>>;
|
|
55
|
+
loading?: ReactNode;
|
|
56
|
+
}
|
|
57
|
+
type ForkSharedRegistry = Record<string, unknown>;
|
|
58
|
+
type ForkChatTarget = {
|
|
59
|
+
type: "slot";
|
|
60
|
+
id: string;
|
|
61
|
+
title?: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: "boundary";
|
|
64
|
+
id: string;
|
|
65
|
+
title?: string;
|
|
66
|
+
};
|
|
67
|
+
type ForkChatTargetInput = {
|
|
68
|
+
target: ForkChatTarget;
|
|
69
|
+
slotId?: never;
|
|
70
|
+
boundaryId?: never;
|
|
71
|
+
title?: never;
|
|
72
|
+
slotLabel?: never;
|
|
73
|
+
} | {
|
|
74
|
+
target?: never;
|
|
75
|
+
slotId: string;
|
|
76
|
+
boundaryId?: never;
|
|
77
|
+
title?: string;
|
|
78
|
+
slotLabel?: string;
|
|
79
|
+
} | {
|
|
80
|
+
target?: never;
|
|
81
|
+
slotId?: never;
|
|
82
|
+
boundaryId: string;
|
|
83
|
+
title?: string;
|
|
84
|
+
slotLabel?: never;
|
|
85
|
+
};
|
|
86
|
+
type ForkChatPanelOptions = ForkChatTargetInput;
|
|
87
|
+
type ForkChatInterfaceProps = ForkChatTargetInput & {
|
|
88
|
+
examplePrompts?: string[];
|
|
89
|
+
};
|
|
90
|
+
interface ForkSlotProps {
|
|
91
|
+
slotId: string;
|
|
92
|
+
/** Props to pass to the forked component (iframe mode). In direct mode, props are forwarded from the host child element automatically. */
|
|
93
|
+
props?: Record<string, unknown>;
|
|
94
|
+
/**
|
|
95
|
+
* The slot's contents. MUST be exactly one React component element —
|
|
96
|
+
* not multiple children, not an HTML element, not a fragment, not a string.
|
|
97
|
+
*
|
|
98
|
+
* The fork pipeline points the AI agent at the source file backing this
|
|
99
|
+
* single component. Multi-child or HTML-element children have no canonical
|
|
100
|
+
* file for the agent to edit, so they're rejected at runtime by
|
|
101
|
+
* <ForkSlot>. The TypeScript type catches the same mistake at compile
|
|
102
|
+
* time wherever JSX inference is strict enough to enforce it.
|
|
103
|
+
*
|
|
104
|
+
* If you need to wrap multiple things, extract them into a single named
|
|
105
|
+
* component:
|
|
106
|
+
* <ForkSlot slotId="x"><MyShell ...props /></ForkSlot>
|
|
107
|
+
*/
|
|
108
|
+
children: ReactElement<unknown, ComponentType<any>>;
|
|
109
|
+
/** Whitelist of API paths the forked component can fetch (iframe mode only). In direct mode, the component can call fetch() natively. */
|
|
110
|
+
allowedFetches?: string[];
|
|
111
|
+
/** Optional GitHub repo in "owner/repo" format. If omitted, Fork resolves repo access from appId onboarding metadata. */
|
|
112
|
+
githubRepo?: string;
|
|
113
|
+
/** Callbacks the forked component can invoke on the parent app (bridged via postMessage) */
|
|
114
|
+
callbacks?: Record<string, (...args: any[]) => void>;
|
|
115
|
+
/** Rendering mode: "iframe" (default, sandboxed) or "direct" (same React tree, no iframe) */
|
|
116
|
+
mode?: "iframe" | "direct";
|
|
117
|
+
/** Cross-boundary state for direct mode. Parent writes, fork reads via bridge.useValue(). */
|
|
118
|
+
shared?: Record<string, unknown>;
|
|
119
|
+
/** Cross-boundary events for direct mode. Fork emits, parent handles. */
|
|
120
|
+
events?: Record<string, (...args: any[]) => void>;
|
|
121
|
+
}
|
|
122
|
+
type ForkState = "idle" | "prompting" | "running" | "complete" | "error";
|
|
123
|
+
|
|
124
|
+
declare function ForkProvider(props: ForkProviderProps): react_jsx_runtime.JSX.Element;
|
|
125
|
+
|
|
126
|
+
declare function ForkSlot({ slotId, props, children, allowedFetches, githubRepo, callbacks, mode, shared, events }: ForkSlotProps): react_jsx_runtime.JSX.Element;
|
|
127
|
+
|
|
128
|
+
declare function ForkChatInterface(props: ForkChatInterfaceProps): react_jsx_runtime.JSX.Element;
|
|
129
|
+
|
|
130
|
+
interface ForkBoundaryUIProps {
|
|
131
|
+
boundaryId: string;
|
|
132
|
+
title?: string;
|
|
133
|
+
examplePrompts?: string[];
|
|
134
|
+
}
|
|
135
|
+
declare function ForkBoundaryUI({ boundaryId, title, examplePrompts }: ForkBoundaryUIProps): react_jsx_runtime.JSX.Element;
|
|
136
|
+
|
|
137
|
+
declare function forkable<TProps extends object>(definition: ForkBoundaryDefinition<TProps>): {
|
|
138
|
+
(props: TProps): react_jsx_runtime.JSX.Element;
|
|
139
|
+
displayName: string;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
declare function registerForkShared(shared: ForkSharedRegistry): ForkSharedRegistry;
|
|
143
|
+
|
|
144
|
+
interface ForkUIProps {
|
|
145
|
+
slotId: string;
|
|
146
|
+
title?: string;
|
|
147
|
+
slotLabel?: string;
|
|
148
|
+
examplePrompts?: string[];
|
|
149
|
+
}
|
|
150
|
+
declare function ForkUI({ slotId, title, slotLabel, examplePrompts }: ForkUIProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
|
|
152
|
+
declare function ForkButton({ onClick }: {
|
|
153
|
+
onClick?: () => void;
|
|
154
|
+
}): react_jsx_runtime.JSX.Element;
|
|
155
|
+
|
|
156
|
+
interface ForkPanelProps {
|
|
157
|
+
state: ForkState;
|
|
158
|
+
fork: Fork | null;
|
|
159
|
+
events: ForkEvent[];
|
|
160
|
+
error: string | null;
|
|
161
|
+
slotId?: string;
|
|
162
|
+
targetId?: string;
|
|
163
|
+
targetLabel?: string;
|
|
164
|
+
historyMode?: "slot" | "boundary" | "none";
|
|
165
|
+
examplePrompts?: string[];
|
|
166
|
+
onSubmit: (prompt: string, targetId: string) => void;
|
|
167
|
+
onUndo?: (targetId: string) => Promise<any>;
|
|
168
|
+
onClose: () => void;
|
|
169
|
+
baseUrl?: string;
|
|
170
|
+
apiKey?: string;
|
|
171
|
+
userId?: string;
|
|
172
|
+
userHash?: string;
|
|
173
|
+
appId?: string;
|
|
174
|
+
}
|
|
175
|
+
declare function ForkPanel({ state, fork, events, error, slotId, targetId, targetLabel, historyMode, examplePrompts, onSubmit, onUndo, onClose, baseUrl, apiKey, userId, userHash, appId, }: ForkPanelProps): react_jsx_runtime.JSX.Element;
|
|
176
|
+
|
|
177
|
+
declare function useFork(): {
|
|
178
|
+
state: ForkState;
|
|
179
|
+
fork: Fork | null;
|
|
180
|
+
events: ForkEvent[];
|
|
181
|
+
error: string | null;
|
|
182
|
+
open: () => void;
|
|
183
|
+
close: () => void;
|
|
184
|
+
startFork: (prompt: string, slotId?: string) => Promise<void>;
|
|
185
|
+
undoFork: (slotId: string) => Promise<any>;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
declare function useBoundaryFork(boundaryId: string): {
|
|
189
|
+
state: ForkState;
|
|
190
|
+
fork: Fork | null;
|
|
191
|
+
events: ForkEvent[];
|
|
192
|
+
error: string | null;
|
|
193
|
+
open: () => void;
|
|
194
|
+
close: () => void;
|
|
195
|
+
startFork: (prompt: string) => Promise<void>;
|
|
196
|
+
undoFork: () => Promise<any>;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
declare function useForkChatPanel(options: ForkChatPanelOptions): {
|
|
200
|
+
target: ForkChatTarget;
|
|
201
|
+
targetId: string;
|
|
202
|
+
targetLabel: string | undefined;
|
|
203
|
+
historyMode: "slot" | "boundary";
|
|
204
|
+
submit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
205
|
+
undo: (submittedTargetId?: string) => Promise<any>;
|
|
206
|
+
buttonProps: {
|
|
207
|
+
onClick: () => void;
|
|
208
|
+
};
|
|
209
|
+
panelProps: {
|
|
210
|
+
onSubmit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
211
|
+
onUndo: (submittedTargetId?: string) => Promise<any>;
|
|
212
|
+
onClose: () => void;
|
|
213
|
+
baseUrl: string;
|
|
214
|
+
apiKey: string;
|
|
215
|
+
userId: string;
|
|
216
|
+
userHash: string | undefined;
|
|
217
|
+
appId: string | undefined;
|
|
218
|
+
slotId: string;
|
|
219
|
+
targetLabel: string | undefined;
|
|
220
|
+
historyMode: "slot" | "boundary";
|
|
221
|
+
state: ForkState;
|
|
222
|
+
fork: Fork | null;
|
|
223
|
+
events: ForkEvent[];
|
|
224
|
+
error: string | null;
|
|
225
|
+
} | {
|
|
226
|
+
onSubmit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
227
|
+
onUndo: (submittedTargetId?: string) => Promise<any>;
|
|
228
|
+
onClose: () => void;
|
|
229
|
+
baseUrl: string;
|
|
230
|
+
apiKey: string;
|
|
231
|
+
userId: string;
|
|
232
|
+
userHash: string | undefined;
|
|
233
|
+
appId: string | undefined;
|
|
234
|
+
targetId: string;
|
|
235
|
+
targetLabel: string | undefined;
|
|
236
|
+
historyMode: "slot" | "boundary";
|
|
237
|
+
state: ForkState;
|
|
238
|
+
fork: Fork | null;
|
|
239
|
+
events: ForkEvent[];
|
|
240
|
+
error: string | null;
|
|
241
|
+
};
|
|
242
|
+
state: ForkState;
|
|
243
|
+
fork: Fork | null;
|
|
244
|
+
events: ForkEvent[];
|
|
245
|
+
error: string | null;
|
|
246
|
+
isOpen: boolean;
|
|
247
|
+
open: () => void;
|
|
248
|
+
close: () => void;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export { type Fork, type ForkBoundaryDefinition, ForkBoundaryUI, ForkButton, ForkChatInterface, type ForkChatInterfaceProps, type ForkChatPanelOptions, type ForkChatTarget, type ForkEvent, ForkPanel, ForkProvider, type ForkProviderProps, type ForkSharedRegistry, ForkSlot, type ForkSlotProps, type ForkState, ForkUI, forkable, registerForkShared, useBoundaryFork, useFork, useForkChatPanel };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode, ReactElement, ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
interface Fork {
|
|
5
|
+
id: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
prompt: string;
|
|
8
|
+
status: "pending" | "running" | "building" | "complete" | "error";
|
|
9
|
+
slotId?: string;
|
|
10
|
+
boundaryId?: string;
|
|
11
|
+
appId?: string;
|
|
12
|
+
bundleUrl?: string;
|
|
13
|
+
moduleUrl?: string;
|
|
14
|
+
cssUrls?: string[];
|
|
15
|
+
summary?: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
completedAt?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
interface ForkEvent {
|
|
21
|
+
type: "status" | "agent_message" | "tool_use" | "build_start" | "build_complete" | "build_error" | "complete" | "error";
|
|
22
|
+
data: unknown;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
interface ForkProviderBase {
|
|
26
|
+
apiKey: string;
|
|
27
|
+
baseUrl: string;
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
appId?: string;
|
|
30
|
+
shared?: ForkSharedRegistry;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* User identity — provide EITHER userId OR authUrl:
|
|
34
|
+
*
|
|
35
|
+
* - `userId`: Client-asserted, no server verification (dev/testing only).
|
|
36
|
+
* - `authUrl`: URL on your backend that returns `{ userId, userHash }`.
|
|
37
|
+
* The SDK calls this on mount (same-origin, cookies sent automatically).
|
|
38
|
+
* Your backend computes: userHash = HMAC-SHA256(sk_fork_key, userId).
|
|
39
|
+
* This provides verified per-user fork isolation.
|
|
40
|
+
*/
|
|
41
|
+
type ForkProviderProps = ForkProviderBase & ({
|
|
42
|
+
userId: string;
|
|
43
|
+
authUrl?: never;
|
|
44
|
+
} | {
|
|
45
|
+
authUrl: string;
|
|
46
|
+
userId?: never;
|
|
47
|
+
});
|
|
48
|
+
interface ForkBoundaryRegistration {
|
|
49
|
+
id: string;
|
|
50
|
+
exportName?: string;
|
|
51
|
+
editorMetadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
interface ForkBoundaryDefinition<TProps extends object> extends ForkBoundaryRegistration {
|
|
54
|
+
original: () => Promise<Record<string, unknown>>;
|
|
55
|
+
loading?: ReactNode;
|
|
56
|
+
}
|
|
57
|
+
type ForkSharedRegistry = Record<string, unknown>;
|
|
58
|
+
type ForkChatTarget = {
|
|
59
|
+
type: "slot";
|
|
60
|
+
id: string;
|
|
61
|
+
title?: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: "boundary";
|
|
64
|
+
id: string;
|
|
65
|
+
title?: string;
|
|
66
|
+
};
|
|
67
|
+
type ForkChatTargetInput = {
|
|
68
|
+
target: ForkChatTarget;
|
|
69
|
+
slotId?: never;
|
|
70
|
+
boundaryId?: never;
|
|
71
|
+
title?: never;
|
|
72
|
+
slotLabel?: never;
|
|
73
|
+
} | {
|
|
74
|
+
target?: never;
|
|
75
|
+
slotId: string;
|
|
76
|
+
boundaryId?: never;
|
|
77
|
+
title?: string;
|
|
78
|
+
slotLabel?: string;
|
|
79
|
+
} | {
|
|
80
|
+
target?: never;
|
|
81
|
+
slotId?: never;
|
|
82
|
+
boundaryId: string;
|
|
83
|
+
title?: string;
|
|
84
|
+
slotLabel?: never;
|
|
85
|
+
};
|
|
86
|
+
type ForkChatPanelOptions = ForkChatTargetInput;
|
|
87
|
+
type ForkChatInterfaceProps = ForkChatTargetInput & {
|
|
88
|
+
examplePrompts?: string[];
|
|
89
|
+
};
|
|
90
|
+
interface ForkSlotProps {
|
|
91
|
+
slotId: string;
|
|
92
|
+
/** Props to pass to the forked component (iframe mode). In direct mode, props are forwarded from the host child element automatically. */
|
|
93
|
+
props?: Record<string, unknown>;
|
|
94
|
+
/**
|
|
95
|
+
* The slot's contents. MUST be exactly one React component element —
|
|
96
|
+
* not multiple children, not an HTML element, not a fragment, not a string.
|
|
97
|
+
*
|
|
98
|
+
* The fork pipeline points the AI agent at the source file backing this
|
|
99
|
+
* single component. Multi-child or HTML-element children have no canonical
|
|
100
|
+
* file for the agent to edit, so they're rejected at runtime by
|
|
101
|
+
* <ForkSlot>. The TypeScript type catches the same mistake at compile
|
|
102
|
+
* time wherever JSX inference is strict enough to enforce it.
|
|
103
|
+
*
|
|
104
|
+
* If you need to wrap multiple things, extract them into a single named
|
|
105
|
+
* component:
|
|
106
|
+
* <ForkSlot slotId="x"><MyShell ...props /></ForkSlot>
|
|
107
|
+
*/
|
|
108
|
+
children: ReactElement<unknown, ComponentType<any>>;
|
|
109
|
+
/** Whitelist of API paths the forked component can fetch (iframe mode only). In direct mode, the component can call fetch() natively. */
|
|
110
|
+
allowedFetches?: string[];
|
|
111
|
+
/** Optional GitHub repo in "owner/repo" format. If omitted, Fork resolves repo access from appId onboarding metadata. */
|
|
112
|
+
githubRepo?: string;
|
|
113
|
+
/** Callbacks the forked component can invoke on the parent app (bridged via postMessage) */
|
|
114
|
+
callbacks?: Record<string, (...args: any[]) => void>;
|
|
115
|
+
/** Rendering mode: "iframe" (default, sandboxed) or "direct" (same React tree, no iframe) */
|
|
116
|
+
mode?: "iframe" | "direct";
|
|
117
|
+
/** Cross-boundary state for direct mode. Parent writes, fork reads via bridge.useValue(). */
|
|
118
|
+
shared?: Record<string, unknown>;
|
|
119
|
+
/** Cross-boundary events for direct mode. Fork emits, parent handles. */
|
|
120
|
+
events?: Record<string, (...args: any[]) => void>;
|
|
121
|
+
}
|
|
122
|
+
type ForkState = "idle" | "prompting" | "running" | "complete" | "error";
|
|
123
|
+
|
|
124
|
+
declare function ForkProvider(props: ForkProviderProps): react_jsx_runtime.JSX.Element;
|
|
125
|
+
|
|
126
|
+
declare function ForkSlot({ slotId, props, children, allowedFetches, githubRepo, callbacks, mode, shared, events }: ForkSlotProps): react_jsx_runtime.JSX.Element;
|
|
127
|
+
|
|
128
|
+
declare function ForkChatInterface(props: ForkChatInterfaceProps): react_jsx_runtime.JSX.Element;
|
|
129
|
+
|
|
130
|
+
interface ForkBoundaryUIProps {
|
|
131
|
+
boundaryId: string;
|
|
132
|
+
title?: string;
|
|
133
|
+
examplePrompts?: string[];
|
|
134
|
+
}
|
|
135
|
+
declare function ForkBoundaryUI({ boundaryId, title, examplePrompts }: ForkBoundaryUIProps): react_jsx_runtime.JSX.Element;
|
|
136
|
+
|
|
137
|
+
declare function forkable<TProps extends object>(definition: ForkBoundaryDefinition<TProps>): {
|
|
138
|
+
(props: TProps): react_jsx_runtime.JSX.Element;
|
|
139
|
+
displayName: string;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
declare function registerForkShared(shared: ForkSharedRegistry): ForkSharedRegistry;
|
|
143
|
+
|
|
144
|
+
interface ForkUIProps {
|
|
145
|
+
slotId: string;
|
|
146
|
+
title?: string;
|
|
147
|
+
slotLabel?: string;
|
|
148
|
+
examplePrompts?: string[];
|
|
149
|
+
}
|
|
150
|
+
declare function ForkUI({ slotId, title, slotLabel, examplePrompts }: ForkUIProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
|
|
152
|
+
declare function ForkButton({ onClick }: {
|
|
153
|
+
onClick?: () => void;
|
|
154
|
+
}): react_jsx_runtime.JSX.Element;
|
|
155
|
+
|
|
156
|
+
interface ForkPanelProps {
|
|
157
|
+
state: ForkState;
|
|
158
|
+
fork: Fork | null;
|
|
159
|
+
events: ForkEvent[];
|
|
160
|
+
error: string | null;
|
|
161
|
+
slotId?: string;
|
|
162
|
+
targetId?: string;
|
|
163
|
+
targetLabel?: string;
|
|
164
|
+
historyMode?: "slot" | "boundary" | "none";
|
|
165
|
+
examplePrompts?: string[];
|
|
166
|
+
onSubmit: (prompt: string, targetId: string) => void;
|
|
167
|
+
onUndo?: (targetId: string) => Promise<any>;
|
|
168
|
+
onClose: () => void;
|
|
169
|
+
baseUrl?: string;
|
|
170
|
+
apiKey?: string;
|
|
171
|
+
userId?: string;
|
|
172
|
+
userHash?: string;
|
|
173
|
+
appId?: string;
|
|
174
|
+
}
|
|
175
|
+
declare function ForkPanel({ state, fork, events, error, slotId, targetId, targetLabel, historyMode, examplePrompts, onSubmit, onUndo, onClose, baseUrl, apiKey, userId, userHash, appId, }: ForkPanelProps): react_jsx_runtime.JSX.Element;
|
|
176
|
+
|
|
177
|
+
declare function useFork(): {
|
|
178
|
+
state: ForkState;
|
|
179
|
+
fork: Fork | null;
|
|
180
|
+
events: ForkEvent[];
|
|
181
|
+
error: string | null;
|
|
182
|
+
open: () => void;
|
|
183
|
+
close: () => void;
|
|
184
|
+
startFork: (prompt: string, slotId?: string) => Promise<void>;
|
|
185
|
+
undoFork: (slotId: string) => Promise<any>;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
declare function useBoundaryFork(boundaryId: string): {
|
|
189
|
+
state: ForkState;
|
|
190
|
+
fork: Fork | null;
|
|
191
|
+
events: ForkEvent[];
|
|
192
|
+
error: string | null;
|
|
193
|
+
open: () => void;
|
|
194
|
+
close: () => void;
|
|
195
|
+
startFork: (prompt: string) => Promise<void>;
|
|
196
|
+
undoFork: () => Promise<any>;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
declare function useForkChatPanel(options: ForkChatPanelOptions): {
|
|
200
|
+
target: ForkChatTarget;
|
|
201
|
+
targetId: string;
|
|
202
|
+
targetLabel: string | undefined;
|
|
203
|
+
historyMode: "slot" | "boundary";
|
|
204
|
+
submit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
205
|
+
undo: (submittedTargetId?: string) => Promise<any>;
|
|
206
|
+
buttonProps: {
|
|
207
|
+
onClick: () => void;
|
|
208
|
+
};
|
|
209
|
+
panelProps: {
|
|
210
|
+
onSubmit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
211
|
+
onUndo: (submittedTargetId?: string) => Promise<any>;
|
|
212
|
+
onClose: () => void;
|
|
213
|
+
baseUrl: string;
|
|
214
|
+
apiKey: string;
|
|
215
|
+
userId: string;
|
|
216
|
+
userHash: string | undefined;
|
|
217
|
+
appId: string | undefined;
|
|
218
|
+
slotId: string;
|
|
219
|
+
targetLabel: string | undefined;
|
|
220
|
+
historyMode: "slot" | "boundary";
|
|
221
|
+
state: ForkState;
|
|
222
|
+
fork: Fork | null;
|
|
223
|
+
events: ForkEvent[];
|
|
224
|
+
error: string | null;
|
|
225
|
+
} | {
|
|
226
|
+
onSubmit: (prompt: string, submittedTargetId?: string) => Promise<void>;
|
|
227
|
+
onUndo: (submittedTargetId?: string) => Promise<any>;
|
|
228
|
+
onClose: () => void;
|
|
229
|
+
baseUrl: string;
|
|
230
|
+
apiKey: string;
|
|
231
|
+
userId: string;
|
|
232
|
+
userHash: string | undefined;
|
|
233
|
+
appId: string | undefined;
|
|
234
|
+
targetId: string;
|
|
235
|
+
targetLabel: string | undefined;
|
|
236
|
+
historyMode: "slot" | "boundary";
|
|
237
|
+
state: ForkState;
|
|
238
|
+
fork: Fork | null;
|
|
239
|
+
events: ForkEvent[];
|
|
240
|
+
error: string | null;
|
|
241
|
+
};
|
|
242
|
+
state: ForkState;
|
|
243
|
+
fork: Fork | null;
|
|
244
|
+
events: ForkEvent[];
|
|
245
|
+
error: string | null;
|
|
246
|
+
isOpen: boolean;
|
|
247
|
+
open: () => void;
|
|
248
|
+
close: () => void;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export { type Fork, type ForkBoundaryDefinition, ForkBoundaryUI, ForkButton, ForkChatInterface, type ForkChatInterfaceProps, type ForkChatPanelOptions, type ForkChatTarget, type ForkEvent, ForkPanel, ForkProvider, type ForkProviderProps, type ForkSharedRegistry, ForkSlot, type ForkSlotProps, type ForkState, ForkUI, forkable, registerForkShared, useBoundaryFork, useFork, useForkChatPanel };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import*as Be from'react';import Be__default,{createContext,useState,useRef,useEffect,useCallback,startTransition,Children,useContext,isValidElement}from'react';import*as Ut from'react-dom';import*as Dt from'react/jsx-runtime';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import*as It from'react/jsx-dev-runtime';import {Minus,X,User,Check,Undo2,ChevronDown,RotateCcw,ArrowUp,Loader2,AlertCircle,Sparkles,Package,Wrench,MessageSquare,Code,Terminal,FileSearch,Pencil}from'lucide-react';var ee="__FORK_SHARED__";function Pe(){var t,r,o,n;let e=globalThis;return e[ee]||(e[ee]={}),(t=e[ee]).react||(t.react=Be),(r=e[ee])["react-dom"]||(r["react-dom"]=Ut),(o=e[ee])["react/jsx-runtime"]||(o["react/jsx-runtime"]=Dt),(n=e[ee])["react/jsx-dev-runtime"]||(n["react/jsx-dev-runtime"]=It),e[ee]}function Me(e){return Object.assign(Pe(),e)}var tt=createContext(null);function et(e,t){if(!t)return t;try{return new URL(t,`${e.replace(/\/+$/,"")}/`).toString()}catch{return t}}function Wt(e,t){let r={};for(let[o,n]of Object.entries(t.boundaries||{}))r[o]={...n,moduleUrl:et(e,n.moduleUrl),cssUrls:Array.isArray(n.cssUrls)?n.cssUrls.map(i=>et(e,i)):[]};return r}function Kt(e){let{apiKey:t,baseUrl:r,children:o,appId:n,shared:i}=e,s="userId"in e?e.userId:void 0,a="authUrl"in e?e.authUrl:void 0,[k,u]=useState({}),[m,S]=useState(s?{userId:s,userHash:void 0}:null),[_,v]=useState(!!s),[y,c]=useState({}),[x,A]=useState(!n),[$,M]=useState(0),E=useRef(new Map),h=useRef(new Map),[R,f]=useState(0),l=useRef(new Set),F=useRef(new Map),b=useRef(void 0);Pe(),i&&b.current!==i&&(Me(i),b.current=i),useEffect(()=>{a&&(v(false),fetch(a,{credentials:"include"}).then(w=>{if(!w.ok)throw new Error(`Auth endpoint returned ${w.status}`);return w.json()}).then(w=>{if(!w.userId||typeof w.userId!="string")throw new Error("authUrl response must include userId");S({userId:w.userId,userHash:w.userHash});}).catch(w=>{console.error("[ForkProvider] Failed to fetch user identity from authUrl:",w.message);}).finally(()=>{v(true);}));},[a]),useEffect(()=>{!a&&s&&(S({userId:s,userHash:void 0}),v(true));},[s,a]);let d=m?.userId??"",g=m?.userHash,p=!!n,L=useCallback(async()=>{if(!p){c({}),A(true),M(C=>C+1);return}if(!_){A(false);return}if(!d||!n){c({}),A(true),M(C=>C+1);return}let w=new URLSearchParams({appId:n,userId:d});g&&w.set("userHash",g),A(false);try{let C=await fetch(`${r}/api/v1/boundaries/manifest?${w.toString()}`,{headers:{Authorization:`Bearer ${t}`}});if(!C.ok)throw new Error(`${C.status}`);let O=await C.json();c(Wt(r,O));}catch(C){console.error("[ForkProvider] Failed to fetch module override manifest:",C.message),c({});}finally{M(C=>C+1),A(true);}},[t,n,r,_,p,g,d]);useEffect(()=>{if(!d)return;let w=new URLSearchParams({userId:d});g&&w.set("userHash",g),fetch(`${r}/api/v1/forks/active?${w.toString()}`,{headers:{Authorization:`Bearer ${t}`}}).then(C=>{if(!C.ok)throw new Error(`${C.status}`);return C.json()}).then(C=>{C&&typeof C=="object"&&u(C);}).catch(()=>{});},[t,d,g,r]),useEffect(()=>{L();},[L]);let I=useCallback((w,C)=>{u(O=>({...O,[w]:C}));},[]),W=useCallback(w=>{u(C=>{let O={...C};return delete O[w],O});},[]),X=useCallback(w=>{l.current.add(w);},[]),q=useCallback(w=>l.current.has(w)?(l.current.delete(w),true):false,[]),J=useCallback((w,C)=>{F.current.set(w,C);},[]),N=useCallback((w,C)=>F.current.get(w)!==C?false:(F.current.delete(w),true),[]),K=useCallback(w=>{if(!n)return;let C=JSON.stringify(w);E.current.get(w.id)===C||h.current.get(w.id)?.signature===C||(h.current.set(w.id,{boundary:w,signature:C}),f(j=>j+1));},[n]);useEffect(()=>{if(!n||h.current.size===0)return;let w=setTimeout(()=>{let C=Array.from(h.current.values());C.length!==0&&fetch(`${r}/api/v1/boundaries`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({appId:n,boundaries:C.map(O=>O.boundary)})}).then(O=>{if(!O.ok)throw new Error(`${O.status}`)}).then(()=>{for(let O of C)h.current.get(O.boundary.id)?.signature===O.signature&&(h.current.delete(O.boundary.id),E.current.set(O.boundary.id,O.signature));}).catch(O=>{console.error("[ForkProvider] Failed to register module boundaries:",O.message);});},50);return ()=>{clearTimeout(w);}},[t,n,r,R]);let G=useCallback(w=>y[w],[y]),V=useCallback(async()=>{if(!g)throw new Error("Reset requires verified user identity (provide authUrl / userHash).");let w=new URLSearchParams({userId:d,userHash:g}),C=await fetch(`${r}/api/v1/forks/all?${w.toString()}`,{method:"DELETE",headers:{Authorization:`Bearer ${t}`}});if(!C.ok){let j=await C.json().catch(()=>({}));throw new Error(j.error||`API error: ${C.status}`)}let O=await C.json().catch(()=>({}));u({}),c({}),A(true),M(j=>j+1),l.current.clear(),F.current.clear();try{for(let j=sessionStorage.length-1;j>=0;j-=1){let ne=sessionStorage.key(j);ne&&ne.startsWith("__fork_animated_")&&sessionStorage.removeItem(ne);}}catch{}return O},[t,r,g,d]);return jsx(tt.Provider,{value:{apiKey:t,userId:d,userHash:g,baseUrl:r,appId:n,forks:k,moduleOverridesEnabled:p,moduleManifestReady:x,moduleManifestVersion:$,setSlotFork:I,clearSlotFork:W,skipAnimationForSlot:X,shouldSkipAnimation:q,queueBoundaryAnimation:J,consumeBoundaryAnimation:N,registerBoundary:K,getBoundaryOverride:G,refreshModuleManifest:L,resetAllForks:V},children:o})}function z(){let e=useContext(tt);if(!e)throw new Error("useForkContext must be used within <ForkProvider>");return e}function be(e){return z().forks[e]}var ue=class{constructor(t){this.values=new Map;this.snapshots=new Map;this.listeners=new Map;this.eventHandlers=new Map;this.slotId=t,window.__FORK_BRIDGE__||(window.__FORK_BRIDGE__={}),window.__FORK_BRIDGE__[t]=this;}set(t,r){let o=this.values.get(t);if(Object.is(o,r))return;if(o!==void 0&&r!==null&&o!==null&&typeof o=="object"&&typeof r=="object")try{if(JSON.stringify(o)===JSON.stringify(r))return}catch{}this.values.set(t,r),this.snapshots.set(t,r);let n=this.listeners.get(t);n&&n.forEach(i=>i());}get(t){return this.values.get(t)}getSnapshot(t){return this.snapshots.get(t)}subscribe(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>{this.listeners.get(t)?.delete(r);}}useValue(t){let r=window.__FORK_REACT__;return r?.useSyncExternalStore?r.useSyncExternalStore(o=>this.subscribe(t,o),()=>this.getSnapshot(t)):(console.warn("[ForkBridge] React.useSyncExternalStore not available, returning static value"),this.values.get(t))}emit(t,...r){let o=this.eventHandlers.get(t);o&&o.forEach(n=>n(...r));}on(t,r){return this.eventHandlers.has(t)||this.eventHandlers.set(t,new Set),this.eventHandlers.get(t).add(r),()=>{this.eventHandlers.get(t)?.delete(r);}}destroy(){this.listeners.clear(),this.eventHandlers.clear(),this.values.clear(),this.snapshots.clear();let t=window.__FORK_BRIDGE__;t&&delete t[this.slotId];}};function Oe(e,t){let r;try{r=Children.only(e);}catch{let n=Children.count(e);throw new Error(`<ForkSlot slotId="${t}"> must wrap exactly one React component, got ${n} children. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`)}let o=r.type;if(typeof o=="string")throw new Error(`<ForkSlot slotId="${t}"> child must be a React component (function or class), not an HTML element <${o}>. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`);if(typeof o=="symbol")throw new Error(`<ForkSlot slotId="${t}"> child must be a single React component, not a fragment or special React element. Wrap your slot's contents in a single named component, e.g. <ForkSlot slotId="${t}"><MyShell ...props /></ForkSlot>.`);return r}var ot=new Set;function nt(e){let t=[],r=e.querySelectorAll("*");for(let o of r){if(!(o instanceof HTMLElement))continue;let n=o.getBoundingClientRect();if(n.width<10||n.height<10||["SCRIPT","STYLE","META","LINK"].includes(o.tagName))continue;let i=getComputedStyle(o),s=parseFloat(i.borderTopLeftRadius)||0;t.push({tag:o.tagName,className:o.className||"",text:(o.textContent||"").slice(0,50).trim(),rect:n,borderRadius:s});}return t}function Yt(e,t){let r=[];for(let o of t)if(!e.find(i=>i.tag===o.tag&&i.className===o.className&&Math.abs(i.rect.top-o.rect.top)<20&&Math.abs(i.rect.left-o.rect.left)<20)&&!r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom)){for(let s=r.length-1;s>=0;s--){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Xt(e,t){let r=[];for(let o of e)if(!t.find(i=>i.tag===o.tag&&i.className===o.className&&Math.abs(i.rect.top-o.rect.top)<20&&Math.abs(i.rect.left-o.rect.left)<20)&&!r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom)){for(let s=r.length-1;s>=0;s--){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function it(e,t,r,o,n){return n=Math.max(0,Math.min(n,r/2,o/2)),n===0?`M ${e} ${t} L ${e+r} ${t} L ${e+r} ${t+o} L ${e} ${t+o} Z`:[`M ${e+n} ${t}`,`L ${e+r-n} ${t}`,`A ${n} ${n} 0 0 1 ${e+r} ${t+n}`,`L ${e+r} ${t+o-n}`,`A ${n} ${n} 0 0 1 ${e+r-n} ${t+o}`,`L ${e+n} ${t+o}`,`A ${n} ${n} 0 0 1 ${e} ${t+o-n}`,`L ${e} ${t+n}`,`A ${n} ${n} 0 0 1 ${e+n} ${t}`,"Z"].join(" ")}function st(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-highlights","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs");o.appendChild(n);let i=[];for(let m=0;m<e.length;m++){let{rect:S,borderRadius:_}=e[m],v=S.left-.5,y=S.top-.5,c=S.width+1,x=S.height+1,A=Math.min(_+.5,c/2,x/2),$=it(v,y,c,x,A),M=`__fork-glow-${m}`,E=document.createElementNS(t,"filter");E.setAttribute("id",M),E.setAttribute("x","-100%"),E.setAttribute("y","-100%"),E.setAttribute("width","300%"),E.setAttribute("height","300%");let h=document.createElementNS(t,"feGaussianBlur");h.setAttribute("in","SourceGraphic"),h.setAttribute("stdDeviation","8"),E.appendChild(h),n.appendChild(E);let R=`__fork-mask-${m}`,f=document.createElementNS(t,"mask");f.setAttribute("id",R),f.setAttribute("maskUnits","userSpaceOnUse"),f.setAttribute("x",String(v-200)),f.setAttribute("y",String(y-200)),f.setAttribute("width",String(c+400)),f.setAttribute("height",String(x+400));let l=document.createElementNS(t,"rect");l.setAttribute("x",String(v-200)),l.setAttribute("y",String(y-200)),l.setAttribute("width",String(c+400)),l.setAttribute("height",String(x+400)),l.setAttribute("fill","white"),f.appendChild(l);let F=document.createElementNS(t,"path");F.setAttribute("d",$),F.setAttribute("fill","black"),f.appendChild(F),n.appendChild(f);let b=document.createElementNS(t,"g");b.setAttribute("mask",`url(#${R})`),b.setAttribute("opacity","0");let d=document.createElementNS(t,"g");d.setAttribute("filter",`url(#${M})`);let g=document.createElementNS(t,"path");g.setAttribute("d",$),g.setAttribute("fill","none"),g.setAttribute("stroke","rgba(150, 185, 220, 0.6)"),g.setAttribute("stroke-width","6"),g.setAttribute("stroke-linecap","round"),d.appendChild(g),b.appendChild(d),o.appendChild(b);let p=document.createElementNS(t,"path");p.setAttribute("d",$),p.setAttribute("fill","none"),p.setAttribute("stroke","rgba(150, 185, 220, 0.35)"),p.setAttribute("stroke-width","2"),p.setAttribute("stroke-linecap","round"),p.setAttribute("opacity","0"),o.appendChild(p),i.push(g,p),g.__group=b;}r.appendChild(o),document.body.appendChild(r);let s=[];for(let m=0;m<i.length;m+=2){let S=i[m],_=i[m+1],v=S.__group,y=_.getTotalLength(),c=S.getTotalLength();if(y<=0)continue;let x=y*.35;_.setAttribute("stroke-dasharray",`${x} ${y-x}`),_.setAttribute("stroke-dashoffset","0"),s.push(_.animate([{strokeDashoffset:0,opacity:0,offset:0},{strokeDashoffset:-0.2*y,opacity:.92,offset:.06},{strokeDashoffset:-2*y,opacity:.92,offset:.92},{strokeDashoffset:-2.25*y,opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));let A=c*.35;S.setAttribute("stroke-dasharray",`${A} ${c-A}`),S.setAttribute("stroke-dashoffset","0"),s.push(S.animate([{strokeDashoffset:0,offset:0},{strokeDashoffset:-0.2*c,offset:.06},{strokeDashoffset:-2*c,offset:.92},{strokeDashoffset:-2.25*c,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"})),s.push(v.animate([{opacity:0,offset:0},{opacity:.92,offset:.06},{opacity:.92,offset:.92},{opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));}let a=false,k=()=>{if(a)return;a=true,clearTimeout(u);for(let S of s)try{S.cancel();}catch{}let m=r.animate([{opacity:1},{opacity:0}],{duration:400,fill:"forwards"});m.onfinish=()=>r.remove(),window.removeEventListener("click",k);},u=setTimeout(k,14500);return setTimeout(()=>{a||window.addEventListener("click",k);},500),k}function Zt(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-removed","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs"),i=document.createElementNS(t,"filter");i.setAttribute("id","__fork-removed-shadow"),i.setAttribute("x","-10%"),i.setAttribute("y","-10%"),i.setAttribute("width","120%"),i.setAttribute("height","120%");let s=document.createElementNS(t,"feDropShadow");s.setAttribute("dx","0"),s.setAttribute("dy","1"),s.setAttribute("stdDeviation","2"),s.setAttribute("flood-color","rgba(0,0,0,0.15)"),i.appendChild(s),n.appendChild(i),o.appendChild(n);for(let{rect:a,borderRadius:k}of e){let u=a.left,m=a.top,S=a.width,_=a.height,v=Math.min(k,S/2,_/2),y=it(u,m,S,_,v),c=document.createElementNS(t,"path");c.setAttribute("d",y),c.setAttribute("fill","none"),c.setAttribute("stroke","rgba(120, 125, 135, 0.6)"),c.setAttribute("stroke-width","1.5"),c.setAttribute("stroke-dasharray","8 4"),c.setAttribute("stroke-linecap","round"),c.setAttribute("filter","url(#__fork-removed-shadow)"),c.setAttribute("opacity","0"),o.appendChild(c),c.animate([{opacity:0,offset:0},{opacity:.6,offset:.08},{opacity:.05,offset:.45},{opacity:.6,offset:.85},{opacity:.05,offset:1}],{duration:5e3,easing:"ease-in-out",fill:"forwards"});}return r.appendChild(o),document.body.appendChild(r),r}function Qt(e,t){if(e===t)return true;let r=Object.keys(e);if(r.length!==Object.keys(t).length)return false;for(let o of r)if(!Object.is(e[o],t[o]))return false;return true}var er=Be__default.memo(function({component:t,containerRef:r,wrapperStyle:o,hostProps:n}){return jsx("div",{ref:r,style:o,children:jsx(t,{...n})})},(e,t)=>e.component===t.component&&Qt(e.hostProps,t.hostProps)),Le=class extends Be__default.Component{constructor(t){super(t),this.state={hasError:false};}static getDerivedStateFromError(){return {hasError:true}}componentDidCatch(t){console.error(`[Fork:${this.props.slotId}] fork render failed`,t);}componentDidUpdate(t){t.resetKey!==this.props.resetKey&&this.state.hasError&&this.setState({hasError:false});}render(){return this.state.hasError?this.props.fallback:this.props.children}};function at({slotId:e,children:t,githubRepo:r,shared:o,events:n}){Oe(t,e);let i=be(e),{baseUrl:s,apiKey:a,appId:k,shouldSkipAnimation:u}=z(),[m,S]=useState(null),_=useRef(null),v=useRef(null),y=useRef(null),c=useRef(false),x=useRef(null),A=useRef(null),$=!!(o||n),M=useRef(null);$&&!M.current&&(M.current=new ue(e));let E=useRef(n);if(E.current=n,useEffect(()=>{if($)return ()=>{M.current?.destroy(),M.current=null;}},[$,e]),$&&M.current&&o)for(let[F,b]of Object.entries(o))M.current.set(F,b);useEffect(()=>{if(!$)return;M.current||(M.current=new ue(e));let F=M.current,b=Object.keys(E.current||{}).map(d=>F.on(d,(...g)=>E.current?.[d]?.(...g)));return ()=>b.forEach(d=>d())},[$,e]),useEffect(()=>{if(ot.has(e))return;ot.add(e);let F={id:e,appId:k,label:e,eventsShape:"{ navigate?: string }",currentLayout:"",githubRepo:r,mode:"direct",sharedKeys:o?Object.keys(o):[],eventNames:n?Object.keys(n):[],propsShape:"",callbackNames:[]};fetch(`${s}/api/v1/slots`,{method:"POST",headers:{Authorization:`Bearer ${a}`,"Content-Type":"application/json"},body:JSON.stringify(F)}).catch(()=>{});},[e,s,a,r,k]);let h=i?.id||null;useEffect(()=>{if(i?.bundleUrl,_.current,v.current,!i?.bundleUrl||!h){return}let F=`${s}${i.bundleUrl.replace("bundle.js","component.js")}`,b=`__fork_animated_${e}`,d=sessionStorage.getItem(b),g=u(e),p=!g&&d!==h;if(g&&h&&sessionStorage.setItem(b,h),p&&v.current){let q=nt(v.current);y.current=q,c.current=true,`${e}${q.length}`;}window.__FORK_REACT__=Be__default,window.__FORK_REACT_DOM__=Ut,window.__FORK_REACT_JSX__=Dt;let L=Date.now(),I=`${s}${i.bundleUrl.replace("bundle.js","component.css")}?t=${L}`,W=document.createElement("link");W.rel="stylesheet",W.href=I,W.dataset.forkSlot=e,document.head.appendChild(W);let X=document.createElement("script");return X.src=F+"?t="+L,X.onload=()=>{let q=window.__FORK_EXPORT__;if(q?.default){if(v.current&&y.current&&c.current){let J=v.current.getBoundingClientRect(),N=v.current.cloneNode(true);N.style.position="fixed",N.style.top=`${J.top}px`,N.style.left=`${J.left}px`,N.style.width=`${J.width}px`,N.style.height=`${J.height}px`,N.style.flex="none",N.style.minHeight="auto",N.style.zIndex="9998",N.style.pointerEvents="none",N.style.overflow="hidden";let K=getComputedStyle(v.current).backgroundColor;N.style.backgroundColor=K&&K!=="rgba(0, 0, 0, 0)"&&K!=="transparent"?K:getComputedStyle(document.body).backgroundColor||"#ffffff",document.body.appendChild(N);let G=v.current.querySelectorAll("*"),V=N.querySelectorAll("*");for(let w=0;w<G.length;w++)G[w].scrollTop!==0&&(V[w].scrollTop=G[w].scrollTop),G[w].scrollLeft!==0&&(V[w].scrollLeft=G[w].scrollLeft);x.current=N;}S(()=>q.default),_.current=h;}else console.error(`[Fork:${e}] component.js loaded but no default export found`);window.__FORK_EXPORT__=void 0;},X.onerror=()=>{console.error(`[Fork:${e}] failed to load component.js`);},document.head.appendChild(X),()=>{X.remove(),W.remove(),A.current&&(clearTimeout(A.current),A.current=null),x.current&&(x.current.remove(),x.current=null);}},[h,s,e]),useEffect(()=>{if(!c.current||!m||!v.current){`${e}${c.current}`,v.current;return}let F=y.current;if(!F){return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(!v.current)return;let b=nt(v.current),d=Yt(F,b),g=Xt(F,b),p=x.current;if(`${e}${d.length}${g.length}`,g.length>0&&p){let L=Zt(g);A.current=setTimeout(()=>{A.current=null;let I=400;p.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),L.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),setTimeout(()=>{p.remove(),L.remove(),x.current=null,d.length>0&&(st(d));},I);},3500);}else p&&(p.remove(),x.current=null),d.length>0&&(st(d));y.current=null,c.current=false,h&&(sessionStorage.setItem(`__fork_animated_${e}`,h),`${e}`);});});},[m]);let R={flex:1,minHeight:0,display:"flex",flexDirection:"column"};if(!i||i.status!=="complete"||!i.bundleUrl)return jsx("div",{ref:v,style:R,children:t});if(!m)return jsx("div",{ref:v,style:R,children:t});let l=t?.props??{};return jsx(Le,{slotId:e,resetKey:h,fallback:jsx("div",{ref:v,style:R,children:t}),children:jsx(er,{component:m,containerRef:v,wrapperStyle:R,hostProps:l})})}var ct=new Set;function or(e){return `{ ${Object.entries(e).map(([r,o])=>o==null?`${r}: unknown`:Array.isArray(o)?`${r}: ${o.length>0?typeof o[0]:"unknown"}[]`:`${r}: ${typeof o}`).join("; ")} }`}function ut(e,t=new Set){return Children.forEach(e,r=>{if(!isValidElement(r))return;let o=r.props;for(let[n,i]of Object.entries(o))typeof i=="function"&&/^on[A-Z]/.test(n)&&t.add(n);o.children&&ut(o.children,t);}),t}function nr({slotId:e,props:t,children:r,allowedFetches:o,githubRepo:n,callbacks:i,mode:s="iframe",shared:a,events:k}){if(Oe(r,e),s==="direct")return jsx(at,{slotId:e,githubRepo:n,shared:a,events:k,children:r});let u=be(e),{baseUrl:m,apiKey:S,appId:_}=z(),v=useRef(null),y=useRef(false),c=useRef(null),x=useRef(i);x.current=i;let A=useRef(t);A.current=t;let $=useRef(o);$.current=o,useEffect(()=>{if(typeof process<"u")return;let R=ut(r),f=new Set(i?Object.keys(i):[]),l=[...R].filter(F=>!f.has(F));l.length>0&&console.error(`[ForkSlot:${e}] Missing bridged callbacks! The following callback props are used by children but not passed to ForkSlot's \`callbacks\` prop:
|
|
2
|
+
`+l.map(F=>` - ${F}`).join(`
|
|
3
|
+
`)+"\n\nThe forked component will not be able to call these. Add them to the `callbacks` prop of <ForkSlot>.");},[e,r,i]),useEffect(()=>{ct.has(e)||(ct.add(e),fetch(`${m}/api/v1/slots`,{method:"POST",headers:{Authorization:`Bearer ${S}`,"Content-Type":"application/json"},body:JSON.stringify({id:e,appId:_,label:e,propsShape:t?or(t):"",eventsShape:"{ navigate?: string }",currentLayout:"",githubRepo:n,callbackNames:i?Object.keys(i):[],mode:s||"iframe"})}).catch(()=>{}));},[e,m,S,n,_]);let M=useCallback(R=>{let f=v.current;if(f?.contentWindow&&y.current){let l=x.current?Object.keys(x.current):[];f.contentWindow.postMessage({type:"slot:props",props:R,callbackNames:l},"*"),c.current=null;}else c.current=R;},[]),E=useCallback((R,f)=>{let l=$.current;return !l||l.length===0?false:l.some(F=>{let[b,d]=F.split(" "),g=f.split("?")[0];return R.toUpperCase()===b.toUpperCase()&&g.startsWith(d)})},[]);if(useEffect(()=>{if(!u?.bundleUrl)return;let R=async f=>{if(f.source===v.current?.contentWindow){if(f.data?.type==="slot:ready")y.current=true,v.current?.contentWindow?.postMessage({type:"slot:allowed-fetches",paths:$.current||[]},"*"),$.current,c.current?M(c.current):M(A.current||{});else if(f.data?.type==="slot:event"){let l=f.data.event;l?.navigate&&(window.location.hash=l.navigate);}else if(f.data?.type==="slot:clipboard-write")navigator.clipboard.writeText(f.data.text).catch(l=>{console.warn(`[ForkSlot:${e}] clipboard write failed:`,l.message);});else if(f.data?.type==="slot:callback"){let{name:l,args:F}=f.data,b=x.current?.[l];b?(b(...F||[])):console.warn(`[ForkSlot:${e}] unknown callback: ${l}`);}else if(f.data?.type==="slot:fetch"){let{id:l,method:F,url:b,body:d}=f.data,g=v.current?.contentWindow;if(!g)return;let p=F||"GET";if(!E(p,b)){console.warn(`[ForkSlot:${e}] BLOCKED fetch #${l}: ${p} ${b} \u2014 not in allowedFetches`),g.postMessage({type:"slot:fetch-response",id:l,error:`Fetch not allowed: ${p} ${b}`},"*");return}try{let L={method:p};d&&p!=="GET"&&(L.headers={"Content-Type":"application/json"},L.body=JSON.stringify(d));let I=await fetch(b,L),W=await I.json();`${e}${l}${I.status}`,g.postMessage({type:"slot:fetch-response",id:l,data:W,status:I.status},"*");}catch(L){console.error(`[ForkSlot:${e}] fetch #${l} failed:`,L.message),g.postMessage({type:"slot:fetch-response",id:l,error:L.message},"*");}}}};return window.addEventListener("message",R),()=>{window.removeEventListener("message",R),y.current=false;}},[u?.bundleUrl,e,M,E]),useEffect(()=>{u?.bundleUrl&&y.current&&M(t||{});},[t,u?.bundleUrl,M]),!u||u.status!=="complete"||!u.bundleUrl)return `${e}${u?.status||"none"}${u?.bundleUrl||"none"}`,jsx(Fragment,{children:r});`${e}${u.bundleUrl}`;let h=`${m}${u.bundleUrl.replace("/bundle.js","/host")}`;return jsx("iframe",{ref:v,src:h,sandbox:"allow-scripts allow-same-origin allow-forms allow-clipboard-write",title:`Forked ${e}`,style:{width:"100%",border:"none",flex:1,minHeight:0}})}function ve({style:e={width:20,height:20},...t}){return jsxs("svg",{viewBox:"320 95 270 345",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:e,...t,children:[jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M357.789 145.428c0-16.186 13.121-29.307 29.307-29.307 7.773 0 15.227 3.088 20.723 8.584 5.496 5.496 8.584 12.95 8.584 20.723 0 16.186-13.121 29.307-29.307 29.307s-29.307-13.121-29.307-29.307z"}),jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M387.096 174.735v188"}),jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M357.789 394.572c0-16.186 13.121-29.307 29.307-29.307 7.773 0 15.227 3.088 20.723 8.584 5.496 5.496 8.584 12.95 8.584 20.723 0 16.186-13.121 29.307-29.307 29.307s-29.307-13.121-29.307-29.307z"}),jsx("path",{stroke:"currentColor",strokeWidth:"30",strokeLinejoin:"round",strokeLinecap:"round",d:"M388.739 319c10.168-6.317 43.997-26.932 61.009-37.9 17.012-10.968 31.758-19.978 41.064-27.91 9.305-7.931 11.782-14.213 14.767-19.679 2.985-5.465 3.014-8.99 3.141-13.114.128-4.124-.999-8.178-2.377-11.632-1.378-3.454-3.563-6.55-5.889-9.094-2.326-2.543-4.98-4.679-8.066-6.167-3.085-1.488-6.624-2.601-10.448-2.76-3.823-.159-8.624.2-12.495 1.806-3.871 1.607-8.047 4.68-10.732 7.835-2.685 3.156-4.446 7.448-5.378 11.099-.932 3.651-.742 7.485-.213 10.807.528 3.322 1.864 6.46 3.386 9.123 1.523 2.663 3.543 4.843 5.75 6.854 2.207 2.011 4.38 3.914 7.491 5.214 3.111 1.3 6.57 2.808 11.178 2.584 4.607-.225 9.363-.471 16.466-3.932 7.103-3.46 16.076-5.382 26.154-16.831 10.077-11.449 28.593-43.219 34.312-51.862"}),jsx("path",{fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round",d:"M527.117 162.547L570.487 134.368Q577.196 130.009 577.624 137.997L580.39 189.69Q580.818 197.678 573.69 194.047L527.536 170.538Q520.408 166.907 527.117 162.547Z"})]})}function Ne({onClick:e}){let[t,r]=useState(false),[o,n]=useState(false),i=t?48:40;return jsx("button",{onClick:e,onMouseEnter:()=>r(true),onMouseLeave:()=>{r(false),n(false);},onMouseDown:()=>n(true),onMouseUp:()=>n(false),style:{position:"fixed",bottom:24,right:24,zIndex:40,width:i,height:i,borderRadius:"50%",backgroundColor:t?"rgba(255, 255, 255, 1)":"rgba(255, 255, 255, 0.3)",border:t?"1px solid rgba(156, 163, 175, 1)":"1px solid rgba(156, 163, 175, 0.3)",display:"flex",alignItems:"center",justifyContent:"center",color:t?"#1c4587":"rgba(28, 69, 135, 0.5)",boxShadow:t?"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)":"0 1px 2px 0 rgba(0, 0, 0, 0.05)",transform:o?"scale(0.95)":"scale(1)",transition:"all 300ms",cursor:"pointer",padding:0,margin:0,outline:"none",boxSizing:"border-box"},title:"Fork this app",children:jsx(ve,{style:{width:24,height:24}})})}var mr={status:Loader2,agent_message:MessageSquare,tool_use:Wrench,build_start:Package,build_complete:Check,build_error:AlertCircle,complete:Sparkles,error:AlertCircle},gr={status:"#60a5fa",agent_message:"#a0a0a0",tool_use:"#fbbf24",build_start:"#c084fc",build_complete:"#6b7280",build_error:"#f87171",complete:"#6b7280",error:"#f87171"},hr={read:FileSearch,write:Pencil,search:FileSearch,shell:Terminal,build:Package},yr={read:"#60a5fa",write:"#fbbf24",search:"#60a5fa",shell:"#a78bfa",build:"#c084fc"};function De(e){let t=e.data;switch(e.type){case "status":return `${t.message||t.status||"..."}`;case "agent_message":{let r=String(t.content||"");return /failed:/i.test(r)&&(r.includes("ENOENT")||r.includes("{")||r.includes("/Users/"))?"Adapting approach...":r}case "tool_use":return String(t.label||"Working on it");case "build_start":return "Bundling your component...";case "build_complete":return "Build complete!";case "build_error":return `Build failed: ${t.error}`;case "complete":return "Your fork is ready!";case "error":return `Error: ${t.error}`;default:return JSON.stringify(t)}}function bt({events:e}){let t=useRef(null);return useEffect(()=>{t.current&&(t.current.scrollTop=t.current.scrollHeight);},[e]),jsxs(Fragment,{children:[jsx("style",{children:`
|
|
4
|
+
@keyframes __fork-spin {
|
|
5
|
+
from { transform: rotate(0deg); }
|
|
6
|
+
to { transform: rotate(360deg); }
|
|
7
|
+
}
|
|
8
|
+
.__fork-stream::-webkit-scrollbar {
|
|
9
|
+
width: 4px;
|
|
10
|
+
}
|
|
11
|
+
.__fork-stream::-webkit-scrollbar-track {
|
|
12
|
+
background: transparent;
|
|
13
|
+
}
|
|
14
|
+
.__fork-stream::-webkit-scrollbar-thumb {
|
|
15
|
+
background: rgba(255, 255, 255, 0.15);
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
}
|
|
18
|
+
.__fork-stream::-webkit-scrollbar-thumb:hover {
|
|
19
|
+
background: rgba(255, 255, 255, 0.3);
|
|
20
|
+
}
|
|
21
|
+
`}),jsxs("div",{className:"__fork-stream",ref:t,style:{scrollbarWidth:"thin",scrollbarColor:"rgba(255, 255, 255, 0.15) transparent",backgroundColor:"#1a1a2e",borderRadius:"8px",padding:"12px",fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:"11px",maxHeight:"300px",overflowY:"auto",boxSizing:"border-box"},children:[e.length===0&&jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",color:"#6b7280",fontSize:"11px"},children:[jsx(Loader2,{style:{width:"12px",height:"12px",animation:"__fork-spin 1s linear infinite",flexShrink:0}}),"Connecting to agent..."]}),e.map((r,o)=>{let n=o===e.length-1,i=r.type==="complete"||r.type==="error"||r.type==="build_complete"||r.type==="build_error",s=n&&!i&&(r.type==="status"||r.type==="tool_use"||r.type==="build_start"),a=mr[r.type]||Code,k=gr[r.type]||"#9ca3af";if(r.type==="tool_use"){let u=String(r.data.category||"");a=hr[u]||Wrench,k=yr[u]||"#fbbf24";}return s?a=Loader2:!n&&r.type==="status"&&(a=Check,k="#4ade80"),jsxs("div",{style:{display:"flex",gap:"6px",marginBottom:"6px",lineHeight:1.625},children:[jsx(a,{style:{width:"12px",height:"12px",marginTop:"2px",flexShrink:0,color:k,...s?{animation:"__fork-spin 1s linear infinite"}:{}}}),jsx("span",{style:{color:n&&!i?"#d1d5db":"#6b7280",wordBreak:"break-all"},children:De(r)})]},o)})]})]})}var Er=["Dark mode redesign","New workflow for adding to this page","Data-dense analytics view"],vt=35,$r="Working on Feature",Ar="Built Custom Feature";function Cr(e){return e.length<=vt?e:e.slice(0,vt-3).trimEnd()+"..."}function Tr({events:e}){let[t,r]=useState("Setting up environment..."),[o,n]=useState(true),i=useRef(t),s=useRef(false);return useEffect(()=>{if(!s.current){for(let k of e)if(k.type==="status"&&String(k.data.message||"").includes("Agent started")){s.current=true;break}}let a="Setting up environment...";if(s.current)for(let k=e.length-1;k>=0;k--){let u=e[k];if(u.type==="tool_use"||u.type==="build_start"||u.type==="build_complete"){a=Cr(De(u));break}}if(a!==i.current){n(false);let k=setTimeout(()=>{r(a),i.current=a,n(true);},200);return ()=>clearTimeout(k)}},[e]),jsx("span",{style:{fontSize:11,color:"#d1d5db",fontWeight:500,opacity:o?1:0,transition:"opacity 0.2s ease",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",minWidth:0},children:t})}function Ie({state:e,fork:t,events:r,error:o,slotId:n,targetId:i,targetLabel:s,historyMode:a="slot",examplePrompts:k=Er,onSubmit:u,onUndo:m,onClose:S,baseUrl:_,apiKey:v,userId:y,userHash:c,appId:x}){let[A,$]=useState(""),[M,E]=useState(false),[h,R]=useState([]),[f,l]=useState(false),[F,b]=useState(false),[d,g]=useState(false),[p,L]=useState(false),[I,W]=useState(false),[X$1,q]=useState(false),[J,N]=useState(null),[K,G]=useState(false),[V,w]=useState(false),[C,O]=useState(false),[j,ne]=useState(false),[Ce,Ye]=useState(null),[Lt,Xe]=useState(false),ge=useRef(null),he=useRef(null),{resetAllForks:Bt}=z(),Z=i??n??"",Te=(s||Z).replace(/[-_]+/g," ").replace(/\b\w/g,P=>P.toUpperCase()),_e=useRef(""),Ot=r.find(P=>{let B=P.data;return P.type==="status"&&B.summary})?.data?.summary||t?.summary||$r;useEffect(()=>{if(a==="none"){l(true);return}if(!_||!v||!y||!Z||f)return;let P=new URLSearchParams({userId:y});if(c&&P.set("userHash",c),a==="slot")P.set("slotId",Z);else if(a==="boundary"){if(!x){l(true);return}P.set("boundaryId",Z),P.set("appId",x);}fetch(`${_}/api/v1/forks/history?${P.toString()}`,{headers:{Authorization:`Bearer ${v}`}}).then(B=>B.ok?B.json():[]).then(B=>{let H=[];for(let ye of B)ye.role==="user"?H.push({type:"user",text:ye.content}):H.push({type:"applied",text:ye.content});H.length>0&&R(H),l(true);}).catch(()=>l(true));},[v,x,_,f,a,Z,c,y]),useEffect(()=>{e==="complete"&&(w(false),G(false));},[e]),useEffect(()=>{let P=requestAnimationFrame(()=>b(true));return ()=>cancelAnimationFrame(P)},[]),useEffect(()=>{if(F&&!d&&(e==="prompting"||e==="complete")){let P=setTimeout(()=>ge.current?.focus(),450);return ()=>clearTimeout(P)}},[F,d,e]),useEffect(()=>{if(e==="complete"&&_e.current){let B=r.find(H=>H.type==="complete")?.data?.summary||t?.summary||Ar;R(H=>H[H.length-1]?.type==="applied"?H:[...H,{type:"applied",text:B}]),$(""),setTimeout(()=>ge.current?.focus(),200);}},[e,Te,r,t?.summary]),useEffect(()=>{he.current&&(he.current.scrollTop=he.current.scrollHeight);},[h,e]);let Ze=()=>{A.trim()&&(_e.current=A.trim(),R(P=>[...P,{type:"user",text:A.trim()}]),u(A.trim(),Z),$(""));},Ht=async()=>{if(!(!m||j||!Z)){ne(true);try{let P=await m(Z);R(B=>{let H=[...B];return H.length>=2&&H[H.length-1]?.type==="applied"?H.splice(-2,2):H.length>=1&&H[H.length-1]?.type==="applied"&&H.splice(-1,1),H}),P?.removed&&R([]);}catch{}finally{ne(false);}}},Qe=()=>{g(true),b(false),setTimeout(()=>S(),350);},se=F&&!d;return jsxs(Fragment,{children:[jsx("style",{children:`
|
|
22
|
+
@keyframes __fork-pulse {
|
|
23
|
+
0%, 100% { opacity: 1; }
|
|
24
|
+
50% { opacity: 0.5; }
|
|
25
|
+
}
|
|
26
|
+
@keyframes __fork-spin {
|
|
27
|
+
from { transform: rotate(0deg); }
|
|
28
|
+
to { transform: rotate(360deg); }
|
|
29
|
+
}
|
|
30
|
+
@keyframes __fork-fade-in {
|
|
31
|
+
from { opacity: 0; }
|
|
32
|
+
to { opacity: 1; }
|
|
33
|
+
}
|
|
34
|
+
.__fork-panel ::-webkit-scrollbar {
|
|
35
|
+
width: 2px;
|
|
36
|
+
}
|
|
37
|
+
.__fork-panel ::-webkit-scrollbar-track {
|
|
38
|
+
background: transparent;
|
|
39
|
+
}
|
|
40
|
+
.__fork-panel ::-webkit-scrollbar-thumb {
|
|
41
|
+
background: rgba(0, 0, 0, 0.12);
|
|
42
|
+
border-radius: 2px;
|
|
43
|
+
}
|
|
44
|
+
.__fork-panel ::-webkit-scrollbar-thumb:hover {
|
|
45
|
+
background: rgba(0, 0, 0, 0.22);
|
|
46
|
+
}
|
|
47
|
+
.__fork-panel {
|
|
48
|
+
scrollbar-width: thin;
|
|
49
|
+
scrollbar-color: rgba(0, 0, 0, 0.12) transparent;
|
|
50
|
+
}
|
|
51
|
+
`}),jsx("div",{className:"__fork-panel",onMouseEnter:()=>E(true),onMouseLeave:()=>E(false),style:{position:"fixed",bottom:24,right:24,zIndex:50,width:V?"auto":320,transformOrigin:"bottom right",transform:se?"scale(1)":"scale(0)",opacity:se?1:0,borderRadius:se?16:200,background:"rgba(255, 255, 255, 0.95)",backdropFilter:"blur(24px) saturate(1.6)",WebkitBackdropFilter:"blur(24px) saturate(1.6)",boxShadow:se?"0 24px 80px -12px rgba(0, 0, 0, 0.25), 0 8px 24px -8px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.06)":"0 2px 12px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.08)",border:"1px solid rgba(0, 0, 0, 0.08)",transition:"transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), border-radius 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease, opacity 0.3s ease, width 0.3s ease",overflow:"hidden",boxSizing:"border-box",fontFamily:'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'},children:jsxs("div",{style:{display:"flex",flexDirection:"column",opacity:se?1:0,transition:se?"opacity 0.25s ease 0.15s":"opacity 0.15s ease"},children:[jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 16px"},children:[jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,cursor:V?"pointer":"default",minWidth:0,flex:1},onClick:V?()=>w(false):void 0,children:[jsx(ve,{style:{width:14,height:14,color:"#1c4587",cursor:"pointer"},onDoubleClick:async P=>{if(P.stopPropagation(),!Lt&&confirm("Reset all forks? This will remove all forked components.")){Xe(true);try{let B=await Bt();`${B?.deleted??0}`,R([]),$(""),G(!1),w(!1),g(!0),b(!1),setTimeout(()=>S(),350);}catch(B){console.error("[Fork] Reset failed:",B);}finally{Xe(false);}}}}),jsx("span",{style:{fontSize:12,fontWeight:600,color:"#111827",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},children:e==="running"?Ot:`Fork ${Te}`}),e==="running"&&V&&jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"#1c4587",strokeWidth:"2.5",strokeLinecap:"round",style:{animation:"__fork-spin 2s linear infinite",flexShrink:0},children:jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),e==="complete"&&jsx("div",{style:{height:6,width:6,backgroundColor:"#1c4587",borderRadius:"50%",flexShrink:0}})]}),jsxs("div",{style:{display:"flex",alignItems:"center",gap:2},children:[e==="running"&&!V&&jsx("button",{onClick:()=>w(true),onMouseEnter:()=>O(true),onMouseLeave:()=>O(false),style:{padding:4,borderRadius:6,color:C?"#4b5563":"#9ca3af",backgroundColor:C?"#f3f4f6":"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.15s, color 0.15s"},children:jsx(Minus,{style:{width:14,height:14}})}),jsx("button",{onClick:Qe,onMouseEnter:()=>L(true),onMouseLeave:()=>L(false),style:{padding:4,borderRadius:6,color:p?"#4b5563":"#9ca3af",backgroundColor:p?"#f3f4f6":"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.15s, color 0.15s"},children:jsx(X,{style:{width:14,height:14}})})]})]}),!V&&jsxs(Fragment,{children:[jsx("div",{style:{height:1,backgroundColor:"rgba(229, 231, 235, 0.6)"}}),jsxs("div",{ref:he,style:{overflowY:"visible"},children:[e==="prompting"&&h.length===0&&jsxs("div",{style:{padding:"20px 16px",textAlign:"center"},children:[jsx("p",{style:{fontSize:12,color:"#6b7280",marginBottom:12,lineHeight:1.625,margin:"0 0 12px 0"},children:"Describe the feature you want to build."}),jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:6,justifyContent:"center"},children:k.map((P,B)=>jsx("button",{onClick:()=>{$(P),ge.current?.focus();},onMouseEnter:()=>N(B),onMouseLeave:()=>N(null),style:{fontSize:11,padding:"4px 10px",borderRadius:9999,color:J===B?"#1f2937":"#6b7280",backgroundColor:J===B?"#f9fafb":"transparent",border:J===B?"1px solid #d1d5db":"1px solid #e5e7eb",cursor:"pointer",transition:"color 0.15s, background-color 0.15s, border-color 0.15s",fontFamily:"inherit"},children:P},P))})]}),h.length>0&&jsx("div",{style:{padding:"12px 12px 0 12px"},children:h.map((P,B)=>jsx("div",{style:{marginBottom:B<h.length-1?8:0},children:P.type==="user"?jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8,flexDirection:"row-reverse"},children:[jsx("div",{style:{width:20,height:20,borderRadius:"50%",backgroundColor:"#e5e7eb",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,marginTop:2},children:jsx(User,{style:{width:12,height:12,color:"#6b7280"}})}),jsx("div",{style:{backgroundColor:"#f3f4f6",borderRadius:"12px 4px 12px 12px",padding:"6px 12px",fontSize:12,color:"#374151",lineHeight:1.5},children:P.text})]}):jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8},children:[jsx("div",{style:{width:20,height:20,borderRadius:"50%",backgroundColor:"#f0fdf4",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,marginTop:2},children:jsx(Check,{style:{width:12,height:12,color:"#9ca3af"}})}),jsxs("div",{style:{backgroundColor:"#f9fafb",borderRadius:"4px 12px 12px 12px",padding:"6px 12px",fontSize:12,color:"#6b7280",fontWeight:500,display:"flex",alignItems:"center",gap:6},children:[jsx("span",{style:{flex:1},children:P.text}),m&&B===h.length-1&&e!=="running"&&jsxs("button",{onClick:H=>{H.stopPropagation(),Ht();},onMouseEnter:()=>Ye(B),onMouseLeave:()=>Ye(null),disabled:j,style:{position:"relative",padding:2,borderRadius:4,border:"none",background:Ce===B?"rgba(0,0,0,0.06)":"transparent",color:Ce===B?"#6b7280":"#d1d5db",cursor:j?"default":"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.15s, background 0.15s",opacity:j?.4:1,flexShrink:0},children:[jsx(Undo2,{style:{width:11,height:11}}),Ce===B&&jsx("span",{style:{position:"absolute",bottom:"calc(100% + 4px)",right:0,fontSize:10,fontWeight:500,color:"#fff",background:"#374151",borderRadius:4,padding:"2px 6px",whiteSpace:"nowrap",pointerEvents:"none",lineHeight:"16px"},children:"Undo"})]})]})]})},B))}),e==="running"&&jsx("div",{style:{padding:12},children:jsxs("div",{onClick:()=>G(!K),style:{backgroundColor:"#1a1a2e",borderRadius:12,overflow:"hidden",cursor:"pointer",transition:"all 0.3s cubic-bezier(0.22, 1, 0.36, 1)"},children:[jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 14px"},children:[jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,minWidth:0},children:[jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"#6b7280",strokeWidth:"2.5",strokeLinecap:"round",style:{animation:"__fork-spin 2s linear infinite",flexShrink:0},children:jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),jsx(Tr,{events:r})]}),jsx("div",{style:{color:"#6b7280",flexShrink:0,marginLeft:8,transition:"transform 0.2s ease",transform:K?"rotate(180deg)":"rotate(0deg)"},children:jsx(ChevronDown,{style:{width:14,height:14}})})]}),jsx("div",{style:{maxHeight:K?300:0,opacity:K?1:0,transition:"max-height 0.35s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.25s ease",overflow:"hidden"},children:jsx("div",{style:{borderTop:"1px solid rgba(255,255,255,0.08)",maxHeight:300,overflowY:"auto"},children:jsx(bt,{events:r})})})]})}),e==="error"&&jsxs("div",{style:{padding:"16px",textAlign:"center"},children:[jsx("div",{style:{width:32,height:32,backgroundColor:"#fef2f2",borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 8px auto"},children:jsx(X,{style:{width:16,height:16,color:"#ef4444"}})}),jsx("p",{style:{fontSize:11,color:"#6b7280",marginBottom:8,maxWidth:260,margin:"0 auto 8px auto"},children:o}),jsxs("button",{onClick:()=>{let P=t?.prompt||_e.current;P&&u(P,Z);},onMouseEnter:()=>q(true),onMouseLeave:()=>q(false),style:{display:"inline-flex",alignItems:"center",gap:6,padding:"6px 12px",borderRadius:8,fontSize:11,fontWeight:500,color:"#4f46e5",backgroundColor:X$1?"#e0e7ff":"#eef2ff",border:"none",cursor:"pointer",transition:"background-color 0.15s",fontFamily:"inherit"},children:[jsx(RotateCcw,{style:{width:12,height:12}})," Try Again"]})]})]}),e!=="running"&&jsx("div",{style:{padding:"4px 8px 8px 8px"},children:jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,borderRadius:12,padding:"6px 8px 6px 12px",background:"rgba(0, 0, 0, 0.04)",border:"1px solid rgba(0, 0, 0, 0.06)"},children:[jsx("textarea",{ref:ge,value:A,onChange:P=>{$(P.target.value),P.target.style.height="auto",P.target.style.height=Math.min(P.target.scrollHeight,120)+"px";},onKeyDown:P=>{P.key==="Enter"&&!P.shiftKey&&(P.preventDefault(),Ze()),P.key==="Escape"&&Qe();},placeholder:h.length>0?"Ask for another change...":`Describe your ideal ${Te.toLowerCase()}...`,rows:1,style:{flex:1,backgroundColor:"transparent",fontSize:12,color:"#111827",border:"none",outline:"none",padding:"0 4px 0 0",fontFamily:"inherit",resize:"none",lineHeight:1.5,maxHeight:120,overflow:"auto"}}),jsx("button",{onClick:Ze,disabled:!A.trim(),onMouseEnter:()=>W(true),onMouseLeave:()=>W(false),style:{width:24,height:24,borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",color:"#ffffff",opacity:A.trim()?1:.25,transform:I&&A.trim()?"scale(1.1)":"scale(1)",background:A.trim()?"#1c4587":"rgba(0,0,0,0.12)",border:"none",cursor:A.trim()?"pointer":"default",flexShrink:0,alignSelf:"flex-end",transition:"transform 0.15s, opacity 0.15s",padding:0,marginBottom:2},children:jsx(ArrowUp,{style:{width:12,height:12}})})]})})]})]})})]})}function St(e){if("target"in e&&e.target)return e.target;if("boundaryId"in e&&e.boundaryId)return {type:"boundary",id:e.boundaryId,title:e.title};if("slotId"in e&&e.slotId)return {type:"slot",id:e.slotId,title:e.title??e.slotLabel};throw new Error("Fork chat target requires either target, slotId, or boundaryId.")}function je(e){let{apiKey:t,userId:r,userHash:o,baseUrl:n,appId:i,refreshModuleManifest:s,queueBoundaryAnimation:a}=z(),[k,u]=useState("idle"),[m,S]=useState(null),[_,v]=useState([]),[y,c]=useState(null),x=useRef(null),A=useCallback(()=>{u("prompting"),v([]),c(null),S(null);},[]),$=useCallback(()=>{u("idle"),x.current&&(x.current.close(),x.current=null);},[]),M=useCallback(async h=>{try{if(!i)throw new Error("ForkProvider requires appId for module boundary prompts.");u("running"),v([]),c(null);let R={userId:r,prompt:h,boundaryId:e,appId:i};o&&(R.userHash=o);let f=await fetch(`${n}/api/v1/forks`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(R)});if(!f.ok){let d=await f.json().catch(()=>({}));throw new Error(d.error||`API error: ${f.status}`)}let l=await f.json();S(l);let F=new URLSearchParams({key:t});o&&(F.set("userId",r),F.set("userHash",o));let b=new EventSource(`${n}/api/v1/forks/${l.id}/events?${F.toString()}`);x.current=b,b.onmessage=d=>{try{let g=JSON.parse(d.data);if(v(p=>[...p,g]),g.type==="complete"){let p=g.data;a(e,l.id),s().catch(()=>{}).finally(()=>{let L={...l,status:"complete",moduleUrl:p.moduleUrl,cssUrls:p.cssUrls,summary:p.summary,completedAt:new Date().toISOString()};S(L),u("complete"),b.close();});}else if(g.type==="error"){let p=g.data;c(p.error||"Unknown error"),u("error"),b.close();}}catch{}},b.onerror=()=>{fetch(`${n}/api/v1/forks/${l.id}`,{headers:{Authorization:`Bearer ${t}`}}).then(d=>d.json()).then(d=>{S(d),d.status==="complete"?(a(e,d.id),s().catch(()=>{}),u("complete")):d.status==="error"&&(c(d.error||"Fork generation failed"),u("error"));}).catch(()=>{c("Connection lost"),u("error");}),b.close();};}catch(R){c(R.message),u("error");}},[t,i,n,e,a,s,o,r]),E=useCallback(async()=>{try{if(!i)throw new Error("ForkProvider requires appId for boundary undo.");let h={userId:r,boundaryId:e,appId:i};o&&(h.userHash=o);let R=await fetch(`${n}/api/v1/forks/undo`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(h)});if(!R.ok){let l=await R.json().catch(()=>({}));throw new Error(l.error||`API error: ${R.status}`)}let f=await R.json();return await s().catch(()=>{}),f.removed?(S(null),u("prompting")):f.fork&&(S(f.fork),u("complete")),f}catch(h){throw c(h.message),h}},[t,i,n,e,s,o,r]);return {state:k,fork:m,events:_,error:y,open:A,close:$,startFork:M,undoFork:E}}function Ft(e){let{state:t,fork:r,events:o,error:n,open:i,close:s,startFork:a,undoFork:k}=je(e);return {state:t,fork:r,events:o,error:n,isOpen:t!=="idle",open:i,close:s,submit:a,undo:k}}function ze(){let{apiKey:e,userId:t,userHash:r,baseUrl:o,setSlotFork:n,clearSlotFork:i,skipAnimationForSlot:s}=z(),[a,k]=useState("idle"),[u,m]=useState(null),[S,_]=useState([]),[v,y]=useState(null),c=useRef(null),x=useCallback(()=>{k("prompting"),_([]),y(null),m(null);},[]),A=useCallback(()=>{k("idle"),c.current&&(c.current.close(),c.current=null);},[]),$=useCallback(async(E,h)=>{try{k("running"),_([]),y(null);let R={userId:t,prompt:E};h&&(R.slotId=h),r&&(R.userHash=r);let f=await fetch(`${o}/api/v1/forks`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(R)});if(!f.ok){let d=await f.json().catch(()=>({}));throw new Error(d.error||`API error: ${f.status}`)}let l=await f.json();m(l);let F=new URLSearchParams({key:e});r&&(F.set("userId",t),F.set("userHash",r));let b=new EventSource(`${o}/api/v1/forks/${l.id}/events?${F.toString()}`);c.current=b,b.onmessage=d=>{try{let g=JSON.parse(d.data);if(_(p=>[...p,g]),g.type==="complete"){let p=g.data,L={...l,status:"complete",bundleUrl:p.bundleUrl,summary:p.summary,completedAt:new Date().toISOString()};m(L),k("complete"),h&&p.bundleUrl&&n(h,L),b.close();}else if(g.type==="error"){let p=g.data;y(p.error||"Unknown error"),k("error"),b.close();}}catch{}},b.onerror=()=>{fetch(`${o}/api/v1/forks/${l.id}`,{headers:{Authorization:`Bearer ${e}`}}).then(d=>d.json()).then(d=>{m(d),d.status==="complete"?(k("complete"),h&&d.bundleUrl&&n(h,d)):d.status==="error"&&(y(d.error||"Fork generation failed"),k("error"));}).catch(()=>{y("Connection lost"),k("error");}),b.close();};}catch(R){y(R.message),k("error");}},[e,t,r,o,n]),M=useCallback(async E=>{try{let h={userId:t,slotId:E};r&&(h.userHash=r);let R=await fetch(`${o}/api/v1/forks/undo`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(h)});if(!R.ok){let l=await R.json().catch(()=>({}));throw new Error(l.error||`API error: ${R.status}`)}let f=await R.json();return s(E),f.removed?(i(E),m(null),k("prompting")):f.fork&&(n(E,f.fork),m(f.fork)),f}catch(h){throw y(h.message),h}},[e,t,r,o,i,n]);return {state:a,fork:u,events:S,error:v,open:x,close:A,startFork:$,undoFork:M}}function Rt(){let{state:e,fork:t,events:r,error:o,open:n,close:i,startFork:s,undoFork:a}=ze();return {state:e,fork:t,events:r,error:o,isOpen:e!=="idle",open:n,close:i,submit:s,undo:a}}function We(e){let t=St(e),r=Rt(),o=Ft(t.type==="boundary"?t.id:""),{baseUrl:n,apiKey:i,userId:s,userHash:a,appId:k}=z(),u=t.type==="slot"?r:o,m=t.type==="slot"?"slot":"boundary",S=t.id,_=t.title,v=useCallback((c,x)=>t.type==="slot"?r.submit(c,x??t.id):o.submit(c),[o,r,t]),y=useCallback(c=>t.type==="slot"?r.undo(c??t.id):o.undo(),[o,r,t]);return {...u,target:t,targetId:S,targetLabel:_,historyMode:m,submit:v,undo:y,buttonProps:{onClick:u.open},panelProps:{state:u.state,fork:u.fork,events:u.events,error:u.error,...t.type==="slot"?{slotId:S,targetLabel:_,historyMode:m}:{targetId:S,targetLabel:_,historyMode:m},onSubmit:v,onUndo:y,onClose:u.close,baseUrl:n,apiKey:i,userId:s,userHash:a,appId:k}}}function me(e){let{examplePrompts:t}=e,r=We(e);return r.isOpen?jsx(Ie,{...r.panelProps,examplePrompts:t}):jsx(Ne,{...r.buttonProps})}function Mr({boundaryId:e,title:t,examplePrompts:r}){return jsx(me,{boundaryId:e,title:t,examplePrompts:r})}function Ke(e){let t=Array.from(e.children).filter(o=>o instanceof HTMLElement);return t.length===1?t[0]:getComputedStyle(e).display==="contents"?null:e}function $t(e){let t=e.getBoundingClientRect(),r=e.cloneNode(true);r.style.position="fixed",r.style.top=`${t.top}px`,r.style.left=`${t.left}px`,r.style.width=`${t.width}px`,r.style.height=`${t.height}px`,r.style.flex="none",r.style.minHeight="auto",r.style.zIndex="9998",r.style.pointerEvents="none",r.style.overflow="hidden";let o=getComputedStyle(e).backgroundColor;r.style.backgroundColor=o&&o!=="rgba(0, 0, 0, 0)"&&o!=="transparent"?o:getComputedStyle(document.body).backgroundColor||"#ffffff",document.body.appendChild(r);let n=e.querySelectorAll("*"),i=r.querySelectorAll("*");for(let s=0;s<n.length;s+=1)n[s].scrollTop!==0&&(i[s].scrollTop=n[s].scrollTop),n[s].scrollLeft!==0&&(i[s].scrollLeft=n[s].scrollLeft);return r}function Ge(e){let t=[],r=e.querySelectorAll("*");for(let o of r){if(!(o instanceof HTMLElement))continue;let n=o.getBoundingClientRect();if(n.width<10||n.height<10||["SCRIPT","STYLE","META","LINK"].includes(o.tagName))continue;let i=getComputedStyle(o),s=parseFloat(i.borderTopLeftRadius)||0;t.push({tag:o.tagName,className:o.className||"",text:(o.textContent||"").slice(0,50).trim(),rect:n,borderRadius:s});}return t}function At(e,t){let r=[];for(let o of t)if(!(e.find(s=>s.tag===o.tag&&s.className===o.className&&Math.abs(s.rect.top-o.rect.top)<20&&Math.abs(s.rect.left-o.rect.left)<20)||r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom))){for(let s=r.length-1;s>=0;s-=1){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Ct(e,t){let r=[];for(let o of e)if(!(t.find(s=>s.tag===o.tag&&s.className===o.className&&Math.abs(s.rect.top-o.rect.top)<20&&Math.abs(s.rect.left-o.rect.left)<20)||r.some(s=>o.rect.top>=s.rect.top&&o.rect.left>=s.rect.left&&o.rect.right<=s.rect.right&&o.rect.bottom<=s.rect.bottom))){for(let s=r.length-1;s>=0;s-=1){let a=r[s];a.rect.top>=o.rect.top&&a.rect.left>=o.rect.left&&a.rect.right<=o.rect.right&&a.rect.bottom<=o.rect.bottom&&r.splice(s,1);}r.push({rect:o.rect,borderRadius:o.borderRadius});}return r}function Tt(e,t,r,o,n){let i=Math.max(0,Math.min(n,r/2,o/2));return i===0?`M ${e} ${t} L ${e+r} ${t} L ${e+r} ${t+o} L ${e} ${t+o} Z`:[`M ${e+i} ${t}`,`L ${e+r-i} ${t}`,`A ${i} ${i} 0 0 1 ${e+r} ${t+i}`,`L ${e+r} ${t+o-i}`,`A ${i} ${i} 0 0 1 ${e+r-i} ${t+o}`,`L ${e+i} ${t+o}`,`A ${i} ${i} 0 0 1 ${e} ${t+o-i}`,`L ${e} ${t+i}`,`A ${i} ${i} 0 0 1 ${e+i} ${t}`,"Z"].join(" ")}function Ve(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-highlights","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs");o.appendChild(n);let i=[];for(let m=0;m<e.length;m+=1){let{rect:S,borderRadius:_}=e[m],v=S.left-.5,y=S.top-.5,c=S.width+1,x=S.height+1,A=Math.min(_+.5,c/2,x/2),$=Tt(v,y,c,x,A),M=`__fork-glow-${m}`,E=document.createElementNS(t,"filter");E.setAttribute("id",M),E.setAttribute("x","-100%"),E.setAttribute("y","-100%"),E.setAttribute("width","300%"),E.setAttribute("height","300%");let h=document.createElementNS(t,"feGaussianBlur");h.setAttribute("in","SourceGraphic"),h.setAttribute("stdDeviation","8"),E.appendChild(h),n.appendChild(E);let R=`__fork-mask-${m}`,f=document.createElementNS(t,"mask");f.setAttribute("id",R),f.setAttribute("maskUnits","userSpaceOnUse"),f.setAttribute("x",String(v-200)),f.setAttribute("y",String(y-200)),f.setAttribute("width",String(c+400)),f.setAttribute("height",String(x+400));let l=document.createElementNS(t,"rect");l.setAttribute("x",String(v-200)),l.setAttribute("y",String(y-200)),l.setAttribute("width",String(c+400)),l.setAttribute("height",String(x+400)),l.setAttribute("fill","white"),f.appendChild(l);let F=document.createElementNS(t,"path");F.setAttribute("d",$),F.setAttribute("fill","black"),f.appendChild(F),n.appendChild(f);let b=document.createElementNS(t,"g");b.setAttribute("mask",`url(#${R})`),b.setAttribute("opacity","0");let d=document.createElementNS(t,"g");d.setAttribute("filter",`url(#${M})`);let g=document.createElementNS(t,"path");g.setAttribute("d",$),g.setAttribute("fill","none"),g.setAttribute("stroke","rgba(150, 185, 220, 0.6)"),g.setAttribute("stroke-width","6"),g.setAttribute("stroke-linecap","round"),d.appendChild(g),b.appendChild(d),o.appendChild(b);let p=document.createElementNS(t,"path");p.setAttribute("d",$),p.setAttribute("fill","none"),p.setAttribute("stroke","rgba(150, 185, 220, 0.35)"),p.setAttribute("stroke-width","2"),p.setAttribute("stroke-linecap","round"),p.setAttribute("opacity","0"),o.appendChild(p),i.push(g,p),g.__group=b;}r.appendChild(o),document.body.appendChild(r);let s=[];for(let m=0;m<i.length;m+=2){let S=i[m],_=i[m+1],v=S.__group;if(!v)continue;let y=_.getTotalLength(),c=S.getTotalLength();if(y<=0)continue;let x=y*.35;_.setAttribute("stroke-dasharray",`${x} ${y-x}`),_.setAttribute("stroke-dashoffset","0"),s.push(_.animate([{strokeDashoffset:0,opacity:0,offset:0},{strokeDashoffset:-0.2*y,opacity:.92,offset:.06},{strokeDashoffset:-2*y,opacity:.92,offset:.92},{strokeDashoffset:-2.25*y,opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));let A=c*.35;S.setAttribute("stroke-dasharray",`${A} ${c-A}`),S.setAttribute("stroke-dashoffset","0"),s.push(S.animate([{strokeDashoffset:0,offset:0},{strokeDashoffset:-0.2*c,offset:.06},{strokeDashoffset:-2*c,offset:.92},{strokeDashoffset:-2.25*c,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"})),s.push(v.animate([{opacity:0,offset:0},{opacity:.92,offset:.06},{opacity:.92,offset:.92},{opacity:0,offset:1}],{duration:14e3,easing:"ease-in-out",fill:"forwards"}));}let a=false,k=()=>{if(a)return;a=true,clearTimeout(u);for(let S of s)try{S.cancel();}catch{}let m=r.animate([{opacity:1},{opacity:0}],{duration:400,fill:"forwards"});m.onfinish=()=>r.remove(),window.removeEventListener("click",k);},u=setTimeout(k,14500);return setTimeout(()=>{a||window.addEventListener("click",k);},500),k}function _t(e){let t="http://www.w3.org/2000/svg",r=document.createElement("div");r.setAttribute("data-fork-removed","true"),r.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;";let o=document.createElementNS(t,"svg");o.setAttribute("width","100%"),o.setAttribute("height","100%"),o.style.cssText="position:absolute;top:0;left:0;overflow:visible;";let n=document.createElementNS(t,"defs"),i=document.createElementNS(t,"filter");i.setAttribute("id","__fork-removed-shadow"),i.setAttribute("x","-10%"),i.setAttribute("y","-10%"),i.setAttribute("width","120%"),i.setAttribute("height","120%");let s=document.createElementNS(t,"feDropShadow");s.setAttribute("dx","0"),s.setAttribute("dy","1"),s.setAttribute("stdDeviation","2"),s.setAttribute("flood-color","rgba(0,0,0,0.15)"),i.appendChild(s),n.appendChild(i),o.appendChild(n);for(let{rect:a,borderRadius:k}of e){let u=document.createElementNS(t,"path");u.setAttribute("d",Tt(a.left,a.top,a.width,a.height,k)),u.setAttribute("fill","none"),u.setAttribute("stroke","rgba(120, 125, 135, 0.6)"),u.setAttribute("stroke-width","1.5"),u.setAttribute("stroke-dasharray","8 4"),u.setAttribute("stroke-linecap","round"),u.setAttribute("filter","url(#__fork-removed-shadow)"),u.setAttribute("opacity","0"),o.appendChild(u),u.animate([{opacity:0,offset:0},{opacity:.6,offset:.08},{opacity:.05,offset:.45},{opacity:.6,offset:.85},{opacity:.05,offset:1}],{duration:5e3,easing:"ease-in-out",fill:"forwards"});}return r.appendChild(o),document.body.appendChild(r),r}var Ae=new Map,qe=new Map;function Or(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown module override error")}function Mt(e,t){let r=(t?e[t]:void 0)??e.default;if(typeof r!="function"){let o=t||"default";throw new Error(`Fork boundary module is missing a React component export: ${o}`)}return r}function Hr(e){if(!e||typeof document>"u")return Promise.resolve();let t=Ae.get(e);if(t)return t;let r=document.querySelector(`link[data-fork-override-href="${e}"]`);if(r instanceof HTMLLinkElement){let n=r.sheet?Promise.resolve():new Promise((i,s)=>{let a=()=>{r.removeEventListener("load",a),r.removeEventListener("error",k),i();},k=()=>{r.removeEventListener("load",a),r.removeEventListener("error",k),s(new Error(`Failed to load boundary stylesheet: ${e}`));};r.addEventListener("load",a,{once:true}),r.addEventListener("error",k,{once:true});});return Ae.set(e,n),n}let o=new Promise((n,i)=>{let s=document.createElement("link");s.rel="stylesheet",s.href=e,s.setAttribute("data-fork-override-href",e),s.onload=()=>n(),s.onerror=()=>{s.remove(),i(new Error(`Failed to load boundary stylesheet: ${e}`));},document.head.appendChild(s);}).catch(n=>{throw Ae.delete(e),n});return Ae.set(e,o),o}function Nr(e){let t=qe.get(e);if(t)return t;let r=import(e).catch(o=>{throw qe.delete(e),o});return qe.set(e,r),r}async function Ur(e,t,r){if(e)try{await Promise.all(e.cssUrls.map(i=>Hr(i)));let n=await Nr(e.moduleUrl);return Mt(n,r)}catch(n){console.error(`[Fork] Failed to load override for boundary "${e.boundaryId}", falling back to original module.`,n);}let o=await t();return Mt(o,r)}function Dr(e){function t(r){let{appId:o,moduleOverridesEnabled:n,moduleManifestReady:i,moduleManifestVersion:s,registerBoundary:a,getBoundaryOverride:k,consumeBoundaryAnimation:u}=z(),[m,S]=useState(null),[_,v]=useState(null),y=useRef(null),c=useRef(null),x=useRef(null),A=useRef(false),$=useRef(null),M=useRef(null),E=k(e.id),h=E?`override:${E.id}`:"original",R=e.editorMetadata?JSON.stringify(e.editorMetadata):void 0;if(useEffect(()=>()=>{M.current&&(clearTimeout(M.current),M.current=null),$.current&&($.current.remove(),$.current=null);},[]),useEffect(()=>{a({id:e.id,exportName:e.exportName,editorMetadata:e.editorMetadata});},[o,a,e.id,e.exportName,R]),useEffect(()=>{if(n&&!i&&!m||c.current===h&&m)return;let f=false;return v(null),Ur(E,e.original,e.exportName).then(l=>{if(!f){if(E?.id&&u(e.id,E.id)&&y.current){let F=Ke(y.current);if(F){let b=Ge(F);b.length>0&&(x.current=b,A.current=true,M.current&&(clearTimeout(M.current),M.current=null),$.current&&$.current.remove(),$.current=$t(F));}}c.current=h,startTransition(()=>{S(()=>l);});}}).catch(l=>{f||v(Or(l));}),()=>{f=true;}},[u,h,n,i,s,E?.id,E?.moduleUrl,E?.integrity,E?.cssUrls.join("|"),e.exportName,e.original,m]),useEffect(()=>{if(!A.current||!m||!y.current)return;let f=false;return requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(f||!y.current)return;let l=x.current,F=Ke(y.current);if(x.current=null,A.current=false,!l||!F){$.current&&($.current.remove(),$.current=null);return}let b=Ge(F),d=At(l,b),g=Ct(l,b),p=$.current;if(g.length>0&&p){let L=_t(g);M.current=setTimeout(()=>{M.current=null;let I=400;p.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),L.animate([{opacity:1},{opacity:0}],{duration:I,fill:"forwards"}),setTimeout(()=>{p.remove(),L.remove(),$.current===p&&($.current=null),d.length>0&&Ve(d);},I);},3500);}else p&&(p.remove(),$.current===p&&($.current=null)),d.length>0&&Ve(d);});}),()=>{f=true;}},[m]),_)throw _;return m?jsx("div",{ref:y,style:{display:"contents"},children:jsx(m,{...r})}):jsx(Fragment,{children:e.loading??null})}return t.displayName=`ForkBoundary(${e.id})`,t}function jr({slotId:e,title:t,slotLabel:r,examplePrompts:o}){return jsx(me,{slotId:e,title:t,slotLabel:r,examplePrompts:o})}
|
|
52
|
+
export{Mr as ForkBoundaryUI,Ne as ForkButton,me as ForkChatInterface,Ie as ForkPanel,Kt as ForkProvider,nr as ForkSlot,jr as ForkUI,Dr as forkable,Me as registerForkShared,je as useBoundaryFork,ze as useFork,We as useForkChatPanel};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fork-api/chat-sdk",
|
|
3
|
+
"version": "0.1.124",
|
|
4
|
+
"description": "React SDK for Fork — let your users customize your UI with AI.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"homepage": "https://withfork.co",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/index.js",
|
|
20
|
+
"dist/index.cjs",
|
|
21
|
+
"dist/index.d.ts",
|
|
22
|
+
"dist/index.d.cts",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"keywords": [
|
|
28
|
+
"fork",
|
|
29
|
+
"ai",
|
|
30
|
+
"react",
|
|
31
|
+
"ui-customization",
|
|
32
|
+
"llm",
|
|
33
|
+
"agent"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=18",
|
|
40
|
+
"react-dom": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"lucide-react": "^0.469.0"
|
|
44
|
+
}
|
|
45
|
+
}
|