@superclawd-ai/fda 0.1.48 → 0.1.50

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.
@@ -308,4 +308,4 @@ Please change the parent <Route path="${D}"> to <Route path="${D==="/"?"*":`${D}
308
308
  `).split(`
309
309
  `),s=[];let o=0;for(;o<r.length;){const u=r[o];if(!u.trim()){o++;continue}const d=u.match(/^\s*(```|~~~)\s*([\w+-]*)/);if(d){const m=[];for(o++;o<r.length&&!r[o].trim().startsWith(d[1]);)m.push(r[o++]);o++,s.push({type:"code",lang:d[2],text:m.join(`
310
310
  `)});continue}const h=u.match(/^(#{1,6})\s+(.*)$/);if(h){s.push({type:"heading",level:h[1].length,text:h[2].replace(/\s#+\s*$/,"")}),o++;continue}if(/^\s*([-*_])(\s*\1){2,}\s*$/.test(u)){s.push({type:"hr"}),o++;continue}if(/^\s*>/.test(u)){const m=[];for(;o<r.length&&/^\s*>/.test(r[o]);)m.push(r[o++].replace(/^\s*>\s?/,""));s.push({type:"quote",text:m.join(`
311
- `)});continue}const p=u.match(Kc);if(p){const m=/\d/.test(p[1]),y=[];for(;o<r.length;){const w=r[o].match(Kc);if(w&&/\d/.test(w[1])===m)y.push(w[2]),o++;else if(r[o].trim()&&/^\s{2,}/.test(r[o])&&y.length)y[y.length-1]+=" "+r[o].trim(),o++;else break}s.push({type:"list",ordered:m,items:y});continue}const g=[];for(;o<r.length&&r[o].trim()&&!/^(#{1,6})\s/.test(r[o])&&!/^\s*(```|~~~|>)/.test(r[o])&&!Kc.test(r[o]);)g.push(r[o++].trim());s.push({type:"para",text:g.join(" ")})}return s}const Db=/(`[^`]{1,500}`)|(\*\*[^*]{1,500}\*\*|__[^_]{1,500}__)|(\*[^*\s][^*]{0,500}\*|_[^_\s][^_]{0,500}_)|(\[[^\]]{1,300}\]\([^)\s]{1,2000}\))|(https?:\/\/[^\s<)]{1,2000})/,Sm=2e4;function Ys(n,r="i"){const s=[];let o=n.length>Sm?`${n.slice(0,Sm)}…`:n,u=0;for(;o;){const d=o.match(Db);if(!d||d.index===void 0){s.push(o);break}d.index>0&&s.push(o.slice(0,d.index));const h=d[0],p=`${r}-${u++}`;if(d[1])s.push(i.jsx("code",{className:"rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]",children:h.slice(1,-1)},p));else if(d[2])s.push(i.jsx("strong",{children:Ys(h.slice(2,-2),p)},p));else if(d[3])s.push(i.jsx("em",{children:Ys(h.slice(1,-1),p)},p));else if(d[4]){const g=h.match(/^\[([^\]]{1,300})\]\(([^)\s]{1,2000})\)$/),m=rl(g==null?void 0:g[2]);s.push(m?i.jsx("a",{href:m,target:"_blank",rel:"noreferrer noopener",className:"text-info underline",children:g==null?void 0:g[1]},p):i.jsx("span",{children:g==null?void 0:g[1]},p))}else if(d[5]){const g=rl(h);s.push(g?i.jsx("a",{href:g,target:"_blank",rel:"noreferrer noopener",className:"break-all text-info underline",children:h},p):h)}o=o.slice(d.index+h.length)}return s}function Ob(n,r){const s=n.match(/^\[([ xX])\]\s+(.*)$/);return s?i.jsxs("li",{className:"list-none",children:[i.jsx("span",{"aria-hidden":!0,className:"mr-1.5 font-mono text-muted-foreground",children:s[1]===" "?"[ ]":"[x]"}),Ys(s[2],r)]},r):i.jsx("li",{children:Ys(n,r)},r)}const Fb=["text-lg","text-base","text-sm","text-sm","text-sm","text-sm"];function Cm({source:n}){const r=Ab(n);return i.jsx("div",{className:"space-y-3 text-sm leading-relaxed",children:r.map((s,o)=>{const u=`b${o}`;switch(s.type){case"heading":{const d=`h${Math.min(s.level+2,6)}`;return i.jsx(d,{className:`${Fb[s.level-1]} mt-4 font-semibold first:mt-0`,children:Ys(s.text,u)},u)}case"para":return i.jsx("p",{children:Ys(s.text,u)},u);case"code":return i.jsx("pre",{className:"overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs",children:i.jsx("code",{children:s.text})},u);case"quote":return i.jsx("blockquote",{className:"border-l-2 pl-3 text-muted-foreground",children:Ys(s.text,u)},u);case"list":{const d=s.ordered?"ol":"ul";return i.jsx(d,{className:`${s.ordered?"list-decimal":"list-disc"} space-y-1 pl-5`,children:s.items.map((h,p)=>Ob(h,`${u}-${p}`))},u)}case"hr":return i.jsx("hr",{},u)}return null})})}const Nm=300;function Ib(n,r){const s=Ct(),[o,u]=k.useState([]),[d,h]=k.useState(null),[p,g]=k.useState("closed"),m=k.useRef(null);return k.useEffect(()=>{if(!r)return;g("connecting");const y=new EventSource(`/api/requests/${encodeURIComponent(n)}/stream`);return y.onopen=()=>g("open"),y.onerror=()=>g(y.readyState===EventSource.CLOSED?"closed":"connecting"),y.addEventListener("snapshot",w=>{let x;try{x=JSON.parse(w.data)}catch{return}const j=m.current;m.current=x,h(x),j&&(j.status!==x.status||j.planStatus!==x.planStatus||j.lastActivityAt!==x.lastActivityAt)&&(s.invalidateQueries({queryKey:Be.request(n)}),j.status!==x.status&&(s.invalidateQueries({queryKey:["requests","list"]}),s.invalidateQueries({queryKey:Be.dashboard})))}),y.addEventListener("activity",w=>{try{const x=JSON.parse(w.data);u(j=>j.length>=Nm?[...j.slice(-Nm+1),x]:[...j,x])}catch{}}),()=>{y.close(),g("closed")}},[n,r,s]),{activity:o,snapshot:d,state:p}}const zb=["live","conversation","turns","plans","artifacts","events"];function Ub(){var j;const{id:n=""}=uw(),r=Vj(n),[s,o]=qd();Wd();const u=(j=r.data)==null?void 0:j.request.status,d=u?!Lb.includes(u):!1,h=Ib(n,d),p=s.get("tab"),g=p&&zb.includes(p)&&(p!=="live"||d)?p:d?"live":"conversation",m=_=>o(E=>{const S=new URLSearchParams(E);return S.set("tab",_),S},{replace:!0});if(r.isLoading)return i.jsx(kt,{});if(r.isError||!r.data)return r.error instanceof Wn&&r.error.code==="not_found"?i.jsxs("div",{className:"space-y-4",children:[i.jsx(Em,{}),i.jsx(rn,{children:"This request does not exist."})]}):i.jsx(Ot,{error:r.error,onRetry:()=>void r.refetch()});const y=r.data,w=y.request,x=[...d?[{value:"live",label:i.jsx($b,{state:h.state})}]:[],{value:"conversation",label:`Conversation (${y.messages.length})`},{value:"turns",label:`Turns (${y.turns.length})`},{value:"plans",label:`Plans (${y.plans.length})`},{value:"artifacts",label:`Artifacts (${y.artifacts.length})`},{value:"events",label:"Events"}];return i.jsxs("div",{className:"space-y-6",children:[i.jsx(Em,{}),i.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[i.jsxs("div",{className:"min-w-0 space-y-2",children:[i.jsx("h1",{className:"break-words text-xl font-semibold",children:w.title}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm text-muted-foreground",children:[i.jsx(hl,{status:w.status}),w.planStatus!=="none"&&i.jsxs(tt,{variant:"outline",children:["Plan ",w.planStatus]}),i.jsxs("span",{children:["by ",w.requesterName??w.requesterId]}),i.jsxs("span",{children:["in ",w.channelName?`#${w.channelName}`:w.channelId]}),i.jsxs("span",{title:mn(w.createdAt),children:["opened ",Yt(w.createdAt)]}),i.jsxs("span",{children:["cost ",fl(w.costUsd)]})]})]}),i.jsx(dy,{request:w})]}),i.jsx(He,{children:i.jsxs(Qe,{className:"grid gap-x-8 gap-y-2 p-5 text-sm sm:grid-cols-2",children:[i.jsx(Lo,{label:"Branch",children:w.branch?i.jsx("code",{className:"text-xs",children:w.branch}):"None"}),i.jsx(Lo,{label:"Working directory",children:i.jsx("code",{className:"break-all text-xs",children:w.cwd||w.workdir})}),i.jsx(Lo,{label:"Last activity",children:i.jsx("span",{title:mn(w.lastActivityAt),children:Yt(w.lastActivityAt)})}),i.jsx(Lo,{label:"Pull requests",children:w.prs.length===0?"None":w.prs.map(_=>{const E=rl(_),S=y.prFollows.find(P=>P.url===_);return i.jsxs("span",{className:"mr-3 inline-block",children:[E?i.jsx("a",{href:E,target:"_blank",rel:"noreferrer noopener",className:"break-all text-info underline",children:my(_)}):_,S&&i.jsxs("span",{className:"ml-1 text-xs text-muted-foreground",title:S.statusReason??S.lastError??void 0,children:["(",Zb(S),")"]})]},_)})}),w.pendingQuestion&&i.jsxs("div",{className:"rounded-md border border-warning/40 bg-warning-muted p-3 sm:col-span-2",children:[i.jsx("p",{className:"text-xs font-medium text-amber-300",children:"Waiting for an answer in Slack"}),i.jsx("p",{className:"mt-1 whitespace-pre-wrap break-words",children:w.pendingQuestion})]})]})}),i.jsxs("div",{children:[i.jsx(hy,{idPrefix:"req",label:"Request details",items:x,value:g,onChange:m}),i.jsxs(py,{idPrefix:"req",value:g,children:[g==="live"&&i.jsx(qb,{activity:h.activity,state:h.state}),g==="conversation"&&i.jsx(Qb,{messages:y.messages}),g==="turns"&&i.jsx(Wb,{turns:y.turns}),g==="plans"&&i.jsx(Kb,{plans:y.plans}),g==="artifacts"&&i.jsx(Yb,{artifacts:y.artifacts,requestId:w.id}),g==="events"&&i.jsx(Xb,{events:y.events})]})]})]})}function Em(){return i.jsxs(Bt,{to:"/requests",className:"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground",children:[i.jsx(Tg,{className:"h-4 w-4","aria-hidden":!0}),"Requests"]})}function Lo({label:n,children:r}){return i.jsxs("div",{className:"flex gap-3",children:[i.jsx("span",{className:"w-36 shrink-0 text-muted-foreground",children:n}),i.jsx("span",{className:"min-w-0",children:r})]})}function my(n){const r=n.match(/github\.com\/([^/]+\/[^/]+)\/pull\/(\d+)/);return r?`${r[1]}#${r[2]}`:n}function $b({state:n}){return i.jsxs(i.Fragment,{children:[i.jsx("span",{"aria-hidden":!0,className:Xe("h-2 w-2 rounded-full",n==="open"?"animate-pulse bg-success":n==="connecting"?"bg-warning":"bg-muted-foreground")}),"Live"]})}function qb({activity:n,state:r}){const s=k.useRef(null),[o,u]=k.useState(!0);return k.useEffect(()=>{o&&s.current&&(s.current.scrollTop=s.current.scrollHeight)},[n,o]),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[i.jsx("span",{children:r==="open"?"Connected. Showing live agent activity.":r==="connecting"?"Connecting":"Disconnected"}),i.jsxs("label",{className:"flex items-center gap-2",children:[i.jsx("input",{type:"checkbox",checked:o,onChange:d=>u(d.target.checked),className:"accent-current"}),"Follow"]})]}),i.jsx("div",{ref:s,className:"h-96 overflow-y-auto rounded-md border bg-black/40 p-3 font-mono text-xs","aria-live":"off",children:n.length===0?i.jsx("p",{className:"text-muted-foreground",children:"No activity yet. It appears here while a turn runs."}):n.map((d,h)=>i.jsxs("div",{className:"flex gap-3 py-0.5",children:[i.jsx("span",{className:"shrink-0 text-muted-foreground",children:new Date(d.ts).toLocaleTimeString()}),i.jsx("span",{className:Xe("shrink-0 w-10",d.kind==="tool"?"text-info":"text-success"),children:d.kind}),i.jsx("span",{className:"min-w-0 whitespace-pre-wrap break-words",children:d.text})]},h))})]})}const Bb={mention:"Mention",follow_up:"Follow-up",prior_context:"Prior context",unlisted:"Unlisted user",synthetic:"System",command:"Command"},Hb=["prior_context","unlisted"];function Qb({messages:n}){return n.length?i.jsx("ol",{className:"space-y-3",children:n.map(r=>{const s=Hb.includes(r.source);return i.jsxs("li",{className:Xe("rounded-md border p-3",s&&"border-dashed border-warning/50 bg-warning-muted/40"),children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx("span",{className:"font-medium text-foreground",children:r.authorName??r.authorId??"System"}),i.jsxs(tt,{variant:s?"warning":"outline",children:[s&&i.jsx(L1,{className:"h-3 w-3","aria-hidden":!0}),Bb[r.source]]}),i.jsx(tt,{variant:r.state==="delivered"?"secondary":r.state==="pending"?"info":"muted",children:r.state}),i.jsx("span",{className:"ml-auto",title:mn(r.receivedAt),children:Yt(r.receivedAt)})]}),s&&i.jsx("p",{className:"mt-1 text-xs text-amber-300",children:"Untrusted: shown to the agent as context only, not as instructions."}),i.jsx("p",{className:"mt-2 whitespace-pre-wrap break-words text-sm",children:r.text})]},r.id)})}):i.jsx(rn,{children:"No messages."})}const Vb={answered:"success",asked:"warning",planned:"info",error:"destructive",cancelled:"muted",timeout:"destructive"};function wd({label:n,children:r,defaultOpen:s}){return i.jsxs("details",{className:"group mt-2",open:s,children:[i.jsxs("summary",{className:"flex cursor-pointer list-none items-center gap-1 text-xs text-muted-foreground hover:text-foreground",children:[i.jsx(_g,{className:"h-3 w-3 transition-transform group-open:rotate-90","aria-hidden":!0}),n]}),i.jsx("div",{className:"mt-2",children:r})]})}function Wb({turns:n}){return n.length?i.jsx("ol",{className:"space-y-3",children:n.map(r=>i.jsxs("li",{className:"rounded-md border p-3 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsxs("span",{className:"font-medium",children:["Turn ",r.seq]}),r.mode==="plan"&&i.jsx(tt,{variant:"outline",children:"Plan mode"}),r.outcome?i.jsx(tt,{variant:Vb[r.outcome],children:r.outcome}):i.jsx(tt,{variant:"secondary",children:r.status}),i.jsxs("span",{className:"text-xs text-muted-foreground",children:["trigger: ",r.trigger]}),i.jsx("span",{className:"ml-auto text-xs text-muted-foreground",title:mn(r.startedAt),children:r.startedAt?Yt(r.startedAt):"not started"})]}),i.jsxs("dl",{className:"mt-2 flex flex-wrap gap-x-6 gap-y-1 text-xs text-muted-foreground",children:[i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Duration "}),i.jsx("dd",{className:"inline text-foreground",children:yb(r.durationMs)})]}),i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Tokens "}),i.jsxs("dd",{className:"inline text-foreground",children:[jm(r.inputTokens)," in, ",jm(r.outputTokens)," out"]})]}),i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Cost "}),i.jsx("dd",{className:"inline text-foreground",children:fl(r.costUsd)})]}),r.stopReason&&i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Stop reason "}),i.jsx("dd",{className:"inline text-foreground",children:r.stopReason})]})]}),r.errorText&&i.jsx(wd,{label:"Error",defaultOpen:!0,children:i.jsx("pre",{className:"overflow-x-auto whitespace-pre-wrap break-words rounded bg-destructive-muted p-2 text-xs text-red-200",children:r.errorText})}),r.resultText&&i.jsx(wd,{label:"Result",children:i.jsx("pre",{className:"max-h-96 overflow-auto whitespace-pre-wrap break-words rounded bg-muted p-2 text-xs",children:r.resultText})})]},r.id))}):i.jsx(rn,{children:"No turns yet."})}function Kb({plans:n}){if(!n.length)return i.jsx(rn,{children:"No plans for this request."});const r=[...n].sort((s,o)=>o.version-s.version);return i.jsx("div",{className:"space-y-4",children:r.map((s,o)=>i.jsx(He,{children:i.jsxs(Qe,{className:"p-5",children:[i.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsxs("span",{className:"text-sm font-medium text-foreground",children:["Version ",s.version]}),i.jsx(tt,{variant:s.status==="approved"?"success":s.status==="rejected"?"destructive":"warning",children:s.status}),s.decidedBy&&i.jsxs("span",{children:["by ",s.decidedBy," ",s.decidedAt?Yt(s.decidedAt):""]}),i.jsx("span",{className:"ml-auto",children:mn(s.createdAt)})]}),s.feedback&&i.jsxs("div",{className:"mb-3 rounded-md border bg-muted/40 p-3 text-sm",children:[i.jsx("p",{className:"text-xs text-muted-foreground",children:"Feedback"}),i.jsx("p",{className:"mt-1 whitespace-pre-wrap break-words",children:s.feedback})]}),o===0?i.jsx(Cm,{source:s.markdown}):i.jsx(wd,{label:"Show plan",children:i.jsx(Cm,{source:s.markdown})})]})},s.version))})}function Gb({requestId:n}){var u;const s=((u=Rt({queryKey:["screenshots",n],queryFn:()=>Ee(`/api/requests/${encodeURIComponent(n)}/screenshots`),refetchInterval:15e3}).data)==null?void 0:u.items)??[];if(!s.length)return null;const o=d=>`/api/requests/${encodeURIComponent(n)}/screenshots/${d.split("/").map(encodeURIComponent).join("/")}`;return i.jsxs("div",{className:"space-y-2",children:[i.jsxs("h3",{className:"text-sm font-medium",children:["Screenshots (",s.length,")"]}),i.jsx("div",{className:"grid grid-cols-2 gap-3 md:grid-cols-3",children:s.map(d=>i.jsxs("a",{href:o(d.name),target:"_blank",rel:"noreferrer noopener",className:"group overflow-hidden rounded-md border",children:[i.jsx("img",{src:o(d.name),alt:d.name,loading:"lazy",className:"aspect-video w-full bg-muted object-cover object-top"}),i.jsxs("div",{className:"flex justify-between gap-2 px-2 py-1 text-xs text-muted-foreground",children:[i.jsx("span",{className:"truncate",children:d.name}),i.jsx("span",{className:"shrink-0",children:Yt(d.mtime)})]})]},d.name))})]})}function Yb({artifacts:n,requestId:r}){return i.jsxs("div",{className:"space-y-4",children:[i.jsx(Gb,{requestId:r}),i.jsx(Jb,{artifacts:n})]})}function Jb({artifacts:n}){return n.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.map(r=>{const s=r.kind==="pr"?Wk:r.kind==="screenshot"?Xk:zk,o=rl(r.urlOrPath);return i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx(s,{className:"h-4 w-4 shrink-0 text-muted-foreground","aria-hidden":!0}),i.jsxs("div",{className:"min-w-0 flex-1",children:[r.title&&i.jsx("p",{className:"truncate font-medium",children:r.title}),o?i.jsx("a",{href:o,target:"_blank",rel:"noreferrer noopener",className:"break-all text-xs text-info underline",children:r.kind==="pr"?my(r.urlOrPath):r.urlOrPath}):i.jsx("code",{className:"break-all text-xs text-muted-foreground",children:r.urlOrPath})]}),i.jsx("span",{className:"shrink-0 text-xs text-muted-foreground",children:Yt(r.createdAt)})]},r.id)})}):i.jsx(rn,{children:"No artifacts yet."})}function Xb({events:n}){return n.length?i.jsx("div",{className:"overflow-x-auto rounded-md border",children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Time"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Type"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Summary"})]})}),i.jsx("tbody",{className:"divide-y",children:n.map(r=>i.jsxs("tr",{children:[i.jsx("td",{className:"whitespace-nowrap px-3 py-1.5 text-xs text-muted-foreground",children:mn(r.ts)}),i.jsx("td",{className:"whitespace-nowrap px-3 py-1.5",children:i.jsx("code",{className:"text-xs",children:r.type})}),i.jsx("td",{className:"px-3 py-1.5 break-words",children:r.summary})]},r.id))})]})}):i.jsx(rn,{children:"No events."})}function Zb(n){const r=n.status==="active"?"following":n.status==="gave_up"?"left for a human":n.status==="paused"?"not following":n.status,s=n.status==="active"&&n.ci&&n.ci!=="none"?`, CI ${n.ci}`:"",o=n.status==="active"&&n.mergeable==="CONFLICTING"?", conflicts":"";return r+s+o}const Rm=50;function eS(){const[n,r]=qd(),s=Math.max(1,Number(n.get("page"))||1),o=ob(s,Rm);return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Audit log",description:"Admin sign-ins and configuration changes on this machine."}),o.isLoading?i.jsx(kt,{}):o.isError||!o.data?i.jsx(Ot,{error:o.error,onRetry:()=>void o.refetch()}):o.data.items.length===0?i.jsx(rn,{children:"No audit entries yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:Xe("overflow-x-auto rounded-lg border",o.isPlaceholderData&&"opacity-60"),children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Time"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Actor"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Action"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Detail"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"IP"})]})}),i.jsx("tbody",{className:"divide-y",children:o.data.items.map(u=>i.jsxs("tr",{children:[i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-muted-foreground",children:mn(u.ts)}),i.jsx("td",{className:"px-3 py-2",children:u.actor}),i.jsx("td",{className:"px-3 py-2",children:i.jsx("code",{className:"text-xs",children:u.action})}),i.jsx("td",{className:"max-w-md break-words px-3 py-2 text-muted-foreground",children:u.detail??""}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-xs text-muted-foreground",children:u.ip??""})]},u.id))})]})}),i.jsx(uy,{page:s,pageSize:Rm,total:o.data.total,onPage:u=>r(u===1?{}:{page:String(u)},{replace:!0})})]})]})}const ps=k.forwardRef(({checked:n,onCheckedChange:r,className:s,...o},u)=>i.jsx("button",{ref:u,type:"button",role:"switch","aria-checked":n,onClick:()=>r(!n),className:Xe("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",n?"bg-primary":"bg-input",s),...o,children:i.jsx("span",{className:Xe("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform",n?"translate-x-5":"translate-x-0")})}));ps.displayName="Switch";const Pm={pending:{label:"Waiting for confirmation",variant:"warning"},active:{label:"Active",variant:"success"},paused:{label:"Paused",variant:"muted"}};function tS(){const n=ub(),r=ry(),s=fb(),o=db(),[u,d]=k.useState(null),[h,p]=k.useState(null),g=(m,y)=>r.mutate({id:m.id,patch:{status:y?"active":"paused"}},{onError:w=>We({title:"Couldn't change the schedule",description:yt(w),variant:"error"})});return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Schedules",description:"Recurring tasks and one-time reminders people set up in Slack (for example daily insights in a channel). Each run posts its result in the channel; replies in its thread continue the conversation. A one-time task leaves this list after it runs."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):n.data.length===0?i.jsx(rn,{children:`No schedules yet. Ask the agent in Slack, e.g. "send a summary of yesterday's sales every weekday at 9:00 in this channel".`}):i.jsx("div",{className:"overflow-x-auto rounded-lg border",children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Schedule"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"When"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Channel"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Next run"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Last run"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"On"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:i.jsx("span",{className:"sr-only",children:"Actions"})})]})}),i.jsx("tbody",{className:"divide-y",children:n.data.map(m=>i.jsxs("tr",{className:"align-top",children:[i.jsxs("td",{className:"px-3 py-2",children:[i.jsx("button",{type:"button",className:"text-left font-medium hover:underline",onClick:()=>d(m),children:m.title}),i.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx(tt,{variant:Pm[m.status].variant,children:Pm[m.status].label}),i.jsxs("span",{children:["by ",m.createdByName??m.createdBy]})]}),m.statusReason&&i.jsx("div",{className:"mt-1 text-xs text-amber-300",children:m.statusReason})]}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2",children:[m.when,i.jsx("div",{className:"text-xs text-muted-foreground",children:m.timezone})]}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2",children:["#",m.channelName??m.channelId]}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-muted-foreground",children:m.nextRunAt?i.jsx("span",{title:mn(m.nextRunAt),children:Yt(m.nextRunAt)}):"—"}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2",children:m.lastRunAt?i.jsxs("div",{className:"flex items-center gap-2",children:[m.lastRunStatus==="missed"?i.jsx(tt,{variant:"muted",children:"Missed"}):m.lastRunStatus?i.jsx(hl,{status:m.lastRunStatus}):null,m.lastRequestId?i.jsx(Bt,{to:`/requests/${m.lastRequestId}`,className:"text-xs text-muted-foreground hover:underline",children:Yt(m.lastRunAt)}):i.jsx("span",{className:"text-xs text-muted-foreground",children:Yt(m.lastRunAt)})]}):i.jsx("span",{className:"text-muted-foreground",children:"Never"})}),i.jsx("td",{className:"px-3 py-2",children:i.jsx(ps,{checked:m.status==="active",disabled:m.status==="pending"||r.isPending,"aria-label":m.status==="active"?`Pause ${m.title}`:`Resume ${m.title}`,onCheckedChange:y=>g(m,y)})}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2 text-right",children:[i.jsxs(oe,{variant:"ghost",size:"sm",disabled:m.status==="pending"||s.isPending,onClick:()=>s.mutate(m.id,{onSuccess:()=>We({title:"Run started",description:`#${m.channelName??m.channelId}`,variant:"success"}),onError:y=>We({title:"Couldn't start the run",description:yt(y),variant:"error"})}),children:[i.jsx(p1,{className:"h-4 w-4","aria-hidden":!0})," Run now"]}),i.jsx(oe,{variant:"ghost",size:"sm",onClick:()=>d(m),"aria-label":`Edit ${m.title}`,children:i.jsx(f1,{className:"h-4 w-4","aria-hidden":!0})}),i.jsx(oe,{variant:"ghost",size:"sm",onClick:()=>p(m),"aria-label":`Delete ${m.title}`,children:i.jsx(qo,{className:"h-4 w-4","aria-hidden":!0})})]})]},m.id))})]})}),u&&i.jsx(nS,{schedule:u,onClose:()=>d(null)}),i.jsx(Gd,{open:!!h,title:"Delete this schedule?",description:h?`"${h.title}" stops running. Past runs stay in Requests.`:"",confirmLabel:"Delete",destructive:!0,pending:o.isPending,onClose:()=>p(null),onConfirm:()=>h&&o.mutate(h.id,{onSuccess:()=>p(null),onError:m=>We({title:"Couldn't delete",description:yt(m),variant:"error"})})})]})}function nS({schedule:n,onClose:r}){var E;const s=cb(n.id),o=ry(),[u,d]=k.useState(n.title),[h,p]=k.useState(n.prompt),[g,m]=k.useState(n.cron),[y,w]=k.useState(n.timezone),[x,j]=k.useState(null),_=()=>{j(null);const S={...u!==n.title&&{title:u},...h!==n.prompt&&{prompt:h},...g!==n.cron&&{cron:g},...y!==n.timezone&&{timezone:y}};if(!Object.keys(S).length)return r();o.mutate({id:n.id,patch:S},{onSuccess:()=>{We({title:"Schedule saved",variant:"success"}),r()},onError:P=>{var U,Q;const D=(Q=(U=P.body)==null?void 0:U.error)==null?void 0:Q.field;j({field:D,message:yt(P)})}})};return i.jsx(Kd,{open:!0,onClose:r,title:"Edit schedule",description:`${n.when} (${n.timezone}) · #${n.channelName??n.channelId}`,className:"max-w-2xl",footer:i.jsxs(i.Fragment,{children:[i.jsx(oe,{variant:"outline",onClick:r,children:"Cancel"}),i.jsx(oe,{onClick:_,disabled:o.isPending,children:"Save"})]}),children:i.jsxs("div",{className:"space-y-4",children:[i.jsx(Oe,{label:"Title",error:(x==null?void 0:x.field)==="title"?x.message:null,children:S=>i.jsx(Re,{...S,value:u,maxLength:80,onChange:P=>d(P.target.value)})}),i.jsx(Oe,{label:"What to do on each run",help:"Runs start without the original conversation, so keep this self-contained.",children:S=>i.jsx("textarea",{...S,value:h,maxLength:4e3,rows:6,onChange:P=>p(P.target.value),className:"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"})}),i.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[i.jsx(Oe,{label:"When (cron)",help:"minute hour day month weekday, e.g. 0 9 * * 1-5 for weekdays at 9:00",error:(x==null?void 0:x.field)==="cron"?x.message:null,children:S=>i.jsx(Re,{...S,value:g,onChange:P=>m(P.target.value),className:"font-mono"})}),i.jsx(Oe,{label:"Timezone",help:"e.g. America/Sao_Paulo",error:(x==null?void 0:x.field)==="timezone"?x.message:null,children:S=>i.jsx(Re,{...S,value:y,onChange:P=>w(P.target.value)})})]}),x&&!["title","cron","timezone"].includes(x.field??"")&&i.jsx("p",{className:"text-sm text-red-300",children:x.message}),i.jsxs("div",{children:[i.jsx("h3",{className:"mb-2 text-sm font-medium",children:"Recent runs"}),s.isLoading?i.jsx(kt,{}):(E=s.data)!=null&&E.runs.length?i.jsx("ul",{className:"divide-y rounded-md border text-sm",children:s.data.runs.map(S=>i.jsxs("li",{className:"flex items-center justify-between gap-2 px-3 py-2",children:[i.jsx(Bt,{to:`/requests/${S.requestId}`,className:"hover:underline",onClick:r,children:mn(S.createdAt)}),i.jsx(hl,{status:S.status})]},S.requestId))}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"No runs yet."})]})]})})}const rS=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/,sS="flex w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";function aS(){const n=hb();return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Setup",description:"Commands a fresh worktree needs before the agent starts: install dependencies, copy an example env file, build. They run in the same sandbox as the agent, once per worktree, without FDA's tokens or the Anthropic key. The agent can propose a script; it only runs after you approve it here."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):!n.data.workdir||!n.data.isRepo?i.jsxs(rn,{children:["Setup scripts run in per-request worktrees, so the working directory must be a git repository. The current one"," ",n.data.workdir?i.jsx("code",{children:n.data.workdir}):"isn't set",n.data.workdir?" isn't a repository":"","."]}):i.jsx(iS,{repoPath:n.data.workdir,row:n.data.scripts.find(r=>r.repoPath===n.data.workdir)??null})]})}function iS({repoPath:n,row:r}){const s=pb(),o=mb(),[u,d]=k.useState((r==null?void 0:r.script)??""),[h,p]=k.useState((r==null?void 0:r.onFailure)??"continue"),[g,m]=k.useState(String((r==null?void 0:r.timeoutSec)??600)),[y,w]=k.useState((r==null?void 0:r.enabled)??!0);k.useEffect(()=>{d((r==null?void 0:r.script)??""),p((r==null?void 0:r.onFailure)??"continue"),m(String((r==null?void 0:r.timeoutSec)??600)),w((r==null?void 0:r.enabled)??!0)},[r==null?void 0:r.updatedAt]);const x=E=>S=>We({title:E,description:yt(S),variant:"error"}),j=()=>s.mutate({repoPath:n,script:u.trim()||null,onFailure:h,timeoutSec:Number(g),enabled:y},{onSuccess:()=>We({title:"Setup script saved"}),onError:x("Couldn't save the setup script")}),_=E=>{var S;return o.mutate({repoPath:n,action:E,proposedAt:((S=r==null?void 0:r.proposal)==null?void 0:S.at)??null},{onSuccess:()=>We(E==="approve"?{title:"Proposal approved",description:"It's saved and runs in every new worktree (no need to press Save)."}:{title:"Proposal dismissed"}),onError:x("Couldn't update the proposal")})};return i.jsxs("div",{className:"space-y-4",children:[(r==null?void 0:r.proposal)&&i.jsx(He,{className:"border-warning/40",children:i.jsxs(Qe,{className:"space-y-3 p-5 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsx(tt,{variant:"warning",children:"Proposed by the agent"}),r.proposal.at&&i.jsx("span",{className:"text-muted-foreground",title:mn(r.proposal.at),children:Yt(r.proposal.at)}),r.proposal.requestId&&i.jsx(Bt,{to:`/requests/${r.proposal.requestId}`,className:"text-info underline",children:"from this request"})]}),r.proposal.reason&&i.jsx("p",{children:r.proposal.reason}),rS.test(r.proposal.script)&&i.jsx("p",{className:"text-xs font-medium text-destructive",children:"This script contains invisible or direction-changing characters. Don't approve it unless you know why."}),i.jsx("pre",{className:"max-h-72 overflow-auto rounded-md bg-muted/40 p-3 font-mono text-xs",children:r.proposal.script}),i.jsx("p",{className:"text-xs text-muted-foreground",children:"Read it before approving: it will run in every new worktree."}),i.jsxs("div",{className:"flex gap-2",children:[i.jsx(oe,{size:"sm",onClick:()=>_("approve"),disabled:o.isPending,children:"Approve and use"}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>_("reject"),disabled:o.isPending,children:"Dismiss"})]})]})}),i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-4 p-5",children:[i.jsxs("p",{className:"text-sm",children:["Repository ",i.jsx("code",{className:"text-xs",children:n})]}),i.jsx(Oe,{label:"Script",help:"Runs with bash in the new worktree. Example: npm ci && cp -n .env.example .env",children:E=>i.jsx("textarea",{...E,value:u,rows:8,maxLength:2e4,spellCheck:!1,placeholder:"npm ci",onChange:S=>d(S.target.value),className:sS})}),i.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[i.jsx(Oe,{label:"If it fails",help:"Continue tells the agent what failed; Stop fails the request.",children:E=>i.jsxs(eu,{...E,value:h,onChange:S=>p(S.target.value),children:[i.jsx("option",{value:"continue",children:"Continue"}),i.jsx("option",{value:"fail",children:"Stop"})]})}),i.jsx(Oe,{label:"Timeout (seconds)",help:"10 to 3600.",children:E=>i.jsx(Re,{...E,type:"number",min:10,max:3600,value:g,onChange:S=>m(S.target.value)})}),i.jsxs("div",{className:"space-y-1.5",children:[i.jsx("p",{className:"text-sm font-medium",children:"Enabled"}),i.jsx(ps,{checked:y,onCheckedChange:w,"aria-label":"Run the setup script"})]})]}),i.jsx(oe,{onClick:j,disabled:s.isPending,children:"Save"})]})}),i.jsxs("div",{children:[i.jsx("h2",{className:"mb-2 text-sm font-medium",children:"Recent runs"}),r!=null&&r.runs.length?i.jsx("ul",{className:"divide-y rounded-md border",children:r.runs.map(E=>i.jsxs("li",{className:"space-y-2 p-3 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsx(tt,{variant:E.status==="ok"?"success":E.status==="timeout"?"warning":"destructive",children:E.status==="ok"?"OK":E.status==="timeout"?"Timed out":`Failed (exit ${E.exitCode??"?"})`}),i.jsx("span",{className:"text-muted-foreground",title:mn(E.startedAt),children:Yt(E.startedAt)}),E.durationMs!==null&&i.jsxs("span",{className:"text-muted-foreground",children:[Math.round(E.durationMs/1e3),"s"]}),i.jsx(Bt,{to:`/requests/${E.requestId}`,className:"text-info underline",children:"request"})]}),E.log&&i.jsxs("details",{children:[i.jsx("summary",{className:"cursor-pointer text-xs text-muted-foreground",children:"Output"}),i.jsx("pre",{className:"mt-2 max-h-72 overflow-auto rounded-md bg-muted/40 p-3 font-mono text-xs",children:E.log})]})]},E.id))}):i.jsx(rn,{children:"No runs yet."})]})]})}const kd=["browser"],lS=new Set(["Enter","Tab","Backspace","Delete","Escape","Home","End","PageUp","PageDown","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]);function oS(){return Rt({queryKey:kd,queryFn:()=>Ee("/api/browser"),refetchInterval:2e4})}function gy(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"sites"in r&&n.setQueryData(kd,r)},onSettled:()=>void n.invalidateQueries({queryKey:kd})})}function uS(){const n=oS();return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Browser",description:"Sign the agent in to the sites it needs (a staging app, a dashboard). You drive a browser on this machine from here; Save and close keeps its cookies (encrypted), and every browser task starts signed in. Use test accounts: the agent can read what its browser holds."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):n.data.installed?i.jsxs(i.Fragment,{children:[!n.data.enabled&&i.jsx("p",{className:"rounded-md border border-warning/50 bg-warning-muted p-3 text-sm",children:"The browser is off for tasks (Settings → General → Browser). You can still save sign-ins now; tasks use them once it's on."}),i.jsx(cS,{data:n.data}),i.jsx(dS,{data:n.data})]}):i.jsxs(rn,{children:["The browser isn't installed on this machine. Install it there with"," ",i.jsx("code",{children:"superclawd fda browser install"}),", then enable it in Settings → General."]})]})}function cS({data:n}){const r=gy(),[s,o]=k.useState(""),[u,d]=k.useState(null),h=k.useRef(null),p=k.useRef(null),g=n.session.open,{width:m,height:y}=n.session.viewport;k.useEffect(()=>{if(!g){d(null);return}const P=new EventSource("/api/browser/session/stream");return P.addEventListener("frame",D=>{const U=JSON.parse(D.data);d({src:`data:image/jpeg;base64,${U.data}`,url:U.url,title:U.title,tabs:U.tabs})}),P.addEventListener("closed",()=>P.close()),P.addEventListener("expired",()=>P.close()),()=>P.close()},[g]),k.useEffect(()=>{var P;u!=null&&u.url&&((P=document.activeElement)==null?void 0:P.id)!=="browser-address"&&o(u.url)},[u==null?void 0:u.url]);const w=P=>D=>We({title:P,description:yt(D),variant:"error"}),x=P=>Ee("/api/browser/session/input",{method:"POST",body:P}).catch(w("Couldn't send that to the browser")),j=P=>{const D=h.current.getBoundingClientRect();return{x:Math.round((P.clientX-D.left)/D.width*m),y:Math.round((P.clientY-D.top)/D.height*y)}},_=P=>r.mutateAsync({path:"/api/browser/session",body:{url:P}}).catch(w("Couldn't open the page")),E=P=>{if(!g)return;const D=[P.ctrlKey&&"Control",P.altKey&&"Alt",P.metaKey&&"Meta"].filter(Boolean);lS.has(P.key)?(P.preventDefault(),x({type:"key",key:[...D,...P.shiftKey?["Shift"]:[],P.key].join("+")})):P.key.length===1&&D.length?(P.preventDefault(),x({type:"key",key:[...D,P.key].join("+")})):P.key.length===1&&(P.preventDefault(),x({type:"text",text:P.key}))},S=P=>{const D=P.clipboardData.getData("text/plain");!D||!g||(P.preventDefault(),x({type:"text",text:D.slice(0,2e3)}))};return i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6",children:[i.jsxs("form",{className:"flex items-center gap-2",onSubmit:P=>{P.preventDefault(),s.trim()&&_(s.trim())},children:[i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Back",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"back"}}).catch(w("Couldn't go back")),children:i.jsx(Tg,{className:"h-4 w-4"})}),i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Forward",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"forward"}}).catch(w("Couldn't go forward")),children:i.jsx(Lg,{className:"h-4 w-4"})}),i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Reload",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"reload"}}).catch(w("Couldn't reload")),children:i.jsx(k1,{className:"h-4 w-4"})}),i.jsx(Re,{id:"browser-address",value:s,onChange:P=>o(P.target.value),placeholder:"https://staging.example.com/login","aria-label":"Address",className:"flex-1"}),i.jsxs(oe,{type:"submit",disabled:r.isPending||!s.trim(),children:[i.jsx(Ag,{className:"mr-1 h-4 w-4"}),g?"Go":"Open browser"]})]}),g?i.jsxs(i.Fragment,{children:[i.jsx("div",{ref:p,tabIndex:0,role:"application","aria-label":"Remote browser: click to focus, then type",className:"relative overflow-hidden rounded-md border bg-muted outline-none focus:ring-2 focus:ring-ring",onKeyDown:E,onPaste:S,children:u?i.jsx("img",{ref:h,src:u.src,alt:u.title||"Remote browser",draggable:!1,className:"block w-full cursor-pointer select-none",style:{aspectRatio:`${m} / ${y}`},onClick:P=>{var D;(D=p.current)==null||D.focus(),x({type:"click",...j(P)})},onDoubleClick:P=>void x({type:"click",double:!0,...j(P)}),onContextMenu:P=>{P.preventDefault(),x({type:"click",button:"right",...j(P)})},onWheel:P=>void x({type:"wheel",...j(P),dx:Math.round(P.deltaX),dy:Math.round(P.deltaY)})}):i.jsx("div",{className:"flex items-center justify-center text-sm text-muted-foreground",style:{aspectRatio:`${m} / ${y}`},children:"Loading the page…"})}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx("span",{children:"Click the page, then type. Paste works too. Passwords you type go straight to the site; they aren't stored by FDA."}),u&&u.tabs>1&&i.jsxs(tt,{variant:"secondary",children:[u.tabs," tabs (showing the newest)"]}),!n.session.sandboxed&&i.jsx(tt,{variant:"secondary",children:"Chrome sandbox unavailable on this host"}),n.session.idleClosesAt&&i.jsxs("span",{children:["Closes when idle, latest ",mn(n.session.idleClosesAt),"."]})]}),i.jsxs("div",{className:"flex gap-2",children:[i.jsxs(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/browser/session/save",body:{close:!0}}).then(()=>We({title:"Sign-ins saved",description:"New browser tasks start signed in. Open the browser again to add another site."})).catch(w("Couldn't save the sign-ins")),children:[i.jsx(b1,{className:"mr-1 h-4 w-4"}),"Save and close"]}),i.jsxs(oe,{variant:"outline",disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/browser/session",method:"DELETE"}).catch(w("Couldn't close the browser")),children:[i.jsx(Bd,{className:"mr-1 h-4 w-4"}),"Close without saving"]})]})]}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"Enter the sign-in page of a site and open the browser. Sign in as you normally would (including two-factor), then Save and close."})]})})}function dS({data:n}){const r=gy(),[s,o]=k.useState(null),u=d=>h=>We({title:d,description:yt(h),variant:"error"});return i.jsxs(He,{children:[i.jsxs(Qe,{className:"space-y-3 pt-6",children:[i.jsxs("div",{className:"flex items-center justify-between",children:[i.jsx("h2",{className:"font-medium",children:"Signed-in sites"}),n.sites.length>1&&i.jsx(oe,{variant:"outline",size:"sm",onClick:()=>o("all"),children:"Sign out of all"})]}),n.sites.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.sites.map(d=>i.jsxs("li",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:d.site}),i.jsxs("span",{className:"text-muted-foreground",children:[d.cookies," cookie",d.cookies===1?"":"s",d.origins?`, local storage on ${d.origins}`:"",d.expiresAt?`, until ${mn(d.expiresAt)}`:", session only"]}),i.jsxs(oe,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>o(d.site),children:[i.jsx(Dg,{className:"mr-1 h-4 w-4"}),"Sign out"]})]},d.site))}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"None yet. Browser tasks start with a clean browser."}),i.jsx("p",{className:"text-xs text-muted-foreground",children:"Signing out here removes the saved cookies from this machine. It doesn't end the session on the site itself; to be sure, sign out there or change the password."})]}),i.jsx(Gd,{open:s!==null,onClose:()=>o(null),title:s==="all"?"Sign out of all sites?":`Sign out of ${s}?`,description:"New browser tasks will start without these sign-ins.",confirmLabel:"Sign out",destructive:!0,onConfirm:()=>{const d=s;o(null),r.mutateAsync({path:d==="all"?"/api/browser/sites":`/api/browser/sites/${encodeURIComponent(d)}`,method:"DELETE"}).catch(u("Couldn't sign out"))}})]})}function Js({text:n,label:r="Copy"}){const[s,o]=k.useState(!1),u=async()=>{try{await navigator.clipboard.writeText(n),o(!0),setTimeout(()=>o(!1),1500)}catch{We({title:"Could not copy",description:"Select the text and copy it manually.",variant:"error"})}};return i.jsxs(oe,{variant:"outline",size:"sm",onClick:u,children:[s?i.jsx(Mg,{}):i.jsx(_k,{}),s?"Copied":r]})}const yy=["tickets"],fS={queued:{label:"Queued",variant:"muted"},working:{label:"Working",variant:"info"},waiting:{label:"Waiting for a reply",variant:"warning"},in_review:{label:"PR in review",variant:"info"},done:{label:"Done",variant:"success"},released:{label:"Taken off",variant:"muted"},refused:{label:"Refused",variant:"destructive"}};function hS(){return Rt({queryKey:yy,queryFn:()=>Ee("/api/tickets"),refetchInterval:15e3})}function Xa(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"items"in r&&n.setQueryData(yy,r)}})}const Vn=n=>r=>We({title:n,description:yt(r),variant:"error"});function pS(){const n=hS(),r=Xa();if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const s=n.data;return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Tickets",description:"People hand tickets to the agent in Linear (assign or @mention it) or GitHub (a label). It works them one at a time in its own worktree, opens a pull request, follows CI and reviews, and replies on the ticket. Only people on the access list can hand tickets over; the ticket's text is treated as data, not instructions.",actions:i.jsxs(oe,{variant:"outline",size:"sm",disabled:r.isPending||!s.settings.enabled,onClick:()=>void r.mutateAsync({path:"/api/tickets/poll"}).then(o=>We({title:"Checked",description:`${o.handled} new event(s).`})).catch(Vn("Couldn't check the trackers")),children:[i.jsx(y1,{className:"mr-1 h-4 w-4"}),"Check now"]})}),i.jsx(mS,{d:s}),i.jsx(gS,{d:s}),i.jsx(yS,{d:s}),s.jira.available&&i.jsx(vS,{d:s}),i.jsx(xS,{d:s}),i.jsx(wS,{d:s})]})}function Xi({label:n,help:r,checked:s,onChange:o}){return i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"font-medium",children:n}),i.jsx("p",{className:"text-sm text-muted-foreground",children:r})]}),i.jsx(ps,{checked:s,onCheckedChange:o,"aria-label":n})]})}function mS({d:n}){const r=Xa(),s=n.settings,[o,u]=k.useState(String(s.atATime)),[d,h]=k.useState(s.budgetUsd===null?"":String(s.budgetUsd)),[p,g]=k.useState(s.dailyBudgetUsd===null?"":String(s.dailyBudgetUsd)),[m,y]=k.useState(s.statusOnPr??""),[w,x]=k.useState(s.statusOnQuestion??""),[j,_]=k.useState(s.questionReminderHours===null?"":String(s.questionReminderHours)),[E,S]=k.useState(s.slackChannel??""),P=(D,U)=>r.mutateAsync({path:"/api/tickets",method:"PUT",body:D}).then(()=>U&&We({title:U,variant:"success"})).catch(Vn("Couldn't save"));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"How it works on tickets"}),i.jsx(Tt,{children:"Off by default. Turn it on once a tracker is connected."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(Xi,{label:"Work on handed-over tickets",help:"Off: tickets are ignored (nothing is read or posted).",checked:s.enabled,onChange:D=>void P({enabled:D})}),i.jsx(Xi,{label:"Auto-merge pull requests",help:"Turns on GitHub auto-merge for a ticket's PR: it merges only when required checks and approvals pass. Off: people merge.",checked:s.autoMerge,onChange:D=>void P({autoMerge:D})}),i.jsx(Xi,{label:"Move tickets to In Progress",help:"When work starts (Linear: the team's first started state).",checked:s.statusOnStart,onChange:D=>void P({statusOnStart:D})}),i.jsx(Xi,{label:"DM the person when a ticket needs them",help:"A question or plan on a ticket mentions whoever handed it over there, and (when their email matches a Slack person) sends them a Slack DM. Needs the im:write scope.",checked:s.dmOnQuestion,onChange:D=>void P({dmOnQuestion:D})}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Tickets at a time",help:"Pull requests in review don't count.",children:D=>i.jsx(Re,{...D,type:"number",min:1,max:8,value:o,onChange:U=>u(U.target.value)})}),i.jsx(Oe,{label:"Budget per ticket (USD)",help:"All its turns together. Empty: unlimited.",children:D=>i.jsx(Re,{...D,type:"number",min:.5,step:.5,value:d,placeholder:"Unlimited",onChange:U=>h(U.target.value)})}),i.jsx(Oe,{label:"Daily budget for tickets (USD)",help:"Tickets wait once it's spent. Empty: unlimited.",children:D=>i.jsx(Re,{...D,type:"number",min:1,value:p,placeholder:"Unlimited",onChange:U=>g(U.target.value)})}),i.jsx(Oe,{label:"State when the PR opens",help:"By name, e.g. In Review (empty: don't move).",children:D=>i.jsx(Re,{...D,value:m,onChange:U=>y(U.target.value),placeholder:"In Review"})}),i.jsx(Oe,{label:"State while waiting on a question",help:"By name, e.g. Blocked (GitHub: a label). Moved back when answered. Empty: don't move.",children:D=>i.jsx(Re,{...D,value:w,onChange:U=>x(U.target.value),placeholder:"Blocked"})}),i.jsx(Oe,{label:"Remind after (hours)",help:"One reminder on the ticket and by DM if nobody answers. Empty: never.",children:D=>i.jsx(Re,{...D,type:"number",min:1,max:720,value:j,placeholder:"Never",onChange:U=>_(U.target.value)})}),i.jsx(Oe,{label:"PR review channel",help:"Optional. The FDA posts each pull request it opens here and reacts when it's merged. Channel id (C…).",children:D=>i.jsx(Re,{...D,value:E,onChange:U=>S(U.target.value),placeholder:"C0123456789"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void P({atATime:Number(o),budgetUsd:d.trim()?Number(d):null,dailyBudgetUsd:p.trim()?Number(p):null,statusOnPr:m.trim(),statusOnQuestion:w.trim(),questionReminderHours:j.trim()?Number(j):null,slackChannel:E.trim()},"Saved"),children:"Save"})]})]})}function gS({d:n}){const r=Xa(),s=n.linear,[o,u]=k.useState(s.clientId??""),[d,h]=k.useState(""),[p,g]=k.useState(s.teams.join(", "));return k.useEffect(()=>u(s.clientId??""),[s.clientId]),i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Linear"}),i.jsx(Tt,{children:"The agent is a Linear app (agents don't take a paid seat). People delegate an issue to it or @mention it; it reports in the issue's agent session. Create an OAuth app in Linear (Settings → API → OAuth applications), with this redirect URI, then connect it as an app."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Workspace:"}),s.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:s.workspace}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/tickets/linear/connection",method:"DELETE"}).catch(Vn("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!s.configured,onClick:()=>void Ee("/api/tickets/linear/connect",{method:"POST"}).then(m=>window.location.assign(m.url)).catch(Vn("Couldn't start the Linear install")),children:"Connect Linear"}),!s.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the client below first."})]})]}),i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Callback URL (add it to the Linear OAuth app)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:s.redirectUri}),i.jsx(Js,{text:s.redirectUri})]})]}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Client ID",children:m=>i.jsx(Re,{...m,value:o,onChange:y=>u(y.target.value)})}),i.jsx(Oe,{label:"Client secret",help:s.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:m=>i.jsx(Re,{...m,type:"password",autoComplete:"off",value:d,onChange:y=>h(y.target.value),placeholder:s.hasSecret?"••••••••":""})}),i.jsx(Oe,{label:"Teams",help:"Team keys, comma separated (empty: every team it can see).",children:m=>i.jsx(Re,{...m,value:p,onChange:y=>g(y.target.value),placeholder:"ENG, OPS"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{linearClientId:o.trim(),...d.trim()?{linearClientSecret:d.trim()}:{},linearTeams:p.split(",").map(m=>m.trim()).filter(Boolean)}}).then(()=>{h(""),We({title:"Linear saved",variant:"success"})}).catch(Vn("Couldn't save Linear")),children:"Save"})]})]})}function yS({d:n}){const r=Xa(),[s,o]=k.useState(n.github.repos.join(", ")),[u,d]=k.useState(n.github.label),[h,p]=k.useState(n.github.people.join(", "));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"GitHub Issues"}),i.jsx(Tt,{children:"GitHub doesn't let apps be assignees, so an issue is handed over with a label. Whoever adds it must be listed under People and have write access. Uses this machine's GitHub login (the same as pull requests); replies are comments."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[i.jsx(Oe,{label:"Repositories",help:"owner/name, comma separated.",children:g=>i.jsx(Re,{...g,value:s,onChange:m=>o(m.target.value),placeholder:"acme/web, acme/api"})}),i.jsx(Oe,{label:"Label",children:g=>i.jsx(Re,{...g,value:u,onChange:m=>d(m.target.value)})}),i.jsx(Oe,{label:"People",help:"GitHub logins allowed to hand issues over and talk to the agent (they also need write access), comma separated. Add a work email to reach them in Slack when the agent has a question: ana <ana@acme.com>.",children:g=>i.jsx(Re,{...g,value:h,onChange:m=>p(m.target.value),placeholder:"ana <ana@acme.com>, bo"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{githubPeople:h.split(",").map(g=>g.trim()).filter(Boolean),githubRepos:s.split(",").map(g=>g.trim()).filter(Boolean),githubLabel:u.trim()}}).then(()=>We({title:"GitHub saved",variant:"success"})).catch(Vn("Couldn't save GitHub")),children:"Save"})]})]})}function vS({d:n}){const r=Xa(),s=n.jira.available?n.jira:null,[o,u]=k.useState((s==null?void 0:s.clientId)??""),[d,h]=k.useState(""),[p,g]=k.useState((s==null?void 0:s.siteInput)??""),[m,y]=k.useState(((s==null?void 0:s.projects)??[]).join(", ")),[w,x]=k.useState((s==null?void 0:s.label)??""),[j,_]=k.useState(((s==null?void 0:s.people)??[]).join(", "));return k.useEffect(()=>u((s==null?void 0:s.clientId)??""),[s==null?void 0:s.clientId]),s?i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Jira"}),i.jsx(Tt,{children:`The agent uses its own Jira user (e.g. "Jim"). People hand an issue over by assigning it to that user (or with the optional label); comments are the conversation. Create an OAuth 2.0 (3LO) app at developer.atlassian.com with the Jira scopes read:jira-work, write:jira-work and read:jira-user and this callback URL, then connect while signed in to Atlassian as the agent's user.`})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Site:"}),s.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:s.site}),s.account&&i.jsxs("span",{className:"text-muted-foreground",children:["as ",s.account]}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/tickets/jira/connection",method:"DELETE"}).catch(Vn("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!s.configured,onClick:()=>void Ee("/api/tickets/jira/connect",{method:"POST"}).then(E=>window.location.assign(E.url)).catch(Vn("Couldn't start the Jira sign-in")),children:"Connect Jira"}),!s.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the client below first."})]})]}),i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Callback URL (add it to the Atlassian app)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:s.redirectUri}),i.jsx(Js,{text:s.redirectUri})]})]}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Client ID",children:E=>i.jsx(Re,{...E,value:o,onChange:S=>u(S.target.value)})}),i.jsx(Oe,{label:"Secret",help:s.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:E=>i.jsx(Re,{...E,type:"password",autoComplete:"off",value:d,onChange:S=>h(S.target.value),placeholder:s.hasSecret?"••••••••":""})}),i.jsx(Oe,{label:"Site",help:"Only needed if the agent's account reaches several sites.",children:E=>i.jsx(Re,{...E,value:p,onChange:S=>g(S.target.value),placeholder:"https://acme.atlassian.net"})}),i.jsx(Oe,{label:"Projects",help:"Project keys, comma separated (empty: every project it can see).",children:E=>i.jsx(Re,{...E,value:m,onChange:S=>y(S.target.value),placeholder:"ENG, OPS"})}),i.jsx(Oe,{label:"Hand-over label (optional)",help:"Adding this label also hands an issue over.",children:E=>i.jsx(Re,{...E,value:w,onChange:S=>x(S.target.value),placeholder:"fda"})}),i.jsx(Oe,{label:"People without a visible email",help:"People are matched to Slack by email. When Jira hides someone's email, add their Jira account id here (a refused ticket shows it).",children:E=>i.jsx(Re,{...E,value:j,onChange:S=>_(S.target.value),placeholder:"712020:…"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{jiraClientId:o.trim(),...d.trim()?{jiraClientSecret:d.trim()}:{},jiraSite:p.trim(),jiraProjects:m.split(",").map(E=>E.trim()).filter(Boolean),jiraLabel:w.trim(),jiraPeople:j.split(",").map(E=>E.trim()).filter(Boolean)}}).then(()=>{h(""),We({title:"Jira saved",variant:"success"})}).catch(Vn("Couldn't save Jira")),children:"Save"})]})]}):null}function xS({d:n}){const r=Xa(),[s,o]=k.useState(""),[u,d]=k.useState(null),h=n.bridge,p=(g,m=!1)=>Ee(`/api/tickets/bridge/${g}`,{method:"POST",body:{rotate:m}}).then(y=>{y.secret&&d(y.secret),r.mutateAsync({path:"/api/tickets",method:"PUT",body:{}}),We({title:"Webhook URL ready",variant:"success"})}).catch(Vn("Couldn't set up the webhook"));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Instant updates (optional)"}),i.jsx(Tt,{children:"Without this, the agent checks Linear every 15 seconds and GitHub every minute. With it, the tracker's webhook goes to SuperClawd's bridge (this machine stays unreachable from the internet), which wakes the agent right away. No ticket data is stored there."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(Xi,{label:"Use the webhook bridge",help:"Polling keeps running either way (a missed webhook only delays).",checked:h.enabled,onChange:g=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{bridge:g}}).catch(Vn("Couldn't change it"))}),i.jsxs("div",{className:"space-y-2 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Linear"}),i.jsx("p",{className:"text-muted-foreground",children:"In the Linear OAuth app: enable Webhooks, select Agent session events and Inbox notifications, paste the URL below, and copy Linear's signing secret here."}),i.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[i.jsx("div",{className:"min-w-64 flex-1",children:i.jsx(Oe,{label:"Linear webhook signing secret",children:g=>i.jsx(Re,{...g,type:"password",autoComplete:"off",value:s,onChange:m=>o(m.target.value),placeholder:h.linear.hasSecret?"••••••••":"lin_wh_…"})})}),i.jsx(oe,{variant:"outline",disabled:!s.trim()&&!h.linear.hasSecret,onClick:()=>void(s.trim()?r.mutateAsync({path:"/api/tickets",method:"PUT",body:{linearWebhookSecret:s.trim()}}):Promise.resolve()).then(()=>(o(""),p("linear"))),children:"Get the webhook URL"})]}),h.linear.hasSecret&&i.jsx("p",{className:"text-xs text-muted-foreground",children:"Secret saved."}),h.linear.url&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.linear.url}),i.jsx(Js,{text:h.linear.url})]})]}),i.jsxs("div",{className:"space-y-2 text-sm",children:[i.jsx("p",{className:"font-medium",children:"GitHub"}),i.jsx("p",{className:"text-muted-foreground",children:"In each repository: Settings → Webhooks → Add webhook. Payload URL and secret below, content type application/json, events: Issues and Issue comments."}),i.jsx(oe,{variant:"outline",onClick:()=>void p("github",h.github.hasSecret),children:h.github.url?"New secret + URL":"Get the webhook URL and secret"}),h.github.url&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.github.url}),i.jsx(Js,{text:h.github.url})]}),u&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{children:"Secret (shown once):"}),i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:u}),i.jsx(Js,{text:u})]})]})]})]})}function wS({d:n}){return i.jsxs(He,{children:[i.jsx(ot,{children:i.jsx(ut,{children:"Recent tickets"})}),i.jsx(Qe,{children:n.items.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.items.map(r=>{const s=fS[r.state]??{label:r.state,variant:"muted"};return i.jsxs("li",{className:"flex flex-wrap items-center gap-3 px-3 py-2 text-sm",children:[r.url?i.jsx("a",{href:r.url,target:"_blank",rel:"noreferrer noopener",className:"font-medium text-info underline",children:r.key}):i.jsx("span",{className:"font-medium",children:r.key}),i.jsx("span",{className:"min-w-0 flex-1 truncate",children:r.title}),i.jsx(tt,{variant:s.variant,children:s.label}),r.statusNote&&i.jsx("span",{className:"text-xs text-muted-foreground",children:r.statusNote}),r.prUrl&&i.jsx("a",{href:r.prUrl,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-info underline",children:"PR"}),i.jsx("span",{className:"text-xs text-muted-foreground",children:fl(r.costUsd)}),r.requestId&&i.jsx(Bt,{to:`/requests/${r.requestId}`,className:"text-xs text-info underline",children:"Request"}),i.jsxs("span",{className:"text-xs text-muted-foreground",children:[r.delegator?`${r.delegator} · `:"",Yt(r.updatedAt)]})]},r.id)})}):i.jsx(rn,{children:"No tickets yet."})})]})}function kS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/trackers/linear/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The install was cancelled.":"Linear didn't complete the install."});return}Ee("/api/tickets/linear/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,workspace:h.linear.workspace})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Linear is connected",n.workspace?i.jsxs(i.Fragment,{children:[" ","to ",i.jsx("code",{children:n.workspace})]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Linear"}),i.jsx(Bt,{to:"/tickets",className:"text-info underline",children:"Back to Tickets"})]})})})}function jS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/trackers/jira/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The sign-in was cancelled.":"Atlassian didn't complete the sign-in."});return}Ee("/api/tickets/jira/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,site:h.jira.site??null,account:h.jira.account??null})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Jira is connected",n.site?i.jsxs(i.Fragment,{children:[" ","to ",i.jsx("code",{children:n.site})]}):null,n.account?i.jsxs(i.Fragment,{children:[" as ",n.account]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Jira"}),i.jsx(Bt,{to:"/tickets",className:"text-info underline",children:"Back to Tickets"})]})})})}const bS=[{to:"agent",label:"Agent"},{to:"anthropic",label:"Anthropic"},{to:"general",label:"General"},{to:"slack",label:"Slack"},{to:"access",label:"Access"},{to:"calendar",label:"Calendar"},{to:"account",label:"Account"}];function SS(){return i.jsxs("div",{children:[i.jsx(ys,{title:"Settings",description:"Configure this FDA machine."}),i.jsxs("div",{className:"flex flex-col gap-6 md:flex-row",children:[i.jsx("nav",{"aria-label":"Settings",className:"flex shrink-0 gap-1 overflow-x-auto md:w-44 md:flex-col",children:bS.map(n=>i.jsx($d,{to:n.to,className:({isActive:r})=>Xe("rounded-md px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",r?"bg-accent font-medium":"text-muted-foreground hover:bg-accent/60 hover:text-foreground"),children:n.label},n.to))}),i.jsx("div",{className:"min-w-0 flex-1",children:i.jsx(Id,{})})]})]})}function CS(){var h,p,g;const n=Gj(),r=Yj(),[s,o]=k.useState(null),u=((p=(h=n.data)==null?void 0:h.selected)==null?void 0:p.id)??null,d=s??u;return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Primary agent"}),i.jsx(Tt,{children:"The SuperClawd agent FDA runs as. It brings its skills, guardrails and memories from your workspace."})]}),i.jsxs(Qe,{className:"space-y-4",children:[((g=n.data)==null?void 0:g.selected)&&i.jsxs("p",{className:"text-sm",children:["Current:"," ",i.jsx("span",{className:"font-medium",children:n.data.selected.name})]}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):i.jsxs(i.Fragment,{children:[n.data.error&&i.jsx(Ot,{error:new Error(`Could not load agents from SuperClawd: ${n.data.error}`),onRetry:()=>void n.refetch()}),n.data.items.length===0&&!n.data.error?i.jsx(rn,{children:"No enabled Primary agents in this workspace. Create one in the SuperClawd app, then come back."}):i.jsx("div",{role:"radiogroup","aria-label":"Primary agent",className:"space-y-2",children:n.data.items.map(m=>{const y=d===m.id;return i.jsxs("button",{type:"button",role:"radio","aria-checked":y,onClick:()=>o(m.id),className:Xe("flex w-full items-start gap-3 rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",y?"border-primary bg-accent":"hover:bg-accent/50"),children:[i.jsx("span",{className:Xe("mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border",y&&"border-primary bg-primary text-primary-foreground"),children:y&&i.jsx(Mg,{className:"h-3 w-3","aria-hidden":!0})}),i.jsxs("span",{className:"min-w-0 flex-1",children:[i.jsxs("span",{className:"flex flex-wrap items-center gap-2",children:[i.jsx("span",{className:"font-medium",children:m.name}),i.jsx("code",{className:"text-xs text-muted-foreground",children:m.slug}),m.model&&i.jsx(tt,{variant:"outline",children:NS(m.model)}),m.id===u&&i.jsx(tt,{variant:"success",children:"Current"})]}),m.description&&i.jsx("span",{className:"mt-1 block text-sm text-muted-foreground",children:m.description})]})]},m.id)})}),i.jsx(oe,{disabled:!d||d===u||r.isPending,onClick:()=>d&&r.mutate(d,{onSuccess:()=>{o(null),We({title:"Agent saved",variant:"success"})}}),children:r.isPending?"Saving":"Save"})]})]})]})}function NS(n){if(n==="default")return"Session model";const r=/^claude-(opus|fable|sonnet|haiku)-latest$/.exec(n);return r?`Claude ${r[1][0].toUpperCase()}${r[1].slice(1)} (latest)`:n}function jd({label:n,value:r}){return i.jsxs("div",{className:"flex items-center justify-between gap-4 rounded-md border px-3 py-2 text-sm",children:[i.jsx("span",{className:"text-muted-foreground",children:n}),r?i.jsx("code",{className:"text-xs",children:r}):i.jsx(tt,{variant:"warning",children:"Not set"})]})}function vy({result:n,error:r}){if(r)return i.jsxs("span",{role:"status",className:"flex items-center gap-1.5 text-sm text-red-300",children:[i.jsx(md,{className:"h-4 w-4","aria-hidden":!0}),yt(r)]});if(!n)return null;const s=[n.botName&&`bot ${n.botName}`,n.teamId&&`team ${n.teamId}`].filter(Boolean).join(", "),o=n.message??(n.ok?"Works.":"Failed.");return i.jsxs("span",{role:"status",className:`flex items-center gap-1.5 text-sm ${n.ok?"text-green-300":"text-red-300"}`,children:[n.ok?i.jsx(Tk,{className:"h-4 w-4","aria-hidden":!0}):i.jsx(md,{className:"h-4 w-4","aria-hidden":!0}),o,s&&i.jsxs("span",{className:"text-muted-foreground",children:["(",s,")"]})]})}function ES(){const n=Jo(),r=Jj(),s=Xj(),[o,u]=k.useState("");if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const d=h=>{h.preventDefault(),r.mutate(o.trim(),{onSuccess:()=>{u(""),s.reset(),We({title:"API key saved",variant:"success"})}})};return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Anthropic API key"}),i.jsx(Tt,{children:"FDA runs Claude Code with this key. It is stored encrypted on this machine and never shown again."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(jd,{label:"Current key",value:n.data.secrets.anthropicApiKey}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{variant:"outline",disabled:s.isPending||!n.data.secrets.anthropicApiKey,onClick:()=>s.mutate(),children:s.isPending?"Testing":"Test key"}),i.jsx(vy,{result:s.data,error:s.error})]}),i.jsxs("form",{onSubmit:d,className:"max-w-md space-y-3",autoComplete:"off",children:[i.jsx(Oe,{label:n.data.secrets.anthropicApiKey?"Replace key":"Set key",help:"Starts with sk-ant-.",error:r.error?yt(r.error):null,children:h=>i.jsx(Re,{...h,type:"password",autoComplete:"off",spellCheck:!1,value:o,onChange:p=>u(p.target.value),placeholder:"sk-ant-..."})}),i.jsx(oe,{type:"submit",disabled:!o.trim()||r.isPending,children:r.isPending?"Saving":"Save key"})]})]})]})}function RS({open:n,initialPath:r,onClose:s,onSelect:o}){return i.jsx(Kd,{open:n,onClose:s,title:"Choose a folder",description:"Folders under your home directory. Repositories are marked.",className:"max-w-xl",children:n&&i.jsx(PS,{initialPath:r??"",onSelect:o,onCancel:s})})}function PS({initialPath:n,onSelect:r,onCancel:s}){var p,g,m,y;const[o,u]=k.useState(n),d=lb(o),h=((p=d.data)==null?void 0:p.path)??o;return i.jsxs("div",{className:"space-y-3",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx(oe,{variant:"outline",size:"icon","aria-label":"Parent folder",disabled:!((g=d.data)!=null&&g.parent),onClick:()=>{var w;return((w=d.data)==null?void 0:w.parent)&&u(d.data.parent)},children:i.jsx(wk,{})}),i.jsx("code",{className:"min-w-0 flex-1 truncate rounded bg-muted px-2 py-1.5 text-xs",title:h,children:h||"Home"})]}),d.isLoading?i.jsx(kt,{}):d.isError?i.jsx(Ot,{error:d.error,onRetry:()=>u(n===o?"":n)}):i.jsxs("ul",{className:Xe("max-h-72 overflow-y-auto rounded-md border",d.isFetching&&"opacity-60"),"aria-label":"Folders",children:[((m=d.data)==null?void 0:m.dirs.length)===0&&i.jsx("li",{className:"p-3 text-sm text-muted-foreground",children:"No folders here."}),(y=d.data)==null?void 0:y.dirs.map(w=>i.jsx("li",{children:i.jsxs("button",{type:"button",onClick:()=>u(w.path),className:"flex w-full items-center gap-2 border-b px-3 py-2 text-left text-sm last:border-b-0 hover:bg-accent focus-visible:bg-accent focus-visible:outline-none",children:[w.isRepo?i.jsx(Qk,{className:"h-4 w-4 text-success","aria-hidden":!0}):i.jsx(Bk,{className:"h-4 w-4 text-muted-foreground","aria-hidden":!0}),i.jsx("span",{className:"truncate",children:w.name}),w.isRepo&&i.jsx("span",{className:"ml-auto text-xs text-muted-foreground",children:"repository"})]})},w.path))]}),i.jsxs("div",{className:"flex justify-end gap-2 pt-1",children:[i.jsx(oe,{variant:"outline",onClick:s,children:"Cancel"}),i.jsx(oe,{disabled:!d.data,onClick:()=>d.data&&r(d.data.path),children:"Use this folder"})]})]})}const bd=[{title:"Workspace",description:"Where FDA works on this machine and who people should contact.",fields:[{key:"workdir",label:"Work directory",help:"Repositories FDA works on live here. Must be inside your home directory.",kind:"folder"},{key:"operatorContact",label:"Operator contact",help:"Shown to Slack users when FDA cannot help, for example a Slack handle or email.",kind:"text",nullable:!0,placeholder:"@alex"}]},{title:"Agent behavior",description:"How the coding agent runs each turn.",fields:[{key:"effort",label:"Reasoning effort",help:"Higher effort is slower and costs more.",kind:"select",nullable:!0,options:[{value:"",label:"Default"},{value:"low",label:"Low"},{value:"medium",label:"Medium"},{value:"high",label:"High"},{value:"xhigh",label:"Extra high"},{value:"max",label:"Max"}]},{key:"permissionMode",label:"Permission mode",help:"Bypass lets the agent run any tool without asking. Auto applies Claude Code's automatic permission checks.",kind:"select",options:[{value:"bypass",label:"Bypass"},{value:"auto",label:"Auto"}]},{key:"planPolicy",label:"Plan first",help:"Whether the agent proposes a plan for approval in Slack before making changes.",kind:"select",options:[{value:"auto",label:"When the task needs it"},{value:"always",label:"Always"},{value:"never",label:"Never"}]},{key:"browserEnabled",label:"Browser",help:"Let the agent use a headless browser for checks and screenshots.",kind:"bool"},{key:"superclawdMemory",label:"SuperClawd memory",help:"Team, repo, agent and private memories from SuperClawd. Off: none is loaded or captured, and the agent uses Claude Code's own memory instead (kept per repository on this machine).",kind:"bool"},{key:"captureMemories",label:"Capture memories",help:"Save learnings to your SuperClawd workspace memories after turns.",kind:"bool"},{key:"allowClaudeaiConnectors",label:"Claude.ai connectors",help:"Allow MCP connectors configured in the Claude.ai account.",kind:"bool"}]},{title:"Turn limits",description:"Guards against runaway turns.",fields:[{key:"debounceMs",label:"Message debounce (ms)",help:"Wait this long after the last Slack message before starting a turn, so quick follow-ups are batched.",kind:"number",min:0,step:100,integer:!0},{key:"turnTimeoutMin",label:"Turn timeout (minutes)",help:"Stop a turn that runs longer than this.",kind:"number",min:1,integer:!0},{key:"turnMaxBudgetUsd",label:"Max cost per turn (USD)",help:"Leave empty for no limit.",kind:"number",nullable:!0,min:0,step:.5},{key:"turnMaxTurns",label:"Max agent steps per turn",help:"Leave empty for no limit.",kind:"number",nullable:!0,min:1,integer:!0}]},{title:"Pull requests",description:"After FDA opens a pull request it keeps an eye on it (through the machine's gh login) and works on it again in the same thread.",fields:[{key:"prMonitorEnabled",label:"Follow pull requests",help:"Check the pull requests FDA opened. Say `stop following` in a thread to stop for that request.",kind:"bool"},{key:"prMonitorFixCi",label:"Fix failing CI",help:"Once per failing commit, up to the attempt limit below.",kind:"bool"},{key:"prMonitorReviews",label:"Address review feedback",help:"Only from people with write access to the repository; other comments are ignored.",kind:"bool"},{key:"prMonitorConflicts",label:"Resolve merge conflicts",help:"Merges the base branch into the pull request branch.",kind:"bool"},{key:"prMonitorIntervalSec",label:"Check every (seconds)",help:"Checks slow down when nothing is happening.",kind:"number",min:30,integer:!0},{key:"prMonitorQuietSec",label:"Wait after the last comment (seconds)",help:"Lets a reviewer finish before FDA starts.",kind:"number",min:0,integer:!0},{key:"prMonitorMaxCiAttempts",label:"CI fix attempts",help:"Then FDA leaves it for a human and says so in the thread.",kind:"number",min:1,integer:!0},{key:"prMonitorMaxPerDay",label:"Follow-ups per pull request per day",help:"A safety cap on automatic work.",kind:"number",min:1,integer:!0},{key:"prMonitorMaxAgeDays",label:"Stop after idle (days)",help:"Stop following a pull request with no activity for this long.",kind:"number",min:1,integer:!0}]},{title:"Slack context",description:"What FDA reads from the thread.",fields:[{key:"threadContextMessages",label:"Earlier thread messages",help:"How many earlier messages in the thread to include as context.",kind:"number",min:0,integer:!0},{key:"includeUnlistedContext",label:"Include messages from people not on the allowlist",help:"They are passed as untrusted context only, never as instructions.",kind:"bool"},{key:"stopButton",label:"Stop button",help:"Show a Stop button on the agent's live line while it works (same as typing `stop`; only the requester or allowed people can use it).",kind:"bool"},{key:"allowDirectMessages",label:"Direct messages",help:"People on the allowlist can DM the agent; each DM is a private request (the team doesn't see it). Turn off to accept requests only in channels.",kind:"bool"}]},{title:"Sessions and cleanup",description:"Housekeeping on this machine.",fields:[{key:"sessionMaxAgeH",label:"Session max age (hours)",help:"Start a fresh agent session for a thread after this long.",kind:"number",min:1,integer:!0},{key:"worktreeRetentionDays",label:"Keep worktrees (days)",help:"Delete finished request worktrees after this many days.",kind:"number",min:0,integer:!0},{key:"diskMinFreeGb",label:"Minimum free disk (GB)",help:"Pause new work when free disk drops below this.",kind:"number",min:0,step:.5},{key:"autoRequeueOnRestart",label:"Requeue after restart",help:"Requeue requests that were running when the daemon stopped.",kind:"bool"}]},{title:"Admin panel",description:"How this panel is reached.",fields:[{key:"adminPublicUrl",label:"Admin URL",help:"The address you use to open this panel. Used in Slack links.",kind:"text",nullable:!0,placeholder:"https://fda.example.ts.net"},{key:"publicHostname",label:"Public hostname",help:"Extra hostname this panel accepts, for example a Tailscale name.",kind:"text",nullable:!0,placeholder:"fda.example.ts.net"}]},{title:"Privacy",description:"What is shared with SuperClawd.",fields:[{key:"shareTitleWithCloud",label:"Share request titles",help:"Send request titles to SuperClawd for usage reporting. Off sends counts only.",kind:"bool"}]}];function Tm(n){const r={};for(const s of bd)for(const o of s.fields){const u=n[o.key];r[o.key]=typeof u=="boolean"?u:u===null?"":String(u)}return r}function TS(n,r){if(n.kind==="bool")return{value:r};const s=String(r).trim();if(n.kind==="number"){if(s==="")return n.nullable?{value:null}:{error:"Required."};const o=Number(s);return Number.isFinite(o)?n.integer&&!Number.isInteger(o)?{error:"Enter a whole number."}:n.min!==void 0&&o<n.min?{error:`Must be at least ${n.min}.`}:{value:o}:{error:"Enter a number."}}return s===""?"nullable"in n&&n.nullable?{value:null}:n.kind==="folder"?{value:null}:{error:"Required."}:{value:s}}function LS(){const n=Jo();return n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):i.jsx(MS,{settings:n.data.settings})}function MS({settings:n}){const[r]=k.useState(()=>Tm(n)),[s,o]=k.useState(r),[u,d]=k.useState(r),[h,p]=k.useState({}),[g,m]=k.useState(!1),y=Vd(),w=Object.keys(s).filter(E=>s[E]!==u[E]),x=(E,S)=>{o(P=>({...P,[E]:S})),p(P=>({...P,[E]:void 0}))},j=E=>{E.preventDefault();const S={},P={};for(const D of bd)for(const U of D.fields){if(!w.includes(U.key))continue;const Q=TS(U,s[U.key]);Q.error?P[U.key]=Q.error:S[U.key]=Q.value}p(P),!Object.keys(P).length&&y.mutate(S,{onSuccess:({settings:D})=>{const U=Tm(D);o(U),d(U),We({title:"Settings saved",variant:"success"})},onError:D=>{D instanceof Wn&&D.field&&p({[D.field]:D.message})}})},_=y.error instanceof Wn&&y.error.field?null:y.error?yt(y.error):null;return i.jsxs("form",{onSubmit:j,className:"space-y-6",noValidate:!0,children:[bd.map(E=>i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:E.title}),i.jsx(Tt,{children:E.description})]}),i.jsx(Qe,{className:"grid gap-5 sm:grid-cols-2",children:E.fields.map(S=>i.jsx("div",{className:S.kind==="folder"||S.kind==="bool"?"sm:col-span-2":void 0,children:i.jsx(Oe,{label:S.label,help:S.help,error:h[S.key],children:P=>{const D=s[S.key];switch(S.kind){case"bool":return i.jsx(ps,{...P,checked:D,onCheckedChange:U=>x(S.key,U)});case"select":return i.jsx(eu,{...P,value:D,onChange:U=>x(S.key,U.target.value),children:S.options.map(U=>i.jsx("option",{value:U.value,children:U.label},U.value))});case"number":return i.jsx(Re,{...P,type:"number",inputMode:"decimal",min:S.min,step:S.step??1,value:D,onChange:U=>x(S.key,U.target.value)});case"folder":return i.jsxs("div",{className:"flex gap-2",children:[i.jsx(Re,{...P,value:D,onChange:U=>x(S.key,U.target.value),placeholder:"/home/you/work",spellCheck:!1}),i.jsxs(oe,{variant:"outline",onClick:()=>m(!0),children:[i.jsx($k,{}),"Browse"]})]});default:return i.jsx(Re,{...P,value:D,onChange:U=>x(S.key,U.target.value),placeholder:S.placeholder,spellCheck:!1})}}})},S.key))})]},E.title)),i.jsxs("div",{className:"sticky bottom-0 flex items-center gap-3 border-t bg-background/95 py-4 backdrop-blur",children:[i.jsx(oe,{type:"submit",disabled:w.length===0||y.isPending,children:y.isPending?"Saving":"Save changes"}),i.jsx(oe,{variant:"ghost",disabled:w.length===0,onClick:()=>{o(u),p({})},children:"Discard"}),w.length>0&&i.jsx("span",{className:"text-sm text-muted-foreground",children:w.length===1?"1 unsaved change":`${w.length} unsaved changes`}),i.jsx(Go,{message:_})]}),i.jsx(RS,{open:g,initialPath:s.workdir||null,onClose:()=>m(!1),onSelect:E=>{x("workdir",E),m(!1)}})]})}function _S(){const n=Jo();if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const{secrets:r,settings:s}=n.data;return i.jsxs("div",{className:"space-y-6",children:[i.jsx(AS,{botToken:r.slackBotToken,appToken:r.slackAppToken,botUserId:s.slackBotUserId,teamId:s.slackTeamId}),i.jsx(DS,{defaultName:s.slackBotName??"FDA"})]})}function AS({botToken:n,appToken:r,botUserId:s,teamId:o}){const u=Zj(),d=eb(),[h,p]=k.useState(""),[g,m]=k.useState(""),y=w=>{w.preventDefault();const x={};h.trim()&&(x.botToken=h.trim()),g.trim()&&(x.appToken=g.trim()),u.mutate(x,{onSuccess:()=>{p(""),m(""),d.reset(),We({title:"Slack tokens saved. Reconnecting.",variant:"success"})}})};return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Slack connection"}),i.jsx(Tt,{children:"FDA connects to Slack over Socket Mode with a bot token and an app-level token."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx(jd,{label:"Bot token",value:n}),i.jsx(jd,{label:"App token",value:r}),(s||o)&&i.jsxs("p",{className:"text-xs text-muted-foreground",children:[s&&i.jsxs(i.Fragment,{children:["Bot user ",s,". "]}),o&&i.jsxs(i.Fragment,{children:["Team ",o,"."]})]})]}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{variant:"outline",disabled:d.isPending||!n,onClick:()=>d.mutate(),children:d.isPending?"Testing":"Test connection"}),i.jsx(vy,{result:d.data,error:d.error})]}),i.jsxs("form",{onSubmit:y,className:"max-w-md space-y-4",autoComplete:"off",children:[i.jsx(Oe,{label:"New bot token",help:"Starts with xoxb-. Leave empty to keep the current one.",children:w=>i.jsx(Re,{...w,type:"password",autoComplete:"off",spellCheck:!1,value:h,onChange:x=>p(x.target.value),placeholder:"xoxb-..."})}),i.jsx(Oe,{label:"New app token",help:"Starts with xapp-. Needs the connections:write scope.",children:w=>i.jsx(Re,{...w,type:"password",autoComplete:"off",spellCheck:!1,value:g,onChange:x=>m(x.target.value),placeholder:"xapp-..."})}),i.jsx(Go,{message:u.error?yt(u.error):null}),i.jsx(oe,{type:"submit",disabled:!h.trim()&&!g.trim()||u.isPending,children:u.isPending?"Saving":"Save tokens"})]})]})]})}function DS({defaultName:n}){const[r,s]=k.useState(n),[o,u]=k.useState(n);k.useEffect(()=>{const p=setTimeout(()=>u(r.trim()||n),300);return()=>clearTimeout(p)},[r,n]);const d=tb(o),h=d.data?JSON.stringify(d.data.manifest,null,2):"";return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Slack app manifest"}),i.jsx(Tt,{children:"Create the Slack app from this manifest at api.slack.com/apps, then install it and paste the tokens above."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsx("div",{className:"max-w-xs",children:i.jsx(Oe,{label:"Bot name",help:"The name people mention in Slack.",children:p=>i.jsx(Re,{...p,value:r,onChange:g=>s(g.target.value),maxLength:35})})}),d.isLoading?i.jsx(kt,{}):d.isError?i.jsx(Ot,{error:d.error,onRetry:()=>void d.refetch()}):i.jsxs("div",{className:"space-y-2",children:[i.jsx("div",{className:"flex justify-end",children:i.jsx(Js,{text:h,label:"Copy manifest"})}),i.jsx("pre",{className:"max-h-96 overflow-auto rounded-md border bg-muted/40 p-3 font-mono text-xs","aria-label":"Manifest JSON",tabIndex:0,children:h})]})]})]})}const Sd={channel:"Channel",user:"User",usergroup:"User group"},OS={channel:Yk,user:I1,usergroup:U1},Oo=(n,r)=>n.kind===r.kind&&n.slackId===r.slackId;function FS(){var u,d,h,p,g;const n=nb(),r=Jo();if(n.isLoading||r.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const s=!!((u=r.data)!=null&&u.settings.allowAnyChannel),o=!!((d=r.data)!=null&&d.settings.allowAnyone);return i.jsxs("div",{className:"space-y-6",children:[i.jsx(zS,{anyChannel:s,anyone:o}),i.jsx(IS,{targets:((h=r.data)==null?void 0:h.settings.handoffTargets)??[],sources:((p=r.data)==null?void 0:p.settings.handoffSources)??[],budget:((g=r.data)==null?void 0:g.settings.handoffMaxBudgetUsd)??5}),i.jsx(US,{initial:n.data,anyChannel:s,anyone:o})]})}function IS({targets:n,sources:r,budget:s}){const o=Vd(),[u,d]=k.useState({botUserId:"",name:"",role:""}),[h,p]=k.useState(""),[g,m]=k.useState(String(s));k.useEffect(()=>m(String(s)),[s]);const y=(x,j)=>o.mutate(x,{onSuccess:()=>We({title:j,variant:"success"}),onError:_=>We({title:"Couldn't save",description:yt(_),variant:"error"})}),w=x=>/^[UW][A-Z0-9]{5,}$/.test(x.trim());return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Agent hand-offs"}),i.jsx(Tt,{children:"Optional. Let this agent hand part of a request to another agent (for example a product manager agent tasking a developer agent). The person who asked approves each hand-off with ✅ in the thread, and the receiving agent must list this one below too. A hand-off can't be passed on again."})]}),i.jsxs(Qe,{className:"space-y-6",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx("p",{className:"text-sm font-medium",children:"Agents this agent can hand work to"}),n.length===0?i.jsx("p",{className:"text-xs text-muted-foreground",children:"None (hand-offs off)."}):i.jsx("ul",{className:"divide-y rounded-md border",children:n.map(x=>i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx("span",{className:"font-medium",children:x.name}),i.jsx("code",{className:"text-xs text-muted-foreground",children:x.botUserId}),i.jsx("span",{className:"flex-1 truncate text-muted-foreground",children:x.role}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":`Remove ${x.name}`,onClick:()=>y({handoffTargets:n.filter(j=>j.botUserId!==x.botUserId)},"Removed"),children:i.jsx(qo,{})})]},x.botUserId))}),i.jsxs("div",{className:"grid gap-2 sm:grid-cols-[1fr_1fr_2fr_auto]",children:[i.jsx(Re,{placeholder:"Slack bot user id (U…)","aria-label":"Bot user id",value:u.botUserId,onChange:x=>d({...u,botUserId:x.target.value.trim()})}),i.jsx(Re,{placeholder:"Name (e.g. John)","aria-label":"Name",value:u.name,onChange:x=>d({...u,name:x.target.value})}),i.jsx(Re,{placeholder:"Role (e.g. backend developer)","aria-label":"Role",value:u.role,onChange:x=>d({...u,role:x.target.value})}),i.jsxs(oe,{disabled:!w(u.botUserId)||!u.name.trim()||o.isPending,onClick:()=>{y({handoffTargets:[...n.filter(x=>x.botUserId!==u.botUserId),{botUserId:u.botUserId,name:u.name.trim(),role:u.role.trim()}]},"Added"),d({botUserId:"",name:"",role:""})},children:[i.jsx(gd,{})," Add"]})]})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsx("p",{className:"text-sm font-medium",children:"Agents allowed to hand work to this agent"}),r.length===0?i.jsx("p",{className:"text-xs text-muted-foreground",children:"None (no hand-offs accepted)."}):i.jsx("ul",{className:"divide-y rounded-md border",children:r.map(x=>i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx("code",{className:"flex-1 text-xs",children:x}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":`Remove ${x}`,onClick:()=>y({handoffSources:r.filter(j=>j!==x)},"Removed"),children:i.jsx(qo,{})})]},x))}),i.jsxs("div",{className:"flex gap-2",children:[i.jsx(Re,{placeholder:"Slack bot user id (U…)","aria-label":"Allowed agent's bot user id",value:h,onChange:x=>p(x.target.value.trim())}),i.jsxs(oe,{disabled:!w(h)||o.isPending,onClick:()=>{y({handoffSources:[...new Set([...r,h])]},"Added"),p("")},children:[i.jsx(gd,{})," Add"]})]})]}),i.jsxs("div",{className:"flex items-end gap-2",children:[i.jsxs("div",{className:"space-y-1",children:[i.jsx("p",{className:"text-sm font-medium",children:"Cost cap per turn for handed-off work (USD)"}),i.jsx(Re,{type:"number",min:.5,step:.5,"aria-label":"Cost cap per turn for handed-off work",value:g,onChange:x=>m(x.target.value)})]}),i.jsx(oe,{variant:"outline",disabled:o.isPending||Number(g)===s,onClick:()=>y({handoffMaxBudgetUsd:Number(g)},"Saved"),children:"Save"})]})]})]})}function zS({anyChannel:n,anyone:r}){const s=Vd(),o=(d,h)=>s.mutate({[d]:h},{onError:p=>We({title:"Couldn't change access",description:yt(p),variant:"error"})}),u=(d,h,p,g)=>i.jsxs("div",{className:"flex items-start justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"text-sm font-medium",children:p}),i.jsx("p",{className:"text-xs text-muted-foreground",children:g})]}),i.jsx(ps,{checked:h,disabled:s.isPending,"aria-label":p,onCheckedChange:m=>o(d,m)})]});return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Open access"}),i.jsx(Tt,{children:"Optional. Anyone who can reach the agent can make it run code and spend money on this machine, so these are off by default."})]}),i.jsxs(Qe,{className:"space-y-4",children:[u("allowAnyChannel",n,"Any channel the agent is in","Inviting the agent to a channel is enough; the channel list below isn't used. Shared (Slack Connect) channels are still refused."),u("allowAnyone",r,"Anyone in this workspace","Every member can use the agent; the people list below isn't used. External users, guest accounts and deactivated accounts are still refused (unless listed below).")]})]})}function US({initial:n,anyChannel:r,anyone:s}){const[o,u]=k.useState(n),[d,h]=k.useState(n),p=rb(),g=JSON.stringify(o)!==JSON.stringify(d),m=x=>u(j=>j.some(_=>Oo(_,x))?j:[...j,x]),y=x=>u(j=>j.filter(_=>!Oo(_,x))),w=(x,j)=>u(_=>_.map(E=>Oo(E,x)?{...E,label:j||null}:E));return i.jsxs("div",{className:"space-y-6",children:[i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Who can use FDA"}),i.jsxs(Tt,{children:["FDA only acts on mentions in allowed channels from allowed people. A user is allowed when they are listed directly or belong to a listed user group.",r&&" Any channel is on: channels listed here aren't needed.",s&&" Anyone in the workspace is on: people and groups listed here are only needed for guests."]})]}),i.jsxs(Qe,{className:"space-y-4",children:[o.length===0?i.jsx(rn,{children:r&&s?"Not needed while both open-access switches are on.":r?"Add at least one user or group (or turn on Anyone in this workspace).":s?"Add at least one channel (or turn on Any channel the agent is in).":"Nobody is allowed yet. Add at least one channel and one user or group."}):i.jsx("ul",{className:"divide-y rounded-md border",children:o.map(x=>{const j=OS[x.kind];return i.jsxs("li",{className:"flex items-center gap-3 p-3",children:[i.jsx(j,{className:"h-4 w-4 shrink-0 text-muted-foreground","aria-hidden":!0}),i.jsx(tt,{variant:"outline",className:"shrink-0",children:Sd[x.kind]}),i.jsx("code",{className:"shrink-0 text-xs text-muted-foreground",children:x.slackId}),i.jsx(Re,{"aria-label":`Label for ${Sd[x.kind].toLowerCase()} ${x.slackId}`,placeholder:"Label",className:"h-8",value:x.label??"",onChange:_=>w(x,_.target.value)}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8 shrink-0","aria-label":`Remove ${x.label??x.slackId}`,onClick:()=>y(x),children:i.jsx(qo,{})})]},`${x.kind}:${x.slackId}`)})}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{disabled:!g||p.isPending,onClick:()=>p.mutate(o,{onSuccess:({entries:x})=>{u(x),h(x),We({title:"Access list saved",variant:"success"})}}),children:p.isPending?"Saving":"Save access list"}),i.jsx(oe,{variant:"ghost",disabled:!g,onClick:()=>u(d),children:"Discard"}),g&&i.jsx("span",{className:"text-sm text-muted-foreground",children:"Unsaved changes"})]})]})]}),i.jsx(qS,{entries:o,onAdd:m})]})}function $S(n,r=300){const[s,o]=k.useState(n);return k.useEffect(()=>{const u=setTimeout(()=>o(n),r);return()=>clearTimeout(u)},[n,r]),s}function qS({entries:n,onAdd:r}){const[s,o]=k.useState("channel"),[u,d]=k.useState(""),h=$S(u.trim()),p=sb(h,s==="channel"),g=ab(h,s==="user"),m=ib(s==="usergroup"),y=s==="channel"?p:s==="user"?g:m;let w=[];if(s==="channel"&&p.data)w=p.data.map(x=>({id:x.id,primary:`#${x.name}`,secondary:x.isMember?void 0:"Bot is not a member yet",label:`#${x.name}`,icon:x.isPrivate?i.jsx(o1,{className:"h-3 w-3","aria-label":"Private"}):void 0}));else if(s==="user"&&g.data)w=g.data.map(x=>({id:x.id,primary:x.realName||x.name,secondary:`@${x.name}`,label:x.realName||x.name}));else if(s==="usergroup"&&m.data){const x=h.toLowerCase();w=m.data.filter(j=>!x||j.handle.toLowerCase().includes(x)||j.name.toLowerCase().includes(x)).map(j=>({id:j.id,primary:j.name,secondary:`@${j.handle}`,label:`@${j.handle}`}))}return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Add to the list"}),i.jsx(Tt,{children:"Search what the bot can see in your Slack workspace. Remember to save."})]}),i.jsxs(Qe,{children:[i.jsx(hy,{idPrefix:"access",label:"Entry type",value:s,onChange:x=>{o(x),d("")},items:[{value:"channel",label:"Channels"},{value:"user",label:"Users"},{value:"usergroup",label:"User groups"}]}),i.jsxs(py,{idPrefix:"access",value:s,className:"space-y-3",children:[i.jsx(Re,{type:"search","aria-label":`Search ${Sd[s].toLowerCase()}s`,placeholder:"Search",value:u,onChange:x=>d(x.target.value)}),y.isLoading?i.jsx(kt,{}):y.isError?i.jsx(Ot,{error:y.error,onRetry:()=>void y.refetch()}):w.length===0?i.jsx("p",{className:"p-2 text-sm text-muted-foreground",children:"No matches."}):i.jsx("ul",{className:Xe("max-h-72 overflow-y-auto rounded-md border",y.isFetching&&"opacity-60"),children:w.map(x=>{const j=n.some(_=>Oo(_,{kind:s,slackId:x.id}));return i.jsxs("li",{className:"flex items-center gap-3 border-b px-3 py-2 text-sm last:border-b-0",children:[i.jsxs("div",{className:"min-w-0 flex-1",children:[i.jsxs("p",{className:"flex items-center gap-1.5 truncate",children:[x.primary,x.icon]}),x.secondary&&i.jsx("p",{className:"truncate text-xs text-muted-foreground",children:x.secondary})]}),i.jsx(oe,{size:"xs",variant:"outline",disabled:j,"aria-label":j?`${x.primary} already added`:`Add ${x.primary}`,onClick:()=>r({kind:s,slackId:x.id,label:x.label}),children:j?"Added":i.jsxs(i.Fragment,{children:[i.jsx(gd,{}),"Add"]})})]},x.id)})})]})]})]})}function BS(){const n=Yo();return n.data?i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Account"}),i.jsx(Tt,{children:"Change your password or username. Your other sessions will be signed out."})]}),i.jsx(Qe,{children:i.jsx(oy,{currentUsername:n.data.username,onDone:()=>We({title:"Account updated",variant:"success"})})})]}):i.jsx(kt,{})}const xy=["calendar"];function HS(){return Rt({queryKey:xy,queryFn:()=>Ee("/api/calendar")})}function QS(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"redirectUri"in r&&n.setQueryData(xy,r)}})}function VS(){var y,w;const n=HS(),r=QS(),[s,o]=k.useState(""),[u,d]=k.useState("");if(k.useEffect(()=>{n.data&&o(n.data.clientId??"")},[(y=n.data)==null?void 0:y.clientId]),n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const h=n.data,p=x=>j=>We({title:x,description:yt(j),variant:"error"}),g=()=>r.mutateAsync({path:"/api/calendar",method:"PUT",body:{clientId:s.trim(),...u.trim()?{clientSecret:u.trim()}:{}}}).then(()=>{d(""),We({title:"Google client saved",variant:"success"})}).catch(p("Couldn't save the Google client")),m=()=>Ee("/api/calendar/connect",{method:"POST"}).then(x=>window.location.assign(x.url)).catch(p("Couldn't start the Google sign-in"));return i.jsxs("div",{className:"space-y-4",children:[i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Calendar"}),i.jsx(Tt,{children:"The agent books meetings on its own Google calendar, around the attendees' availability (Google Calendar). Connect the Google account the agent should use (ideally its own account, e.g. jane@yourcompany.com). The sign-in stays encrypted on this machine; tasks never see Google's tokens."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"font-medium",children:"Calendar for tasks"}),i.jsx("p",{className:"text-sm text-muted-foreground",children:"Off: tasks don't get the calendar tools."})]}),i.jsx(ps,{checked:h.enabled,onCheckedChange:x=>void r.mutateAsync({path:"/api/calendar",method:"PUT",body:{enabled:x}}).catch(p("Couldn't change it")),"aria-label":"Calendar for tasks"})]}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Google account:"}),h.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:h.account}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/calendar/connection",method:"DELETE"}).catch(p("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!h.configured,onClick:()=>void m(),children:"Connect Google"}),!h.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the Google client below first."})]})]}),i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsxs("p",{className:"font-medium",children:["Invite people outside"," ",((w=h.account)==null?void 0:w.split("@")[1])??"the account's domain"]}),i.jsx("p",{className:"text-sm text-muted-foreground",children:"Off: the agent can only invite people from its own Google Workspace domain."})]}),i.jsx(ps,{checked:h.allowExternal,onCheckedChange:x=>void r.mutateAsync({path:"/api/calendar",method:"PUT",body:{allowExternal:x}}).catch(p("Couldn't change it")),"aria-label":"Allow external guests"})]})]})]}),i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Google client"}),i.jsx(Tt,{children:"From your Google Cloud project (Google Auth Platform → Clients): a Web application client, with the Google Calendar API enabled. See the setup guide for the steps."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Authorized redirect URI (add it to the client exactly)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.redirectUri}),i.jsx(Js,{text:h.redirectUri})]})]}),i.jsx(Oe,{label:"Client ID",children:x=>i.jsx(Re,{...x,value:s,onChange:j=>o(j.target.value),placeholder:"1234…apps.googleusercontent.com"})}),i.jsx(Oe,{label:"Client secret",help:h.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:x=>i.jsx(Re,{...x,type:"password",autoComplete:"off",value:u,onChange:j=>d(j.target.value),placeholder:h.hasSecret?"••••••••":"GOCSPX-…"})}),i.jsx(oe,{onClick:()=>void g(),disabled:r.isPending||!s.trim(),children:"Save"})]})]})]})}function WS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/calendar/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The sign-in was cancelled.":"Google didn't complete the sign-in."});return}Ee("/api/calendar/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,account:h.account})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Google Calendar is connected",n.account?i.jsxs(i.Fragment,{children:[" ","as ",i.jsx("code",{children:n.account})]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Google"}),i.jsx(Bt,{to:"/settings/calendar",className:"text-info underline",children:"Back to Calendar settings"})]})})})}function KS(){return i.jsxs("div",{className:"py-16 text-center",children:[i.jsx("h1",{className:"text-xl font-semibold",children:"Page not found"}),i.jsx(Bt,{to:"/",className:"mt-3 inline-block text-sm text-info underline",children:"Back to the dashboard"})]})}const GS=Xw([{element:i.jsx(bb,{}),children:[{path:"/login",element:i.jsx(Cb,{})},{path:"/change-password",element:i.jsx(km,{children:i.jsx(Nb,{})})},{element:i.jsx(km,{children:i.jsx(jb,{})}),children:[{index:!0,element:i.jsx(Rb,{})},{path:"requests",element:i.jsx(_b,{})},{path:"requests/:id",element:i.jsx(Ub,{})},{path:"schedules",element:i.jsx(tS,{})},{path:"setup",element:i.jsx(aS,{})},{path:"browser",element:i.jsx(uS,{})},{path:"tickets",element:i.jsx(pS,{})},{path:"trackers/linear/callback",element:i.jsx(kS,{})},{path:"trackers/jira/callback",element:i.jsx(jS,{})},{path:"calendar/callback",element:i.jsx(WS,{})},{path:"settings",element:i.jsx(SS,{}),children:[{index:!0,element:i.jsx(hd,{to:"agent",replace:!0})},{path:"agent",element:i.jsx(CS,{})},{path:"anthropic",element:i.jsx(ES,{})},{path:"general",element:i.jsx(LS,{})},{path:"slack",element:i.jsx(_S,{})},{path:"access",element:i.jsx(FS,{})},{path:"calendar",element:i.jsx(VS,{})},{path:"account",element:i.jsx(BS,{})}]},{path:"audit",element:i.jsx(eS,{})},{path:"*",element:i.jsx(KS,{})}]}]}]);function YS(){const n=k.useSyncExternalStore(Dj,Oj);return i.jsx("div",{"aria-live":"polite",role:"status",className:"pointer-events-none fixed bottom-4 right-4 z-50 flex w-full max-w-sm flex-col gap-2",children:n.map(r=>i.jsxs("div",{className:Xe("pointer-events-auto flex items-start gap-3 rounded-md border bg-card p-4 text-sm shadow-lg animate-in fade-in slide-in-from-bottom-2",r.variant==="error"&&"border-destructive/50",r.variant==="success"&&"border-success/50"),children:[i.jsxs("div",{className:"min-w-0 flex-1",children:[i.jsx("p",{className:"font-medium",children:r.title}),r.description&&i.jsx("p",{className:"mt-1 break-words text-muted-foreground",children:r.description})]}),i.jsx("button",{type:"button",onClick:()=>ty(r.id),"aria-label":"Dismiss",className:"rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:i.jsx(Bd,{className:"h-4 w-4"})})]},r.id))})}const JS=new Set(["unauthorized","must_change_password","csrf"]),XS=new Ax({defaultOptions:{queries:{retry:(n,r)=>!(r instanceof Wn&&r.status>=400&&r.status<500)&&n<2,refetchOnWindowFocus:!0}},mutationCache:new eg({onError:(n,r,s,o)=>{var u;(u=o.meta)!=null&&u.inlineError||n instanceof Wn&&JS.has(n.code)||We({title:"Action failed",description:yt(n),variant:"error"})}})});fx.createRoot(document.getElementById("root")).render(i.jsx(ix.StrictMode,{children:i.jsxs(Dx,{client:XS,children:[i.jsx(ck,{router:GS}),i.jsx(YS,{})]})}));
311
+ `)});continue}const p=u.match(Kc);if(p){const m=/\d/.test(p[1]),y=[];for(;o<r.length;){const w=r[o].match(Kc);if(w&&/\d/.test(w[1])===m)y.push(w[2]),o++;else if(r[o].trim()&&/^\s{2,}/.test(r[o])&&y.length)y[y.length-1]+=" "+r[o].trim(),o++;else break}s.push({type:"list",ordered:m,items:y});continue}const g=[];for(;o<r.length&&r[o].trim()&&!/^(#{1,6})\s/.test(r[o])&&!/^\s*(```|~~~|>)/.test(r[o])&&!Kc.test(r[o]);)g.push(r[o++].trim());s.push({type:"para",text:g.join(" ")})}return s}const Db=/(`[^`]{1,500}`)|(\*\*[^*]{1,500}\*\*|__[^_]{1,500}__)|(\*[^*\s][^*]{0,500}\*|_[^_\s][^_]{0,500}_)|(\[[^\]]{1,300}\]\([^)\s]{1,2000}\))|(https?:\/\/[^\s<)]{1,2000})/,Sm=2e4;function Ys(n,r="i"){const s=[];let o=n.length>Sm?`${n.slice(0,Sm)}…`:n,u=0;for(;o;){const d=o.match(Db);if(!d||d.index===void 0){s.push(o);break}d.index>0&&s.push(o.slice(0,d.index));const h=d[0],p=`${r}-${u++}`;if(d[1])s.push(i.jsx("code",{className:"rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]",children:h.slice(1,-1)},p));else if(d[2])s.push(i.jsx("strong",{children:Ys(h.slice(2,-2),p)},p));else if(d[3])s.push(i.jsx("em",{children:Ys(h.slice(1,-1),p)},p));else if(d[4]){const g=h.match(/^\[([^\]]{1,300})\]\(([^)\s]{1,2000})\)$/),m=rl(g==null?void 0:g[2]);s.push(m?i.jsx("a",{href:m,target:"_blank",rel:"noreferrer noopener",className:"text-info underline",children:g==null?void 0:g[1]},p):i.jsx("span",{children:g==null?void 0:g[1]},p))}else if(d[5]){const g=rl(h);s.push(g?i.jsx("a",{href:g,target:"_blank",rel:"noreferrer noopener",className:"break-all text-info underline",children:h},p):h)}o=o.slice(d.index+h.length)}return s}function Ob(n,r){const s=n.match(/^\[([ xX])\]\s+(.*)$/);return s?i.jsxs("li",{className:"list-none",children:[i.jsx("span",{"aria-hidden":!0,className:"mr-1.5 font-mono text-muted-foreground",children:s[1]===" "?"[ ]":"[x]"}),Ys(s[2],r)]},r):i.jsx("li",{children:Ys(n,r)},r)}const Fb=["text-lg","text-base","text-sm","text-sm","text-sm","text-sm"];function Cm({source:n}){const r=Ab(n);return i.jsx("div",{className:"space-y-3 text-sm leading-relaxed",children:r.map((s,o)=>{const u=`b${o}`;switch(s.type){case"heading":{const d=`h${Math.min(s.level+2,6)}`;return i.jsx(d,{className:`${Fb[s.level-1]} mt-4 font-semibold first:mt-0`,children:Ys(s.text,u)},u)}case"para":return i.jsx("p",{children:Ys(s.text,u)},u);case"code":return i.jsx("pre",{className:"overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs",children:i.jsx("code",{children:s.text})},u);case"quote":return i.jsx("blockquote",{className:"border-l-2 pl-3 text-muted-foreground",children:Ys(s.text,u)},u);case"list":{const d=s.ordered?"ol":"ul";return i.jsx(d,{className:`${s.ordered?"list-decimal":"list-disc"} space-y-1 pl-5`,children:s.items.map((h,p)=>Ob(h,`${u}-${p}`))},u)}case"hr":return i.jsx("hr",{},u)}return null})})}const Nm=300;function Ib(n,r){const s=Ct(),[o,u]=k.useState([]),[d,h]=k.useState(null),[p,g]=k.useState("closed"),m=k.useRef(null);return k.useEffect(()=>{if(!r)return;g("connecting");const y=new EventSource(`/api/requests/${encodeURIComponent(n)}/stream`);return y.onopen=()=>g("open"),y.onerror=()=>g(y.readyState===EventSource.CLOSED?"closed":"connecting"),y.addEventListener("snapshot",w=>{let x;try{x=JSON.parse(w.data)}catch{return}const j=m.current;m.current=x,h(x),j&&(j.status!==x.status||j.planStatus!==x.planStatus||j.lastActivityAt!==x.lastActivityAt)&&(s.invalidateQueries({queryKey:Be.request(n)}),j.status!==x.status&&(s.invalidateQueries({queryKey:["requests","list"]}),s.invalidateQueries({queryKey:Be.dashboard})))}),y.addEventListener("activity",w=>{try{const x=JSON.parse(w.data);u(j=>j.length>=Nm?[...j.slice(-Nm+1),x]:[...j,x])}catch{}}),()=>{y.close(),g("closed")}},[n,r,s]),{activity:o,snapshot:d,state:p}}const zb=["live","conversation","turns","plans","artifacts","events"];function Ub(){var j;const{id:n=""}=uw(),r=Vj(n),[s,o]=qd();Wd();const u=(j=r.data)==null?void 0:j.request.status,d=u?!Lb.includes(u):!1,h=Ib(n,d),p=s.get("tab"),g=p&&zb.includes(p)&&(p!=="live"||d)?p:d?"live":"conversation",m=_=>o(E=>{const S=new URLSearchParams(E);return S.set("tab",_),S},{replace:!0});if(r.isLoading)return i.jsx(kt,{});if(r.isError||!r.data)return r.error instanceof Wn&&r.error.code==="not_found"?i.jsxs("div",{className:"space-y-4",children:[i.jsx(Em,{}),i.jsx(rn,{children:"This request does not exist."})]}):i.jsx(Ot,{error:r.error,onRetry:()=>void r.refetch()});const y=r.data,w=y.request,x=[...d?[{value:"live",label:i.jsx($b,{state:h.state})}]:[],{value:"conversation",label:`Conversation (${y.messages.length})`},{value:"turns",label:`Turns (${y.turns.length})`},{value:"plans",label:`Plans (${y.plans.length})`},{value:"artifacts",label:`Artifacts (${y.artifacts.length})`},{value:"events",label:"Events"}];return i.jsxs("div",{className:"space-y-6",children:[i.jsx(Em,{}),i.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[i.jsxs("div",{className:"min-w-0 space-y-2",children:[i.jsx("h1",{className:"break-words text-xl font-semibold",children:w.title}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm text-muted-foreground",children:[i.jsx(hl,{status:w.status}),w.planStatus!=="none"&&i.jsxs(tt,{variant:"outline",children:["Plan ",w.planStatus]}),i.jsxs("span",{children:["by ",w.requesterName??w.requesterId]}),i.jsxs("span",{children:["in ",w.channelName?`#${w.channelName}`:w.channelId]}),i.jsxs("span",{title:mn(w.createdAt),children:["opened ",Yt(w.createdAt)]}),i.jsxs("span",{children:["cost ",fl(w.costUsd)]})]})]}),i.jsx(dy,{request:w})]}),i.jsx(He,{children:i.jsxs(Qe,{className:"grid gap-x-8 gap-y-2 p-5 text-sm sm:grid-cols-2",children:[i.jsx(Lo,{label:"Branch",children:w.branch?i.jsx("code",{className:"text-xs",children:w.branch}):"None"}),i.jsx(Lo,{label:"Working directory",children:i.jsx("code",{className:"break-all text-xs",children:w.cwd||w.workdir})}),i.jsx(Lo,{label:"Last activity",children:i.jsx("span",{title:mn(w.lastActivityAt),children:Yt(w.lastActivityAt)})}),i.jsx(Lo,{label:"Pull requests",children:w.prs.length===0?"None":w.prs.map(_=>{const E=rl(_),S=y.prFollows.find(P=>P.url===_);return i.jsxs("span",{className:"mr-3 inline-block",children:[E?i.jsx("a",{href:E,target:"_blank",rel:"noreferrer noopener",className:"break-all text-info underline",children:my(_)}):_,S&&i.jsxs("span",{className:"ml-1 text-xs text-muted-foreground",title:S.statusReason??S.lastError??void 0,children:["(",Zb(S),")"]})]},_)})}),w.pendingQuestion&&i.jsxs("div",{className:"rounded-md border border-warning/40 bg-warning-muted p-3 sm:col-span-2",children:[i.jsx("p",{className:"text-xs font-medium text-amber-300",children:"Waiting for an answer in Slack"}),i.jsx("p",{className:"mt-1 whitespace-pre-wrap break-words",children:w.pendingQuestion})]})]})}),i.jsxs("div",{children:[i.jsx(hy,{idPrefix:"req",label:"Request details",items:x,value:g,onChange:m}),i.jsxs(py,{idPrefix:"req",value:g,children:[g==="live"&&i.jsx(qb,{activity:h.activity,state:h.state}),g==="conversation"&&i.jsx(Qb,{messages:y.messages}),g==="turns"&&i.jsx(Wb,{turns:y.turns}),g==="plans"&&i.jsx(Kb,{plans:y.plans}),g==="artifacts"&&i.jsx(Yb,{artifacts:y.artifacts,requestId:w.id}),g==="events"&&i.jsx(Xb,{events:y.events})]})]})]})}function Em(){return i.jsxs(Bt,{to:"/requests",className:"inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground",children:[i.jsx(Tg,{className:"h-4 w-4","aria-hidden":!0}),"Requests"]})}function Lo({label:n,children:r}){return i.jsxs("div",{className:"flex gap-3",children:[i.jsx("span",{className:"w-36 shrink-0 text-muted-foreground",children:n}),i.jsx("span",{className:"min-w-0",children:r})]})}function my(n){const r=n.match(/github\.com\/([^/]+\/[^/]+)\/pull\/(\d+)/);return r?`${r[1]}#${r[2]}`:n}function $b({state:n}){return i.jsxs(i.Fragment,{children:[i.jsx("span",{"aria-hidden":!0,className:Xe("h-2 w-2 rounded-full",n==="open"?"animate-pulse bg-success":n==="connecting"?"bg-warning":"bg-muted-foreground")}),"Live"]})}function qb({activity:n,state:r}){const s=k.useRef(null),[o,u]=k.useState(!0);return k.useEffect(()=>{o&&s.current&&(s.current.scrollTop=s.current.scrollHeight)},[n,o]),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[i.jsx("span",{children:r==="open"?"Connected. Showing live agent activity.":r==="connecting"?"Connecting":"Disconnected"}),i.jsxs("label",{className:"flex items-center gap-2",children:[i.jsx("input",{type:"checkbox",checked:o,onChange:d=>u(d.target.checked),className:"accent-current"}),"Follow"]})]}),i.jsx("div",{ref:s,className:"h-96 overflow-y-auto rounded-md border bg-black/40 p-3 font-mono text-xs","aria-live":"off",children:n.length===0?i.jsx("p",{className:"text-muted-foreground",children:"No activity yet. It appears here while a turn runs."}):n.map((d,h)=>i.jsxs("div",{className:"flex gap-3 py-0.5",children:[i.jsx("span",{className:"shrink-0 text-muted-foreground",children:new Date(d.ts).toLocaleTimeString()}),i.jsx("span",{className:Xe("shrink-0 w-10",d.kind==="tool"?"text-info":"text-success"),children:d.kind}),i.jsx("span",{className:"min-w-0 whitespace-pre-wrap break-words",children:d.text})]},h))})]})}const Bb={mention:"Mention",follow_up:"Follow-up",prior_context:"Prior context",unlisted:"Unlisted user",synthetic:"System",command:"Command",conversation:"Conversation reply"},Hb=["prior_context","unlisted","conversation"];function Qb({messages:n}){return n.length?i.jsx("ol",{className:"space-y-3",children:n.map(r=>{const s=Hb.includes(r.source);return i.jsxs("li",{className:Xe("rounded-md border p-3",s&&"border-dashed border-warning/50 bg-warning-muted/40"),children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx("span",{className:"font-medium text-foreground",children:r.authorName??r.authorId??"System"}),i.jsxs(tt,{variant:s?"warning":"outline",children:[s&&i.jsx(L1,{className:"h-3 w-3","aria-hidden":!0}),Bb[r.source]]}),i.jsx(tt,{variant:r.state==="delivered"?"secondary":r.state==="pending"?"info":"muted",children:r.state}),i.jsx("span",{className:"ml-auto",title:mn(r.receivedAt),children:Yt(r.receivedAt)})]}),s&&i.jsx("p",{className:"mt-1 text-xs text-amber-300",children:"Untrusted: shown to the agent as context only, not as instructions."}),i.jsx("p",{className:"mt-2 whitespace-pre-wrap break-words text-sm",children:r.text})]},r.id)})}):i.jsx(rn,{children:"No messages."})}const Vb={answered:"success",asked:"warning",planned:"info",error:"destructive",cancelled:"muted",timeout:"destructive"};function wd({label:n,children:r,defaultOpen:s}){return i.jsxs("details",{className:"group mt-2",open:s,children:[i.jsxs("summary",{className:"flex cursor-pointer list-none items-center gap-1 text-xs text-muted-foreground hover:text-foreground",children:[i.jsx(_g,{className:"h-3 w-3 transition-transform group-open:rotate-90","aria-hidden":!0}),n]}),i.jsx("div",{className:"mt-2",children:r})]})}function Wb({turns:n}){return n.length?i.jsx("ol",{className:"space-y-3",children:n.map(r=>i.jsxs("li",{className:"rounded-md border p-3 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsxs("span",{className:"font-medium",children:["Turn ",r.seq]}),r.mode==="plan"&&i.jsx(tt,{variant:"outline",children:"Plan mode"}),r.outcome?i.jsx(tt,{variant:Vb[r.outcome],children:r.outcome}):i.jsx(tt,{variant:"secondary",children:r.status}),i.jsxs("span",{className:"text-xs text-muted-foreground",children:["trigger: ",r.trigger]}),i.jsx("span",{className:"ml-auto text-xs text-muted-foreground",title:mn(r.startedAt),children:r.startedAt?Yt(r.startedAt):"not started"})]}),i.jsxs("dl",{className:"mt-2 flex flex-wrap gap-x-6 gap-y-1 text-xs text-muted-foreground",children:[i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Duration "}),i.jsx("dd",{className:"inline text-foreground",children:yb(r.durationMs)})]}),i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Tokens "}),i.jsxs("dd",{className:"inline text-foreground",children:[jm(r.inputTokens)," in, ",jm(r.outputTokens)," out"]})]}),i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Cost "}),i.jsx("dd",{className:"inline text-foreground",children:fl(r.costUsd)})]}),r.stopReason&&i.jsxs("div",{children:[i.jsx("dt",{className:"inline",children:"Stop reason "}),i.jsx("dd",{className:"inline text-foreground",children:r.stopReason})]})]}),r.errorText&&i.jsx(wd,{label:"Error",defaultOpen:!0,children:i.jsx("pre",{className:"overflow-x-auto whitespace-pre-wrap break-words rounded bg-destructive-muted p-2 text-xs text-red-200",children:r.errorText})}),r.resultText&&i.jsx(wd,{label:"Result",children:i.jsx("pre",{className:"max-h-96 overflow-auto whitespace-pre-wrap break-words rounded bg-muted p-2 text-xs",children:r.resultText})})]},r.id))}):i.jsx(rn,{children:"No turns yet."})}function Kb({plans:n}){if(!n.length)return i.jsx(rn,{children:"No plans for this request."});const r=[...n].sort((s,o)=>o.version-s.version);return i.jsx("div",{className:"space-y-4",children:r.map((s,o)=>i.jsx(He,{children:i.jsxs(Qe,{className:"p-5",children:[i.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsxs("span",{className:"text-sm font-medium text-foreground",children:["Version ",s.version]}),i.jsx(tt,{variant:s.status==="approved"?"success":s.status==="rejected"?"destructive":"warning",children:s.status}),s.decidedBy&&i.jsxs("span",{children:["by ",s.decidedBy," ",s.decidedAt?Yt(s.decidedAt):""]}),i.jsx("span",{className:"ml-auto",children:mn(s.createdAt)})]}),s.feedback&&i.jsxs("div",{className:"mb-3 rounded-md border bg-muted/40 p-3 text-sm",children:[i.jsx("p",{className:"text-xs text-muted-foreground",children:"Feedback"}),i.jsx("p",{className:"mt-1 whitespace-pre-wrap break-words",children:s.feedback})]}),o===0?i.jsx(Cm,{source:s.markdown}):i.jsx(wd,{label:"Show plan",children:i.jsx(Cm,{source:s.markdown})})]})},s.version))})}function Gb({requestId:n}){var u;const s=((u=Rt({queryKey:["screenshots",n],queryFn:()=>Ee(`/api/requests/${encodeURIComponent(n)}/screenshots`),refetchInterval:15e3}).data)==null?void 0:u.items)??[];if(!s.length)return null;const o=d=>`/api/requests/${encodeURIComponent(n)}/screenshots/${d.split("/").map(encodeURIComponent).join("/")}`;return i.jsxs("div",{className:"space-y-2",children:[i.jsxs("h3",{className:"text-sm font-medium",children:["Screenshots (",s.length,")"]}),i.jsx("div",{className:"grid grid-cols-2 gap-3 md:grid-cols-3",children:s.map(d=>i.jsxs("a",{href:o(d.name),target:"_blank",rel:"noreferrer noopener",className:"group overflow-hidden rounded-md border",children:[i.jsx("img",{src:o(d.name),alt:d.name,loading:"lazy",className:"aspect-video w-full bg-muted object-cover object-top"}),i.jsxs("div",{className:"flex justify-between gap-2 px-2 py-1 text-xs text-muted-foreground",children:[i.jsx("span",{className:"truncate",children:d.name}),i.jsx("span",{className:"shrink-0",children:Yt(d.mtime)})]})]},d.name))})]})}function Yb({artifacts:n,requestId:r}){return i.jsxs("div",{className:"space-y-4",children:[i.jsx(Gb,{requestId:r}),i.jsx(Jb,{artifacts:n})]})}function Jb({artifacts:n}){return n.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.map(r=>{const s=r.kind==="pr"?Wk:r.kind==="screenshot"?Xk:zk,o=rl(r.urlOrPath);return i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx(s,{className:"h-4 w-4 shrink-0 text-muted-foreground","aria-hidden":!0}),i.jsxs("div",{className:"min-w-0 flex-1",children:[r.title&&i.jsx("p",{className:"truncate font-medium",children:r.title}),o?i.jsx("a",{href:o,target:"_blank",rel:"noreferrer noopener",className:"break-all text-xs text-info underline",children:r.kind==="pr"?my(r.urlOrPath):r.urlOrPath}):i.jsx("code",{className:"break-all text-xs text-muted-foreground",children:r.urlOrPath})]}),i.jsx("span",{className:"shrink-0 text-xs text-muted-foreground",children:Yt(r.createdAt)})]},r.id)})}):i.jsx(rn,{children:"No artifacts yet."})}function Xb({events:n}){return n.length?i.jsx("div",{className:"overflow-x-auto rounded-md border",children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Time"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Type"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Summary"})]})}),i.jsx("tbody",{className:"divide-y",children:n.map(r=>i.jsxs("tr",{children:[i.jsx("td",{className:"whitespace-nowrap px-3 py-1.5 text-xs text-muted-foreground",children:mn(r.ts)}),i.jsx("td",{className:"whitespace-nowrap px-3 py-1.5",children:i.jsx("code",{className:"text-xs",children:r.type})}),i.jsx("td",{className:"px-3 py-1.5 break-words",children:r.summary})]},r.id))})]})}):i.jsx(rn,{children:"No events."})}function Zb(n){const r=n.status==="active"?"following":n.status==="gave_up"?"left for a human":n.status==="paused"?"not following":n.status,s=n.status==="active"&&n.ci&&n.ci!=="none"?`, CI ${n.ci}`:"",o=n.status==="active"&&n.mergeable==="CONFLICTING"?", conflicts":"";return r+s+o}const Rm=50;function eS(){const[n,r]=qd(),s=Math.max(1,Number(n.get("page"))||1),o=ob(s,Rm);return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Audit log",description:"Admin sign-ins and configuration changes on this machine."}),o.isLoading?i.jsx(kt,{}):o.isError||!o.data?i.jsx(Ot,{error:o.error,onRetry:()=>void o.refetch()}):o.data.items.length===0?i.jsx(rn,{children:"No audit entries yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:Xe("overflow-x-auto rounded-lg border",o.isPlaceholderData&&"opacity-60"),children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Time"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Actor"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Action"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Detail"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"IP"})]})}),i.jsx("tbody",{className:"divide-y",children:o.data.items.map(u=>i.jsxs("tr",{children:[i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-muted-foreground",children:mn(u.ts)}),i.jsx("td",{className:"px-3 py-2",children:u.actor}),i.jsx("td",{className:"px-3 py-2",children:i.jsx("code",{className:"text-xs",children:u.action})}),i.jsx("td",{className:"max-w-md break-words px-3 py-2 text-muted-foreground",children:u.detail??""}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-xs text-muted-foreground",children:u.ip??""})]},u.id))})]})}),i.jsx(uy,{page:s,pageSize:Rm,total:o.data.total,onPage:u=>r(u===1?{}:{page:String(u)},{replace:!0})})]})]})}const ps=k.forwardRef(({checked:n,onCheckedChange:r,className:s,...o},u)=>i.jsx("button",{ref:u,type:"button",role:"switch","aria-checked":n,onClick:()=>r(!n),className:Xe("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",n?"bg-primary":"bg-input",s),...o,children:i.jsx("span",{className:Xe("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform",n?"translate-x-5":"translate-x-0")})}));ps.displayName="Switch";const Pm={pending:{label:"Waiting for confirmation",variant:"warning"},active:{label:"Active",variant:"success"},paused:{label:"Paused",variant:"muted"}};function tS(){const n=ub(),r=ry(),s=fb(),o=db(),[u,d]=k.useState(null),[h,p]=k.useState(null),g=(m,y)=>r.mutate({id:m.id,patch:{status:y?"active":"paused"}},{onError:w=>We({title:"Couldn't change the schedule",description:yt(w),variant:"error"})});return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Schedules",description:"Recurring tasks and one-time reminders people set up in Slack (for example daily insights in a channel). Each run posts its result in the channel; replies in its thread continue the conversation. A one-time task leaves this list after it runs."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):n.data.length===0?i.jsx(rn,{children:`No schedules yet. Ask the agent in Slack, e.g. "send a summary of yesterday's sales every weekday at 9:00 in this channel".`}):i.jsx("div",{className:"overflow-x-auto rounded-lg border",children:i.jsxs("table",{className:"w-full text-sm",children:[i.jsx("thead",{className:"bg-muted/40 text-left text-xs text-muted-foreground",children:i.jsxs("tr",{children:[i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Schedule"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"When"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Channel"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Next run"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"Last run"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:"On"}),i.jsx("th",{scope:"col",className:"px-3 py-2 font-medium",children:i.jsx("span",{className:"sr-only",children:"Actions"})})]})}),i.jsx("tbody",{className:"divide-y",children:n.data.map(m=>i.jsxs("tr",{className:"align-top",children:[i.jsxs("td",{className:"px-3 py-2",children:[i.jsx("button",{type:"button",className:"text-left font-medium hover:underline",onClick:()=>d(m),children:m.title}),i.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx(tt,{variant:Pm[m.status].variant,children:Pm[m.status].label}),i.jsxs("span",{children:["by ",m.createdByName??m.createdBy]})]}),m.statusReason&&i.jsx("div",{className:"mt-1 text-xs text-amber-300",children:m.statusReason})]}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2",children:[m.when,i.jsx("div",{className:"text-xs text-muted-foreground",children:m.timezone})]}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2",children:["#",m.channelName??m.channelId]}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2 text-muted-foreground",children:m.nextRunAt?i.jsx("span",{title:mn(m.nextRunAt),children:Yt(m.nextRunAt)}):"—"}),i.jsx("td",{className:"whitespace-nowrap px-3 py-2",children:m.lastRunAt?i.jsxs("div",{className:"flex items-center gap-2",children:[m.lastRunStatus==="missed"?i.jsx(tt,{variant:"muted",children:"Missed"}):m.lastRunStatus?i.jsx(hl,{status:m.lastRunStatus}):null,m.lastRequestId?i.jsx(Bt,{to:`/requests/${m.lastRequestId}`,className:"text-xs text-muted-foreground hover:underline",children:Yt(m.lastRunAt)}):i.jsx("span",{className:"text-xs text-muted-foreground",children:Yt(m.lastRunAt)})]}):i.jsx("span",{className:"text-muted-foreground",children:"Never"})}),i.jsx("td",{className:"px-3 py-2",children:i.jsx(ps,{checked:m.status==="active",disabled:m.status==="pending"||r.isPending,"aria-label":m.status==="active"?`Pause ${m.title}`:`Resume ${m.title}`,onCheckedChange:y=>g(m,y)})}),i.jsxs("td",{className:"whitespace-nowrap px-3 py-2 text-right",children:[i.jsxs(oe,{variant:"ghost",size:"sm",disabled:m.status==="pending"||s.isPending,onClick:()=>s.mutate(m.id,{onSuccess:()=>We({title:"Run started",description:`#${m.channelName??m.channelId}`,variant:"success"}),onError:y=>We({title:"Couldn't start the run",description:yt(y),variant:"error"})}),children:[i.jsx(p1,{className:"h-4 w-4","aria-hidden":!0})," Run now"]}),i.jsx(oe,{variant:"ghost",size:"sm",onClick:()=>d(m),"aria-label":`Edit ${m.title}`,children:i.jsx(f1,{className:"h-4 w-4","aria-hidden":!0})}),i.jsx(oe,{variant:"ghost",size:"sm",onClick:()=>p(m),"aria-label":`Delete ${m.title}`,children:i.jsx(qo,{className:"h-4 w-4","aria-hidden":!0})})]})]},m.id))})]})}),u&&i.jsx(nS,{schedule:u,onClose:()=>d(null)}),i.jsx(Gd,{open:!!h,title:"Delete this schedule?",description:h?`"${h.title}" stops running. Past runs stay in Requests.`:"",confirmLabel:"Delete",destructive:!0,pending:o.isPending,onClose:()=>p(null),onConfirm:()=>h&&o.mutate(h.id,{onSuccess:()=>p(null),onError:m=>We({title:"Couldn't delete",description:yt(m),variant:"error"})})})]})}function nS({schedule:n,onClose:r}){var E;const s=cb(n.id),o=ry(),[u,d]=k.useState(n.title),[h,p]=k.useState(n.prompt),[g,m]=k.useState(n.cron),[y,w]=k.useState(n.timezone),[x,j]=k.useState(null),_=()=>{j(null);const S={...u!==n.title&&{title:u},...h!==n.prompt&&{prompt:h},...g!==n.cron&&{cron:g},...y!==n.timezone&&{timezone:y}};if(!Object.keys(S).length)return r();o.mutate({id:n.id,patch:S},{onSuccess:()=>{We({title:"Schedule saved",variant:"success"}),r()},onError:P=>{var U,Q;const D=(Q=(U=P.body)==null?void 0:U.error)==null?void 0:Q.field;j({field:D,message:yt(P)})}})};return i.jsx(Kd,{open:!0,onClose:r,title:"Edit schedule",description:`${n.when} (${n.timezone}) · #${n.channelName??n.channelId}`,className:"max-w-2xl",footer:i.jsxs(i.Fragment,{children:[i.jsx(oe,{variant:"outline",onClick:r,children:"Cancel"}),i.jsx(oe,{onClick:_,disabled:o.isPending,children:"Save"})]}),children:i.jsxs("div",{className:"space-y-4",children:[i.jsx(Oe,{label:"Title",error:(x==null?void 0:x.field)==="title"?x.message:null,children:S=>i.jsx(Re,{...S,value:u,maxLength:80,onChange:P=>d(P.target.value)})}),i.jsx(Oe,{label:"What to do on each run",help:"Runs start without the original conversation, so keep this self-contained.",children:S=>i.jsx("textarea",{...S,value:h,maxLength:4e3,rows:6,onChange:P=>p(P.target.value),className:"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"})}),i.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[i.jsx(Oe,{label:"When (cron)",help:"minute hour day month weekday, e.g. 0 9 * * 1-5 for weekdays at 9:00",error:(x==null?void 0:x.field)==="cron"?x.message:null,children:S=>i.jsx(Re,{...S,value:g,onChange:P=>m(P.target.value),className:"font-mono"})}),i.jsx(Oe,{label:"Timezone",help:"e.g. America/Sao_Paulo",error:(x==null?void 0:x.field)==="timezone"?x.message:null,children:S=>i.jsx(Re,{...S,value:y,onChange:P=>w(P.target.value)})})]}),x&&!["title","cron","timezone"].includes(x.field??"")&&i.jsx("p",{className:"text-sm text-red-300",children:x.message}),i.jsxs("div",{children:[i.jsx("h3",{className:"mb-2 text-sm font-medium",children:"Recent runs"}),s.isLoading?i.jsx(kt,{}):(E=s.data)!=null&&E.runs.length?i.jsx("ul",{className:"divide-y rounded-md border text-sm",children:s.data.runs.map(S=>i.jsxs("li",{className:"flex items-center justify-between gap-2 px-3 py-2",children:[i.jsx(Bt,{to:`/requests/${S.requestId}`,className:"hover:underline",onClick:r,children:mn(S.createdAt)}),i.jsx(hl,{status:S.status})]},S.requestId))}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"No runs yet."})]})]})})}const rS=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/,sS="flex w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";function aS(){const n=hb();return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Setup",description:"Commands a fresh worktree needs before the agent starts: install dependencies, copy an example env file, build. They run in the same sandbox as the agent, once per worktree, without FDA's tokens or the Anthropic key. The agent can propose a script; it only runs after you approve it here."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):!n.data.workdir||!n.data.isRepo?i.jsxs(rn,{children:["Setup scripts run in per-request worktrees, so the working directory must be a git repository. The current one"," ",n.data.workdir?i.jsx("code",{children:n.data.workdir}):"isn't set",n.data.workdir?" isn't a repository":"","."]}):i.jsx(iS,{repoPath:n.data.workdir,row:n.data.scripts.find(r=>r.repoPath===n.data.workdir)??null})]})}function iS({repoPath:n,row:r}){const s=pb(),o=mb(),[u,d]=k.useState((r==null?void 0:r.script)??""),[h,p]=k.useState((r==null?void 0:r.onFailure)??"continue"),[g,m]=k.useState(String((r==null?void 0:r.timeoutSec)??600)),[y,w]=k.useState((r==null?void 0:r.enabled)??!0);k.useEffect(()=>{d((r==null?void 0:r.script)??""),p((r==null?void 0:r.onFailure)??"continue"),m(String((r==null?void 0:r.timeoutSec)??600)),w((r==null?void 0:r.enabled)??!0)},[r==null?void 0:r.updatedAt]);const x=E=>S=>We({title:E,description:yt(S),variant:"error"}),j=()=>s.mutate({repoPath:n,script:u.trim()||null,onFailure:h,timeoutSec:Number(g),enabled:y},{onSuccess:()=>We({title:"Setup script saved"}),onError:x("Couldn't save the setup script")}),_=E=>{var S;return o.mutate({repoPath:n,action:E,proposedAt:((S=r==null?void 0:r.proposal)==null?void 0:S.at)??null},{onSuccess:()=>We(E==="approve"?{title:"Proposal approved",description:"It's saved and runs in every new worktree (no need to press Save)."}:{title:"Proposal dismissed"}),onError:x("Couldn't update the proposal")})};return i.jsxs("div",{className:"space-y-4",children:[(r==null?void 0:r.proposal)&&i.jsx(He,{className:"border-warning/40",children:i.jsxs(Qe,{className:"space-y-3 p-5 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsx(tt,{variant:"warning",children:"Proposed by the agent"}),r.proposal.at&&i.jsx("span",{className:"text-muted-foreground",title:mn(r.proposal.at),children:Yt(r.proposal.at)}),r.proposal.requestId&&i.jsx(Bt,{to:`/requests/${r.proposal.requestId}`,className:"text-info underline",children:"from this request"})]}),r.proposal.reason&&i.jsx("p",{children:r.proposal.reason}),rS.test(r.proposal.script)&&i.jsx("p",{className:"text-xs font-medium text-destructive",children:"This script contains invisible or direction-changing characters. Don't approve it unless you know why."}),i.jsx("pre",{className:"max-h-72 overflow-auto rounded-md bg-muted/40 p-3 font-mono text-xs",children:r.proposal.script}),i.jsx("p",{className:"text-xs text-muted-foreground",children:"Read it before approving: it will run in every new worktree."}),i.jsxs("div",{className:"flex gap-2",children:[i.jsx(oe,{size:"sm",onClick:()=>_("approve"),disabled:o.isPending,children:"Approve and use"}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>_("reject"),disabled:o.isPending,children:"Dismiss"})]})]})}),i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-4 p-5",children:[i.jsxs("p",{className:"text-sm",children:["Repository ",i.jsx("code",{className:"text-xs",children:n})]}),i.jsx(Oe,{label:"Script",help:"Runs with bash in the new worktree. Example: npm ci && cp -n .env.example .env",children:E=>i.jsx("textarea",{...E,value:u,rows:8,maxLength:2e4,spellCheck:!1,placeholder:"npm ci",onChange:S=>d(S.target.value),className:sS})}),i.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[i.jsx(Oe,{label:"If it fails",help:"Continue tells the agent what failed; Stop fails the request.",children:E=>i.jsxs(eu,{...E,value:h,onChange:S=>p(S.target.value),children:[i.jsx("option",{value:"continue",children:"Continue"}),i.jsx("option",{value:"fail",children:"Stop"})]})}),i.jsx(Oe,{label:"Timeout (seconds)",help:"10 to 3600.",children:E=>i.jsx(Re,{...E,type:"number",min:10,max:3600,value:g,onChange:S=>m(S.target.value)})}),i.jsxs("div",{className:"space-y-1.5",children:[i.jsx("p",{className:"text-sm font-medium",children:"Enabled"}),i.jsx(ps,{checked:y,onCheckedChange:w,"aria-label":"Run the setup script"})]})]}),i.jsx(oe,{onClick:j,disabled:s.isPending,children:"Save"})]})}),i.jsxs("div",{children:[i.jsx("h2",{className:"mb-2 text-sm font-medium",children:"Recent runs"}),r!=null&&r.runs.length?i.jsx("ul",{className:"divide-y rounded-md border",children:r.runs.map(E=>i.jsxs("li",{className:"space-y-2 p-3 text-sm",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i.jsx(tt,{variant:E.status==="ok"?"success":E.status==="timeout"?"warning":"destructive",children:E.status==="ok"?"OK":E.status==="timeout"?"Timed out":`Failed (exit ${E.exitCode??"?"})`}),i.jsx("span",{className:"text-muted-foreground",title:mn(E.startedAt),children:Yt(E.startedAt)}),E.durationMs!==null&&i.jsxs("span",{className:"text-muted-foreground",children:[Math.round(E.durationMs/1e3),"s"]}),i.jsx(Bt,{to:`/requests/${E.requestId}`,className:"text-info underline",children:"request"})]}),E.log&&i.jsxs("details",{children:[i.jsx("summary",{className:"cursor-pointer text-xs text-muted-foreground",children:"Output"}),i.jsx("pre",{className:"mt-2 max-h-72 overflow-auto rounded-md bg-muted/40 p-3 font-mono text-xs",children:E.log})]})]},E.id))}):i.jsx(rn,{children:"No runs yet."})]})]})}const kd=["browser"],lS=new Set(["Enter","Tab","Backspace","Delete","Escape","Home","End","PageUp","PageDown","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]);function oS(){return Rt({queryKey:kd,queryFn:()=>Ee("/api/browser"),refetchInterval:2e4})}function gy(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"sites"in r&&n.setQueryData(kd,r)},onSettled:()=>void n.invalidateQueries({queryKey:kd})})}function uS(){const n=oS();return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Browser",description:"Sign the agent in to the sites it needs (a staging app, a dashboard). You drive a browser on this machine from here; Save and close keeps its cookies (encrypted), and every browser task starts signed in. Use test accounts: the agent can read what its browser holds."}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):n.data.installed?i.jsxs(i.Fragment,{children:[!n.data.enabled&&i.jsx("p",{className:"rounded-md border border-warning/50 bg-warning-muted p-3 text-sm",children:"The browser is off for tasks (Settings → General → Browser). You can still save sign-ins now; tasks use them once it's on."}),i.jsx(cS,{data:n.data}),i.jsx(dS,{data:n.data})]}):i.jsxs(rn,{children:["The browser isn't installed on this machine. Install it there with"," ",i.jsx("code",{children:"superclawd fda browser install"}),", then enable it in Settings → General."]})]})}function cS({data:n}){const r=gy(),[s,o]=k.useState(""),[u,d]=k.useState(null),h=k.useRef(null),p=k.useRef(null),g=n.session.open,{width:m,height:y}=n.session.viewport;k.useEffect(()=>{if(!g){d(null);return}const P=new EventSource("/api/browser/session/stream");return P.addEventListener("frame",D=>{const U=JSON.parse(D.data);d({src:`data:image/jpeg;base64,${U.data}`,url:U.url,title:U.title,tabs:U.tabs})}),P.addEventListener("closed",()=>P.close()),P.addEventListener("expired",()=>P.close()),()=>P.close()},[g]),k.useEffect(()=>{var P;u!=null&&u.url&&((P=document.activeElement)==null?void 0:P.id)!=="browser-address"&&o(u.url)},[u==null?void 0:u.url]);const w=P=>D=>We({title:P,description:yt(D),variant:"error"}),x=P=>Ee("/api/browser/session/input",{method:"POST",body:P}).catch(w("Couldn't send that to the browser")),j=P=>{const D=h.current.getBoundingClientRect();return{x:Math.round((P.clientX-D.left)/D.width*m),y:Math.round((P.clientY-D.top)/D.height*y)}},_=P=>r.mutateAsync({path:"/api/browser/session",body:{url:P}}).catch(w("Couldn't open the page")),E=P=>{if(!g)return;const D=[P.ctrlKey&&"Control",P.altKey&&"Alt",P.metaKey&&"Meta"].filter(Boolean);lS.has(P.key)?(P.preventDefault(),x({type:"key",key:[...D,...P.shiftKey?["Shift"]:[],P.key].join("+")})):P.key.length===1&&D.length?(P.preventDefault(),x({type:"key",key:[...D,P.key].join("+")})):P.key.length===1&&(P.preventDefault(),x({type:"text",text:P.key}))},S=P=>{const D=P.clipboardData.getData("text/plain");!D||!g||(P.preventDefault(),x({type:"text",text:D.slice(0,2e3)}))};return i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6",children:[i.jsxs("form",{className:"flex items-center gap-2",onSubmit:P=>{P.preventDefault(),s.trim()&&_(s.trim())},children:[i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Back",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"back"}}).catch(w("Couldn't go back")),children:i.jsx(Tg,{className:"h-4 w-4"})}),i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Forward",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"forward"}}).catch(w("Couldn't go forward")),children:i.jsx(Lg,{className:"h-4 w-4"})}),i.jsx(oe,{type:"button",variant:"outline",size:"icon","aria-label":"Reload",disabled:!g,onClick:()=>void Ee("/api/browser/session/go",{method:"POST",body:{action:"reload"}}).catch(w("Couldn't reload")),children:i.jsx(k1,{className:"h-4 w-4"})}),i.jsx(Re,{id:"browser-address",value:s,onChange:P=>o(P.target.value),placeholder:"https://staging.example.com/login","aria-label":"Address",className:"flex-1"}),i.jsxs(oe,{type:"submit",disabled:r.isPending||!s.trim(),children:[i.jsx(Ag,{className:"mr-1 h-4 w-4"}),g?"Go":"Open browser"]})]}),g?i.jsxs(i.Fragment,{children:[i.jsx("div",{ref:p,tabIndex:0,role:"application","aria-label":"Remote browser: click to focus, then type",className:"relative overflow-hidden rounded-md border bg-muted outline-none focus:ring-2 focus:ring-ring",onKeyDown:E,onPaste:S,children:u?i.jsx("img",{ref:h,src:u.src,alt:u.title||"Remote browser",draggable:!1,className:"block w-full cursor-pointer select-none",style:{aspectRatio:`${m} / ${y}`},onClick:P=>{var D;(D=p.current)==null||D.focus(),x({type:"click",...j(P)})},onDoubleClick:P=>void x({type:"click",double:!0,...j(P)}),onContextMenu:P=>{P.preventDefault(),x({type:"click",button:"right",...j(P)})},onWheel:P=>void x({type:"wheel",...j(P),dx:Math.round(P.deltaX),dy:Math.round(P.deltaY)})}):i.jsx("div",{className:"flex items-center justify-center text-sm text-muted-foreground",style:{aspectRatio:`${m} / ${y}`},children:"Loading the page…"})}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-muted-foreground",children:[i.jsx("span",{children:"Click the page, then type. Paste works too. Passwords you type go straight to the site; they aren't stored by FDA."}),u&&u.tabs>1&&i.jsxs(tt,{variant:"secondary",children:[u.tabs," tabs (showing the newest)"]}),!n.session.sandboxed&&i.jsx(tt,{variant:"secondary",children:"Chrome sandbox unavailable on this host"}),n.session.idleClosesAt&&i.jsxs("span",{children:["Closes when idle, latest ",mn(n.session.idleClosesAt),"."]})]}),i.jsxs("div",{className:"flex gap-2",children:[i.jsxs(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/browser/session/save",body:{close:!0}}).then(()=>We({title:"Sign-ins saved",description:"New browser tasks start signed in. Open the browser again to add another site."})).catch(w("Couldn't save the sign-ins")),children:[i.jsx(b1,{className:"mr-1 h-4 w-4"}),"Save and close"]}),i.jsxs(oe,{variant:"outline",disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/browser/session",method:"DELETE"}).catch(w("Couldn't close the browser")),children:[i.jsx(Bd,{className:"mr-1 h-4 w-4"}),"Close without saving"]})]})]}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"Enter the sign-in page of a site and open the browser. Sign in as you normally would (including two-factor), then Save and close."})]})})}function dS({data:n}){const r=gy(),[s,o]=k.useState(null),u=d=>h=>We({title:d,description:yt(h),variant:"error"});return i.jsxs(He,{children:[i.jsxs(Qe,{className:"space-y-3 pt-6",children:[i.jsxs("div",{className:"flex items-center justify-between",children:[i.jsx("h2",{className:"font-medium",children:"Signed-in sites"}),n.sites.length>1&&i.jsx(oe,{variant:"outline",size:"sm",onClick:()=>o("all"),children:"Sign out of all"})]}),n.sites.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.sites.map(d=>i.jsxs("li",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:d.site}),i.jsxs("span",{className:"text-muted-foreground",children:[d.cookies," cookie",d.cookies===1?"":"s",d.origins?`, local storage on ${d.origins}`:"",d.expiresAt?`, until ${mn(d.expiresAt)}`:", session only"]}),i.jsxs(oe,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>o(d.site),children:[i.jsx(Dg,{className:"mr-1 h-4 w-4"}),"Sign out"]})]},d.site))}):i.jsx("p",{className:"text-sm text-muted-foreground",children:"None yet. Browser tasks start with a clean browser."}),i.jsx("p",{className:"text-xs text-muted-foreground",children:"Signing out here removes the saved cookies from this machine. It doesn't end the session on the site itself; to be sure, sign out there or change the password."})]}),i.jsx(Gd,{open:s!==null,onClose:()=>o(null),title:s==="all"?"Sign out of all sites?":`Sign out of ${s}?`,description:"New browser tasks will start without these sign-ins.",confirmLabel:"Sign out",destructive:!0,onConfirm:()=>{const d=s;o(null),r.mutateAsync({path:d==="all"?"/api/browser/sites":`/api/browser/sites/${encodeURIComponent(d)}`,method:"DELETE"}).catch(u("Couldn't sign out"))}})]})}function Js({text:n,label:r="Copy"}){const[s,o]=k.useState(!1),u=async()=>{try{await navigator.clipboard.writeText(n),o(!0),setTimeout(()=>o(!1),1500)}catch{We({title:"Could not copy",description:"Select the text and copy it manually.",variant:"error"})}};return i.jsxs(oe,{variant:"outline",size:"sm",onClick:u,children:[s?i.jsx(Mg,{}):i.jsx(_k,{}),s?"Copied":r]})}const yy=["tickets"],fS={queued:{label:"Queued",variant:"muted"},working:{label:"Working",variant:"info"},waiting:{label:"Waiting for a reply",variant:"warning"},in_review:{label:"PR in review",variant:"info"},done:{label:"Done",variant:"success"},released:{label:"Taken off",variant:"muted"},refused:{label:"Refused",variant:"destructive"}};function hS(){return Rt({queryKey:yy,queryFn:()=>Ee("/api/tickets"),refetchInterval:15e3})}function Xa(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"items"in r&&n.setQueryData(yy,r)}})}const Vn=n=>r=>We({title:n,description:yt(r),variant:"error"});function pS(){const n=hS(),r=Xa();if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const s=n.data;return i.jsxs("div",{className:"space-y-4",children:[i.jsx(ys,{title:"Tickets",description:"People hand tickets to the agent in Linear (assign or @mention it) or GitHub (a label). It works them one at a time in its own worktree, opens a pull request, follows CI and reviews, and replies on the ticket. Only people on the access list can hand tickets over; the ticket's text is treated as data, not instructions.",actions:i.jsxs(oe,{variant:"outline",size:"sm",disabled:r.isPending||!s.settings.enabled,onClick:()=>void r.mutateAsync({path:"/api/tickets/poll"}).then(o=>We({title:"Checked",description:`${o.handled} new event(s).`})).catch(Vn("Couldn't check the trackers")),children:[i.jsx(y1,{className:"mr-1 h-4 w-4"}),"Check now"]})}),i.jsx(mS,{d:s}),i.jsx(gS,{d:s}),i.jsx(yS,{d:s}),s.jira.available&&i.jsx(vS,{d:s}),i.jsx(xS,{d:s}),i.jsx(wS,{d:s})]})}function Xi({label:n,help:r,checked:s,onChange:o}){return i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"font-medium",children:n}),i.jsx("p",{className:"text-sm text-muted-foreground",children:r})]}),i.jsx(ps,{checked:s,onCheckedChange:o,"aria-label":n})]})}function mS({d:n}){const r=Xa(),s=n.settings,[o,u]=k.useState(String(s.atATime)),[d,h]=k.useState(s.budgetUsd===null?"":String(s.budgetUsd)),[p,g]=k.useState(s.dailyBudgetUsd===null?"":String(s.dailyBudgetUsd)),[m,y]=k.useState(s.statusOnPr??""),[w,x]=k.useState(s.statusOnQuestion??""),[j,_]=k.useState(s.questionReminderHours===null?"":String(s.questionReminderHours)),[E,S]=k.useState(s.slackChannel??""),P=(D,U)=>r.mutateAsync({path:"/api/tickets",method:"PUT",body:D}).then(()=>U&&We({title:U,variant:"success"})).catch(Vn("Couldn't save"));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"How it works on tickets"}),i.jsx(Tt,{children:"Off by default. Turn it on once a tracker is connected."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(Xi,{label:"Work on handed-over tickets",help:"Off: tickets are ignored (nothing is read or posted).",checked:s.enabled,onChange:D=>void P({enabled:D})}),i.jsx(Xi,{label:"Auto-merge pull requests",help:"Turns on GitHub auto-merge for a ticket's PR: it merges only when required checks and approvals pass. Off: people merge.",checked:s.autoMerge,onChange:D=>void P({autoMerge:D})}),i.jsx(Xi,{label:"Move tickets to In Progress",help:"When work starts (Linear: the team's first started state).",checked:s.statusOnStart,onChange:D=>void P({statusOnStart:D})}),i.jsx(Xi,{label:"DM the person when a ticket needs them",help:"A question or plan on a ticket mentions whoever handed it over there, and (when their email matches a Slack person) sends them a Slack DM. Needs the im:write scope.",checked:s.dmOnQuestion,onChange:D=>void P({dmOnQuestion:D})}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Tickets at a time",help:"Pull requests in review don't count.",children:D=>i.jsx(Re,{...D,type:"number",min:1,max:8,value:o,onChange:U=>u(U.target.value)})}),i.jsx(Oe,{label:"Budget per ticket (USD)",help:"All its turns together. Empty: unlimited.",children:D=>i.jsx(Re,{...D,type:"number",min:.5,step:.5,value:d,placeholder:"Unlimited",onChange:U=>h(U.target.value)})}),i.jsx(Oe,{label:"Daily budget for tickets (USD)",help:"Tickets wait once it's spent. Empty: unlimited.",children:D=>i.jsx(Re,{...D,type:"number",min:1,value:p,placeholder:"Unlimited",onChange:U=>g(U.target.value)})}),i.jsx(Oe,{label:"State when the PR opens",help:"By name, e.g. In Review (empty: don't move).",children:D=>i.jsx(Re,{...D,value:m,onChange:U=>y(U.target.value),placeholder:"In Review"})}),i.jsx(Oe,{label:"State while waiting on a question",help:"By name, e.g. Blocked (GitHub: a label). Moved back when answered. Empty: don't move.",children:D=>i.jsx(Re,{...D,value:w,onChange:U=>x(U.target.value),placeholder:"Blocked"})}),i.jsx(Oe,{label:"Remind after (hours)",help:"One reminder on the ticket and by DM if nobody answers. Empty: never.",children:D=>i.jsx(Re,{...D,type:"number",min:1,max:720,value:j,placeholder:"Never",onChange:U=>_(U.target.value)})}),i.jsx(Oe,{label:"PR review channel",help:"Optional. The FDA posts each pull request it opens here and reacts when it's merged. Channel id (C…).",children:D=>i.jsx(Re,{...D,value:E,onChange:U=>S(U.target.value),placeholder:"C0123456789"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void P({atATime:Number(o),budgetUsd:d.trim()?Number(d):null,dailyBudgetUsd:p.trim()?Number(p):null,statusOnPr:m.trim(),statusOnQuestion:w.trim(),questionReminderHours:j.trim()?Number(j):null,slackChannel:E.trim()},"Saved"),children:"Save"})]})]})}function gS({d:n}){const r=Xa(),s=n.linear,[o,u]=k.useState(s.clientId??""),[d,h]=k.useState(""),[p,g]=k.useState(s.teams.join(", "));return k.useEffect(()=>u(s.clientId??""),[s.clientId]),i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Linear"}),i.jsx(Tt,{children:"The agent is a Linear app (agents don't take a paid seat). People delegate an issue to it or @mention it; it reports in the issue's agent session. Create an OAuth app in Linear (Settings → API → OAuth applications), with this redirect URI, then connect it as an app."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Workspace:"}),s.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:s.workspace}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/tickets/linear/connection",method:"DELETE"}).catch(Vn("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!s.configured,onClick:()=>void Ee("/api/tickets/linear/connect",{method:"POST"}).then(m=>window.location.assign(m.url)).catch(Vn("Couldn't start the Linear install")),children:"Connect Linear"}),!s.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the client below first."})]})]}),i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Callback URL (add it to the Linear OAuth app)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:s.redirectUri}),i.jsx(Js,{text:s.redirectUri})]})]}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Client ID",children:m=>i.jsx(Re,{...m,value:o,onChange:y=>u(y.target.value)})}),i.jsx(Oe,{label:"Client secret",help:s.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:m=>i.jsx(Re,{...m,type:"password",autoComplete:"off",value:d,onChange:y=>h(y.target.value),placeholder:s.hasSecret?"••••••••":""})}),i.jsx(Oe,{label:"Teams",help:"Team keys, comma separated (empty: every team it can see).",children:m=>i.jsx(Re,{...m,value:p,onChange:y=>g(y.target.value),placeholder:"ENG, OPS"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{linearClientId:o.trim(),...d.trim()?{linearClientSecret:d.trim()}:{},linearTeams:p.split(",").map(m=>m.trim()).filter(Boolean)}}).then(()=>{h(""),We({title:"Linear saved",variant:"success"})}).catch(Vn("Couldn't save Linear")),children:"Save"})]})]})}function yS({d:n}){const r=Xa(),[s,o]=k.useState(n.github.repos.join(", ")),[u,d]=k.useState(n.github.label),[h,p]=k.useState(n.github.people.join(", "));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"GitHub Issues"}),i.jsx(Tt,{children:"GitHub doesn't let apps be assignees, so an issue is handed over with a label. Whoever adds it must be listed under People and have write access. Uses this machine's GitHub login (the same as pull requests); replies are comments."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[i.jsx(Oe,{label:"Repositories",help:"owner/name, comma separated.",children:g=>i.jsx(Re,{...g,value:s,onChange:m=>o(m.target.value),placeholder:"acme/web, acme/api"})}),i.jsx(Oe,{label:"Label",children:g=>i.jsx(Re,{...g,value:u,onChange:m=>d(m.target.value)})}),i.jsx(Oe,{label:"People",help:"GitHub logins allowed to hand issues over and talk to the agent (they also need write access), comma separated. Add a work email to reach them in Slack when the agent has a question: ana <ana@acme.com>.",children:g=>i.jsx(Re,{...g,value:h,onChange:m=>p(m.target.value),placeholder:"ana <ana@acme.com>, bo"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{githubPeople:h.split(",").map(g=>g.trim()).filter(Boolean),githubRepos:s.split(",").map(g=>g.trim()).filter(Boolean),githubLabel:u.trim()}}).then(()=>We({title:"GitHub saved",variant:"success"})).catch(Vn("Couldn't save GitHub")),children:"Save"})]})]})}function vS({d:n}){const r=Xa(),s=n.jira.available?n.jira:null,[o,u]=k.useState((s==null?void 0:s.clientId)??""),[d,h]=k.useState(""),[p,g]=k.useState((s==null?void 0:s.siteInput)??""),[m,y]=k.useState(((s==null?void 0:s.projects)??[]).join(", ")),[w,x]=k.useState((s==null?void 0:s.label)??""),[j,_]=k.useState(((s==null?void 0:s.people)??[]).join(", "));return k.useEffect(()=>u((s==null?void 0:s.clientId)??""),[s==null?void 0:s.clientId]),s?i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Jira"}),i.jsx(Tt,{children:`The agent uses its own Jira user (e.g. "Jim"). People hand an issue over by assigning it to that user (or with the optional label); comments are the conversation. Create an OAuth 2.0 (3LO) app at developer.atlassian.com with the Jira scopes read:jira-work, write:jira-work and read:jira-user and this callback URL, then connect while signed in to Atlassian as the agent's user.`})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Site:"}),s.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:s.site}),s.account&&i.jsxs("span",{className:"text-muted-foreground",children:["as ",s.account]}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/tickets/jira/connection",method:"DELETE"}).catch(Vn("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!s.configured,onClick:()=>void Ee("/api/tickets/jira/connect",{method:"POST"}).then(E=>window.location.assign(E.url)).catch(Vn("Couldn't start the Jira sign-in")),children:"Connect Jira"}),!s.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the client below first."})]})]}),i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Callback URL (add it to the Atlassian app)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:s.redirectUri}),i.jsx(Js,{text:s.redirectUri})]})]}),i.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[i.jsx(Oe,{label:"Client ID",children:E=>i.jsx(Re,{...E,value:o,onChange:S=>u(S.target.value)})}),i.jsx(Oe,{label:"Secret",help:s.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:E=>i.jsx(Re,{...E,type:"password",autoComplete:"off",value:d,onChange:S=>h(S.target.value),placeholder:s.hasSecret?"••••••••":""})}),i.jsx(Oe,{label:"Site",help:"Only needed if the agent's account reaches several sites.",children:E=>i.jsx(Re,{...E,value:p,onChange:S=>g(S.target.value),placeholder:"https://acme.atlassian.net"})}),i.jsx(Oe,{label:"Projects",help:"Project keys, comma separated (empty: every project it can see).",children:E=>i.jsx(Re,{...E,value:m,onChange:S=>y(S.target.value),placeholder:"ENG, OPS"})}),i.jsx(Oe,{label:"Hand-over label (optional)",help:"Adding this label also hands an issue over.",children:E=>i.jsx(Re,{...E,value:w,onChange:S=>x(S.target.value),placeholder:"fda"})}),i.jsx(Oe,{label:"People without a visible email",help:"People are matched to Slack by email. When Jira hides someone's email, add their Jira account id here (a refused ticket shows it).",children:E=>i.jsx(Re,{...E,value:j,onChange:S=>_(S.target.value),placeholder:"712020:…"})})]}),i.jsx(oe,{disabled:r.isPending,onClick:()=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{jiraClientId:o.trim(),...d.trim()?{jiraClientSecret:d.trim()}:{},jiraSite:p.trim(),jiraProjects:m.split(",").map(E=>E.trim()).filter(Boolean),jiraLabel:w.trim(),jiraPeople:j.split(",").map(E=>E.trim()).filter(Boolean)}}).then(()=>{h(""),We({title:"Jira saved",variant:"success"})}).catch(Vn("Couldn't save Jira")),children:"Save"})]})]}):null}function xS({d:n}){const r=Xa(),[s,o]=k.useState(""),[u,d]=k.useState(null),h=n.bridge,p=(g,m=!1)=>Ee(`/api/tickets/bridge/${g}`,{method:"POST",body:{rotate:m}}).then(y=>{y.secret&&d(y.secret),r.mutateAsync({path:"/api/tickets",method:"PUT",body:{}}),We({title:"Webhook URL ready",variant:"success"})}).catch(Vn("Couldn't set up the webhook"));return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Instant updates (optional)"}),i.jsx(Tt,{children:"Without this, the agent checks Linear every 15 seconds and GitHub every minute. With it, the tracker's webhook goes to SuperClawd's bridge (this machine stays unreachable from the internet), which wakes the agent right away. No ticket data is stored there."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(Xi,{label:"Use the webhook bridge",help:"Polling keeps running either way (a missed webhook only delays).",checked:h.enabled,onChange:g=>void r.mutateAsync({path:"/api/tickets",method:"PUT",body:{bridge:g}}).catch(Vn("Couldn't change it"))}),i.jsxs("div",{className:"space-y-2 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Linear"}),i.jsx("p",{className:"text-muted-foreground",children:"In the Linear OAuth app: enable Webhooks, select Agent session events and Inbox notifications, paste the URL below, and copy Linear's signing secret here."}),i.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[i.jsx("div",{className:"min-w-64 flex-1",children:i.jsx(Oe,{label:"Linear webhook signing secret",children:g=>i.jsx(Re,{...g,type:"password",autoComplete:"off",value:s,onChange:m=>o(m.target.value),placeholder:h.linear.hasSecret?"••••••••":"lin_wh_…"})})}),i.jsx(oe,{variant:"outline",disabled:!s.trim()&&!h.linear.hasSecret,onClick:()=>void(s.trim()?r.mutateAsync({path:"/api/tickets",method:"PUT",body:{linearWebhookSecret:s.trim()}}):Promise.resolve()).then(()=>(o(""),p("linear"))),children:"Get the webhook URL"})]}),h.linear.hasSecret&&i.jsx("p",{className:"text-xs text-muted-foreground",children:"Secret saved."}),h.linear.url&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.linear.url}),i.jsx(Js,{text:h.linear.url})]})]}),i.jsxs("div",{className:"space-y-2 text-sm",children:[i.jsx("p",{className:"font-medium",children:"GitHub"}),i.jsx("p",{className:"text-muted-foreground",children:"In each repository: Settings → Webhooks → Add webhook. Payload URL and secret below, content type application/json, events: Issues and Issue comments."}),i.jsx(oe,{variant:"outline",onClick:()=>void p("github",h.github.hasSecret),children:h.github.url?"New secret + URL":"Get the webhook URL and secret"}),h.github.url&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.github.url}),i.jsx(Js,{text:h.github.url})]}),u&&i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{children:"Secret (shown once):"}),i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:u}),i.jsx(Js,{text:u})]})]})]})]})}function wS({d:n}){return i.jsxs(He,{children:[i.jsx(ot,{children:i.jsx(ut,{children:"Recent tickets"})}),i.jsx(Qe,{children:n.items.length?i.jsx("ul",{className:"divide-y rounded-md border",children:n.items.map(r=>{const s=fS[r.state]??{label:r.state,variant:"muted"};return i.jsxs("li",{className:"flex flex-wrap items-center gap-3 px-3 py-2 text-sm",children:[r.url?i.jsx("a",{href:r.url,target:"_blank",rel:"noreferrer noopener",className:"font-medium text-info underline",children:r.key}):i.jsx("span",{className:"font-medium",children:r.key}),i.jsx("span",{className:"min-w-0 flex-1 truncate",children:r.title}),i.jsx(tt,{variant:s.variant,children:s.label}),r.statusNote&&i.jsx("span",{className:"text-xs text-muted-foreground",children:r.statusNote}),r.prUrl&&i.jsx("a",{href:r.prUrl,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-info underline",children:"PR"}),i.jsx("span",{className:"text-xs text-muted-foreground",children:fl(r.costUsd)}),r.requestId&&i.jsx(Bt,{to:`/requests/${r.requestId}`,className:"text-xs text-info underline",children:"Request"}),i.jsxs("span",{className:"text-xs text-muted-foreground",children:[r.delegator?`${r.delegator} · `:"",Yt(r.updatedAt)]})]},r.id)})}):i.jsx(rn,{children:"No tickets yet."})})]})}function kS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/trackers/linear/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The install was cancelled.":"Linear didn't complete the install."});return}Ee("/api/tickets/linear/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,workspace:h.linear.workspace})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Linear is connected",n.workspace?i.jsxs(i.Fragment,{children:[" ","to ",i.jsx("code",{children:n.workspace})]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Linear"}),i.jsx(Bt,{to:"/tickets",className:"text-info underline",children:"Back to Tickets"})]})})})}function jS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/trackers/jira/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The sign-in was cancelled.":"Atlassian didn't complete the sign-in."});return}Ee("/api/tickets/jira/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,site:h.jira.site??null,account:h.jira.account??null})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Jira is connected",n.site?i.jsxs(i.Fragment,{children:[" ","to ",i.jsx("code",{children:n.site})]}):null,n.account?i.jsxs(i.Fragment,{children:[" as ",n.account]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Jira"}),i.jsx(Bt,{to:"/tickets",className:"text-info underline",children:"Back to Tickets"})]})})})}const bS=[{to:"agent",label:"Agent"},{to:"anthropic",label:"Anthropic"},{to:"general",label:"General"},{to:"slack",label:"Slack"},{to:"access",label:"Access"},{to:"calendar",label:"Calendar"},{to:"account",label:"Account"}];function SS(){return i.jsxs("div",{children:[i.jsx(ys,{title:"Settings",description:"Configure this FDA machine."}),i.jsxs("div",{className:"flex flex-col gap-6 md:flex-row",children:[i.jsx("nav",{"aria-label":"Settings",className:"flex shrink-0 gap-1 overflow-x-auto md:w-44 md:flex-col",children:bS.map(n=>i.jsx($d,{to:n.to,className:({isActive:r})=>Xe("rounded-md px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",r?"bg-accent font-medium":"text-muted-foreground hover:bg-accent/60 hover:text-foreground"),children:n.label},n.to))}),i.jsx("div",{className:"min-w-0 flex-1",children:i.jsx(Id,{})})]})]})}function CS(){var h,p,g;const n=Gj(),r=Yj(),[s,o]=k.useState(null),u=((p=(h=n.data)==null?void 0:h.selected)==null?void 0:p.id)??null,d=s??u;return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Primary agent"}),i.jsx(Tt,{children:"The SuperClawd agent FDA runs as. It brings its skills, guardrails and memories from your workspace."})]}),i.jsxs(Qe,{className:"space-y-4",children:[((g=n.data)==null?void 0:g.selected)&&i.jsxs("p",{className:"text-sm",children:["Current:"," ",i.jsx("span",{className:"font-medium",children:n.data.selected.name})]}),n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):i.jsxs(i.Fragment,{children:[n.data.error&&i.jsx(Ot,{error:new Error(`Could not load agents from SuperClawd: ${n.data.error}`),onRetry:()=>void n.refetch()}),n.data.items.length===0&&!n.data.error?i.jsx(rn,{children:"No enabled Primary agents in this workspace. Create one in the SuperClawd app, then come back."}):i.jsx("div",{role:"radiogroup","aria-label":"Primary agent",className:"space-y-2",children:n.data.items.map(m=>{const y=d===m.id;return i.jsxs("button",{type:"button",role:"radio","aria-checked":y,onClick:()=>o(m.id),className:Xe("flex w-full items-start gap-3 rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",y?"border-primary bg-accent":"hover:bg-accent/50"),children:[i.jsx("span",{className:Xe("mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border",y&&"border-primary bg-primary text-primary-foreground"),children:y&&i.jsx(Mg,{className:"h-3 w-3","aria-hidden":!0})}),i.jsxs("span",{className:"min-w-0 flex-1",children:[i.jsxs("span",{className:"flex flex-wrap items-center gap-2",children:[i.jsx("span",{className:"font-medium",children:m.name}),i.jsx("code",{className:"text-xs text-muted-foreground",children:m.slug}),m.model&&i.jsx(tt,{variant:"outline",children:NS(m.model)}),m.id===u&&i.jsx(tt,{variant:"success",children:"Current"})]}),m.description&&i.jsx("span",{className:"mt-1 block text-sm text-muted-foreground",children:m.description})]})]},m.id)})}),i.jsx(oe,{disabled:!d||d===u||r.isPending,onClick:()=>d&&r.mutate(d,{onSuccess:()=>{o(null),We({title:"Agent saved",variant:"success"})}}),children:r.isPending?"Saving":"Save"})]})]})]})}function NS(n){if(n==="default")return"Session model";const r=/^claude-(opus|fable|sonnet|haiku)-latest$/.exec(n);return r?`Claude ${r[1][0].toUpperCase()}${r[1].slice(1)} (latest)`:n}function jd({label:n,value:r}){return i.jsxs("div",{className:"flex items-center justify-between gap-4 rounded-md border px-3 py-2 text-sm",children:[i.jsx("span",{className:"text-muted-foreground",children:n}),r?i.jsx("code",{className:"text-xs",children:r}):i.jsx(tt,{variant:"warning",children:"Not set"})]})}function vy({result:n,error:r}){if(r)return i.jsxs("span",{role:"status",className:"flex items-center gap-1.5 text-sm text-red-300",children:[i.jsx(md,{className:"h-4 w-4","aria-hidden":!0}),yt(r)]});if(!n)return null;const s=[n.botName&&`bot ${n.botName}`,n.teamId&&`team ${n.teamId}`].filter(Boolean).join(", "),o=n.message??(n.ok?"Works.":"Failed.");return i.jsxs("span",{role:"status",className:`flex items-center gap-1.5 text-sm ${n.ok?"text-green-300":"text-red-300"}`,children:[n.ok?i.jsx(Tk,{className:"h-4 w-4","aria-hidden":!0}):i.jsx(md,{className:"h-4 w-4","aria-hidden":!0}),o,s&&i.jsxs("span",{className:"text-muted-foreground",children:["(",s,")"]})]})}function ES(){const n=Jo(),r=Jj(),s=Xj(),[o,u]=k.useState("");if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const d=h=>{h.preventDefault(),r.mutate(o.trim(),{onSuccess:()=>{u(""),s.reset(),We({title:"API key saved",variant:"success"})}})};return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Anthropic API key"}),i.jsx(Tt,{children:"FDA runs Claude Code with this key. It is stored encrypted on this machine and never shown again."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsx(jd,{label:"Current key",value:n.data.secrets.anthropicApiKey}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{variant:"outline",disabled:s.isPending||!n.data.secrets.anthropicApiKey,onClick:()=>s.mutate(),children:s.isPending?"Testing":"Test key"}),i.jsx(vy,{result:s.data,error:s.error})]}),i.jsxs("form",{onSubmit:d,className:"max-w-md space-y-3",autoComplete:"off",children:[i.jsx(Oe,{label:n.data.secrets.anthropicApiKey?"Replace key":"Set key",help:"Starts with sk-ant-.",error:r.error?yt(r.error):null,children:h=>i.jsx(Re,{...h,type:"password",autoComplete:"off",spellCheck:!1,value:o,onChange:p=>u(p.target.value),placeholder:"sk-ant-..."})}),i.jsx(oe,{type:"submit",disabled:!o.trim()||r.isPending,children:r.isPending?"Saving":"Save key"})]})]})]})}function RS({open:n,initialPath:r,onClose:s,onSelect:o}){return i.jsx(Kd,{open:n,onClose:s,title:"Choose a folder",description:"Folders under your home directory. Repositories are marked.",className:"max-w-xl",children:n&&i.jsx(PS,{initialPath:r??"",onSelect:o,onCancel:s})})}function PS({initialPath:n,onSelect:r,onCancel:s}){var p,g,m,y;const[o,u]=k.useState(n),d=lb(o),h=((p=d.data)==null?void 0:p.path)??o;return i.jsxs("div",{className:"space-y-3",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx(oe,{variant:"outline",size:"icon","aria-label":"Parent folder",disabled:!((g=d.data)!=null&&g.parent),onClick:()=>{var w;return((w=d.data)==null?void 0:w.parent)&&u(d.data.parent)},children:i.jsx(wk,{})}),i.jsx("code",{className:"min-w-0 flex-1 truncate rounded bg-muted px-2 py-1.5 text-xs",title:h,children:h||"Home"})]}),d.isLoading?i.jsx(kt,{}):d.isError?i.jsx(Ot,{error:d.error,onRetry:()=>u(n===o?"":n)}):i.jsxs("ul",{className:Xe("max-h-72 overflow-y-auto rounded-md border",d.isFetching&&"opacity-60"),"aria-label":"Folders",children:[((m=d.data)==null?void 0:m.dirs.length)===0&&i.jsx("li",{className:"p-3 text-sm text-muted-foreground",children:"No folders here."}),(y=d.data)==null?void 0:y.dirs.map(w=>i.jsx("li",{children:i.jsxs("button",{type:"button",onClick:()=>u(w.path),className:"flex w-full items-center gap-2 border-b px-3 py-2 text-left text-sm last:border-b-0 hover:bg-accent focus-visible:bg-accent focus-visible:outline-none",children:[w.isRepo?i.jsx(Qk,{className:"h-4 w-4 text-success","aria-hidden":!0}):i.jsx(Bk,{className:"h-4 w-4 text-muted-foreground","aria-hidden":!0}),i.jsx("span",{className:"truncate",children:w.name}),w.isRepo&&i.jsx("span",{className:"ml-auto text-xs text-muted-foreground",children:"repository"})]})},w.path))]}),i.jsxs("div",{className:"flex justify-end gap-2 pt-1",children:[i.jsx(oe,{variant:"outline",onClick:s,children:"Cancel"}),i.jsx(oe,{disabled:!d.data,onClick:()=>d.data&&r(d.data.path),children:"Use this folder"})]})]})}const bd=[{title:"Workspace",description:"Where FDA works on this machine and who people should contact.",fields:[{key:"workdir",label:"Work directory",help:"Repositories FDA works on live here. Must be inside your home directory.",kind:"folder"},{key:"operatorContact",label:"Operator contact",help:"Shown to Slack users when FDA cannot help, for example a Slack handle or email.",kind:"text",nullable:!0,placeholder:"@alex"}]},{title:"Agent behavior",description:"How the coding agent runs each turn.",fields:[{key:"effort",label:"Reasoning effort",help:"Higher effort is slower and costs more.",kind:"select",nullable:!0,options:[{value:"",label:"Default"},{value:"low",label:"Low"},{value:"medium",label:"Medium"},{value:"high",label:"High"},{value:"xhigh",label:"Extra high"},{value:"max",label:"Max"}]},{key:"permissionMode",label:"Permission mode",help:"Bypass lets the agent run any tool without asking. Auto applies Claude Code's automatic permission checks.",kind:"select",options:[{value:"bypass",label:"Bypass"},{value:"auto",label:"Auto"}]},{key:"planPolicy",label:"Plan first",help:"Whether the agent proposes a plan for approval in Slack before making changes.",kind:"select",options:[{value:"auto",label:"When the task needs it"},{value:"always",label:"Always"},{value:"never",label:"Never"}]},{key:"browserEnabled",label:"Browser",help:"Let the agent use a headless browser for checks and screenshots.",kind:"bool"},{key:"superclawdMemory",label:"SuperClawd memory",help:"Team, repo, agent and private memories from SuperClawd. Off: none is loaded or captured, and the agent uses Claude Code's own memory instead (kept per repository on this machine).",kind:"bool"},{key:"captureMemories",label:"Capture memories",help:"Save learnings to your SuperClawd workspace memories after turns.",kind:"bool"},{key:"allowClaudeaiConnectors",label:"Claude.ai connectors",help:"Allow MCP connectors configured in the Claude.ai account.",kind:"bool"}]},{title:"Turn limits",description:"Guards against runaway turns.",fields:[{key:"debounceMs",label:"Message debounce (ms)",help:"Wait this long after the last Slack message before starting a turn, so quick follow-ups are batched.",kind:"number",min:0,step:100,integer:!0},{key:"turnTimeoutMin",label:"Turn timeout (minutes)",help:"Stop a turn that runs longer than this.",kind:"number",min:1,integer:!0},{key:"turnMaxBudgetUsd",label:"Max cost per turn (USD)",help:"Leave empty for no limit.",kind:"number",nullable:!0,min:0,step:.5},{key:"turnMaxTurns",label:"Max agent steps per turn",help:"Leave empty for no limit.",kind:"number",nullable:!0,min:1,integer:!0}]},{title:"Pull requests",description:"After FDA opens a pull request it keeps an eye on it (through the machine's gh login) and works on it again in the same thread.",fields:[{key:"prMonitorEnabled",label:"Follow pull requests",help:"Check the pull requests FDA opened. Say `stop following` in a thread to stop for that request.",kind:"bool"},{key:"prMonitorFixCi",label:"Fix failing CI",help:"Once per failing commit, up to the attempt limit below.",kind:"bool"},{key:"prMonitorReviews",label:"Address review feedback",help:"Only from people with write access to the repository; other comments are ignored.",kind:"bool"},{key:"prMonitorConflicts",label:"Resolve merge conflicts",help:"Merges the base branch into the pull request branch.",kind:"bool"},{key:"prMonitorIntervalSec",label:"Check every (seconds)",help:"Checks slow down when nothing is happening.",kind:"number",min:30,integer:!0},{key:"prMonitorQuietSec",label:"Wait after the last comment (seconds)",help:"Lets a reviewer finish before FDA starts.",kind:"number",min:0,integer:!0},{key:"prMonitorMaxCiAttempts",label:"CI fix attempts",help:"Then FDA leaves it for a human and says so in the thread.",kind:"number",min:1,integer:!0},{key:"prMonitorMaxPerDay",label:"Follow-ups per pull request per day",help:"A safety cap on automatic work.",kind:"number",min:1,integer:!0},{key:"prMonitorMaxAgeDays",label:"Stop after idle (days)",help:"Stop following a pull request with no activity for this long.",kind:"number",min:1,integer:!0}]},{title:"Slack context",description:"What FDA reads from the thread.",fields:[{key:"threadContextMessages",label:"Earlier thread messages",help:"How many earlier messages in the thread to include as context.",kind:"number",min:0,integer:!0},{key:"includeUnlistedContext",label:"Include messages from people not on the allowlist",help:"They are passed as untrusted context only, never as instructions.",kind:"bool"},{key:"stopButton",label:"Stop button",help:"Show a Stop button on the agent's live line while it works (same as typing `stop`; only the requester or allowed people can use it).",kind:"bool"},{key:"allowDirectMessages",label:"Direct messages",help:"People on the allowlist can DM the agent; each DM is a private request (the team doesn't see it). Turn off to accept requests only in channels.",kind:"bool"}]},{title:"Sessions and cleanup",description:"Housekeeping on this machine.",fields:[{key:"sessionMaxAgeH",label:"Session max age (hours)",help:"Start a fresh agent session for a thread after this long.",kind:"number",min:1,integer:!0},{key:"worktreeRetentionDays",label:"Keep worktrees (days)",help:"Delete finished request worktrees after this many days.",kind:"number",min:0,integer:!0},{key:"diskMinFreeGb",label:"Minimum free disk (GB)",help:"Pause new work when free disk drops below this.",kind:"number",min:0,step:.5},{key:"autoRequeueOnRestart",label:"Requeue after restart",help:"Requeue requests that were running when the daemon stopped.",kind:"bool"}]},{title:"Admin panel",description:"How this panel is reached.",fields:[{key:"adminPublicUrl",label:"Admin URL",help:"The address you use to open this panel. Used in Slack links.",kind:"text",nullable:!0,placeholder:"https://fda.example.ts.net"},{key:"publicHostname",label:"Public hostname",help:"Extra hostname this panel accepts, for example a Tailscale name.",kind:"text",nullable:!0,placeholder:"fda.example.ts.net"}]},{title:"Privacy",description:"What is shared with SuperClawd.",fields:[{key:"shareTitleWithCloud",label:"Share request titles",help:"Send request titles to SuperClawd for usage reporting. Off sends counts only.",kind:"bool"}]}];function Tm(n){const r={};for(const s of bd)for(const o of s.fields){const u=n[o.key];r[o.key]=typeof u=="boolean"?u:u===null?"":String(u)}return r}function TS(n,r){if(n.kind==="bool")return{value:r};const s=String(r).trim();if(n.kind==="number"){if(s==="")return n.nullable?{value:null}:{error:"Required."};const o=Number(s);return Number.isFinite(o)?n.integer&&!Number.isInteger(o)?{error:"Enter a whole number."}:n.min!==void 0&&o<n.min?{error:`Must be at least ${n.min}.`}:{value:o}:{error:"Enter a number."}}return s===""?"nullable"in n&&n.nullable?{value:null}:n.kind==="folder"?{value:null}:{error:"Required."}:{value:s}}function LS(){const n=Jo();return n.isLoading?i.jsx(kt,{}):n.isError||!n.data?i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()}):i.jsx(MS,{settings:n.data.settings})}function MS({settings:n}){const[r]=k.useState(()=>Tm(n)),[s,o]=k.useState(r),[u,d]=k.useState(r),[h,p]=k.useState({}),[g,m]=k.useState(!1),y=Vd(),w=Object.keys(s).filter(E=>s[E]!==u[E]),x=(E,S)=>{o(P=>({...P,[E]:S})),p(P=>({...P,[E]:void 0}))},j=E=>{E.preventDefault();const S={},P={};for(const D of bd)for(const U of D.fields){if(!w.includes(U.key))continue;const Q=TS(U,s[U.key]);Q.error?P[U.key]=Q.error:S[U.key]=Q.value}p(P),!Object.keys(P).length&&y.mutate(S,{onSuccess:({settings:D})=>{const U=Tm(D);o(U),d(U),We({title:"Settings saved",variant:"success"})},onError:D=>{D instanceof Wn&&D.field&&p({[D.field]:D.message})}})},_=y.error instanceof Wn&&y.error.field?null:y.error?yt(y.error):null;return i.jsxs("form",{onSubmit:j,className:"space-y-6",noValidate:!0,children:[bd.map(E=>i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:E.title}),i.jsx(Tt,{children:E.description})]}),i.jsx(Qe,{className:"grid gap-5 sm:grid-cols-2",children:E.fields.map(S=>i.jsx("div",{className:S.kind==="folder"||S.kind==="bool"?"sm:col-span-2":void 0,children:i.jsx(Oe,{label:S.label,help:S.help,error:h[S.key],children:P=>{const D=s[S.key];switch(S.kind){case"bool":return i.jsx(ps,{...P,checked:D,onCheckedChange:U=>x(S.key,U)});case"select":return i.jsx(eu,{...P,value:D,onChange:U=>x(S.key,U.target.value),children:S.options.map(U=>i.jsx("option",{value:U.value,children:U.label},U.value))});case"number":return i.jsx(Re,{...P,type:"number",inputMode:"decimal",min:S.min,step:S.step??1,value:D,onChange:U=>x(S.key,U.target.value)});case"folder":return i.jsxs("div",{className:"flex gap-2",children:[i.jsx(Re,{...P,value:D,onChange:U=>x(S.key,U.target.value),placeholder:"/home/you/work",spellCheck:!1}),i.jsxs(oe,{variant:"outline",onClick:()=>m(!0),children:[i.jsx($k,{}),"Browse"]})]});default:return i.jsx(Re,{...P,value:D,onChange:U=>x(S.key,U.target.value),placeholder:S.placeholder,spellCheck:!1})}}})},S.key))})]},E.title)),i.jsxs("div",{className:"sticky bottom-0 flex items-center gap-3 border-t bg-background/95 py-4 backdrop-blur",children:[i.jsx(oe,{type:"submit",disabled:w.length===0||y.isPending,children:y.isPending?"Saving":"Save changes"}),i.jsx(oe,{variant:"ghost",disabled:w.length===0,onClick:()=>{o(u),p({})},children:"Discard"}),w.length>0&&i.jsx("span",{className:"text-sm text-muted-foreground",children:w.length===1?"1 unsaved change":`${w.length} unsaved changes`}),i.jsx(Go,{message:_})]}),i.jsx(RS,{open:g,initialPath:s.workdir||null,onClose:()=>m(!1),onSelect:E=>{x("workdir",E),m(!1)}})]})}function _S(){const n=Jo();if(n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const{secrets:r,settings:s}=n.data;return i.jsxs("div",{className:"space-y-6",children:[i.jsx(AS,{botToken:r.slackBotToken,appToken:r.slackAppToken,botUserId:s.slackBotUserId,teamId:s.slackTeamId}),i.jsx(DS,{defaultName:s.slackBotName??"FDA"})]})}function AS({botToken:n,appToken:r,botUserId:s,teamId:o}){const u=Zj(),d=eb(),[h,p]=k.useState(""),[g,m]=k.useState(""),y=w=>{w.preventDefault();const x={};h.trim()&&(x.botToken=h.trim()),g.trim()&&(x.appToken=g.trim()),u.mutate(x,{onSuccess:()=>{p(""),m(""),d.reset(),We({title:"Slack tokens saved. Reconnecting.",variant:"success"})}})};return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Slack connection"}),i.jsx(Tt,{children:"FDA connects to Slack over Socket Mode with a bot token and an app-level token."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx(jd,{label:"Bot token",value:n}),i.jsx(jd,{label:"App token",value:r}),(s||o)&&i.jsxs("p",{className:"text-xs text-muted-foreground",children:[s&&i.jsxs(i.Fragment,{children:["Bot user ",s,". "]}),o&&i.jsxs(i.Fragment,{children:["Team ",o,"."]})]})]}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{variant:"outline",disabled:d.isPending||!n,onClick:()=>d.mutate(),children:d.isPending?"Testing":"Test connection"}),i.jsx(vy,{result:d.data,error:d.error})]}),i.jsxs("form",{onSubmit:y,className:"max-w-md space-y-4",autoComplete:"off",children:[i.jsx(Oe,{label:"New bot token",help:"Starts with xoxb-. Leave empty to keep the current one.",children:w=>i.jsx(Re,{...w,type:"password",autoComplete:"off",spellCheck:!1,value:h,onChange:x=>p(x.target.value),placeholder:"xoxb-..."})}),i.jsx(Oe,{label:"New app token",help:"Starts with xapp-. Needs the connections:write scope.",children:w=>i.jsx(Re,{...w,type:"password",autoComplete:"off",spellCheck:!1,value:g,onChange:x=>m(x.target.value),placeholder:"xapp-..."})}),i.jsx(Go,{message:u.error?yt(u.error):null}),i.jsx(oe,{type:"submit",disabled:!h.trim()&&!g.trim()||u.isPending,children:u.isPending?"Saving":"Save tokens"})]})]})]})}function DS({defaultName:n}){const[r,s]=k.useState(n),[o,u]=k.useState(n);k.useEffect(()=>{const p=setTimeout(()=>u(r.trim()||n),300);return()=>clearTimeout(p)},[r,n]);const d=tb(o),h=d.data?JSON.stringify(d.data.manifest,null,2):"";return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Slack app manifest"}),i.jsx(Tt,{children:"Create the Slack app from this manifest at api.slack.com/apps, then install it and paste the tokens above."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsx("div",{className:"max-w-xs",children:i.jsx(Oe,{label:"Bot name",help:"The name people mention in Slack.",children:p=>i.jsx(Re,{...p,value:r,onChange:g=>s(g.target.value),maxLength:35})})}),d.isLoading?i.jsx(kt,{}):d.isError?i.jsx(Ot,{error:d.error,onRetry:()=>void d.refetch()}):i.jsxs("div",{className:"space-y-2",children:[i.jsx("div",{className:"flex justify-end",children:i.jsx(Js,{text:h,label:"Copy manifest"})}),i.jsx("pre",{className:"max-h-96 overflow-auto rounded-md border bg-muted/40 p-3 font-mono text-xs","aria-label":"Manifest JSON",tabIndex:0,children:h})]})]})]})}const Sd={channel:"Channel",user:"User",usergroup:"User group"},OS={channel:Yk,user:I1,usergroup:U1},Oo=(n,r)=>n.kind===r.kind&&n.slackId===r.slackId;function FS(){var u,d,h,p,g;const n=nb(),r=Jo();if(n.isLoading||r.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const s=!!((u=r.data)!=null&&u.settings.allowAnyChannel),o=!!((d=r.data)!=null&&d.settings.allowAnyone);return i.jsxs("div",{className:"space-y-6",children:[i.jsx(zS,{anyChannel:s,anyone:o}),i.jsx(IS,{targets:((h=r.data)==null?void 0:h.settings.handoffTargets)??[],sources:((p=r.data)==null?void 0:p.settings.handoffSources)??[],budget:((g=r.data)==null?void 0:g.settings.handoffMaxBudgetUsd)??5}),i.jsx(US,{initial:n.data,anyChannel:s,anyone:o})]})}function IS({targets:n,sources:r,budget:s}){const o=Vd(),[u,d]=k.useState({botUserId:"",name:"",role:""}),[h,p]=k.useState(""),[g,m]=k.useState(String(s));k.useEffect(()=>m(String(s)),[s]);const y=(x,j)=>o.mutate(x,{onSuccess:()=>We({title:j,variant:"success"}),onError:_=>We({title:"Couldn't save",description:yt(_),variant:"error"})}),w=x=>/^[UW][A-Z0-9]{5,}$/.test(x.trim());return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Agent hand-offs"}),i.jsx(Tt,{children:"Optional. Let this agent hand part of a request to another agent (for example a product manager agent tasking a developer agent). The person who asked approves each hand-off with ✅ in the thread, and the receiving agent must list this one below too. A hand-off can't be passed on again."})]}),i.jsxs(Qe,{className:"space-y-6",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx("p",{className:"text-sm font-medium",children:"Agents this agent can hand work to"}),n.length===0?i.jsx("p",{className:"text-xs text-muted-foreground",children:"None (hand-offs off)."}):i.jsx("ul",{className:"divide-y rounded-md border",children:n.map(x=>i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx("span",{className:"font-medium",children:x.name}),i.jsx("code",{className:"text-xs text-muted-foreground",children:x.botUserId}),i.jsx("span",{className:"flex-1 truncate text-muted-foreground",children:x.role}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":`Remove ${x.name}`,onClick:()=>y({handoffTargets:n.filter(j=>j.botUserId!==x.botUserId)},"Removed"),children:i.jsx(qo,{})})]},x.botUserId))}),i.jsxs("div",{className:"grid gap-2 sm:grid-cols-[1fr_1fr_2fr_auto]",children:[i.jsx(Re,{placeholder:"Slack bot user id (U…)","aria-label":"Bot user id",value:u.botUserId,onChange:x=>d({...u,botUserId:x.target.value.trim()})}),i.jsx(Re,{placeholder:"Name (e.g. John)","aria-label":"Name",value:u.name,onChange:x=>d({...u,name:x.target.value})}),i.jsx(Re,{placeholder:"Role (e.g. backend developer)","aria-label":"Role",value:u.role,onChange:x=>d({...u,role:x.target.value})}),i.jsxs(oe,{disabled:!w(u.botUserId)||!u.name.trim()||o.isPending,onClick:()=>{y({handoffTargets:[...n.filter(x=>x.botUserId!==u.botUserId),{botUserId:u.botUserId,name:u.name.trim(),role:u.role.trim()}]},"Added"),d({botUserId:"",name:"",role:""})},children:[i.jsx(gd,{})," Add"]})]})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsx("p",{className:"text-sm font-medium",children:"Agents allowed to hand work to this agent"}),r.length===0?i.jsx("p",{className:"text-xs text-muted-foreground",children:"None (no hand-offs accepted)."}):i.jsx("ul",{className:"divide-y rounded-md border",children:r.map(x=>i.jsxs("li",{className:"flex items-center gap-3 p-3 text-sm",children:[i.jsx("code",{className:"flex-1 text-xs",children:x}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":`Remove ${x}`,onClick:()=>y({handoffSources:r.filter(j=>j!==x)},"Removed"),children:i.jsx(qo,{})})]},x))}),i.jsxs("div",{className:"flex gap-2",children:[i.jsx(Re,{placeholder:"Slack bot user id (U…)","aria-label":"Allowed agent's bot user id",value:h,onChange:x=>p(x.target.value.trim())}),i.jsxs(oe,{disabled:!w(h)||o.isPending,onClick:()=>{y({handoffSources:[...new Set([...r,h])]},"Added"),p("")},children:[i.jsx(gd,{})," Add"]})]})]}),i.jsxs("div",{className:"flex items-end gap-2",children:[i.jsxs("div",{className:"space-y-1",children:[i.jsx("p",{className:"text-sm font-medium",children:"Cost cap per turn for handed-off work (USD)"}),i.jsx(Re,{type:"number",min:.5,step:.5,"aria-label":"Cost cap per turn for handed-off work",value:g,onChange:x=>m(x.target.value)})]}),i.jsx(oe,{variant:"outline",disabled:o.isPending||Number(g)===s,onClick:()=>y({handoffMaxBudgetUsd:Number(g)},"Saved"),children:"Save"})]})]})]})}function zS({anyChannel:n,anyone:r}){const s=Vd(),o=(d,h)=>s.mutate({[d]:h},{onError:p=>We({title:"Couldn't change access",description:yt(p),variant:"error"})}),u=(d,h,p,g)=>i.jsxs("div",{className:"flex items-start justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"text-sm font-medium",children:p}),i.jsx("p",{className:"text-xs text-muted-foreground",children:g})]}),i.jsx(ps,{checked:h,disabled:s.isPending,"aria-label":p,onCheckedChange:m=>o(d,m)})]});return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Open access"}),i.jsx(Tt,{children:"Optional. Anyone who can reach the agent can make it run code and spend money on this machine, so these are off by default."})]}),i.jsxs(Qe,{className:"space-y-4",children:[u("allowAnyChannel",n,"Any channel the agent is in","Inviting the agent to a channel is enough; the channel list below isn't used. Shared (Slack Connect) channels are still refused."),u("allowAnyone",r,"Anyone in this workspace","Every member can use the agent; the people list below isn't used. External users, guest accounts and deactivated accounts are still refused (unless listed below).")]})]})}function US({initial:n,anyChannel:r,anyone:s}){const[o,u]=k.useState(n),[d,h]=k.useState(n),p=rb(),g=JSON.stringify(o)!==JSON.stringify(d),m=x=>u(j=>j.some(_=>Oo(_,x))?j:[...j,x]),y=x=>u(j=>j.filter(_=>!Oo(_,x))),w=(x,j)=>u(_=>_.map(E=>Oo(E,x)?{...E,label:j||null}:E));return i.jsxs("div",{className:"space-y-6",children:[i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Who can use FDA"}),i.jsxs(Tt,{children:["FDA only acts on mentions in allowed channels from allowed people. A user is allowed when they are listed directly or belong to a listed user group.",r&&" Any channel is on: channels listed here aren't needed.",s&&" Anyone in the workspace is on: people and groups listed here are only needed for guests."]})]}),i.jsxs(Qe,{className:"space-y-4",children:[o.length===0?i.jsx(rn,{children:r&&s?"Not needed while both open-access switches are on.":r?"Add at least one user or group (or turn on Anyone in this workspace).":s?"Add at least one channel (or turn on Any channel the agent is in).":"Nobody is allowed yet. Add at least one channel and one user or group."}):i.jsx("ul",{className:"divide-y rounded-md border",children:o.map(x=>{const j=OS[x.kind];return i.jsxs("li",{className:"flex items-center gap-3 p-3",children:[i.jsx(j,{className:"h-4 w-4 shrink-0 text-muted-foreground","aria-hidden":!0}),i.jsx(tt,{variant:"outline",className:"shrink-0",children:Sd[x.kind]}),i.jsx("code",{className:"shrink-0 text-xs text-muted-foreground",children:x.slackId}),i.jsx(Re,{"aria-label":`Label for ${Sd[x.kind].toLowerCase()} ${x.slackId}`,placeholder:"Label",className:"h-8",value:x.label??"",onChange:_=>w(x,_.target.value)}),i.jsx(oe,{variant:"ghost",size:"icon",className:"h-8 w-8 shrink-0","aria-label":`Remove ${x.label??x.slackId}`,onClick:()=>y(x),children:i.jsx(qo,{})})]},`${x.kind}:${x.slackId}`)})}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx(oe,{disabled:!g||p.isPending,onClick:()=>p.mutate(o,{onSuccess:({entries:x})=>{u(x),h(x),We({title:"Access list saved",variant:"success"})}}),children:p.isPending?"Saving":"Save access list"}),i.jsx(oe,{variant:"ghost",disabled:!g,onClick:()=>u(d),children:"Discard"}),g&&i.jsx("span",{className:"text-sm text-muted-foreground",children:"Unsaved changes"})]})]})]}),i.jsx(qS,{entries:o,onAdd:m})]})}function $S(n,r=300){const[s,o]=k.useState(n);return k.useEffect(()=>{const u=setTimeout(()=>o(n),r);return()=>clearTimeout(u)},[n,r]),s}function qS({entries:n,onAdd:r}){const[s,o]=k.useState("channel"),[u,d]=k.useState(""),h=$S(u.trim()),p=sb(h,s==="channel"),g=ab(h,s==="user"),m=ib(s==="usergroup"),y=s==="channel"?p:s==="user"?g:m;let w=[];if(s==="channel"&&p.data)w=p.data.map(x=>({id:x.id,primary:`#${x.name}`,secondary:x.isMember?void 0:"Bot is not a member yet",label:`#${x.name}`,icon:x.isPrivate?i.jsx(o1,{className:"h-3 w-3","aria-label":"Private"}):void 0}));else if(s==="user"&&g.data)w=g.data.map(x=>({id:x.id,primary:x.realName||x.name,secondary:`@${x.name}`,label:x.realName||x.name}));else if(s==="usergroup"&&m.data){const x=h.toLowerCase();w=m.data.filter(j=>!x||j.handle.toLowerCase().includes(x)||j.name.toLowerCase().includes(x)).map(j=>({id:j.id,primary:j.name,secondary:`@${j.handle}`,label:`@${j.handle}`}))}return i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Add to the list"}),i.jsx(Tt,{children:"Search what the bot can see in your Slack workspace. Remember to save."})]}),i.jsxs(Qe,{children:[i.jsx(hy,{idPrefix:"access",label:"Entry type",value:s,onChange:x=>{o(x),d("")},items:[{value:"channel",label:"Channels"},{value:"user",label:"Users"},{value:"usergroup",label:"User groups"}]}),i.jsxs(py,{idPrefix:"access",value:s,className:"space-y-3",children:[i.jsx(Re,{type:"search","aria-label":`Search ${Sd[s].toLowerCase()}s`,placeholder:"Search",value:u,onChange:x=>d(x.target.value)}),y.isLoading?i.jsx(kt,{}):y.isError?i.jsx(Ot,{error:y.error,onRetry:()=>void y.refetch()}):w.length===0?i.jsx("p",{className:"p-2 text-sm text-muted-foreground",children:"No matches."}):i.jsx("ul",{className:Xe("max-h-72 overflow-y-auto rounded-md border",y.isFetching&&"opacity-60"),children:w.map(x=>{const j=n.some(_=>Oo(_,{kind:s,slackId:x.id}));return i.jsxs("li",{className:"flex items-center gap-3 border-b px-3 py-2 text-sm last:border-b-0",children:[i.jsxs("div",{className:"min-w-0 flex-1",children:[i.jsxs("p",{className:"flex items-center gap-1.5 truncate",children:[x.primary,x.icon]}),x.secondary&&i.jsx("p",{className:"truncate text-xs text-muted-foreground",children:x.secondary})]}),i.jsx(oe,{size:"xs",variant:"outline",disabled:j,"aria-label":j?`${x.primary} already added`:`Add ${x.primary}`,onClick:()=>r({kind:s,slackId:x.id,label:x.label}),children:j?"Added":i.jsxs(i.Fragment,{children:[i.jsx(gd,{}),"Add"]})})]},x.id)})})]})]})]})}function BS(){const n=Yo();return n.data?i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Account"}),i.jsx(Tt,{children:"Change your password or username. Your other sessions will be signed out."})]}),i.jsx(Qe,{children:i.jsx(oy,{currentUsername:n.data.username,onDone:()=>We({title:"Account updated",variant:"success"})})})]}):i.jsx(kt,{})}const xy=["calendar"];function HS(){return Rt({queryKey:xy,queryFn:()=>Ee("/api/calendar")})}function QS(){const n=Ct();return Ft({mutationFn:r=>Ee(r.path,{method:r.method??"POST",body:r.body}),onSuccess:r=>{r&&"redirectUri"in r&&n.setQueryData(xy,r)}})}function VS(){var y,w;const n=HS(),r=QS(),[s,o]=k.useState(""),[u,d]=k.useState("");if(k.useEffect(()=>{n.data&&o(n.data.clientId??"")},[(y=n.data)==null?void 0:y.clientId]),n.isLoading)return i.jsx(kt,{});if(n.isError||!n.data)return i.jsx(Ot,{error:n.error,onRetry:()=>void n.refetch()});const h=n.data,p=x=>j=>We({title:x,description:yt(j),variant:"error"}),g=()=>r.mutateAsync({path:"/api/calendar",method:"PUT",body:{clientId:s.trim(),...u.trim()?{clientSecret:u.trim()}:{}}}).then(()=>{d(""),We({title:"Google client saved",variant:"success"})}).catch(p("Couldn't save the Google client")),m=()=>Ee("/api/calendar/connect",{method:"POST"}).then(x=>window.location.assign(x.url)).catch(p("Couldn't start the Google sign-in"));return i.jsxs("div",{className:"space-y-4",children:[i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Calendar"}),i.jsx(Tt,{children:"The agent books meetings on its own Google calendar, around the attendees' availability (Google Calendar). Connect the Google account the agent should use (ideally its own account, e.g. jane@yourcompany.com). The sign-in stays encrypted on this machine; tasks never see Google's tokens."})]}),i.jsxs(Qe,{className:"space-y-5",children:[i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsx("p",{className:"font-medium",children:"Calendar for tasks"}),i.jsx("p",{className:"text-sm text-muted-foreground",children:"Off: tasks don't get the calendar tools."})]}),i.jsx(ps,{checked:h.enabled,onCheckedChange:x=>void r.mutateAsync({path:"/api/calendar",method:"PUT",body:{enabled:x}}).catch(p("Couldn't change it")),"aria-label":"Calendar for tasks"})]}),i.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[i.jsx("span",{className:"font-medium",children:"Google account:"}),h.connected?i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"success",children:"Connected"}),i.jsx("code",{children:h.account}),i.jsx(oe,{size:"sm",variant:"outline",onClick:()=>void r.mutateAsync({path:"/api/calendar/connection",method:"DELETE"}).catch(p("Couldn't disconnect")),children:"Disconnect"})]}):i.jsxs(i.Fragment,{children:[i.jsx(tt,{variant:"muted",children:"Not connected"}),i.jsx(oe,{size:"sm",disabled:!h.configured,onClick:()=>void m(),children:"Connect Google"}),!h.configured&&i.jsx("span",{className:"text-muted-foreground",children:"Save the Google client below first."})]})]}),i.jsxs("div",{className:"flex items-center justify-between gap-4",children:[i.jsxs("div",{children:[i.jsxs("p",{className:"font-medium",children:["Invite people outside"," ",((w=h.account)==null?void 0:w.split("@")[1])??"the account's domain"]}),i.jsx("p",{className:"text-sm text-muted-foreground",children:"Off: the agent can only invite people from its own Google Workspace domain."})]}),i.jsx(ps,{checked:h.allowExternal,onCheckedChange:x=>void r.mutateAsync({path:"/api/calendar",method:"PUT",body:{allowExternal:x}}).catch(p("Couldn't change it")),"aria-label":"Allow external guests"})]})]})]}),i.jsxs(He,{children:[i.jsxs(ot,{children:[i.jsx(ut,{children:"Google client"}),i.jsx(Tt,{children:"From your Google Cloud project (Google Auth Platform → Clients): a Web application client, with the Google Calendar API enabled. See the setup guide for the steps."})]}),i.jsxs(Qe,{className:"space-y-4",children:[i.jsxs("div",{className:"space-y-1.5 text-sm",children:[i.jsx("p",{className:"font-medium",children:"Authorized redirect URI (add it to the client exactly)"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("code",{className:"break-all rounded bg-muted px-2 py-1",children:h.redirectUri}),i.jsx(Js,{text:h.redirectUri})]})]}),i.jsx(Oe,{label:"Client ID",children:x=>i.jsx(Re,{...x,value:s,onChange:j=>o(j.target.value),placeholder:"1234…apps.googleusercontent.com"})}),i.jsx(Oe,{label:"Client secret",help:h.hasSecret?"Saved. Enter a new one only to replace it.":void 0,children:x=>i.jsx(Re,{...x,type:"password",autoComplete:"off",value:u,onChange:j=>d(j.target.value),placeholder:h.hasSecret?"••••••••":"GOCSPX-…"})}),i.jsx(oe,{onClick:()=>void g(),disabled:r.isPending||!s.trim(),children:"Save"})]})]})]})}function WS(){const[n,r]=k.useState(null),s=k.useRef(!1);return k.useEffect(()=>{if(s.current)return;s.current=!0;const o=new URLSearchParams(window.location.search),u=o.get("code"),d=o.get("state");if(window.history.replaceState(null,"","/calendar/callback"),o.get("error")||!u||!d){r({ok:!1,message:o.get("error")==="access_denied"?"The sign-in was cancelled.":"Google didn't complete the sign-in."});return}Ee("/api/calendar/exchange",{method:"POST",body:{code:u,state:d}}).then(h=>r({ok:!0,account:h.account})).catch(h=>r({ok:!1,message:yt(h)}))},[]),i.jsx("div",{className:"mx-auto max-w-lg p-6",children:i.jsx(He,{children:i.jsxs(Qe,{className:"space-y-3 pt-6 text-sm",children:[n?n.ok?i.jsxs("p",{children:["Google Calendar is connected",n.account?i.jsxs(i.Fragment,{children:[" ","as ",i.jsx("code",{children:n.account})]}):null,"."]}):i.jsx("p",{className:"text-destructive",children:n.message}):i.jsx(kt,{label:"Connecting Google"}),i.jsx(Bt,{to:"/settings/calendar",className:"text-info underline",children:"Back to Calendar settings"})]})})})}function KS(){return i.jsxs("div",{className:"py-16 text-center",children:[i.jsx("h1",{className:"text-xl font-semibold",children:"Page not found"}),i.jsx(Bt,{to:"/",className:"mt-3 inline-block text-sm text-info underline",children:"Back to the dashboard"})]})}const GS=Xw([{element:i.jsx(bb,{}),children:[{path:"/login",element:i.jsx(Cb,{})},{path:"/change-password",element:i.jsx(km,{children:i.jsx(Nb,{})})},{element:i.jsx(km,{children:i.jsx(jb,{})}),children:[{index:!0,element:i.jsx(Rb,{})},{path:"requests",element:i.jsx(_b,{})},{path:"requests/:id",element:i.jsx(Ub,{})},{path:"schedules",element:i.jsx(tS,{})},{path:"setup",element:i.jsx(aS,{})},{path:"browser",element:i.jsx(uS,{})},{path:"tickets",element:i.jsx(pS,{})},{path:"trackers/linear/callback",element:i.jsx(kS,{})},{path:"trackers/jira/callback",element:i.jsx(jS,{})},{path:"calendar/callback",element:i.jsx(WS,{})},{path:"settings",element:i.jsx(SS,{}),children:[{index:!0,element:i.jsx(hd,{to:"agent",replace:!0})},{path:"agent",element:i.jsx(CS,{})},{path:"anthropic",element:i.jsx(ES,{})},{path:"general",element:i.jsx(LS,{})},{path:"slack",element:i.jsx(_S,{})},{path:"access",element:i.jsx(FS,{})},{path:"calendar",element:i.jsx(VS,{})},{path:"account",element:i.jsx(BS,{})}]},{path:"audit",element:i.jsx(eS,{})},{path:"*",element:i.jsx(KS,{})}]}]}]);function YS(){const n=k.useSyncExternalStore(Dj,Oj);return i.jsx("div",{"aria-live":"polite",role:"status",className:"pointer-events-none fixed bottom-4 right-4 z-50 flex w-full max-w-sm flex-col gap-2",children:n.map(r=>i.jsxs("div",{className:Xe("pointer-events-auto flex items-start gap-3 rounded-md border bg-card p-4 text-sm shadow-lg animate-in fade-in slide-in-from-bottom-2",r.variant==="error"&&"border-destructive/50",r.variant==="success"&&"border-success/50"),children:[i.jsxs("div",{className:"min-w-0 flex-1",children:[i.jsx("p",{className:"font-medium",children:r.title}),r.description&&i.jsx("p",{className:"mt-1 break-words text-muted-foreground",children:r.description})]}),i.jsx("button",{type:"button",onClick:()=>ty(r.id),"aria-label":"Dismiss",className:"rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:i.jsx(Bd,{className:"h-4 w-4"})})]},r.id))})}const JS=new Set(["unauthorized","must_change_password","csrf"]),XS=new Ax({defaultOptions:{queries:{retry:(n,r)=>!(r instanceof Wn&&r.status>=400&&r.status<500)&&n<2,refetchOnWindowFocus:!0}},mutationCache:new eg({onError:(n,r,s,o)=>{var u;(u=o.meta)!=null&&u.inlineError||n instanceof Wn&&JS.has(n.code)||We({title:"Action failed",description:yt(n),variant:"error"})}})});fx.createRoot(document.getElementById("root")).render(i.jsx(ix.StrictMode,{children:i.jsxs(Dx,{client:XS,children:[i.jsx(ck,{router:GS}),i.jsx(YS,{})]})}));