@openparachute/agent 0.2.3-rc.3 → 0.2.3-rc.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openparachute/agent",
|
|
3
|
-
"version": "0.2.3-rc.
|
|
3
|
+
"version": "0.2.3-rc.4",
|
|
4
4
|
"description": "Vault-native agents for Claude Code — a #agent/definition note + an inbound message becomes a sandboxed claude turn; the reply is written back as a note. Messaging gateway on :1941.",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"type": "module",
|
|
@@ -57,4 +57,4 @@ Error generating stack: `+a.message+`
|
|
|
57
57
|
* @license MIT
|
|
58
58
|
*/var nr=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,Jh=/^[\\/]{2}/;function tg(i,o){return o+i.replace(/\\/g,"/")}var Oh="popstate";function Mh(i){return typeof i=="object"&&i!=null&&"pathname"in i&&"search"in i&&"hash"in i&&"state"in i&&"key"in i}function lg(i={}){function o(r,d){var m;let y=(m=d.state)==null?void 0:m.masked,{pathname:p,search:j,hash:S}=y||r.location;return Ps("",{pathname:p,search:j,hash:S},d.state&&d.state.usr||null,d.state&&d.state.key||"default",y?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function f(r,d){return typeof d=="string"?d:Xn(d)}return ng(o,f,null,i)}function Me(i,o){if(i===!1||i===null||typeof i>"u")throw new Error(o)}function Gt(i,o){if(!i){typeof console<"u"&&console.warn(o);try{throw new Error(o)}catch{}}}function ag(){return Math.random().toString(36).substring(2,10)}function Uh(i,o){return{usr:i.state,key:i.key,idx:o,masked:i.mask?{pathname:i.pathname,search:i.search,hash:i.hash}:void 0}}function Ps(i,o,f=null,r,d){return{pathname:typeof i=="string"?i:i.pathname,search:"",hash:"",...typeof o=="string"?Ga(o):o,state:f,key:o&&o.key||r||ag(),mask:d}}function Xn({pathname:i="/",search:o="",hash:f=""}){return o&&o!=="?"&&(i+=o.charAt(0)==="?"?o:"?"+o),f&&f!=="#"&&(i+=f.charAt(0)==="#"?f:"#"+f),i}function Ga(i){let o={};if(i){let f=i.indexOf("#");f>=0&&(o.hash=i.substring(f),i=i.substring(0,f));let r=i.indexOf("?");r>=0&&(o.search=i.substring(r),i=i.substring(0,r)),i&&(o.pathname=i)}return o}function ng(i,o,f,r={}){let{window:d=document.defaultView,v5Compat:y=!1}=r,p=d.history,j="POP",S=null,m=C();m==null&&(m=0,p.replaceState({...p.state,idx:m},""));function C(){return(p.state||{idx:null}).idx}function N(){j="POP";let G=C(),M=G==null?null:G-m;m=G,S&&S({action:j,location:q.location,delta:M})}function _(G,M){j="PUSH";let D=Mh(G)?G:Ps(q.location,G,M);m=C()+1;let k=Uh(D,m),Z=q.createHref(D.mask||D);try{p.pushState(k,"",Z)}catch(J){if(J instanceof DOMException&&J.name==="DataCloneError")throw J;d.location.assign(Z)}y&&S&&S({action:j,location:q.location,delta:1})}function Y(G,M){j="REPLACE";let D=Mh(G)?G:Ps(q.location,G,M);m=C();let k=Uh(D,m),Z=q.createHref(D.mask||D);p.replaceState(k,"",Z),y&&S&&S({action:j,location:q.location,delta:0})}function Q(G){return ug(d,G)}let q={get action(){return j},get location(){return i(d,p)},listen(G){if(S)throw new Error("A history only accepts one active listener");return d.addEventListener(Oh,N),S=G,()=>{d.removeEventListener(Oh,N),S=null}},createHref(G){return o(d,G)},createURL:Q,encodeLocation(G){let M=Q(G);return{pathname:M.pathname,search:M.search,hash:M.hash}},push:_,replace:Y,go(G){return p.go(G)}};return q}function ug(i,o,f=!1){let r="http://localhost";i&&(r=i.location.origin!=="null"?i.location.origin:i.location.href),Me(r,"No window.location.(origin|href) available to create URL");let d=typeof o=="string"?o:Xn(o);return d=d.replace(/ $/,"%20"),!f&&Jh.test(d)&&(d=r+d),new URL(d,r)}function $h(i,o,f="/"){return ig(i,o,f,!1)}function ig(i,o,f,r,d){let y=typeof o=="string"?Ga(o):o,p=ol(y.pathname||"/",f);if(p==null)return null;let j=cg(i),S=null,m=pg(p);for(let C=0;S==null&&C<j.length;++C)S=gg(j[C],m,r);return S}function cg(i){let o=Wh(i);return sg(o),o}function Wh(i,o=[],f=[],r="",d=!1){let y=(p,j,S=d,m)=>{let C={relativePath:m===void 0?p.path||"":m,caseSensitive:p.caseSensitive===!0,childrenIndex:j,route:p};if(C.relativePath.startsWith("/")){if(!C.relativePath.startsWith(r)&&S)return;Me(C.relativePath.startsWith(r),`Absolute route path "${C.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),C.relativePath=C.relativePath.slice(r.length)}let N=wt([r,C.relativePath]),_=f.concat(C);p.children&&p.children.length>0&&(Me(p.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${N}".`),Wh(p.children,o,_,N,S)),!(p.path==null&&!p.index)&&o.push({path:N,score:vg(N,p.index),routesMeta:_.map((Y,Q)=>{let[q,G]=Ph(Y.relativePath,Y.caseSensitive,Q===_.length-1);return{...Y,matcher:q,compiledParams:G}})})};return i.forEach((p,j)=>{var S;if(p.path===""||!((S=p.path)!=null&&S.includes("?")))y(p,j);else for(let m of Fh(p.path))y(p,j,!0,m)}),o}function Fh(i){let o=i.split("/");if(o.length===0)return[];let[f,...r]=o,d=f.endsWith("?"),y=f.replace(/\?$/,"");if(r.length===0)return d?[y,""]:[y];let p=Fh(r.join("/")),j=[];return j.push(...p.map(S=>S===""?y:[y,S].join("/"))),d&&j.push(...p),j.map(S=>i.startsWith("/")&&S===""?"/":S)}function sg(i){i.sort((o,f)=>o.score!==f.score?f.score-o.score:yg(o.routesMeta.map(r=>r.childrenIndex),f.routesMeta.map(r=>r.childrenIndex)))}var rg=/^:[\w-]+$/,og=3,fg=2,dg=1,hg=10,mg=-2,Hh=i=>i==="*";function vg(i,o){let f=i.split("/"),r=f.length;return f.some(Hh)&&(r+=mg),o&&(r+=fg),f.filter(d=>!Hh(d)).reduce((d,y)=>d+(rg.test(y)?og:y===""?dg:hg),r)}function yg(i,o){return i.length===o.length&&i.slice(0,-1).every((r,d)=>r===o[d])?i[i.length-1]-o[o.length-1]:0}function gg(i,o,f=!1){let{routesMeta:r}=i,d={},y="/",p=[];for(let j=0;j<r.length;++j){let S=r[j],m=j===r.length-1,C=y==="/"?o:o.slice(y.length)||"/",N={path:S.relativePath,caseSensitive:S.caseSensitive,end:m},_=S.matcher&&S.compiledParams?Ih(N,C,S.matcher,S.compiledParams):yi(N,C),Y=S.route;if(!_&&m&&f&&!r[r.length-1].route.index&&(_=yi({path:S.relativePath,caseSensitive:S.caseSensitive,end:!1},C)),!_)return null;Object.assign(d,_.params),p.push({params:d,pathname:wt([y,_.pathname]),pathnameBase:xg(wt([y,_.pathnameBase])),route:Y}),_.pathnameBase!=="/"&&(y=wt([y,_.pathnameBase]))}return p}function yi(i,o){typeof i=="string"&&(i={path:i,caseSensitive:!1,end:!0});let[f,r]=Ph(i.path,i.caseSensitive,i.end);return Ih(i,o,f,r)}function Ih(i,o,f,r){let d=o.match(f);if(!d)return null;let y=d[0],p=y.replace(/(.)\/+$/,"$1"),j=d.slice(1);return{params:r.reduce((m,{paramName:C,isOptional:N},_)=>{if(C==="*"){let Q=j[_]||"";p=y.slice(0,y.length-Q.length).replace(/(.)\/+$/,"$1")}const Y=j[_];return N&&!Y?m[C]=void 0:m[C]=(Y||"").replace(/%2F/g,"/"),m},{}),pathname:y,pathnameBase:p,pattern:i}}function Ph(i,o=!1,f=!0){Gt(i==="*"||!i.endsWith("*")||i.endsWith("/*"),`Route path "${i}" will be treated as if it were "${i.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${i.replace(/\*$/,"/*")}".`);let r=[],d="^"+i.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(p,j,S,m,C)=>{if(r.push({paramName:j,isOptional:S!=null}),S){let N=C.charAt(m+p.length);return N&&N!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return i.endsWith("*")?(r.push({paramName:"*"}),d+=i==="*"||i==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):f?d+="\\/*$":i!==""&&i!=="/"&&(d+="(?:(?=\\/|$))"),[new RegExp(d,o?void 0:"i"),r]}function pg(i){try{return i.split("/").map(o=>decodeURIComponent(o).replace(/\//g,"%2F")).join("/")}catch(o){return Gt(!1,`The URL path "${i}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${o}).`),i}}function ol(i,o){if(o==="/")return i;if(!i.toLowerCase().startsWith(o.toLowerCase()))return null;let f=o.endsWith("/")?o.length-1:o.length,r=i.charAt(f);return r&&r!=="/"?null:i.slice(f)||"/"}function bg(i,o="/"){let{pathname:f,search:r="",hash:d=""}=typeof i=="string"?Ga(i):i,y;return f?(f=tm(f),f.startsWith("/")?y=wh(f.substring(1),"/"):y=wh(f,o)):y=o,{pathname:y,search:Eg(r),hash:jg(d)}}function wh(i,o){let f=gi(o).split("/");return i.split("/").forEach(d=>{d===".."?f.length>1&&f.pop():d!=="."&&f.push(d)}),f.length>1?f.join("/"):"/"}function Js(i,o,f,r){return`Cannot include a '${i}' character in a manually specified \`to.${o}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${f}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function Sg(i){return i.filter((o,f)=>f===0||o.route.path&&o.route.path.length>0)}function em(i){let o=Sg(i);return o.map((f,r)=>r===o.length-1?f.pathname:f.pathnameBase)}function ur(i,o,f,r=!1){let d;typeof i=="string"?d=Ga(i):(d={...i},Me(!d.pathname||!d.pathname.includes("?"),Js("?","pathname","search",d)),Me(!d.pathname||!d.pathname.includes("#"),Js("#","pathname","hash",d)),Me(!d.search||!d.search.includes("#"),Js("#","search","hash",d)));let y=i===""||d.pathname==="",p=y?"/":d.pathname,j;if(p==null)j=f;else{let N=o.length-1;if(!r&&p.startsWith("..")){let _=p.split("/");for(;_[0]==="..";)_.shift(),N-=1;d.pathname=_.join("/")}j=N>=0?o[N]:"/"}let S=bg(d,j),m=p&&p!=="/"&&p.endsWith("/"),C=(y||p===".")&&f.endsWith("/");return!S.pathname.endsWith("/")&&(m||C)&&(S.pathname+="/"),S}var tm=i=>i.replace(/[\\/]{2,}/g,"/"),wt=i=>tm(i.join("/")),gi=i=>i.replace(/\/+$/,""),xg=i=>gi(i).replace(/^\/*/,"/"),Eg=i=>!i||i==="?"?"":i.startsWith("?")?i:"?"+i,jg=i=>!i||i==="#"?"":i.startsWith("#")?i:"#"+i,Ng=class{constructor(i,o,f,r=!1){this.status=i,this.statusText=o||"",this.internal=r,f instanceof Error?(this.data=f.toString(),this.error=f):this.data=f}};function Cg(i){return i!=null&&typeof i.status=="number"&&typeof i.statusText=="string"&&typeof i.internal=="boolean"&&"data"in i}function Tg(i){let o=i.map(f=>f.route.path).filter(Boolean);return wt(o)||"/"}var lm=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function am(i,o){let f=i;if(typeof f!="string"||!nr.test(f))return{absoluteURL:void 0,isExternal:!1,to:f};let r=f,d=!1;if(lm)try{let y=new URL(window.location.href),p=Jh.test(f)?new URL(tg(f,y.protocol)):new URL(f),j=ol(p.pathname,o);p.origin===y.origin&&j!=null?f=j+p.search+p.hash:d=!0}catch{Gt(!1,`<Link to="${f}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:d,to:f}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var nm=["POST","PUT","PATCH","DELETE"];new Set(nm);var Ag=["GET",...nm];new Set(Ag);var Rg=["about:","blob:","chrome:","chrome-untrusted:","content:","data:","devtools:","file:","filesystem:","javascript:"];function zg(i){try{return Rg.includes(new URL(i).protocol)}catch{return!1}}var Xa=g.createContext(null);Xa.displayName="DataRouter";var bi=g.createContext(null);bi.displayName="DataRouterState";var um=g.createContext(!1);function _g(){return g.useContext(um)}var im=g.createContext({isTransitioning:!1});im.displayName="ViewTransition";var Dg=g.createContext(new Map);Dg.displayName="Fetchers";var Og=g.createContext(null);Og.displayName="Await";var Ot=g.createContext(null);Ot.displayName="Navigation";var Vn=g.createContext(null);Vn.displayName="Location";var Xt=g.createContext({outlet:null,matches:[],isDataRoute:!1});Xt.displayName="Route";var ir=g.createContext(null);ir.displayName="RouteError";var cm="REACT_ROUTER_ERROR",Mg="REDIRECT",Ug="ROUTE_ERROR_RESPONSE";function Hg(i){if(i.startsWith(`${cm}:${Mg}:{`))try{let o=JSON.parse(i.slice(28));if(typeof o=="object"&&o&&typeof o.status=="number"&&typeof o.statusText=="string"&&typeof o.location=="string"&&typeof o.reloadDocument=="boolean"&&typeof o.replace=="boolean")return o}catch{}}function wg(i){if(i.startsWith(`${cm}:${Ug}:{`))try{let o=JSON.parse(i.slice(40));if(typeof o=="object"&&o&&typeof o.status=="number"&&typeof o.statusText=="string")return new Ng(o.status,o.statusText,o.data)}catch{}}function Bg(i,{relative:o}={}){Me(Zn(),"useHref() may be used only in the context of a <Router> component.");let{basename:f,navigator:r}=g.useContext(Ot),{hash:d,pathname:y,search:p}=Kn(i,{relative:o}),j=y;return f!=="/"&&(j=y==="/"?f:wt([f,y])),r.createHref({pathname:j,search:p,hash:d})}function Zn(){return g.useContext(Vn)!=null}function Bt(){return Me(Zn(),"useLocation() may be used only in the context of a <Router> component."),g.useContext(Vn).location}var sm="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function rm(i){g.useContext(Ot).static||g.useLayoutEffect(i)}function om(){let{isDataRoute:i}=g.useContext(Xt);return i?Fg():Lg()}function Lg(){Me(Zn(),"useNavigate() may be used only in the context of a <Router> component.");let i=g.useContext(Xa),{basename:o,navigator:f}=g.useContext(Ot),{matches:r}=g.useContext(Xt),{pathname:d}=Bt(),y=JSON.stringify(em(r)),p=g.useRef(!1);return rm(()=>{p.current=!0}),g.useCallback((S,m={})=>{if(Gt(p.current,sm),!p.current)return;if(typeof S=="number"){f.go(S);return}let C=ur(S,JSON.parse(y),d,m.relative==="path");i==null&&o!=="/"&&(C.pathname=C.pathname==="/"?o:wt([o,C.pathname])),(m.replace?f.replace:f.push)(C,m.state,m)},[o,f,y,d,i])}g.createContext(null);function qg(){let{matches:i}=g.useContext(Xt),o=i[i.length-1];return(o==null?void 0:o.params)??{}}function Kn(i,{relative:o}={}){let{matches:f}=g.useContext(Xt),{pathname:r}=Bt(),d=JSON.stringify(em(f));return g.useMemo(()=>ur(i,JSON.parse(d),r,o==="path"),[i,d,r,o])}function Yg(i,o){return fm(i,o)}function fm(i,o,f){var G;Me(Zn(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=g.useContext(Ot),{matches:d}=g.useContext(Xt),y=d[d.length-1],p=y?y.params:{},j=y?y.pathname:"/",S=y?y.pathnameBase:"/",m=y&&y.route;{let M=m&&m.path||"";hm(j,!m||M.endsWith("*")||M.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${j}" (under <Route path="${M}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
|
|
59
59
|
|
|
60
|
-
Please change the parent <Route path="${M}"> to <Route path="${M==="/"?"*":`${M}/*`}">.`)}let C=Bt(),N;if(o){let M=typeof o=="string"?Ga(o):o;Me(S==="/"||((G=M.pathname)==null?void 0:G.startsWith(S)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${S}" but pathname "${M.pathname}" was given in the \`location\` prop.`),N=M}else N=C;let _=N.pathname||"/",Y=_;if(S!=="/"){let M=S.replace(/^\//,"").split("/");Y="/"+_.replace(/^\//,"").split("/").slice(M.length).join("/")}let Q=f&&f.state.matches.length?f.state.matches.map(M=>Object.assign(M,{route:f.manifest[M.route.id]||M.route})):$h(i,{pathname:Y});Gt(m||Q!=null,`No routes matched location "${N.pathname}${N.search}${N.hash}" `),Gt(Q==null||Q[Q.length-1].route.element!==void 0||Q[Q.length-1].route.Component!==void 0||Q[Q.length-1].route.lazy!==void 0,`Matched leaf route at location "${N.pathname}${N.search}${N.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let q=Vg(Q&&Q.map(M=>Object.assign({},M,{params:Object.assign({},p,M.params),pathname:wt([S,r.encodeLocation?r.encodeLocation(M.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathname]),pathnameBase:M.pathnameBase==="/"?S:wt([S,r.encodeLocation?r.encodeLocation(M.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathnameBase])})),d,f);return o&&q?g.createElement(Vn.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...N},navigationType:"POP"}},q):q}function kg(){let i=Wg(),o=Cg(i)?`${i.status} ${i.statusText}`:i instanceof Error?i.message:JSON.stringify(i),f=i instanceof Error?i.stack:null,r="rgba(200,200,200, 0.5)",d={padding:"0.5rem",backgroundColor:r},y={padding:"2px 4px",backgroundColor:r},p=null;return console.error("Error handled by React Router default ErrorBoundary:",i),p=g.createElement(g.Fragment,null,g.createElement("p",null,"💿 Hey developer 👋"),g.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",g.createElement("code",{style:y},"ErrorBoundary")," or"," ",g.createElement("code",{style:y},"errorElement")," prop on your route.")),g.createElement(g.Fragment,null,g.createElement("h2",null,"Unexpected Application Error!"),g.createElement("h3",{style:{fontStyle:"italic"}},o),f?g.createElement("pre",{style:d},f):null,p)}var Gg=g.createElement(kg,null),dm=class extends g.Component{constructor(i){super(i),this.state={location:i.location,revalidation:i.revalidation,error:i.error}}static getDerivedStateFromError(i){return{error:i}}static getDerivedStateFromProps(i,o){return o.location!==i.location||o.revalidation!=="idle"&&i.revalidation==="idle"?{error:i.error,location:i.location,revalidation:i.revalidation}:{error:i.error!==void 0?i.error:o.error,location:o.location,revalidation:i.revalidation||o.revalidation}}componentDidCatch(i,o){this.props.onError?this.props.onError(i,o):console.error("React Router caught the following error during render",i)}render(){let i=this.state.error;if(this.context&&typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){const f=wg(i.digest);f&&(i=f)}let o=i!==void 0?g.createElement(Xt.Provider,{value:this.props.routeContext},g.createElement(ir.Provider,{value:i,children:this.props.component})):this.props.children;return this.context?g.createElement(Xg,{error:i},o):o}};dm.contextType=um;var $s=new WeakMap;function Xg({children:i,error:o}){let{basename:f}=g.useContext(Ot);if(typeof o=="object"&&o&&"digest"in o&&typeof o.digest=="string"){let r=Hg(o.digest);if(r){let d=$s.get(o);if(d)throw d;let y=am(r.location,f),p=y.absoluteURL||y.to;if(zg(p))throw new Error("Invalid redirect location");if(lm&&!$s.get(o))if(y.isExternal||r.reloadDocument)window.location.href=p;else{const j=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(y.to,{replace:r.replace}));throw $s.set(o,j),j}return g.createElement("meta",{httpEquiv:"refresh",content:`0;url=${p}`})}}return i}function Qg({routeContext:i,match:o,children:f}){let r=g.useContext(Xa);return r&&r.static&&r.staticContext&&(o.route.errorElement||o.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=o.route.id),g.createElement(Xt.Provider,{value:i},f)}function Vg(i,o=[],f){let r=f==null?void 0:f.state;if(i==null){if(!r)return null;if(r.errors)i=r.matches;else if(o.length===0&&!r.initialized&&r.matches.length>0)i=r.matches;else return null}let d=i,y=r==null?void 0:r.errors;if(y!=null){let C=d.findIndex(N=>N.route.id&&(y==null?void 0:y[N.route.id])!==void 0);Me(C>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(y).join(",")}`),d=d.slice(0,Math.min(d.length,C+1))}let p=!1,j=-1;if(f&&r){p=r.renderFallback;for(let C=0;C<d.length;C++){let N=d[C];if((N.route.HydrateFallback||N.route.hydrateFallbackElement)&&(j=C),N.route.id){let{loaderData:_,errors:Y}=r,Q=N.route.loader&&!_.hasOwnProperty(N.route.id)&&(!Y||Y[N.route.id]===void 0);if(N.route.lazy||Q){f.isStatic&&(p=!0),j>=0?d=d.slice(0,j+1):d=[d[0]];break}}}}let S=f==null?void 0:f.onError,m=r&&S?(C,N)=>{var _,Y;S(C,{location:r.location,params:((Y=(_=r.matches)==null?void 0:_[0])==null?void 0:Y.params)??{},pattern:Tg(r.matches),errorInfo:N})}:void 0;return d.reduceRight((C,N,_)=>{let Y,Q=!1,q=null,G=null;r&&(Y=y&&N.route.id?y[N.route.id]:void 0,q=N.route.errorElement||Gg,p&&(j<0&&_===0?(hm("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),Q=!0,G=null):j===_&&(Q=!0,G=N.route.hydrateFallbackElement||null)));let M=o.concat(d.slice(0,_+1)),D=()=>{let k;return Y?k=q:Q?k=G:N.route.Component?k=g.createElement(N.route.Component,null):N.route.element?k=N.route.element:k=C,g.createElement(Qg,{match:N,routeContext:{outlet:C,matches:M,isDataRoute:r!=null},children:k})};return r&&(N.route.ErrorBoundary||N.route.errorElement||_===0)?g.createElement(dm,{location:r.location,revalidation:r.revalidation,component:q,error:Y,children:D(),routeContext:{outlet:null,matches:M,isDataRoute:!0},onError:m}):D()},null)}function cr(i){return`${i} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Zg(i){let o=g.useContext(Xa);return Me(o,cr(i)),o}function Kg(i){let o=g.useContext(bi);return Me(o,cr(i)),o}function Jg(i){let o=g.useContext(Xt);return Me(o,cr(i)),o}function sr(i){let o=Jg(i),f=o.matches[o.matches.length-1];return Me(f.route.id,`${i} can only be used on routes that contain a unique "id"`),f.route.id}function $g(){return sr("useRouteId")}function Wg(){var r;let i=g.useContext(ir),o=Kg("useRouteError"),f=sr("useRouteError");return i!==void 0?i:(r=o.errors)==null?void 0:r[f]}function Fg(){let{router:i}=Zg("useNavigate"),o=sr("useNavigate"),f=g.useRef(!1);return rm(()=>{f.current=!0}),g.useCallback(async(d,y={})=>{Gt(f.current,sm),f.current&&(typeof d=="number"?await i.navigate(d):await i.navigate(d,{fromRouteId:o,...y}))},[i,o])}var Bh={};function hm(i,o,f){!o&&!Bh[i]&&(Bh[i]=!0,Gt(!1,f))}g.memo(Ig);function Ig({routes:i,manifest:o,future:f,state:r,isStatic:d,onError:y}){return fm(i,void 0,{manifest:o,state:r,isStatic:d,onError:y})}function aa(i){Me(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Pg({basename:i="/",children:o=null,location:f,navigationType:r="POP",navigator:d,static:y=!1,useTransitions:p}){Me(!Zn(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let j=i.replace(/^\/*/,"/"),S=g.useMemo(()=>({basename:j,navigator:d,static:y,useTransitions:p,future:{}}),[j,d,y,p]);typeof f=="string"&&(f=Ga(f));let{pathname:m="/",search:C="",hash:N="",state:_=null,key:Y="default",mask:Q}=f,q=g.useMemo(()=>{let G=ol(m,j);return G==null?null:{location:{pathname:G,search:C,hash:N,state:_,key:Y,mask:Q},navigationType:r}},[j,m,C,N,_,Y,r,Q]);return Gt(q!=null,`<Router basename="${j}"> is not able to match the URL "${m}${C}${N}" because it does not start with the basename, so the <Router> won't render anything.`),q==null?null:g.createElement(Ot.Provider,{value:S},g.createElement(Vn.Provider,{children:o,value:q}))}function ep({children:i,location:o}){return Yg(er(i),o)}function er(i,o=[]){let f=[];return g.Children.forEach(i,(r,d)=>{if(!g.isValidElement(r))return;let y=[...o,d];if(r.type===g.Fragment){f.push.apply(f,er(r.props.children,y));return}Me(r.type===aa,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),Me(!r.props.index||!r.props.children,"An index route cannot have child routes.");let p={id:r.props.id||y.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(p.children=er(r.props.children,y)),f.push(p)}),f}var mi="get",vi="application/x-www-form-urlencoded";function Si(i){return typeof HTMLElement<"u"&&i instanceof HTMLElement}function tp(i){return Si(i)&&i.tagName.toLowerCase()==="button"}function lp(i){return Si(i)&&i.tagName.toLowerCase()==="form"}function ap(i){return Si(i)&&i.tagName.toLowerCase()==="input"}function np(i){return!!(i.metaKey||i.altKey||i.ctrlKey||i.shiftKey)}function up(i,o){return i.button===0&&(!o||o==="_self")&&!np(i)}var di=null;function ip(){if(di===null)try{new FormData(document.createElement("form"),0),di=!1}catch{di=!0}return di}var cp=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Ws(i){return i!=null&&!cp.has(i)?(Gt(!1,`"${i}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${vi}"`),null):i}function sp(i,o){let f,r,d,y,p;if(lp(i)){let j=i.getAttribute("action");r=j?ol(j,o):null,f=i.getAttribute("method")||mi,d=Ws(i.getAttribute("enctype"))||vi,y=new FormData(i)}else if(tp(i)||ap(i)&&(i.type==="submit"||i.type==="image")){let j=i.form;if(j==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let S=i.getAttribute("formaction")||j.getAttribute("action");if(r=S?ol(S,o):null,f=i.getAttribute("formmethod")||j.getAttribute("method")||mi,d=Ws(i.getAttribute("formenctype"))||Ws(j.getAttribute("enctype"))||vi,y=new FormData(j,i),!ip()){let{name:m,type:C,value:N}=i;if(C==="image"){let _=m?`${m}.`:"";y.append(`${_}x`,"0"),y.append(`${_}y`,"0")}else m&&y.append(m,N)}}else{if(Si(i))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');f=mi,r=null,d=vi,p=i}return y&&d==="text/plain"&&(p=y,y=void 0),{action:r,method:f.toLowerCase(),encType:d,formData:y,body:p}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function rr(i,o){if(i===!1||i===null||typeof i>"u")throw new Error(o)}function mm(i,o,f,r){let d=typeof i=="string"?new URL(i,typeof window>"u"?"server://singlefetch/":window.location.origin):i;return f?d.pathname.endsWith("/")?d.pathname=`${d.pathname}_.${r}`:d.pathname=`${d.pathname}.${r}`:d.pathname==="/"?d.pathname=`_root.${r}`:o&&ol(d.pathname,o)==="/"?d.pathname=`${gi(o)}/_root.${r}`:d.pathname=`${gi(d.pathname)}.${r}`,d}async function rp(i,o){if(i.id in o)return o[i.id];try{let f=await import(i.module);return o[i.id]=f,f}catch(f){return console.error(`Error loading route module \`${i.module}\`, reloading page...`),console.error(f),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function op(i){return i==null?!1:i.href==null?i.rel==="preload"&&typeof i.imageSrcSet=="string"&&typeof i.imageSizes=="string":typeof i.rel=="string"&&typeof i.href=="string"}async function fp(i,o,f){let r=await Promise.all(i.map(async d=>{let y=o.routes[d.route.id];if(y){let p=await rp(y,f);return p.links?p.links():[]}return[]}));return vp(r.flat(1).filter(op).filter(d=>d.rel==="stylesheet"||d.rel==="preload").map(d=>d.rel==="stylesheet"?{...d,rel:"prefetch",as:"style"}:{...d,rel:"prefetch"}))}function Lh(i,o,f,r,d,y){let p=(S,m)=>f[m]?S.route.id!==f[m].route.id:!0,j=(S,m)=>{var C;return f[m].pathname!==S.pathname||((C=f[m].route.path)==null?void 0:C.endsWith("*"))&&f[m].params["*"]!==S.params["*"]};return y==="assets"?o.filter((S,m)=>p(S,m)||j(S,m)):y==="data"?o.filter((S,m)=>{var N;let C=r.routes[S.route.id];if(!C||!C.hasLoader)return!1;if(p(S,m)||j(S,m))return!0;if(S.route.shouldRevalidate){let _=S.route.shouldRevalidate({currentUrl:new URL(d.pathname+d.search+d.hash,window.origin),currentParams:((N=f[0])==null?void 0:N.params)||{},nextUrl:new URL(i,window.origin),nextParams:S.params,defaultShouldRevalidate:!0});if(typeof _=="boolean")return _}return!0}):[]}function dp(i,o,{includeHydrateFallback:f}={}){return hp(i.map(r=>{let d=o.routes[r.route.id];if(!d)return[];let y=[d.module];return d.clientActionModule&&(y=y.concat(d.clientActionModule)),d.clientLoaderModule&&(y=y.concat(d.clientLoaderModule)),f&&d.hydrateFallbackModule&&(y=y.concat(d.hydrateFallbackModule)),d.imports&&(y=y.concat(d.imports)),y}).flat(1))}function hp(i){return[...new Set(i)]}function mp(i){let o={},f=Object.keys(i).sort();for(let r of f)o[r]=i[r];return o}function vp(i,o){let f=new Set;return new Set(o),i.reduce((r,d)=>{let y=JSON.stringify(mp(d));return f.has(y)||(f.add(y),r.push({key:y,link:d})),r},[])}function or(){let i=g.useContext(Xa);return rr(i,"You must render this element inside a <DataRouterContext.Provider> element"),i}function yp(){let i=g.useContext(bi);return rr(i,"You must render this element inside a <DataRouterStateContext.Provider> element"),i}var fr=g.createContext(void 0);fr.displayName="FrameworkContext";function xi(){let i=g.useContext(fr);return rr(i,"You must render this element inside a <HydratedRouter> element"),i}function gp(i,o){let f=g.useContext(fr),[r,d]=g.useState(!1),[y,p]=g.useState(!1),{onFocus:j,onBlur:S,onMouseEnter:m,onMouseLeave:C,onTouchStart:N}=o,_=g.useRef(null);g.useEffect(()=>{if(i==="render"&&p(!0),i==="viewport"){let q=M=>{M.forEach(D=>{p(D.isIntersecting)})},G=new IntersectionObserver(q,{threshold:.5});return _.current&&G.observe(_.current),()=>{G.disconnect()}}},[i]),g.useEffect(()=>{if(r){let q=setTimeout(()=>{p(!0)},100);return()=>{clearTimeout(q)}}},[r]);let Y=()=>{d(!0)},Q=()=>{d(!1),p(!1)};return f?i!=="intent"?[y,_,{}]:[y,_,{onFocus:kn(j,Y),onBlur:kn(S,Q),onMouseEnter:kn(m,Y),onMouseLeave:kn(C,Q),onTouchStart:kn(N,Y)}]:[!1,_,{}]}function kn(i,o){return f=>{i&&i(f),f.defaultPrevented||o(f)}}function pp({page:i,...o}){let f=_g(),{nonce:r}=xi(),{router:d}=or(),y=g.useMemo(()=>$h(d.routes,i,d.basename),[d.routes,i,d.basename]);return y?(o.nonce==null&&r&&(o={...o,nonce:r}),f?g.createElement(Sp,{page:i,matches:y,...o}):g.createElement(xp,{page:i,matches:y,...o})):null}function bp(i){let{manifest:o,routeModules:f}=xi(),[r,d]=g.useState([]);return g.useEffect(()=>{let y=!1;return fp(i,o,f).then(p=>{y||d(p)}),()=>{y=!0}},[i,o,f]),r}function Sp({page:i,matches:o,...f}){let r=Bt(),{future:d}=xi(),{basename:y}=or(),p=g.useMemo(()=>{if(i===r.pathname+r.search+r.hash)return[];let j=mm(i,y,d.v8_trailingSlashAwareDataRequests,"rsc"),S=!1,m=[];for(let C of o)typeof C.route.shouldRevalidate=="function"?S=!0:m.push(C.route.id);return S&&m.length>0&&j.searchParams.set("_routes",m.join(",")),[j.pathname+j.search]},[y,d.v8_trailingSlashAwareDataRequests,i,r,o]);return g.createElement(g.Fragment,null,p.map(j=>g.createElement("link",{key:j,rel:"prefetch",as:"fetch",href:j,...f})))}function xp({page:i,matches:o,...f}){let r=Bt(),{future:d,manifest:y,routeModules:p}=xi(),{basename:j}=or(),{loaderData:S,matches:m}=yp(),C=g.useMemo(()=>Lh(i,o,m,y,r,"data"),[i,o,m,y,r]),N=g.useMemo(()=>Lh(i,o,m,y,r,"assets"),[i,o,m,y,r]),_=g.useMemo(()=>{if(i===r.pathname+r.search+r.hash)return[];let q=new Set,G=!1;if(o.forEach(D=>{var Z;let k=y.routes[D.route.id];!k||!k.hasLoader||(!C.some(J=>J.route.id===D.route.id)&&D.route.id in S&&((Z=p[D.route.id])!=null&&Z.shouldRevalidate)||k.hasClientLoader?G=!0:q.add(D.route.id))}),q.size===0)return[];let M=mm(i,j,d.v8_trailingSlashAwareDataRequests,"data");return G&&q.size>0&&M.searchParams.set("_routes",o.filter(D=>q.has(D.route.id)).map(D=>D.route.id).join(",")),[M.pathname+M.search]},[j,d.v8_trailingSlashAwareDataRequests,S,r,y,C,o,i,p]),Y=g.useMemo(()=>dp(N,y),[N,y]),Q=bp(N);return g.createElement(g.Fragment,null,_.map(q=>g.createElement("link",{key:q,rel:"prefetch",as:"fetch",href:q,...f})),Y.map(q=>g.createElement("link",{key:q,rel:"modulepreload",href:q,...f})),Q.map(({key:q,link:G})=>g.createElement("link",{key:q,nonce:f.nonce,...G,crossOrigin:G.crossOrigin??f.crossOrigin})))}function Ep(...i){return o=>{i.forEach(f=>{typeof f=="function"?f(o):f!=null&&(f.current=o)})}}var jp=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{jp&&(window.__reactRouterVersion="7.18.0")}catch{}function Np({basename:i,children:o,useTransitions:f,window:r}){let d=g.useRef();d.current==null&&(d.current=lg({window:r,v5Compat:!0}));let y=d.current,[p,j]=g.useState({action:y.action,location:y.location}),S=g.useCallback(m=>{f===!1?j(m):g.startTransition(()=>j(m))},[f]);return g.useLayoutEffect(()=>y.listen(S),[y,S]),g.createElement(Pg,{basename:i,children:o,location:p.location,navigationType:p.action,navigator:y,useTransitions:f})}var fl=g.forwardRef(function({onClick:o,discover:f="render",prefetch:r="none",relative:d,reloadDocument:y,replace:p,mask:j,state:S,target:m,to:C,preventScrollReset:N,viewTransition:_,defaultShouldRevalidate:Y,...Q},q){let{basename:G,navigator:M,useTransitions:D}=g.useContext(Ot),k=typeof C=="string"&&nr.test(C),Z=am(C,G);C=Z.to;let J=Bg(C,{relative:d}),ie=Bt(),F=null;if(j){let De=ur(j,[],ie.mask?ie.mask.pathname:"/",!0);G!=="/"&&(De.pathname=De.pathname==="/"?G:wt([G,De.pathname])),F=M.createHref(De)}let[P,I,Re]=gp(r,Q),le=Rp(C,{replace:p,mask:j,state:S,target:m,preventScrollReset:N,relative:d,viewTransition:_,defaultShouldRevalidate:Y,useTransitions:D});function xe(De){o&&o(De),De.defaultPrevented||le(De)}let Ie=!(Z.isExternal||y),Ze=g.createElement("a",{...Q,...Re,href:(Ie?F:void 0)||Z.absoluteURL||J,onClick:Ie?xe:o,ref:Ep(q,I),target:m,"data-discover":!k&&f==="render"?"true":void 0});return P&&!k?g.createElement(g.Fragment,null,Ze,g.createElement(pp,{page:J})):Ze});fl.displayName="Link";var Cp=g.forwardRef(function({"aria-current":o="page",caseSensitive:f=!1,className:r="",end:d=!1,style:y,to:p,viewTransition:j,children:S,...m},C){let N=Kn(p,{relative:m.relative}),_=Bt(),Y=g.useContext(bi),{navigator:Q,basename:q}=g.useContext(Ot),G=Y!=null&&Mp(N)&&j===!0,M=Q.encodeLocation?Q.encodeLocation(N).pathname:N.pathname,D=_.pathname,k=Y&&Y.navigation&&Y.navigation.location?Y.navigation.location.pathname:null;f||(D=D.toLowerCase(),k=k?k.toLowerCase():null,M=M.toLowerCase()),k&&q&&(k=ol(k,q)||k);const Z=M!=="/"&&M.endsWith("/")?M.length-1:M.length;let J=D===M||!d&&D.startsWith(M)&&D.charAt(Z)==="/",ie=k!=null&&(k===M||!d&&k.startsWith(M)&&k.charAt(M.length)==="/"),F={isActive:J,isPending:ie,isTransitioning:G},P=J?o:void 0,I;typeof r=="function"?I=r(F):I=[r,J?"active":null,ie?"pending":null,G?"transitioning":null].filter(Boolean).join(" ");let Re=typeof y=="function"?y(F):y;return g.createElement(fl,{...m,"aria-current":P,className:I,ref:C,style:Re,to:p,viewTransition:j},typeof S=="function"?S(F):S)});Cp.displayName="NavLink";var Tp=g.forwardRef(({discover:i="render",fetcherKey:o,navigate:f,reloadDocument:r,replace:d,state:y,method:p=mi,action:j,onSubmit:S,relative:m,preventScrollReset:C,viewTransition:N,defaultShouldRevalidate:_,...Y},Q)=>{let{useTransitions:q}=g.useContext(Ot),G=Dp(),M=Op(j,{relative:m}),D=p.toLowerCase()==="get"?"get":"post",k=typeof j=="string"&&nr.test(j),Z=J=>{if(S&&S(J),J.defaultPrevented)return;J.preventDefault();let ie=J.nativeEvent.submitter,F=(ie==null?void 0:ie.getAttribute("formmethod"))||p,P=()=>G(ie||J.currentTarget,{fetcherKey:o,method:F,navigate:f,replace:d,state:y,relative:m,preventScrollReset:C,viewTransition:N,defaultShouldRevalidate:_});q&&f!==!1?g.startTransition(()=>P()):P()};return g.createElement("form",{ref:Q,method:D,action:M,onSubmit:r?S:Z,...Y,"data-discover":!k&&i==="render"?"true":void 0})});Tp.displayName="Form";function Ap(i){return`${i} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function vm(i){let o=g.useContext(Xa);return Me(o,Ap(i)),o}function Rp(i,{target:o,replace:f,mask:r,state:d,preventScrollReset:y,relative:p,viewTransition:j,defaultShouldRevalidate:S,useTransitions:m}={}){let C=om(),N=Bt(),_=Kn(i,{relative:p});return g.useCallback(Y=>{if(up(Y,o)){Y.preventDefault();let Q=f!==void 0?f:Xn(N)===Xn(_),q=()=>C(i,{replace:Q,mask:r,state:d,preventScrollReset:y,relative:p,viewTransition:j,defaultShouldRevalidate:S});m?g.startTransition(()=>q()):q()}},[N,C,_,f,r,d,o,i,y,p,j,S,m])}var zp=0,_p=()=>`__${String(++zp)}__`;function Dp(){let{router:i}=vm("useSubmit"),{basename:o}=g.useContext(Ot),f=$g(),r=i.fetch,d=i.navigate;return g.useCallback(async(y,p={})=>{let{action:j,method:S,encType:m,formData:C,body:N}=sp(y,o);if(p.navigate===!1){let _=p.fetcherKey||_p();await r(_,f,p.action||j,{defaultShouldRevalidate:p.defaultShouldRevalidate,preventScrollReset:p.preventScrollReset,formData:C,body:N,formMethod:p.method||S,formEncType:p.encType||m,flushSync:p.flushSync})}else await d(p.action||j,{defaultShouldRevalidate:p.defaultShouldRevalidate,preventScrollReset:p.preventScrollReset,formData:C,body:N,formMethod:p.method||S,formEncType:p.encType||m,replace:p.replace,state:p.state,fromRouteId:f,flushSync:p.flushSync,viewTransition:p.viewTransition})},[r,d,o,f])}function Op(i,{relative:o}={}){let{basename:f}=g.useContext(Ot),r=g.useContext(Xt);Me(r,"useFormAction must be used inside a RouteContext");let[d]=r.matches.slice(-1),y={...Kn(i||".",{relative:o})},p=Bt();if(i==null){y.search=p.search;let j=new URLSearchParams(y.search),S=j.getAll("index");if(S.some(C=>C==="")){j.delete("index"),S.filter(N=>N).forEach(N=>j.append("index",N));let C=j.toString();y.search=C?`?${C}`:""}}return(!i||i===".")&&d.route.index&&(y.search=y.search?y.search.replace(/^\?/,"?index&"):"?index"),f!=="/"&&(y.pathname=y.pathname==="/"?f:wt([f,y.pathname])),Xn(y)}function Mp(i,{relative:o}={}){let f=g.useContext(im);Me(f!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=vm("useViewTransitionState"),d=Kn(i,{relative:o});if(!f.isTransitioning)return!1;let y=ol(f.currentLocation.pathname,r)||f.currentLocation.pathname,p=ol(f.nextLocation.pathname,r)||f.nextLocation.pathname;return yi(d.pathname,p)!=null||yi(d.pathname,y)!=null}let rl=null,Gn=null;const Up=3e4,Hp=600*1e3;function wp(){return`${typeof window<"u"?window.location.origin:""}/admin/agent-token`}async function tr(){const i=Date.now();return rl&&rl.expiresAt-i>Up?rl.token:Gn||(Gn=Bp().finally(()=>{Gn=null}),Gn)}async function Bp(){let i;try{i=await fetch(wp(),{method:"GET",headers:{accept:"application/json"},credentials:"include"})}catch{return rl=null,null}if(!i.ok)return rl=null,null;let o;try{o=await i.json()}catch{return rl=null,null}if(!o.token)return rl=null,null;const f=o.expires_at?new Date(o.expires_at).getTime():Date.now()+Hp;return rl={token:o.token,expiresAt:f},o.token}function ym(){rl=null}class Dt extends Error{constructor(o,f){super(f),this.status=o,this.name="HttpError"}}function Qa(){const o="/agent/app/".match(/^(.*\/)app\/?$/);return o?`${o[1]}api`:"/agent/api"}async function dr(i,o={}){const f=await tr(),r=new Headers(o.headers);r.set("accept","application/json"),f&&r.set("authorization",`Bearer ${f}`);const d=await fetch(i,{...o,headers:r});if(d.status!==401)return d;ym();const y=await tr();if(!y)return d;const p=new Headers(o.headers);return p.set("accept","application/json"),p.set("authorization",`Bearer ${y}`),fetch(i,{...o,headers:p})}async function hr(i){try{return(await i.json()).error??""}catch{return await i.text().catch(()=>"")}}async function Qt(i){const o=await dr(`${Qa()}${i}`);if(!o.ok)throw new Dt(o.status,await hr(o)||`${i} failed: ${o.status}`);return await o.json()}async function Bl(i,o){return mr("POST",i,o)}async function Lp(i,o){return mr("PATCH",i,o)}async function Ei(i){const o=await dr(`${Qa()}${i}`,{method:"DELETE"});if(!o.ok)throw new Dt(o.status,await hr(o)||`${i} failed: ${o.status}`);return await o.json()}async function mr(i,o,f){const r=await dr(`${Qa()}${o}`,{method:i,headers:{"content-type":"application/json"},body:JSON.stringify(f)});if(!r.ok)throw new Dt(r.status,await hr(r)||`${o} failed: ${r.status}`);return await r.json()}function qp(i,o){return mr("DELETE",i,o)}function Yp(){return Qt("/agents")}function kp(){return Qt("/agent-defs")}function gm(){return Qt("/agent-vaults")}function Gp(i){return Bl("/agent-defs",i)}function Xp(i){return Qt(`/agent-defs/${encodeURIComponent(i)}`)}function pm(i,o){return Lp(`/agent-defs/${encodeURIComponent(i)}`,o)}function Qp(i){return Ei(`/agent-defs/${encodeURIComponent(i)}`)}function Vp(i){return Bl("/agent-vaults",i)}function Zp(i){return Ei(`/agent-vaults/${encodeURIComponent(i)}`)}const Kp=new Set(["ANTHROPIC_API_KEY","CLAUDE_API_KEY","CLAUDE_CODE_OAUTH_TOKEN"]),Jp=/^[A-Za-z_][A-Za-z0-9_]*$/;function $p(){return Qt("/credentials/env")}function Wp(i){return Bl("/credentials/env",i)}function Fp(i){return qp("/credentials/env",i)}function Ip(){return Qt("/credentials/claude")}function Pp(i){var f;const o=(f=i.channel)==null?void 0:f.trim();return o&&o.length>0?Bl(`/credentials/claude/${encodeURIComponent(o)}`,{token:i.token}):Bl("/credentials/claude",{token:i.token})}function e0(i){return Ei(`/credentials/claude/${encodeURIComponent(i)}`)}function t0(i){return Qt(`/agents/${encodeURIComponent(i)}/env`)}function l0(){return Qt("/jobs")}function a0(i){return Bl("/jobs",i)}function n0(i){return Bl(`/jobs/${encodeURIComponent(i)}/run`,{})}function u0(i){return Ei(`/jobs/${encodeURIComponent(i)}`)}function i0(i,o){const f=Qa().replace(/\/api$/,"");return`claude mcp add --transport http --scope user agent-${i} ${o}${f}/mcp/${i}`}function c0(){return Qt("/channels")}function qh(i){return Qt(`/channels/${encodeURIComponent(i)}/messages`)}function s0(i,o){return Bl(`/channels/${encodeURIComponent(i)}/send`,{text:o})}function r0(i,o){let r=`${Qa().replace(/\/api$/,"")}/ui/events?channel=${encodeURIComponent(i)}`;return o&&(r+=`&token=${encodeURIComponent(o)}`),r}function o0(i,o){let r=`${Qa().replace(/\/api$/,"")}/api/channels/${encodeURIComponent(i)}/turn-events`;return o&&(r+=`?token=${encodeURIComponent(o)}`),r}class Jn extends Error{constructor(o,f){super(f),this.status=o,this.name="HubError"}}function f0(){return typeof window<"u"?window.location.origin:""}function d0(){if(typeof window>"u")return!1;const{hostname:i,port:o}=window.location;return(i==="127.0.0.1"||i==="localhost"||i==="[::1]")&&o==="1941"}const vr="definition.reload",yr="note.created",gr="note.updated",h0="agent/definition";function lr(i,o){return`agentdefs-${o}-${i}`}function m0(i,o){return{id:lr(i,o),requestedBy:"agent",source:{module:"vault",vault:i,event:o==="create"?yr:gr,filter:{tags:[h0]}},sink:{module:"agent",action:vr}}}async function ji(i,o={}){const f=new Headers(o.headers);return f.set("accept","application/json"),fetch(`${f0()}${i}`,{...o,credentials:"include",headers:f})}function Qn(i,o){return i===401?"Not signed in to the hub portal — sign in, then retry.":i===403?"Not authorized — reactive reload needs host-admin access.":i===404?"Reactive reload needs the hub-proxied URL — open the agent app via your hub origin, not the loopback daemon.":o||`hub request failed (${i})`}async function Ni(i){try{const o=await i.json();return o.error_description??o.error??""}catch{return await i.text().catch(()=>"")}}async function Yh(){const i=await ji("/admin/connections");if(!i.ok)throw new Jn(i.status,Qn(i.status,await Ni(i)));return(await i.json()).connections??[]}function v0(i,o){const f=y=>o.some(p=>p.source.module==="vault"&&p.source.vault===i&&p.source.event===y&&p.sink.module==="agent"&&p.sink.action===vr),r=f(yr),d=f(gr);return{create:r,edit:d,active:r&&d}}async function kh(i){const o=["create","edit"],f=[];let r=0,d="";for(const y of o){const p=await ji("/admin/connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(m0(i,y))});if(!p.ok){const j=await Ni(p);r===0&&(r=p.status,d=j),f.push(`${y}: ${Qn(p.status,j)}`)}}if(f.length===o.length)throw new Jn(r,Qn(r,d||"provisioning failed"));return{ok:f.length===0,failures:f}}async function Gh(i,o,f){const r={};o!==void 0&&(r.token=o),f&&(r.returnTo=f);const d=await ji(`/admin/grants/${encodeURIComponent(i)}/approve`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)});if(!d.ok)throw new Jn(d.status,Qn(d.status,await Ni(d)));return await d.json()}async function Xh(i,o=[]){const f=new Set([lr(i,"create"),lr(i,"edit")]);for(const r of o)r.source.module==="vault"&&r.source.vault===i&&(r.source.event===yr||r.source.event===gr)&&r.sink.module==="agent"&&r.sink.action===vr&&f.add(r.id);for(const r of f){const d=await ji(`/admin/connections/${encodeURIComponent(r)}`,{method:"DELETE"});if(!d.ok&&d.status!==404)throw new Jn(d.status,Qn(d.status,await Ni(d)))}}const pr=[{value:"",label:"Default (Claude Code's default)"},{value:"opus",label:"Opus — most capable"},{value:"sonnet",label:"Sonnet — balanced"},{value:"haiku",label:"Haiku — fastest"}];function y0(i){var o;return i?((o=pr.find(f=>f.value===i))==null?void 0:o.label)??i:"Default"}function g0(i,o){const f=new Map;for(const r of i)f.set(r.name,{name:r.name,backend:r.backend,...r.channel?{channel:r.channel}:{},...r.vault?{vault:r.vault}:{},...r.status?{status:r.status}:{},live:!0});for(const r of o){const d=f.get(r.name);d?(d.def=r,d.mode=r.mode,!d.channel&&r.channel&&(d.channel=r.channel),!d.vault&&r.vault&&(d.vault=r.vault)):f.set(r.name,{name:r.name,backend:r.backend,channel:r.channel,vault:r.vault,status:r.status,mode:r.mode,live:!1,def:r})}return[...f.values()].sort((r,d)=>r.name.localeCompare(d.name))}function bm(i){return i==="programmatic"?"pill backend-programmatic":i==="channel"?"pill backend-channel":"pill backend-interactive"}function Sm(i){return i==="enabled"||i==="idle"?"pill status-enabled":i==="working"?"pill status-working":i==="pending"||i.startsWith("queued")?"pill status-queued":i==="error"?"pill status-error":"pill"}function Qh(){const[i,o]=g.useState({kind:"loading"}),[f,r]=g.useState(null),[d,y]=g.useState(!1),p=g.useCallback(async()=>{o({kind:"loading"});try{const[m,C,N]=await Promise.all([Yp(),kp(),gm()]);o({kind:"ok",agents:m.agents,defs:C.defs,vaults:N.vaults})}catch(m){const C=m instanceof Dt?m.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load agents: ${m.message}`:`Failed to load agents: ${m.message}`;o({kind:"error",message:C})}},[]);g.useEffect(()=>{p()},[p]),g.useEffect(()=>{const m=new URLSearchParams(window.location.search);if(m.get("mcp_connected")!=="1")return;y(!0),m.delete("mcp_connected");const C=m.toString();window.history.replaceState(null,"",window.location.pathname+(C?`?${C}`:"")+window.location.hash)},[]);const j=g.useMemo(()=>i.kind==="ok"?g0(i.agents,i.defs):[],[i]),S=g.useMemo(()=>j.find(m=>m.name===f)??null,[j,f]);return c.jsxs("div",{children:[c.jsx("h1",{children:"Agents"}),c.jsx("p",{className:"lede",children:"Every agent across all backends, in one place — programmatic, channel, and interactive. Read-only for now; the create flow and def-vault editor land in later phases."}),i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void p(),children:"Retry"})]}):null,d?c.jsxs("div",{className:"success-banner",role:"status",children:["✓ MCP server connected — it'll be available to the agent on its next run."," ",c.jsx("button",{type:"button",className:"link",onClick:()=>y(!1),children:"Dismiss"})]}):null,i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading agents…"}):null,i.kind==="ok"?c.jsxs(c.Fragment,{children:[S?c.jsx(p0,{agent:S,onClose:()=>r(null),onChanged:()=>void p(),onDeleted:()=>{r(null),p()}}):null,c.jsxs("section",{className:"card","aria-label":"Agents",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"All agents"}),c.jsxs("span",{className:"section-head-actions",children:[c.jsxs("span",{className:"count","data-testid":"agents-count",children:[j.length," ",j.length===1?"agent":"agents"]}),c.jsx(fl,{to:"/create",className:"button-link","data-testid":"new-agent-link",children:"New agent"})]})]}),j.length===0?c.jsxs("div",{className:"empty",children:["No agents yet. Define one in a vault as an"," ",c.jsx("code",{children:"#agent/definition"})," note, or spawn one from the create flow (coming in a later phase)."]}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Backend"}),c.jsx("th",{children:"Channel"}),c.jsx("th",{children:"Status"}),c.jsx("th",{children:"Vault"})]})}),c.jsx("tbody",{children:j.map(m=>c.jsxs("tr",{className:`agent-row${f===m.name?" selected":""}`,"data-testid":`agent-row-${m.name}`,onClick:()=>r(f===m.name?null:m.name),children:[c.jsx("td",{className:"cell-name",children:m.name}),c.jsx("td",{children:c.jsx("span",{className:bm(m.backend),children:m.backend})}),c.jsx("td",{className:m.channel?"":"cell-dim",children:m.channel??"—"}),c.jsx("td",{children:m.status?c.jsx("span",{className:Sm(m.status),children:m.status}):m.live?c.jsx("span",{className:"cell-dim",children:"live"}):c.jsx("span",{className:"cell-dim",children:"not running"})}),c.jsx("td",{className:m.vault?"":"cell-dim",children:m.vault??"—"})]},m.name))})]})]}),c.jsx(M0,{}),c.jsx(U0,{vaults:i.vaults,onChanged:()=>void p()})]}):null]})}function p0({agent:i,onClose:o,onChanged:f,onDeleted:r}){const d=i.def,y=d==null?void 0:d.noteId,[p,j]=g.useState("view");return g.useEffect(()=>{j("view")},[i.name]),p==="edit"&&y?c.jsx(S0,{noteId:y,name:i.name,onCancel:()=>j("view"),onSaved:()=>{j("view"),f()}}):c.jsxs("div",{className:"detail","data-testid":"agent-detail",children:[c.jsxs("div",{className:"detail-head",children:[c.jsx("h2",{children:i.name}),c.jsx("span",{className:bm(i.backend),children:i.backend}),i.status?c.jsx("span",{className:Sm(i.status),children:i.status}):null,c.jsx("button",{type:"button",className:"detail-close",onClick:o,children:"Close"})]}),c.jsxs("dl",{className:"detail-grid",children:[c.jsx("dt",{children:"Backend"}),c.jsx("dd",{children:i.backend}),c.jsx("dt",{children:"Mode"}),c.jsx("dd",{"data-testid":"detail-mode",children:i.mode?b0(i.mode):"—"}),c.jsx("dt",{children:"Channel"}),c.jsx("dd",{children:i.channel??"—"}),c.jsx("dt",{children:"Vault"}),c.jsx("dd",{children:i.vault??"—"}),c.jsx("dt",{children:"Running"}),c.jsx("dd",{children:i.live?"yes":"no (defined, not instantiated)"}),d?c.jsxs(c.Fragment,{children:[c.jsx("dt",{children:"Model"}),c.jsx("dd",{"data-testid":"detail-model",children:y0(d.model)}),c.jsx("dt",{children:"Def status"}),c.jsx("dd",{children:d.status})]}):null]}),d?c.jsxs(c.Fragment,{children:[c.jsx("h3",{children:"System prompt"}),d.systemPromptPreview?c.jsx("p",{className:"detail-prompt","data-testid":"detail-prompt",children:d.systemPromptPreview}):c.jsx("p",{className:"dim",children:"No system prompt set (Claude Code's default)."}),c.jsx("h3",{children:"Wants"}),d.wants.length>0?c.jsx("div",{className:"tag-list",children:d.wants.map(S=>c.jsx("span",{className:"tag",children:S},S))}):c.jsx("p",{className:"dim",children:"Own-vault only — no extra connections requested."}),d.pending.length>0?c.jsxs(c.Fragment,{children:[c.jsx("h3",{children:"Pending approval"}),c.jsx("div",{className:"tag-list",children:d.pending.map(S=>c.jsx("span",{className:"tag",children:S},S))})]}):null,y?c.jsx(N0,{noteId:y,def:d,onChanged:f}):null]}):c.jsxs("p",{className:"dim","data-testid":"detail-no-def",children:["This agent isn't backed by a vault-native ",c.jsx("code",{children:"#agent/definition"})," note, so there's no system prompt or wants to show."]}),i.backend==="channel"?c.jsx("p",{className:"detail-note","data-testid":"detail-channel-note",children:'Channel backend — the queue depth and the "connect your Claude Code session" affordance arrive in a later phase.'}):null,i.channel?c.jsx(A0,{channel:i.channel}):null,i.channel?c.jsx(O0,{channel:i.channel,backend:i.backend}):null,i.channel?c.jsx(D0,{name:i.name}):null,y?p==="delete"?c.jsx(x0,{noteId:y,name:i.name,onCancel:()=>j("view"),onDeleted:r}):c.jsxs("div",{className:"detail-actions","data-testid":"detail-actions",children:[c.jsx("button",{type:"button",className:"secondary","data-testid":"edit-agent",onClick:()=>j("edit"),children:"Edit"}),c.jsx("button",{type:"button",className:"button-danger","data-testid":"delete-agent",onClick:()=>j("delete"),children:"Delete"})]}):null]})}function b0(i){return i==="single-threaded"?"Single-threaded":"Multi-threaded"}function S0({noteId:i,name:o,onCancel:f,onSaved:r}){const[d,y]=g.useState({kind:"loading"}),[p,j]=g.useState(""),[S,m]=g.useState("single-threaded"),[C,N]=g.useState(""),[_,Y]=g.useState(""),[Q,q]=g.useState(!1),[G,M]=g.useState(null),D=g.useCallback(async()=>{y({kind:"loading"});try{const J=(await Xp(i)).def;j(J.systemPrompt),m(J.mode),N(J.model??""),Y(J.wants.join(", ")),y({kind:"ready",systemPrompt:J.systemPrompt,mode:J.mode,wants:J.wants.join(", ")})}catch(Z){const J=Z instanceof Dt?Z.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load the def: ${Z.message}`:`Failed to load the def: ${Z.message}`;y({kind:"error",message:J})}},[i]);g.useEffect(()=>{D()},[D]);async function k(Z){if(Z.preventDefault(),!Q){q(!0),M(null);try{await pm(i,{systemPrompt:p,metadata:{mode:S,model:C},wants:_.trim()}),r()}catch(J){const ie=J instanceof Dt&&J.status===401?"Not signed in to the hub — sign in to the portal, then reload.":J.message;M(ie)}finally{q(!1)}}}return c.jsxs("div",{className:"detail","data-testid":"edit-agent-form",children:[c.jsxs("div",{className:"detail-head",children:[c.jsxs("h2",{children:["Edit ",o]}),c.jsx("button",{type:"button",className:"detail-close",onClick:f,children:"Close"})]}),d.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading def…"}):null,d.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"edit-load-error",children:[d.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void D(),children:"Retry"})]}):null,d.kind==="ready"?c.jsxs("form",{className:"card",onSubmit:k,"aria-label":"Edit agent",children:[G?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"edit-error",children:G}):null,c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Mode"}),c.jsx(pi,{name:"edit-mode",value:"single-threaded",checked:S==="single-threaded",onChange:()=>m("single-threaded"),label:"Single-threaded",help:"One continuous conversation — remembers everything on this channel.",testid:"edit-mode-single-threaded"}),c.jsx(pi,{name:"edit-mode",value:"multi-threaded",checked:S==="multi-threaded",onChange:()=>m("multi-threaded"),label:"Multi-threaded",help:"Each run is its own thread — good for scheduled or stateless tasks.",testid:"edit-mode-multi-threaded"})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-model",children:"Model"}),c.jsx("select",{id:"edit-model",value:C,"data-testid":"edit-model",onChange:Z=>N(Z.target.value),children:pr.map(Z=>c.jsx("option",{value:Z.value,children:Z.label},Z.value))}),c.jsx("p",{className:"field-hint",children:"Which model Parachute runs this agent on (programmatic backend). A channel-backend agent uses whatever model your own session runs."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-prompt",children:"System prompt"}),c.jsx("textarea",{id:"edit-prompt",rows:8,value:p,placeholder:"You are…",onChange:Z=>j(Z.target.value)}),c.jsx("p",{className:"field-hint",children:"The agent's persona + instructions (the note body). Leave blank for Claude Code's default."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-wants",children:"Wants (connections)"}),c.jsx("input",{id:"edit-wants",type:"text",value:_,placeholder:"vault:other, service:github",autoComplete:"off",onChange:Z=>Y(Z.target.value)}),c.jsx("p",{className:"field-hint",children:"Comma-separated connection keys the agent requests beyond its own vault. Each needs approval before it's granted."})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:Q,children:Q?"Saving…":"Save changes"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]}):null]})}function x0({noteId:i,name:o,onCancel:f,onDeleted:r}){const[d,y]=g.useState(""),[p,j]=g.useState(!1),[S,m]=g.useState(null),C=d===o&&!p;async function N(){if(C){j(!0),m(null);try{await Qp(i),r()}catch(_){const Y=_ instanceof Dt&&_.status===401?"Not signed in to the hub — sign in to the portal, then reload.":_.message;m(Y),j(!1)}}}return c.jsxs("div",{className:"confirm-box","data-testid":"delete-confirm",children:[c.jsxs("p",{className:"confirm-prompt",children:["Delete ",c.jsx("strong",{children:o}),"? This removes the definition note and deregisters the agent. Type the agent name to confirm."]}),S?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"delete-error",children:S}):null,c.jsx("div",{className:"field",children:c.jsx("input",{type:"text",value:d,placeholder:o,autoComplete:"off","aria-label":"Type the agent name to confirm deletion","data-testid":"delete-confirm-input",onChange:_=>y(_.target.value)})}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":"delete-confirm-button",disabled:!C,onClick:()=>void N(),children:p?"Deleting…":"Delete agent"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]})}function E0({status:i}){return i==="approved"?c.jsx("span",{className:"pill status-enabled","data-testid":"conn-status-approved",children:"Connected"}):i==="needs_consent"?c.jsx("span",{className:"pill status-error","data-testid":"conn-status-needs_consent",children:"Needs reconnect"}):i==="revoked"?c.jsx("span",{className:"pill status-error","data-testid":"conn-status-revoked",children:"Revoked"}):c.jsx("span",{className:"pill status-pending","data-testid":"conn-status-pending",children:"Pending"})}function j0(i){if(i.connections&&i.connections.length>0)return i.connections.filter(f=>f.kind==="mcp");const o=new Set(i.pending);return i.wants.filter(f=>f.startsWith("mcp:")&&/^mcp:https?:\/\//i.test(f)).map(f=>({key:f,kind:"mcp",target:f.slice(4),status:o.has(f)?"pending":"approved"}))}function N0({noteId:i,def:o,onChanged:f}){const[r,d]=g.useState(!1),[y,p]=g.useState(null),[j,S]=g.useState(null),[m,C]=g.useState(""),[N,_]=g.useState(null),Y=j0(o),Q=d0();async function q(M){p(M),_(null);try{const D=window.location.pathname+window.location.search+window.location.hash,k=await Gh(M,void 0,D);if(k.authorizeUrl){window.location.assign(k.authorizeUrl);return}f()}catch(D){_(Vh(D))}finally{p(null)}}async function G(M){const D=m.trim();if(D.length!==0){p(M),_(null);try{await Gh(M,D),S(null),C(""),f()}catch(k){_(Vh(k))}finally{p(null)}}}return c.jsxs("section",{className:"detail-section","aria-label":"Connections","data-testid":"connections-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Connections / MCP servers"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-mcp-toggle",onClick:()=>{d(M=>!M),_(null)},children:r?"Cancel":"Add MCP server"})]}),c.jsx("p",{className:"muted",children:"Remote MCP servers this agent can reach. Add one, then connect it via OAuth (or paste a static bearer). Each connection is operator-approved before it's granted."}),Q?c.jsx("div",{className:"info-banner",role:"status","data-testid":"connections-daemon-direct",children:"Open this surface via your hub to connect MCP servers — the OAuth/approve step needs the hub origin (you're on the loopback daemon)."}):null,r?c.jsx(C0,{noteId:i,def:o,onCancel:()=>d(!1),onAdded:()=>{d(!1),f()}}):null,N?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"connections-row-error",children:N}):null,Y.length===0?c.jsx("div",{className:"empty","data-testid":"connections-empty",children:"No MCP servers connected to this agent yet."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"MCP server"}),c.jsx("th",{children:"Status"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:Y.map(M=>{const D=M.status!=="approved",k=D&&!!M.grantId&&!Q;return c.jsxs("tr",{"data-testid":`connection-row-${M.target}`,children:[c.jsx("td",{className:"cell-name",children:c.jsx("code",{children:M.target})}),c.jsx("td",{children:c.jsx(E0,{status:M.status})}),c.jsx("td",{children:D?j===M.grantId?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("input",{type:"password",value:m,placeholder:"bearer token",autoComplete:"off",spellCheck:!1,"aria-label":"Static bearer token","data-testid":`paste-token-input-${M.target}`,onChange:Z=>C(Z.target.value)}),c.jsx("button",{type:"button",disabled:y===M.grantId||m.trim().length===0,"data-testid":`paste-token-save-${M.target}`,onClick:()=>void G(M.grantId),children:y===M.grantId?"Saving…":"Save"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>{S(null),C("")},children:"Cancel"})]}):c.jsxs("span",{className:"schedule-row-actions",children:[c.jsx("button",{type:"button",disabled:!k||y===M.grantId,"data-testid":`connect-${M.target}`,title:Q?"Open the agent app via your hub origin to connect.":M.grantId?void 0:"No grant registered yet — reload after the daemon registers it.",onClick:()=>void q(M.grantId),children:y===M.grantId?"Connecting…":M.status==="needs_consent"?"Reconnect":"Connect"}),M.grantId&&!Q?c.jsx("button",{type:"button",className:"cancel-link","data-testid":`paste-token-${M.target}`,onClick:()=>{_(null),C(""),S(M.grantId)},children:"Paste token"}):null]}):c.jsx("span",{className:"cell-dim",children:"—"})})]},M.key)})})]})]})}function Vh(i){return i instanceof Jn,i.message}function C0({noteId:i,def:o,onCancel:f,onAdded:r}){const[d,y]=g.useState(""),[p,j]=g.useState("oauth"),[S,m]=g.useState(!1),[C,N]=g.useState(null),_=d.trim(),Y=/^https?:\/\/.+/i.test(_)&&T0(_),Q=o.wants.includes(`mcp:${_}`),q=Y&&!Q&&!S;async function G(M){if(M.preventDefault(),!!q){m(!0),N(null);try{const D=[...o.wants,`mcp:${_}`].join(", ");await pm(i,{wants:D}),r()}catch(D){const k=D instanceof Dt&&D.status===401?"Not signed in to the hub — sign in to the portal, then reload.":D.message;N(k)}finally{m(!1)}}}return c.jsxs("form",{className:"inline-form",onSubmit:G,"aria-label":"Add MCP server","data-testid":"add-mcp-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-mcp-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"mcp-url",children:"MCP server URL"}),c.jsx("input",{id:"mcp-url",type:"text",value:d,placeholder:"https://mcp.example.com/mcp",autoComplete:"off",spellCheck:!1,onChange:M=>y(M.target.value)}),_.length>0&&!Y?c.jsx("p",{className:"field-error","data-testid":"mcp-url-invalid",children:"Must be a full http(s) URL."}):null,Q?c.jsx("p",{className:"field-error","data-testid":"mcp-url-duplicate",children:"This MCP server is already connected to the agent."}):null]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Authentication"}),c.jsx("p",{className:"muted",children:"You'll enter credentials in the next step — on the connection's row after it's added."}),c.jsx(pi,{name:"mcp-auth",value:"oauth",checked:p==="oauth",onChange:()=>j("oauth"),label:"OAuth",help:"Sign in to the MCP server in your browser (recommended). Connect on the row after adding.",testid:"mcp-auth-oauth"}),c.jsx(pi,{name:"mcp-auth",value:"token",checked:p==="token",onChange:()=>j("token"),label:"Paste a token",help:"For an MCP server with a static bearer token. Paste it on the row's “Paste token” after adding.",testid:"mcp-auth-token"})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!q,"data-testid":"add-mcp-submit",children:S?"Adding…":"Add MCP server"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]})}function T0(i){try{return new URL(i),!0}catch{return!1}}function A0({channel:i}){const[o,f]=g.useState({kind:"loading"}),[r,d]=g.useState(!1),[y,p]=g.useState(null),[j,S]=g.useState(null),[m,C]=g.useState(null),[N,_]=g.useState(null),[Y,Q]=g.useState(null),q=g.useCallback(async()=>{f({kind:"loading"});try{const k=(await l0()).jobs.filter(Z=>Z.channel===i);f({kind:"ok",jobs:k})}catch(D){f({kind:"error",message:at(D)})}},[i]);g.useEffect(()=>{q()},[q]);async function G(D){p(D),_(null),Q(null);try{const k=await n0(D);Q(`Ran ${D} (${k.status}).`),await q()}catch(k){_(`Run failed: ${at(k)}`)}finally{p(null)}}async function M(D){C(D),_(null);try{await u0(D),S(null),await q()}catch(k){_(at(k))}finally{C(null)}}return c.jsxs("section",{className:"schedules","aria-label":"Schedules","data-testid":"schedules-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Schedules"}),c.jsx("span",{className:"section-head-actions",children:c.jsx("button",{type:"button",className:"secondary","data-testid":"add-schedule-toggle",onClick:()=>d(D=>!D),children:r?"Cancel":"New schedule"})})]}),c.jsx("p",{className:"muted",children:"Send this agent a message on a cron schedule. The runner writes the message as an inbound note; the agent runs its turn as if you typed it."}),r?c.jsx(z0,{channel:i,onCancel:()=>d(!1),onCreated:()=>{d(!1),q()}}):null,Y?c.jsx("p",{className:"schedule-status","data-testid":"schedule-row-status",children:Y}):null,N?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"schedule-row-error",children:N}):null,o.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading schedules…"}):null,o.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"schedules-error",children:[o.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void q(),children:"Retry"})]}):null,o.kind==="ok"?o.jobs.length===0?c.jsx("div",{className:"empty","data-testid":"schedules-empty",children:"No schedules yet for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Id"}),c.jsx("th",{children:"Cron"}),c.jsx("th",{children:"Next run"}),c.jsx("th",{children:"Last status"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:o.jobs.map(D=>c.jsxs("tr",{"data-testid":`schedule-row-${D.id}`,children:[c.jsxs("td",{className:"cell-name",children:[c.jsx("code",{children:D.id}),D.enabled?null:c.jsx("span",{className:"cell-dim",children:" (disabled)"})]}),c.jsxs("td",{children:[c.jsx("code",{children:D.schedule.cron}),D.schedule.tz?c.jsxs("span",{className:"cell-dim",children:[" ",D.schedule.tz]}):null]}),c.jsx("td",{className:D.nextRunAt?"":"cell-dim",children:Zh(D.nextRunAt)}),c.jsxs("td",{children:[D.lastStatus?c.jsx("span",{className:D.lastStatus.startsWith("error")?"pill status-error":"pill status-enabled",children:D.lastStatus}):c.jsx("span",{className:"cell-dim",children:"—"}),D.lastRunAt?c.jsxs("span",{className:"cell-dim",children:[" ",Zh(D.lastRunAt)]}):null]}),c.jsx("td",{children:j===D.id?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`schedule-delete-confirm-${D.id}`,disabled:m===D.id,onClick:()=>void M(D.id),children:m===D.id?"Deleting…":"Confirm delete"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>S(null),children:"Cancel"})]}):c.jsxs("span",{className:"schedule-row-actions",children:[c.jsx("button",{type:"button",className:"secondary","data-testid":`schedule-run-${D.id}`,disabled:y===D.id,onClick:()=>void G(D.id),children:y===D.id?"Running…":"Run now"}),c.jsx("button",{type:"button",className:"button-danger","data-testid":`schedule-delete-${D.id}`,onClick:()=>{_(null),S(D.id)},children:"Delete"})]})})]},D.id))})]}):null]})}const R0=[{label:"daily 8am",cron:"0 8 * * *"},{label:"hourly",cron:"0 * * * *"},{label:"every 15m",cron:"*/15 * * * *"},{label:"weekdays 9am",cron:"0 9 * * 1-5"},{label:"weekly Mon 8am",cron:"0 8 * * 1"}];function z0({channel:i,onCancel:o,onCreated:f}){const[r,d]=g.useState(""),[y,p]=g.useState(""),[j,S]=g.useState(""),[m,C]=g.useState(""),[N,_]=g.useState(!1),[Y,Q]=g.useState(null),q=/^[a-zA-Z0-9_-]+$/.test(r),G=q&&y.trim().length>0&&j.trim().length>0&&!N;async function M(D){if(D.preventDefault(),!!G){_(!0),Q(null);try{await a0({id:r,channel:i,message:y.trim(),schedule:{cron:j.trim(),...m.trim()?{tz:m.trim()}:{}},enabled:!0}),f()}catch(k){Q(at(k))}finally{_(!1)}}}return c.jsxs("form",{className:"inline-form",onSubmit:M,"aria-label":"New schedule","data-testid":"schedule-form",children:[Y?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"schedule-form-error",children:Y}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-id",children:"Job id (slug)"}),c.jsx("input",{id:"schedule-id",type:"text",value:r,placeholder:"morning-standup",autoComplete:"off",onChange:D=>d(D.target.value)}),r.length>0&&!q?c.jsx("p",{className:"field-error","data-testid":"schedule-id-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-message",children:"Message to send"}),c.jsx("textarea",{id:"schedule-message",rows:3,value:y,placeholder:"Run the morning weave…",onChange:D=>p(D.target.value)})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-cron",children:"Cron (min hour dom mon dow)"}),c.jsx("input",{id:"schedule-cron",type:"text",value:j,placeholder:"0 8 * * *",autoComplete:"off",onChange:D=>S(D.target.value)}),c.jsx("div",{className:"schedule-presets",children:R0.map(D=>c.jsx("button",{type:"button",className:"secondary",onClick:()=>S(D.cron),children:D.label},D.cron))})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-tz",children:"Timezone (IANA, optional)"}),c.jsx("input",{id:"schedule-tz",type:"text",value:m,placeholder:"America/Los_Angeles",autoComplete:"off",onChange:D=>C(D.target.value)}),c.jsx("p",{className:"field-hint",children:"Leave blank to use the daemon's local timezone."})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!G,children:N?"Scheduling…":"Create schedule"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:o,children:"Cancel"})]})]})}function Zh(i){if(!i)return"—";try{return new Date(i).toLocaleString()}catch{return i}}function pi(i){return c.jsxs("label",{className:`radio-row${i.checked?" selected":""}`,"data-testid":i.testid,children:[c.jsx("input",{type:"radio",name:i.name,value:i.value,checked:i.checked,onChange:i.onChange}),c.jsxs("span",{className:"radio-body",children:[c.jsx("span",{className:"radio-label",children:i.label}),c.jsx("span",{className:"radio-help",children:i.help})]})]})}function _0(i){return i==="channel"?"pill backend-channel":i.startsWith("grant:")?"pill backend-programmatic":"pill"}function D0({name:i}){const[o,f]=g.useState({kind:"loading"}),r=g.useCallback(async()=>{f({kind:"loading"});try{const d=await t0(i);f({kind:"ok",env:d.env,...d.note?{note:d.note}:{}})}catch(d){f({kind:"error",message:at(d)})}},[i]);return g.useEffect(()=>{r()},[r]),c.jsxs("section",{className:"detail-section","aria-label":"Effective env","data-testid":"effective-env-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Effective env"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"effective-env-refresh",onClick:()=>void r(),children:"Refresh"})]}),c.jsxs("p",{className:"muted",children:["The env-var ",c.jsx("strong",{children:"names"})," this agent's sandboxed turn runs with, resolved across the operator default, this agent's override, and approved-grant service env."," ",c.jsx("strong",{children:"Names only"})," — values are never shown. Precedence: channel > default > grant."]}),o.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading effective env…"}):null,o.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"effective-env-error",children:[o.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void r(),children:"Retry"})]}):null,o.kind==="ok"?c.jsxs(c.Fragment,{children:[o.note?c.jsx("p",{className:"muted","data-testid":"effective-env-note",children:o.note}):null,o.env.length===0?c.jsx("div",{className:"empty","data-testid":"effective-env-empty",children:"No env vars resolved for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Source"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:o.env.map((d,y)=>c.jsxs("tr",{className:d.overridden?"cell-dim":"","data-testid":`effective-env-${d.name}-${d.source}`,children:[c.jsx("td",{className:"cell-name",children:d.name}),c.jsx("td",{children:c.jsx("span",{className:_0(d.source),children:d.source})}),c.jsx("td",{children:d.overridden?c.jsx("span",{className:"cell-dim","data-testid":`effective-env-overridden-${d.name}-${d.source}`,children:"overridden"}):null})]},`${d.name}-${d.source}-${y}`))})]})]}):null]})}function O0({channel:i,backend:o}){const[f,r]=g.useState({kind:"loading"}),[d,y]=g.useState(!1),[p,j]=g.useState(""),[S,m]=g.useState(""),[C,N]=g.useState(!1),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),Z=g.useCallback(async()=>{r({kind:"loading"});try{const le=await $p();r({kind:"ok",names:(le.channels[i]??[]).slice().sort()})}catch(le){r({kind:"error",message:at(le)})}},[i]);g.useEffect(()=>{Z()},[Z]);const J=p.trim(),ie=Kp.has(J),F=J.length===0||Jp.test(J),P=J.length>0&&F&&!ie&&S.length>0&&!C;async function I(le){if(le.preventDefault(),!!P){N(!0),Y(null);try{await Wp({channel:i,name:J,value:S}),j(""),m(""),y(!1),await Z()}catch(xe){Y(at(xe))}finally{N(!1)}}}async function Re(le){M(le),k(null);try{await Fp({channel:i,name:le}),q(null),await Z()}catch(xe){k(at(xe))}finally{M(null)}}return c.jsxs("section",{className:"detail-section","aria-label":"Secrets","data-testid":"secrets-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Secrets (env vars)"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-secret-toggle",onClick:()=>{y(le=>!le),Y(null)},children:d?"Cancel":"Add secret"})]}),c.jsxs("p",{className:"muted",children:["Local env vars (e.g. ",c.jsx("code",{children:"GH_TOKEN"}),") injected into this agent's sandboxed turns — stored 0600 on this machine, ",c.jsx("strong",{children:"never in the vault"}),". Values are write-only: they're never shown again.",o==="channel"?c.jsxs(c.Fragment,{children:[" ","This agent uses the ",c.jsx("strong",{children:"channel"})," backend, so it runs in your own Claude Code session with your own environment — these vars apply only to programmatic turns."]}):null]}),d?c.jsxs("form",{className:"inline-form",onSubmit:I,"aria-label":"Add secret","aria-busy":C,"data-testid":"add-secret-form",children:[_?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-secret-error",children:_}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"secret-name",children:"Name"}),c.jsx("input",{id:"secret-name",type:"text",value:p,placeholder:"GH_TOKEN",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:le=>j(le.target.value)}),J.length>0&&!F?c.jsx("p",{className:"field-error","data-testid":"secret-name-invalid",children:"A valid env var name — letters, numbers, underscore; not starting with a digit."}):null,ie?c.jsxs("p",{className:"field-error","data-testid":"secret-name-denylisted",children:["Reserved — ",J," would hijack the agent's managed billing/auth."]}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"secret-value",children:"Value"}),c.jsx("input",{id:"secret-value",type:"password",value:S,placeholder:"ghp_…",autoComplete:"off",spellCheck:!1,onChange:le=>m(le.target.value)}),c.jsx("p",{className:"field-hint",children:"Stored 0600 on disk (access-controlled, not encrypted). Write-only — never re-displayed."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!P,children:C?"Saving…":"Save secret"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"secret-row-error",children:D}):null,f.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading secrets…"}):null,f.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"secrets-load-error",children:[f.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void Z(),children:"Retry"})]}):null,f.kind==="ok"?f.names.length===0?c.jsx("div",{className:"empty","data-testid":"secrets-empty",children:"No secrets set for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Value"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:f.names.map(le=>c.jsxs("tr",{"data-testid":`secret-${le}`,children:[c.jsx("td",{className:"cell-name",children:le}),c.jsx("td",{className:"cell-dim",children:"••••••••"}),c.jsx("td",{children:Q===le?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`secret-remove-confirm-${le}`,disabled:G===le,onClick:()=>void Re(le),children:G===le?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`secret-remove-${le}`,onClick:()=>{k(null),q(le)},children:"Remove"})})]},le))})]}):null]})}function M0(){const[i,o]=g.useState({kind:"loading"}),[f,r]=g.useState(!1),[d,y]=g.useState(""),[p,j]=g.useState(""),[S,m]=g.useState(!1),[C,N]=g.useState(null),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),Z=g.useCallback(async()=>{o({kind:"loading"});try{const I=await Ip();o({kind:"ok",status:I})}catch(I){o({kind:"error",message:at(I)})}},[]);g.useEffect(()=>{Z()},[Z]);const J=p.trim(),ie=d.length>0&&!S;async function F(I){if(I.preventDefault(),!!ie){m(!0),N(null),Y(null);try{await Pp({token:d,...J.length>0?{channel:J}:{}}),y(""),j(""),r(!1),Y(J.length>0?`Saved a Claude token override for "${J}".`:"Saved the default Claude token."),await Z()}catch(Re){N(at(Re))}finally{m(!1)}}}async function P(I){M(I),k(null);try{await e0(I),q(null),await Z()}catch(Re){k(at(Re))}finally{M(null)}}return c.jsxs("section",{className:"card","aria-label":"Claude auth","data-testid":"claude-auth-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"Claude auth"}),c.jsxs("span",{className:"section-head-actions",children:[i.kind==="ok"?i.status.defaultSet?c.jsx("span",{className:"pill status-enabled","data-testid":"claude-default-configured",children:"configured"}):c.jsx("span",{className:"pill status-error","data-testid":"claude-default-missing",children:"not configured"}):null,c.jsx("button",{type:"button",className:"secondary","data-testid":"set-claude-token-toggle",onClick:()=>{r(I=>(I&&(y(""),j("")),!I)),N(null),Y(null)},children:f?"Cancel":"Set token"})]})]}),c.jsxs("p",{className:"muted",children:["The token from ",c.jsx("code",{children:"claude setup-token"})," that the daemon runs each agent turn on. It's stored locally (",c.jsx("code",{children:"credentials.json"}),", 0600) and used to run turns on your ",c.jsx("strong",{children:"Claude subscription"})," — ",c.jsx("strong",{children:"not"})," API billing. It's write-only: the value is never shown again. Set a ",c.jsx("strong",{children:"default"})," token (used by every agent) or a per-",c.jsx("strong",{children:"channel"})," override."]}),_?c.jsx("div",{className:"info-banner",role:"status","data-testid":"claude-saved-notice",children:_}):null,f?c.jsxs("form",{className:"inline-form",onSubmit:F,"aria-label":"Set Claude token","aria-busy":S,"data-testid":"set-claude-token-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"set-claude-token-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"claude-token",children:"Token"}),c.jsx("input",{id:"claude-token",type:"password",value:d,placeholder:"paste the output of `claude setup-token`",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:I=>y(I.target.value)}),c.jsxs("p",{className:"field-hint",children:["Run ",c.jsx("code",{children:"claude setup-token"})," on a machine where you're signed in, then paste it here. Stored 0600 on disk (access-controlled, not encrypted). Write-only — never re-displayed."]})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"claude-channel",children:"Channel (optional)"}),c.jsx("input",{id:"claude-channel",type:"text",value:p,placeholder:"leave blank for the default (operator) token",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:I=>j(I.target.value)}),c.jsx("p",{className:"field-hint",children:"A channel name to override just that agent; blank sets the default token every agent falls back to."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!ie,children:S?"Saving…":"Save token"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"claude-row-error",children:D}):null,i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading Claude auth…"}):null,i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"claude-auth-load-error",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void Z(),children:"Retry"})]}):null,i.kind==="ok"?c.jsxs(c.Fragment,{children:[i.status.defaultSet?null:c.jsx("div",{className:"empty","data-testid":"claude-default-empty",children:"No default Claude token set — programmatic agents can't run turns until one is set (or a per-channel override covers them)."}),i.status.channels.length>0?c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Channel override"}),c.jsx("th",{children:"Token"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:i.status.channels.map(I=>c.jsxs("tr",{"data-testid":`claude-override-${I}`,children:[c.jsx("td",{className:"cell-name",children:I}),c.jsx("td",{className:"cell-dim",children:"••••••••"}),c.jsx("td",{children:Q===I?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`claude-override-remove-confirm-${I}`,disabled:G===I,onClick:()=>void P(I),children:G===I?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`claude-override-remove-${I}`,onClick:()=>{k(null),q(I)},children:"Remove"})})]},I))})]}):null]}):null]})}function U0({vaults:i,onChanged:o}){const[f,r]=g.useState(!1),[d,y]=g.useState(""),[p,j]=g.useState(""),[S,m]=g.useState(!1),[C,N]=g.useState(null),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),[Z,J]=g.useState([]),[ie,F]=g.useState(!1),[P,I]=g.useState(null),[Re,le]=g.useState(null),xe=g.useCallback(async()=>{try{const X=await Yh();J(X),F(!0)}catch{F(!1)}},[]);g.useEffect(()=>{xe()},[xe]);const Ie=/^[a-zA-Z0-9_-]+$/.test(d),Ze=Ie&&!S;async function De(X){if(X.preventDefault(),!Ze)return;m(!0),N(null),Y(null);const ne=d;try{await Vp({vault:ne,...p.trim().length>0?{url:p.trim()}:{}}),y(""),j(""),r(!1),o();try{const{ok:oe}=await kh(ne);Y(oe?`Added "${ne}" — reactive reload is on (def changes apply instantly).`:`Added "${ne}" — reactive reload partially wired; defs still converge within 60s.`)}catch(oe){Y(`Added "${ne}". Reactive reload couldn't be enabled (${at(oe)}) — def changes converge within 60s; you can enable it below.`)}await xe()}catch(oe){N(at(oe))}finally{m(!1)}}async function U(X){M(X),k(null);try{await Zp(X);try{const ne=await Yh().catch(()=>Z);await Xh(X,ne)}catch{}q(null),o(),await xe()}catch(ne){k(at(ne))}finally{M(null)}}async function V(X,ne){I(X),le(null);try{ne?await Xh(X,Z):await kh(X),await xe()}catch(oe){le(at(oe))}finally{I(null)}}return c.jsxs("section",{className:"card","aria-label":"Def-vaults",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"Def-vaults"}),c.jsxs("span",{className:"section-head-actions",children:[c.jsx("span",{className:"count",children:i.length}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-def-vault-toggle",onClick:()=>r(X=>!X),children:f?"Cancel":"Add def-vault"})]})]}),c.jsxs("p",{className:"muted",children:["Vaults this module reads ",c.jsx("code",{children:"#agent/definition"})," notes from. Removing one deregisters every agent defined in it. ",c.jsx("strong",{children:"Reactive reload"})," wires a vault trigger so def changes apply instantly instead of waiting up to 60s."]}),_?c.jsx("div",{className:"info-banner",role:"status","data-testid":"add-def-vault-notice",children:_}):null,Re?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"reactive-reload-error",children:Re}):null,f?c.jsxs("form",{className:"inline-form",onSubmit:De,"aria-label":"Add def-vault","data-testid":"add-def-vault-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-def-vault-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"new-vault-name",children:"Vault name"}),c.jsx("input",{id:"new-vault-name",type:"text",value:d,placeholder:"research",autoComplete:"off",onChange:X=>y(X.target.value)}),d.length>0&&!Ie?c.jsx("p",{className:"field-error","data-testid":"new-vault-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"new-vault-url",children:"Vault URL (optional)"}),c.jsx("input",{id:"new-vault-url",type:"text",value:p,placeholder:"http://127.0.0.1:1940",autoComplete:"off",onChange:X=>j(X.target.value)}),c.jsx("p",{className:"field-hint",children:"The vault REST origin. Defaults to the loopback vault."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!Ze,children:S?"Adding…":"Add def-vault"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"remove-def-vault-error",children:D}):null,i.length===0?c.jsx("div",{className:"empty","data-testid":"def-vaults-empty",children:"No def-vaults configured yet."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Vault"}),c.jsx("th",{children:"URL"}),c.jsx("th",{children:"Token"}),c.jsx("th",{children:"Reactive reload"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:i.map(X=>{const ne=v0(X.vault,Z);return c.jsxs("tr",{"data-testid":`def-vault-${X.vault}`,children:[c.jsx("td",{className:"cell-name",children:X.vault}),c.jsx("td",{className:"cell-dim",children:X.url}),c.jsx("td",{children:X.tokenPresent?c.jsx("span",{className:"pill status-enabled",children:"present"}):c.jsx("span",{className:"pill status-error",children:"missing"})}),c.jsx("td",{"data-testid":`reactive-reload-cell-${X.vault}`,children:ie?c.jsxs("span",{className:"confirm-inline",children:[ne.active?c.jsx("span",{className:"pill status-enabled","data-testid":`reactive-on-${X.vault}`,children:"on"}):c.jsx("span",{className:"pill","data-testid":`reactive-off-${X.vault}`,children:"off"}),c.jsx("button",{type:"button",className:"cancel-link","data-testid":`reactive-toggle-${X.vault}`,disabled:P===X.vault,onClick:()=>void V(X.vault,ne.active),children:P===X.vault?"Working…":ne.active?"Disable":"Enable"})]}):c.jsx("span",{className:"cell-dim",title:"Open the agent app via your hub origin to manage reactive reload.",children:"—"})}),c.jsx("td",{children:Q===X.vault?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`remove-def-vault-confirm-${X.vault}`,disabled:G===X.vault,onClick:()=>void U(X.vault),children:G===X.vault?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`remove-def-vault-${X.vault}`,onClick:()=>{k(null),q(X.vault)},children:"Remove"})})]},X.vault)})})]})]})}function at(i){return i instanceof Dt&&i.status===401?"Not signed in to the hub — sign in to the portal, then reload.":i.message}function H0(i){return{key:i.id,kind:i.direction==="outbound"?"them":"you",text:i.text}}function Kh(){const i=qg(),o=om(),[f,r]=g.useState(null),[d,y]=g.useState(null),[p,j]=g.useState(i.channel??null),[S,m]=g.useState([]),[C,N]=g.useState(null),[_,Y]=g.useState({text:"",kind:""}),[Q,q]=g.useState(""),[G,M]=g.useState(!1),D=g.useRef(new Set),k=g.useRef(null),Z=g.useRef(null),J=g.useRef(!1),ie=g.useRef(0),F=g.useRef(null),P=g.useCallback(v=>{var O;return((O=f==null?void 0:f.find(w=>w.name===v))==null?void 0:O.transport)??""},[f]),I=g.useCallback(v=>P(v)==="vault",[P]),Re=g.useCallback(v=>{m(O=>[...O,{key:crypto.randomUUID(),kind:"sys",text:v}])},[]),le=g.useCallback(v=>{!v.id||D.current.has(v.id)||(D.current.add(v.id),m(O=>[...O,H0(v)]))},[]);g.useEffect(()=>{const v=F.current;v&&(v.scrollTop=v.scrollHeight)},[S,C]);const xe=g.useCallback(async v=>{var ge,Xe;const O=ie.current;(ge=k.current)==null||ge.close(),k.current=null,(Xe=Z.current)==null||Xe.close(),Z.current=null;const w=await tr();if(O!==ie.current)return;const K=P(v),ae=()=>{J.current=!1,Y({text:`live - ${v}`,kind:"live"})},re=()=>{var he,Pe;if(!J.current&&w){J.current=!0,Y({text:"re-authenticating...",kind:""}),(he=k.current)==null||he.close(),k.current=null,(Pe=Z.current)==null||Pe.close(),Z.current=null,ym(),xe(v);return}Y({text:"reconnecting...",kind:""})};if(K==="http-ui"){const he=new EventSource(r0(v,w));he.onopen=ae,he.addEventListener("reply",Pe=>{try{const tt=JSON.parse(Pe.data);tt.id?le({id:tt.id,text:tt.text??"",direction:"outbound",sender:"session",ts:""}):m(Va=>[...Va,{key:crypto.randomUUID(),kind:"them",text:tt.text??""}])}catch{}}),he.addEventListener("edit",Pe=>{try{const tt=JSON.parse(Pe.data);Re(`(edited) ${tt.text??""}`)}catch{}}),he.addEventListener("permission",Pe=>{try{const tt=JSON.parse(Pe.data);Re(`permission: ${tt.tool_name??""}${tt.description?` - ${tt.description}`:""} (respond in the session terminal)`)}catch{}}),he.onerror=re,k.current=he}if(I(v)){const he=new EventSource(o0(v,w));he.onopen=ae,he.addEventListener("turn",Pe=>{try{Ze(JSON.parse(Pe.data),v)}catch{}}),he.onerror=re,Z.current=he}},[le,Re,I,P]),Ie=g.useCallback(async v=>{try{(await qh(v)).messages.forEach(le)}catch{}},[le]),Ze=g.useCallback((v,O)=>{switch(v.kind){case"init":N({text:"",tools:[]});return;case"text":N(w=>({text:((w==null?void 0:w.text)??"")+v.text,tools:(w==null?void 0:w.tools)??[],...w!=null&&w.error?{error:w.error}:{}}));return;case"tool":N(w=>{const K=(w==null?void 0:w.tools)??[];return{text:(w==null?void 0:w.text)??"",tools:K.includes(v.tool)?K:[...K,v.tool]}});return;case"done":N(null),Ie(O);return;case"error":N(w=>({text:(w==null?void 0:w.text)??"",tools:(w==null?void 0:w.tools)??[],error:v.error}));return}},[Ie]);g.useEffect(()=>{let v=!1;return(async()=>{try{const O=await c0();if(v)return;r(O.channels),j(w=>{var K;return w&&O.channels.some(ae=>ae.name===w)?w:((K=O.channels[0])==null?void 0:K.name)??null})}catch(O){v||y(Fs(O))}})(),()=>{v=!0}},[]),g.useEffect(()=>{const v=p;if(!v){Y({text:"no channel",kind:""});return}let O=!1;return ie.current+=1,D.current=new Set,J.current=!1,m([]),N(null),Y({text:"loading history...",kind:""}),(async()=>{try{const w=await qh(v);if(O)return;w.messages.forEach(le),Y({text:`live - ${v}`,kind:"live"})}catch(w){if(O)return;Y({text:`history error: ${Fs(w)}`,kind:"err"})}O||await xe(v)})(),()=>{var w,K;O=!0,ie.current+=1,(w=k.current)==null||w.close(),k.current=null,(K=Z.current)==null||K.close(),Z.current=null}},[p]);function De(v){j(v),o(`/chat/${encodeURIComponent(v)}`,{replace:!0})}async function U(){const v=Q.trim(),O=p;if(!(!v||!O||G)){M(!0),m(w=>[...w,{key:crypto.randomUUID(),kind:"you",text:v}]),q("");try{const w=await s0(O,v);w.id&&D.current.add(w.id)}catch(w){Re(`send failed: ${Fs(w)}`)}finally{M(!1)}}}function V(v){v.key==="Enter"&&!v.shiftKey&&(v.preventDefault(),U())}const X=((f==null?void 0:f.length)??0)>0,ne=!!p&&Q.trim().length>0&&!G,oe=g.useMemo(()=>_.kind==="live"?"chat-status status-live":_.kind==="err"?"chat-status status-err":"chat-status",[_.kind]);return c.jsxs("div",{className:"chat","data-testid":"chat-view",children:[c.jsxs("div",{className:"chat-head",children:[c.jsx("h1",{children:"Chat"}),f&&X?c.jsxs("label",{className:"chat-picker",children:[c.jsx("span",{className:"chat-picker-label",children:"Channel"}),c.jsx("select",{"data-testid":"chat-channel-select",value:p??"",onChange:v=>De(v.target.value),children:f.map(v=>c.jsxs("option",{value:v.name,children:[v.name," (",v.transport,")"]},v.name))})]}):null,_.text?c.jsx("span",{className:oe,"data-testid":"chat-status",children:_.text}):null]}),d?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"chat-channels-error",children:d}):null,f&&!X&&!d?c.jsx("div",{className:"empty","data-testid":"chat-no-channels",children:"No channels yet. Create a channel-backed agent in the create flow, then chat with it here."}):null,X?c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:"transcript",ref:F,"data-testid":"chat-transcript",children:[S.map(v=>c.jsx("div",{className:`msg ${v.kind}`,"data-testid":`chat-msg-${v.kind}`,children:v.text},v.key)),C?c.jsx(w0,{turn:C}):null]}),c.jsxs("form",{className:"composer","data-testid":"chat-composer",onSubmit:v=>{v.preventDefault(),U()},children:[c.jsx("textarea",{className:"chat-input","data-testid":"chat-input",rows:1,value:Q,placeholder:"Type a message... (Enter to send, Shift+Enter for newline)",autoComplete:"off",onChange:v=>q(v.target.value),onKeyDown:V}),c.jsx("button",{type:"submit","data-testid":"chat-send",disabled:!ne,children:G?"Sending...":"Send"})]})]}):null]})}function w0({turn:i}){return c.jsxs("div",{className:`msg them live${i.error?" errored":""}`,"data-testid":"chat-live-turn",children:[i.text?c.jsx("div",{className:"live-text",children:i.text}):null,i.tools.length>0?c.jsx("div",{className:"live-tools",children:i.tools.map(o=>c.jsx("span",{className:"tool-chip","data-testid":`chat-tool-${o}`,children:o},o))}):null,c.jsx("div",{className:"live-working","data-testid":"chat-live-status",children:i.error?`turn failed: ${i.error}`:"working..."})]})}function Fs(i){return i instanceof Dt&&i.status===401?"Not signed in to the hub - sign in to the portal, then reload.":i.message}const B0=/^[a-zA-Z0-9_-]+$/;function L0({vaults:i}){var F;const o=i.length>0,[f,r]=g.useState(""),[d,y]=g.useState(((F=i[0])==null?void 0:F.vault)??""),[p,j]=g.useState("single-threaded"),[S,m]=g.useState("programmatic"),[C,N]=g.useState(""),[_,Y]=g.useState(""),[Q,q]=g.useState(""),[G,M]=g.useState(!1),[D,k]=g.useState({kind:"idle"}),Z=B0.test(f),J=o&&Z&&d.length>0&&D.kind!=="submitting";async function ie(P){if(P.preventDefault(),!!J){k({kind:"submitting"});try{const I=await Gp({vault:d,name:f,backend:S,systemPrompt:_,metadata:{mode:p,...C?{model:C}:{}},...Q.trim().length>0?{wants:Q.trim()}:{}});k({kind:"ok",result:I,mode:p})}catch(I){const Re=I instanceof Dt&&I.status===401?"Not signed in to the hub — sign in to the portal, then reload.":I.message;k({kind:"error",message:Re})}}}return D.kind==="ok"?c.jsx(Y0,{result:D.result,mode:D.mode}):c.jsxs("div",{children:[c.jsx("h1",{children:"New agent"}),c.jsxs("p",{className:"lede",children:["A ",c.jsx("code",{children:"#agent/definition"})," note IS the agent — writing it instantiates the agent and its channel routing in one step. The def-vault editor, schedules, and editing land in a later phase."]}),o?null:c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"no-def-vaults",children:["No def-vault is configured, and one is required to create an agent. The add / remove def-vault editor arrives in a later phase; until then, configure a def-vault out-of-band. Submitting anyway will return the daemon's"," ",c.jsx("code",{children:"no def-vaults configured"})," error."]}),D.kind==="error"?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"create-error",children:D.message}):null,c.jsxs("form",{className:"card",onSubmit:ie,"aria-label":"Create agent",children:[c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-name",children:"Name"}),c.jsx("input",{id:"agent-name",type:"text",value:f,placeholder:"my-agent",autoComplete:"off",onChange:P=>r(P.target.value)}),c.jsx("p",{className:"field-hint",children:"A slug (letters, numbers, dash, underscore). This is also the agent's channel."}),f.length>0&&!Z?c.jsx("p",{className:"field-error","data-testid":"name-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-vault",children:"Def-vault"}),c.jsx("select",{id:"agent-vault",value:d,disabled:!o,onChange:P=>y(P.target.value),children:o?i.map(P=>c.jsxs("option",{value:P.vault,children:[P.vault,P.tokenPresent?"":" (token missing)"]},P.vault)):c.jsx("option",{value:"",children:"No def-vaults configured"})}),c.jsx("p",{className:"field-hint",children:"The vault this agent's definition note is written to."})]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Mode"}),c.jsx(hi,{name:"mode",value:"single-threaded",checked:p==="single-threaded",onChange:()=>j("single-threaded"),label:"Single-threaded",help:"One continuous conversation — remembers everything on this channel.",testid:"mode-single-threaded"}),c.jsx(hi,{name:"mode",value:"multi-threaded",checked:p==="multi-threaded",onChange:()=>j("multi-threaded"),label:"Multi-threaded",help:"Each run is its own thread; today every run starts fresh (per-conversation continuation is coming) — good for scheduled or stateless tasks.",testid:"mode-multi-threaded"})]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Backend"}),c.jsx(hi,{name:"backend",value:"programmatic",checked:S==="programmatic",onChange:()=>m("programmatic"),label:"Programmatic",help:"Parachute runs it headless — always on, sandboxed.",testid:"backend-programmatic"}),c.jsx(hi,{name:"backend",value:"channel",checked:S==="channel",onChange:()=>m("channel"),label:"Channel",help:"You run a Claude Code session on your own machine and connect it — your env, unsandboxed.",testid:"backend-channel"})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-model",children:"Model"}),c.jsx("select",{id:"agent-model",value:C,"data-testid":"agent-model",onChange:P=>N(P.target.value),children:pr.map(P=>c.jsx("option",{value:P.value,children:P.label},P.value))}),c.jsx("p",{className:"field-hint",children:"Which model Parachute runs this agent on (programmatic backend). A channel-backend agent uses whatever model your own session runs."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-prompt",children:"System prompt"}),c.jsx("textarea",{id:"agent-prompt",rows:6,value:_,placeholder:"You are…",onChange:P=>Y(P.target.value)}),c.jsx("p",{className:"field-hint",children:"The agent's persona + instructions (the note body). Leave blank for Claude Code's default."})]}),c.jsxs("details",{className:"advanced",open:G,onToggle:P=>M(P.target.open),children:[c.jsx("summary",{children:"Advanced"}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-wants",children:"Wants (connections)"}),c.jsx("input",{id:"agent-wants",type:"text",value:Q,placeholder:"vault:other, service:github",autoComplete:"off",onChange:P=>q(P.target.value)}),c.jsx("p",{className:"field-hint",children:"Comma-separated connection keys the agent requests beyond its own vault. Each needs approval before it's granted."})]})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!J,children:D.kind==="submitting"?"Creating…":"Create agent"}),c.jsx(fl,{to:"/",className:"cancel-link",children:"Cancel"})]})]})]})}function q0(){const[i,o]=g.useState({kind:"loading"}),f=g.useCallback(async()=>{o({kind:"loading"});try{const r=await gm();o({kind:"ok",vaults:r.vaults})}catch(r){const d=r instanceof Dt?r.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load def-vaults: ${r.message}`:`Failed to load def-vaults: ${r.message}`;o({kind:"error",message:d})}},[]);return g.useEffect(()=>{f()},[f]),i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading…"}):i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void f(),children:"Retry"})]}):c.jsx(L0,{vaults:i.vaults},i.vaults.map(r=>r.vault).join(","))}function hi(i){return c.jsxs("label",{className:`radio-row${i.checked?" selected":""}`,"data-testid":i.testid,children:[c.jsx("input",{type:"radio",name:i.name,value:i.value,checked:i.checked,onChange:i.onChange}),c.jsxs("span",{className:"radio-body",children:[c.jsx("span",{className:"radio-label",children:i.label}),c.jsx("span",{className:"radio-help",children:i.help})]})]})}function Y0({result:i,mode:o}){const f=i.def;return c.jsxs("div",{"data-testid":"create-success",children:[c.jsx("h1",{children:"Agent created"}),c.jsxs("div",{className:"success-banner",role:"status",children:[c.jsx("strong",{children:f.name})," · ",o," · ",f.backend]}),c.jsxs("p",{className:"lede",children:["The definition was written to ",c.jsx("code",{children:f.vault})," and instantiated. It now appears in the ",c.jsx(fl,{to:"/",children:"Agents list"}),"."]}),f.backend==="channel"?c.jsx(k0,{name:f.name}):null,c.jsx("p",{children:c.jsx(fl,{to:"/",children:"← Back to agents"})})]})}function k0({name:i}){const[o,f]=g.useState(!1),r=typeof window<"u"?window.location.origin:"",d=g.useMemo(()=>i0(i,r),[i,r]);async function y(){var p;try{await((p=navigator.clipboard)==null?void 0:p.writeText(d)),f(!0),setTimeout(()=>f(!1),2e3)}catch{}}return c.jsxs("section",{className:"card","aria-label":"Connect a session","data-testid":"connect-session",children:[c.jsx("h2",{children:"Connect your Claude Code session"}),c.jsx("p",{className:"muted",children:"Run this on your own machine to make a Claude Code session a responder for this channel:"}),c.jsxs("div",{className:"snippet-row",children:[c.jsx("code",{className:"snippet","data-testid":"connect-command",children:d}),c.jsx("button",{type:"button",className:"secondary",onClick:()=>void y(),children:o?"Copied":"Copy"})]}),c.jsx("p",{className:"field-hint",children:"Your Claude Code session pulls messages from this channel; until you connect, inbound messages queue durably in the vault."})]})}const G0="Parachute Agent";function X0(i){return i==="/create"||i.startsWith("/create/")?"new agent":i==="/chat"||i.startsWith("/chat/")?"chat":"agents"}function Q0(){const{pathname:i}=Bt(),o=X0(i);return c.jsxs("div",{className:"page",children:[c.jsxs("nav",{className:"nav",children:[c.jsxs(fl,{to:"/",className:"brand",children:[c.jsx("span",{className:"brand-wordmark",children:G0}),c.jsx("span",{className:"sub",children:o})]}),c.jsx(Is,{to:"/",label:"Agents",exact:!0}),c.jsx(Is,{to:"/create",label:"New agent"}),c.jsx(Is,{to:"/chat",label:"Chat"})]}),c.jsxs(ep,{children:[c.jsx(aa,{path:"/",element:c.jsx(Qh,{})}),c.jsx(aa,{path:"/agents",element:c.jsx(Qh,{})}),c.jsx(aa,{path:"/create",element:c.jsx(q0,{})}),c.jsx(aa,{path:"/chat",element:c.jsx(Kh,{})}),c.jsx(aa,{path:"/chat/:channel",element:c.jsx(Kh,{})}),c.jsx(aa,{path:"*",element:c.jsxs("div",{className:"empty",children:["404 — back to ",c.jsx(fl,{to:"/",children:"Agents"}),"."]})})]})]})}function Is({to:i,label:o,exact:f}){const{pathname:r}=Bt(),d=f?r===i||r==="/agents":r===i||r.startsWith(`${i}/`);return c.jsx(fl,{to:i,className:d?"nav-link nav-link-active":"nav-link","aria-current":d?"page":void 0,children:o})}function V0(i){return i==="/agent/app"||i.startsWith("/agent/app/")?"/agent/app":i==="/app"||i.startsWith("/app/")?"/app":""}const xm=document.getElementById("root");if(!xm)throw new Error("#root not found");eg.createRoot(xm).render(c.jsx(g.StrictMode,{children:c.jsx(Np,{basename:V0(window.location.pathname),children:c.jsx(Q0,{})})}));
|
|
60
|
+
Please change the parent <Route path="${M}"> to <Route path="${M==="/"?"*":`${M}/*`}">.`)}let C=Bt(),N;if(o){let M=typeof o=="string"?Ga(o):o;Me(S==="/"||((G=M.pathname)==null?void 0:G.startsWith(S)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${S}" but pathname "${M.pathname}" was given in the \`location\` prop.`),N=M}else N=C;let _=N.pathname||"/",Y=_;if(S!=="/"){let M=S.replace(/^\//,"").split("/");Y="/"+_.replace(/^\//,"").split("/").slice(M.length).join("/")}let Q=f&&f.state.matches.length?f.state.matches.map(M=>Object.assign(M,{route:f.manifest[M.route.id]||M.route})):$h(i,{pathname:Y});Gt(m||Q!=null,`No routes matched location "${N.pathname}${N.search}${N.hash}" `),Gt(Q==null||Q[Q.length-1].route.element!==void 0||Q[Q.length-1].route.Component!==void 0||Q[Q.length-1].route.lazy!==void 0,`Matched leaf route at location "${N.pathname}${N.search}${N.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let q=Vg(Q&&Q.map(M=>Object.assign({},M,{params:Object.assign({},p,M.params),pathname:wt([S,r.encodeLocation?r.encodeLocation(M.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathname]),pathnameBase:M.pathnameBase==="/"?S:wt([S,r.encodeLocation?r.encodeLocation(M.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathnameBase])})),d,f);return o&&q?g.createElement(Vn.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...N},navigationType:"POP"}},q):q}function kg(){let i=Wg(),o=Cg(i)?`${i.status} ${i.statusText}`:i instanceof Error?i.message:JSON.stringify(i),f=i instanceof Error?i.stack:null,r="rgba(200,200,200, 0.5)",d={padding:"0.5rem",backgroundColor:r},y={padding:"2px 4px",backgroundColor:r},p=null;return console.error("Error handled by React Router default ErrorBoundary:",i),p=g.createElement(g.Fragment,null,g.createElement("p",null,"💿 Hey developer 👋"),g.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",g.createElement("code",{style:y},"ErrorBoundary")," or"," ",g.createElement("code",{style:y},"errorElement")," prop on your route.")),g.createElement(g.Fragment,null,g.createElement("h2",null,"Unexpected Application Error!"),g.createElement("h3",{style:{fontStyle:"italic"}},o),f?g.createElement("pre",{style:d},f):null,p)}var Gg=g.createElement(kg,null),dm=class extends g.Component{constructor(i){super(i),this.state={location:i.location,revalidation:i.revalidation,error:i.error}}static getDerivedStateFromError(i){return{error:i}}static getDerivedStateFromProps(i,o){return o.location!==i.location||o.revalidation!=="idle"&&i.revalidation==="idle"?{error:i.error,location:i.location,revalidation:i.revalidation}:{error:i.error!==void 0?i.error:o.error,location:o.location,revalidation:i.revalidation||o.revalidation}}componentDidCatch(i,o){this.props.onError?this.props.onError(i,o):console.error("React Router caught the following error during render",i)}render(){let i=this.state.error;if(this.context&&typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){const f=wg(i.digest);f&&(i=f)}let o=i!==void 0?g.createElement(Xt.Provider,{value:this.props.routeContext},g.createElement(ir.Provider,{value:i,children:this.props.component})):this.props.children;return this.context?g.createElement(Xg,{error:i},o):o}};dm.contextType=um;var $s=new WeakMap;function Xg({children:i,error:o}){let{basename:f}=g.useContext(Ot);if(typeof o=="object"&&o&&"digest"in o&&typeof o.digest=="string"){let r=Hg(o.digest);if(r){let d=$s.get(o);if(d)throw d;let y=am(r.location,f),p=y.absoluteURL||y.to;if(zg(p))throw new Error("Invalid redirect location");if(lm&&!$s.get(o))if(y.isExternal||r.reloadDocument)window.location.href=p;else{const j=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(y.to,{replace:r.replace}));throw $s.set(o,j),j}return g.createElement("meta",{httpEquiv:"refresh",content:`0;url=${p}`})}}return i}function Qg({routeContext:i,match:o,children:f}){let r=g.useContext(Xa);return r&&r.static&&r.staticContext&&(o.route.errorElement||o.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=o.route.id),g.createElement(Xt.Provider,{value:i},f)}function Vg(i,o=[],f){let r=f==null?void 0:f.state;if(i==null){if(!r)return null;if(r.errors)i=r.matches;else if(o.length===0&&!r.initialized&&r.matches.length>0)i=r.matches;else return null}let d=i,y=r==null?void 0:r.errors;if(y!=null){let C=d.findIndex(N=>N.route.id&&(y==null?void 0:y[N.route.id])!==void 0);Me(C>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(y).join(",")}`),d=d.slice(0,Math.min(d.length,C+1))}let p=!1,j=-1;if(f&&r){p=r.renderFallback;for(let C=0;C<d.length;C++){let N=d[C];if((N.route.HydrateFallback||N.route.hydrateFallbackElement)&&(j=C),N.route.id){let{loaderData:_,errors:Y}=r,Q=N.route.loader&&!_.hasOwnProperty(N.route.id)&&(!Y||Y[N.route.id]===void 0);if(N.route.lazy||Q){f.isStatic&&(p=!0),j>=0?d=d.slice(0,j+1):d=[d[0]];break}}}}let S=f==null?void 0:f.onError,m=r&&S?(C,N)=>{var _,Y;S(C,{location:r.location,params:((Y=(_=r.matches)==null?void 0:_[0])==null?void 0:Y.params)??{},pattern:Tg(r.matches),errorInfo:N})}:void 0;return d.reduceRight((C,N,_)=>{let Y,Q=!1,q=null,G=null;r&&(Y=y&&N.route.id?y[N.route.id]:void 0,q=N.route.errorElement||Gg,p&&(j<0&&_===0?(hm("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),Q=!0,G=null):j===_&&(Q=!0,G=N.route.hydrateFallbackElement||null)));let M=o.concat(d.slice(0,_+1)),D=()=>{let k;return Y?k=q:Q?k=G:N.route.Component?k=g.createElement(N.route.Component,null):N.route.element?k=N.route.element:k=C,g.createElement(Qg,{match:N,routeContext:{outlet:C,matches:M,isDataRoute:r!=null},children:k})};return r&&(N.route.ErrorBoundary||N.route.errorElement||_===0)?g.createElement(dm,{location:r.location,revalidation:r.revalidation,component:q,error:Y,children:D(),routeContext:{outlet:null,matches:M,isDataRoute:!0},onError:m}):D()},null)}function cr(i){return`${i} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Zg(i){let o=g.useContext(Xa);return Me(o,cr(i)),o}function Kg(i){let o=g.useContext(bi);return Me(o,cr(i)),o}function Jg(i){let o=g.useContext(Xt);return Me(o,cr(i)),o}function sr(i){let o=Jg(i),f=o.matches[o.matches.length-1];return Me(f.route.id,`${i} can only be used on routes that contain a unique "id"`),f.route.id}function $g(){return sr("useRouteId")}function Wg(){var r;let i=g.useContext(ir),o=Kg("useRouteError"),f=sr("useRouteError");return i!==void 0?i:(r=o.errors)==null?void 0:r[f]}function Fg(){let{router:i}=Zg("useNavigate"),o=sr("useNavigate"),f=g.useRef(!1);return rm(()=>{f.current=!0}),g.useCallback(async(d,y={})=>{Gt(f.current,sm),f.current&&(typeof d=="number"?await i.navigate(d):await i.navigate(d,{fromRouteId:o,...y}))},[i,o])}var Bh={};function hm(i,o,f){!o&&!Bh[i]&&(Bh[i]=!0,Gt(!1,f))}g.memo(Ig);function Ig({routes:i,manifest:o,future:f,state:r,isStatic:d,onError:y}){return fm(i,void 0,{manifest:o,state:r,isStatic:d,onError:y})}function aa(i){Me(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Pg({basename:i="/",children:o=null,location:f,navigationType:r="POP",navigator:d,static:y=!1,useTransitions:p}){Me(!Zn(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let j=i.replace(/^\/*/,"/"),S=g.useMemo(()=>({basename:j,navigator:d,static:y,useTransitions:p,future:{}}),[j,d,y,p]);typeof f=="string"&&(f=Ga(f));let{pathname:m="/",search:C="",hash:N="",state:_=null,key:Y="default",mask:Q}=f,q=g.useMemo(()=>{let G=ol(m,j);return G==null?null:{location:{pathname:G,search:C,hash:N,state:_,key:Y,mask:Q},navigationType:r}},[j,m,C,N,_,Y,r,Q]);return Gt(q!=null,`<Router basename="${j}"> is not able to match the URL "${m}${C}${N}" because it does not start with the basename, so the <Router> won't render anything.`),q==null?null:g.createElement(Ot.Provider,{value:S},g.createElement(Vn.Provider,{children:o,value:q}))}function ep({children:i,location:o}){return Yg(er(i),o)}function er(i,o=[]){let f=[];return g.Children.forEach(i,(r,d)=>{if(!g.isValidElement(r))return;let y=[...o,d];if(r.type===g.Fragment){f.push.apply(f,er(r.props.children,y));return}Me(r.type===aa,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),Me(!r.props.index||!r.props.children,"An index route cannot have child routes.");let p={id:r.props.id||y.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(p.children=er(r.props.children,y)),f.push(p)}),f}var mi="get",vi="application/x-www-form-urlencoded";function Si(i){return typeof HTMLElement<"u"&&i instanceof HTMLElement}function tp(i){return Si(i)&&i.tagName.toLowerCase()==="button"}function lp(i){return Si(i)&&i.tagName.toLowerCase()==="form"}function ap(i){return Si(i)&&i.tagName.toLowerCase()==="input"}function np(i){return!!(i.metaKey||i.altKey||i.ctrlKey||i.shiftKey)}function up(i,o){return i.button===0&&(!o||o==="_self")&&!np(i)}var di=null;function ip(){if(di===null)try{new FormData(document.createElement("form"),0),di=!1}catch{di=!0}return di}var cp=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Ws(i){return i!=null&&!cp.has(i)?(Gt(!1,`"${i}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${vi}"`),null):i}function sp(i,o){let f,r,d,y,p;if(lp(i)){let j=i.getAttribute("action");r=j?ol(j,o):null,f=i.getAttribute("method")||mi,d=Ws(i.getAttribute("enctype"))||vi,y=new FormData(i)}else if(tp(i)||ap(i)&&(i.type==="submit"||i.type==="image")){let j=i.form;if(j==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let S=i.getAttribute("formaction")||j.getAttribute("action");if(r=S?ol(S,o):null,f=i.getAttribute("formmethod")||j.getAttribute("method")||mi,d=Ws(i.getAttribute("formenctype"))||Ws(j.getAttribute("enctype"))||vi,y=new FormData(j,i),!ip()){let{name:m,type:C,value:N}=i;if(C==="image"){let _=m?`${m}.`:"";y.append(`${_}x`,"0"),y.append(`${_}y`,"0")}else m&&y.append(m,N)}}else{if(Si(i))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');f=mi,r=null,d=vi,p=i}return y&&d==="text/plain"&&(p=y,y=void 0),{action:r,method:f.toLowerCase(),encType:d,formData:y,body:p}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function rr(i,o){if(i===!1||i===null||typeof i>"u")throw new Error(o)}function mm(i,o,f,r){let d=typeof i=="string"?new URL(i,typeof window>"u"?"server://singlefetch/":window.location.origin):i;return f?d.pathname.endsWith("/")?d.pathname=`${d.pathname}_.${r}`:d.pathname=`${d.pathname}.${r}`:d.pathname==="/"?d.pathname=`_root.${r}`:o&&ol(d.pathname,o)==="/"?d.pathname=`${gi(o)}/_root.${r}`:d.pathname=`${gi(d.pathname)}.${r}`,d}async function rp(i,o){if(i.id in o)return o[i.id];try{let f=await import(i.module);return o[i.id]=f,f}catch(f){return console.error(`Error loading route module \`${i.module}\`, reloading page...`),console.error(f),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function op(i){return i==null?!1:i.href==null?i.rel==="preload"&&typeof i.imageSrcSet=="string"&&typeof i.imageSizes=="string":typeof i.rel=="string"&&typeof i.href=="string"}async function fp(i,o,f){let r=await Promise.all(i.map(async d=>{let y=o.routes[d.route.id];if(y){let p=await rp(y,f);return p.links?p.links():[]}return[]}));return vp(r.flat(1).filter(op).filter(d=>d.rel==="stylesheet"||d.rel==="preload").map(d=>d.rel==="stylesheet"?{...d,rel:"prefetch",as:"style"}:{...d,rel:"prefetch"}))}function Lh(i,o,f,r,d,y){let p=(S,m)=>f[m]?S.route.id!==f[m].route.id:!0,j=(S,m)=>{var C;return f[m].pathname!==S.pathname||((C=f[m].route.path)==null?void 0:C.endsWith("*"))&&f[m].params["*"]!==S.params["*"]};return y==="assets"?o.filter((S,m)=>p(S,m)||j(S,m)):y==="data"?o.filter((S,m)=>{var N;let C=r.routes[S.route.id];if(!C||!C.hasLoader)return!1;if(p(S,m)||j(S,m))return!0;if(S.route.shouldRevalidate){let _=S.route.shouldRevalidate({currentUrl:new URL(d.pathname+d.search+d.hash,window.origin),currentParams:((N=f[0])==null?void 0:N.params)||{},nextUrl:new URL(i,window.origin),nextParams:S.params,defaultShouldRevalidate:!0});if(typeof _=="boolean")return _}return!0}):[]}function dp(i,o,{includeHydrateFallback:f}={}){return hp(i.map(r=>{let d=o.routes[r.route.id];if(!d)return[];let y=[d.module];return d.clientActionModule&&(y=y.concat(d.clientActionModule)),d.clientLoaderModule&&(y=y.concat(d.clientLoaderModule)),f&&d.hydrateFallbackModule&&(y=y.concat(d.hydrateFallbackModule)),d.imports&&(y=y.concat(d.imports)),y}).flat(1))}function hp(i){return[...new Set(i)]}function mp(i){let o={},f=Object.keys(i).sort();for(let r of f)o[r]=i[r];return o}function vp(i,o){let f=new Set;return new Set(o),i.reduce((r,d)=>{let y=JSON.stringify(mp(d));return f.has(y)||(f.add(y),r.push({key:y,link:d})),r},[])}function or(){let i=g.useContext(Xa);return rr(i,"You must render this element inside a <DataRouterContext.Provider> element"),i}function yp(){let i=g.useContext(bi);return rr(i,"You must render this element inside a <DataRouterStateContext.Provider> element"),i}var fr=g.createContext(void 0);fr.displayName="FrameworkContext";function xi(){let i=g.useContext(fr);return rr(i,"You must render this element inside a <HydratedRouter> element"),i}function gp(i,o){let f=g.useContext(fr),[r,d]=g.useState(!1),[y,p]=g.useState(!1),{onFocus:j,onBlur:S,onMouseEnter:m,onMouseLeave:C,onTouchStart:N}=o,_=g.useRef(null);g.useEffect(()=>{if(i==="render"&&p(!0),i==="viewport"){let q=M=>{M.forEach(D=>{p(D.isIntersecting)})},G=new IntersectionObserver(q,{threshold:.5});return _.current&&G.observe(_.current),()=>{G.disconnect()}}},[i]),g.useEffect(()=>{if(r){let q=setTimeout(()=>{p(!0)},100);return()=>{clearTimeout(q)}}},[r]);let Y=()=>{d(!0)},Q=()=>{d(!1),p(!1)};return f?i!=="intent"?[y,_,{}]:[y,_,{onFocus:kn(j,Y),onBlur:kn(S,Q),onMouseEnter:kn(m,Y),onMouseLeave:kn(C,Q),onTouchStart:kn(N,Y)}]:[!1,_,{}]}function kn(i,o){return f=>{i&&i(f),f.defaultPrevented||o(f)}}function pp({page:i,...o}){let f=_g(),{nonce:r}=xi(),{router:d}=or(),y=g.useMemo(()=>$h(d.routes,i,d.basename),[d.routes,i,d.basename]);return y?(o.nonce==null&&r&&(o={...o,nonce:r}),f?g.createElement(Sp,{page:i,matches:y,...o}):g.createElement(xp,{page:i,matches:y,...o})):null}function bp(i){let{manifest:o,routeModules:f}=xi(),[r,d]=g.useState([]);return g.useEffect(()=>{let y=!1;return fp(i,o,f).then(p=>{y||d(p)}),()=>{y=!0}},[i,o,f]),r}function Sp({page:i,matches:o,...f}){let r=Bt(),{future:d}=xi(),{basename:y}=or(),p=g.useMemo(()=>{if(i===r.pathname+r.search+r.hash)return[];let j=mm(i,y,d.v8_trailingSlashAwareDataRequests,"rsc"),S=!1,m=[];for(let C of o)typeof C.route.shouldRevalidate=="function"?S=!0:m.push(C.route.id);return S&&m.length>0&&j.searchParams.set("_routes",m.join(",")),[j.pathname+j.search]},[y,d.v8_trailingSlashAwareDataRequests,i,r,o]);return g.createElement(g.Fragment,null,p.map(j=>g.createElement("link",{key:j,rel:"prefetch",as:"fetch",href:j,...f})))}function xp({page:i,matches:o,...f}){let r=Bt(),{future:d,manifest:y,routeModules:p}=xi(),{basename:j}=or(),{loaderData:S,matches:m}=yp(),C=g.useMemo(()=>Lh(i,o,m,y,r,"data"),[i,o,m,y,r]),N=g.useMemo(()=>Lh(i,o,m,y,r,"assets"),[i,o,m,y,r]),_=g.useMemo(()=>{if(i===r.pathname+r.search+r.hash)return[];let q=new Set,G=!1;if(o.forEach(D=>{var Z;let k=y.routes[D.route.id];!k||!k.hasLoader||(!C.some(J=>J.route.id===D.route.id)&&D.route.id in S&&((Z=p[D.route.id])!=null&&Z.shouldRevalidate)||k.hasClientLoader?G=!0:q.add(D.route.id))}),q.size===0)return[];let M=mm(i,j,d.v8_trailingSlashAwareDataRequests,"data");return G&&q.size>0&&M.searchParams.set("_routes",o.filter(D=>q.has(D.route.id)).map(D=>D.route.id).join(",")),[M.pathname+M.search]},[j,d.v8_trailingSlashAwareDataRequests,S,r,y,C,o,i,p]),Y=g.useMemo(()=>dp(N,y),[N,y]),Q=bp(N);return g.createElement(g.Fragment,null,_.map(q=>g.createElement("link",{key:q,rel:"prefetch",as:"fetch",href:q,...f})),Y.map(q=>g.createElement("link",{key:q,rel:"modulepreload",href:q,...f})),Q.map(({key:q,link:G})=>g.createElement("link",{key:q,nonce:f.nonce,...G,crossOrigin:G.crossOrigin??f.crossOrigin})))}function Ep(...i){return o=>{i.forEach(f=>{typeof f=="function"?f(o):f!=null&&(f.current=o)})}}var jp=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{jp&&(window.__reactRouterVersion="7.18.0")}catch{}function Np({basename:i,children:o,useTransitions:f,window:r}){let d=g.useRef();d.current==null&&(d.current=lg({window:r,v5Compat:!0}));let y=d.current,[p,j]=g.useState({action:y.action,location:y.location}),S=g.useCallback(m=>{f===!1?j(m):g.startTransition(()=>j(m))},[f]);return g.useLayoutEffect(()=>y.listen(S),[y,S]),g.createElement(Pg,{basename:i,children:o,location:p.location,navigationType:p.action,navigator:y,useTransitions:f})}var fl=g.forwardRef(function({onClick:o,discover:f="render",prefetch:r="none",relative:d,reloadDocument:y,replace:p,mask:j,state:S,target:m,to:C,preventScrollReset:N,viewTransition:_,defaultShouldRevalidate:Y,...Q},q){let{basename:G,navigator:M,useTransitions:D}=g.useContext(Ot),k=typeof C=="string"&&nr.test(C),Z=am(C,G);C=Z.to;let J=Bg(C,{relative:d}),ie=Bt(),F=null;if(j){let De=ur(j,[],ie.mask?ie.mask.pathname:"/",!0);G!=="/"&&(De.pathname=De.pathname==="/"?G:wt([G,De.pathname])),F=M.createHref(De)}let[P,I,Re]=gp(r,Q),le=Rp(C,{replace:p,mask:j,state:S,target:m,preventScrollReset:N,relative:d,viewTransition:_,defaultShouldRevalidate:Y,useTransitions:D});function xe(De){o&&o(De),De.defaultPrevented||le(De)}let Ie=!(Z.isExternal||y),Ze=g.createElement("a",{...Q,...Re,href:(Ie?F:void 0)||Z.absoluteURL||J,onClick:Ie?xe:o,ref:Ep(q,I),target:m,"data-discover":!k&&f==="render"?"true":void 0});return P&&!k?g.createElement(g.Fragment,null,Ze,g.createElement(pp,{page:J})):Ze});fl.displayName="Link";var Cp=g.forwardRef(function({"aria-current":o="page",caseSensitive:f=!1,className:r="",end:d=!1,style:y,to:p,viewTransition:j,children:S,...m},C){let N=Kn(p,{relative:m.relative}),_=Bt(),Y=g.useContext(bi),{navigator:Q,basename:q}=g.useContext(Ot),G=Y!=null&&Mp(N)&&j===!0,M=Q.encodeLocation?Q.encodeLocation(N).pathname:N.pathname,D=_.pathname,k=Y&&Y.navigation&&Y.navigation.location?Y.navigation.location.pathname:null;f||(D=D.toLowerCase(),k=k?k.toLowerCase():null,M=M.toLowerCase()),k&&q&&(k=ol(k,q)||k);const Z=M!=="/"&&M.endsWith("/")?M.length-1:M.length;let J=D===M||!d&&D.startsWith(M)&&D.charAt(Z)==="/",ie=k!=null&&(k===M||!d&&k.startsWith(M)&&k.charAt(M.length)==="/"),F={isActive:J,isPending:ie,isTransitioning:G},P=J?o:void 0,I;typeof r=="function"?I=r(F):I=[r,J?"active":null,ie?"pending":null,G?"transitioning":null].filter(Boolean).join(" ");let Re=typeof y=="function"?y(F):y;return g.createElement(fl,{...m,"aria-current":P,className:I,ref:C,style:Re,to:p,viewTransition:j},typeof S=="function"?S(F):S)});Cp.displayName="NavLink";var Tp=g.forwardRef(({discover:i="render",fetcherKey:o,navigate:f,reloadDocument:r,replace:d,state:y,method:p=mi,action:j,onSubmit:S,relative:m,preventScrollReset:C,viewTransition:N,defaultShouldRevalidate:_,...Y},Q)=>{let{useTransitions:q}=g.useContext(Ot),G=Dp(),M=Op(j,{relative:m}),D=p.toLowerCase()==="get"?"get":"post",k=typeof j=="string"&&nr.test(j),Z=J=>{if(S&&S(J),J.defaultPrevented)return;J.preventDefault();let ie=J.nativeEvent.submitter,F=(ie==null?void 0:ie.getAttribute("formmethod"))||p,P=()=>G(ie||J.currentTarget,{fetcherKey:o,method:F,navigate:f,replace:d,state:y,relative:m,preventScrollReset:C,viewTransition:N,defaultShouldRevalidate:_});q&&f!==!1?g.startTransition(()=>P()):P()};return g.createElement("form",{ref:Q,method:D,action:M,onSubmit:r?S:Z,...Y,"data-discover":!k&&i==="render"?"true":void 0})});Tp.displayName="Form";function Ap(i){return`${i} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function vm(i){let o=g.useContext(Xa);return Me(o,Ap(i)),o}function Rp(i,{target:o,replace:f,mask:r,state:d,preventScrollReset:y,relative:p,viewTransition:j,defaultShouldRevalidate:S,useTransitions:m}={}){let C=om(),N=Bt(),_=Kn(i,{relative:p});return g.useCallback(Y=>{if(up(Y,o)){Y.preventDefault();let Q=f!==void 0?f:Xn(N)===Xn(_),q=()=>C(i,{replace:Q,mask:r,state:d,preventScrollReset:y,relative:p,viewTransition:j,defaultShouldRevalidate:S});m?g.startTransition(()=>q()):q()}},[N,C,_,f,r,d,o,i,y,p,j,S,m])}var zp=0,_p=()=>`__${String(++zp)}__`;function Dp(){let{router:i}=vm("useSubmit"),{basename:o}=g.useContext(Ot),f=$g(),r=i.fetch,d=i.navigate;return g.useCallback(async(y,p={})=>{let{action:j,method:S,encType:m,formData:C,body:N}=sp(y,o);if(p.navigate===!1){let _=p.fetcherKey||_p();await r(_,f,p.action||j,{defaultShouldRevalidate:p.defaultShouldRevalidate,preventScrollReset:p.preventScrollReset,formData:C,body:N,formMethod:p.method||S,formEncType:p.encType||m,flushSync:p.flushSync})}else await d(p.action||j,{defaultShouldRevalidate:p.defaultShouldRevalidate,preventScrollReset:p.preventScrollReset,formData:C,body:N,formMethod:p.method||S,formEncType:p.encType||m,replace:p.replace,state:p.state,fromRouteId:f,flushSync:p.flushSync,viewTransition:p.viewTransition})},[r,d,o,f])}function Op(i,{relative:o}={}){let{basename:f}=g.useContext(Ot),r=g.useContext(Xt);Me(r,"useFormAction must be used inside a RouteContext");let[d]=r.matches.slice(-1),y={...Kn(i||".",{relative:o})},p=Bt();if(i==null){y.search=p.search;let j=new URLSearchParams(y.search),S=j.getAll("index");if(S.some(C=>C==="")){j.delete("index"),S.filter(N=>N).forEach(N=>j.append("index",N));let C=j.toString();y.search=C?`?${C}`:""}}return(!i||i===".")&&d.route.index&&(y.search=y.search?y.search.replace(/^\?/,"?index&"):"?index"),f!=="/"&&(y.pathname=y.pathname==="/"?f:wt([f,y.pathname])),Xn(y)}function Mp(i,{relative:o}={}){let f=g.useContext(im);Me(f!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=vm("useViewTransitionState"),d=Kn(i,{relative:o});if(!f.isTransitioning)return!1;let y=ol(f.currentLocation.pathname,r)||f.currentLocation.pathname,p=ol(f.nextLocation.pathname,r)||f.nextLocation.pathname;return yi(d.pathname,p)!=null||yi(d.pathname,y)!=null}let rl=null,Gn=null;const Up=3e4,Hp=600*1e3;function wp(){return`${typeof window<"u"?window.location.origin:""}/admin/agent-token`}async function tr(){const i=Date.now();return rl&&rl.expiresAt-i>Up?rl.token:Gn||(Gn=Bp().finally(()=>{Gn=null}),Gn)}async function Bp(){let i;try{i=await fetch(wp(),{method:"GET",headers:{accept:"application/json"},credentials:"include"})}catch{return rl=null,null}if(!i.ok)return rl=null,null;let o;try{o=await i.json()}catch{return rl=null,null}if(!o.token)return rl=null,null;const f=o.expires_at?new Date(o.expires_at).getTime():Date.now()+Hp;return rl={token:o.token,expiresAt:f},o.token}function ym(){rl=null}class Dt extends Error{constructor(o,f){super(f),this.status=o,this.name="HttpError"}}function Qa(){const o="/agent/app/".match(/^(.*\/)app\/?$/);return o?`${o[1]}api`:"/agent/api"}async function dr(i,o={}){const f=await tr(),r=new Headers(o.headers);r.set("accept","application/json"),f&&r.set("authorization",`Bearer ${f}`);const d=await fetch(i,{...o,headers:r});if(d.status!==401)return d;ym();const y=await tr();if(!y)return d;const p=new Headers(o.headers);return p.set("accept","application/json"),p.set("authorization",`Bearer ${y}`),fetch(i,{...o,headers:p})}async function hr(i){try{return(await i.json()).error??""}catch{return await i.text().catch(()=>"")}}async function Qt(i){const o=await dr(`${Qa()}${i}`);if(!o.ok)throw new Dt(o.status,await hr(o)||`${i} failed: ${o.status}`);return await o.json()}async function Bl(i,o){return mr("POST",i,o)}async function Lp(i,o){return mr("PATCH",i,o)}async function Ei(i){const o=await dr(`${Qa()}${i}`,{method:"DELETE"});if(!o.ok)throw new Dt(o.status,await hr(o)||`${i} failed: ${o.status}`);return await o.json()}async function mr(i,o,f){const r=await dr(`${Qa()}${o}`,{method:i,headers:{"content-type":"application/json"},body:JSON.stringify(f)});if(!r.ok)throw new Dt(r.status,await hr(r)||`${o} failed: ${r.status}`);return await r.json()}function qp(i,o){return mr("DELETE",i,o)}function Yp(){return Qt("/agents")}function kp(){return Qt("/agent-defs")}function gm(){return Qt("/agent-vaults")}function Gp(i){return Bl("/agent-defs",i)}function Xp(i){return Qt(`/agent-defs/${encodeURIComponent(i)}`)}function pm(i,o){return Lp(`/agent-defs/${encodeURIComponent(i)}`,o)}function Qp(i){return Ei(`/agent-defs/${encodeURIComponent(i)}`)}function Vp(i){return Bl("/agent-vaults",i)}function Zp(i){return Ei(`/agent-vaults/${encodeURIComponent(i)}`)}const Kp=new Set(["ANTHROPIC_API_KEY","CLAUDE_API_KEY","CLAUDE_CODE_OAUTH_TOKEN"]),Jp=/^[A-Za-z_][A-Za-z0-9_]*$/;function $p(){return Qt("/credentials/env")}function Wp(i){return Bl("/credentials/env",i)}function Fp(i){return qp("/credentials/env",i)}function Ip(){return Qt("/credentials/claude")}function Pp(i){var f;const o=(f=i.channel)==null?void 0:f.trim();return o&&o.length>0?Bl(`/credentials/claude/${encodeURIComponent(o)}`,{token:i.token}):Bl("/credentials/claude",{token:i.token})}function e0(i){return Ei(`/credentials/claude/${encodeURIComponent(i)}`)}function t0(i){return Qt(`/agents/${encodeURIComponent(i)}/env`)}function l0(){return Qt("/jobs")}function a0(i){return Bl("/jobs",i)}function n0(i){return Bl(`/jobs/${encodeURIComponent(i)}/run`,{})}function u0(i){return Ei(`/jobs/${encodeURIComponent(i)}`)}function i0(i,o){const f=Qa().replace(/\/api$/,"");return`claude mcp add --transport http --scope user agent-${i} ${o}${f}/mcp/${i}`}function c0(){return Qt("/channels")}function qh(i){return Qt(`/channels/${encodeURIComponent(i)}/messages`)}function s0(i,o){return Bl(`/channels/${encodeURIComponent(i)}/send`,{text:o})}function r0(i,o){let r=`${Qa().replace(/\/api$/,"")}/ui/events?channel=${encodeURIComponent(i)}`;return o&&(r+=`&token=${encodeURIComponent(o)}`),r}function o0(i,o){let r=`${Qa().replace(/\/api$/,"")}/api/channels/${encodeURIComponent(i)}/turn-events`;return o&&(r+=`?token=${encodeURIComponent(o)}`),r}class Jn extends Error{constructor(o,f){super(f),this.status=o,this.name="HubError"}}function f0(){return typeof window<"u"?window.location.origin:""}function d0(){if(typeof window>"u")return!1;const{hostname:i,port:o}=window.location;return(i==="127.0.0.1"||i==="localhost"||i==="[::1]")&&o==="1941"}const vr="definition.reload",yr="note.created",gr="note.updated",h0="agent/definition";function lr(i,o){return`agentdefs-${o}-${i}`}function m0(i,o){return{id:lr(i,o),requestedBy:"agent",source:{module:"vault",vault:i,event:o==="create"?yr:gr,filter:{tags:[h0]}},sink:{module:"agent",action:vr}}}async function ji(i,o={}){const f=new Headers(o.headers);return f.set("accept","application/json"),fetch(`${f0()}${i}`,{...o,credentials:"include",headers:f})}function Qn(i,o){return i===401?"Not signed in to the hub portal — sign in, then retry.":i===403?"Not authorized — reactive reload needs host-admin access.":i===404?"Reactive reload needs the hub-proxied URL — open the agent app via your hub origin, not the loopback daemon.":o||`hub request failed (${i})`}async function Ni(i){try{const o=await i.json();return o.error_description??o.error??""}catch{return await i.text().catch(()=>"")}}async function Yh(){const i=await ji("/admin/connections");if(!i.ok)throw new Jn(i.status,Qn(i.status,await Ni(i)));return(await i.json()).connections??[]}function v0(i,o){const f=y=>o.some(p=>p.source.module==="vault"&&p.source.vault===i&&p.source.event===y&&p.sink.module==="agent"&&p.sink.action===vr),r=f(yr),d=f(gr);return{create:r,edit:d,active:r&&d}}async function kh(i){const o=["create","edit"],f=[];let r=0,d="";for(const y of o){const p=await ji("/admin/connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(m0(i,y))});if(!p.ok){const j=await Ni(p);r===0&&(r=p.status,d=j),f.push(`${y}: ${Qn(p.status,j)}`)}}if(f.length===o.length)throw new Jn(r,Qn(r,d||"provisioning failed"));return{ok:f.length===0,failures:f}}async function Gh(i,o,f){const r={};o!==void 0&&(r.token=o),f&&(r.returnTo=f);const d=await ji(`/admin/grants/${encodeURIComponent(i)}/approve`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)});if(!d.ok)throw new Jn(d.status,Qn(d.status,await Ni(d)));return await d.json()}async function Xh(i,o=[]){const f=new Set([lr(i,"create"),lr(i,"edit")]);for(const r of o)r.source.module==="vault"&&r.source.vault===i&&(r.source.event===yr||r.source.event===gr)&&r.sink.module==="agent"&&r.sink.action===vr&&f.add(r.id);for(const r of f){const d=await ji(`/admin/connections/${encodeURIComponent(r)}`,{method:"DELETE"});if(!d.ok&&d.status!==404)throw new Jn(d.status,Qn(d.status,await Ni(d)))}}const pr=[{value:"",label:"Default (Claude Code's default)"},{value:"opus",label:"Opus — most capable"},{value:"sonnet",label:"Sonnet — balanced"},{value:"haiku",label:"Haiku — fastest"}];function y0(i){var o;return i?((o=pr.find(f=>f.value===i))==null?void 0:o.label)??i:"Default"}function g0(i,o){const f=new Map;for(const r of i)f.set(r.name,{name:r.name,backend:r.backend,...r.channel?{channel:r.channel}:{},...r.vault?{vault:r.vault}:{},...r.status?{status:r.status}:{},live:!0});for(const r of o){const d=f.get(r.name);d?(d.def=r,d.mode=r.mode,!d.channel&&r.channel&&(d.channel=r.channel),!d.vault&&r.vault&&(d.vault=r.vault)):f.set(r.name,{name:r.name,backend:r.backend,channel:r.channel,vault:r.vault,status:r.status,mode:r.mode,live:!1,def:r})}return[...f.values()].sort((r,d)=>r.name.localeCompare(d.name))}function bm(i){return i==="programmatic"?"pill backend-programmatic":i==="channel"?"pill backend-channel":"pill"}function Sm(i){return i==="enabled"||i==="idle"?"pill status-enabled":i==="working"?"pill status-working":i==="pending"||i.startsWith("queued")?"pill status-queued":i==="error"?"pill status-error":"pill"}function Qh(){const[i,o]=g.useState({kind:"loading"}),[f,r]=g.useState(null),[d,y]=g.useState(!1),p=g.useCallback(async()=>{o({kind:"loading"});try{const[m,C,N]=await Promise.all([Yp(),kp(),gm()]);o({kind:"ok",agents:m.agents,defs:C.defs,vaults:N.vaults})}catch(m){const C=m instanceof Dt?m.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load agents: ${m.message}`:`Failed to load agents: ${m.message}`;o({kind:"error",message:C})}},[]);g.useEffect(()=>{p()},[p]),g.useEffect(()=>{const m=new URLSearchParams(window.location.search);if(m.get("mcp_connected")!=="1")return;y(!0),m.delete("mcp_connected");const C=m.toString();window.history.replaceState(null,"",window.location.pathname+(C?`?${C}`:"")+window.location.hash)},[]);const j=g.useMemo(()=>i.kind==="ok"?g0(i.agents,i.defs):[],[i]),S=g.useMemo(()=>j.find(m=>m.name===f)??null,[j,f]);return c.jsxs("div",{children:[c.jsx("h1",{children:"Agents"}),c.jsx("p",{className:"lede",children:"Every agent across all backends, in one place — programmatic and channel. Read-only for now; the create flow and def-vault editor land in later phases."}),i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void p(),children:"Retry"})]}):null,d?c.jsxs("div",{className:"success-banner",role:"status",children:["✓ MCP server connected — it'll be available to the agent on its next run."," ",c.jsx("button",{type:"button",className:"link",onClick:()=>y(!1),children:"Dismiss"})]}):null,i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading agents…"}):null,i.kind==="ok"?c.jsxs(c.Fragment,{children:[S?c.jsx(p0,{agent:S,onClose:()=>r(null),onChanged:()=>void p(),onDeleted:()=>{r(null),p()}}):null,c.jsxs("section",{className:"card","aria-label":"Agents",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"All agents"}),c.jsxs("span",{className:"section-head-actions",children:[c.jsxs("span",{className:"count","data-testid":"agents-count",children:[j.length," ",j.length===1?"agent":"agents"]}),c.jsx(fl,{to:"/create",className:"button-link","data-testid":"new-agent-link",children:"New agent"})]})]}),j.length===0?c.jsxs("div",{className:"empty",children:["No agents yet. Define one in a vault as an"," ",c.jsx("code",{children:"#agent/definition"})," note, or spawn one from the create flow (coming in a later phase)."]}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Backend"}),c.jsx("th",{children:"Channel"}),c.jsx("th",{children:"Status"}),c.jsx("th",{children:"Vault"})]})}),c.jsx("tbody",{children:j.map(m=>c.jsxs("tr",{className:`agent-row${f===m.name?" selected":""}`,"data-testid":`agent-row-${m.name}`,onClick:()=>r(f===m.name?null:m.name),children:[c.jsx("td",{className:"cell-name",children:m.name}),c.jsx("td",{children:c.jsx("span",{className:bm(m.backend),children:m.backend})}),c.jsx("td",{className:m.channel?"":"cell-dim",children:m.channel??"—"}),c.jsx("td",{children:m.status?c.jsx("span",{className:Sm(m.status),children:m.status}):m.live?c.jsx("span",{className:"cell-dim",children:"live"}):c.jsx("span",{className:"cell-dim",children:"not running"})}),c.jsx("td",{className:m.vault?"":"cell-dim",children:m.vault??"—"})]},m.name))})]})]}),c.jsx(M0,{}),c.jsx(U0,{vaults:i.vaults,onChanged:()=>void p()})]}):null]})}function p0({agent:i,onClose:o,onChanged:f,onDeleted:r}){const d=i.def,y=d==null?void 0:d.noteId,[p,j]=g.useState("view");return g.useEffect(()=>{j("view")},[i.name]),p==="edit"&&y?c.jsx(S0,{noteId:y,name:i.name,onCancel:()=>j("view"),onSaved:()=>{j("view"),f()}}):c.jsxs("div",{className:"detail","data-testid":"agent-detail",children:[c.jsxs("div",{className:"detail-head",children:[c.jsx("h2",{children:i.name}),c.jsx("span",{className:bm(i.backend),children:i.backend}),i.status?c.jsx("span",{className:Sm(i.status),children:i.status}):null,c.jsx("button",{type:"button",className:"detail-close",onClick:o,children:"Close"})]}),c.jsxs("dl",{className:"detail-grid",children:[c.jsx("dt",{children:"Backend"}),c.jsx("dd",{children:i.backend}),c.jsx("dt",{children:"Mode"}),c.jsx("dd",{"data-testid":"detail-mode",children:i.mode?b0(i.mode):"—"}),c.jsx("dt",{children:"Channel"}),c.jsx("dd",{children:i.channel??"—"}),c.jsx("dt",{children:"Vault"}),c.jsx("dd",{children:i.vault??"—"}),c.jsx("dt",{children:"Running"}),c.jsx("dd",{children:i.live?"yes":"no (defined, not instantiated)"}),d?c.jsxs(c.Fragment,{children:[c.jsx("dt",{children:"Model"}),c.jsx("dd",{"data-testid":"detail-model",children:y0(d.model)}),c.jsx("dt",{children:"Def status"}),c.jsx("dd",{children:d.status})]}):null]}),d?c.jsxs(c.Fragment,{children:[c.jsx("h3",{children:"System prompt"}),d.systemPromptPreview?c.jsx("p",{className:"detail-prompt","data-testid":"detail-prompt",children:d.systemPromptPreview}):c.jsx("p",{className:"dim",children:"No system prompt set (Claude Code's default)."}),c.jsx("h3",{children:"Wants"}),d.wants.length>0?c.jsx("div",{className:"tag-list",children:d.wants.map(S=>c.jsx("span",{className:"tag",children:S},S))}):c.jsx("p",{className:"dim",children:"Own-vault only — no extra connections requested."}),d.pending.length>0?c.jsxs(c.Fragment,{children:[c.jsx("h3",{children:"Pending approval"}),c.jsx("div",{className:"tag-list",children:d.pending.map(S=>c.jsx("span",{className:"tag",children:S},S))})]}):null,y?c.jsx(N0,{noteId:y,def:d,onChanged:f}):null]}):c.jsxs("p",{className:"dim","data-testid":"detail-no-def",children:["This agent isn't backed by a vault-native ",c.jsx("code",{children:"#agent/definition"})," note, so there's no system prompt or wants to show."]}),i.backend==="channel"?c.jsx("p",{className:"detail-note","data-testid":"detail-channel-note",children:'Channel backend — the queue depth and the "connect your Claude Code session" affordance arrive in a later phase.'}):null,i.channel?c.jsx(A0,{channel:i.channel}):null,i.channel?c.jsx(O0,{channel:i.channel,backend:i.backend}):null,i.channel?c.jsx(D0,{name:i.name}):null,y?p==="delete"?c.jsx(x0,{noteId:y,name:i.name,onCancel:()=>j("view"),onDeleted:r}):c.jsxs("div",{className:"detail-actions","data-testid":"detail-actions",children:[c.jsx("button",{type:"button",className:"secondary","data-testid":"edit-agent",onClick:()=>j("edit"),children:"Edit"}),c.jsx("button",{type:"button",className:"button-danger","data-testid":"delete-agent",onClick:()=>j("delete"),children:"Delete"})]}):null]})}function b0(i){return i==="single-threaded"?"Single-threaded":"Multi-threaded"}function S0({noteId:i,name:o,onCancel:f,onSaved:r}){const[d,y]=g.useState({kind:"loading"}),[p,j]=g.useState(""),[S,m]=g.useState("single-threaded"),[C,N]=g.useState(""),[_,Y]=g.useState(""),[Q,q]=g.useState(!1),[G,M]=g.useState(null),D=g.useCallback(async()=>{y({kind:"loading"});try{const J=(await Xp(i)).def;j(J.systemPrompt),m(J.mode),N(J.model??""),Y(J.wants.join(", ")),y({kind:"ready",systemPrompt:J.systemPrompt,mode:J.mode,wants:J.wants.join(", ")})}catch(Z){const J=Z instanceof Dt?Z.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load the def: ${Z.message}`:`Failed to load the def: ${Z.message}`;y({kind:"error",message:J})}},[i]);g.useEffect(()=>{D()},[D]);async function k(Z){if(Z.preventDefault(),!Q){q(!0),M(null);try{await pm(i,{systemPrompt:p,metadata:{mode:S,model:C},wants:_.trim()}),r()}catch(J){const ie=J instanceof Dt&&J.status===401?"Not signed in to the hub — sign in to the portal, then reload.":J.message;M(ie)}finally{q(!1)}}}return c.jsxs("div",{className:"detail","data-testid":"edit-agent-form",children:[c.jsxs("div",{className:"detail-head",children:[c.jsxs("h2",{children:["Edit ",o]}),c.jsx("button",{type:"button",className:"detail-close",onClick:f,children:"Close"})]}),d.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading def…"}):null,d.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"edit-load-error",children:[d.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void D(),children:"Retry"})]}):null,d.kind==="ready"?c.jsxs("form",{className:"card",onSubmit:k,"aria-label":"Edit agent",children:[G?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"edit-error",children:G}):null,c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Mode"}),c.jsx(pi,{name:"edit-mode",value:"single-threaded",checked:S==="single-threaded",onChange:()=>m("single-threaded"),label:"Single-threaded",help:"One continuous conversation — remembers everything on this channel.",testid:"edit-mode-single-threaded"}),c.jsx(pi,{name:"edit-mode",value:"multi-threaded",checked:S==="multi-threaded",onChange:()=>m("multi-threaded"),label:"Multi-threaded",help:"Each run is its own thread — good for scheduled or stateless tasks.",testid:"edit-mode-multi-threaded"})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-model",children:"Model"}),c.jsx("select",{id:"edit-model",value:C,"data-testid":"edit-model",onChange:Z=>N(Z.target.value),children:pr.map(Z=>c.jsx("option",{value:Z.value,children:Z.label},Z.value))}),c.jsx("p",{className:"field-hint",children:"Which model Parachute runs this agent on (programmatic backend). A channel-backend agent uses whatever model your own session runs."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-prompt",children:"System prompt"}),c.jsx("textarea",{id:"edit-prompt",rows:8,value:p,placeholder:"You are…",onChange:Z=>j(Z.target.value)}),c.jsx("p",{className:"field-hint",children:"The agent's persona + instructions (the note body). Leave blank for Claude Code's default."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"edit-wants",children:"Wants (connections)"}),c.jsx("input",{id:"edit-wants",type:"text",value:_,placeholder:"vault:other, service:github",autoComplete:"off",onChange:Z=>Y(Z.target.value)}),c.jsx("p",{className:"field-hint",children:"Comma-separated connection keys the agent requests beyond its own vault. Each needs approval before it's granted."})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:Q,children:Q?"Saving…":"Save changes"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]}):null]})}function x0({noteId:i,name:o,onCancel:f,onDeleted:r}){const[d,y]=g.useState(""),[p,j]=g.useState(!1),[S,m]=g.useState(null),C=d===o&&!p;async function N(){if(C){j(!0),m(null);try{await Qp(i),r()}catch(_){const Y=_ instanceof Dt&&_.status===401?"Not signed in to the hub — sign in to the portal, then reload.":_.message;m(Y),j(!1)}}}return c.jsxs("div",{className:"confirm-box","data-testid":"delete-confirm",children:[c.jsxs("p",{className:"confirm-prompt",children:["Delete ",c.jsx("strong",{children:o}),"? This removes the definition note and deregisters the agent. Type the agent name to confirm."]}),S?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"delete-error",children:S}):null,c.jsx("div",{className:"field",children:c.jsx("input",{type:"text",value:d,placeholder:o,autoComplete:"off","aria-label":"Type the agent name to confirm deletion","data-testid":"delete-confirm-input",onChange:_=>y(_.target.value)})}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":"delete-confirm-button",disabled:!C,onClick:()=>void N(),children:p?"Deleting…":"Delete agent"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]})}function E0({status:i}){return i==="approved"?c.jsx("span",{className:"pill status-enabled","data-testid":"conn-status-approved",children:"Connected"}):i==="needs_consent"?c.jsx("span",{className:"pill status-error","data-testid":"conn-status-needs_consent",children:"Needs reconnect"}):i==="revoked"?c.jsx("span",{className:"pill status-error","data-testid":"conn-status-revoked",children:"Revoked"}):c.jsx("span",{className:"pill status-pending","data-testid":"conn-status-pending",children:"Pending"})}function j0(i){if(i.connections&&i.connections.length>0)return i.connections.filter(f=>f.kind==="mcp");const o=new Set(i.pending);return i.wants.filter(f=>f.startsWith("mcp:")&&/^mcp:https?:\/\//i.test(f)).map(f=>({key:f,kind:"mcp",target:f.slice(4),status:o.has(f)?"pending":"approved"}))}function N0({noteId:i,def:o,onChanged:f}){const[r,d]=g.useState(!1),[y,p]=g.useState(null),[j,S]=g.useState(null),[m,C]=g.useState(""),[N,_]=g.useState(null),Y=j0(o),Q=d0();async function q(M){p(M),_(null);try{const D=window.location.pathname+window.location.search+window.location.hash,k=await Gh(M,void 0,D);if(k.authorizeUrl){window.location.assign(k.authorizeUrl);return}f()}catch(D){_(Vh(D))}finally{p(null)}}async function G(M){const D=m.trim();if(D.length!==0){p(M),_(null);try{await Gh(M,D),S(null),C(""),f()}catch(k){_(Vh(k))}finally{p(null)}}}return c.jsxs("section",{className:"detail-section","aria-label":"Connections","data-testid":"connections-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Connections / MCP servers"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-mcp-toggle",onClick:()=>{d(M=>!M),_(null)},children:r?"Cancel":"Add MCP server"})]}),c.jsx("p",{className:"muted",children:"Remote MCP servers this agent can reach. Add one, then connect it via OAuth (or paste a static bearer). Each connection is operator-approved before it's granted."}),Q?c.jsx("div",{className:"info-banner",role:"status","data-testid":"connections-daemon-direct",children:"Open this surface via your hub to connect MCP servers — the OAuth/approve step needs the hub origin (you're on the loopback daemon)."}):null,r?c.jsx(C0,{noteId:i,def:o,onCancel:()=>d(!1),onAdded:()=>{d(!1),f()}}):null,N?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"connections-row-error",children:N}):null,Y.length===0?c.jsx("div",{className:"empty","data-testid":"connections-empty",children:"No MCP servers connected to this agent yet."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"MCP server"}),c.jsx("th",{children:"Status"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:Y.map(M=>{const D=M.status!=="approved",k=D&&!!M.grantId&&!Q;return c.jsxs("tr",{"data-testid":`connection-row-${M.target}`,children:[c.jsx("td",{className:"cell-name",children:c.jsx("code",{children:M.target})}),c.jsx("td",{children:c.jsx(E0,{status:M.status})}),c.jsx("td",{children:D?j===M.grantId?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("input",{type:"password",value:m,placeholder:"bearer token",autoComplete:"off",spellCheck:!1,"aria-label":"Static bearer token","data-testid":`paste-token-input-${M.target}`,onChange:Z=>C(Z.target.value)}),c.jsx("button",{type:"button",disabled:y===M.grantId||m.trim().length===0,"data-testid":`paste-token-save-${M.target}`,onClick:()=>void G(M.grantId),children:y===M.grantId?"Saving…":"Save"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>{S(null),C("")},children:"Cancel"})]}):c.jsxs("span",{className:"schedule-row-actions",children:[c.jsx("button",{type:"button",disabled:!k||y===M.grantId,"data-testid":`connect-${M.target}`,title:Q?"Open the agent app via your hub origin to connect.":M.grantId?void 0:"No grant registered yet — reload after the daemon registers it.",onClick:()=>void q(M.grantId),children:y===M.grantId?"Connecting…":M.status==="needs_consent"?"Reconnect":"Connect"}),M.grantId&&!Q?c.jsx("button",{type:"button",className:"cancel-link","data-testid":`paste-token-${M.target}`,onClick:()=>{_(null),C(""),S(M.grantId)},children:"Paste token"}):null]}):c.jsx("span",{className:"cell-dim",children:"—"})})]},M.key)})})]})]})}function Vh(i){return i instanceof Jn,i.message}function C0({noteId:i,def:o,onCancel:f,onAdded:r}){const[d,y]=g.useState(""),[p,j]=g.useState("oauth"),[S,m]=g.useState(!1),[C,N]=g.useState(null),_=d.trim(),Y=/^https?:\/\/.+/i.test(_)&&T0(_),Q=o.wants.includes(`mcp:${_}`),q=Y&&!Q&&!S;async function G(M){if(M.preventDefault(),!!q){m(!0),N(null);try{const D=[...o.wants,`mcp:${_}`].join(", ");await pm(i,{wants:D}),r()}catch(D){const k=D instanceof Dt&&D.status===401?"Not signed in to the hub — sign in to the portal, then reload.":D.message;N(k)}finally{m(!1)}}}return c.jsxs("form",{className:"inline-form",onSubmit:G,"aria-label":"Add MCP server","data-testid":"add-mcp-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-mcp-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"mcp-url",children:"MCP server URL"}),c.jsx("input",{id:"mcp-url",type:"text",value:d,placeholder:"https://mcp.example.com/mcp",autoComplete:"off",spellCheck:!1,onChange:M=>y(M.target.value)}),_.length>0&&!Y?c.jsx("p",{className:"field-error","data-testid":"mcp-url-invalid",children:"Must be a full http(s) URL."}):null,Q?c.jsx("p",{className:"field-error","data-testid":"mcp-url-duplicate",children:"This MCP server is already connected to the agent."}):null]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Authentication"}),c.jsx("p",{className:"muted",children:"You'll enter credentials in the next step — on the connection's row after it's added."}),c.jsx(pi,{name:"mcp-auth",value:"oauth",checked:p==="oauth",onChange:()=>j("oauth"),label:"OAuth",help:"Sign in to the MCP server in your browser (recommended). Connect on the row after adding.",testid:"mcp-auth-oauth"}),c.jsx(pi,{name:"mcp-auth",value:"token",checked:p==="token",onChange:()=>j("token"),label:"Paste a token",help:"For an MCP server with a static bearer token. Paste it on the row's “Paste token” after adding.",testid:"mcp-auth-token"})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!q,"data-testid":"add-mcp-submit",children:S?"Adding…":"Add MCP server"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:f,children:"Cancel"})]})]})}function T0(i){try{return new URL(i),!0}catch{return!1}}function A0({channel:i}){const[o,f]=g.useState({kind:"loading"}),[r,d]=g.useState(!1),[y,p]=g.useState(null),[j,S]=g.useState(null),[m,C]=g.useState(null),[N,_]=g.useState(null),[Y,Q]=g.useState(null),q=g.useCallback(async()=>{f({kind:"loading"});try{const k=(await l0()).jobs.filter(Z=>Z.channel===i);f({kind:"ok",jobs:k})}catch(D){f({kind:"error",message:at(D)})}},[i]);g.useEffect(()=>{q()},[q]);async function G(D){p(D),_(null),Q(null);try{const k=await n0(D);Q(`Ran ${D} (${k.status}).`),await q()}catch(k){_(`Run failed: ${at(k)}`)}finally{p(null)}}async function M(D){C(D),_(null);try{await u0(D),S(null),await q()}catch(k){_(at(k))}finally{C(null)}}return c.jsxs("section",{className:"schedules","aria-label":"Schedules","data-testid":"schedules-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Schedules"}),c.jsx("span",{className:"section-head-actions",children:c.jsx("button",{type:"button",className:"secondary","data-testid":"add-schedule-toggle",onClick:()=>d(D=>!D),children:r?"Cancel":"New schedule"})})]}),c.jsx("p",{className:"muted",children:"Send this agent a message on a cron schedule. The runner writes the message as an inbound note; the agent runs its turn as if you typed it."}),r?c.jsx(z0,{channel:i,onCancel:()=>d(!1),onCreated:()=>{d(!1),q()}}):null,Y?c.jsx("p",{className:"schedule-status","data-testid":"schedule-row-status",children:Y}):null,N?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"schedule-row-error",children:N}):null,o.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading schedules…"}):null,o.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"schedules-error",children:[o.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void q(),children:"Retry"})]}):null,o.kind==="ok"?o.jobs.length===0?c.jsx("div",{className:"empty","data-testid":"schedules-empty",children:"No schedules yet for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Id"}),c.jsx("th",{children:"Cron"}),c.jsx("th",{children:"Next run"}),c.jsx("th",{children:"Last status"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:o.jobs.map(D=>c.jsxs("tr",{"data-testid":`schedule-row-${D.id}`,children:[c.jsxs("td",{className:"cell-name",children:[c.jsx("code",{children:D.id}),D.enabled?null:c.jsx("span",{className:"cell-dim",children:" (disabled)"})]}),c.jsxs("td",{children:[c.jsx("code",{children:D.schedule.cron}),D.schedule.tz?c.jsxs("span",{className:"cell-dim",children:[" ",D.schedule.tz]}):null]}),c.jsx("td",{className:D.nextRunAt?"":"cell-dim",children:Zh(D.nextRunAt)}),c.jsxs("td",{children:[D.lastStatus?c.jsx("span",{className:D.lastStatus.startsWith("error")?"pill status-error":"pill status-enabled",children:D.lastStatus}):c.jsx("span",{className:"cell-dim",children:"—"}),D.lastRunAt?c.jsxs("span",{className:"cell-dim",children:[" ",Zh(D.lastRunAt)]}):null]}),c.jsx("td",{children:j===D.id?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`schedule-delete-confirm-${D.id}`,disabled:m===D.id,onClick:()=>void M(D.id),children:m===D.id?"Deleting…":"Confirm delete"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>S(null),children:"Cancel"})]}):c.jsxs("span",{className:"schedule-row-actions",children:[c.jsx("button",{type:"button",className:"secondary","data-testid":`schedule-run-${D.id}`,disabled:y===D.id,onClick:()=>void G(D.id),children:y===D.id?"Running…":"Run now"}),c.jsx("button",{type:"button",className:"button-danger","data-testid":`schedule-delete-${D.id}`,onClick:()=>{_(null),S(D.id)},children:"Delete"})]})})]},D.id))})]}):null]})}const R0=[{label:"daily 8am",cron:"0 8 * * *"},{label:"hourly",cron:"0 * * * *"},{label:"every 15m",cron:"*/15 * * * *"},{label:"weekdays 9am",cron:"0 9 * * 1-5"},{label:"weekly Mon 8am",cron:"0 8 * * 1"}];function z0({channel:i,onCancel:o,onCreated:f}){const[r,d]=g.useState(""),[y,p]=g.useState(""),[j,S]=g.useState(""),[m,C]=g.useState(""),[N,_]=g.useState(!1),[Y,Q]=g.useState(null),q=/^[a-zA-Z0-9_-]+$/.test(r),G=q&&y.trim().length>0&&j.trim().length>0&&!N;async function M(D){if(D.preventDefault(),!!G){_(!0),Q(null);try{await a0({id:r,channel:i,message:y.trim(),schedule:{cron:j.trim(),...m.trim()?{tz:m.trim()}:{}},enabled:!0}),f()}catch(k){Q(at(k))}finally{_(!1)}}}return c.jsxs("form",{className:"inline-form",onSubmit:M,"aria-label":"New schedule","data-testid":"schedule-form",children:[Y?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"schedule-form-error",children:Y}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-id",children:"Job id (slug)"}),c.jsx("input",{id:"schedule-id",type:"text",value:r,placeholder:"morning-standup",autoComplete:"off",onChange:D=>d(D.target.value)}),r.length>0&&!q?c.jsx("p",{className:"field-error","data-testid":"schedule-id-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-message",children:"Message to send"}),c.jsx("textarea",{id:"schedule-message",rows:3,value:y,placeholder:"Run the morning weave…",onChange:D=>p(D.target.value)})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-cron",children:"Cron (min hour dom mon dow)"}),c.jsx("input",{id:"schedule-cron",type:"text",value:j,placeholder:"0 8 * * *",autoComplete:"off",onChange:D=>S(D.target.value)}),c.jsx("div",{className:"schedule-presets",children:R0.map(D=>c.jsx("button",{type:"button",className:"secondary",onClick:()=>S(D.cron),children:D.label},D.cron))})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"schedule-tz",children:"Timezone (IANA, optional)"}),c.jsx("input",{id:"schedule-tz",type:"text",value:m,placeholder:"America/Los_Angeles",autoComplete:"off",onChange:D=>C(D.target.value)}),c.jsx("p",{className:"field-hint",children:"Leave blank to use the daemon's local timezone."})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!G,children:N?"Scheduling…":"Create schedule"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:o,children:"Cancel"})]})]})}function Zh(i){if(!i)return"—";try{return new Date(i).toLocaleString()}catch{return i}}function pi(i){return c.jsxs("label",{className:`radio-row${i.checked?" selected":""}`,"data-testid":i.testid,children:[c.jsx("input",{type:"radio",name:i.name,value:i.value,checked:i.checked,onChange:i.onChange}),c.jsxs("span",{className:"radio-body",children:[c.jsx("span",{className:"radio-label",children:i.label}),c.jsx("span",{className:"radio-help",children:i.help})]})]})}function _0(i){return i==="channel"?"pill backend-channel":i.startsWith("grant:")?"pill backend-programmatic":"pill"}function D0({name:i}){const[o,f]=g.useState({kind:"loading"}),r=g.useCallback(async()=>{f({kind:"loading"});try{const d=await t0(i);f({kind:"ok",env:d.env,...d.note?{note:d.note}:{}})}catch(d){f({kind:"error",message:at(d)})}},[i]);return g.useEffect(()=>{r()},[r]),c.jsxs("section",{className:"detail-section","aria-label":"Effective env","data-testid":"effective-env-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Effective env"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"effective-env-refresh",onClick:()=>void r(),children:"Refresh"})]}),c.jsxs("p",{className:"muted",children:["The env-var ",c.jsx("strong",{children:"names"})," this agent's sandboxed turn runs with, resolved across the operator default, this agent's override, and approved-grant service env."," ",c.jsx("strong",{children:"Names only"})," — values are never shown. Precedence: channel > default > grant."]}),o.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading effective env…"}):null,o.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"effective-env-error",children:[o.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void r(),children:"Retry"})]}):null,o.kind==="ok"?c.jsxs(c.Fragment,{children:[o.note?c.jsx("p",{className:"muted","data-testid":"effective-env-note",children:o.note}):null,o.env.length===0?c.jsx("div",{className:"empty","data-testid":"effective-env-empty",children:"No env vars resolved for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Source"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:o.env.map((d,y)=>c.jsxs("tr",{className:d.overridden?"cell-dim":"","data-testid":`effective-env-${d.name}-${d.source}`,children:[c.jsx("td",{className:"cell-name",children:d.name}),c.jsx("td",{children:c.jsx("span",{className:_0(d.source),children:d.source})}),c.jsx("td",{children:d.overridden?c.jsx("span",{className:"cell-dim","data-testid":`effective-env-overridden-${d.name}-${d.source}`,children:"overridden"}):null})]},`${d.name}-${d.source}-${y}`))})]})]}):null]})}function O0({channel:i,backend:o}){const[f,r]=g.useState({kind:"loading"}),[d,y]=g.useState(!1),[p,j]=g.useState(""),[S,m]=g.useState(""),[C,N]=g.useState(!1),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),Z=g.useCallback(async()=>{r({kind:"loading"});try{const le=await $p();r({kind:"ok",names:(le.channels[i]??[]).slice().sort()})}catch(le){r({kind:"error",message:at(le)})}},[i]);g.useEffect(()=>{Z()},[Z]);const J=p.trim(),ie=Kp.has(J),F=J.length===0||Jp.test(J),P=J.length>0&&F&&!ie&&S.length>0&&!C;async function I(le){if(le.preventDefault(),!!P){N(!0),Y(null);try{await Wp({channel:i,name:J,value:S}),j(""),m(""),y(!1),await Z()}catch(xe){Y(at(xe))}finally{N(!1)}}}async function Re(le){M(le),k(null);try{await Fp({channel:i,name:le}),q(null),await Z()}catch(xe){k(at(xe))}finally{M(null)}}return c.jsxs("section",{className:"detail-section","aria-label":"Secrets","data-testid":"secrets-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h3",{children:"Secrets (env vars)"}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-secret-toggle",onClick:()=>{y(le=>!le),Y(null)},children:d?"Cancel":"Add secret"})]}),c.jsxs("p",{className:"muted",children:["Local env vars (e.g. ",c.jsx("code",{children:"GH_TOKEN"}),") injected into this agent's sandboxed turns — stored 0600 on this machine, ",c.jsx("strong",{children:"never in the vault"}),". Values are write-only: they're never shown again.",o==="channel"?c.jsxs(c.Fragment,{children:[" ","This agent uses the ",c.jsx("strong",{children:"channel"})," backend, so it runs in your own Claude Code session with your own environment — these vars apply only to programmatic turns."]}):null]}),d?c.jsxs("form",{className:"inline-form",onSubmit:I,"aria-label":"Add secret","aria-busy":C,"data-testid":"add-secret-form",children:[_?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-secret-error",children:_}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"secret-name",children:"Name"}),c.jsx("input",{id:"secret-name",type:"text",value:p,placeholder:"GH_TOKEN",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:le=>j(le.target.value)}),J.length>0&&!F?c.jsx("p",{className:"field-error","data-testid":"secret-name-invalid",children:"A valid env var name — letters, numbers, underscore; not starting with a digit."}):null,ie?c.jsxs("p",{className:"field-error","data-testid":"secret-name-denylisted",children:["Reserved — ",J," would hijack the agent's managed billing/auth."]}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"secret-value",children:"Value"}),c.jsx("input",{id:"secret-value",type:"password",value:S,placeholder:"ghp_…",autoComplete:"off",spellCheck:!1,onChange:le=>m(le.target.value)}),c.jsx("p",{className:"field-hint",children:"Stored 0600 on disk (access-controlled, not encrypted). Write-only — never re-displayed."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!P,children:C?"Saving…":"Save secret"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"secret-row-error",children:D}):null,f.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading secrets…"}):null,f.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"secrets-load-error",children:[f.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void Z(),children:"Retry"})]}):null,f.kind==="ok"?f.names.length===0?c.jsx("div",{className:"empty","data-testid":"secrets-empty",children:"No secrets set for this agent."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Name"}),c.jsx("th",{children:"Value"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:f.names.map(le=>c.jsxs("tr",{"data-testid":`secret-${le}`,children:[c.jsx("td",{className:"cell-name",children:le}),c.jsx("td",{className:"cell-dim",children:"••••••••"}),c.jsx("td",{children:Q===le?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`secret-remove-confirm-${le}`,disabled:G===le,onClick:()=>void Re(le),children:G===le?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`secret-remove-${le}`,onClick:()=>{k(null),q(le)},children:"Remove"})})]},le))})]}):null]})}function M0(){const[i,o]=g.useState({kind:"loading"}),[f,r]=g.useState(!1),[d,y]=g.useState(""),[p,j]=g.useState(""),[S,m]=g.useState(!1),[C,N]=g.useState(null),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),Z=g.useCallback(async()=>{o({kind:"loading"});try{const I=await Ip();o({kind:"ok",status:I})}catch(I){o({kind:"error",message:at(I)})}},[]);g.useEffect(()=>{Z()},[Z]);const J=p.trim(),ie=d.length>0&&!S;async function F(I){if(I.preventDefault(),!!ie){m(!0),N(null),Y(null);try{await Pp({token:d,...J.length>0?{channel:J}:{}}),y(""),j(""),r(!1),Y(J.length>0?`Saved a Claude token override for "${J}".`:"Saved the default Claude token."),await Z()}catch(Re){N(at(Re))}finally{m(!1)}}}async function P(I){M(I),k(null);try{await e0(I),q(null),await Z()}catch(Re){k(at(Re))}finally{M(null)}}return c.jsxs("section",{className:"card","aria-label":"Claude auth","data-testid":"claude-auth-section",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"Claude auth"}),c.jsxs("span",{className:"section-head-actions",children:[i.kind==="ok"?i.status.defaultSet?c.jsx("span",{className:"pill status-enabled","data-testid":"claude-default-configured",children:"configured"}):c.jsx("span",{className:"pill status-error","data-testid":"claude-default-missing",children:"not configured"}):null,c.jsx("button",{type:"button",className:"secondary","data-testid":"set-claude-token-toggle",onClick:()=>{r(I=>(I&&(y(""),j("")),!I)),N(null),Y(null)},children:f?"Cancel":"Set token"})]})]}),c.jsxs("p",{className:"muted",children:["The token from ",c.jsx("code",{children:"claude setup-token"})," that the daemon runs each agent turn on. It's stored locally (",c.jsx("code",{children:"credentials.json"}),", 0600) and used to run turns on your ",c.jsx("strong",{children:"Claude subscription"})," — ",c.jsx("strong",{children:"not"})," API billing. It's write-only: the value is never shown again. Set a ",c.jsx("strong",{children:"default"})," token (used by every agent) or a per-",c.jsx("strong",{children:"channel"})," override."]}),_?c.jsx("div",{className:"info-banner",role:"status","data-testid":"claude-saved-notice",children:_}):null,f?c.jsxs("form",{className:"inline-form",onSubmit:F,"aria-label":"Set Claude token","aria-busy":S,"data-testid":"set-claude-token-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"set-claude-token-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"claude-token",children:"Token"}),c.jsx("input",{id:"claude-token",type:"password",value:d,placeholder:"paste the output of `claude setup-token`",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:I=>y(I.target.value)}),c.jsxs("p",{className:"field-hint",children:["Run ",c.jsx("code",{children:"claude setup-token"})," on a machine where you're signed in, then paste it here. Stored 0600 on disk (access-controlled, not encrypted). Write-only — never re-displayed."]})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"claude-channel",children:"Channel (optional)"}),c.jsx("input",{id:"claude-channel",type:"text",value:p,placeholder:"leave blank for the default (operator) token",autoComplete:"off",autoCapitalize:"off",spellCheck:!1,onChange:I=>j(I.target.value)}),c.jsx("p",{className:"field-hint",children:"A channel name to override just that agent; blank sets the default token every agent falls back to."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!ie,children:S?"Saving…":"Save token"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"claude-row-error",children:D}):null,i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading Claude auth…"}):null,i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"claude-auth-load-error",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void Z(),children:"Retry"})]}):null,i.kind==="ok"?c.jsxs(c.Fragment,{children:[i.status.defaultSet?null:c.jsx("div",{className:"empty","data-testid":"claude-default-empty",children:"No default Claude token set — programmatic agents can't run turns until one is set (or a per-channel override covers them)."}),i.status.channels.length>0?c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Channel override"}),c.jsx("th",{children:"Token"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:i.status.channels.map(I=>c.jsxs("tr",{"data-testid":`claude-override-${I}`,children:[c.jsx("td",{className:"cell-name",children:I}),c.jsx("td",{className:"cell-dim",children:"••••••••"}),c.jsx("td",{children:Q===I?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`claude-override-remove-confirm-${I}`,disabled:G===I,onClick:()=>void P(I),children:G===I?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`claude-override-remove-${I}`,onClick:()=>{k(null),q(I)},children:"Remove"})})]},I))})]}):null]}):null]})}function U0({vaults:i,onChanged:o}){const[f,r]=g.useState(!1),[d,y]=g.useState(""),[p,j]=g.useState(""),[S,m]=g.useState(!1),[C,N]=g.useState(null),[_,Y]=g.useState(null),[Q,q]=g.useState(null),[G,M]=g.useState(null),[D,k]=g.useState(null),[Z,J]=g.useState([]),[ie,F]=g.useState(!1),[P,I]=g.useState(null),[Re,le]=g.useState(null),xe=g.useCallback(async()=>{try{const X=await Yh();J(X),F(!0)}catch{F(!1)}},[]);g.useEffect(()=>{xe()},[xe]);const Ie=/^[a-zA-Z0-9_-]+$/.test(d),Ze=Ie&&!S;async function De(X){if(X.preventDefault(),!Ze)return;m(!0),N(null),Y(null);const ne=d;try{await Vp({vault:ne,...p.trim().length>0?{url:p.trim()}:{}}),y(""),j(""),r(!1),o();try{const{ok:oe}=await kh(ne);Y(oe?`Added "${ne}" — reactive reload is on (def changes apply instantly).`:`Added "${ne}" — reactive reload partially wired; defs still converge within 60s.`)}catch(oe){Y(`Added "${ne}". Reactive reload couldn't be enabled (${at(oe)}) — def changes converge within 60s; you can enable it below.`)}await xe()}catch(oe){N(at(oe))}finally{m(!1)}}async function U(X){M(X),k(null);try{await Zp(X);try{const ne=await Yh().catch(()=>Z);await Xh(X,ne)}catch{}q(null),o(),await xe()}catch(ne){k(at(ne))}finally{M(null)}}async function V(X,ne){I(X),le(null);try{ne?await Xh(X,Z):await kh(X),await xe()}catch(oe){le(at(oe))}finally{I(null)}}return c.jsxs("section",{className:"card","aria-label":"Def-vaults",children:[c.jsxs("div",{className:"section-head",children:[c.jsx("h2",{children:"Def-vaults"}),c.jsxs("span",{className:"section-head-actions",children:[c.jsx("span",{className:"count",children:i.length}),c.jsx("button",{type:"button",className:"secondary","data-testid":"add-def-vault-toggle",onClick:()=>r(X=>!X),children:f?"Cancel":"Add def-vault"})]})]}),c.jsxs("p",{className:"muted",children:["Vaults this module reads ",c.jsx("code",{children:"#agent/definition"})," notes from. Removing one deregisters every agent defined in it. ",c.jsx("strong",{children:"Reactive reload"})," wires a vault trigger so def changes apply instantly instead of waiting up to 60s."]}),_?c.jsx("div",{className:"info-banner",role:"status","data-testid":"add-def-vault-notice",children:_}):null,Re?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"reactive-reload-error",children:Re}):null,f?c.jsxs("form",{className:"inline-form",onSubmit:De,"aria-label":"Add def-vault","data-testid":"add-def-vault-form",children:[C?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"add-def-vault-error",children:C}):null,c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"new-vault-name",children:"Vault name"}),c.jsx("input",{id:"new-vault-name",type:"text",value:d,placeholder:"research",autoComplete:"off",onChange:X=>y(X.target.value)}),d.length>0&&!Ie?c.jsx("p",{className:"field-error","data-testid":"new-vault-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"new-vault-url",children:"Vault URL (optional)"}),c.jsx("input",{id:"new-vault-url",type:"text",value:p,placeholder:"http://127.0.0.1:1940",autoComplete:"off",onChange:X=>j(X.target.value)}),c.jsx("p",{className:"field-hint",children:"The vault REST origin. Defaults to the loopback vault."})]}),c.jsx("div",{className:"form-actions",children:c.jsx("button",{type:"submit",disabled:!Ze,children:S?"Adding…":"Add def-vault"})})]}):null,D?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"remove-def-vault-error",children:D}):null,i.length===0?c.jsx("div",{className:"empty","data-testid":"def-vaults-empty",children:"No def-vaults configured yet."}):c.jsxs("table",{children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Vault"}),c.jsx("th",{children:"URL"}),c.jsx("th",{children:"Token"}),c.jsx("th",{children:"Reactive reload"}),c.jsx("th",{})]})}),c.jsx("tbody",{children:i.map(X=>{const ne=v0(X.vault,Z);return c.jsxs("tr",{"data-testid":`def-vault-${X.vault}`,children:[c.jsx("td",{className:"cell-name",children:X.vault}),c.jsx("td",{className:"cell-dim",children:X.url}),c.jsx("td",{children:X.tokenPresent?c.jsx("span",{className:"pill status-enabled",children:"present"}):c.jsx("span",{className:"pill status-error",children:"missing"})}),c.jsx("td",{"data-testid":`reactive-reload-cell-${X.vault}`,children:ie?c.jsxs("span",{className:"confirm-inline",children:[ne.active?c.jsx("span",{className:"pill status-enabled","data-testid":`reactive-on-${X.vault}`,children:"on"}):c.jsx("span",{className:"pill","data-testid":`reactive-off-${X.vault}`,children:"off"}),c.jsx("button",{type:"button",className:"cancel-link","data-testid":`reactive-toggle-${X.vault}`,disabled:P===X.vault,onClick:()=>void V(X.vault,ne.active),children:P===X.vault?"Working…":ne.active?"Disable":"Enable"})]}):c.jsx("span",{className:"cell-dim",title:"Open the agent app via your hub origin to manage reactive reload.",children:"—"})}),c.jsx("td",{children:Q===X.vault?c.jsxs("span",{className:"confirm-inline",children:[c.jsx("button",{type:"button",className:"button-danger","data-testid":`remove-def-vault-confirm-${X.vault}`,disabled:G===X.vault,onClick:()=>void U(X.vault),children:G===X.vault?"Removing…":"Confirm remove"}),c.jsx("button",{type:"button",className:"cancel-link",onClick:()=>q(null),children:"Cancel"})]}):c.jsx("button",{type:"button",className:"button-danger","data-testid":`remove-def-vault-${X.vault}`,onClick:()=>{k(null),q(X.vault)},children:"Remove"})})]},X.vault)})})]})]})}function at(i){return i instanceof Dt&&i.status===401?"Not signed in to the hub — sign in to the portal, then reload.":i.message}function H0(i){return{key:i.id,kind:i.direction==="outbound"?"them":"you",text:i.text}}function Kh(){const i=qg(),o=om(),[f,r]=g.useState(null),[d,y]=g.useState(null),[p,j]=g.useState(i.channel??null),[S,m]=g.useState([]),[C,N]=g.useState(null),[_,Y]=g.useState({text:"",kind:""}),[Q,q]=g.useState(""),[G,M]=g.useState(!1),D=g.useRef(new Set),k=g.useRef(null),Z=g.useRef(null),J=g.useRef(!1),ie=g.useRef(0),F=g.useRef(null),P=g.useCallback(v=>{var O;return((O=f==null?void 0:f.find(w=>w.name===v))==null?void 0:O.transport)??""},[f]),I=g.useCallback(v=>P(v)==="vault",[P]),Re=g.useCallback(v=>{m(O=>[...O,{key:crypto.randomUUID(),kind:"sys",text:v}])},[]),le=g.useCallback(v=>{!v.id||D.current.has(v.id)||(D.current.add(v.id),m(O=>[...O,H0(v)]))},[]);g.useEffect(()=>{const v=F.current;v&&(v.scrollTop=v.scrollHeight)},[S,C]);const xe=g.useCallback(async v=>{var ge,Xe;const O=ie.current;(ge=k.current)==null||ge.close(),k.current=null,(Xe=Z.current)==null||Xe.close(),Z.current=null;const w=await tr();if(O!==ie.current)return;const K=P(v),ae=()=>{J.current=!1,Y({text:`live - ${v}`,kind:"live"})},re=()=>{var he,Pe;if(!J.current&&w){J.current=!0,Y({text:"re-authenticating...",kind:""}),(he=k.current)==null||he.close(),k.current=null,(Pe=Z.current)==null||Pe.close(),Z.current=null,ym(),xe(v);return}Y({text:"reconnecting...",kind:""})};if(K==="http-ui"){const he=new EventSource(r0(v,w));he.onopen=ae,he.addEventListener("reply",Pe=>{try{const tt=JSON.parse(Pe.data);tt.id?le({id:tt.id,text:tt.text??"",direction:"outbound",sender:"session",ts:""}):m(Va=>[...Va,{key:crypto.randomUUID(),kind:"them",text:tt.text??""}])}catch{}}),he.addEventListener("edit",Pe=>{try{const tt=JSON.parse(Pe.data);Re(`(edited) ${tt.text??""}`)}catch{}}),he.addEventListener("permission",Pe=>{try{const tt=JSON.parse(Pe.data);Re(`permission: ${tt.tool_name??""}${tt.description?` - ${tt.description}`:""} (respond in the session terminal)`)}catch{}}),he.onerror=re,k.current=he}if(I(v)){const he=new EventSource(o0(v,w));he.onopen=ae,he.addEventListener("turn",Pe=>{try{Ze(JSON.parse(Pe.data),v)}catch{}}),he.onerror=re,Z.current=he}},[le,Re,I,P]),Ie=g.useCallback(async v=>{try{(await qh(v)).messages.forEach(le)}catch{}},[le]),Ze=g.useCallback((v,O)=>{switch(v.kind){case"init":N({text:"",tools:[]});return;case"text":N(w=>({text:((w==null?void 0:w.text)??"")+v.text,tools:(w==null?void 0:w.tools)??[],...w!=null&&w.error?{error:w.error}:{}}));return;case"tool":N(w=>{const K=(w==null?void 0:w.tools)??[];return{text:(w==null?void 0:w.text)??"",tools:K.includes(v.tool)?K:[...K,v.tool]}});return;case"done":N(null),Ie(O);return;case"error":N(w=>({text:(w==null?void 0:w.text)??"",tools:(w==null?void 0:w.tools)??[],error:v.error}));return}},[Ie]);g.useEffect(()=>{let v=!1;return(async()=>{try{const O=await c0();if(v)return;r(O.channels),j(w=>{var K;return w&&O.channels.some(ae=>ae.name===w)?w:((K=O.channels[0])==null?void 0:K.name)??null})}catch(O){v||y(Fs(O))}})(),()=>{v=!0}},[]),g.useEffect(()=>{const v=p;if(!v){Y({text:"no channel",kind:""});return}let O=!1;return ie.current+=1,D.current=new Set,J.current=!1,m([]),N(null),Y({text:"loading history...",kind:""}),(async()=>{try{const w=await qh(v);if(O)return;w.messages.forEach(le),Y({text:`live - ${v}`,kind:"live"})}catch(w){if(O)return;Y({text:`history error: ${Fs(w)}`,kind:"err"})}O||await xe(v)})(),()=>{var w,K;O=!0,ie.current+=1,(w=k.current)==null||w.close(),k.current=null,(K=Z.current)==null||K.close(),Z.current=null}},[p]);function De(v){j(v),o(`/chat/${encodeURIComponent(v)}`,{replace:!0})}async function U(){const v=Q.trim(),O=p;if(!(!v||!O||G)){M(!0),m(w=>[...w,{key:crypto.randomUUID(),kind:"you",text:v}]),q("");try{const w=await s0(O,v);w.id&&D.current.add(w.id)}catch(w){Re(`send failed: ${Fs(w)}`)}finally{M(!1)}}}function V(v){v.key==="Enter"&&!v.shiftKey&&(v.preventDefault(),U())}const X=((f==null?void 0:f.length)??0)>0,ne=!!p&&Q.trim().length>0&&!G,oe=g.useMemo(()=>_.kind==="live"?"chat-status status-live":_.kind==="err"?"chat-status status-err":"chat-status",[_.kind]);return c.jsxs("div",{className:"chat","data-testid":"chat-view",children:[c.jsxs("div",{className:"chat-head",children:[c.jsx("h1",{children:"Chat"}),f&&X?c.jsxs("label",{className:"chat-picker",children:[c.jsx("span",{className:"chat-picker-label",children:"Channel"}),c.jsx("select",{"data-testid":"chat-channel-select",value:p??"",onChange:v=>De(v.target.value),children:f.map(v=>c.jsxs("option",{value:v.name,children:[v.name," (",v.transport,")"]},v.name))})]}):null,_.text?c.jsx("span",{className:oe,"data-testid":"chat-status",children:_.text}):null]}),d?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"chat-channels-error",children:d}):null,f&&!X&&!d?c.jsx("div",{className:"empty","data-testid":"chat-no-channels",children:"No channels yet. Create a channel-backed agent in the create flow, then chat with it here."}):null,X?c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:"transcript",ref:F,"data-testid":"chat-transcript",children:[S.map(v=>c.jsx("div",{className:`msg ${v.kind}`,"data-testid":`chat-msg-${v.kind}`,children:v.text},v.key)),C?c.jsx(w0,{turn:C}):null]}),c.jsxs("form",{className:"composer","data-testid":"chat-composer",onSubmit:v=>{v.preventDefault(),U()},children:[c.jsx("textarea",{className:"chat-input","data-testid":"chat-input",rows:1,value:Q,placeholder:"Type a message... (Enter to send, Shift+Enter for newline)",autoComplete:"off",onChange:v=>q(v.target.value),onKeyDown:V}),c.jsx("button",{type:"submit","data-testid":"chat-send",disabled:!ne,children:G?"Sending...":"Send"})]})]}):null]})}function w0({turn:i}){return c.jsxs("div",{className:`msg them live${i.error?" errored":""}`,"data-testid":"chat-live-turn",children:[i.text?c.jsx("div",{className:"live-text",children:i.text}):null,i.tools.length>0?c.jsx("div",{className:"live-tools",children:i.tools.map(o=>c.jsx("span",{className:"tool-chip","data-testid":`chat-tool-${o}`,children:o},o))}):null,c.jsx("div",{className:"live-working","data-testid":"chat-live-status",children:i.error?`turn failed: ${i.error}`:"working..."})]})}function Fs(i){return i instanceof Dt&&i.status===401?"Not signed in to the hub - sign in to the portal, then reload.":i.message}const B0=/^[a-zA-Z0-9_-]+$/;function L0({vaults:i}){var F;const o=i.length>0,[f,r]=g.useState(""),[d,y]=g.useState(((F=i[0])==null?void 0:F.vault)??""),[p,j]=g.useState("single-threaded"),[S,m]=g.useState("programmatic"),[C,N]=g.useState(""),[_,Y]=g.useState(""),[Q,q]=g.useState(""),[G,M]=g.useState(!1),[D,k]=g.useState({kind:"idle"}),Z=B0.test(f),J=o&&Z&&d.length>0&&D.kind!=="submitting";async function ie(P){if(P.preventDefault(),!!J){k({kind:"submitting"});try{const I=await Gp({vault:d,name:f,backend:S,systemPrompt:_,metadata:{mode:p,...C?{model:C}:{}},...Q.trim().length>0?{wants:Q.trim()}:{}});k({kind:"ok",result:I,mode:p})}catch(I){const Re=I instanceof Dt&&I.status===401?"Not signed in to the hub — sign in to the portal, then reload.":I.message;k({kind:"error",message:Re})}}}return D.kind==="ok"?c.jsx(Y0,{result:D.result,mode:D.mode}):c.jsxs("div",{children:[c.jsx("h1",{children:"New agent"}),c.jsxs("p",{className:"lede",children:["A ",c.jsx("code",{children:"#agent/definition"})," note IS the agent — writing it instantiates the agent and its channel routing in one step. The def-vault editor, schedules, and editing land in a later phase."]}),o?null:c.jsxs("div",{className:"error-banner",role:"alert","data-testid":"no-def-vaults",children:["No def-vault is configured, and one is required to create an agent. The add / remove def-vault editor arrives in a later phase; until then, configure a def-vault out-of-band. Submitting anyway will return the daemon's"," ",c.jsx("code",{children:"no def-vaults configured"})," error."]}),D.kind==="error"?c.jsx("div",{className:"error-banner",role:"alert","data-testid":"create-error",children:D.message}):null,c.jsxs("form",{className:"card",onSubmit:ie,"aria-label":"Create agent",children:[c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-name",children:"Name"}),c.jsx("input",{id:"agent-name",type:"text",value:f,placeholder:"my-agent",autoComplete:"off",onChange:P=>r(P.target.value)}),c.jsx("p",{className:"field-hint",children:"A slug (letters, numbers, dash, underscore). This is also the agent's channel."}),f.length>0&&!Z?c.jsx("p",{className:"field-error","data-testid":"name-invalid",children:"Must be a slug — letters, numbers, dash, underscore only."}):null]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-vault",children:"Def-vault"}),c.jsx("select",{id:"agent-vault",value:d,disabled:!o,onChange:P=>y(P.target.value),children:o?i.map(P=>c.jsxs("option",{value:P.vault,children:[P.vault,P.tokenPresent?"":" (token missing)"]},P.vault)):c.jsx("option",{value:"",children:"No def-vaults configured"})}),c.jsx("p",{className:"field-hint",children:"The vault this agent's definition note is written to."})]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Mode"}),c.jsx(hi,{name:"mode",value:"single-threaded",checked:p==="single-threaded",onChange:()=>j("single-threaded"),label:"Single-threaded",help:"One continuous conversation — remembers everything on this channel.",testid:"mode-single-threaded"}),c.jsx(hi,{name:"mode",value:"multi-threaded",checked:p==="multi-threaded",onChange:()=>j("multi-threaded"),label:"Multi-threaded",help:"Each run is its own thread; today every run starts fresh (per-conversation continuation is coming) — good for scheduled or stateless tasks.",testid:"mode-multi-threaded"})]}),c.jsxs("fieldset",{className:"field",children:[c.jsx("legend",{children:"Backend"}),c.jsx(hi,{name:"backend",value:"programmatic",checked:S==="programmatic",onChange:()=>m("programmatic"),label:"Programmatic",help:"Parachute runs it headless — always on, sandboxed.",testid:"backend-programmatic"}),c.jsx(hi,{name:"backend",value:"channel",checked:S==="channel",onChange:()=>m("channel"),label:"Channel",help:"You run a Claude Code session on your own machine and connect it — your env, unsandboxed.",testid:"backend-channel"})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-model",children:"Model"}),c.jsx("select",{id:"agent-model",value:C,"data-testid":"agent-model",onChange:P=>N(P.target.value),children:pr.map(P=>c.jsx("option",{value:P.value,children:P.label},P.value))}),c.jsx("p",{className:"field-hint",children:"Which model Parachute runs this agent on (programmatic backend). A channel-backend agent uses whatever model your own session runs."})]}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-prompt",children:"System prompt"}),c.jsx("textarea",{id:"agent-prompt",rows:6,value:_,placeholder:"You are…",onChange:P=>Y(P.target.value)}),c.jsx("p",{className:"field-hint",children:"The agent's persona + instructions (the note body). Leave blank for Claude Code's default."})]}),c.jsxs("details",{className:"advanced",open:G,onToggle:P=>M(P.target.open),children:[c.jsx("summary",{children:"Advanced"}),c.jsxs("div",{className:"field",children:[c.jsx("label",{htmlFor:"agent-wants",children:"Wants (connections)"}),c.jsx("input",{id:"agent-wants",type:"text",value:Q,placeholder:"vault:other, service:github",autoComplete:"off",onChange:P=>q(P.target.value)}),c.jsx("p",{className:"field-hint",children:"Comma-separated connection keys the agent requests beyond its own vault. Each needs approval before it's granted."})]})]}),c.jsxs("div",{className:"form-actions",children:[c.jsx("button",{type:"submit",disabled:!J,children:D.kind==="submitting"?"Creating…":"Create agent"}),c.jsx(fl,{to:"/",className:"cancel-link",children:"Cancel"})]})]})]})}function q0(){const[i,o]=g.useState({kind:"loading"}),f=g.useCallback(async()=>{o({kind:"loading"});try{const r=await gm();o({kind:"ok",vaults:r.vaults})}catch(r){const d=r instanceof Dt?r.status===401?"Not signed in to the hub — sign in to the portal, then reload.":`Failed to load def-vaults: ${r.message}`:`Failed to load def-vaults: ${r.message}`;o({kind:"error",message:d})}},[]);return g.useEffect(()=>{f()},[f]),i.kind==="loading"?c.jsx("div",{className:"loading",children:"Loading…"}):i.kind==="error"?c.jsxs("div",{className:"error-banner",role:"alert",children:[i.message," ",c.jsx("button",{type:"button",className:"secondary",onClick:()=>void f(),children:"Retry"})]}):c.jsx(L0,{vaults:i.vaults},i.vaults.map(r=>r.vault).join(","))}function hi(i){return c.jsxs("label",{className:`radio-row${i.checked?" selected":""}`,"data-testid":i.testid,children:[c.jsx("input",{type:"radio",name:i.name,value:i.value,checked:i.checked,onChange:i.onChange}),c.jsxs("span",{className:"radio-body",children:[c.jsx("span",{className:"radio-label",children:i.label}),c.jsx("span",{className:"radio-help",children:i.help})]})]})}function Y0({result:i,mode:o}){const f=i.def;return c.jsxs("div",{"data-testid":"create-success",children:[c.jsx("h1",{children:"Agent created"}),c.jsxs("div",{className:"success-banner",role:"status",children:[c.jsx("strong",{children:f.name})," · ",o," · ",f.backend]}),c.jsxs("p",{className:"lede",children:["The definition was written to ",c.jsx("code",{children:f.vault})," and instantiated. It now appears in the ",c.jsx(fl,{to:"/",children:"Agents list"}),"."]}),f.backend==="channel"?c.jsx(k0,{name:f.name}):null,c.jsx("p",{children:c.jsx(fl,{to:"/",children:"← Back to agents"})})]})}function k0({name:i}){const[o,f]=g.useState(!1),r=typeof window<"u"?window.location.origin:"",d=g.useMemo(()=>i0(i,r),[i,r]);async function y(){var p;try{await((p=navigator.clipboard)==null?void 0:p.writeText(d)),f(!0),setTimeout(()=>f(!1),2e3)}catch{}}return c.jsxs("section",{className:"card","aria-label":"Connect a session","data-testid":"connect-session",children:[c.jsx("h2",{children:"Connect your Claude Code session"}),c.jsx("p",{className:"muted",children:"Run this on your own machine to make a Claude Code session a responder for this channel:"}),c.jsxs("div",{className:"snippet-row",children:[c.jsx("code",{className:"snippet","data-testid":"connect-command",children:d}),c.jsx("button",{type:"button",className:"secondary",onClick:()=>void y(),children:o?"Copied":"Copy"})]}),c.jsx("p",{className:"field-hint",children:"Your Claude Code session pulls messages from this channel; until you connect, inbound messages queue durably in the vault."})]})}const G0="Parachute Agent";function X0(i){return i==="/create"||i.startsWith("/create/")?"new agent":i==="/chat"||i.startsWith("/chat/")?"chat":"agents"}function Q0(){const{pathname:i}=Bt(),o=X0(i);return c.jsxs("div",{className:"page",children:[c.jsxs("nav",{className:"nav",children:[c.jsxs(fl,{to:"/",className:"brand",children:[c.jsx("span",{className:"brand-wordmark",children:G0}),c.jsx("span",{className:"sub",children:o})]}),c.jsx(Is,{to:"/",label:"Agents",exact:!0}),c.jsx(Is,{to:"/create",label:"New agent"}),c.jsx(Is,{to:"/chat",label:"Chat"})]}),c.jsxs(ep,{children:[c.jsx(aa,{path:"/",element:c.jsx(Qh,{})}),c.jsx(aa,{path:"/agents",element:c.jsx(Qh,{})}),c.jsx(aa,{path:"/create",element:c.jsx(q0,{})}),c.jsx(aa,{path:"/chat",element:c.jsx(Kh,{})}),c.jsx(aa,{path:"/chat/:channel",element:c.jsx(Kh,{})}),c.jsx(aa,{path:"*",element:c.jsxs("div",{className:"empty",children:["404 — back to ",c.jsx(fl,{to:"/",children:"Agents"}),"."]})})]})]})}function Is({to:i,label:o,exact:f}){const{pathname:r}=Bt(),d=f?r===i||r==="/agents":r===i||r.startsWith(`${i}/`);return c.jsx(fl,{to:i,className:d?"nav-link nav-link-active":"nav-link","aria-current":d?"page":void 0,children:o})}function V0(i){return i==="/agent/app"||i.startsWith("/agent/app/")?"/agent/app":i==="/app"||i.startsWith("/app/")?"/app":""}const xm=document.getElementById("root");if(!xm)throw new Error("#root not found");eg.createRoot(xm).render(c.jsx(g.StrictMode,{children:c.jsx(Np,{basename:V0(window.location.pathname),children:c.jsx(Q0,{})})}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg: #faf8f4;--bg-soft: #f3f0ea;--fg: #2c2a26;--fg-muted: #6b6860;--fg-dim: #9a9690;--accent: #4a7c59;--accent-soft: rgba(74, 124, 89, .08);--accent-hover: #3d6849;--border: #e4e0d8;--border-light: #ece9e2;--card-bg: #ffffff;--error: #a3392b;--error-soft: rgba(163, 57, 43, .08);--warn: #b08023;--warn-soft: rgba(176, 128, 35, .08);--success: #3d6849;--success-soft: rgba(61, 104, 73, .08);--font-serif: Georgia, "Times New Roman", serif;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;--font-mono: ui-monospace, "SF Mono", Menlo, Monaco, "Cascadia Mono", monospace;font-family:var(--font-sans)}*{box-sizing:border-box}html,body{margin:0;padding:0;background:var(--bg);color:var(--fg)}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}button{font:inherit;background:var(--accent);color:#fff;border:0;border-radius:6px;padding:.45rem .9rem;cursor:pointer;transition:background .15s ease}button:hover{background:var(--accent-hover)}button:disabled{opacity:.5;cursor:not-allowed}button.secondary{background:#fff;color:var(--fg);border:1px solid var(--border)}button.secondary:hover{background:var(--bg-soft)}code{font-family:var(--font-mono);font-size:.85em;background:var(--bg-soft);padding:.1em .3em;border-radius:3px}.page{max-width:960px;margin:0 auto;padding:1.5rem 1.5rem 6rem}.nav{display:flex;flex-wrap:wrap;gap:.6rem 1rem;align-items:center;padding-bottom:1rem;border-bottom:1px solid var(--border);margin-bottom:2rem}.nav .brand{font-weight:600;font-family:var(--font-serif);font-size:1.15rem;margin-right:auto;display:inline-flex;align-items:center;gap:.45rem;color:var(--accent);text-decoration:none}.nav .brand:hover{color:var(--accent-hover);text-decoration:none}.nav .brand-wordmark{color:var(--fg);letter-spacing:-.005em}.nav .brand .sub{color:var(--fg-dim);font-size:.78rem;font-weight:400;margin-left:.4rem;font-family:var(--font-sans)}.nav a{color:var(--fg-muted);font-size:.95rem}.nav a:hover{text-decoration:none;color:var(--fg)}.nav a.nav-link-active{color:var(--accent);font-weight:500;text-decoration:underline;text-underline-offset:.3em;text-decoration-thickness:2px}h1{margin:0 0 .5rem;font-family:var(--font-serif);font-size:1.85rem;font-weight:400;letter-spacing:-.01em;line-height:1.2;color:var(--fg)}h2{margin:0 0 1rem;font-size:1.4rem;font-weight:500}h3{margin:0 0 .5rem;font-size:1.05rem;font-weight:600}.muted{color:var(--fg-muted);font-size:.92rem}.dim{color:var(--fg-dim);font-size:.85rem}.lede{color:var(--fg-muted);font-size:.95rem;margin:0 0 1.5rem;max-width:60ch}.error-banner{background:var(--error-soft);border:1px solid var(--error);color:var(--error);padding:.75rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.9rem}.info-banner{background:var(--accent-soft);border:1px solid var(--accent);color:var(--fg);padding:.65rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.88rem}.empty{border:1px dashed var(--border);border-radius:10px;padding:2rem 1.5rem;text-align:center;color:var(--fg-muted);background:var(--card-bg)}.loading{color:var(--fg-muted);padding:1rem 0;font-size:.92rem}.card{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;padding:1.1rem 1.25rem;box-shadow:0 1px 2px #2c2a260a,0 8px 24px #2c2a260d;margin-bottom:1.5rem}.section-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin-bottom:.75rem}.section-head .count{color:var(--fg-dim);font-size:.85rem}table{width:100%;border-collapse:collapse;font-size:.88rem}th,td{text-align:left;padding:.6rem .7rem;border-bottom:1px solid var(--border);vertical-align:middle}th{color:var(--fg-muted);font-weight:500;font-size:.78rem;text-transform:uppercase;letter-spacing:.03em}tr.agent-row{cursor:pointer}tr.agent-row:hover{background:var(--bg-soft)}tr.agent-row.selected{background:var(--accent-soft)}.cell-name{font-weight:600;color:var(--fg)}.cell-dim{color:var(--fg-dim)}.pill{display:inline-block;padding:.1rem .5rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.02em;border:1px solid var(--border);color:var(--fg-muted);background:var(--bg-soft)}.pill.backend-programmatic{color:var(--accent);background:var(--accent-soft);border-color:transparent}.pill.backend-channel{color:var(--warn);background:var(--warn-soft);border-color:transparent}.pill.status-enabled,.pill.status-idle{color:var(--success);background:var(--success-soft);border-color:transparent}.pill.status-working{color:var(--accent);background:var(--accent-soft);border-color:transparent}.pill.status-pending,.pill.status-queued{color:var(--warn);background:var(--warn-soft);border-color:transparent}.pill.status-error{color:var(--error);background:var(--error-soft);border-color:transparent}.detail{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;padding:1.25rem 1.4rem;margin-bottom:1.5rem;box-shadow:0 1px 2px #2c2a260a,0 8px 24px #2c2a260d}.detail-head{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:.9rem}.detail-head h2{margin:0;font-size:1.25rem}.detail-grid{display:grid;grid-template-columns:max-content 1fr;gap:.45rem 1.2rem;font-size:.9rem;margin-bottom:1rem}.detail-grid dt{color:var(--fg-muted);font-weight:500}.detail-grid dd{margin:0;color:var(--fg);word-break:break-word}.detail-prompt{background:var(--bg-soft);border:1px solid var(--border-light);border-radius:8px;padding:.75rem .9rem;font-family:var(--font-mono);font-size:.82rem;white-space:pre-wrap;color:var(--fg);margin:.3rem 0 1rem}.detail-note{font-size:.82rem;color:var(--fg-dim);margin:.5rem 0 0}.detail-close{margin-left:auto;background:#fff;color:var(--fg-muted);border:1px solid var(--border);padding:.3rem .7rem;font-size:.82rem}.detail-close:hover{background:var(--bg-soft);color:var(--fg)}.tag-list{display:flex;flex-wrap:wrap;gap:.35rem}.tag{font-family:var(--font-mono);font-size:.76rem;background:var(--bg-soft);border:1px solid var(--border-light);border-radius:4px;padding:.05rem .35rem;color:var(--fg-muted)}.section-head-actions{display:inline-flex;align-items:center;gap:.9rem}.button-link{display:inline-block;background:var(--accent);color:#fff;border-radius:6px;padding:.4rem .85rem;font-size:.85rem;font-weight:500;transition:background .15s ease}.button-link:hover{background:var(--accent-hover);color:#fff;text-decoration:none}.field{display:block;border:0;margin:0 0 1.25rem;padding:0}.field>label,.field>legend{display:block;font-weight:500;font-size:.9rem;color:var(--fg);margin-bottom:.35rem;padding:0}.field input[type=text],.field select,.field textarea{width:100%;font:inherit;font-size:.9rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:6px;padding:.5rem .6rem}.field textarea{font-family:var(--font-mono);font-size:.82rem;resize:vertical}.field input[type=text]:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}.field-hint{color:var(--fg-dim);font-size:.8rem;margin:.3rem 0 0}.field-error{color:var(--error);font-size:.8rem;margin:.3rem 0 0}.radio-row{display:flex;align-items:flex-start;gap:.6rem;border:1px solid var(--border);border-radius:8px;padding:.65rem .8rem;margin-bottom:.5rem;cursor:pointer;transition:border-color .15s ease,background .15s ease}.radio-row:hover{background:var(--bg-soft)}.radio-row.selected{border-color:var(--accent);background:var(--accent-soft)}.radio-row input[type=radio]{margin-top:.2rem;accent-color:var(--accent)}.radio-body{display:flex;flex-direction:column;gap:.15rem}.radio-label{font-weight:500;font-size:.9rem;color:var(--fg)}.radio-help{font-size:.8rem;color:var(--fg-muted)}.advanced{margin:0 0 1.25rem}.advanced>summary{cursor:pointer;font-size:.88rem;font-weight:500;color:var(--fg-muted);margin-bottom:.75rem}.advanced>summary:hover{color:var(--fg)}.form-actions{display:flex;align-items:center;gap:1rem}.cancel-link{color:var(--fg-muted);font-size:.9rem}.success-banner{background:var(--success-soft);border:1px solid var(--success);color:var(--success);padding:.75rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.95rem}.snippet-row{display:flex;align-items:stretch;gap:.6rem;margin:.5rem 0}.snippet{flex:1;font-family:var(--font-mono);font-size:.8rem;background:var(--bg-soft);border:1px solid var(--border-light);border-radius:6px;padding:.6rem .75rem;color:var(--fg);white-space:pre-wrap;word-break:break-all}.detail-actions{display:flex;gap:.6rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border-light)}button.button-danger{background:#fff;color:var(--error);border:1px solid var(--error)}button.button-danger:hover{background:var(--error-soft)}button.button-danger:disabled{opacity:.5;cursor:not-allowed}.confirm-box{margin-top:1.25rem;padding:1rem;border:1px solid var(--error);border-radius:8px;background:var(--error-soft)}.confirm-prompt{margin:0 0 .75rem;font-size:.9rem;color:var(--fg)}.confirm-inline{display:inline-flex;align-items:center;gap:.6rem}.inline-form{margin:.75rem 0 1rem}.schedules,.detail-section{margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border-light)}.schedules .section-head h3,.detail-section .section-head h3{margin:0;font-size:1.05rem}.schedule-presets{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.45rem}.schedule-presets button{font-size:.78rem;padding:.2rem .55rem}.schedule-row-actions{display:inline-flex;align-items:center;gap:.6rem}.schedule-status{font-size:.82rem;color:var(--fg-muted);margin:.5rem 0 0}.chat-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.75rem 1rem;margin-bottom:1rem}.chat-head h1{margin:0}.chat-picker{display:inline-flex;align-items:center;gap:.5rem}.chat-picker-label{font-size:.82rem;color:var(--fg-muted)}.chat-picker select{font:inherit;font-size:.88rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:6px;padding:.35rem .5rem}.chat-status{font-size:.8rem;color:var(--fg-muted);margin-left:auto}.chat-status.status-live{color:var(--success)}.chat-status.status-err{color:var(--error)}.transcript{display:flex;flex-direction:column;gap:.5rem;height:60vh;min-height:18rem;overflow-y:auto;padding:1rem;background:var(--card-bg);border:1px solid var(--border);border-radius:12px 12px 0 0}.transcript .msg{max-width:78%;padding:.5rem .75rem;border-radius:12px;font-size:.9rem;line-height:1.4;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:anywhere}.transcript .msg.you{align-self:flex-end;background:var(--accent);color:#fff;border-bottom-right-radius:4px}.transcript .msg.them{align-self:flex-start;background:var(--bg-soft);color:var(--fg);border:1px solid var(--border);border-bottom-left-radius:4px}.transcript .msg.sys{align-self:center;background:transparent;color:var(--fg-muted);font-size:.8rem;font-style:italic;max-width:90%;text-align:center}.transcript .msg.live{border-style:dashed;animation:chatLivePulse 1.4s ease-in-out infinite}@keyframes chatLivePulse{0%,to{opacity:1}50%{opacity:.6}}.transcript .msg.live.errored{border-color:var(--error);color:var(--error);animation:none}.transcript .live-tools{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.4rem}.transcript .tool-chip{font-family:var(--font-mono);font-size:.72rem;padding:.05rem .45rem;border-radius:10px;background:var(--card-bg);color:var(--fg-muted);border:1px solid var(--border)}.transcript .live-working{margin-top:.4rem;font-size:.75rem;color:var(--fg-muted);font-style:italic}.composer{display:flex;gap:.6rem;padding:.75rem 1rem;background:var(--card-bg);border:1px solid var(--border);border-top:0;border-radius:0 0 12px 12px;margin-bottom:1.5rem}.composer .chat-input{flex:1;font:inherit;font-size:.9rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:8px;padding:.55rem .7rem;resize:none;max-height:7.5rem}.composer .chat-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}.composer button{flex:0 0 auto;align-self:flex-end}
|
package/web/ui/dist/index.html
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<meta name="referrer" content="no-referrer" />
|
|
7
7
|
<title>Parachute Agent</title>
|
|
8
8
|
<meta name="description" content="Manage Parachute agents — every backend, one surface." />
|
|
9
|
-
<script type="module" crossorigin src="/agent/app/assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/agent/app/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/agent/app/assets/index-0e7eQymr.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/agent/app/assets/index-tvKbxee4.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{--bg: #faf8f4;--bg-soft: #f3f0ea;--fg: #2c2a26;--fg-muted: #6b6860;--fg-dim: #9a9690;--accent: #4a7c59;--accent-soft: rgba(74, 124, 89, .08);--accent-hover: #3d6849;--border: #e4e0d8;--border-light: #ece9e2;--card-bg: #ffffff;--error: #a3392b;--error-soft: rgba(163, 57, 43, .08);--warn: #b08023;--warn-soft: rgba(176, 128, 35, .08);--success: #3d6849;--success-soft: rgba(61, 104, 73, .08);--font-serif: Georgia, "Times New Roman", serif;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;--font-mono: ui-monospace, "SF Mono", Menlo, Monaco, "Cascadia Mono", monospace;font-family:var(--font-sans)}*{box-sizing:border-box}html,body{margin:0;padding:0;background:var(--bg);color:var(--fg)}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}button{font:inherit;background:var(--accent);color:#fff;border:0;border-radius:6px;padding:.45rem .9rem;cursor:pointer;transition:background .15s ease}button:hover{background:var(--accent-hover)}button:disabled{opacity:.5;cursor:not-allowed}button.secondary{background:#fff;color:var(--fg);border:1px solid var(--border)}button.secondary:hover{background:var(--bg-soft)}code{font-family:var(--font-mono);font-size:.85em;background:var(--bg-soft);padding:.1em .3em;border-radius:3px}.page{max-width:960px;margin:0 auto;padding:1.5rem 1.5rem 6rem}.nav{display:flex;flex-wrap:wrap;gap:.6rem 1rem;align-items:center;padding-bottom:1rem;border-bottom:1px solid var(--border);margin-bottom:2rem}.nav .brand{font-weight:600;font-family:var(--font-serif);font-size:1.15rem;margin-right:auto;display:inline-flex;align-items:center;gap:.45rem;color:var(--accent);text-decoration:none}.nav .brand:hover{color:var(--accent-hover);text-decoration:none}.nav .brand-wordmark{color:var(--fg);letter-spacing:-.005em}.nav .brand .sub{color:var(--fg-dim);font-size:.78rem;font-weight:400;margin-left:.4rem;font-family:var(--font-sans)}.nav a{color:var(--fg-muted);font-size:.95rem}.nav a:hover{text-decoration:none;color:var(--fg)}.nav a.nav-link-active{color:var(--accent);font-weight:500;text-decoration:underline;text-underline-offset:.3em;text-decoration-thickness:2px}h1{margin:0 0 .5rem;font-family:var(--font-serif);font-size:1.85rem;font-weight:400;letter-spacing:-.01em;line-height:1.2;color:var(--fg)}h2{margin:0 0 1rem;font-size:1.4rem;font-weight:500}h3{margin:0 0 .5rem;font-size:1.05rem;font-weight:600}.muted{color:var(--fg-muted);font-size:.92rem}.dim{color:var(--fg-dim);font-size:.85rem}.lede{color:var(--fg-muted);font-size:.95rem;margin:0 0 1.5rem;max-width:60ch}.error-banner{background:var(--error-soft);border:1px solid var(--error);color:var(--error);padding:.75rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.9rem}.info-banner{background:var(--accent-soft);border:1px solid var(--accent);color:var(--fg);padding:.65rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.88rem}.empty{border:1px dashed var(--border);border-radius:10px;padding:2rem 1.5rem;text-align:center;color:var(--fg-muted);background:var(--card-bg)}.loading{color:var(--fg-muted);padding:1rem 0;font-size:.92rem}.card{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;padding:1.1rem 1.25rem;box-shadow:0 1px 2px #2c2a260a,0 8px 24px #2c2a260d;margin-bottom:1.5rem}.section-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin-bottom:.75rem}.section-head .count{color:var(--fg-dim);font-size:.85rem}table{width:100%;border-collapse:collapse;font-size:.88rem}th,td{text-align:left;padding:.6rem .7rem;border-bottom:1px solid var(--border);vertical-align:middle}th{color:var(--fg-muted);font-weight:500;font-size:.78rem;text-transform:uppercase;letter-spacing:.03em}tr.agent-row{cursor:pointer}tr.agent-row:hover{background:var(--bg-soft)}tr.agent-row.selected{background:var(--accent-soft)}.cell-name{font-weight:600;color:var(--fg)}.cell-dim{color:var(--fg-dim)}.pill{display:inline-block;padding:.1rem .5rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.02em;border:1px solid var(--border);color:var(--fg-muted);background:var(--bg-soft)}.pill.backend-programmatic{color:var(--accent);background:var(--accent-soft);border-color:transparent}.pill.backend-channel{color:var(--warn);background:var(--warn-soft);border-color:transparent}.pill.backend-interactive{color:var(--fg-muted);background:var(--bg-soft)}.pill.status-enabled,.pill.status-idle{color:var(--success);background:var(--success-soft);border-color:transparent}.pill.status-working{color:var(--accent);background:var(--accent-soft);border-color:transparent}.pill.status-pending,.pill.status-queued{color:var(--warn);background:var(--warn-soft);border-color:transparent}.pill.status-error{color:var(--error);background:var(--error-soft);border-color:transparent}.detail{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;padding:1.25rem 1.4rem;margin-bottom:1.5rem;box-shadow:0 1px 2px #2c2a260a,0 8px 24px #2c2a260d}.detail-head{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:.9rem}.detail-head h2{margin:0;font-size:1.25rem}.detail-grid{display:grid;grid-template-columns:max-content 1fr;gap:.45rem 1.2rem;font-size:.9rem;margin-bottom:1rem}.detail-grid dt{color:var(--fg-muted);font-weight:500}.detail-grid dd{margin:0;color:var(--fg);word-break:break-word}.detail-prompt{background:var(--bg-soft);border:1px solid var(--border-light);border-radius:8px;padding:.75rem .9rem;font-family:var(--font-mono);font-size:.82rem;white-space:pre-wrap;color:var(--fg);margin:.3rem 0 1rem}.detail-note{font-size:.82rem;color:var(--fg-dim);margin:.5rem 0 0}.detail-close{margin-left:auto;background:#fff;color:var(--fg-muted);border:1px solid var(--border);padding:.3rem .7rem;font-size:.82rem}.detail-close:hover{background:var(--bg-soft);color:var(--fg)}.tag-list{display:flex;flex-wrap:wrap;gap:.35rem}.tag{font-family:var(--font-mono);font-size:.76rem;background:var(--bg-soft);border:1px solid var(--border-light);border-radius:4px;padding:.05rem .35rem;color:var(--fg-muted)}.section-head-actions{display:inline-flex;align-items:center;gap:.9rem}.button-link{display:inline-block;background:var(--accent);color:#fff;border-radius:6px;padding:.4rem .85rem;font-size:.85rem;font-weight:500;transition:background .15s ease}.button-link:hover{background:var(--accent-hover);color:#fff;text-decoration:none}.field{display:block;border:0;margin:0 0 1.25rem;padding:0}.field>label,.field>legend{display:block;font-weight:500;font-size:.9rem;color:var(--fg);margin-bottom:.35rem;padding:0}.field input[type=text],.field select,.field textarea{width:100%;font:inherit;font-size:.9rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:6px;padding:.5rem .6rem}.field textarea{font-family:var(--font-mono);font-size:.82rem;resize:vertical}.field input[type=text]:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}.field-hint{color:var(--fg-dim);font-size:.8rem;margin:.3rem 0 0}.field-error{color:var(--error);font-size:.8rem;margin:.3rem 0 0}.radio-row{display:flex;align-items:flex-start;gap:.6rem;border:1px solid var(--border);border-radius:8px;padding:.65rem .8rem;margin-bottom:.5rem;cursor:pointer;transition:border-color .15s ease,background .15s ease}.radio-row:hover{background:var(--bg-soft)}.radio-row.selected{border-color:var(--accent);background:var(--accent-soft)}.radio-row input[type=radio]{margin-top:.2rem;accent-color:var(--accent)}.radio-body{display:flex;flex-direction:column;gap:.15rem}.radio-label{font-weight:500;font-size:.9rem;color:var(--fg)}.radio-help{font-size:.8rem;color:var(--fg-muted)}.advanced{margin:0 0 1.25rem}.advanced>summary{cursor:pointer;font-size:.88rem;font-weight:500;color:var(--fg-muted);margin-bottom:.75rem}.advanced>summary:hover{color:var(--fg)}.form-actions{display:flex;align-items:center;gap:1rem}.cancel-link{color:var(--fg-muted);font-size:.9rem}.success-banner{background:var(--success-soft);border:1px solid var(--success);color:var(--success);padding:.75rem 1rem;border-radius:8px;margin-bottom:1rem;font-size:.95rem}.snippet-row{display:flex;align-items:stretch;gap:.6rem;margin:.5rem 0}.snippet{flex:1;font-family:var(--font-mono);font-size:.8rem;background:var(--bg-soft);border:1px solid var(--border-light);border-radius:6px;padding:.6rem .75rem;color:var(--fg);white-space:pre-wrap;word-break:break-all}.detail-actions{display:flex;gap:.6rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border-light)}button.button-danger{background:#fff;color:var(--error);border:1px solid var(--error)}button.button-danger:hover{background:var(--error-soft)}button.button-danger:disabled{opacity:.5;cursor:not-allowed}.confirm-box{margin-top:1.25rem;padding:1rem;border:1px solid var(--error);border-radius:8px;background:var(--error-soft)}.confirm-prompt{margin:0 0 .75rem;font-size:.9rem;color:var(--fg)}.confirm-inline{display:inline-flex;align-items:center;gap:.6rem}.inline-form{margin:.75rem 0 1rem}.schedules,.detail-section{margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border-light)}.schedules .section-head h3,.detail-section .section-head h3{margin:0;font-size:1.05rem}.schedule-presets{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.45rem}.schedule-presets button{font-size:.78rem;padding:.2rem .55rem}.schedule-row-actions{display:inline-flex;align-items:center;gap:.6rem}.schedule-status{font-size:.82rem;color:var(--fg-muted);margin:.5rem 0 0}.chat-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.75rem 1rem;margin-bottom:1rem}.chat-head h1{margin:0}.chat-picker{display:inline-flex;align-items:center;gap:.5rem}.chat-picker-label{font-size:.82rem;color:var(--fg-muted)}.chat-picker select{font:inherit;font-size:.88rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:6px;padding:.35rem .5rem}.chat-status{font-size:.8rem;color:var(--fg-muted);margin-left:auto}.chat-status.status-live{color:var(--success)}.chat-status.status-err{color:var(--error)}.transcript{display:flex;flex-direction:column;gap:.5rem;height:60vh;min-height:18rem;overflow-y:auto;padding:1rem;background:var(--card-bg);border:1px solid var(--border);border-radius:12px 12px 0 0}.transcript .msg{max-width:78%;padding:.5rem .75rem;border-radius:12px;font-size:.9rem;line-height:1.4;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:anywhere}.transcript .msg.you{align-self:flex-end;background:var(--accent);color:#fff;border-bottom-right-radius:4px}.transcript .msg.them{align-self:flex-start;background:var(--bg-soft);color:var(--fg);border:1px solid var(--border);border-bottom-left-radius:4px}.transcript .msg.sys{align-self:center;background:transparent;color:var(--fg-muted);font-size:.8rem;font-style:italic;max-width:90%;text-align:center}.transcript .msg.live{border-style:dashed;animation:chatLivePulse 1.4s ease-in-out infinite}@keyframes chatLivePulse{0%,to{opacity:1}50%{opacity:.6}}.transcript .msg.live.errored{border-color:var(--error);color:var(--error);animation:none}.transcript .live-tools{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.4rem}.transcript .tool-chip{font-family:var(--font-mono);font-size:.72rem;padding:.05rem .45rem;border-radius:10px;background:var(--card-bg);color:var(--fg-muted);border:1px solid var(--border)}.transcript .live-working{margin-top:.4rem;font-size:.75rem;color:var(--fg-muted);font-style:italic}.composer{display:flex;gap:.6rem;padding:.75rem 1rem;background:var(--card-bg);border:1px solid var(--border);border-top:0;border-radius:0 0 12px 12px;margin-bottom:1.5rem}.composer .chat-input{flex:1;font:inherit;font-size:.9rem;color:var(--fg);background:var(--card-bg);border:1px solid var(--border);border-radius:8px;padding:.55rem .7rem;resize:none;max-height:7.5rem}.composer .chat-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}.composer button{flex:0 0 auto;align-self:flex-end}
|