specrails-hub 1.54.2 → 1.54.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/{ActivityFeedPage-D-6pkYiq.js → ActivityFeedPage-Bst7JQBD.js} +1 -1
- package/client/dist/assets/{AgentsPage-BmlV0tLU.js → AgentsPage-CQSsFPUf.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-BLA44-85.js → AnalyticsPage-BXSGt62I.js} +1 -1
- package/client/dist/assets/{BarChart-erGMYSLM.js → BarChart-D0Js4qm-.js} +1 -1
- package/client/dist/assets/{DocsDialog-BUuWLIDI.js → DocsDialog-Dx-XFezQ.js} +1 -1
- package/client/dist/assets/{DocsPage-Dfnfe1v9.js → DocsPage-DBe0KLC6.js} +1 -1
- package/client/dist/assets/{ExportDropdown-XowR3m8-.js → ExportDropdown-CHJbkux7.js} +1 -1
- package/client/dist/assets/{HubAnalyticsPage-BzcWFJdx.js → HubAnalyticsPage-CExwOxYs.js} +1 -1
- package/client/dist/assets/{IntegrationsPage-FoDqpmGE.js → IntegrationsPage-Cq0TXYaZ.js} +1 -1
- package/client/dist/assets/{JobDetailPage-BEDHHbcD.js → JobDetailPage-C00ccK2a.js} +1 -1
- package/client/dist/assets/{JobsPage-D4m_aDkA.js → JobsPage-BgrKbNeS.js} +1 -1
- package/client/dist/assets/{dist-js-YZ0tOOEy.js → dist-js-BNqVf1xQ.js} +1 -1
- package/client/dist/assets/{dist-js-DI_gx9G3.js → dist-js-CEpsPzWv.js} +1 -1
- package/client/dist/assets/{index-BC3icgTz.js → index-NFgJciDY.js} +7 -7
- package/client/dist/assets/{lib-h5sZK86Y.js → lib-CKFRx_1H.js} +1 -1
- package/client/dist/assets/{useProjectCache-T9bpe46I.js → useProjectCache-bmnxPDIP.js} +1 -1
- package/client/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{L as t,St as n,Vt as r,Z as i,_t as a,bt as o,ot as s,st as c,vt as l,xt as u,yt as d}from"./index-
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{L as t,St as n,Vt as r,Z as i,_t as a,bt as o,ot as s,st as c,vt as l,xt as u,yt as d}from"./index-NFgJciDY.js";var f=l(`ban`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M4.929 4.929 19.07 19.071`,key:`196cmz`}]]),p=e(r(),1);function m(e){let t=new Set;return e.filter(e=>{let n=`${e.type}:${e.jobId}`;return t.has(n)?!1:(t.add(n),!0)})}function h({activeProjectId:e,limit:t=50}){let[r,i]=(0,p.useState)([]),[a,s]=(0,p.useState)(!1),[c,l]=(0,p.useState)(!0),u=(0,p.useRef)(e);(0,p.useEffect)(()=>{u.current=e},[e]);let{registerHandler:d,unregisterHandler:f}=o();(0,p.useEffect)(()=>{if(!e){i([]),l(!0);return}let r=!1;s(!0),i([]),l(!0);async function a(){let e=n();try{let n=await fetch(`${e}/activity?limit=${t}`);if(!n.ok||r)return;let a=await n.json();if(r)return;i(a),l(a.length===t)}catch{}finally{r||s(!1)}}return a(),()=>{r=!0}},[e,t]);let h=(0,p.useCallback)(async()=>{if(a||!c)return;s(!0);let e=n();try{i(n=>{let r=n[n.length-1];if(!r)return n;let a=encodeURIComponent(r.timestamp);return fetch(`${e}/activity?limit=${t}&before=${a}`).then(e=>e.json()).then(e=>{i(t=>m([...t,...e])),l(e.length===t),s(!1)}).catch(()=>s(!1)),n})}catch{s(!1)}},[a,c,t]),g=(0,p.useCallback)(e=>{let t=e,n=u.current;if(!(!t||typeof t.type!=`string`)&&!(t.projectId&&t.projectId!==n)){if(t.type===`queue`&&Array.isArray(t.jobs)){let e=[];for(let n of t.jobs){let t=n.status===`completed`?`job_completed`:n.status===`failed`?`job_failed`:n.status===`canceled`?`job_canceled`:`job_started`;e.push({id:`${t}:${n.id}`,type:t,jobId:n.id,jobCommand:n.command??``,timestamp:n.startedAt??new Date().toISOString(),summary:`${t.replace(`_`,` `)}: ${n.command??``}`,costUsd:null})}e.length>0&&i(t=>m([...e,...t]))}if(t.type===`phase`&&t.phase&&t.state&&t.timestamp){let e={id:`phase:${t.phase}:${t.state}:${t.timestamp}`,type:`job_started`,jobId:`phase-${t.phase}`,jobCommand:`Phase: ${t.phase} → ${t.state}`,timestamp:t.timestamp,summary:`Phase ${t.phase} is ${t.state}`,costUsd:null};i(t=>m([e,...t]))}}},[]);return(0,p.useLayoutEffect)(()=>(d(`activity`,g),()=>f(`activity`)),[g,d,f]),{items:r,loading:a,hasMore:c,loadMore:h}}var g=u();function _(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let i=Math.floor(r/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}function v({type:e}){switch(e){case`job_completed`:return(0,g.jsx)(c,{className:`w-4 h-4 text-green-500 flex-shrink-0`});case`job_failed`:return(0,g.jsx)(s,{className:`w-4 h-4 text-red-500 flex-shrink-0`});case`job_canceled`:return(0,g.jsx)(f,{className:`w-4 h-4 text-muted-foreground flex-shrink-0`});default:return(0,g.jsx)(t,{className:`w-4 h-4 text-blue-500 flex-shrink-0`})}}function y(e){switch(e){case`job_completed`:return`Completed`;case`job_failed`:return`Failed`;case`job_canceled`:return`Canceled`;default:return`Started`}}function b(e){switch(e){case`job_completed`:return`text-green-500`;case`job_failed`:return`text-red-500`;case`job_canceled`:return`text-muted-foreground`;default:return`text-blue-500`}}function x(){let{activeProjectId:e}=d(),{items:t,loading:n,hasMore:r,loadMore:o}=h({activeProjectId:e}),s=(0,p.useRef)(null);return(0,p.useEffect)(()=>{let e=s.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&r&&!n&&o()},{threshold:.1});return t.observe(e),()=>t.disconnect()},[r,n,o]),(0,g.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,g.jsxs)(`div`,{className:`flex items-center gap-2 px-4 py-3 border-b border-border bg-background/50`,children:[(0,g.jsx)(a,{className:`w-4 h-4 text-muted-foreground`}),(0,g.jsx)(`h1`,{className:`text-sm font-medium`,children:`Activity`})]}),(0,g.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[n&&t.length===0?(0,g.jsx)(`div`,{className:`flex items-center justify-center h-32`,children:(0,g.jsx)(i,{className:`w-4 h-4 animate-spin text-muted-foreground`})}):t.length===0?(0,g.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-48 gap-2 text-muted-foreground`,children:[(0,g.jsx)(a,{className:`w-8 h-8 opacity-40`}),(0,g.jsx)(`p`,{className:`text-sm`,children:`No activity yet`}),(0,g.jsx)(`p`,{className:`text-xs opacity-70`,children:`Job events will appear here when jobs run`})]}):(0,g.jsx)(`ul`,{className:`divide-y divide-border/50`,children:t.map(e=>(0,g.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-2.5 hover:bg-accent/30 transition-colors`,children:[(0,g.jsx)(v,{type:e.type}),(0,g.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,g.jsx)(`p`,{className:`text-xs text-foreground truncate`,title:e.jobCommand,children:e.jobCommand}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2 mt-0.5`,children:[(0,g.jsx)(`span`,{className:`text-xs font-medium ${b(e.type)}`,children:y(e.type)}),e.costUsd!=null&&(0,g.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`$`,e.costUsd.toFixed(4)]})]})]}),(0,g.jsx)(`span`,{className:`text-xs text-muted-foreground flex-shrink-0 tabular-nums`,children:_(e.timestamp)})]},`${e.type}:${e.jobId}`))}),(0,g.jsx)(`div`,{ref:s,className:`h-1`}),n&&t.length>0&&(0,g.jsx)(`div`,{className:`flex justify-center py-3`,children:(0,g.jsx)(i,{className:`w-4 h-4 animate-spin text-muted-foreground`})}),!r&&t.length>0&&(0,g.jsx)(`p`,{className:`text-center text-xs text-muted-foreground py-3`,children:`All activity loaded`})]})]})}export{x as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{$ as t,A as n,At as r,B as i,Ct as a,D as o,Dt as s,E as c,Et as l,F as u,Ft as d,H as f,J as p,K as m,M as h,Mt as g,N as _,Nt as v,O as y,Ot as b,Pt as x,R as S,St as C,Tt as w,U as T,V as E,Vt as D,W as O,X as k,Y as A,Z as j,a as M,bt as N,ct as ee,dt as P,et as F,ft as I,gt as L,ht as R,j as z,jt as B,k as V,kt as H,mt as U,rt as te,tt as ne,ut as re,vt as W,wt as G,xt as ie,yt as ae,z as K}from"./index-BC3icgTz.js";var oe=W(`flask-conical`,[[`path`,{d:`M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2`,key:`18mbvz`}],[`path`,{d:`M6.453 15h11.094`,key:`3shlmq`}],[`path`,{d:`M8.5 2h7`,key:`csnxdl`}]]),q=W(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),se=W(`pin`,[[`path`,{d:`M12 17v5`,key:`bb1du9`}],[`path`,{d:`M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z`,key:`1nkz8b`}]]),ce=W(`wand-sparkles`,[[`path`,{d:`m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72`,key:`ul74o6`}],[`path`,{d:`m14 7 3 3`,key:`1r5n42`}],[`path`,{d:`M5 6v4`,key:`ilb8ba`}],[`path`,{d:`M19 14v4`,key:`blhpug`}],[`path`,{d:`M10 2v2`,key:`7u0qdc`}],[`path`,{d:`M7 8H3`,key:`zfb6yr`}],[`path`,{d:`M21 16h-4`,key:`1cnmox`}],[`path`,{d:`M11 3H9`,key:`1obp7u`}]]),J=e(D(),1),Y=ie(),X=/^[a-z0-9][a-z0-9-]*$/;function le({open:e,mode:t=`add`,initial:r,chainAgents:i,onConfirm:a,onCancel:s}){let[l,d]=(0,J.useState)(``),[f,p]=(0,J.useState)(i[0]??``);(0,J.useEffect)(()=>{e&&(t===`edit`&&r?(d(r.tags.join(`, `)),p(i.includes(r.agent)?r.agent:i[0]??``)):(d(``),p(i[0]??``)))},[e,t,r,i]);let m=l.split(`,`).map(e=>e.trim()).filter(Boolean),h=m.filter(e=>!X.test(e)),g=m.length>0&&h.length===0&&i.includes(f);return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||s()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsxs)(n,{children:[(0,Y.jsx)(z,{children:t===`edit`?`Edit routing rule`:`Add routing rule`}),(0,Y.jsx)(y,{children:t===`edit`?`Update the tags or target agent for this rule.`:`Add a tag-matched routing rule using lowercase kebab-case tags.`})]}),(0,Y.jsxs)(`div`,{className:`py-2 space-y-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Tags`}),(0,Y.jsx)(M,{autoFocus:!0,value:l,onChange:e=>d(e.target.value),placeholder:`frontend, ui`,"aria-label":`Tags`,className:`text-sm font-mono`}),(0,Y.jsxs)(`p`,{className:`text-[11px] text-muted-foreground mt-1`,children:[`Comma-separated. Use lowercase kebab-case like `,(0,Y.jsx)(`code`,{children:`frontend`}),` or `,(0,Y.jsx)(`code`,{children:`api-design`}),`.`]}),h.length>0&&(0,Y.jsxs)(`p`,{className:`text-[11px] text-red-400 mt-1`,children:[`Invalid tag`,h.length===1?``:`s`,`: `,h.join(`, `),`. Tags must use lowercase letters, digits, and hyphens only.`]})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Route to`}),(0,Y.jsx)(`select`,{value:f,onChange:e=>p(e.target.value),"aria-label":`Route to`,className:`w-full h-9 px-2 text-sm rounded-md border border-border bg-background`,children:i.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground mt-1`,children:`Only agents in this profile's chain can be routing targets.`})]})]}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:s,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:()=>a(m,f),disabled:!g,children:t===`edit`?`Save changes`:`Add rule`})]})]})})}var Z=new Set([`sr-architect`,`sr-developer`,`sr-reviewer`,`sr-merge-resolver`]),ue=[`sonnet`,`opus`,`haiku`],de=/^[a-z0-9][a-z0-9-]*$/;function fe({profile:e,onChange:t,footer:n,onValidityChange:i,onSoftWarningsChange:o}){let[c,l]=(0,J.useState)([]),[d,f]=(0,J.useState)(!1),[m,h]=(0,J.useState)(!1),[_,y]=(0,J.useState)(null);(0,J.useEffect)(()=>{let e=!1;return fetch(`${C()}/profiles/catalog`).then(e=>e.ok?e.json():{agents:[]}).then(t=>{e||l(t.agents)}).catch(()=>{e||l([])}),()=>{e=!0}},[]);let x=n=>{let r=JSON.parse(JSON.stringify(e));n(r),t(r)},T=new Set(e.agents.map(e=>e.id)),E=c.filter(e=>!T.has(e.id)),D=(0,J.useMemo)(()=>{let t=[];for(let n of Z)e.agents.some(e=>e.id===n)||t.push(`Missing required baseline agent: ${n}`);let n=e.routing.filter(e=>`default`in e&&e.default===!0);if(n.length>1&&t.push(`Routing may have at most one default rule (found ${n.length})`),n.length===1){let n=e.routing[e.routing.length-1];`default`in n&&n.default===!0||t.push(`The default routing rule must be the last entry`)}for(let n of e.routing)if(e.agents.some(e=>e.id===n.agent)||t.push(`Routing references agent not in the chain: ${n.agent}`),`tags`in n){let e=n.tags.filter(e=>!de.test(e));e.length>0&&t.push(`Routing rule ${n.agent} has invalid tags: ${e.join(`, `)} (use lowercase kebab-case)`)}return t},[e]),O=(0,J.useMemo)(()=>{if(e.routing.length===0)return[];let t=new Set(e.routing.map(e=>e.agent));return e.agents.filter(e=>!Z.has(e.id)&&!t.has(e.id)).map(e=>e.id)},[e]),k=(0,J.useMemo)(()=>e.routing.some(e=>`default`in e&&e.default===!0),[e.routing]);(0,J.useEffect)(()=>{i&&i(D)},[D,i]),(0,J.useEffect)(()=>{o&&o({agentsMissingRouting:O})},[O,o]);let A=e=>{x(t=>{let n={id:e,model:`sonnet`},r=t.agents.findIndex(e=>e.id===`sr-merge-resolver`);r>=0?t.agents.splice(r,0,n):t.agents.push(n)}),f(!1)},j=t=>{let n=e.agents[t];Z.has(n.id)||x(e=>{e.agents.splice(t,1),e.routing=e.routing.filter(e=>e.agent!==n.id)})},N=(t,n)=>{if(t===n)return;let r=e.agents.findIndex(e=>e.id===t),i=e.agents.findIndex(e=>e.id===n);if(r<0||i<0)return;let a=G(e.agents,r,i),o=a.findIndex(e=>e.id===`sr-architect`);if(o>0){let[e]=a.splice(o,1);a.unshift(e)}let s=a.findIndex(e=>e.id===`sr-merge-resolver`);if(s>=0&&s!==a.length-1){let[e]=a.splice(s,1);a.push(e)}x(e=>{e.agents=a})},ee=v(g(r,{activationConstraint:{distance:4}}),g(H,{coordinateGetter:w})),P=e=>{let{active:t,over:n}=e;n&&N(String(t.id),String(n.id))},F=(e,t)=>{x(n=>{n.agents[e].model=t})},I=(e,t)=>{x(n=>{let r={tags:e,agent:t},i=n.routing.findIndex(e=>`default`in e&&e.default===!0);i>=0?n.routing.splice(i,0,r):n.routing.push(r)}),h(!1)},L=()=>{x(e=>{e.routing.some(e=>`default`in e&&e.default===!0)||e.agents.some(e=>e.id===`sr-developer`)&&e.routing.push({default:!0,agent:`sr-developer`})})},R=e=>`default`in e&&e.default===!0,z=(e,t)=>{x(n=>{let r=n.routing[e];r&&(R(r)||(r.agent=t))})},V=(e,t,n)=>{x(r=>{let i=r.routing[e];i&&(R(i)||(i.tags=t,i.agent=n))})},U=e=>{x(t=>{let n=t.routing[e];n&&(R(n)||t.routing.splice(e,1))})},te=(t,n)=>{let r=t+n;if(r<0||r>=e.routing.length)return;let i=e.routing[t],a=e.routing[r];R(i)||R(a)||x(e=>{let[n]=e.routing.splice(t,1);e.routing.splice(r,0,n)})};return(0,Y.jsxs)(`div`,{className:`p-6 space-y-6 max-w-3xl`,children:[(0,Y.jsx)(le,{open:m,mode:`add`,chainAgents:e.agents.map(e=>e.id),onConfirm:I,onCancel:()=>h(!1)}),(0,Y.jsx)(le,{open:_!==null,mode:`edit`,initial:_!==null&&e.routing[_]&&!(`default`in e.routing[_])?{tags:e.routing[_].tags,agent:e.routing[_].agent}:void 0,chainAgents:e.agents.map(e=>e.id),onConfirm:(e,t)=>{_!==null&&(V(_,e,t),y(null))},onCancel:()=>y(null)}),D.length>0&&(0,Y.jsxs)(`div`,{className:`px-3 py-2 text-xs rounded-md border border-yellow-500/30 bg-yellow-500/10 text-yellow-500`,children:[(0,Y.jsxs)(`div`,{className:`font-medium mb-1`,children:[D.length,` validation `,D.length===1?`issue`:`issues`]}),(0,Y.jsx)(`ul`,{className:`list-disc list-inside space-y-0.5`,children:D.map((e,t)=>(0,Y.jsx)(`li`,{children:e},t))})]}),(0,Y.jsxs)(`section`,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Name`}),(0,Y.jsx)(M,{value:e.name,disabled:!0,className:`text-sm`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Description`}),(0,Y.jsx)(M,{value:e.description??``,onChange:e=>x(t=>{t.description=e.target.value}),className:`text-sm`,placeholder:`What is this profile for?`})]})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2`,children:`Orchestrator`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-3 p-3 rounded-md border border-border`,children:[(0,Y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-mono text-foreground truncate`,children:`/specrails:implement · /specrails:batch-implement`}),(0,Y.jsx)(`div`,{className:`text-[11px] text-muted-foreground mt-0.5`,children:`Top-level model for both commands. batch-implement delegates to implement per feature, so every rail it spawns inherits this profile's agent chain.`})]}),(0,Y.jsx)(he,{value:e.orchestrator.model,onChange:e=>x(t=>{t.orchestrator.model=e})})]})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,Y.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[`Agent chain (`,e.agents.length,`)`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:()=>f(e=>!e),disabled:E.length===0,title:E.length===0?`All catalog agents are already in the chain`:`Add an agent from the catalog`,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add`]})]}),d&&(0,Y.jsxs)(`div`,{className:`mb-2 p-2 rounded-md border border-border bg-muted/30`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-1.5 px-1`,children:[(0,Y.jsxs)(`span`,{className:`text-[11px] text-muted-foreground`,children:[`Pick from catalog (`,E.length,` available)`]}),(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:()=>f(!1),title:`Close`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]}),E.length===0?(0,Y.jsx)(`div`,{className:`px-2 py-3 text-xs text-muted-foreground text-center`,children:`No more agents in the catalog. Add custom agents from the Agents Catalog tab.`}):(0,Y.jsx)(`div`,{className:`space-y-0.5 max-h-64 overflow-auto`,children:E.map(e=>(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>A(e.id),className:`w-full flex items-center justify-between gap-2 px-2 py-1.5 text-left rounded hover:bg-accent transition-colors`,children:[(0,Y.jsx)(`span`,{className:`text-sm font-mono`,children:e.id}),(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded `+(e.kind===`custom`?`bg-purple-500/15 text-purple-400`:`bg-muted text-muted-foreground`),children:e.kind})]},e.id))})]}),(0,Y.jsx)(b,{sensors:ee,collisionDetection:B,onDragEnd:P,children:(0,Y.jsx)(a,{items:e.agents.map(e=>e.id),strategy:s,children:(0,Y.jsx)(`div`,{className:`space-y-1.5`,children:e.agents.map((e,t)=>(0,Y.jsx)(pe,{agent:e,canRemove:!Z.has(e.id),onModel:e=>F(t,e),onRemove:()=>j(t)},e.id))})})})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,Y.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[`Routing (`,e.routing.length,`)`]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1`,children:[!k&&(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:L,disabled:e.agents.length===0,title:e.agents.length===0?`Add at least one agent before creating routing rules`:void 0,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add default`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:()=>h(!0),disabled:e.agents.length===0,title:e.agents.length===0?`Add at least one agent before creating routing rules`:void 0,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add rule`]})]})]}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground mb-2`,children:`First matching rule wins. Rules are editable and removable, and the default catch-all stays last when present. If you leave routing empty, the pipeline falls back to the first developer-shaped agent in the chain.`}),O.length>0&&(0,Y.jsxs)(`div`,{className:`mb-2 px-3 py-2 text-xs rounded-md border border-yellow-500/30 bg-yellow-500/10 text-yellow-500`,children:[(0,Y.jsx)(`div`,{className:`font-medium mb-1`,children:`Untargeted agents in the chain`}),(0,Y.jsxs)(`div`,{children:[`No routing rule points to: `,(0,Y.jsx)(`span`,{className:`font-mono`,children:O.join(`, `)}),`. Add a tag rule or retarget the default rule if you want them to run.`]})]}),(0,Y.jsx)(`div`,{className:`space-y-1.5`,children:e.routing.map((t,n)=>{let r=`default`in t&&t.default===!0;return(0,Y.jsx)(me,{rule:t,ordinal:n+1,isLast:n===e.routing.length-1,canMove:!r,canRemove:!r,canEdit:!r,chainAgents:e.agents.map(e=>e.id),onAgentChange:e=>z(n,e),onEdit:()=>y(n),onUp:()=>te(n,-1),onDown:()=>te(n,1),onRemove:()=>U(n)},n)})})]}),n&&(0,Y.jsx)(`div`,{className:`pt-3 border-t border-border`,children:n})]})}function pe({agent:e,canRemove:n,onModel:r,onRemove:i}){let a=Z.has(e.id),o=e.id===`sr-architect`,s=e.id===`sr-merge-resolver`,{attributes:c,listeners:u,setNodeRef:d,transform:f,transition:p,isDragging:m}=l({id:e.id});return(0,Y.jsxs)(`div`,{ref:d,style:{transform:x.Transform.toString(f),transition:p,opacity:m?.5:void 0,zIndex:m?10:void 0},className:`flex items-center gap-2 px-2 py-1.5 rounded-md border border-border group hover:bg-accent/30 transition-colors bg-background`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`flex-shrink-0 p-0.5 rounded text-muted-foreground cursor-grab active:cursor-grabbing hover:text-foreground`,title:`Drag to reorder`,"aria-label":`Drag handle`,...c,...u,children:(0,Y.jsx)(t,{className:`w-3.5 h-3.5`})}),(0,Y.jsx)(`span`,{className:`text-sm font-mono flex-1 truncate`,children:e.id}),o&&(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-accent-primary/15 text-accent-primary`,title:`Pinned to first position — pipeline always starts with sr-architect`,children:[(0,Y.jsx)(se,{className:`w-2.5 h-2.5 rotate-[135deg]`}),` first`]}),s&&(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-accent-primary/15 text-accent-primary`,title:`Pinned to last position — merge phase always runs last`,children:[(0,Y.jsx)(se,{className:`w-2.5 h-2.5 rotate-45`}),` last`]}),a&&!o&&!s&&(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground`,children:`required`}),(0,Y.jsx)(he,{value:e.model??`sonnet`,onChange:r}),(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded disabled:opacity-30 disabled:cursor-not-allowed opacity-0 group-hover:opacity-100 transition-opacity`,onClick:i,disabled:!n,title:n?`Remove`:`Required baseline agent — the pipeline depends on this row`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]})}function me({rule:e,ordinal:t,isLast:n,canMove:r,canRemove:i,canEdit:a,chainAgents:o,onAgentChange:s,onEdit:c,onUp:l,onDown:u,onRemove:d}){let f=`default`in e&&e.default===!0;return(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-1.5 rounded-md border border-border group hover:bg-accent/30 transition-colors`,children:[(0,Y.jsxs)(`span`,{className:`text-[10px] font-mono text-muted-foreground w-5 text-center flex-shrink-0`,children:[t,`.`]}),f?(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground flex-1`,children:`everything else`}):(0,Y.jsx)(`span`,{className:`text-xs flex-1 flex gap-1 flex-wrap items-center`,children:e.tags.map(e=>(0,Y.jsx)(`span`,{className:`px-1.5 py-0.5 rounded bg-muted font-mono text-[11px]`,children:e},e))}),(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`→`}),f?(0,Y.jsx)(`span`,{className:`h-7 max-w-[15rem] px-2 text-xs font-mono rounded border border-border bg-muted/40 text-muted-foreground inline-flex items-center`,"aria-label":`Default routing target (core, read-only)`,title:`Core fallback — not editable`,children:e.agent}):(0,Y.jsx)(`select`,{value:e.agent,onChange:e=>s(e.target.value),"aria-label":`Routing target for rule ${t}`,className:`h-7 max-w-[15rem] px-2 text-xs font-mono rounded border border-border bg-background`,children:o.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))}),(0,Y.jsxs)(`div`,{className:`flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity`,children:[a&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:c,title:`Edit rule`,"aria-label":`Edit rule ${t}`,children:(0,Y.jsx)(A,{className:`w-3 h-3`})}),r&&!n&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:u,title:`Move down`,children:(0,Y.jsx)(L,{className:`w-3 h-3`})}),r&&t>1&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:l,title:`Move up`,children:(0,Y.jsx)(U,{className:`w-3 h-3`})}),i&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded`,onClick:d,title:`Remove`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]}),f&&(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground`,title:`Core fallback — the pipeline's last-resort rule, pinned to sr-developer`,children:`core · default`})]})}function he({value:e,onChange:t}){return(0,Y.jsx)(`select`,{value:e,onChange:e=>t(e.target.value),className:`h-7 px-2 text-xs rounded border border-border bg-background`,children:ue.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))})}function ge({open:e,title:t,description:r,placeholder:i,initialValue:a=``,confirmLabel:s=`Confirm`,inputPattern:l,inputInvalidHint:d,onConfirm:f,onCancel:p}){let[m,h]=(0,J.useState)(a);(0,J.useEffect)(()=>{e&&h(a)},[e,a]);let g=m.trim(),_=!l||l.test(g),v=g.length>0&&_;return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||p()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsx)(n,{children:(0,Y.jsx)(z,{children:t})}),(0,Y.jsxs)(`div`,{className:`py-2 space-y-2`,children:[r&&(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r}),(0,Y.jsx)(M,{autoFocus:!0,value:m,placeholder:i,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Enter`&&v&&f(g)},className:`text-sm font-mono`}),g.length>0&&!_&&d&&(0,Y.jsx)(`p`,{className:`text-[11px] text-yellow-500`,children:d})]}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:p,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:()=>f(g),disabled:!v,children:s})]})]})})}function _e({open:e,title:t,description:r,confirmLabel:i=`Confirm`,destructive:a=!1,onConfirm:s,onCancel:l}){return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||l()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsx)(n,{children:(0,Y.jsx)(z,{children:t})}),r&&(0,Y.jsx)(`div`,{className:`py-2`,children:(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r})}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:l,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:s,className:a?`bg-red-500 hover:bg-red-600 text-white`:void 0,children:i})]})]})})}function ve(){let[e,t]=(0,J.useState)([]),[n,r]=(0,J.useState)(null),[a,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(!0),[l,f]=(0,J.useState)(null),[m,h]=(0,J.useState)(!1),[g,_]=(0,J.useState)([]),[v,y]=(0,J.useState)([]),[b,x]=(0,J.useState)(!1),[S,w]=(0,J.useState)(null),[T,E]=(0,J.useState)(null),D=(0,J.useCallback)(async()=>{c(!0),f(null);try{let e=await fetch(`${C()}/profiles`);if(!e.ok)throw Error(`List failed: ${e.status}`);let i=await e.json();t(i.profiles),i.profiles.length>0&&!n&&r(i.profiles[0].name)}catch(e){f(e.message)}finally{c(!1)}},[n]);(0,J.useEffect)(()=>{D()},[D]),(0,J.useEffect)(()=>{if(!n){o(null);return}let e=!1;return fetch(`${C()}/profiles/${encodeURIComponent(n)}`).then(e=>{if(!e.ok)throw Error(`Load failed: ${e.status}`);return e.json()}).then(t=>{e||o(t.profile)}).catch(t=>{e||f(t.message)}),()=>{e=!0}},[n]);let k=(0,J.useCallback)(async()=>{h(!0),f(null);try{let e=await fetch(`${C()}/profiles/migrate-from-settings`,{method:`POST`});if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t.error??`Migration failed: ${e.status}`)}await D(),r(`default`),d.success(`Profile migrated`,{description:`default profile created from your current agents`})}catch(e){let t=e.message;f(t),d.error(`Migration failed`,{description:t})}finally{h(!1)}},[D]),A=(0,J.useCallback)(async e=>{x(!1),h(!0),f(null);try{let t={schemaVersion:1,name:e,description:``,orchestrator:{model:`sonnet`},agents:[{id:`sr-architect`,model:`sonnet`,required:!0},{id:`sr-developer`,model:`sonnet`,required:!0},{id:`sr-reviewer`,model:`sonnet`,required:!0},{id:`sr-merge-resolver`,model:`sonnet`,required:!0}],routing:[{default:!0,agent:`sr-developer`}]},n=await fetch(`${C()}/profiles`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Create failed: ${n.status}`)}await D(),r(e),d.success(`Profile created`,{description:e})}catch(e){let t=e.message;f(t),d.error(`Failed to create profile`,{description:t})}finally{h(!1)}},[D]),j=(0,J.useCallback)(async(e,t)=>{w(null),h(!0),f(null);try{let n=await fetch(`${C()}/profiles/${encodeURIComponent(e)}/duplicate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Duplicate failed: ${n.status}`)}await D(),r(t),d.success(`Profile duplicated`,{description:`${e} → ${t}`})}catch(e){let t=e.message;f(t),d.error(`Failed to duplicate profile`,{description:t})}finally{h(!1)}},[D]),M=(0,J.useCallback)(async e=>{E(null),h(!0),f(null);try{let t=await fetch(`${C()}/profiles/${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`Delete failed: ${t.status}`)}r(t=>t===e?null:t),await D(),d.success(`Profile deleted`,{description:e})}catch(e){let t=e.message;f(t),d.error(`Failed to delete profile`,{description:t})}finally{h(!1)}},[D]),N=(0,J.useCallback)(()=>x(!0),[]),ee=(0,J.useCallback)(e=>w({from:e}),[]),P=(0,J.useCallback)(e=>E({name:e}),[]),F=(0,J.useCallback)(async(e,t)=>{h(!0),f(null);try{let n=await fetch(`${C()}/profiles/${encodeURIComponent(e.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Save failed: ${n.status}`)}o(e),t.length>0?d.warning(`Profile saved with untargeted agents`,{description:`No routing rule points to: ${t.join(`, `)}. Add a tag rule or retarget the default rule if you want them to run.`,duration:6e3}):d.success(`Profile saved`,{description:e.name})}catch(e){let t=e.message;f(t),d.error(`Failed to save profile`,{description:t})}finally{h(!1)}},[]),I=(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(ge,{open:b,title:`New profile`,description:`Pick a lowercase kebab-case name (letters, digits, and hyphens).`,placeholder:`my-profile`,confirmLabel:`Create`,inputPattern:/^[a-z0-9][a-z0-9-]*$/,inputInvalidHint:`Must start with a letter or digit and contain only lowercase letters, digits, and hyphens.`,onConfirm:e=>void A(e),onCancel:()=>x(!1)}),S&&(0,Y.jsx)(ge,{open:!0,title:`Duplicate "${S.from}"`,description:`Name for the new profile.`,placeholder:`${S.from}-copy`,initialValue:`${S.from}-copy`,confirmLabel:`Duplicate`,inputPattern:/^[a-z0-9][a-z0-9-]*$/,inputInvalidHint:`Lowercase kebab-case only.`,onConfirm:e=>void j(S.from,e),onCancel:()=>w(null)}),T&&(0,Y.jsx)(_e,{open:!0,title:`Delete profile "${T.name}"?`,description:`This cannot be undone. Jobs already launched with this profile keep their snapshot; future launches will fall back to the resolution order.`,confirmLabel:`Delete`,destructive:!0,onConfirm:()=>void M(T.name),onCancel:()=>E(null)})]});return s?(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Loading profiles…`})}):e.length===0?(0,Y.jsxs)(Y.Fragment,{children:[I,(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsxs)(`div`,{className:`text-center max-w-md`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`No profiles yet`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground mt-1 mb-4`,children:`Profiles let you save orchestrator + agent + routing combinations and pick one per rail.`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 justify-center`,children:[(0,Y.jsxs)(u,{size:`sm`,onClick:k,disabled:m,children:[(0,Y.jsx)(ce,{className:`w-3.5 h-3.5 mr-1.5`}),` Migrate from current agents`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:N,disabled:m,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1.5`}),` Blank profile`]})]}),(0,Y.jsxs)(`div`,{className:`text-[11px] text-muted-foreground/70 mt-3`,children:[`"Migrate" reads your existing `,(0,Y.jsx)(`code`,{className:`text-foreground`,children:`.claude/agents/`}),` `,`frontmatter models and creates a `,(0,Y.jsx)(`code`,{className:`text-foreground`,children:`default`}),` profile mirroring today's behavior — zero-loss.`]}),l&&(0,Y.jsx)(`div`,{className:`mt-3 text-xs text-red-400`,children:l})]})})]}):(0,Y.jsxs)(`div`,{className:`flex flex-col h-full`,children:[I,(0,Y.jsxs)(`div`,{className:`flex flex-1 min-h-0`,children:[(0,Y.jsxs)(`aside`,{className:`w-64 flex-shrink-0 border-r border-border flex flex-col`,children:[(0,Y.jsxs)(`div`,{className:`p-3 flex items-center justify-between`,children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:`Profiles`}),(0,Y.jsx)(u,{size:`sm`,variant:`ghost`,onClick:N,disabled:m,children:(0,Y.jsx)(p,{className:`w-3.5 h-3.5`})})]}),(0,Y.jsx)(`div`,{className:`flex-1 overflow-auto px-2 pb-3`,children:e.map(e=>(0,Y.jsxs)(`div`,{className:`group mb-1 rounded-md px-2 py-1.5 text-xs cursor-pointer transition-colors flex items-center justify-between `+(e.name===n?`bg-accent text-foreground`:`text-muted-foreground hover:bg-accent/50 hover:text-foreground`),onClick:()=>r(e.name),role:`button`,tabIndex:0,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&r(e.name)},children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 min-w-0`,children:[(0,Y.jsx)(`span`,{className:`truncate font-medium`,children:e.name}),e.isDefault&&(0,Y.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`(team default)`})]}),(0,Y.jsxs)(`div`,{className:`flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,title:`Duplicate`,onClick:t=>{t.stopPropagation(),ee(e.name)},children:(0,Y.jsx)(te,{className:`w-3 h-3`})}),!e.isDefault&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded`,title:`Delete`,onClick:t=>{t.stopPropagation(),P(e.name)},children:(0,Y.jsx)(i,{className:`w-3 h-3`})})]})]},e.name))})]}),(0,Y.jsxs)(`main`,{className:`flex-1 overflow-auto`,children:[l&&(0,Y.jsx)(`div`,{className:`mx-4 mt-4 px-3 py-2 text-xs rounded border border-red-500/30 bg-red-500/10 text-red-400`,children:l}),a?(0,Y.jsx)(fe,{profile:a,onChange:o,onValidityChange:_,onSoftWarningsChange:e=>y(e.agentsMissingRouting),footer:(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsxs)(u,{size:`sm`,onClick:()=>void F(a,v),disabled:m||g.length>0,title:g.length>0?`Fix validation issues before saving`:void 0,children:[(0,Y.jsx)(O,{className:`w-3.5 h-3.5 mr-1.5`}),`Save`]}),m&&(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Saving…`}),g.length>0&&(0,Y.jsxs)(`span`,{className:`text-xs text-yellow-500`,children:[g.length,` `,g.length===1?`issue`:`issues`,` to resolve`]})]})},a.name):(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Select a profile to edit`})})]})]})]})}function Q(e){let t=e.workflow.map((e,t)=>`${t+1}. ${e}`).join(`
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{$ as t,A as n,At as r,B as i,Ct as a,D as o,Dt as s,E as c,Et as l,F as u,Ft as d,H as f,J as p,K as m,M as h,Mt as g,N as _,Nt as v,O as y,Ot as b,Pt as x,R as S,St as C,Tt as w,U as T,V as E,Vt as D,W as O,X as k,Y as A,Z as j,a as M,bt as N,ct as ee,dt as P,et as F,ft as I,gt as L,ht as R,j as z,jt as B,k as V,kt as H,mt as U,rt as te,tt as ne,ut as re,vt as W,wt as G,xt as ie,yt as ae,z as K}from"./index-NFgJciDY.js";var oe=W(`flask-conical`,[[`path`,{d:`M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2`,key:`18mbvz`}],[`path`,{d:`M6.453 15h11.094`,key:`3shlmq`}],[`path`,{d:`M8.5 2h7`,key:`csnxdl`}]]),q=W(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),se=W(`pin`,[[`path`,{d:`M12 17v5`,key:`bb1du9`}],[`path`,{d:`M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z`,key:`1nkz8b`}]]),ce=W(`wand-sparkles`,[[`path`,{d:`m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72`,key:`ul74o6`}],[`path`,{d:`m14 7 3 3`,key:`1r5n42`}],[`path`,{d:`M5 6v4`,key:`ilb8ba`}],[`path`,{d:`M19 14v4`,key:`blhpug`}],[`path`,{d:`M10 2v2`,key:`7u0qdc`}],[`path`,{d:`M7 8H3`,key:`zfb6yr`}],[`path`,{d:`M21 16h-4`,key:`1cnmox`}],[`path`,{d:`M11 3H9`,key:`1obp7u`}]]),J=e(D(),1),Y=ie(),X=/^[a-z0-9][a-z0-9-]*$/;function le({open:e,mode:t=`add`,initial:r,chainAgents:i,onConfirm:a,onCancel:s}){let[l,d]=(0,J.useState)(``),[f,p]=(0,J.useState)(i[0]??``);(0,J.useEffect)(()=>{e&&(t===`edit`&&r?(d(r.tags.join(`, `)),p(i.includes(r.agent)?r.agent:i[0]??``)):(d(``),p(i[0]??``)))},[e,t,r,i]);let m=l.split(`,`).map(e=>e.trim()).filter(Boolean),h=m.filter(e=>!X.test(e)),g=m.length>0&&h.length===0&&i.includes(f);return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||s()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsxs)(n,{children:[(0,Y.jsx)(z,{children:t===`edit`?`Edit routing rule`:`Add routing rule`}),(0,Y.jsx)(y,{children:t===`edit`?`Update the tags or target agent for this rule.`:`Add a tag-matched routing rule using lowercase kebab-case tags.`})]}),(0,Y.jsxs)(`div`,{className:`py-2 space-y-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Tags`}),(0,Y.jsx)(M,{autoFocus:!0,value:l,onChange:e=>d(e.target.value),placeholder:`frontend, ui`,"aria-label":`Tags`,className:`text-sm font-mono`}),(0,Y.jsxs)(`p`,{className:`text-[11px] text-muted-foreground mt-1`,children:[`Comma-separated. Use lowercase kebab-case like `,(0,Y.jsx)(`code`,{children:`frontend`}),` or `,(0,Y.jsx)(`code`,{children:`api-design`}),`.`]}),h.length>0&&(0,Y.jsxs)(`p`,{className:`text-[11px] text-red-400 mt-1`,children:[`Invalid tag`,h.length===1?``:`s`,`: `,h.join(`, `),`. Tags must use lowercase letters, digits, and hyphens only.`]})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Route to`}),(0,Y.jsx)(`select`,{value:f,onChange:e=>p(e.target.value),"aria-label":`Route to`,className:`w-full h-9 px-2 text-sm rounded-md border border-border bg-background`,children:i.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground mt-1`,children:`Only agents in this profile's chain can be routing targets.`})]})]}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:s,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:()=>a(m,f),disabled:!g,children:t===`edit`?`Save changes`:`Add rule`})]})]})})}var Z=new Set([`sr-architect`,`sr-developer`,`sr-reviewer`,`sr-merge-resolver`]),ue=[`sonnet`,`opus`,`haiku`],de=/^[a-z0-9][a-z0-9-]*$/;function fe({profile:e,onChange:t,footer:n,onValidityChange:i,onSoftWarningsChange:o}){let[c,l]=(0,J.useState)([]),[d,f]=(0,J.useState)(!1),[m,h]=(0,J.useState)(!1),[_,y]=(0,J.useState)(null);(0,J.useEffect)(()=>{let e=!1;return fetch(`${C()}/profiles/catalog`).then(e=>e.ok?e.json():{agents:[]}).then(t=>{e||l(t.agents)}).catch(()=>{e||l([])}),()=>{e=!0}},[]);let x=n=>{let r=JSON.parse(JSON.stringify(e));n(r),t(r)},T=new Set(e.agents.map(e=>e.id)),E=c.filter(e=>!T.has(e.id)),D=(0,J.useMemo)(()=>{let t=[];for(let n of Z)e.agents.some(e=>e.id===n)||t.push(`Missing required baseline agent: ${n}`);let n=e.routing.filter(e=>`default`in e&&e.default===!0);if(n.length>1&&t.push(`Routing may have at most one default rule (found ${n.length})`),n.length===1){let n=e.routing[e.routing.length-1];`default`in n&&n.default===!0||t.push(`The default routing rule must be the last entry`)}for(let n of e.routing)if(e.agents.some(e=>e.id===n.agent)||t.push(`Routing references agent not in the chain: ${n.agent}`),`tags`in n){let e=n.tags.filter(e=>!de.test(e));e.length>0&&t.push(`Routing rule ${n.agent} has invalid tags: ${e.join(`, `)} (use lowercase kebab-case)`)}return t},[e]),O=(0,J.useMemo)(()=>{if(e.routing.length===0)return[];let t=new Set(e.routing.map(e=>e.agent));return e.agents.filter(e=>!Z.has(e.id)&&!t.has(e.id)).map(e=>e.id)},[e]),k=(0,J.useMemo)(()=>e.routing.some(e=>`default`in e&&e.default===!0),[e.routing]);(0,J.useEffect)(()=>{i&&i(D)},[D,i]),(0,J.useEffect)(()=>{o&&o({agentsMissingRouting:O})},[O,o]);let A=e=>{x(t=>{let n={id:e,model:`sonnet`},r=t.agents.findIndex(e=>e.id===`sr-merge-resolver`);r>=0?t.agents.splice(r,0,n):t.agents.push(n)}),f(!1)},j=t=>{let n=e.agents[t];Z.has(n.id)||x(e=>{e.agents.splice(t,1),e.routing=e.routing.filter(e=>e.agent!==n.id)})},N=(t,n)=>{if(t===n)return;let r=e.agents.findIndex(e=>e.id===t),i=e.agents.findIndex(e=>e.id===n);if(r<0||i<0)return;let a=G(e.agents,r,i),o=a.findIndex(e=>e.id===`sr-architect`);if(o>0){let[e]=a.splice(o,1);a.unshift(e)}let s=a.findIndex(e=>e.id===`sr-merge-resolver`);if(s>=0&&s!==a.length-1){let[e]=a.splice(s,1);a.push(e)}x(e=>{e.agents=a})},ee=v(g(r,{activationConstraint:{distance:4}}),g(H,{coordinateGetter:w})),P=e=>{let{active:t,over:n}=e;n&&N(String(t.id),String(n.id))},F=(e,t)=>{x(n=>{n.agents[e].model=t})},I=(e,t)=>{x(n=>{let r={tags:e,agent:t},i=n.routing.findIndex(e=>`default`in e&&e.default===!0);i>=0?n.routing.splice(i,0,r):n.routing.push(r)}),h(!1)},L=()=>{x(e=>{e.routing.some(e=>`default`in e&&e.default===!0)||e.agents.some(e=>e.id===`sr-developer`)&&e.routing.push({default:!0,agent:`sr-developer`})})},R=e=>`default`in e&&e.default===!0,z=(e,t)=>{x(n=>{let r=n.routing[e];r&&(R(r)||(r.agent=t))})},V=(e,t,n)=>{x(r=>{let i=r.routing[e];i&&(R(i)||(i.tags=t,i.agent=n))})},U=e=>{x(t=>{let n=t.routing[e];n&&(R(n)||t.routing.splice(e,1))})},te=(t,n)=>{let r=t+n;if(r<0||r>=e.routing.length)return;let i=e.routing[t],a=e.routing[r];R(i)||R(a)||x(e=>{let[n]=e.routing.splice(t,1);e.routing.splice(r,0,n)})};return(0,Y.jsxs)(`div`,{className:`p-6 space-y-6 max-w-3xl`,children:[(0,Y.jsx)(le,{open:m,mode:`add`,chainAgents:e.agents.map(e=>e.id),onConfirm:I,onCancel:()=>h(!1)}),(0,Y.jsx)(le,{open:_!==null,mode:`edit`,initial:_!==null&&e.routing[_]&&!(`default`in e.routing[_])?{tags:e.routing[_].tags,agent:e.routing[_].agent}:void 0,chainAgents:e.agents.map(e=>e.id),onConfirm:(e,t)=>{_!==null&&(V(_,e,t),y(null))},onCancel:()=>y(null)}),D.length>0&&(0,Y.jsxs)(`div`,{className:`px-3 py-2 text-xs rounded-md border border-yellow-500/30 bg-yellow-500/10 text-yellow-500`,children:[(0,Y.jsxs)(`div`,{className:`font-medium mb-1`,children:[D.length,` validation `,D.length===1?`issue`:`issues`]}),(0,Y.jsx)(`ul`,{className:`list-disc list-inside space-y-0.5`,children:D.map((e,t)=>(0,Y.jsx)(`li`,{children:e},t))})]}),(0,Y.jsxs)(`section`,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Name`}),(0,Y.jsx)(M,{value:e.name,disabled:!0,className:`text-sm`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground mb-1`,children:`Description`}),(0,Y.jsx)(M,{value:e.description??``,onChange:e=>x(t=>{t.description=e.target.value}),className:`text-sm`,placeholder:`What is this profile for?`})]})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2`,children:`Orchestrator`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-3 p-3 rounded-md border border-border`,children:[(0,Y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-mono text-foreground truncate`,children:`/specrails:implement · /specrails:batch-implement`}),(0,Y.jsx)(`div`,{className:`text-[11px] text-muted-foreground mt-0.5`,children:`Top-level model for both commands. batch-implement delegates to implement per feature, so every rail it spawns inherits this profile's agent chain.`})]}),(0,Y.jsx)(he,{value:e.orchestrator.model,onChange:e=>x(t=>{t.orchestrator.model=e})})]})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,Y.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[`Agent chain (`,e.agents.length,`)`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:()=>f(e=>!e),disabled:E.length===0,title:E.length===0?`All catalog agents are already in the chain`:`Add an agent from the catalog`,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add`]})]}),d&&(0,Y.jsxs)(`div`,{className:`mb-2 p-2 rounded-md border border-border bg-muted/30`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-1.5 px-1`,children:[(0,Y.jsxs)(`span`,{className:`text-[11px] text-muted-foreground`,children:[`Pick from catalog (`,E.length,` available)`]}),(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:()=>f(!1),title:`Close`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]}),E.length===0?(0,Y.jsx)(`div`,{className:`px-2 py-3 text-xs text-muted-foreground text-center`,children:`No more agents in the catalog. Add custom agents from the Agents Catalog tab.`}):(0,Y.jsx)(`div`,{className:`space-y-0.5 max-h-64 overflow-auto`,children:E.map(e=>(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>A(e.id),className:`w-full flex items-center justify-between gap-2 px-2 py-1.5 text-left rounded hover:bg-accent transition-colors`,children:[(0,Y.jsx)(`span`,{className:`text-sm font-mono`,children:e.id}),(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded `+(e.kind===`custom`?`bg-purple-500/15 text-purple-400`:`bg-muted text-muted-foreground`),children:e.kind})]},e.id))})]}),(0,Y.jsx)(b,{sensors:ee,collisionDetection:B,onDragEnd:P,children:(0,Y.jsx)(a,{items:e.agents.map(e=>e.id),strategy:s,children:(0,Y.jsx)(`div`,{className:`space-y-1.5`,children:e.agents.map((e,t)=>(0,Y.jsx)(pe,{agent:e,canRemove:!Z.has(e.id),onModel:e=>F(t,e),onRemove:()=>j(t)},e.id))})})})]}),(0,Y.jsxs)(`section`,{children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,Y.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[`Routing (`,e.routing.length,`)`]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1`,children:[!k&&(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:L,disabled:e.agents.length===0,title:e.agents.length===0?`Add at least one agent before creating routing rules`:void 0,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add default`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:()=>h(!0),disabled:e.agents.length===0,title:e.agents.length===0?`Add at least one agent before creating routing rules`:void 0,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1`}),` Add rule`]})]})]}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground mb-2`,children:`First matching rule wins. Rules are editable and removable, and the default catch-all stays last when present. If you leave routing empty, the pipeline falls back to the first developer-shaped agent in the chain.`}),O.length>0&&(0,Y.jsxs)(`div`,{className:`mb-2 px-3 py-2 text-xs rounded-md border border-yellow-500/30 bg-yellow-500/10 text-yellow-500`,children:[(0,Y.jsx)(`div`,{className:`font-medium mb-1`,children:`Untargeted agents in the chain`}),(0,Y.jsxs)(`div`,{children:[`No routing rule points to: `,(0,Y.jsx)(`span`,{className:`font-mono`,children:O.join(`, `)}),`. Add a tag rule or retarget the default rule if you want them to run.`]})]}),(0,Y.jsx)(`div`,{className:`space-y-1.5`,children:e.routing.map((t,n)=>{let r=`default`in t&&t.default===!0;return(0,Y.jsx)(me,{rule:t,ordinal:n+1,isLast:n===e.routing.length-1,canMove:!r,canRemove:!r,canEdit:!r,chainAgents:e.agents.map(e=>e.id),onAgentChange:e=>z(n,e),onEdit:()=>y(n),onUp:()=>te(n,-1),onDown:()=>te(n,1),onRemove:()=>U(n)},n)})})]}),n&&(0,Y.jsx)(`div`,{className:`pt-3 border-t border-border`,children:n})]})}function pe({agent:e,canRemove:n,onModel:r,onRemove:i}){let a=Z.has(e.id),o=e.id===`sr-architect`,s=e.id===`sr-merge-resolver`,{attributes:c,listeners:u,setNodeRef:d,transform:f,transition:p,isDragging:m}=l({id:e.id});return(0,Y.jsxs)(`div`,{ref:d,style:{transform:x.Transform.toString(f),transition:p,opacity:m?.5:void 0,zIndex:m?10:void 0},className:`flex items-center gap-2 px-2 py-1.5 rounded-md border border-border group hover:bg-accent/30 transition-colors bg-background`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`flex-shrink-0 p-0.5 rounded text-muted-foreground cursor-grab active:cursor-grabbing hover:text-foreground`,title:`Drag to reorder`,"aria-label":`Drag handle`,...c,...u,children:(0,Y.jsx)(t,{className:`w-3.5 h-3.5`})}),(0,Y.jsx)(`span`,{className:`text-sm font-mono flex-1 truncate`,children:e.id}),o&&(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-accent-primary/15 text-accent-primary`,title:`Pinned to first position — pipeline always starts with sr-architect`,children:[(0,Y.jsx)(se,{className:`w-2.5 h-2.5 rotate-[135deg]`}),` first`]}),s&&(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-accent-primary/15 text-accent-primary`,title:`Pinned to last position — merge phase always runs last`,children:[(0,Y.jsx)(se,{className:`w-2.5 h-2.5 rotate-45`}),` last`]}),a&&!o&&!s&&(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground`,children:`required`}),(0,Y.jsx)(he,{value:e.model??`sonnet`,onChange:r}),(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded disabled:opacity-30 disabled:cursor-not-allowed opacity-0 group-hover:opacity-100 transition-opacity`,onClick:i,disabled:!n,title:n?`Remove`:`Required baseline agent — the pipeline depends on this row`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]})}function me({rule:e,ordinal:t,isLast:n,canMove:r,canRemove:i,canEdit:a,chainAgents:o,onAgentChange:s,onEdit:c,onUp:l,onDown:u,onRemove:d}){let f=`default`in e&&e.default===!0;return(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-1.5 rounded-md border border-border group hover:bg-accent/30 transition-colors`,children:[(0,Y.jsxs)(`span`,{className:`text-[10px] font-mono text-muted-foreground w-5 text-center flex-shrink-0`,children:[t,`.`]}),f?(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground flex-1`,children:`everything else`}):(0,Y.jsx)(`span`,{className:`text-xs flex-1 flex gap-1 flex-wrap items-center`,children:e.tags.map(e=>(0,Y.jsx)(`span`,{className:`px-1.5 py-0.5 rounded bg-muted font-mono text-[11px]`,children:e},e))}),(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`→`}),f?(0,Y.jsx)(`span`,{className:`h-7 max-w-[15rem] px-2 text-xs font-mono rounded border border-border bg-muted/40 text-muted-foreground inline-flex items-center`,"aria-label":`Default routing target (core, read-only)`,title:`Core fallback — not editable`,children:e.agent}):(0,Y.jsx)(`select`,{value:e.agent,onChange:e=>s(e.target.value),"aria-label":`Routing target for rule ${t}`,className:`h-7 max-w-[15rem] px-2 text-xs font-mono rounded border border-border bg-background`,children:o.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))}),(0,Y.jsxs)(`div`,{className:`flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity`,children:[a&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:c,title:`Edit rule`,"aria-label":`Edit rule ${t}`,children:(0,Y.jsx)(A,{className:`w-3 h-3`})}),r&&!n&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:u,title:`Move down`,children:(0,Y.jsx)(L,{className:`w-3 h-3`})}),r&&t>1&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,onClick:l,title:`Move up`,children:(0,Y.jsx)(U,{className:`w-3 h-3`})}),i&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded`,onClick:d,title:`Remove`,children:(0,Y.jsx)(S,{className:`w-3 h-3`})})]}),f&&(0,Y.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground`,title:`Core fallback — the pipeline's last-resort rule, pinned to sr-developer`,children:`core · default`})]})}function he({value:e,onChange:t}){return(0,Y.jsx)(`select`,{value:e,onChange:e=>t(e.target.value),className:`h-7 px-2 text-xs rounded border border-border bg-background`,children:ue.map(e=>(0,Y.jsx)(`option`,{value:e,children:e},e))})}function ge({open:e,title:t,description:r,placeholder:i,initialValue:a=``,confirmLabel:s=`Confirm`,inputPattern:l,inputInvalidHint:d,onConfirm:f,onCancel:p}){let[m,h]=(0,J.useState)(a);(0,J.useEffect)(()=>{e&&h(a)},[e,a]);let g=m.trim(),_=!l||l.test(g),v=g.length>0&&_;return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||p()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsx)(n,{children:(0,Y.jsx)(z,{children:t})}),(0,Y.jsxs)(`div`,{className:`py-2 space-y-2`,children:[r&&(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r}),(0,Y.jsx)(M,{autoFocus:!0,value:m,placeholder:i,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Enter`&&v&&f(g)},className:`text-sm font-mono`}),g.length>0&&!_&&d&&(0,Y.jsx)(`p`,{className:`text-[11px] text-yellow-500`,children:d})]}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:p,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:()=>f(g),disabled:!v,children:s})]})]})})}function _e({open:e,title:t,description:r,confirmLabel:i=`Confirm`,destructive:a=!1,onConfirm:s,onCancel:l}){return(0,Y.jsx)(c,{open:e,onOpenChange:e=>{e||l()},children:(0,Y.jsxs)(o,{className:`max-w-md`,children:[(0,Y.jsx)(n,{children:(0,Y.jsx)(z,{children:t})}),r&&(0,Y.jsx)(`div`,{className:`py-2`,children:(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r})}),(0,Y.jsxs)(V,{children:[(0,Y.jsx)(u,{variant:`ghost`,size:`sm`,onClick:l,children:`Cancel`}),(0,Y.jsx)(u,{size:`sm`,onClick:s,className:a?`bg-red-500 hover:bg-red-600 text-white`:void 0,children:i})]})]})})}function ve(){let[e,t]=(0,J.useState)([]),[n,r]=(0,J.useState)(null),[a,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(!0),[l,f]=(0,J.useState)(null),[m,h]=(0,J.useState)(!1),[g,_]=(0,J.useState)([]),[v,y]=(0,J.useState)([]),[b,x]=(0,J.useState)(!1),[S,w]=(0,J.useState)(null),[T,E]=(0,J.useState)(null),D=(0,J.useCallback)(async()=>{c(!0),f(null);try{let e=await fetch(`${C()}/profiles`);if(!e.ok)throw Error(`List failed: ${e.status}`);let i=await e.json();t(i.profiles),i.profiles.length>0&&!n&&r(i.profiles[0].name)}catch(e){f(e.message)}finally{c(!1)}},[n]);(0,J.useEffect)(()=>{D()},[D]),(0,J.useEffect)(()=>{if(!n){o(null);return}let e=!1;return fetch(`${C()}/profiles/${encodeURIComponent(n)}`).then(e=>{if(!e.ok)throw Error(`Load failed: ${e.status}`);return e.json()}).then(t=>{e||o(t.profile)}).catch(t=>{e||f(t.message)}),()=>{e=!0}},[n]);let k=(0,J.useCallback)(async()=>{h(!0),f(null);try{let e=await fetch(`${C()}/profiles/migrate-from-settings`,{method:`POST`});if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t.error??`Migration failed: ${e.status}`)}await D(),r(`default`),d.success(`Profile migrated`,{description:`default profile created from your current agents`})}catch(e){let t=e.message;f(t),d.error(`Migration failed`,{description:t})}finally{h(!1)}},[D]),A=(0,J.useCallback)(async e=>{x(!1),h(!0),f(null);try{let t={schemaVersion:1,name:e,description:``,orchestrator:{model:`sonnet`},agents:[{id:`sr-architect`,model:`sonnet`,required:!0},{id:`sr-developer`,model:`sonnet`,required:!0},{id:`sr-reviewer`,model:`sonnet`,required:!0},{id:`sr-merge-resolver`,model:`sonnet`,required:!0}],routing:[{default:!0,agent:`sr-developer`}]},n=await fetch(`${C()}/profiles`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Create failed: ${n.status}`)}await D(),r(e),d.success(`Profile created`,{description:e})}catch(e){let t=e.message;f(t),d.error(`Failed to create profile`,{description:t})}finally{h(!1)}},[D]),j=(0,J.useCallback)(async(e,t)=>{w(null),h(!0),f(null);try{let n=await fetch(`${C()}/profiles/${encodeURIComponent(e)}/duplicate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Duplicate failed: ${n.status}`)}await D(),r(t),d.success(`Profile duplicated`,{description:`${e} → ${t}`})}catch(e){let t=e.message;f(t),d.error(`Failed to duplicate profile`,{description:t})}finally{h(!1)}},[D]),M=(0,J.useCallback)(async e=>{E(null),h(!0),f(null);try{let t=await fetch(`${C()}/profiles/${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`Delete failed: ${t.status}`)}r(t=>t===e?null:t),await D(),d.success(`Profile deleted`,{description:e})}catch(e){let t=e.message;f(t),d.error(`Failed to delete profile`,{description:t})}finally{h(!1)}},[D]),N=(0,J.useCallback)(()=>x(!0),[]),ee=(0,J.useCallback)(e=>w({from:e}),[]),P=(0,J.useCallback)(e=>E({name:e}),[]),F=(0,J.useCallback)(async(e,t)=>{h(!0),f(null);try{let n=await fetch(`${C()}/profiles/${encodeURIComponent(e.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Save failed: ${n.status}`)}o(e),t.length>0?d.warning(`Profile saved with untargeted agents`,{description:`No routing rule points to: ${t.join(`, `)}. Add a tag rule or retarget the default rule if you want them to run.`,duration:6e3}):d.success(`Profile saved`,{description:e.name})}catch(e){let t=e.message;f(t),d.error(`Failed to save profile`,{description:t})}finally{h(!1)}},[]),I=(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(ge,{open:b,title:`New profile`,description:`Pick a lowercase kebab-case name (letters, digits, and hyphens).`,placeholder:`my-profile`,confirmLabel:`Create`,inputPattern:/^[a-z0-9][a-z0-9-]*$/,inputInvalidHint:`Must start with a letter or digit and contain only lowercase letters, digits, and hyphens.`,onConfirm:e=>void A(e),onCancel:()=>x(!1)}),S&&(0,Y.jsx)(ge,{open:!0,title:`Duplicate "${S.from}"`,description:`Name for the new profile.`,placeholder:`${S.from}-copy`,initialValue:`${S.from}-copy`,confirmLabel:`Duplicate`,inputPattern:/^[a-z0-9][a-z0-9-]*$/,inputInvalidHint:`Lowercase kebab-case only.`,onConfirm:e=>void j(S.from,e),onCancel:()=>w(null)}),T&&(0,Y.jsx)(_e,{open:!0,title:`Delete profile "${T.name}"?`,description:`This cannot be undone. Jobs already launched with this profile keep their snapshot; future launches will fall back to the resolution order.`,confirmLabel:`Delete`,destructive:!0,onConfirm:()=>void M(T.name),onCancel:()=>E(null)})]});return s?(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Loading profiles…`})}):e.length===0?(0,Y.jsxs)(Y.Fragment,{children:[I,(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsxs)(`div`,{className:`text-center max-w-md`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-foreground`,children:`No profiles yet`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground mt-1 mb-4`,children:`Profiles let you save orchestrator + agent + routing combinations and pick one per rail.`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 justify-center`,children:[(0,Y.jsxs)(u,{size:`sm`,onClick:k,disabled:m,children:[(0,Y.jsx)(ce,{className:`w-3.5 h-3.5 mr-1.5`}),` Migrate from current agents`]}),(0,Y.jsxs)(u,{size:`sm`,variant:`ghost`,onClick:N,disabled:m,children:[(0,Y.jsx)(p,{className:`w-3.5 h-3.5 mr-1.5`}),` Blank profile`]})]}),(0,Y.jsxs)(`div`,{className:`text-[11px] text-muted-foreground/70 mt-3`,children:[`"Migrate" reads your existing `,(0,Y.jsx)(`code`,{className:`text-foreground`,children:`.claude/agents/`}),` `,`frontmatter models and creates a `,(0,Y.jsx)(`code`,{className:`text-foreground`,children:`default`}),` profile mirroring today's behavior — zero-loss.`]}),l&&(0,Y.jsx)(`div`,{className:`mt-3 text-xs text-red-400`,children:l})]})})]}):(0,Y.jsxs)(`div`,{className:`flex flex-col h-full`,children:[I,(0,Y.jsxs)(`div`,{className:`flex flex-1 min-h-0`,children:[(0,Y.jsxs)(`aside`,{className:`w-64 flex-shrink-0 border-r border-border flex flex-col`,children:[(0,Y.jsxs)(`div`,{className:`p-3 flex items-center justify-between`,children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:`Profiles`}),(0,Y.jsx)(u,{size:`sm`,variant:`ghost`,onClick:N,disabled:m,children:(0,Y.jsx)(p,{className:`w-3.5 h-3.5`})})]}),(0,Y.jsx)(`div`,{className:`flex-1 overflow-auto px-2 pb-3`,children:e.map(e=>(0,Y.jsxs)(`div`,{className:`group mb-1 rounded-md px-2 py-1.5 text-xs cursor-pointer transition-colors flex items-center justify-between `+(e.name===n?`bg-accent text-foreground`:`text-muted-foreground hover:bg-accent/50 hover:text-foreground`),onClick:()=>r(e.name),role:`button`,tabIndex:0,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&r(e.name)},children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 min-w-0`,children:[(0,Y.jsx)(`span`,{className:`truncate font-medium`,children:e.name}),e.isDefault&&(0,Y.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`(team default)`})]}),(0,Y.jsxs)(`div`,{className:`flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-accent rounded`,title:`Duplicate`,onClick:t=>{t.stopPropagation(),ee(e.name)},children:(0,Y.jsx)(te,{className:`w-3 h-3`})}),!e.isDefault&&(0,Y.jsx)(`button`,{type:`button`,className:`p-1 hover:bg-red-500/20 text-red-400 rounded`,title:`Delete`,onClick:t=>{t.stopPropagation(),P(e.name)},children:(0,Y.jsx)(i,{className:`w-3 h-3`})})]})]},e.name))})]}),(0,Y.jsxs)(`main`,{className:`flex-1 overflow-auto`,children:[l&&(0,Y.jsx)(`div`,{className:`mx-4 mt-4 px-3 py-2 text-xs rounded border border-red-500/30 bg-red-500/10 text-red-400`,children:l}),a?(0,Y.jsx)(fe,{profile:a,onChange:o,onValidityChange:_,onSoftWarningsChange:e=>y(e.agentsMissingRouting),footer:(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsxs)(u,{size:`sm`,onClick:()=>void F(a,v),disabled:m||g.length>0,title:g.length>0?`Fix validation issues before saving`:void 0,children:[(0,Y.jsx)(O,{className:`w-3.5 h-3.5 mr-1.5`}),`Save`]}),m&&(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Saving…`}),g.length>0&&(0,Y.jsxs)(`span`,{className:`text-xs text-yellow-500`,children:[g.length,` `,g.length===1?`issue`:`issues`,` to resolve`]})]})},a.name):(0,Y.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Select a profile to edit`})})]})]})]})}function Q(e){let t=e.workflow.map((e,t)=>`${t+1}. ${e}`).join(`
|
|
2
2
|
`);return`---
|
|
3
3
|
name: ${e.id}
|
|
4
4
|
description: "${e.descriptionOneLine}"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{t}from"./clsx-fiJc2n10.js";import{K as n,St as r,Vt as i,bt as a,o,s,vt as c,xt as l,yt as u,zt as d}from"./index-BC3icgTz.js";import{t as f}from"./ExportDropdown-XowR3m8-.js";import{A as p,B as m,C as h,D as g,E as _,F as v,G as y,H as b,I as x,J as S,K as C,L as w,M as T,N as E,O as D,P as O,Q as k,R as A,S as j,T as ee,V as M,X as N,Z as P,_ as te,_t as ne,a as F,at as re,b as ie,c as ae,ct as oe,et as se,f as ce,g as le,gt as I,h as ue,i as L,j as de,k as fe,l as R,lt as z,m as pe,n as me,nt as B,o as he,ot as ge,p as _e,pt as V,q as H,r as U,rt as W,s as ve,st as ye,t as be,tt as xe,ut as G,v as Se,x as Ce,y as we,z as Te}from"./BarChart-erGMYSLM.js";var Ee=c(`arrow-down-right`,[[`path`,{d:`m7 7 10 10`,key:`1fmybs`}],[`path`,{d:`M17 7v10H7`,key:`6fjiku`}]]),De=c(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),K=e(i(),1),q=l();function Oe(e){return e>=100?`$${e.toFixed(0)}`:e>=10?`$${e.toFixed(1)}`:`$${e.toFixed(2)}`}function ke(e){return e>=1e3?`$${(e/1e3).toFixed(1)}k`:`$${e.toFixed(2)}`}var Ae=[`job`,`explore-spec`,`quick-spec`,`ai-edit`,`smash`];function je({data:e,loading:t}){let[n,r]=(0,K.useState)(0),i=(0,K.useRef)(0);if((0,K.useEffect)(()=>{if(!e)return;let t=e.summary.totalCostUsd;if(i.current===0&&t>0){let e=performance.now(),n=i=>{let a=Math.min(1,(i-e)/600),o=1-(1-a)**3;r(0+(t-0)*o),a<1&&requestAnimationFrame(n)};requestAnimationFrame(n)}else r(t);i.current=t},[e]),t&&!e)return(0,q.jsx)(`div`,{className:`h-44 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let a=e.summary.totalCostUsd,c=e.summary.totalRuns,l=e.summary.deltaPct,u=e.trackingStartedAt,d=Ae.map(t=>{let n=e.bySurface.find(e=>e.surface===t);return{surface:t,costUsd:n?.costUsd??0,count:n?.count??0}});return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-gradient-to-br from-card/80 to-card/40 p-5`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-end justify-between gap-3 mb-4`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-[11px] uppercase tracking-wider text-muted-foreground mb-1`,children:`Spending`}),(0,q.jsxs)(`div`,{className:`flex items-baseline gap-3`,children:[(0,q.jsx)(`div`,{className:`text-5xl font-semibold tabular-nums tracking-tight`,children:ke(n)}),l!==null&&(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 text-xs font-medium ${l>=0?`text-accent-warning`:`text-accent-success`}`,children:[l>=0?(0,q.jsx)(De,{className:`w-3 h-3`}):(0,q.jsx)(Ee,{className:`w-3 h-3`}),Math.abs(l).toFixed(0),`% vs prev`]})]}),(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-1 tabular-nums`,children:[c,` invocation`,c===1?``:`s`]})]}),c===0&&u&&(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Tracking started `,u.slice(0,10)]})]}),c===0?(0,q.jsxs)(`div`,{className:`rounded-lg border border-dashed border-border/40 p-6 text-center`,children:[(0,q.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No invocations yet for this filter window.`}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground/70 mt-1`,children:[`Tracking started `,u?u.slice(0,10):`on first invocation`]})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{className:`h-3 w-full rounded-full overflow-hidden bg-background-deep flex`,children:d.map(e=>{let t=a>0?e.costUsd/a*100:0;return t===0?null:(0,q.jsx)(`div`,{className:`h-full ${o[e.surface].dot}`,style:{width:`${t}%`},title:`${s[e.surface]}: ${Oe(e.costUsd)}`},e.surface)})}),(0,q.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-x-5 gap-y-1.5 text-xs`,children:d.filter(e=>e.costUsd>0).map(e=>(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 tabular-nums`,children:[(0,q.jsx)(`span`,{className:`w-2 h-2 rounded-full ${o[e.surface].dot}`}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:s[e.surface]}),(0,q.jsx)(`span`,{className:`text-foreground font-medium`,children:Oe(e.costUsd)}),(0,q.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,q.jsx)(`span`,{className:`text-muted-foreground/80`,children:e.count})]},e.surface))})]})]})}var Me=[`option`,`isActive`];function J(){return J=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},J.apply(null,arguments)}function Ne(e,t){if(e==null)return{};var n,r,i=Pe(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Pe(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Fe(e){var{option:t,isActive:n}=e,r=Ne(e,Me);return typeof t==`string`?K.createElement(j,J({option:K.createElement(ye,J({type:t},r)),isActive:n,shapeType:`symbols`},r)):K.createElement(j,J({option:t,isActive:n,shapeType:`symbols`},r))}var Ie=se([(e,t,n,r,i,a,o)=>A(e,void 0,void 0,o),(e,t,n,r,i,a,o)=>E(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>O(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>E(e,`yAxis`,n,o),(e,t,n,r,i,a,o)=>O(e,`yAxis`,n,o),(e,t,n,r)=>x(e,`zAxis`,r,!1),se([v,(e,t,n,r,i)=>i],(e,t)=>e.filter(e=>e.type===`scatter`).find(e=>e.id===t)),(e,t,n,r,i,a)=>a],(e,t,n,r,i,a,o,s)=>{var{chartData:c,dataStartIndex:l,dataEndIndex:u}=e;if(o!=null){var d=o?.data!=null&&o.data.length>0?o.data:c?.slice(l,u+1);if(!(d==null||t==null||r==null||n==null||i==null||n?.length===0||i?.length===0))return Ze({displayedData:d,xAxis:t,yAxis:r,zAxis:a,scatterSettings:o,xAxisTicks:n,yAxisTicks:i,cells:s})}}),Le=[`id`],Re=[`onMouseEnter`,`onClick`,`onMouseLeave`],ze=[`animationBegin`,`animationDuration`,`animationEasing`,`hide`,`isAnimationActive`,`legendType`,`lineJointType`,`lineType`,`shape`,`xAxisId`,`yAxisId`,`zAxisId`];function Y(e,t){if(e==null)return{};var n,r,i=Be(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Be(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function X(){return X=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},X.apply(null,arguments)}function Ve(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Z(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Ve(Object(n),!0).forEach(function(t){He(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ve(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function He(e,t,n){return(t=Ue(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ue(e){var t=We(e,`string`);return typeof t==`symbol`?t:t+``}function We(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var Ge=e=>{var{dataKey:t,name:n,fill:r,legendType:i,hide:a}=e;return[{inactive:a,dataKey:t,type:i,color:r,value:P(n,t),payload:e}]},Ke=K.memo(e=>{var{dataKey:t,points:n,stroke:r,strokeWidth:i,fill:a,name:o,hide:s,tooltipType:c,id:l}=e,u={dataDefinedOnItem:n?.map(e=>e.tooltipPayload),getPosition:e=>{var t;return n==null||(t=n[Number(e)])==null?void 0:t.tooltipPosition},settings:{stroke:r,strokeWidth:i,fill:a,nameKey:void 0,dataKey:t,name:P(o,t),hide:s,type:c,color:a,unit:``,graphicalItemId:l}};return K.createElement(Se,{tooltipEntrySettings:u})});function qe(e){var{points:t,props:n}=e,{line:r,lineType:i,lineJointType:a}=n;if(!r)return null;var o=I(n),s=ne(r),c,l;if(i===`joint`)c=t.map(e=>({x:e.cx??null,y:e.cy??null}));else if(i===`fitting`){var{xmin:u,xmax:d,a:f,b:p}=oe(t),m=e=>f*e+p;c=[{x:u,y:m(u)},{x:d,y:m(d)}]}var h=Z(Z(Z({},o),{},{fill:`none`,stroke:o&&o.fill},s),{},{points:c});return l=K.isValidElement(r)?K.cloneElement(r,h):typeof r==`function`?r(h):K.createElement(M,X({},h,{type:a})),K.createElement(V,{className:`recharts-scatter-line`,key:`recharts-scatter-line`},l)}function Je(e){var{showLabels:t,points:n,children:r}=e,i=y(),a=(0,K.useMemo)(()=>n?.map(e=>{var t={x:e.x??0,y:e.y??0,width:e.width,height:e.height,lowerWidth:e.width,upperWidth:e.width};return Z(Z({},t),{},{value:void 0,payload:e.payload,viewBox:t,parentViewBox:i,fill:void 0})}),[i,n]);return K.createElement(ee,{value:t?a:void 0},r)}function Ye(e){var{points:t,allOtherScatterProps:n}=e,{shape:r,activeShape:i,dataKey:a}=n,{id:o}=n,s=Y(n,Le),c=B(de),{onMouseEnter:l,onClick:u,onMouseLeave:d}=n,f=Y(n,Re),m=ie(l,a,o),h=Ce(d),g=we(u,a,o);if(!ge(t))return null;var _=I(s);return K.createElement(K.Fragment,null,K.createElement(qe,{points:t,props:s}),t.map((e,t)=>{var n=i!=null&&i!==!1,a=n&&c===String(t),s=n&&a?i:r,l=Z(Z(Z({},_),e),{},{index:t,[S]:String(o)});return K.createElement(p,{key:`symbol-${e?.cx}-${e?.cy}-${e?.size}-${t}`,zIndex:a?w.activeDot:void 0},K.createElement(V,X({className:`recharts-scatter-symbol`},re(f,e,t),{onMouseEnter:m(e,t),onMouseLeave:h(e,t),onClick:g(e,t)}),K.createElement(Fe,X({option:s,isActive:a},l))))}))}function Xe(e){var{previousPointsRef:t,props:n}=e,{points:r,isAnimationActive:i,animationBegin:a,animationDuration:o,animationEasing:s}=n,c=t.current,l=Te(n,`recharts-scatter-`),[u,d]=(0,K.useState)(!1),f=(0,K.useCallback)(()=>{d(!1)},[]),p=(0,K.useCallback)(()=>{d(!0)},[]),h=!u;return K.createElement(Je,{showLabels:h,points:r},n.children,K.createElement(m,{animationId:l,begin:a,duration:o,isActive:i,easing:s,onAnimationEnd:f,onAnimationStart:p,key:l},e=>{var i=e===1?r:r?.map((t,n)=>{var r=c&&c[n];return r?Z(Z({},t),{},{cx:t.cx==null?void 0:z(r.cx,t.cx,e),cy:t.cy==null?void 0:z(r.cy,t.cy,e),size:z(r.size,t.size,e)}):Z(Z({},t),{},{size:z(0,t.size,e)})});return e>0&&(t.current=i),K.createElement(V,null,K.createElement(Ye,{points:i,allOtherScatterProps:n,showLabels:h}))}),K.createElement(_,{label:n.label}))}function Ze(e){var{displayedData:t,xAxis:n,yAxis:r,zAxis:i,scatterSettings:a,xAxisTicks:o,yAxisTicks:s,cells:c}=e,l=G(n.dataKey)?a.dataKey:n.dataKey,u=G(r.dataKey)?a.dataKey:r.dataKey,d=i&&i.dataKey,f=i?i.range:T.range,p=f&&f[0],m=n.scale.bandwidth?n.scale.bandwidth():0,h=r.scale.bandwidth?r.scale.bandwidth():0;return t.map((e,t)=>{var f=k(e,l),g=k(e,u),_=!G(d)&&k(e,d)||`-`,v=[{name:G(n.dataKey)?a.name:n.name||String(n.dataKey),unit:n.unit||``,value:f,payload:e,dataKey:l,type:a.tooltipType,graphicalItemId:a.id},{name:G(r.dataKey)?a.name:r.name||String(r.dataKey),unit:r.unit||``,value:g,payload:e,dataKey:u,type:a.tooltipType,graphicalItemId:a.id}];_!==`-`&&i!=null&&v.push({name:i.name||i.dataKey,unit:i.unit||``,value:_,payload:e,dataKey:d,type:a.tooltipType,graphicalItemId:a.id});var y=N({axis:n,ticks:o,bandSize:m,entry:e,index:t,dataKey:l}),b=N({axis:r,ticks:s,bandSize:h,entry:e,index:t,dataKey:u}),x=_!==`-`&&i!=null?i.scale.map(_):p,S=x==null?0:Math.sqrt(Math.max(x,0)/Math.PI);return Z(Z({},e),{},{cx:y,cy:b,x:y==null?void 0:y-S,y:b==null?void 0:b-S,width:2*S,height:2*S,size:x,node:{x:f,y:g,z:_},tooltipPayload:v,tooltipPosition:{x:y,y:b},payload:e},c&&c[t]&&c[t].props)})}var Qe=(e,t,n)=>({x:e.cx,y:e.cy,value:Number(n===`x`?e.node.x:e.node.y),errorVal:k(e,t)});function $e(e){var{hide:n,points:r,className:i,needClip:a,xAxisId:o,yAxisId:s,id:c}=e,l=(0,K.useRef)(null);if(n)return null;var u=t(`recharts-scatter`,i),d=c;return K.createElement(p,{zIndex:e.zIndex},K.createElement(V,{className:u,clipPath:a?`url(#clipPath-${d})`:void 0,id:c},a&&K.createElement(`defs`,null,K.createElement(he,{clipPathId:d,xAxisId:o,yAxisId:s})),K.createElement(ae,{xAxisId:o,yAxisId:s,data:r,dataPointFormatter:Qe,errorBarOffset:0},K.createElement(V,{key:`recharts-scatter-symbols`},K.createElement(Xe,{props:e,previousPointsRef:l})))))}var et={xAxisId:0,yAxisId:0,zAxisId:0,label:!1,line:!1,legendType:`circle`,lineType:`joint`,lineJointType:`linear`,shape:`circle`,hide:!1,isAnimationActive:`auto`,animationBegin:0,animationDuration:400,animationEasing:`linear`,zIndex:w.scatter};function tt(e){var t=W(e,et),{animationBegin:n,animationDuration:r,animationEasing:i,hide:a,isAnimationActive:o,legendType:s,lineJointType:c,lineType:l,shape:u,xAxisId:d,yAxisId:f,zAxisId:p}=t,m=Y(t,ze),{needClip:_}=ve(d,f),v=(0,K.useMemo)(()=>h(e.children,g),[e.children]),y=H(),b=B(t=>Ie(t,d,f,p,e.id,v,y));return _==null||b==null?null:K.createElement(K.Fragment,null,K.createElement(Ke,{dataKey:e.dataKey,points:b,stroke:e.stroke,strokeWidth:e.strokeWidth,fill:e.fill,name:e.name,hide:e.hide,tooltipType:e.tooltipType,id:e.id}),K.createElement($e,X({},m,{xAxisId:d,yAxisId:f,zAxisId:p,lineType:l,lineJointType:c,legendType:s,shape:u,hide:a,isAnimationActive:o,animationBegin:n,animationDuration:r,animationEasing:i,points:b,needClip:_})))}function nt(e){var t=W(e,et),n=H();return K.createElement(le,{id:t.id,type:`scatter`},e=>K.createElement(K.Fragment,null,K.createElement(te,{legendPayload:Ge(t)}),K.createElement(ue,{type:`scatter`,id:e,data:t.data,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:t.zAxisId,dataKey:t.dataKey,hide:t.hide,name:t.name,tooltipType:t.tooltipType,isPanorama:n}),K.createElement(tt,X({},t,{id:e}))))}var rt=K.memo(nt,b);rt.displayName=`Scatter`;function it(e){var t=xe(),n=(0,K.useRef)(null);return(0,K.useLayoutEffect)(()=>{n.current===null?t(ce(e)):n.current!==e&&t(pe({prev:n.current,next:e})),n.current=e},[e,t]),(0,K.useLayoutEffect)(()=>()=>{n.current&&=(t(_e(n.current)),null)},[t]),null}var at={zAxisId:0,range:T.range,scale:T.scale,type:T.type};function Q(e){var t=W(e,at);return K.createElement(it,{domain:t.domain,id:t.zAxisId,dataKey:t.dataKey,name:t.name,unit:t.unit,range:t.range,scale:t.scale,type:t.type,allowDuplicatedCategory:T.allowDuplicatedCategory,allowDataOverflow:T.allowDataOverflow,reversed:T.reversed,includeHidden:T.includeHidden})}Q.displayName=`ZAxis`;var ot=[`item`],st=(0,K.forwardRef)((e,t)=>K.createElement(me,{chartName:`ScatterChart`,defaultTooltipEventType:`item`,validateTooltipEventTypes:ot,tooltipPayloadSearcher:fe,categoricalChartProps:e,ref:t}));function ct({data:e,loading:t}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let n=e.dailyTimeline.map(e=>({date:e.date.slice(5),Jobs:e.jobsCostUsd,Explore:e.exploreCostUsd,Quick:e.quickCostUsd,Refine:e.aiEditCostUsd})),r=n.every(e=>e.Jobs+e.Explore+e.Quick+e.Refine===0);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Daily timeline`}),(0,q.jsx)(`span`,{className:`text-[10px] text-muted-foreground/70`,children:`stacked by surface`})]}),r?(0,q.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No spend in this period.`}):(0,q.jsx)(`div`,{className:`h-[220px]`,children:(0,q.jsx)(C,{width:`100%`,height:`100%`,children:(0,q.jsxs)(be,{data:n,margin:{top:10,right:10,left:-8,bottom:0},children:[(0,q.jsx)(R,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`,vertical:!1}),(0,q.jsx)(L,{dataKey:`date`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`}),(0,q.jsx)(U,{tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e}`}),(0,q.jsx)(D,{contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>[`$${typeof e==`number`?e.toFixed(2):`—`}`,String(t)]}),(0,q.jsx)(F,{dataKey:`Jobs`,stackId:`a`,fill:`var(--accent-info, #5fa8d3)`}),(0,q.jsx)(F,{dataKey:`Explore`,stackId:`a`,fill:`var(--accent-highlight, #c084fc)`}),(0,q.jsx)(F,{dataKey:`Quick`,stackId:`a`,fill:`var(--accent-secondary, #f7768e)`}),(0,q.jsx)(F,{dataKey:`Refine`,stackId:`a`,fill:`var(--accent-success, #50fa7b)`})]})})})]})}function lt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:e<1?`$${e.toFixed(3)}`:`$${e.toFixed(2)}`}function ut(e){return e==null?`—`:e<1e3?`${e} ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}function dt({values:e}){let t=Math.max(1e-4,...e);return(0,q.jsx)(`div`,{className:`flex items-end gap-[1px] h-5`,children:e.map((e,n)=>(0,q.jsx)(`div`,{className:`w-[3px] rounded-sm bg-foreground/40`,style:{height:`${Math.max(2,e/t*20)}px`}},n))})}function ft({mode:e,label:t,accentClass:n}){let r=e.mode===`explore`&&e.totalRuns<5;return(0,q.jsxs)(`div`,{className:`flex-1 p-4 first:pr-2 last:pl-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${n}`}),(0,q.jsx)(`span`,{className:`text-xs font-medium uppercase tracking-wider text-muted-foreground`,children:t})]}),r?(0,q.jsxs)(`div`,{className:`py-3`,children:[(0,q.jsx)(`p`,{className:`text-sm text-foreground`,children:`Try Explore for richer specs`}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:[e.totalRuns,` run`,e.totalRuns===1?``:`s`,` so far`]})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{className:`text-3xl font-semibold tabular-nums tracking-tight`,children:lt(e.avgCostPerSpec)}),(0,q.jsx)(`div`,{className:`text-[11px] text-muted-foreground mt-0.5`,children:`per spec`}),(0,q.jsx)(`div`,{className:`mt-3`,children:(0,q.jsx)(dt,{values:e.sparkline.length>0?e.sparkline:[0]})}),(0,q.jsxs)(`div`,{className:`mt-3 space-y-0.5 text-xs tabular-nums text-muted-foreground`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`span`,{className:`text-foreground font-medium`,children:e.ticketsCreated}),` created · `,e.totalRuns,` runs`]}),(0,q.jsxs)(`div`,{children:[ut(e.avgDurationMs),` avg`]}),(0,q.jsx)(`div`,{className:`truncate`,children:e.dominantModel??`—`})]})]})]})}function pt({data:e,loading:t}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let n=e.byMode.find(e=>e.mode===`quick`),r=e.byMode.find(e=>e.mode===`explore`);if(!n||!r)return null;let i=n.avgCostPerSpec&&r.avgCostPerSpec&&n.avgCostPerSpec>0?r.avgCostPerSpec/n.avgCostPerSpec:null,a=i!==null&&n.totalRuns>=1&&r.totalRuns>=5;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40`,children:[(0,q.jsx)(`div`,{className:`px-4 pt-3 pb-1`,children:(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Quick vs Explore`})}),(0,q.jsxs)(`div`,{className:`flex divide-x divide-border/40`,children:[(0,q.jsx)(ft,{mode:n,label:`Quick`,accentClass:`bg-accent-secondary`}),(0,q.jsx)(ft,{mode:r,label:`Explore`,accentClass:`bg-accent-highlight`})]}),a&&(0,q.jsx)(`div`,{className:`px-4 pb-3 -mt-1`,children:(0,q.jsx)(`div`,{className:`text-center text-[11px] text-muted-foreground tabular-nums`,children:(0,q.jsxs)(`span`,{className:`px-2`,children:[`━━━━━━ `,i.toFixed(1),`× more per spec ━━━━━━`]})})})]})}function mt({data:e,loading:t,onSelectModel:n,activeModel:r}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let i=e.byModel.reduce((e,t)=>e+t.costUsd,0),a=e.byModel.slice(0,5);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:`Models`}),a.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No models recorded.`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:a.map(e=>{let t=i>0?e.costUsd/i*100:0,a=r===e.model;return(0,q.jsx)(`li`,{children:(0,q.jsxs)(`button`,{type:`button`,onClick:()=>n(e.model),className:`w-full text-left group rounded-md px-2 py-1.5 transition-colors ${a?`bg-accent-highlight/10 ring-1 ring-accent-highlight/30`:`hover:bg-accent/30`}`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between text-[12px] mb-1 tabular-nums`,children:[(0,q.jsx)(`span`,{className:`truncate font-medium`,children:e.model}),(0,q.jsxs)(`span`,{className:`text-muted-foreground`,children:[`$`,e.costUsd.toFixed(2),` · `,e.count]})]}),(0,q.jsx)(`div`,{className:`h-1.5 rounded-full bg-background-deep overflow-hidden`,children:(0,q.jsx)(`div`,{className:`h-full ${a?`bg-accent-highlight`:`bg-foreground/40 group-hover:bg-foreground/60`} transition-colors`,style:{width:`${t}%`}})})]})},e.model)})})]})}var ht={job:`var(--accent-info, #5fa8d3)`,"quick-spec":`var(--accent-secondary, #f7768e)`,"explore-spec":`var(--accent-highlight, #c084fc)`,"ai-edit":`var(--accent-success, #50fa7b)`,smash:`var(--accent-highlight, #c084fc)`};function gt({data:e,loading:t,onSelectPoint:n}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[260px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let r=[`job`,`quick-spec`,`explore-spec`,`ai-edit`,`smash`],i=r.map(t=>({surface:t,points:e.scatter.filter(e=>e.surface===t).map(e=>({id:e.id,x:e.numTurns??Math.round((e.durationMs??0)/1e3),y:e.costUsd,surface:t,ticketId:e.ticketId,startedAt:e.startedAt,raw:e}))})),a=e.scatter.length===0;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Cost vs Turns`}),(0,q.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 text-[10px]`,children:r.map(e=>(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full`,style:{background:ht[e]}}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:s[e]})]},e))})]}),a?(0,q.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No invocations to plot.`}):(0,q.jsx)(`div`,{className:`h-[260px]`,children:(0,q.jsx)(C,{width:`100%`,height:`100%`,children:(0,q.jsxs)(st,{margin:{top:10,right:10,left:-8,bottom:5},children:[(0,q.jsx)(R,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`}),(0,q.jsx)(L,{type:`number`,dataKey:`x`,name:`turns`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,label:{value:`turns`,position:`insideBottomRight`,offset:-2,fontSize:10,fill:`currentColor`}}),(0,q.jsx)(U,{type:`number`,dataKey:`y`,name:`cost`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e.toFixed(e<1?2:0)}`}),(0,q.jsx)(Q,{range:[40,80]}),(0,q.jsx)(D,{cursor:{strokeDasharray:`3 3`},contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>{let n=String(t);return n===`cost`&&typeof e==`number`?[`$${e.toFixed(3)}`,`cost`]:[String(e),n]}}),i.map(e=>(0,q.jsx)(rt,{data:e.points,fill:ht[e.surface],onClick:e=>{let t=e;t?.raw&&n(t.raw)}},e.surface))]})})})]})}function _t({data:e,loading:t,onSelectTicket:n}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-40 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let r=e.topTickets;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:`Top tickets`}),r.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No ticket activity in this period.`}):(0,q.jsx)(`ul`,{className:`divide-y divide-border/30`,children:r.map((e,t)=>{let r=Object.entries(e.bySurface).filter(([,e])=>e.count>0).map(([e,t])=>`${t.count} ${s[e].toLowerCase()}`).join(` + `),i=e.isUnattributed,a=i?`Unattributed`:e.ticketTitle?`#${e.ticketId} ${e.ticketTitle}`:`deleted ticket #${e.ticketId}`;return(0,q.jsx)(`li`,{children:(0,q.jsxs)(`button`,{type:`button`,onClick:()=>n(e.ticketId),className:`w-full text-left flex items-center justify-between gap-3 py-2 px-1 hover:bg-accent/30 rounded transition-colors ${!e.ticketTitle&&!i?`opacity-50`:``}`,disabled:i,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`text-sm truncate`,children:a}),(0,q.jsx)(`div`,{className:`text-[11px] text-muted-foreground truncate`,children:r||`—`})]}),(0,q.jsxs)(`div`,{className:`text-right tabular-nums`,children:[(0,q.jsxs)(`div`,{className:`text-sm font-medium`,children:[`$`,e.totalCostUsd.toFixed(2)]}),(0,q.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.totalRuns,` run`,e.totalRuns===1?``:`s`]})]})]})},`${e.ticketId??`u`}-${t}`)})})]})}function vt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}function yt(e){return e==null?`—`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function bt(e){return e.surface_ref_id?.startsWith(`contract-refine:`)?!0:e.surface===`explore-spec`&&e.ticket_id!=null&&e.conversation_id!=null&&e.surface_ref_id===e.conversation_id&&e.model==null}function xt(e){let t=new Map;for(let n of e)n.model&&(n.conversation_id&&t.set(`conversation:${n.conversation_id}`,n.model),n.ticket_id!=null&&n.surface===`explore-spec`&&t.set(`ticket:${n.ticket_id}:explore-spec`,n.model),n.ticket_id!=null&&n.surface===`quick-spec`&&t.set(`ticket:${n.ticket_id}:quick-spec`,n.model));return t}function St(e,t){if(e.model)return e.model;if(!bt(e))return null;if(e.conversation_id){let n=t.get(`conversation:${e.conversation_id}`);if(n)return n}return e.ticket_id==null?null:t.get(`ticket:${e.ticket_id}:${e.surface}`)??null}function Ct({rows:e,loading:t,truncated:n,totalAvailable:r,tableFilters:i,onTableFiltersChange:a}){let[c,l]=(0,K.useState)(null),u=xt(e);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 mb-3`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`All invocations`}),(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-[11px]`,children:[(0,q.jsxs)(`select`,{value:i.status??``,onChange:e=>a({...i,status:e.target.value||void 0}),className:`h-7 px-2 rounded-md bg-background-deep border border-border/60 text-xs`,"aria-label":`Status filter`,children:[(0,q.jsx)(`option`,{value:``,children:`All status`}),(0,q.jsx)(`option`,{value:`success`,children:`Success`}),(0,q.jsx)(`option`,{value:`failed`,children:`Failed`}),(0,q.jsx)(`option`,{value:`aborted`,children:`Aborted`})]}),(0,q.jsx)(`input`,{type:`number`,step:`0.01`,min:`0`,placeholder:`≥ $0.00`,value:i.minCostUsd??``,onChange:e=>{let t=e.target.value===``?void 0:parseFloat(e.target.value);a({...i,minCostUsd:Number.isNaN(t)?void 0:t})},className:`h-7 w-24 px-2 rounded-md bg-background-deep border border-border/60 text-xs tabular-nums`,"aria-label":`Minimum cost filter`})]})]}),t?(0,q.jsx)(`div`,{className:`h-32 rounded bg-card/30 animate-pulse`}):e.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No invocations match the current filters.`}):(0,q.jsx)(`div`,{className:`overflow-x-auto`,children:(0,q.jsxs)(`table`,{className:`w-full text-[12px] tabular-nums`,children:[(0,q.jsx)(`thead`,{className:`text-[10px] uppercase tracking-wider text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`text-left`,children:[(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Surface`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Ticket`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Cost`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Turns`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Tokens`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Model`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Status`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Started`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>{let t=e.surface,n=o[t],r=(e.tokens_in??0)+(e.tokens_out??0),i=bt(e),a=i?`Contract Layer`:s[t],d=St(e,u);return(0,q.jsxs)(`tr`,{onClick:()=>l(c===e.id?null:e.id),className:`border-t border-border/30 hover:bg-accent/30 cursor-pointer`,children:[(0,q.jsx)(`td`,{className:`px-2 py-2`,children:(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2 h-5 rounded-full text-[10px] font-medium ${n.bg} ${n.text}`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${n.dot}`}),a]})}),(0,q.jsx)(`td`,{className:`px-2 py-2 max-w-[260px]`,children:e.ticket_id==null?e.ticket_title?(0,q.jsx)(`span`,{className:`truncate block text-muted-foreground/90 italic`,title:`Provisional Explore title — not yet committed`,children:e.ticket_title}):(0,q.jsx)(`span`,{className:`text-muted-foreground/70`,children:`—`}):(0,q.jsxs)(`span`,{className:`truncate block`,children:[`#`,e.ticket_id,` `,i?(0,q.jsx)(`span`,{className:`text-muted-foreground/90`,children:`Contract Layer refinement`}):e.ticket_title??(0,q.jsx)(`span`,{className:`text-muted-foreground/70 italic`,children:`(deleted)`})]})}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right font-medium`,children:vt(e.total_cost_usd)}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right`,children:yt(e.num_turns)}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right`,children:r>0?yt(r):`—`}),(0,q.jsxs)(`td`,{className:`px-2 py-2 max-w-[180px] truncate`,children:[d??`—`,d&&!e.model?(0,q.jsx)(`span`,{className:`ml-1 text-[10px] text-muted-foreground/70`,children:`inferred`}):null]}),(0,q.jsxs)(`td`,{className:`px-2 py-2`,children:[e.status===`success`?(0,q.jsx)(`span`,{className:`text-accent-success/90`,children:`●`}):e.status===`failed`?(0,q.jsx)(`span`,{className:`text-accent-warning`,children:`⚠`}):(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`○`}),(0,q.jsx)(`span`,{className:`ml-1 text-muted-foreground`,children:e.status})]}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-muted-foreground`,children:e.started_at.slice(0,16).replace(`T`,` `)})]},e.id)})})]})}),n&&(0,q.jsxs)(`div`,{className:`mt-2 text-[11px] text-muted-foreground/80`,children:[`Showing first `,e.length,` of `,r.toLocaleString(),` matching rows.`]})]})}var wt=[{value:`7d`,label:`7d`},{value:`30d`,label:`30d`},{value:`90d`,label:`90d`},{value:`all`,label:`All`}],Tt=[{value:`all`,label:`All`},{value:`job`,label:`Jobs`},{value:`explore-spec`,label:`Explore`},{value:`quick-spec`,label:`Quick`},{value:`ai-edit`,label:`Refine`},{value:`smash`,label:`SMASH`}];function $(e){let t=new URLSearchParams;return e.period&&t.set(`period`,e.period),e.from&&t.set(`from`,e.from),e.to&&t.set(`to`,e.to),e.surface&&e.surface.length>0&&t.set(`surface`,e.surface.join(`,`)),e.model&&e.model.length>0&&t.set(`model`,e.model.join(`,`)),e.status&&t.set(`status`,e.status),typeof e.minCostUsd==`number`&&t.set(`minCostUsd`,String(e.minCostUsd)),typeof e.ticketId==`number`&&t.set(`ticketId`,String(e.ticketId)),t.toString()}function Et(){let{activeProjectId:e}=u(),[t,i]=d(),o=t.get(`period`)??`30d`,s=(t.get(`surface`)??``).split(`,`).filter(Boolean),c=t.get(`ticketId`),[l,p]=(0,K.useState)({period:o,surface:s.length>0?s:void 0,ticketId:c?Number(c):void 0}),[m,h]=(0,K.useState)(null),[g,_]=(0,K.useState)(!0),[v,y]=(0,K.useState)(null),[b,x]=(0,K.useState)({}),[S,C]=(0,K.useState)(null),w=(0,K.useRef)(new Map),T=(0,K.useRef)(0);(0,K.useEffect)(()=>{let e=new URLSearchParams;e.set(`period`,l.period),l.surface&&l.surface.length>0&&e.set(`surface`,l.surface.join(`,`)),l.ticketId&&e.set(`ticketId`,String(l.ticketId)),i(e,{replace:!0})},[l.period,l.surface,l.ticketId,i]);let E=(0,K.useCallback)(async()=>{if(!e)return;let t=++T.current;y(null);let n=`${e}:${$(l)}`,i=w.current.get(n);i?(h(i),_(!1)):_(!0);try{let e=await fetch(`${r()}/spending?${$(l)}`);if(!e.ok)throw Error(`HTTP ${e.status}`);if(t!==T.current)return;let i=await e.json();w.current.set(n,i),h(i),_(!1)}catch(e){if(t!==T.current)return;y(e.message),_(!1)}},[e,l]),D=(0,K.useCallback)(async()=>{if(!e)return;let t={...l};b.model&&(t.model=[b.model]),b.status&&(t.status=b.status),typeof b.minCostUsd==`number`&&(t.minCostUsd=b.minCostUsd);try{let e=await fetch(`${r()}/invocations?${$(t)}&limit=100`);if(!e.ok)throw Error(`HTTP ${e.status}`);C(await e.json())}catch{C(null)}},[e,l,b]);(0,K.useEffect)(()=>{E()},[E]),(0,K.useEffect)(()=>{D()},[D]);let O=(0,K.useRef)(null),k=a();(0,K.useEffect)(()=>{let t=`analytics-spending`;return k.registerHandler(t,t=>{let n=t;n.type===`spending.invalidated`&&n.projectId===e&&(O.current&&clearTimeout(O.current),O.current=setTimeout(()=>{w.current.clear(),E(),D()},500))}),()=>{k.unregisterHandler(t)}},[k,e,E,D]);function A(e){if(e===`all`){p(e=>({...e,surface:void 0}));return}p(t=>{let n=t.surface??[],r=n.includes(e)?n.filter(t=>t!==e):[...n,e];return{...t,surface:r.length>0?r:void 0}})}let j=l.surface,ee=!j||j.length===0,M=(0,K.useMemo)(()=>{let e={period:l.period};return l.surface&&l.surface.length>0&&(e.surface=l.surface.join(`,`)),l.ticketId&&(e.ticketId=String(l.ticketId)),e},[l]),N=m?m.summary.totalRuns===0:!1;return(0,q.jsxs)(`div`,{className:`flex flex-col gap-6 p-4 pb-12`,children:[(0,q.jsxs)(`div`,{className:`sticky top-0 z-10 -mx-4 px-4 py-3 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-b border-border/40`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,q.jsx)(`h1`,{className:`text-base font-semibold tracking-tight`,children:`Analytics`}),l.ticketId&&(0,q.jsxs)(`button`,{type:`button`,onClick:()=>p(e=>({...e,ticketId:void 0})),className:`inline-flex items-center gap-1 h-6 px-2 rounded-full text-[11px] font-medium bg-accent-highlight/15 text-accent-highlight ring-1 ring-accent-highlight/30 hover:bg-accent-highlight/25`,children:[`ticket #`,l.ticketId,` · ✕`]})]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`div`,{className:`flex items-center gap-1 rounded-md border border-border/60 bg-card/40 p-0.5`,children:wt.map(e=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>p(t=>({...t,period:e.value})),className:`px-2.5 h-6 rounded text-[11px] font-medium transition-colors ${l.period===e.value?`bg-accent text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:e.label},e.value))}),(0,q.jsx)(f,{baseUrl:`${r()}/analytics/export`,params:M,disabled:N}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>{w.current.clear(),E(),D()},className:`h-7 w-7 inline-flex items-center justify-center rounded-md border border-border/60 bg-card/50 text-muted-foreground hover:text-foreground hover:bg-accent/60`,title:`Refresh`,children:(0,q.jsx)(n,{className:`w-3 h-3`})})]})]}),(0,q.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5`,children:Tt.map(e=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>A(e.value),className:`h-7 px-3 rounded-full text-[11px] font-medium transition-all ${(e.value===`all`?ee:j?.includes(e.value)??!1)?`bg-foreground/10 text-foreground ring-1 ring-foreground/20`:`text-muted-foreground hover:text-foreground hover:bg-accent/40`}`,children:e.label},e.value))})]}),v&&(0,q.jsxs)(`div`,{className:`rounded-lg border border-accent-warning/30 bg-accent-warning/10 p-4 flex items-center justify-between`,children:[(0,q.jsxs)(`p`,{className:`text-sm text-accent-warning`,children:[`Failed to load: `,v]}),(0,q.jsxs)(`button`,{onClick:()=>E(),className:`flex items-center gap-1.5 h-7 px-3 rounded-md text-xs text-accent-warning border border-accent-warning/30 hover:bg-accent-warning/10`,children:[(0,q.jsx)(n,{className:`w-3 h-3`}),`Retry`]})]}),(0,q.jsx)(je,{data:m,loading:g}),(0,q.jsx)(ct,{data:m,loading:g}),(0,q.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-4`,children:[(0,q.jsx)(pt,{data:m,loading:g}),(0,q.jsx)(mt,{data:m,loading:g,onSelectModel:e=>p(t=>({...t,model:[e]})),activeModel:l.model?.[0]})]}),(0,q.jsx)(gt,{data:m,loading:g,onSelectPoint:e=>{x(e=>({...e})),p(t=>({...t,ticketId:e.ticketId??void 0}))}}),(0,q.jsx)(_t,{data:m,loading:g,onSelectTicket:e=>p(t=>({...t,ticketId:e??void 0}))}),(0,q.jsx)(Ct,{rows:S?.rows??[],loading:g&&!S,truncated:S?.truncated??!1,totalAvailable:S?.totalAvailable??0,tableFilters:b,onTableFiltersChange:x})]})}export{Et as default};
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{t}from"./clsx-fiJc2n10.js";import{K as n,St as r,Vt as i,bt as a,o,s,vt as c,xt as l,yt as u,zt as d}from"./index-NFgJciDY.js";import{t as f}from"./ExportDropdown-CHJbkux7.js";import{A as p,B as m,C as h,D as g,E as _,F as v,G as y,H as b,I as x,J as S,K as C,L as w,M as T,N as E,O as D,P as O,Q as k,R as A,S as j,T as ee,V as M,X as N,Z as P,_ as te,_t as ne,a as F,at as re,b as ie,c as ae,ct as oe,et as se,f as ce,g as le,gt as I,h as ue,i as L,j as de,k as fe,l as R,lt as z,m as pe,n as me,nt as B,o as he,ot as ge,p as _e,pt as V,q as H,r as U,rt as W,s as ve,st as ye,t as be,tt as xe,ut as G,v as Se,x as Ce,y as we,z as Te}from"./BarChart-D0Js4qm-.js";var Ee=c(`arrow-down-right`,[[`path`,{d:`m7 7 10 10`,key:`1fmybs`}],[`path`,{d:`M17 7v10H7`,key:`6fjiku`}]]),De=c(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),K=e(i(),1),q=l();function Oe(e){return e>=100?`$${e.toFixed(0)}`:e>=10?`$${e.toFixed(1)}`:`$${e.toFixed(2)}`}function ke(e){return e>=1e3?`$${(e/1e3).toFixed(1)}k`:`$${e.toFixed(2)}`}var Ae=[`job`,`explore-spec`,`quick-spec`,`ai-edit`,`smash`];function je({data:e,loading:t}){let[n,r]=(0,K.useState)(0),i=(0,K.useRef)(0);if((0,K.useEffect)(()=>{if(!e)return;let t=e.summary.totalCostUsd;if(i.current===0&&t>0){let e=performance.now(),n=i=>{let a=Math.min(1,(i-e)/600),o=1-(1-a)**3;r(0+(t-0)*o),a<1&&requestAnimationFrame(n)};requestAnimationFrame(n)}else r(t);i.current=t},[e]),t&&!e)return(0,q.jsx)(`div`,{className:`h-44 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let a=e.summary.totalCostUsd,c=e.summary.totalRuns,l=e.summary.deltaPct,u=e.trackingStartedAt,d=Ae.map(t=>{let n=e.bySurface.find(e=>e.surface===t);return{surface:t,costUsd:n?.costUsd??0,count:n?.count??0}});return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-gradient-to-br from-card/80 to-card/40 p-5`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-end justify-between gap-3 mb-4`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-[11px] uppercase tracking-wider text-muted-foreground mb-1`,children:`Spending`}),(0,q.jsxs)(`div`,{className:`flex items-baseline gap-3`,children:[(0,q.jsx)(`div`,{className:`text-5xl font-semibold tabular-nums tracking-tight`,children:ke(n)}),l!==null&&(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 text-xs font-medium ${l>=0?`text-accent-warning`:`text-accent-success`}`,children:[l>=0?(0,q.jsx)(De,{className:`w-3 h-3`}):(0,q.jsx)(Ee,{className:`w-3 h-3`}),Math.abs(l).toFixed(0),`% vs prev`]})]}),(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-1 tabular-nums`,children:[c,` invocation`,c===1?``:`s`]})]}),c===0&&u&&(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Tracking started `,u.slice(0,10)]})]}),c===0?(0,q.jsxs)(`div`,{className:`rounded-lg border border-dashed border-border/40 p-6 text-center`,children:[(0,q.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No invocations yet for this filter window.`}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground/70 mt-1`,children:[`Tracking started `,u?u.slice(0,10):`on first invocation`]})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{className:`h-3 w-full rounded-full overflow-hidden bg-background-deep flex`,children:d.map(e=>{let t=a>0?e.costUsd/a*100:0;return t===0?null:(0,q.jsx)(`div`,{className:`h-full ${o[e.surface].dot}`,style:{width:`${t}%`},title:`${s[e.surface]}: ${Oe(e.costUsd)}`},e.surface)})}),(0,q.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-x-5 gap-y-1.5 text-xs`,children:d.filter(e=>e.costUsd>0).map(e=>(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 tabular-nums`,children:[(0,q.jsx)(`span`,{className:`w-2 h-2 rounded-full ${o[e.surface].dot}`}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:s[e.surface]}),(0,q.jsx)(`span`,{className:`text-foreground font-medium`,children:Oe(e.costUsd)}),(0,q.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,q.jsx)(`span`,{className:`text-muted-foreground/80`,children:e.count})]},e.surface))})]})]})}var Me=[`option`,`isActive`];function J(){return J=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},J.apply(null,arguments)}function Ne(e,t){if(e==null)return{};var n,r,i=Pe(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Pe(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Fe(e){var{option:t,isActive:n}=e,r=Ne(e,Me);return typeof t==`string`?K.createElement(j,J({option:K.createElement(ye,J({type:t},r)),isActive:n,shapeType:`symbols`},r)):K.createElement(j,J({option:t,isActive:n,shapeType:`symbols`},r))}var Ie=se([(e,t,n,r,i,a,o)=>A(e,void 0,void 0,o),(e,t,n,r,i,a,o)=>E(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>O(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>E(e,`yAxis`,n,o),(e,t,n,r,i,a,o)=>O(e,`yAxis`,n,o),(e,t,n,r)=>x(e,`zAxis`,r,!1),se([v,(e,t,n,r,i)=>i],(e,t)=>e.filter(e=>e.type===`scatter`).find(e=>e.id===t)),(e,t,n,r,i,a)=>a],(e,t,n,r,i,a,o,s)=>{var{chartData:c,dataStartIndex:l,dataEndIndex:u}=e;if(o!=null){var d=o?.data!=null&&o.data.length>0?o.data:c?.slice(l,u+1);if(!(d==null||t==null||r==null||n==null||i==null||n?.length===0||i?.length===0))return Ze({displayedData:d,xAxis:t,yAxis:r,zAxis:a,scatterSettings:o,xAxisTicks:n,yAxisTicks:i,cells:s})}}),Le=[`id`],Re=[`onMouseEnter`,`onClick`,`onMouseLeave`],ze=[`animationBegin`,`animationDuration`,`animationEasing`,`hide`,`isAnimationActive`,`legendType`,`lineJointType`,`lineType`,`shape`,`xAxisId`,`yAxisId`,`zAxisId`];function Y(e,t){if(e==null)return{};var n,r,i=Be(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Be(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function X(){return X=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},X.apply(null,arguments)}function Ve(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Z(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Ve(Object(n),!0).forEach(function(t){He(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ve(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function He(e,t,n){return(t=Ue(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ue(e){var t=We(e,`string`);return typeof t==`symbol`?t:t+``}function We(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var Ge=e=>{var{dataKey:t,name:n,fill:r,legendType:i,hide:a}=e;return[{inactive:a,dataKey:t,type:i,color:r,value:P(n,t),payload:e}]},Ke=K.memo(e=>{var{dataKey:t,points:n,stroke:r,strokeWidth:i,fill:a,name:o,hide:s,tooltipType:c,id:l}=e,u={dataDefinedOnItem:n?.map(e=>e.tooltipPayload),getPosition:e=>{var t;return n==null||(t=n[Number(e)])==null?void 0:t.tooltipPosition},settings:{stroke:r,strokeWidth:i,fill:a,nameKey:void 0,dataKey:t,name:P(o,t),hide:s,type:c,color:a,unit:``,graphicalItemId:l}};return K.createElement(Se,{tooltipEntrySettings:u})});function qe(e){var{points:t,props:n}=e,{line:r,lineType:i,lineJointType:a}=n;if(!r)return null;var o=I(n),s=ne(r),c,l;if(i===`joint`)c=t.map(e=>({x:e.cx??null,y:e.cy??null}));else if(i===`fitting`){var{xmin:u,xmax:d,a:f,b:p}=oe(t),m=e=>f*e+p;c=[{x:u,y:m(u)},{x:d,y:m(d)}]}var h=Z(Z(Z({},o),{},{fill:`none`,stroke:o&&o.fill},s),{},{points:c});return l=K.isValidElement(r)?K.cloneElement(r,h):typeof r==`function`?r(h):K.createElement(M,X({},h,{type:a})),K.createElement(V,{className:`recharts-scatter-line`,key:`recharts-scatter-line`},l)}function Je(e){var{showLabels:t,points:n,children:r}=e,i=y(),a=(0,K.useMemo)(()=>n?.map(e=>{var t={x:e.x??0,y:e.y??0,width:e.width,height:e.height,lowerWidth:e.width,upperWidth:e.width};return Z(Z({},t),{},{value:void 0,payload:e.payload,viewBox:t,parentViewBox:i,fill:void 0})}),[i,n]);return K.createElement(ee,{value:t?a:void 0},r)}function Ye(e){var{points:t,allOtherScatterProps:n}=e,{shape:r,activeShape:i,dataKey:a}=n,{id:o}=n,s=Y(n,Le),c=B(de),{onMouseEnter:l,onClick:u,onMouseLeave:d}=n,f=Y(n,Re),m=ie(l,a,o),h=Ce(d),g=we(u,a,o);if(!ge(t))return null;var _=I(s);return K.createElement(K.Fragment,null,K.createElement(qe,{points:t,props:s}),t.map((e,t)=>{var n=i!=null&&i!==!1,a=n&&c===String(t),s=n&&a?i:r,l=Z(Z(Z({},_),e),{},{index:t,[S]:String(o)});return K.createElement(p,{key:`symbol-${e?.cx}-${e?.cy}-${e?.size}-${t}`,zIndex:a?w.activeDot:void 0},K.createElement(V,X({className:`recharts-scatter-symbol`},re(f,e,t),{onMouseEnter:m(e,t),onMouseLeave:h(e,t),onClick:g(e,t)}),K.createElement(Fe,X({option:s,isActive:a},l))))}))}function Xe(e){var{previousPointsRef:t,props:n}=e,{points:r,isAnimationActive:i,animationBegin:a,animationDuration:o,animationEasing:s}=n,c=t.current,l=Te(n,`recharts-scatter-`),[u,d]=(0,K.useState)(!1),f=(0,K.useCallback)(()=>{d(!1)},[]),p=(0,K.useCallback)(()=>{d(!0)},[]),h=!u;return K.createElement(Je,{showLabels:h,points:r},n.children,K.createElement(m,{animationId:l,begin:a,duration:o,isActive:i,easing:s,onAnimationEnd:f,onAnimationStart:p,key:l},e=>{var i=e===1?r:r?.map((t,n)=>{var r=c&&c[n];return r?Z(Z({},t),{},{cx:t.cx==null?void 0:z(r.cx,t.cx,e),cy:t.cy==null?void 0:z(r.cy,t.cy,e),size:z(r.size,t.size,e)}):Z(Z({},t),{},{size:z(0,t.size,e)})});return e>0&&(t.current=i),K.createElement(V,null,K.createElement(Ye,{points:i,allOtherScatterProps:n,showLabels:h}))}),K.createElement(_,{label:n.label}))}function Ze(e){var{displayedData:t,xAxis:n,yAxis:r,zAxis:i,scatterSettings:a,xAxisTicks:o,yAxisTicks:s,cells:c}=e,l=G(n.dataKey)?a.dataKey:n.dataKey,u=G(r.dataKey)?a.dataKey:r.dataKey,d=i&&i.dataKey,f=i?i.range:T.range,p=f&&f[0],m=n.scale.bandwidth?n.scale.bandwidth():0,h=r.scale.bandwidth?r.scale.bandwidth():0;return t.map((e,t)=>{var f=k(e,l),g=k(e,u),_=!G(d)&&k(e,d)||`-`,v=[{name:G(n.dataKey)?a.name:n.name||String(n.dataKey),unit:n.unit||``,value:f,payload:e,dataKey:l,type:a.tooltipType,graphicalItemId:a.id},{name:G(r.dataKey)?a.name:r.name||String(r.dataKey),unit:r.unit||``,value:g,payload:e,dataKey:u,type:a.tooltipType,graphicalItemId:a.id}];_!==`-`&&i!=null&&v.push({name:i.name||i.dataKey,unit:i.unit||``,value:_,payload:e,dataKey:d,type:a.tooltipType,graphicalItemId:a.id});var y=N({axis:n,ticks:o,bandSize:m,entry:e,index:t,dataKey:l}),b=N({axis:r,ticks:s,bandSize:h,entry:e,index:t,dataKey:u}),x=_!==`-`&&i!=null?i.scale.map(_):p,S=x==null?0:Math.sqrt(Math.max(x,0)/Math.PI);return Z(Z({},e),{},{cx:y,cy:b,x:y==null?void 0:y-S,y:b==null?void 0:b-S,width:2*S,height:2*S,size:x,node:{x:f,y:g,z:_},tooltipPayload:v,tooltipPosition:{x:y,y:b},payload:e},c&&c[t]&&c[t].props)})}var Qe=(e,t,n)=>({x:e.cx,y:e.cy,value:Number(n===`x`?e.node.x:e.node.y),errorVal:k(e,t)});function $e(e){var{hide:n,points:r,className:i,needClip:a,xAxisId:o,yAxisId:s,id:c}=e,l=(0,K.useRef)(null);if(n)return null;var u=t(`recharts-scatter`,i),d=c;return K.createElement(p,{zIndex:e.zIndex},K.createElement(V,{className:u,clipPath:a?`url(#clipPath-${d})`:void 0,id:c},a&&K.createElement(`defs`,null,K.createElement(he,{clipPathId:d,xAxisId:o,yAxisId:s})),K.createElement(ae,{xAxisId:o,yAxisId:s,data:r,dataPointFormatter:Qe,errorBarOffset:0},K.createElement(V,{key:`recharts-scatter-symbols`},K.createElement(Xe,{props:e,previousPointsRef:l})))))}var et={xAxisId:0,yAxisId:0,zAxisId:0,label:!1,line:!1,legendType:`circle`,lineType:`joint`,lineJointType:`linear`,shape:`circle`,hide:!1,isAnimationActive:`auto`,animationBegin:0,animationDuration:400,animationEasing:`linear`,zIndex:w.scatter};function tt(e){var t=W(e,et),{animationBegin:n,animationDuration:r,animationEasing:i,hide:a,isAnimationActive:o,legendType:s,lineJointType:c,lineType:l,shape:u,xAxisId:d,yAxisId:f,zAxisId:p}=t,m=Y(t,ze),{needClip:_}=ve(d,f),v=(0,K.useMemo)(()=>h(e.children,g),[e.children]),y=H(),b=B(t=>Ie(t,d,f,p,e.id,v,y));return _==null||b==null?null:K.createElement(K.Fragment,null,K.createElement(Ke,{dataKey:e.dataKey,points:b,stroke:e.stroke,strokeWidth:e.strokeWidth,fill:e.fill,name:e.name,hide:e.hide,tooltipType:e.tooltipType,id:e.id}),K.createElement($e,X({},m,{xAxisId:d,yAxisId:f,zAxisId:p,lineType:l,lineJointType:c,legendType:s,shape:u,hide:a,isAnimationActive:o,animationBegin:n,animationDuration:r,animationEasing:i,points:b,needClip:_})))}function nt(e){var t=W(e,et),n=H();return K.createElement(le,{id:t.id,type:`scatter`},e=>K.createElement(K.Fragment,null,K.createElement(te,{legendPayload:Ge(t)}),K.createElement(ue,{type:`scatter`,id:e,data:t.data,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:t.zAxisId,dataKey:t.dataKey,hide:t.hide,name:t.name,tooltipType:t.tooltipType,isPanorama:n}),K.createElement(tt,X({},t,{id:e}))))}var rt=K.memo(nt,b);rt.displayName=`Scatter`;function it(e){var t=xe(),n=(0,K.useRef)(null);return(0,K.useLayoutEffect)(()=>{n.current===null?t(ce(e)):n.current!==e&&t(pe({prev:n.current,next:e})),n.current=e},[e,t]),(0,K.useLayoutEffect)(()=>()=>{n.current&&=(t(_e(n.current)),null)},[t]),null}var at={zAxisId:0,range:T.range,scale:T.scale,type:T.type};function Q(e){var t=W(e,at);return K.createElement(it,{domain:t.domain,id:t.zAxisId,dataKey:t.dataKey,name:t.name,unit:t.unit,range:t.range,scale:t.scale,type:t.type,allowDuplicatedCategory:T.allowDuplicatedCategory,allowDataOverflow:T.allowDataOverflow,reversed:T.reversed,includeHidden:T.includeHidden})}Q.displayName=`ZAxis`;var ot=[`item`],st=(0,K.forwardRef)((e,t)=>K.createElement(me,{chartName:`ScatterChart`,defaultTooltipEventType:`item`,validateTooltipEventTypes:ot,tooltipPayloadSearcher:fe,categoricalChartProps:e,ref:t}));function ct({data:e,loading:t}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let n=e.dailyTimeline.map(e=>({date:e.date.slice(5),Jobs:e.jobsCostUsd,Explore:e.exploreCostUsd,Quick:e.quickCostUsd,Refine:e.aiEditCostUsd})),r=n.every(e=>e.Jobs+e.Explore+e.Quick+e.Refine===0);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Daily timeline`}),(0,q.jsx)(`span`,{className:`text-[10px] text-muted-foreground/70`,children:`stacked by surface`})]}),r?(0,q.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No spend in this period.`}):(0,q.jsx)(`div`,{className:`h-[220px]`,children:(0,q.jsx)(C,{width:`100%`,height:`100%`,children:(0,q.jsxs)(be,{data:n,margin:{top:10,right:10,left:-8,bottom:0},children:[(0,q.jsx)(R,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`,vertical:!1}),(0,q.jsx)(L,{dataKey:`date`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`}),(0,q.jsx)(U,{tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e}`}),(0,q.jsx)(D,{contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>[`$${typeof e==`number`?e.toFixed(2):`—`}`,String(t)]}),(0,q.jsx)(F,{dataKey:`Jobs`,stackId:`a`,fill:`var(--accent-info, #5fa8d3)`}),(0,q.jsx)(F,{dataKey:`Explore`,stackId:`a`,fill:`var(--accent-highlight, #c084fc)`}),(0,q.jsx)(F,{dataKey:`Quick`,stackId:`a`,fill:`var(--accent-secondary, #f7768e)`}),(0,q.jsx)(F,{dataKey:`Refine`,stackId:`a`,fill:`var(--accent-success, #50fa7b)`})]})})})]})}function lt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:e<1?`$${e.toFixed(3)}`:`$${e.toFixed(2)}`}function ut(e){return e==null?`—`:e<1e3?`${e} ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}function dt({values:e}){let t=Math.max(1e-4,...e);return(0,q.jsx)(`div`,{className:`flex items-end gap-[1px] h-5`,children:e.map((e,n)=>(0,q.jsx)(`div`,{className:`w-[3px] rounded-sm bg-foreground/40`,style:{height:`${Math.max(2,e/t*20)}px`}},n))})}function ft({mode:e,label:t,accentClass:n}){let r=e.mode===`explore`&&e.totalRuns<5;return(0,q.jsxs)(`div`,{className:`flex-1 p-4 first:pr-2 last:pl-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${n}`}),(0,q.jsx)(`span`,{className:`text-xs font-medium uppercase tracking-wider text-muted-foreground`,children:t})]}),r?(0,q.jsxs)(`div`,{className:`py-3`,children:[(0,q.jsx)(`p`,{className:`text-sm text-foreground`,children:`Try Explore for richer specs`}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:[e.totalRuns,` run`,e.totalRuns===1?``:`s`,` so far`]})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`div`,{className:`text-3xl font-semibold tabular-nums tracking-tight`,children:lt(e.avgCostPerSpec)}),(0,q.jsx)(`div`,{className:`text-[11px] text-muted-foreground mt-0.5`,children:`per spec`}),(0,q.jsx)(`div`,{className:`mt-3`,children:(0,q.jsx)(dt,{values:e.sparkline.length>0?e.sparkline:[0]})}),(0,q.jsxs)(`div`,{className:`mt-3 space-y-0.5 text-xs tabular-nums text-muted-foreground`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`span`,{className:`text-foreground font-medium`,children:e.ticketsCreated}),` created · `,e.totalRuns,` runs`]}),(0,q.jsxs)(`div`,{children:[ut(e.avgDurationMs),` avg`]}),(0,q.jsx)(`div`,{className:`truncate`,children:e.dominantModel??`—`})]})]})]})}function pt({data:e,loading:t}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let n=e.byMode.find(e=>e.mode===`quick`),r=e.byMode.find(e=>e.mode===`explore`);if(!n||!r)return null;let i=n.avgCostPerSpec&&r.avgCostPerSpec&&n.avgCostPerSpec>0?r.avgCostPerSpec/n.avgCostPerSpec:null,a=i!==null&&n.totalRuns>=1&&r.totalRuns>=5;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40`,children:[(0,q.jsx)(`div`,{className:`px-4 pt-3 pb-1`,children:(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Quick vs Explore`})}),(0,q.jsxs)(`div`,{className:`flex divide-x divide-border/40`,children:[(0,q.jsx)(ft,{mode:n,label:`Quick`,accentClass:`bg-accent-secondary`}),(0,q.jsx)(ft,{mode:r,label:`Explore`,accentClass:`bg-accent-highlight`})]}),a&&(0,q.jsx)(`div`,{className:`px-4 pb-3 -mt-1`,children:(0,q.jsx)(`div`,{className:`text-center text-[11px] text-muted-foreground tabular-nums`,children:(0,q.jsxs)(`span`,{className:`px-2`,children:[`━━━━━━ `,i.toFixed(1),`× more per spec ━━━━━━`]})})})]})}function mt({data:e,loading:t,onSelectModel:n,activeModel:r}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let i=e.byModel.reduce((e,t)=>e+t.costUsd,0),a=e.byModel.slice(0,5);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:`Models`}),a.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No models recorded.`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:a.map(e=>{let t=i>0?e.costUsd/i*100:0,a=r===e.model;return(0,q.jsx)(`li`,{children:(0,q.jsxs)(`button`,{type:`button`,onClick:()=>n(e.model),className:`w-full text-left group rounded-md px-2 py-1.5 transition-colors ${a?`bg-accent-highlight/10 ring-1 ring-accent-highlight/30`:`hover:bg-accent/30`}`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between text-[12px] mb-1 tabular-nums`,children:[(0,q.jsx)(`span`,{className:`truncate font-medium`,children:e.model}),(0,q.jsxs)(`span`,{className:`text-muted-foreground`,children:[`$`,e.costUsd.toFixed(2),` · `,e.count]})]}),(0,q.jsx)(`div`,{className:`h-1.5 rounded-full bg-background-deep overflow-hidden`,children:(0,q.jsx)(`div`,{className:`h-full ${a?`bg-accent-highlight`:`bg-foreground/40 group-hover:bg-foreground/60`} transition-colors`,style:{width:`${t}%`}})})]})},e.model)})})]})}var ht={job:`var(--accent-info, #5fa8d3)`,"quick-spec":`var(--accent-secondary, #f7768e)`,"explore-spec":`var(--accent-highlight, #c084fc)`,"ai-edit":`var(--accent-success, #50fa7b)`,smash:`var(--accent-highlight, #c084fc)`};function gt({data:e,loading:t,onSelectPoint:n}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-[260px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let r=[`job`,`quick-spec`,`explore-spec`,`ai-edit`,`smash`],i=r.map(t=>({surface:t,points:e.scatter.filter(e=>e.surface===t).map(e=>({id:e.id,x:e.numTurns??Math.round((e.durationMs??0)/1e3),y:e.costUsd,surface:t,ticketId:e.ticketId,startedAt:e.startedAt,raw:e}))})),a=e.scatter.length===0;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Cost vs Turns`}),(0,q.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 text-[10px]`,children:r.map(e=>(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full`,style:{background:ht[e]}}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:s[e]})]},e))})]}),a?(0,q.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No invocations to plot.`}):(0,q.jsx)(`div`,{className:`h-[260px]`,children:(0,q.jsx)(C,{width:`100%`,height:`100%`,children:(0,q.jsxs)(st,{margin:{top:10,right:10,left:-8,bottom:5},children:[(0,q.jsx)(R,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`}),(0,q.jsx)(L,{type:`number`,dataKey:`x`,name:`turns`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,label:{value:`turns`,position:`insideBottomRight`,offset:-2,fontSize:10,fill:`currentColor`}}),(0,q.jsx)(U,{type:`number`,dataKey:`y`,name:`cost`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e.toFixed(e<1?2:0)}`}),(0,q.jsx)(Q,{range:[40,80]}),(0,q.jsx)(D,{cursor:{strokeDasharray:`3 3`},contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>{let n=String(t);return n===`cost`&&typeof e==`number`?[`$${e.toFixed(3)}`,`cost`]:[String(e),n]}}),i.map(e=>(0,q.jsx)(rt,{data:e.points,fill:ht[e.surface],onClick:e=>{let t=e;t?.raw&&n(t.raw)}},e.surface))]})})})]})}function _t({data:e,loading:t,onSelectTicket:n}){if(t&&!e)return(0,q.jsx)(`div`,{className:`h-40 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let r=e.topTickets;return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:`Top tickets`}),r.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No ticket activity in this period.`}):(0,q.jsx)(`ul`,{className:`divide-y divide-border/30`,children:r.map((e,t)=>{let r=Object.entries(e.bySurface).filter(([,e])=>e.count>0).map(([e,t])=>`${t.count} ${s[e].toLowerCase()}`).join(` + `),i=e.isUnattributed,a=i?`Unattributed`:e.ticketTitle?`#${e.ticketId} ${e.ticketTitle}`:`deleted ticket #${e.ticketId}`;return(0,q.jsx)(`li`,{children:(0,q.jsxs)(`button`,{type:`button`,onClick:()=>n(e.ticketId),className:`w-full text-left flex items-center justify-between gap-3 py-2 px-1 hover:bg-accent/30 rounded transition-colors ${!e.ticketTitle&&!i?`opacity-50`:``}`,disabled:i,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`text-sm truncate`,children:a}),(0,q.jsx)(`div`,{className:`text-[11px] text-muted-foreground truncate`,children:r||`—`})]}),(0,q.jsxs)(`div`,{className:`text-right tabular-nums`,children:[(0,q.jsxs)(`div`,{className:`text-sm font-medium`,children:[`$`,e.totalCostUsd.toFixed(2)]}),(0,q.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.totalRuns,` run`,e.totalRuns===1?``:`s`]})]})]})},`${e.ticketId??`u`}-${t}`)})})]})}function vt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}function yt(e){return e==null?`—`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function bt(e){return e.surface_ref_id?.startsWith(`contract-refine:`)?!0:e.surface===`explore-spec`&&e.ticket_id!=null&&e.conversation_id!=null&&e.surface_ref_id===e.conversation_id&&e.model==null}function xt(e){let t=new Map;for(let n of e)n.model&&(n.conversation_id&&t.set(`conversation:${n.conversation_id}`,n.model),n.ticket_id!=null&&n.surface===`explore-spec`&&t.set(`ticket:${n.ticket_id}:explore-spec`,n.model),n.ticket_id!=null&&n.surface===`quick-spec`&&t.set(`ticket:${n.ticket_id}:quick-spec`,n.model));return t}function St(e,t){if(e.model)return e.model;if(!bt(e))return null;if(e.conversation_id){let n=t.get(`conversation:${e.conversation_id}`);if(n)return n}return e.ticket_id==null?null:t.get(`ticket:${e.ticket_id}:${e.surface}`)??null}function Ct({rows:e,loading:t,truncated:n,totalAvailable:r,tableFilters:i,onTableFiltersChange:a}){let[c,l]=(0,K.useState)(null),u=xt(e);return(0,q.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 mb-3`,children:[(0,q.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`All invocations`}),(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-[11px]`,children:[(0,q.jsxs)(`select`,{value:i.status??``,onChange:e=>a({...i,status:e.target.value||void 0}),className:`h-7 px-2 rounded-md bg-background-deep border border-border/60 text-xs`,"aria-label":`Status filter`,children:[(0,q.jsx)(`option`,{value:``,children:`All status`}),(0,q.jsx)(`option`,{value:`success`,children:`Success`}),(0,q.jsx)(`option`,{value:`failed`,children:`Failed`}),(0,q.jsx)(`option`,{value:`aborted`,children:`Aborted`})]}),(0,q.jsx)(`input`,{type:`number`,step:`0.01`,min:`0`,placeholder:`≥ $0.00`,value:i.minCostUsd??``,onChange:e=>{let t=e.target.value===``?void 0:parseFloat(e.target.value);a({...i,minCostUsd:Number.isNaN(t)?void 0:t})},className:`h-7 w-24 px-2 rounded-md bg-background-deep border border-border/60 text-xs tabular-nums`,"aria-label":`Minimum cost filter`})]})]}),t?(0,q.jsx)(`div`,{className:`h-32 rounded bg-card/30 animate-pulse`}):e.length===0?(0,q.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:`No invocations match the current filters.`}):(0,q.jsx)(`div`,{className:`overflow-x-auto`,children:(0,q.jsxs)(`table`,{className:`w-full text-[12px] tabular-nums`,children:[(0,q.jsx)(`thead`,{className:`text-[10px] uppercase tracking-wider text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`text-left`,children:[(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Surface`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Ticket`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Cost`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Turns`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:`Tokens`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Model`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Status`}),(0,q.jsx)(`th`,{className:`font-medium px-2 py-2`,children:`Started`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>{let t=e.surface,n=o[t],r=(e.tokens_in??0)+(e.tokens_out??0),i=bt(e),a=i?`Contract Layer`:s[t],d=St(e,u);return(0,q.jsxs)(`tr`,{onClick:()=>l(c===e.id?null:e.id),className:`border-t border-border/30 hover:bg-accent/30 cursor-pointer`,children:[(0,q.jsx)(`td`,{className:`px-2 py-2`,children:(0,q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2 h-5 rounded-full text-[10px] font-medium ${n.bg} ${n.text}`,children:[(0,q.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${n.dot}`}),a]})}),(0,q.jsx)(`td`,{className:`px-2 py-2 max-w-[260px]`,children:e.ticket_id==null?e.ticket_title?(0,q.jsx)(`span`,{className:`truncate block text-muted-foreground/90 italic`,title:`Provisional Explore title — not yet committed`,children:e.ticket_title}):(0,q.jsx)(`span`,{className:`text-muted-foreground/70`,children:`—`}):(0,q.jsxs)(`span`,{className:`truncate block`,children:[`#`,e.ticket_id,` `,i?(0,q.jsx)(`span`,{className:`text-muted-foreground/90`,children:`Contract Layer refinement`}):e.ticket_title??(0,q.jsx)(`span`,{className:`text-muted-foreground/70 italic`,children:`(deleted)`})]})}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right font-medium`,children:vt(e.total_cost_usd)}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right`,children:yt(e.num_turns)}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-right`,children:r>0?yt(r):`—`}),(0,q.jsxs)(`td`,{className:`px-2 py-2 max-w-[180px] truncate`,children:[d??`—`,d&&!e.model?(0,q.jsx)(`span`,{className:`ml-1 text-[10px] text-muted-foreground/70`,children:`inferred`}):null]}),(0,q.jsxs)(`td`,{className:`px-2 py-2`,children:[e.status===`success`?(0,q.jsx)(`span`,{className:`text-accent-success/90`,children:`●`}):e.status===`failed`?(0,q.jsx)(`span`,{className:`text-accent-warning`,children:`⚠`}):(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`○`}),(0,q.jsx)(`span`,{className:`ml-1 text-muted-foreground`,children:e.status})]}),(0,q.jsx)(`td`,{className:`px-2 py-2 text-muted-foreground`,children:e.started_at.slice(0,16).replace(`T`,` `)})]},e.id)})})]})}),n&&(0,q.jsxs)(`div`,{className:`mt-2 text-[11px] text-muted-foreground/80`,children:[`Showing first `,e.length,` of `,r.toLocaleString(),` matching rows.`]})]})}var wt=[{value:`7d`,label:`7d`},{value:`30d`,label:`30d`},{value:`90d`,label:`90d`},{value:`all`,label:`All`}],Tt=[{value:`all`,label:`All`},{value:`job`,label:`Jobs`},{value:`explore-spec`,label:`Explore`},{value:`quick-spec`,label:`Quick`},{value:`ai-edit`,label:`Refine`},{value:`smash`,label:`SMASH`}];function $(e){let t=new URLSearchParams;return e.period&&t.set(`period`,e.period),e.from&&t.set(`from`,e.from),e.to&&t.set(`to`,e.to),e.surface&&e.surface.length>0&&t.set(`surface`,e.surface.join(`,`)),e.model&&e.model.length>0&&t.set(`model`,e.model.join(`,`)),e.status&&t.set(`status`,e.status),typeof e.minCostUsd==`number`&&t.set(`minCostUsd`,String(e.minCostUsd)),typeof e.ticketId==`number`&&t.set(`ticketId`,String(e.ticketId)),t.toString()}function Et(){let{activeProjectId:e}=u(),[t,i]=d(),o=t.get(`period`)??`30d`,s=(t.get(`surface`)??``).split(`,`).filter(Boolean),c=t.get(`ticketId`),[l,p]=(0,K.useState)({period:o,surface:s.length>0?s:void 0,ticketId:c?Number(c):void 0}),[m,h]=(0,K.useState)(null),[g,_]=(0,K.useState)(!0),[v,y]=(0,K.useState)(null),[b,x]=(0,K.useState)({}),[S,C]=(0,K.useState)(null),w=(0,K.useRef)(new Map),T=(0,K.useRef)(0);(0,K.useEffect)(()=>{let e=new URLSearchParams;e.set(`period`,l.period),l.surface&&l.surface.length>0&&e.set(`surface`,l.surface.join(`,`)),l.ticketId&&e.set(`ticketId`,String(l.ticketId)),i(e,{replace:!0})},[l.period,l.surface,l.ticketId,i]);let E=(0,K.useCallback)(async()=>{if(!e)return;let t=++T.current;y(null);let n=`${e}:${$(l)}`,i=w.current.get(n);i?(h(i),_(!1)):_(!0);try{let e=await fetch(`${r()}/spending?${$(l)}`);if(!e.ok)throw Error(`HTTP ${e.status}`);if(t!==T.current)return;let i=await e.json();w.current.set(n,i),h(i),_(!1)}catch(e){if(t!==T.current)return;y(e.message),_(!1)}},[e,l]),D=(0,K.useCallback)(async()=>{if(!e)return;let t={...l};b.model&&(t.model=[b.model]),b.status&&(t.status=b.status),typeof b.minCostUsd==`number`&&(t.minCostUsd=b.minCostUsd);try{let e=await fetch(`${r()}/invocations?${$(t)}&limit=100`);if(!e.ok)throw Error(`HTTP ${e.status}`);C(await e.json())}catch{C(null)}},[e,l,b]);(0,K.useEffect)(()=>{E()},[E]),(0,K.useEffect)(()=>{D()},[D]);let O=(0,K.useRef)(null),k=a();(0,K.useEffect)(()=>{let t=`analytics-spending`;return k.registerHandler(t,t=>{let n=t;n.type===`spending.invalidated`&&n.projectId===e&&(O.current&&clearTimeout(O.current),O.current=setTimeout(()=>{w.current.clear(),E(),D()},500))}),()=>{k.unregisterHandler(t)}},[k,e,E,D]);function A(e){if(e===`all`){p(e=>({...e,surface:void 0}));return}p(t=>{let n=t.surface??[],r=n.includes(e)?n.filter(t=>t!==e):[...n,e];return{...t,surface:r.length>0?r:void 0}})}let j=l.surface,ee=!j||j.length===0,M=(0,K.useMemo)(()=>{let e={period:l.period};return l.surface&&l.surface.length>0&&(e.surface=l.surface.join(`,`)),l.ticketId&&(e.ticketId=String(l.ticketId)),e},[l]),N=m?m.summary.totalRuns===0:!1;return(0,q.jsxs)(`div`,{className:`flex flex-col gap-6 p-4 pb-12`,children:[(0,q.jsxs)(`div`,{className:`sticky top-0 z-10 -mx-4 px-4 py-3 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-b border-border/40`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,q.jsx)(`h1`,{className:`text-base font-semibold tracking-tight`,children:`Analytics`}),l.ticketId&&(0,q.jsxs)(`button`,{type:`button`,onClick:()=>p(e=>({...e,ticketId:void 0})),className:`inline-flex items-center gap-1 h-6 px-2 rounded-full text-[11px] font-medium bg-accent-highlight/15 text-accent-highlight ring-1 ring-accent-highlight/30 hover:bg-accent-highlight/25`,children:[`ticket #`,l.ticketId,` · ✕`]})]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`div`,{className:`flex items-center gap-1 rounded-md border border-border/60 bg-card/40 p-0.5`,children:wt.map(e=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>p(t=>({...t,period:e.value})),className:`px-2.5 h-6 rounded text-[11px] font-medium transition-colors ${l.period===e.value?`bg-accent text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:e.label},e.value))}),(0,q.jsx)(f,{baseUrl:`${r()}/analytics/export`,params:M,disabled:N}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>{w.current.clear(),E(),D()},className:`h-7 w-7 inline-flex items-center justify-center rounded-md border border-border/60 bg-card/50 text-muted-foreground hover:text-foreground hover:bg-accent/60`,title:`Refresh`,children:(0,q.jsx)(n,{className:`w-3 h-3`})})]})]}),(0,q.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5`,children:Tt.map(e=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>A(e.value),className:`h-7 px-3 rounded-full text-[11px] font-medium transition-all ${(e.value===`all`?ee:j?.includes(e.value)??!1)?`bg-foreground/10 text-foreground ring-1 ring-foreground/20`:`text-muted-foreground hover:text-foreground hover:bg-accent/40`}`,children:e.label},e.value))})]}),v&&(0,q.jsxs)(`div`,{className:`rounded-lg border border-accent-warning/30 bg-accent-warning/10 p-4 flex items-center justify-between`,children:[(0,q.jsxs)(`p`,{className:`text-sm text-accent-warning`,children:[`Failed to load: `,v]}),(0,q.jsxs)(`button`,{onClick:()=>E(),className:`flex items-center gap-1.5 h-7 px-3 rounded-md text-xs text-accent-warning border border-accent-warning/30 hover:bg-accent-warning/10`,children:[(0,q.jsx)(n,{className:`w-3 h-3`}),`Retry`]})]}),(0,q.jsx)(je,{data:m,loading:g}),(0,q.jsx)(ct,{data:m,loading:g}),(0,q.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-4`,children:[(0,q.jsx)(pt,{data:m,loading:g}),(0,q.jsx)(mt,{data:m,loading:g,onSelectModel:e=>p(t=>({...t,model:[e]})),activeModel:l.model?.[0]})]}),(0,q.jsx)(gt,{data:m,loading:g,onSelectPoint:e=>{x(e=>({...e})),p(t=>({...t,ticketId:e.ticketId??void 0}))}}),(0,q.jsx)(_t,{data:m,loading:g,onSelectTicket:e=>p(t=>({...t,ticketId:e??void 0}))}),(0,q.jsx)(Ct,{rows:S?.rows??[],loading:g&&!S,truncated:S?.truncated??!1,totalAvailable:S?.totalAvailable??0,tableFilters:b,onTableFiltersChange:x})]})}export{Et as default};
|