@coreplane/switchboard 1.267.3 → 1.268.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/assets/deploy/cloudflare-memory/worker.ts +23 -1
  2. package/dist/assets/deploy/cloudflare-resident/imageReconcileState.ts +28 -0
  3. package/dist/assets/deploy/cloudflare-resident/shared.ts +2 -3
  4. package/dist/assets/deploy/cloudflare-resident/worker.ts +162 -27
  5. package/dist/assets/package-lock.json +3 -3
  6. package/dist/assets/package.json +1 -1
  7. package/dist/assets/source.json +3 -3
  8. package/dist/assets/src/core/budgets.ts +4 -0
  9. package/dist/assets/src/core/coordinator/contract.ts +14 -8
  10. package/dist/assets/src/core/costs.ts +2 -0
  11. package/dist/assets/src/core/runEvents.ts +1 -0
  12. package/dist/assets/src/core/runLedger/types.ts +2 -0
  13. package/dist/assets/src/core/runRecord.ts +10 -0
  14. package/dist/assets/src/core/runUsage.ts +53 -0
  15. package/dist/assets/src/core/shipSpend.ts +52 -0
  16. package/dist/assets/src/execution/residentPoolSpends.ts +9 -0
  17. package/dist/assets/src/execution/residentRecreateAdmission.ts +28 -0
  18. package/dist/assets/web/dist/.vite/manifest.json +31 -31
  19. package/dist/assets/web/dist/assets/CostsPage-6P9rJ7k_.js +1 -0
  20. package/dist/assets/web/dist/assets/{HomePage-BQmun9kS.js → HomePage-B4LGwXHO.js} +1 -1
  21. package/dist/assets/web/dist/assets/ResidentDetailPage-jpGfsR5n.js +1 -0
  22. package/dist/assets/web/dist/assets/ResidentsIndexPage-C4-5nG9M.js +1 -0
  23. package/dist/assets/web/dist/assets/{RunFoldRow-C1w-mwch.js → RunFoldRow-u4FTh57c.js} +1 -1
  24. package/dist/assets/web/dist/assets/{RunRoutePage-zWMHTzla.js → RunRoutePage-CxOKb7oC.js} +4 -4
  25. package/dist/assets/web/dist/assets/{RunsIndexPage-DF16D2Gg.js → RunsIndexPage-CULSlv_d.js} +1 -1
  26. package/dist/assets/web/dist/assets/{ScheduledPage-CyRs0fXN.js → ScheduledPage-CDjkZuqM.js} +1 -1
  27. package/dist/assets/web/dist/assets/{SettingsPage-BRuMCHSj.js → SettingsPage-BMSomotV.js} +1 -1
  28. package/dist/assets/web/dist/assets/{StatusDot-BIAQN7iD.js → StatusDot-XxLkmRaK.js} +1 -1
  29. package/dist/assets/web/dist/assets/{Tooltip-CxiQ7luL.js → Tooltip-qB73RL4b.js} +1 -1
  30. package/dist/assets/web/dist/assets/{UnitRoutePage-BQB5mAAl.js → UnitRoutePage-DFRWAdOT.js} +1 -1
  31. package/dist/assets/web/dist/assets/{dist-I2OEmPqz.js → dist-BsLBAkQJ.js} +1 -1
  32. package/dist/assets/web/dist/assets/{main-DYwKyLY5.js → main-9ynpo780.js} +10 -10
  33. package/dist/assets/web/dist/assets/main-DSiJ9sHU.css +1 -0
  34. package/dist/cli.js +385 -226
  35. package/package.json +1 -1
  36. package/dist/assets/web/dist/assets/CostsPage-RRggVvIx.js +0 -1
  37. package/dist/assets/web/dist/assets/ResidentDetailPage-CT6v9INM.js +0 -1
  38. package/dist/assets/web/dist/assets/ResidentsIndexPage-CWqPFf40.js +0 -1
  39. package/dist/assets/web/dist/assets/main-DPB0UO1-.css +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreplane/switchboard",
3
- "version": "1.267.3",
3
+ "version": "1.268.0",
4
4
  "description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://openswitchboard.dev",
@@ -1 +0,0 @@
1
- import{t as e}from"./AppShell-CCPwPqvc.js";import{An as t,Cr as n,Dn as r,Fi as i,Jr as a,Jt as o,Mi as s,Pi as c,Qt as l,Xr as u,_n as d,bn as f,hr as p,ki as m,lr as h,o as ee,pr as g,sn as _,vn as v,xn as y,xr as b,yi as x,yn as S}from"./browser-BWnzWwaT.js";import{a as C,c as te,d as w,f as T,g as E,h as D,l as O,m as k,o as ne,p as re,s as ie,t as A,u as j}from"./CostChart-Y5BqJKLA.js";import{t as ae}from"./eventSource-Ds6_gjPD.js";import{r as oe}from"./settingsApi-Dm6eaQcu.js";import{t as se}from"./wallClock-DaewxNMY.js";var M=[`data-dimension`],ce={class:`flex flex-wrap items-center gap-x-4 gap-y-2`},N={class:`flex items-center gap-2 text-sm text-muted`},P=[`placeholder`,`aria-label`],F=[`title`],I=[`disabled`,`aria-describedby`],L={key:0,id:`me-hint`,class:`me-hint text-xs text-dimmed`},R={class:`coverage font-mono text-xs tabular-nums text-muted`},le={class:`overflow-x-auto`},z={class:`by w-full min-w-[40rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},B={class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},V={class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},H={key:0,class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},ue=[`title`],U={class:`text-highlighted`},de={key:0,class:`ml-1.5 text-xs text-dimmed`},fe={key:1,class:`ml-1.5 rounded-xs bg-accented px-1 text-xs text-highlighted`},W=[`title`],G={class:`border-b border-muted px-2.5 py-1.5 text-right`},K={class:`border-b border-muted px-2.5 py-1.5 text-right`},q={key:0,class:`border-b border-muted px-2.5 py-1.5 text-right`},J={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium text-highlighted`},Y={class:`border-b border-muted px-2.5 py-1.5 text-right`},X={key:0},Z=[`colspan`],pe={key:0},Q=[`colspan`],me={class:`px-2.5 py-1.5 text-right text-xs text-muted`},he={class:`px-2.5 py-1.5 text-right text-xs text-muted`},ge={class:`reconciliation font-mono text-xs tabular-nums text-muted`},_e={class:`text-xs text-dimmed`},ve=t({__name:`CostsByDimension`,props:{report:{}},setup(e){let t=e,n={user:`User`,thread:`Thread`,channel:`Channel`,agent:`Agent`,model:`Model`},a=x(``),c=x(!1),h=d(()=>t.report.dimension),ee=d(()=>t.report.viewer!==void 0),g=d(()=>(t.report.viewer?.userIds.length??0)>0),S=d(()=>t.report.cloudAllocated),C=d(()=>h.value===`model`?`Turns`:`Runs`),te=e=>h.value===`model`?e.turns:e.runs,w=d(()=>{let e=a.value.trim().toLowerCase(),n=new Set(t.report.viewer?.userIds??[]);return t.report.rows.filter(t=>c.value&&!n.has(t.key)?!1:!e||t.key.toLowerCase().includes(e)||(t.label??``).toLowerCase().includes(e))}),T=d(()=>t.report.rows.reduce((e,t)=>e+t.totalUsd,0)),E=d(()=>w.value.reduce((e,t)=>e+t.totalUsd,0)),k=e=>t.report.viewer?.userIds.includes(e.key)??!1,ne=d(()=>h.value===`user`||h.value===`thread`||h.value===`channel`),re=e=>e.label?h.value===`channel`?`#${e.label}`:e.label:ne.value?e.key.replace(/^[a-z]+:/,``):e.key,ie=e=>ne.value&&e.key.includes(`:`)?e.key.split(`:`)[0]:``,A=e=>`${e} day${e===1?``:`s`}`,j=d(()=>S.value?6:5);return(t,d)=>(p(),y(`section`,{class:`by-dimension grid gap-3`,"data-dimension":h.value},[v(`div`,ce,[v(`label`,N,[d[2]||=v(`span`,null,`Filter`,-1),u(v(`input`,{"onUpdate:modelValue":d[0]||=e=>a.value=e,class:`key-filter rounded-md border border-default bg-elevated px-2.5 py-1 font-mono text-xs text-highlighted`,type:`search`,placeholder:h.value===`user`?`name or id`:n[h.value].toLowerCase(),"aria-label":`Filter by ${n[h.value].toLowerCase()}`},null,8,P),[[l,a.value]])]),ee.value?(p(),y(`label`,{key:0,class:s([`me-toggle flex items-center gap-2 text-sm`,g.value?`text-muted`:`text-dimmed`]),title:g.value?`Only your own runs`:void 0},[u(v(`input`,{"onUpdate:modelValue":d[1]||=e=>c.value=e,type:`checkbox`,disabled:!g.value,"aria-label":`Only me`,"aria-describedby":g.value?void 0:`me-hint`},null,8,I),[[o,c.value]]),d[3]||=v(`span`,null,`me`,-1),g.value?f(``,!0):(p(),y(`span`,L,`— your sign-in email matched no Slack user in this range`))],10,F)):f(``,!0),v(`p`,R,[e.report.coverage.historyOn?(p(),y(_,{key:1},[r(` runs from `+i(m(O)(e.report.coverage.from))+` to `+i(m(O)(e.report.range.to)),1),e.report.coverage.clamped?(p(),y(_,{key:0},[r(` · earlier days are past the history's `+i(e.report.coverage.retentionDays)+`-day window`,1)],64)):f(``,!0),e.report.pending>0?(p(),y(_,{key:1},[r(` · `+i(e.report.pending)+` run`+i(e.report.pending===1?``:`s`)+` still being priced`,1)],64)):f(``,!0)],64)):(p(),y(_,{key:0},[r(`history is off — no runs to attribute`)],64))])]),v(`div`,le,[v(`table`,z,[v(`thead`,null,[v(`tr`,null,[v(`th`,B,i(n[h.value]),1),v(`th`,V,i(C.value),1),d[5]||=v(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` LLM `,-1),S.value?(p(),y(`th`,H,[...d[4]||=[r(` Cloud `,-1),v(`span`,{class:`font-normal text-dimmed`},`allocated`,-1)]])):f(``,!0),d[6]||=v(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Total `,-1),d[7]||=v(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Share `,-1)])]),v(`tbody`,null,[(p(!0),y(_,null,b(w.value,e=>(p(),y(`tr`,{key:e.key,class:s([`by-row`,k(e)?`is-me`:``])},[v(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.key},[v(`span`,U,i(re(e)),1),ie(e)?(p(),y(`span`,de,i(ie(e)),1)):f(``,!0),k(e)?(p(),y(`span`,fe,`me`)):f(``,!0),e.unpricedTokens>0?(p(),y(`span`,{key:2,class:`ml-1.5 text-xs text-warn`,title:`${e.unpricedTokens} tokens ran under a model with no price`},`unpriced tokens`,8,W)):f(``,!0)],8,ue),v(`td`,G,i(te(e)),1),v(`td`,K,i(m(D)(e.llmUsd)),1),S.value?(p(),y(`td`,q,i(m(D)(e.cloudUsd)),1)):f(``,!0),v(`td`,J,i(m(D)(e.totalUsd)),1),v(`td`,Y,i(T.value>0?Math.round(e.totalUsd/T.value*100):0)+`% `,1)],2))),128)),w.value.length===0?(p(),y(`tr`,X,[v(`td`,{class:`empty px-2.5 py-3 text-sm text-muted`,colspan:j.value},i(e.report.rows.length===0?`no runs in this range`:`no ${n[h.value].toLowerCase()} matches`),9,Z)])):f(``,!0)]),w.value.length>0&&w.value.length<e.report.rows.length?(p(),y(`tfoot`,pe,[v(`tr`,null,[v(`td`,{class:`px-2.5 py-1.5 text-xs text-muted`,colspan:j.value-2},`shown`,8,Q),v(`td`,me,i(m(D)(E.value)),1),v(`td`,he,i(T.value>0?Math.round(E.value/T.value*100):0)+`% `,1)])])):f(``,!0)])]),v(`p`,ge,[e.report.reconciliation.comparedDays>0?(p(),y(_,{key:0},[r(` LLM attributed `+i(m(D)(e.report.reconciliation.attributedLlmUsd))+` of `+i(m(D)(e.report.reconciliation.workspaceLlmUsd))+` on the workspace over `+i(A(e.report.reconciliation.comparedDays))+` · `,1),e.report.reconciliation.unattributedLlmUsd>=0?(p(),y(_,{key:0},[r(i(m(D)(e.report.reconciliation.unattributedLlmUsd))+` unattributed (router, review abridges, runs without a record, list vs invoice) `,1)],64)):(p(),y(_,{key:1},[r(i(m(D)(-e.report.reconciliation.unattributedLlmUsd))+` more attributed than the workspace figure (list vs invoice, or spend billed outside this workspace on a compared day) `,1)],64))],64)):(p(),y(_,{key:1},[r(`no day in range has a workspace LLM figure to compare against`)],64)),e.report.reconciliation.uncomparedDays>0?(p(),y(_,{key:2},[r(` · `+i(A(e.report.reconciliation.uncomparedDays))+` with `+i(m(D)(e.report.reconciliation.uncomparedLlmUsd))+` of tokens from runs but no workspace figure (billed outside this workspace) not compared`,1)],64)):f(``,!0),S.value?(p(),y(_,{key:3},[r(` · cloud allocated `+i(m(D)(e.report.reconciliation.cloudAllocatedUsd)),1),e.report.reconciliation.cloudUnallocatedUsd>0?(p(),y(_,{key:0},[r(` · `+i(m(D)(e.report.reconciliation.cloudUnallocatedUsd))+` on days with no runs`,1)],64)):f(``,!0)],64)):f(``,!0)]),v(`p`,_e,[h.value===`model`?(p(),y(_,{key:0},[r(` A model's LLM is the runs' tokens on it, priced through the price table (the configured rates over Anthropic list; cache writes at the 5-minute rate); a run that spent on two models counts under both, and cloud is not split by model — a container runs a run, not a model. `)],64)):(p(),y(_,{key:1},[r(` A `+i(n[h.value].toLowerCase())+`'s LLM is its runs' tokens priced through the price table (the configured rates over Anthropic list; cache writes at the 5-minute rate); a child run bills to whoever started its parent, in the child's own thread and agent. Cloud is each day's Cloudflare spend split by share of run wall-clock — an allocation, not a meter. `,1)],64))])],8,M))}}),ye={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},be={class:`flex items-center gap-1`,"aria-label":`Range`},xe={key:0,class:`rounded-md bg-accented px-2.5 py-1 font-mono text-xs font-medium tabular-nums text-highlighted`,"aria-current":`page`},Se={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},Ce={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},we={class:`font-mono text-sm tabular-nums text-muted`},Te={key:1,class:`flex basis-full flex-wrap items-center gap-x-3 gap-y-1`},Ee={class:`font-mono text-xs tabular-nums text-dimmed`,"data-snapshot-status":``},De=[`disabled`],Oe={key:1,class:`text-xs text-error`,role:`status`,"data-snapshot-error":``},ke={class:`mb-5 grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},Ae={key:0,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},je={class:`font-mono text-2xl font-medium tabular-nums`},Me={class:`text-xs text-muted`},Ne={key:1,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Pe={class:`font-mono text-2xl font-medium tabular-nums`},Fe={class:`text-xs text-muted`},Ie={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Le={class:`font-mono text-2xl font-medium tabular-nums`},Re={class:`text-xs text-muted`},ze={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Be={class:`font-mono text-2xl font-medium tabular-nums`},Ve={class:`text-xs text-muted`},He={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ue={class:`font-mono text-2xl font-medium tabular-nums`},We={class:`text-xs text-muted`},Ge={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ke={class:`font-mono text-2xl font-medium tabular-nums`},qe={class:`text-xs text-muted`},Je=[`href`,`title`],Ye=[`href`],Xe={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},Ze={class:`flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2`},Qe={class:`legend flex flex-wrap gap-x-4 gap-y-1.5 text-xs text-muted`},$e=[`href`,`title`],et={key:1,class:`text-xs text-warn`},tt={key:2,class:`text-xs text-muted`},nt={class:`mb-3 flex flex-wrap items-center gap-1 border-b border-default`,"aria-label":`View`},rt={key:0,class:`-mb-px border-b-2 border-primary px-3 py-1.5 text-sm font-medium text-highlighted`,"aria-current":`page`},it={key:0,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},at={class:`text-[0.9375rem] font-medium`},ot={class:`text-sm text-muted`},st={key:1,class:`text-sm text-warn`},ct={class:`text-xs text-muted`},lt={class:`rounded bg-accented px-1 py-0.5`},ut={key:1,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},dt={class:`w-full border-collapse font-mono text-[0.8125rem] tabular-nums`},ft={class:`px-2.5 py-1.5`},pt=[`href`],mt={class:`px-2.5 py-1.5 text-right`},ht={class:`px-2.5 py-1.5 text-right`},gt={class:`w-2/5 px-2.5 py-1.5`},_t={key:2,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},vt={open:``},yt={class:`mt-2.5 overflow-x-auto`},bt={class:`data w-full min-w-[38rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},xt=[`title`],St={key:0,class:`text-xs text-dimmed`},Ct={key:1,class:`text-xs text-dimmed`},wt={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium`},Tt={class:`text-xs text-muted`},Et={class:`rounded bg-accented px-1 py-0.5`},Dt={key:3,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},Ot=[`data-biller`],kt={class:`text-sm`},At={key:1,class:`text-muted`},jt={key:2,class:`text-muted`},Mt={key:0,class:`overflow-x-auto`},Nt={class:`data w-full border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},Pt={key:0,class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},Ft={key:1,class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},It=[`title`],Lt={key:0,class:`border-b border-muted px-2.5 py-1 text-right`},Rt={class:`border-b border-muted px-2.5 py-1 text-right`},zt={class:`border-b border-muted px-2.5 py-1 text-right`},Bt={class:`border-b border-muted px-2.5 py-1 text-right`},Vt={key:1,class:`border-b border-muted px-2.5 py-1 text-right`},Ht={class:`border-t border-default pt-3.5 text-xs text-dimmed`},Ut={class:`mt-2 grid gap-1.5`},Wt=[`href`],Gt={key:2},Kt=[`href`],qt={key:2},Jt=[`href`],Yt=[`href`],Xt={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},Zt={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},Qt={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},$t={class:`mb-5 grid gap-2 rounded-lg border border-default bg-elevated px-5 py-4`},en={class:`flex flex-wrap items-center gap-x-3 gap-y-1`},tn={class:`font-mono text-xs tabular-nums text-muted`,"data-snapshot-status":``},nn=[`disabled`],rn={key:1,class:`text-xs text-error`,role:`status`,"data-snapshot-error":``},an=t({__name:`CostsPage`,setup(t){let o=ee(`costs`),l=x(o?.report??null),u=d(()=>o?.groups??[]),O=d(()=>o?.group??l.value?.group??``),M=x(o?.snapshot??null),ce=se(void 0,6e4),N=d(()=>M.value?re(M.value,ce.value):``),P=d(()=>o?.view??`daily`),F=x(o&&o.view!==`daily`?o.by??null:null),I=[{view:`daily`,tab:`Daily`,subtitle:``},{view:`users`,tab:`By user`,subtitle:`Who started the runs · LLM from their tokens through the price table · cloud allocated by wall-clock`},{view:`threads`,tab:`By thread`,subtitle:`The thread each run ran in · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`channels`,tab:`By channel`,subtitle:`The channel each run ran in · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`agents`,tab:`By agent`,subtitle:`The agent each run ran on · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`models`,tab:`By model`,subtitle:`The model each turn ran on · LLM from its tokens through the price table · cloud is not split by model`}],L=d(()=>I.find(e=>e.view===P.value)??I[0]),R=d(()=>o?.canSnapshot===!0),le=d(()=>typeof window>`u`?null:new URLSearchParams(window.location.search).get(`days`)),z=e=>`/costs/${O.value}${e}${le.value?`?days=${le.value}`:``}`,B=o?.snapshot?.snapshot?.takenAt??null,V=B,H=null;async function ue(){try{let[e,t]=await Promise.all([fetch(z(`.json`),{credentials:`same-origin`}),P.value===`daily`?Promise.resolve(null):fetch(z(`/${P.value}.json`),{credentials:`same-origin`})]);return e.ok?(l.value=await e.json(),t?.ok&&(F.value=await t.json()),!0):!1}catch{return!1}}function U(){if(H||V===null||V===B)return;let e=V;H=ue().then(t=>{t&&(B=e)}).finally(()=>{H=null,V!==e&&U()})}function de(e){M.value=e;let t=e.snapshot?.takenAt??null;t&&(V=t,U())}let fe=ae(),W=null;h(()=>{O.value&&(W=fe(`/costs/${O.value}?stream=1`),W.onmessage=e=>{let t=j(e.data);t&&de(t)})}),g(()=>W?.close());let G=x(!1),K=x(``);async function q(){G.value=!0,K.value=``;let e=await oe(fetch,`costs.snapshot`,{});e.ok||(K.value=e.failure.message),G.value=!1}function J(e,t,n){let r=[`days=${t}`];return n!==`daily`&&r.push(`view=${n}`),`/costs/${e}?${r.join(`&`)}`}let Y=d(()=>l.value?T(l.value):[]),X=d(()=>l.value?ie(l.value,Y.value):null),Z=d(()=>l.value?k(l.value):null),pe=d(()=>l.value?w(l.value):[]),Q=d(()=>l.value?te(l.value):null),me=d(()=>l.value?ne(l.value):``);function he(e){let t=Q.value;if(t){if(/^(Memory|vCPU|Disk)/.test(e))return t.containers;if(e.startsWith(`Durable Object`))return t.durableObjects;if(e.startsWith(`Workers`))return t.workers;if(e.startsWith(`R2`))return t.r2;if(e.startsWith(`Workflow`))return t.workflows}}function ge(e){let t=Q.value;if(t)return e===`LLM (Anthropic)`?t.anthropic:e===`Durable Objects`?t.durableObjects:e===`Workers · storage · R2`?t.workers:t.containers}let _e=d(()=>{let e=l.value,t=Z.value;if(!e||!t)return``;let n=t.projection,r=`cloud ${D(n.cloudRate)}/day`,i=n.cloudBasis===`today`?`cloud from today so far`:`cloud from the last 7 full days`;if(!e.llmAvailable)return`${r} × 30.4 · ${i} · before plan fees and included allowances`;let a=`LLM ${D(n.llmRate)}/day`,o=n.llmBasis===`closed-days`?`LLM from ${n.llmClosedDays} closed day${n.llmClosedDays===1?``:`s`}`:n.llmBasis===`today`?`LLM from today so far`:`no LLM spend in range`;return`${r} + ${a} · × 30.4 · ${n.cloudBasis===`today`&&n.llmBasis===`today`?`both from today so far`:`${i} · ${o}`}`}),an=d(()=>l.value?[...l.value.days].reverse():[]),on=d(()=>(l.value?.billers??[]).map(e=>({...e,days:[...e.days].reverse(),unpricedTokens:e.days.reduce((e,t)=>e+(t.unpricedTokens??0),0)}))),sn=[1,7,30],cn=e=>e===1?`today`:`${e}d`,ln=d(()=>{let e=l.value,t=Z.value;if(!e||!t)return``;if(!e.llmAvailable)return`LLM spend not configured`;let n=[];return t.llm.yesterday!==void 0&&n.push(`yesterday ${D(t.llm.yesterday)}`),t.llm.today&&n.push(`today ${D(t.llm.today.usd)}${t.llm.today.estimated?` (estimate)`:``}`),n.length?n.join(` · `):`in range`});function $(e){let t=new Date(`${e}T00:00:00Z`);return Number.isNaN(t.getTime())?e:`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][t.getUTCMonth()]} ${t.getUTCDate()}`}return(t,o)=>{let d=n(`RouterLink`);return l.value&&Z.value?(p(),S(e,{key:0,title:`${l.value.label} spend`,nav:`costs`},{default:a(()=>[v(`div`,ye,[v(`nav`,be,[(p(),y(_,null,b(sn,e=>(p(),y(_,{key:e},[e===l.value.range.days?(p(),y(`span`,xe,i(cn(e)),1)):(p(),S(d,{key:1,class:`rounded-md px-2.5 py-1 font-mono text-xs tabular-nums text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:J(l.value.group,e,P.value)},{default:a(()=>[r(i(cn(e)),1)]),_:2},1032,[`to`]))],64))),64))]),u.value.length>1?(p(),y(`nav`,Se,[(p(!0),y(_,null,b(u.value,e=>(p(),y(_,{key:e},[e===l.value.group?(p(),y(`span`,Ce,i(e),1)):(p(),S(d,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:J(e,l.value.range.days,P.value)},{default:a(()=>[r(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):f(``,!0),v(`p`,we,[r(i($(l.value.range.from))+` → `+i($(l.value.range.to))+` · `+i(l.value.range.days)+`d`,1),l.value.range.partialLastDay?(p(),y(_,{key:0},[r(` · today partial`)],64)):f(``,!0)]),N.value?(p(),y(`div`,Te,[v(`p`,Ee,i(N.value),1),R.value?(p(),y(`button`,{key:0,type:`button`,class:`rounded-md border border-default px-2 py-0.5 text-xs text-muted hover:bg-elevated hover:text-highlighted disabled:cursor-not-allowed disabled:opacity-60`,disabled:G.value||M.value?.inFlight!==null,"data-snapshot-now":``,onClick:q},i(M.value?.inFlight?`Taking…`:`Snapshot now`),9,De)):f(``,!0),K.value?(p(),y(`span`,Oe,i(K.value),1)):f(``,!0)])):f(``,!0)]),v(`section`,ke,[Z.value.yesterday?(p(),y(`div`,Ae,[o[0]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Yesterday`,-1),v(`span`,je,i(m(D)(Z.value.yesterday.total)),1),v(`span`,Me,i(Z.value.yesterday.date)+` · last full day`,1)])):(p(),y(`div`,Ne,[o[1]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Today so far`,-1),v(`span`,Pe,i(Z.value.today?m(D)(Z.value.today.total):`—`),1),v(`span`,Fe,i(Z.value.today?`${Z.value.today.date} · partial day, UTC`:`no day in range`),1)])),v(`div`,Ie,[o[2]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`7-day average`,-1),v(`span`,Le,i(Z.value.avg7===void 0?`—`:m(D)(Z.value.avg7)),1),v(`span`,Re,i(Z.value.avg7===void 0?`no full day yet in this range`:`per day, full days only`),1)]),v(`div`,ze,[o[3]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Projected month`,-1),v(`span`,Be,i(m(D)(Z.value.projection.monthUsd,0)),1),v(`span`,Ve,i(_e.value),1)]),v(`div`,He,[o[4]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`LLM spend`,-1),v(`span`,Ue,i(l.value.llmAvailable?m(D)(Z.value.llm.range):`—`),1),v(`span`,We,i(ln.value),1)]),v(`div`,Ge,[o[6]||=v(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Share of account`,-1),v(`span`,Ke,i(Z.value.accountShare)+`%`,1),v(`span`,qe,[r(i(m(D)(l.value.totals.cloudUsd))+` of `+i(m(D)(l.value.account.cloudUsd))+` on `,1),Q.value?(p(),y(`a`,{key:0,class:`text-primary hover:underline`,href:Q.value.account,target:`_blank`,rel:`noopener noreferrer`,title:`Cloudflare account ${l.value.account.id}`},i(me.value),9,Je)):f(``,!0),o[5]||=r(` · Cloudflare spend in range · `,-1),Q.value?(p(),y(`a`,{key:1,class:`text-primary hover:underline`,href:Q.value.billing,target:`_blank`,rel:`noopener noreferrer`},`billing`,8,Ye)):f(``,!0)])])]),v(`section`,Xe,[v(`div`,Ze,[o[7]||=v(`div`,null,[v(`h2`,{class:`text-[0.9375rem] font-medium`},`Daily cost`),v(`p`,{class:`text-sm text-muted`},`Stacked by component · USD list price`)],-1),v(`div`,Qe,[(p(!0),y(_,null,b(Y.value,(e,t)=>(p(),y(`a`,{key:e,class:`inline-flex items-center gap-1.5 no-underline hover:text-highlighted hover:underline`,href:ge(e),target:`_blank`,rel:`noopener noreferrer`,title:`Open where ${e} is billed`},[v(`i`,{class:s([`inline-block size-2.5 rounded-xs`,m(C)[t%m(C).length]])},null,2),r(i(e),1)],8,$e))),128))])]),X.value?(p(),S(A,{key:0,model:X.value,label:`Daily cost, stacked by component`},null,8,[`model`])):f(``,!0),l.value.llmAvailable?l.value.days.some(e=>e.llmEstimated)?(p(),y(`p`,tt,[o[9]||=r(` A day the Anthropic cost report has not closed yet (today, and yesterday until a few hours after midnight UTC) shows its LLM figure as an estimate: the hourly usage report priced at list. The closed days are the cost report itself. `,-1),l.value.days.some(e=>e.llmUnpricedTokens>0)?(p(),y(_,{key:0},[r(` Some tokens ran under a model this page has no price for and are not in the estimate. `)],64)):f(``,!0)])):f(``,!0):(p(),y(`p`,et,[...o[8]||=[r(` LLM spend not configured — set `,-1),v(`code`,null,`ANTHROPIC_ADMIN_KEY`,-1),r(` and the group's `,-1),v(`code`,null,`anthropicWorkspaceId`,-1),r(` to layer it in. `,-1)]]))]),v(`nav`,nt,[(p(),y(_,null,b(I,e=>(p(),y(_,{key:e.view},[e.view===P.value?(p(),y(`span`,rt,i(e.tab),1)):(p(),S(d,{key:1,class:`-mb-px border-b-2 border-transparent px-3 py-1.5 text-sm text-muted no-underline hover:border-muted hover:text-highlighted`,to:J(l.value.group,l.value.range.days,e.view)},{default:a(()=>[r(i(e.tab),1)]),_:2},1032,[`to`]))],64))),64))]),P.value===`daily`?f(``,!0):(p(),y(`section`,it,[v(`div`,null,[v(`h2`,at,`Cost `+i(L.value.tab.toLowerCase()),1),v(`p`,ot,i(L.value.subtitle),1)]),F.value?(p(),S(ve,{key:0,report:F.value},null,8,[`report`])):(p(),y(`p`,st,` The `+i(L.value.tab.toLowerCase())+` report did not load with this page. `,1)),v(`p`,ct,[o[10]||=r(` Machine-readable twin: `,-1),v(`code`,lt,`GET /costs/`+i(l.value.group)+`/`+i(P.value)+`.json`,1),o[11]||=r(` (same Access gate). `,-1)])])),P.value===`daily`?(p(),y(`section`,ut,[o[12]||=v(`div`,null,[v(`h2`,{class:`text-[0.9375rem] font-medium`},`What each cloud dollar buys`)],-1),v(`table`,dt,[v(`tbody`,null,[(p(!0),y(_,null,b(pe.value,e=>(p(),y(`tr`,{key:e.label,class:`border-b border-muted`},[v(`td`,ft,[he(e.label)?(p(),y(`a`,{key:0,class:`no-underline hover:text-highlighted hover:underline`,href:he(e.label),target:`_blank`,rel:`noopener noreferrer`,title:`Open where this is billed on Cloudflare`},i(e.label),9,pt)):(p(),y(_,{key:1},[r(i(e.label),1)],64))]),v(`td`,mt,i(m(D)(e.usd)),1),v(`td`,ht,i(Math.round(e.percent))+`%`,1),v(`td`,gt,[v(`i`,{class:`block h-2.5 rounded-xs bg-primary opacity-75`,style:c({width:`${e.percent.toFixed(1)}%`})},null,4)])]))),128))])])])):f(``,!0),P.value===`daily`?(p(),y(`section`,_t,[v(`details`,vt,[o[15]||=v(`summary`,{class:`cursor-pointer text-sm text-muted`},`Table view — daily cost by component (USD)`,-1),v(`div`,yt,[v(`table`,bt,[v(`thead`,null,[v(`tr`,null,[o[13]||=v(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},` Date `,-1),(p(!0),y(_,null,b(Y.value,e=>(p(),y(`th`,{key:e,class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},i(e),1))),128)),o[14]||=v(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Total `,-1)])]),v(`tbody`,null,[(p(!0),y(_,null,b(an.value,e=>(p(),y(`tr`,{key:e.date},[v(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.date},[r(i($(e.date))+` `,1),l.value.range.partialLastDay&&e.date===l.value.range.to?(p(),y(`span`,St,`(partial day`+i(e.llmEstimated?` · LLM estimated`:``)+`)`,1)):e.llmEstimated?(p(),y(`span`,Ct,`(LLM estimated)`)):f(``,!0)],8,xt),(p(!0),y(_,null,b(Y.value,t=>(p(),y(`td`,{key:t,class:`border-b border-muted px-2.5 py-1.5 text-right`},i(m(D)(m(E)(e,t),3)),1))),128)),v(`td`,wt,i(m(D)(e.total,3)),1)]))),128))])])])]),v(`p`,Tt,[o[16]||=r(` Machine-readable twin: `,-1),v(`code`,Et,`GET /costs/`+i(l.value.group)+`.json`,1),o[17]||=r(` (same Access gate). `,-1)])])):f(``,!0),P.value===`daily`&&on.value.length?(p(),y(`section`,Dt,[o[22]||=v(`div`,null,[v(`h2`,{class:`text-[0.9375rem] font-medium`},`Invoice tie-out by biller`),v(`p`,{class:`text-xs text-muted`},[r(` Each biller's own invoice beside the summed `),v(`code`,null,`model.turn`),r(` dollars its runs attributed — an aggregator's fee against the summed fees, its BYOK upstream against the remainder. Attributed is the meter's charged figure — each turn's own `),v(`code`,null,`usd`),r(` (the provider's, the operator's or the registry's price at the time) — never the price table's repricing the dimension tabs show, so the two need not agree. `)])],-1),(p(!0),y(_,null,b(on.value,e=>(p(),y(`div`,{key:e.biller,class:`grid gap-1.5`,"data-biller":e.biller},[v(`p`,kt,[v(`b`,null,i(e.biller),1),e.invoice?(p(),y(_,{key:0},[r(` · invoice `+i(m(D)(e.totals.invoiceUsd,4))+` · attributed `+i(m(D)(e.totals.attributedUsd,4)),1)],64)):(p(),y(`span`,At,` · no invoice — the block names no invoice source`)),e.unpricedTokens>0?(p(),y(`span`,jt,` · `+i(e.unpricedTokens.toLocaleString(`en-US`))+` tokens unpriced — not in the attributed figure`,1)):f(``,!0)]),e.days.length?(p(),y(`div`,Mt,[v(`table`,Nt,[v(`thead`,null,[v(`tr`,null,[o[18]||=v(`th`,{class:`border-b border-muted px-2.5 py-1 text-left text-xs font-medium text-muted`},`Date`,-1),e.invoice?(p(),y(`th`,Pt,` Invoice `)):f(``,!0),o[19]||=v(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},`Attributed`,-1),o[20]||=v(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},` Fee (invoice / rows) `,-1),o[21]||=v(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},` Upstream (invoice / remainder) `,-1),e.unpricedTokens>0?(p(),y(`th`,Ft,` Unpriced tokens `)):f(``,!0)])]),v(`tbody`,null,[(p(!0),y(_,null,b(e.days,t=>(p(),y(`tr`,{key:t.date},[v(`td`,{class:`border-b border-muted px-2.5 py-1`,title:t.date},i($(t.date)),9,It),e.invoice?(p(),y(`td`,Lt,i(t.invoiceUsd===void 0?`—`:m(D)(t.invoiceUsd,4)),1)):f(``,!0),v(`td`,Rt,i(m(D)(t.attributedUsd,4)),1),v(`td`,zt,[t.invoiceFeeUsd!==void 0||t.attributedFeeUsd!==void 0?(p(),y(_,{key:0},[r(i(t.invoiceFeeUsd===void 0?`—`:m(D)(t.invoiceFeeUsd,4))+` / `+i(t.attributedFeeUsd===void 0?`—`:m(D)(t.attributedFeeUsd,4)),1)],64)):(p(),y(_,{key:1},[r(`—`)],64))]),v(`td`,Bt,[t.invoiceByokUsd!==void 0||t.attributedUpstreamUsd!==void 0?(p(),y(_,{key:0},[r(i(t.invoiceByokUsd===void 0?`—`:m(D)(t.invoiceByokUsd,4))+` / `+i(t.attributedUpstreamUsd===void 0?`—`:m(D)(t.attributedUpstreamUsd,4)),1)],64)):(p(),y(_,{key:1},[r(`—`)],64))]),e.unpricedTokens>0?(p(),y(`td`,Vt,i((t.unpricedTokens??0).toLocaleString(`en-US`)),1)):f(``,!0)]))),128))])])])):f(``,!0)],8,Ot))),128))])):f(``,!0),v(`footer`,Ht,[v(`details`,null,[o[30]||=v(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),v(`div`,Ut,[o[28]||=v(`div`,null,[v(`b`,null,`Snapshot.`),r(` Both billing sources and the run history are read once over the widest range this page offers and kept as a snapshot; every figure here, the JSON twins and the dimension tabs are arithmetic over it, with `),v(`em`,null,`today`),r(` the day it was taken. The line under the range says when that was, how old it is and when the next one is due (`),v(`code`,null,`costs.snapshot.everyHours`),r(`, daily by default); `),v(`code`,null,`costs snapshot`),r(` takes one now. Cloudflare bills vCPU on active use only; memory and disk bill on the provisioned size for every second a container is awake. LLM spend is the Anthropic Admin API cost report for this group's workspace (gross, USD); a day the cost report has not closed is the Admin API usage report, hourly, priced at Anthropic list per model (input, output, cache writes, cache reads) and marked as an estimate. The invoice tie-out's attributed side is different money: the meter's charged figure from each turn's own `),v(`code`,null,`usd`),r(`, never the price table's repricing the dimension tabs show, with the tokens no turn priced counted beside it as unpriced. `)],-1),o[29]||=v(`div`,null,[v(`b`,null,`Method.`),r(` Cloudflare GraphQL Analytics, every meter a Workers deployment is billed on: `),v(`code`,null,`containersUsageAdaptiveGroups`),r(` (cpuTimeSec, allocatedMemory, allocatedDisk per app per UTC day), `),v(`code`,null,`durableObjectsPeriodicGroups`),r(` (billable `),v(`code`,null,`duration`),r(` GB-s and SQLite rows read and written per namespace), `),v(`code`,null,`durableObjectsInvocationsAdaptiveGroups`),r(` (requests per namespace), `),v(`code`,null,`durableObjectsSqlStorageGroups`),r(` (bytes stored), `),v(`code`,null,`workersInvocationsAdaptive`),r(` (requests, CPU time), `),v(`code`,null,`r2StorageAdaptiveGroups`),r(` and `),v(`code`,null,`r2OperationsAdaptiveGroups`),r(` (bytes stored, class A/B operations). Prices: vCPU $0.000020/s, memory $0.0000025/GiB-s, disk $0.00000007/GB-s, DO duration $12.50 per million GB-s, DO requests $0.15/M, SQLite rows $0.001/M read and $1.00/M written, DO storage $0.20/GB-month, Workers $0.30/M requests and $0.02/M CPU-ms, R2 $0.015/GB-month, $4.50/M class A and $0.36/M class B (deletes free). Storage is the day's peak, prorated over a 30.44-day month. Gross list price — plan fees and included allowances are not subtracted; Workers Logs volume has no analytics dataset and is not priced. `)],-1),v(`div`,null,[o[23]||=v(`b`,null,`Scope.`,-1),o[24]||=r(` Attributed to this group: the Workers `,-1),(p(!0),y(_,null,b(l.value.attribution.workers,(e,t)=>(p(),y(_,{key:e},[t>0?(p(),y(_,{key:0},[r(`, `)],64)):f(``,!0),Q.value?(p(),y(`a`,{key:1,class:`font-mono hover:underline`,href:Q.value.worker(e),target:`_blank`,rel:`noopener noreferrer`},i(e),9,Wt)):(p(),y(`code`,Gt,i(e),1))],64))),128)),r(`, every Durable Object namespace they host (`+i(Object.keys(l.value.attribution.durableObjectNamespaces).length)+`), the R2 buckets named after them (`,1),(p(!0),y(_,null,b(Object.keys(l.value.attribution.r2Buckets),(e,t)=>(p(),y(_,{key:e},[t>0?(p(),y(_,{key:0},[r(`, `)],64)):f(``,!0),Q.value?(p(),y(`a`,{key:1,class:`font-mono hover:underline`,href:Q.value.bucket(e),target:`_blank`,rel:`noopener noreferrer`},i(e),9,Kt)):(p(),y(`code`,qt,i(e),1))],64))),128)),Object.keys(l.value.attribution.r2Buckets).length===0?(p(),y(_,{key:0},[r(`none`)],64)):f(``,!0),o[25]||=r(`), and the container apps mapped in `,-1),v(`code`,null,`costs.groups.`+i(l.value.group),1),r(` (`+i(Object.keys(l.value.attribution.containerApps).length)+`). Everything else in the account is priced the same way into the account total, which is what "share of account" divides by. Every figure above links to where it is billed: the `,1),Q.value?(p(),y(`a`,{key:1,class:`hover:underline`,href:Q.value.account,target:`_blank`,rel:`noopener noreferrer`},`Cloudflare dashboard`,8,Jt)):f(``,!0),o[26]||=r(` for the account `,-1),v(`code`,null,i(l.value.account.id),1),r(i(l.value.account.name?` (${l.value.account.name})`:``)+`, and `,1),Q.value?(p(),y(`a`,{key:2,class:`hover:underline`,href:Q.value.anthropic,target:`_blank`,rel:`noopener noreferrer`},`Anthropic's cost page`,8,Yt)):f(``,!0),o[27]||=r(` for the LLM line. `,-1)])])])])]),_:1},8,[`title`])):(p(),S(e,{key:1,title:`${O.value} spend`,nav:`costs`},{default:a(()=>[v(`div`,Xt,[u.value.length>1?(p(),y(`nav`,Zt,[(p(!0),y(_,null,b(u.value,e=>(p(),y(_,{key:e},[e===O.value?(p(),y(`span`,Qt,i(e),1)):(p(),S(d,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:`/costs/${e}`},{default:a(()=>[r(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):f(``,!0)]),v(`section`,$t,[o[31]||=v(`h2`,{class:`text-sm font-medium text-highlighted`},`Nothing to show yet`,-1),v(`div`,en,[v(`p`,tn,i(N.value),1),R.value?(p(),y(`button`,{key:0,type:`button`,class:`rounded-md border border-default px-2 py-0.5 text-xs text-muted hover:bg-elevated hover:text-highlighted disabled:cursor-not-allowed disabled:opacity-60`,disabled:G.value||M.value?.inFlight!==null,"data-snapshot-now":``,onClick:q},i(M.value?.inFlight?`Taking…`:`Snapshot now`),9,nn)):f(``,!0),K.value?(p(),y(`span`,rn,i(K.value),1)):f(``,!0)]),o[32]||=v(`p`,{class:`text-xs text-dimmed`},[r(` The page prices a stored snapshot of both billing sources, never a live read; the figures appear here the moment the first one lands (this page listens for it), or take one now with `),v(`code`,null,`costs snapshot`),r(`. `)],-1)])]),_:1},8,[`title`]))}}});export{an as default};
@@ -1 +0,0 @@
1
- import{t as e}from"./AppShell-CCPwPqvc.js";import{An as t,Cr as n,Dn as r,Fi as i,Jr as a,On as o,_n as s,bn as ee,hr as c,ki as l,o as u,sn as d,vn as f,xn as p,xr as m,yn as h}from"./browser-BWnzWwaT.js";import{_ as g,a as te,c as ne,d as re,g as ie,l as ae,m as _,n as oe,o as v,s as se,u as ce,v as y}from"./main-DYwKyLY5.js";import{t as b}from"./StatusDot-BIAQN7iD.js";var le={class:`mt-4 first:mt-0`},ue={class:`w-full border-collapse font-mono text-[0.8125rem]`},de={class:`border-t border-muted`},fe={class:`px-2 py-1 align-top`},pe={class:`ml-1.5 font-medium`},me={class:`border-t border-muted`},x={class:`break-all px-2 py-1 align-top`},S={key:0},C={key:1,class:`text-dimmed`},w={class:`border-t border-muted`},T={class:`break-all px-2 py-1 align-top`},E={key:0},D={key:1,class:`text-dimmed`},O={class:`border-t border-muted`},k={class:`break-all px-2 py-1 align-top`},A={key:0},j={key:1,class:`text-dimmed`},M={class:`border-t border-muted`},N={class:`break-all px-2 py-1 align-top`},P={key:0},F={key:1,class:`text-dimmed`},I={class:`border-t border-muted`},L={class:`break-all px-2 py-1 align-top`},R={key:1,class:`text-dimmed`},z={class:`mt-4`},he={class:`w-full border-collapse font-mono text-[0.8125rem]`},ge={class:`border-t border-muted`},_e={class:`break-all px-2 py-1 align-top`},ve=[`href`],ye={key:1},be={class:`border-t border-muted`},xe={class:`break-all px-2 py-1 align-top`},Se={class:`border-t border-muted`},Ce={class:`break-all px-2 py-1 align-top`},we=[`href`],Te={key:1},Ee={key:2,class:`text-dimmed`},De={class:`border-t border-muted`},Oe={class:`break-all px-2 py-1 align-top`},ke={key:0},Ae={key:1,class:`text-dimmed`},je={class:`border-t border-muted`},Me={class:`break-all px-2 py-1 align-top`},Ne={key:0},Pe={key:1,class:`text-dimmed`},Fe={class:`border-t border-muted`},Ie={class:`break-all px-2 py-1 align-top`},Le={key:0},Re={key:1,class:`text-dimmed`},ze={class:`mt-4`},Be={class:`w-full border-collapse font-mono text-[0.8125rem]`},Ve={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},He={class:`break-all px-2 py-1 align-top`},Ue={class:`w-full border-collapse font-mono text-[0.8125rem]`},We={class:`w-32 break-all px-2 py-1 align-top text-muted sm:w-96 sm:break-words`},Ge={class:`px-2 py-1 align-top`},Ke={key:1,class:`text-xs text-muted`},qe={class:`mt-4`},Je={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Ye={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},B={class:`break-all px-2 py-1 align-top`},Xe={key:0},Ze={key:1,class:`text-dimmed`},Qe={key:1,class:`text-xs text-muted`},$e={class:`mt-4`},et={class:`mb-1 text-xs text-muted`},tt={class:`overflow-x-auto`},nt={class:`w-full border-collapse font-mono text-[0.8125rem]`},rt={class:`break-all px-2 py-1 align-top`},it={key:0,class:`text-xs text-muted`},at={class:`break-all px-2 py-1 align-top`},ot=[`href`],st={key:1},ct={key:2,class:`text-dimmed`},lt={class:`break-all px-2 py-1 align-top`},ut={key:0},dt={key:1,class:`text-dimmed`},ft={key:2},pt={key:3,class:`text-dimmed`},mt={class:`break-all px-2 py-1 align-top`},ht={key:0},gt={key:1,class:`text-dimmed`},_t={key:2},vt={key:3,class:`text-dimmed`},yt={key:1,class:`text-xs text-muted`},bt={class:`mt-4`},xt={class:`w-full border-collapse font-mono text-[0.8125rem]`},St={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Ct={class:`px-2 py-1 align-top`},wt={class:`mt-4`},Tt={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Et={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Dt={class:`break-all px-2 py-1 align-top`},Ot={class:`text-xs text-muted`},kt={key:1,class:`text-xs text-muted`},At={class:`mt-4`},jt={class:`w-full border-collapse font-mono text-[0.8125rem]`},Mt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Nt={class:`break-all px-2 py-1 align-top`},Pt={key:0},Ft={key:1,class:`text-dimmed`},It={class:`mt-4 text-xs text-muted`},Lt={class:`rounded bg-elevated px-1 py-0.5`},Rt={class:`rounded bg-elevated px-1 py-0.5`},zt={class:`rounded bg-elevated px-1 py-0.5`},V=t({__name:`ResidentDetailPage`,setup(t){let V=u(`resident`),H=s(()=>V?.record??{}),U=s(()=>ne(H.value)),W=s(()=>ae(H.value)||(V?.slug??``)),G=s(()=>_(U.value.sha)),K=s(()=>oe.test(W.value)?`https://github.com/${W.value}`:void 0),q=s(()=>K.value&&/^[0-9a-f]{7,40}$/.test(G.value)?`${K.value}/commit/${G.value}`:void 0),J=s(()=>{let e=U.value.snapshot;return e&&typeof e==`object`?v(e):void 0}),Bt=s(()=>v(U.value.schedules)),Y=s(()=>{let e=v(H.value.commands),t=v(H.value.effects);return Object.keys(e).sort().map(n=>({name:n,command:_(e[n]),effect:_(t[n])||`readonly`}))}),X=s(()=>re(H.value).map(e=>({...e,threadKey:e.threadKey||`?`,ref:e.ref||`?`,sha:e.sha?e.sha.slice(0,8):``,commitHref:K.value&&/^[0-9a-f]{7,40}$/.test(e.sha)?`${K.value}/commit/${e.sha}`:void 0}))),Z=s(()=>X.value.filter(e=>!e.evicted).length),Q=s(()=>{let e=U.value.lastRestore;return e?JSON.stringify(e):``}),$=s(()=>se(H.value)),Vt=s(()=>typeof H.value.diskBudgetMb==`number`?H.value.diskBudgetMb:void 0),Ht=s(()=>{let e=$.value;if(!e)return[];let t=te(e,Vt.value),n=n=>{let r=t.room[n];return r===null?y(e.parts,n)===null?`? (checkout not measured)`:`?`:`${r} more (${g(y(e.parts,n))} each)`};return[[`used / total`,ie(e)],[`free`,`${g(t.freeKiB)}${t.capped?` under the ${g(t.capacityKiB)} diskBudgetMb cap`:``}`],[`reserve`,`${g(t.reserve.totalKiB)} (snapshot staging ${g(t.reserve.stagingKiB)} + floor ${g(t.reserve.floorKiB)})`],[`headroom`,`${g(t.headroomKiB)} — room for ${n(`hardlink`)} hardlinked trees, ${n(`reconcile`)} lockfile-diverged (reconciling)`],[`measured`,e.at||`—`]]}),Ut=s(()=>{let e=$.value;if(!e)return[];let t=[[`mirror`,g(e.parts.mirror)],[`checkout deps (node_modules)`,g(e.parts.deps)],[`checkout (history + tree + build)`,g(e.parts.checkout)]];for(let[n,r]of Object.entries(e.parts.threads).sort((e,t)=>t[1]-e[1]))t.push([`thread ${n}`,g(r)]);for(let[n,r]of Object.entries(e.parts.homes).sort((e,t)=>t[1]-e[1]))r>=1024&&t.push([`home ${n}`,g(r)]);return t.push([`other (image, /tmp, …)`,g(e.parts.other)]),t});return(t,s)=>{let u=n(`RouterLink`);return c(),h(e,{title:W.value||`Resident`,nav:`residents`},{leading:a(()=>[o(u,{class:`back text-sm text-muted no-underline hover:text-primary`,to:`/residents`},{default:a(()=>[...s[0]||=[r(`← All residents`,-1)]]),_:1})]),default:a(()=>[f(`section`,le,[s[8]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Lifecycle`,-1),f(`table`,ue,[f(`tbody`,null,[f(`tr`,de,[s[1]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state`,-1),f(`td`,fe,[o(b,{tone:l(ce)(U.value.state),label:U.value.state},null,8,[`tone`,`label`]),f(`span`,pe,i(U.value.state),1)])]),f(`tr`,me,[s[2]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`reason`,-1),f(`td`,x,[U.value.reason?(c(),p(`span`,S,i(U.value.reason),1)):(c(),p(`span`,C,`—`))])]),f(`tr`,w,[s[3]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh error`,-1),f(`td`,T,[l(_)(U.value.lastRefreshError)?(c(),p(`span`,E,i(l(_)(U.value.lastRefreshError)),1)):(c(),p(`span`,D,`—`))])]),f(`tr`,O,[s[4]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last restore`,-1),f(`td`,k,[Q.value?(c(),p(`span`,A,i(Q.value),1)):(c(),p(`span`,j,`—`))])]),f(`tr`,M,[s[5]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state updated`,-1),f(`td`,N,[l(_)(U.value.updatedAt)?(c(),p(`span`,P,i(l(_)(U.value.updatedAt)),1)):(c(),p(`span`,F,`—`))])]),f(`tr`,I,[s[7]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`idle since`,-1),f(`td`,L,[l(_)(U.value.idleSince)?(c(),p(d,{key:0},[r(i(l(_)(U.value.idleSince))+` `,1),s[6]||=f(`span`,{class:`text-xs text-muted`},`(refresh parked; container may sleep)`,-1)],64)):(c(),p(`span`,R,`awake`))])])])])]),f(`section`,z,[s[15]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pinned facts`,-1),f(`table`,he,[f(`tbody`,null,[f(`tr`,ge,[s[9]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`repository`,-1),f(`td`,_e,[K.value?(c(),p(`a`,{key:0,class:`text-primary`,href:K.value},i(K.value),9,ve)):(c(),p(`span`,ye,i(l(_)(H.value.resource)||`—`),1))])]),f(`tr`,be,[s[10]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`default ref`,-1),f(`td`,xe,i(l(_)(U.value.defaultRef)||l(_)(H.value.defaultRef)||`—`),1)]),f(`tr`,Se,[s[11]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`pinned sha`,-1),f(`td`,Ce,[q.value?(c(),p(`a`,{key:0,class:`text-primary`,href:q.value},i(G.value),9,we)):G.value?(c(),p(`span`,Te,i(G.value),1)):(c(),p(`span`,Ee,`—`))])]),f(`tr`,De,[s[12]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`lockfile hash`,-1),f(`td`,Oe,[l(_)(U.value.lockfileHash)?(c(),p(`span`,ke,i(l(_)(U.value.lockfileHash)),1)):(c(),p(`span`,Ae,`—`))])]),f(`tr`,je,[s[13]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`provisioned`,-1),f(`td`,Me,[l(_)(U.value.provisionedAt)?(c(),p(`span`,Ne,i(l(_)(U.value.provisionedAt)),1)):(c(),p(`span`,Pe,`—`))])]),f(`tr`,Fe,[s[14]||=f(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh`,-1),f(`td`,Ie,[l(_)(U.value.lastRefreshAt)?(c(),p(`span`,Le,i(l(_)(U.value.lastRefreshAt)),1)):(c(),p(`span`,Re,`—`))])])])])]),f(`section`,ze,[s[17]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Disk`,-1),$.value?(c(),p(d,{key:0},[f(`table`,Be,[f(`tbody`,null,[(c(!0),p(d,null,m(Ht.value,([e,t])=>(c(),p(`tr`,{key:e,class:`border-t border-muted`},[f(`td`,Ve,i(e),1),f(`td`,He,i(t),1)]))),128))])]),s[16]||=f(`p`,{class:`mb-1 mt-2 text-xs text-muted`},` components (one du, hardlinks counted once — a thread tree shows only what it does not share with the checkout) `,-1),f(`table`,Ue,[f(`tbody`,null,[(c(!0),p(d,null,m(Ut.value,([e,t])=>(c(),p(`tr`,{key:e,class:`border-t border-muted`},[f(`td`,We,i(e),1),f(`td`,Ge,i(t),1)]))),128))])])],64)):(c(),p(`p`,Ke,` not measured yet — the first refresh cycle or attach of this container measures it `))]),f(`section`,qe,[s[18]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Snapshot stamp`,-1),J.value?(c(),p(`table`,Je,[f(`tbody`,null,[(c(),p(d,null,m([`ref`,`sha`,`lockfileHash`,`createdAt`,`mirrorBackupId`,`checkoutBackupId`],e=>f(`tr`,{key:e,class:`border-t border-muted`},[f(`td`,Ye,i(e),1),f(`td`,B,[l(_)(J.value[e])?(c(),p(`span`,Xe,i(l(_)(J.value[e])),1)):(c(),p(`span`,Ze,`—`))])])),64))])])):(c(),p(`p`,Qe,`no snapshot recorded`))]),f(`section`,$e,[s[22]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Thread worktrees`,-1),X.value.length>0?(c(),p(d,{key:0},[f(`p`,et,i(Z.value)+` live · `+i(X.value.length-Z.value)+` evicted`,1),f(`div`,tt,[f(`table`,nt,[f(`tbody`,null,[s[21]||=f(`tr`,{class:`text-xs text-muted`},[f(`td`,{class:`px-2 py-1`},`thread`),f(`td`,{class:`px-2 py-1`},`ref · sha`),f(`td`,{class:`px-2 py-1`},`user · deps`),f(`td`,{class:`px-2 py-1`},`bound · last attach`)],-1),(c(!0),p(d,null,m(X.value,e=>(c(),p(`tr`,{key:e.threadKey,class:`border-t border-muted`},[f(`td`,rt,[e.evicted?(c(),p(`span`,it,[r(`evicted `+i(e.evictedAt||`—`),1),e.evictedWhy?(c(),p(d,{key:0},[r(` · `+i(e.evictedWhy),1)],64)):ee(``,!0)])):(c(),h(b,{key:1,tone:`green`,label:`live`,tip:`live`})),r(` `+i(e.threadKey),1)]),f(`td`,at,[r(i(e.ref)+` · `,1),e.commitHref?(c(),p(`a`,{key:0,class:`text-primary`,href:e.commitHref},i(e.sha),9,ot)):e.sha?(c(),p(`span`,st,i(e.sha),1)):(c(),p(`span`,ct,`—`))]),f(`td`,lt,[e.user?(c(),p(`span`,ut,i(e.user),1)):(c(),p(`span`,dt,`—`)),s[19]||=r(` · `,-1),e.deps?(c(),p(`span`,ft,i(e.deps),1)):(c(),p(`span`,pt,`—`))]),f(`td`,mt,[e.boundAt?(c(),p(`span`,ht,i(e.boundAt),1)):(c(),p(`span`,gt,`—`)),s[20]||=r(` · `,-1),e.lastAttachAt?(c(),p(`span`,_t,i(e.lastAttachAt),1)):(c(),p(`span`,vt,`—`))])]))),128))])])])],64)):(c(),p(`p`,yt,`no thread worktrees`))]),f(`section`,bt,[s[23]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pending schedules`,-1),f(`table`,xt,[f(`tbody`,null,[(c(),p(d,null,m([[`refresh`,`refresh`],[`provision run`,`provisionRun`],[`provision deadline`,`provisionDeadline`]],([e,t])=>f(`tr`,{key:t,class:`border-t border-muted`},[f(`td`,St,i(e),1),f(`td`,Ct,i(l(_)(Bt.value[t]??0)||`0`),1)])),64))])])]),f(`section`,wt,[s[25]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Command table`,-1),Y.value.length>0?(c(),p(`table`,Tt,[f(`tbody`,null,[(c(!0),p(d,null,m(Y.value,e=>(c(),p(`tr`,{key:e.name,class:`border-t border-muted`},[f(`td`,Et,i(e.name),1),f(`td`,Dt,[f(`code`,null,i(e.command),1),s[24]||=r(),f(`span`,Ot,i(e.effect),1)])]))),128))])])):(c(),p(`p`,kt,`no command table`))]),f(`section`,At,[s[26]||=f(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Registry settings`,-1),f(`table`,jt,[f(`tbody`,null,[(c(!0),p(d,null,m([[`onboarded`,l(_)(H.value.onboardedAt)],[`record updated`,l(_)(H.value.updatedAt)],[`provisioning timeout (ms)`,l(_)(H.value.provisioningTimeoutMs)],[`disk budget (MB)`,l(_)(H.value.diskBudgetMb)],[`worktree TTL (days)`,l(_)(H.value.worktreeTtlDays??7)]],([e,t])=>(c(),p(`tr`,{key:e,class:`border-t border-muted`},[f(`td`,Mt,i(e),1),f(`td`,Nt,[t?(c(),p(`span`,Pt,i(t),1)):(c(),p(`span`,Ft,`—`))])]))),128))])])]),f(`p`,It,[s[27]||=r(` Manage from chat: `,-1),f(`code`,Lt,`repo rebuild `+i(W.value),1),s[28]||=r(` · `,-1),f(`code`,Rt,`repo reconfigure `+i(W.value)+` …`,1),s[29]||=r(` · `,-1),f(`code`,zt,`repo offboard `+i(W.value)+` --dry-run`,1)])]),_:1},8,[`title`])}}});export{V as default};
@@ -1 +0,0 @@
1
- import{t as e}from"./AppShell-CCPwPqvc.js";import{An as t,Cr as n,Dn as r,Fi as i,Jr as a,Mi as o,On as s,Ur as c,_i as l,_n as u,bn as d,hr as f,ki as p,lr as m,o as h,pr as g,sn as _,t as v,tn as y,vn as b,xn as x,xr as S,yi as C,yn as w}from"./browser-BWnzWwaT.js";import{t as ee}from"./Tooltip-CxiQ7luL.js";import{_ as T,a as E,c as D,d as O,f as k,g as A,h as j,i as M,l as N,m as P,n as F,p as I,r as L,s as te,u as ne,y as R}from"./main-DYwKyLY5.js";import{t as z}from"./eventSource-Ds6_gjPD.js";import{t as B}from"./wallClock-DaewxNMY.js";import{n as V,r as re}from"./indexFormat-B-pd4r7Y.js";import{A as ie,C as H,D as ae,S as oe,a as se,c as ce,i as le,l as ue,t as de,x as fe}from"./indexRow-BGjjLnN5.js";import"./format-BldUwl_R.js";import{t as U}from"./StatusDot-BIAQN7iD.js";var pe=[`data-slug`,`data-running`],me=[`open`],he={class:`row flex cursor-pointer list-none flex-wrap items-baseline gap-x-2.5 gap-y-1 rounded-md px-2 py-2 hover:bg-elevated [&::-webkit-details-marker]:hidden`},ge={class:`self-center`},_e={class:`font-mono text-[0.9375rem] font-medium text-highlighted`},ve={class:`text-sm text-toned`},ye={key:0,class:`running shrink-0 rounded border border-ok/25 bg-ok/8 px-1.5 font-mono text-[0.68rem] font-medium tabular-nums text-ok`},be=[`title`],xe={key:2,class:`basis-full pl-[1.9rem] text-xs text-warn`},Se={class:`fold pb-3 pl-[1.9rem] pr-2 pt-0.5`},Ce={key:0,class:`m-0 list-none divide-y divide-(--ui-border-muted) p-0`},we=[`data-run-id`,`data-thread`],Te={class:`pt-[0.3rem]`},Ee={class:`what min-w-0`},De={class:`flex min-w-0 items-baseline gap-2`},Oe=[`title`],ke={key:0,class:`who block truncate text-xs text-dimmed`},Ae=[`href`],je={key:1,class:`who block text-xs text-dimmed`},Me={class:`min-w-0 font-mono text-xs max-sm:col-span-2 max-sm:col-start-2 max-sm:row-start-2`},Ne=[`title`],Pe=[`href`],Fe={key:1},Ie={key:1,class:`font-sans text-dimmed`},Le={key:0,class:`facts-tree block truncate text-dimmed`},Re={class:`user`},ze={class:`deps`},Be=[`title`],Ve={class:`flex items-baseline gap-3 justify-self-end max-sm:col-start-3 max-sm:row-start-1`},He=[`title`],Ue={key:1,class:`py-1 text-xs text-dimmed`},We=[`data-idle`],Ge={key:1},W=t({__name:`ResidentRow`,props:{record:{},runs:{},now:{},open:{type:Boolean}},setup(e){let t=e,l=C(t.open===!0);c(()=>t.open,e=>{e&&(l.value=!0)});function m(e){l.value=e.target.open}let h=u(()=>N(t.record)),g=u(()=>h.value||P(t.record.resource)||`?`),v=u(()=>D(t.record)),ee=u(()=>ne(v.value.state)),k=u(()=>F.test(h.value)?`/residents/${h.value}`:null),I=u(()=>F.test(h.value)?`https://github.com/${h.value}`:void 0),L=e=>I.value&&/^[0-9a-f]{7,40}$/.test(e)?`${I.value}/commit/${e}`:void 0,R=u(()=>P(t.record.defaultRef)||`?`),z=u(()=>P(v.value.sha).slice(0,8)),B=u(()=>P(v.value.lastRefreshAt)),W=e=>{let n=e?Date.parse(e):NaN;return Number.isFinite(n)?V(n,t.now):e||`—`},G=u(()=>B.value?W(B.value):``),K=u(()=>te(t.record)),q=u(()=>K.value?A(K.value):``),J=u(()=>{let e=K.value;if(!e)return null;let n=typeof t.record.diskBudgetMb==`number`?t.record.diskBudgetMb:void 0;return E(e,n)}),Y=u(()=>[`ref ${R.value}`,z.value,G.value?`refreshed ${G.value}`:``,q.value?`disk ${q.value}`:``].filter(Boolean).join(` · `)),X=u(()=>[B.value?`refreshed ${B.value}`:``,K.value?.at?`disk measured ${K.value.at}`:``].filter(Boolean).join(` · `)),Z=u(()=>{let e=K.value,t=J.value;if(!e||!t)return``;let n=t.room.hardlink===null?`room not projected (checkout not measured)`:`room for ${t.room.hardlink} more ${t.room.hardlink===1?`tree`:`trees`}`;return[`${T(t.freeKiB)} free${t.capped?` under the ${T(t.capacityKiB)} cap`:``}`,n,`measured ${W(e.at)}`].join(` · `)}),Q=u(()=>O(t.record)),$=u(()=>{let e=t.runs.map(e=>{let n=re(e.label||H(e.id)),r=M(Q.value,e.threadKey),i=ie(e);return{key:`run:${e.id}`,run:e,agent:n.agent,text:n.snippet??n.scope,who:i.identity,surface:le[i.kind]??i.kind,threadUrl:oe(e),href:fe(e),elapsed:ue(e,t.now),binding:r,treeKiB:r?j(K.value,r.threadKey):null}}),n=new Set(t.runs.map(e=>e.threadKey));for(let t of Q.value)t.evicted||n.has(t.threadKey)||e.push({key:`idle:${t.threadKey}`,text:`idle`,who:``,surface:``,threadUrl:``,href:``,elapsed:``,binding:t,treeKiB:j(K.value,t.threadKey)});return e}),Ke=u(()=>$.value.filter(e=>!e.run).length);return(t,c)=>{let u=n(`RouterLink`);return f(),x(`li`,{class:`resident border-b border-muted first:border-t`,"data-slug":h.value,"data-running":e.runs.length},[b(`details`,{class:`group/fold`,open:l.value,onToggle:m},[b(`summary`,he,[c[2]||=b(`span`,{class:`chev w-3 select-none self-center text-xs text-dimmed transition-transform group-open/fold:rotate-90 motion-reduce:transition-none`,"aria-hidden":`true`},`❯`,-1),b(`span`,ge,[s(U,{tone:ee.value,label:v.value.state,tip:v.value.state},null,8,[`tone`,`label`,`tip`])]),b(`span`,_e,i(g.value),1),b(`span`,ve,i(v.value.state),1),e.runs.length>0?(f(),x(`span`,ye,i(e.runs.length)+` running`,1)):d(``,!0),b(`span`,{class:`facts font-mono text-xs text-muted max-sm:basis-full max-sm:pl-[1.9rem] sm:ml-2`,title:X.value||void 0},i(Y.value),9,be),k.value?(f(),w(u,{key:1,class:`detail ml-auto shrink-0 text-xs text-muted no-underline hover:text-highlighted hover:underline`,to:k.value,onClick:c[0]||=y(()=>{},[`stop`])},{default:a(()=>[...c[1]||=[r(`detail ↗`,-1)]]),_:1},8,[`to`])):d(``,!0),v.value.reason?(f(),x(`span`,xe,i(v.value.reason),1)):d(``,!0)]),b(`div`,Se,[$.value.length>0?(f(),x(`ul`,Ce,[(f(!0),x(_,null,S($.value,t=>(f(),x(`li`,{key:t.key,class:o([`grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-x-3 gap-y-1 py-2 sm:grid-cols-[auto_minmax(0,1fr)_minmax(14rem,22rem)_auto]`,t.run?`run`:`idle`]),"data-run-id":t.run?.id,"data-thread":t.run?void 0:t.binding?.threadKey},[b(`span`,Te,[t.run?(f(),w(U,{key:0,tone:`green`,label:p(ae)(t.run),tip:p(ce)(t.run),pulse:``},null,8,[`label`,`tip`])):(f(),w(U,{key:1,tone:`grey`,label:`idle`,tip:`no run is using this tree`}))]),b(`span`,Ee,[b(`span`,De,[t.agent?(f(),x(`span`,{key:0,class:o([`agent shrink-0 rounded border px-1.5 font-mono text-[0.65rem] font-medium uppercase tracking-wider`,p(de)[p(se)(t.agent)]])},i(t.agent),3)):d(``,!0),b(`span`,{class:o([`text min-w-0 truncate text-[0.8125rem]`,t.run?`text-highlighted`:`text-dimmed`]),title:t.run?t.text:void 0},i(t.text),11,Oe)]),t.run?(f(),x(`span`,ke,[t.who?(f(),x(_,{key:0},[r(`by `+i(t.who),1)],64)):d(``,!0),t.who&&(t.threadUrl||t.surface)?(f(),x(_,{key:1},[r(i(` · `))],64)):d(``,!0),t.threadUrl?(f(),x(`a`,{key:2,class:`text-muted no-underline hover:text-highlighted hover:underline`,href:t.threadUrl,target:`_blank`,rel:`noopener noreferrer`},i(t.surface)+` thread ↗`,9,Ae)):t.surface?(f(),x(_,{key:3},[r(`via `+i(t.surface),1)],64)):d(``,!0)])):t.binding?(f(),x(`span`,je,`last used `+i(W(t.binding.lastAttachAt)),1)):d(``,!0)]),b(`span`,Me,[b(`span`,{class:`tree block truncate text-toned`,title:t.binding&&t.binding.ref||void 0},[t.binding?(f(),x(_,{key:0},[r(i(t.binding.ref||`?`),1),t.binding.sha?(f(),x(_,{key:0},[c[3]||=r(i(` `),-1),c[4]||=b(`span`,{class:`text-dimmed`},`@`,-1),c[5]||=r(i(` `)+` `,-1),L(t.binding.sha)?(f(),x(`a`,{key:0,class:`text-highlighted no-underline hover:underline`,href:L(t.binding.sha)},i(t.binding.sha.slice(0,8)),9,Pe)):(f(),x(`span`,Fe,i(t.binding.sha.slice(0,8)),1))],64)):d(``,!0)],64)):(f(),x(`span`,Ie,`no worktree bound yet`))],8,Ne),t.binding?(f(),x(`span`,Le,[b(`span`,Re,i(t.binding.user||`—`),1),c[6]||=r(` `+i(` · `),-1),b(`span`,ze,i(t.binding.deps||`—`),1),c[7]||=r(` `+i(` · `),-1),b(`span`,{class:o([`size`,t.treeKiB===null?``:`text-muted`]),title:t.treeKiB===null?`size not measured yet`:`on disk`},i(t.treeKiB===null?`—`:p(T)(t.treeKiB)),11,Be)])):d(``,!0)]),b(`span`,Ve,[t.run?(f(),x(`span`,{key:0,class:`elapsed whitespace-nowrap font-mono text-xs tabular-nums text-ok`,title:`running for · started ${p(V)(t.run.startedAt,e.now)}`},i(t.elapsed),9,He)):d(``,!0),t.run?(f(),w(u,{key:1,class:`open text-xs text-muted no-underline hover:text-highlighted hover:underline`,to:t.href,"aria-label":`open run ${t.run.label||p(H)(t.run.id)}`},{default:a(()=>[...c[8]||=[r(`open ↗`,-1)]]),_:1},8,[`to`,`aria-label`])):d(``,!0)])],10,we))),128))])):(f(),x(`p`,Ue,`nothing on this resident — no run, no worktree`)),b(`p`,{class:`disk mt-2 font-mono text-xs text-dimmed`,"data-idle":Ke.value},[Z.value?(f(),x(_,{key:0},[r(i(Z.value),1)],64)):(f(),x(`span`,Ge,`disk not measured yet`))],8,We)])],40,me)],8,pe)}}}),G={class:`conn flex items-center gap-1.5`},K={id:`state`,class:`text-xs text-muted`},q={class:`mb-2 text-xs text-muted`},J={id:`running`,class:`font-mono tabular-nums`},Y={id:`residents`,class:`m-0 list-none p-0`},X={key:1,class:`px-2 py-1.5 text-muted`},Z=`Resident repos`,Q=t({__name:`ResidentsIndexPage`,setup(t){let n=h(`residents`),o=l({cap:n?.cap,count:n?.count,residents:n?.residents??[],runs:new Map((n?.runs??[]).map(e=>[e.id,e]))}),d=B(n?.now),y=C({tone:`amber`,text:`connecting…`}),T=typeof window<`u`?new URLSearchParams(window.location.search).get(`open`):null,E=u(()=>o.residents.map((e,t)=>{let n=e,r=N(n);return{key:`${r||`?`}-${t}`,record:n,slug:r,runs:I(o.runs.values(),r)}})),D=u(()=>P(o.cap)||`?`),O=u(()=>P(o.count)||String(E.value.length)),A=u(()=>E.value.reduce((e,t)=>e+t.runs.length,0));c([A,()=>o.residents],([e,t])=>{v.setTitle((e>0?`(${e}) `:``)+Z),v.setFavicon(R[k(t)])},{immediate:!0});let j=z(),M=null;return m(()=>{M=j(`/residents?stream=1`);let e=!1;M.onopen=()=>{if(e){v.reload();return}e=!0,y.value={tone:`green`,text:`live`}},M.onmessage=e=>{let t;try{t=JSON.parse(e.data)}catch{return}L(o,t)},M.onerror=()=>{M&&M.readyState===2?y.value={tone:`red`,text:`disconnected`}:y.value={tone:`amber`,text:`connecting…`}}}),g(()=>{M?.close()}),(t,n)=>{let o=ee;return f(),w(e,{title:Z,nav:`residents`},{status:a(()=>[s(o,{text:`runs arrive from the registry feed; the listing is re-read when a run attaches or ends`},{default:a(()=>[b(`span`,G,[s(U,{tone:y.value.tone,label:y.value.text},null,8,[`tone`,`label`]),b(`span`,K,i(y.value.text),1)])]),_:1})]),default:a(()=>[E.value.length>0?(f(),x(_,{key:0},[b(`p`,q,[r(i(`${O.value}/${D.value} resident slots in use · `),1),b(`span`,J,i(A.value)+` running`,1)]),b(`ul`,Y,[(f(!0),x(_,null,S(E.value,e=>(f(),w(W,{key:e.key,record:e.record,runs:e.runs,now:p(d),open:p(T)!==null&&p(T)===e.slug},null,8,[`record`,`runs`,`now`,`open`]))),128))])],64)):(f(),x(`p`,X,[r(` No repos onboarded (0/`+i(D.value)+`). Onboard one from chat: `,1),n[0]||=b(`code`,{class:`rounded bg-elevated px-1.5 py-0.5`},`repo onboard <owner/name>`,-1),n[1]||=r(`. `,-1)]))]),_:1})}}});export{Q as default};