tokentracker-cli 0.81.3 → 0.82.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 (85) hide show
  1. package/dashboard/dist/assets/{AchievementBadge-DiSoAalB.js → AchievementBadge-D6iPEEbz.js} +1 -1
  2. package/dashboard/dist/assets/{AchievementsPage-DI_cvzqy.js → AchievementsPage-Jry355YE.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-ClWZZNvc.js → AchievementsSection-ah-kG00E.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-DpQeG_6H.js → BadgeDetailModal-FyvUrVvF.js} +1 -1
  5. package/dashboard/dist/assets/{Card-B0hyofoy.js → Card-C3nLScju.js} +1 -1
  6. package/dashboard/dist/assets/{ClawdAnimated-DZJGQ3-9.js → ClawdAnimated-CLHhE26z.js} +1 -1
  7. package/dashboard/dist/assets/{CommunityStatsModal-Dcikt0kT.js → CommunityStatsModal-DA3PHLV5.js} +1 -1
  8. package/dashboard/dist/assets/{ConfirmModal-DCfRP4oI.js → ConfirmModal-CTDarLrD.js} +1 -1
  9. package/dashboard/dist/assets/DashboardPage-DZIiWc3Y.js +1 -0
  10. package/dashboard/dist/assets/{DevicePage-De6KuFaJ.js → DevicePage-CyXjUO8W.js} +1 -1
  11. package/dashboard/dist/assets/DialogDescription-ahxSNUcB.js +1 -0
  12. package/dashboard/dist/assets/DialogTitle-z86PHHyk.js +1 -0
  13. package/dashboard/dist/assets/{FadeIn-DZoN7vbQ.js → FadeIn-BDWtfIsO.js} +1 -1
  14. package/dashboard/dist/assets/{HeaderGithubStar-C9HQnEsI.js → HeaderGithubStar-DE1USQbb.js} +1 -1
  15. package/dashboard/dist/assets/{IpCheckPage-82zniXwO.js → IpCheckPage-B2SkgT0P.js} +1 -1
  16. package/dashboard/dist/assets/{LandingPage-Df9fdR0n.js → LandingPage-PU5gxsfY.js} +14 -14
  17. package/dashboard/dist/assets/{LeaderboardAvatar-CjfEgoR8.js → LeaderboardAvatar-CaOV_hFE.js} +1 -1
  18. package/dashboard/dist/assets/{LeaderboardPage-BdbE6Nhj.js → LeaderboardPage-B0JtEyRP.js} +2 -2
  19. package/dashboard/dist/assets/{LeaderboardProfileModal-CDTK21dp.js → LeaderboardProfileModal-DtNEbVH8.js} +3 -3
  20. package/dashboard/dist/assets/{LeaderboardProfilePage-B6QWnwB1.js → LeaderboardProfilePage-DRklax3-.js} +3 -3
  21. package/dashboard/dist/assets/LimitsPage-Dg0cJa40.js +4 -0
  22. package/dashboard/dist/assets/{LocalOnlyNotice-DOcSDrOy.js → LocalOnlyNotice-si9PMKya.js} +1 -1
  23. package/dashboard/dist/assets/{LoginPage-WY_sRA7I.js → LoginPage-DgLwhXKo.js} +1 -1
  24. package/dashboard/dist/assets/{PetPage-CNbgNE6f.js → PetPage-DEZbjk99.js} +1 -1
  25. package/dashboard/dist/assets/{PopoverPopup-Cv525-dF.js → PopoverPopup-DX7v1XfE.js} +1 -1
  26. package/dashboard/dist/assets/ResetPasswordPage-C6NvRO-Q.js +1 -0
  27. package/dashboard/dist/assets/{Select-3HkgkO8y.js → Select-CH2xVU8X.js} +1 -1
  28. package/dashboard/dist/assets/{SelectItemText-Bz8FAKEv.js → SelectItemText-CCW6JeeN.js} +1 -1
  29. package/dashboard/dist/assets/SettingsPage-Cm3uT11D.js +1 -0
  30. package/dashboard/dist/assets/{SkillsPage-Dnz3eGcE.js → SkillsPage-CljRL6yF.js} +1 -1
  31. package/dashboard/dist/assets/{TrendMonitor-OopQ06B8.js → TrendMonitor-DM1_WNfw.js} +2 -2
  32. package/dashboard/dist/assets/WidgetsPage-mJ1j6hly.js +1 -0
  33. package/dashboard/dist/assets/{WrappedPage-Dbd-8EKD.js → WrappedPage-Dz71ln4t.js} +1 -1
  34. package/dashboard/dist/assets/__vite-browser-external-C7JwykID.css +1 -0
  35. package/dashboard/dist/assets/{__vite-browser-external-CxN2E6q5.js → __vite-browser-external-Eoyj4eG-.js} +47 -18
  36. package/dashboard/dist/assets/agent-logos-D3K_ZRUj.js +1 -0
  37. package/dashboard/dist/assets/{arrow-up-right-CGnVz9Km.js → arrow-up-right-CT4-gmOS.js} +1 -1
  38. package/dashboard/dist/assets/{check-CkI3WNti.js → check-B87_qvAg.js} +1 -1
  39. package/dashboard/dist/assets/{copy-Bh3g2_O-.js → copy-Dtr68epm.js} +1 -1
  40. package/dashboard/dist/assets/{download-BITw7nKX.js → download-DaWsA_Gj.js} +1 -1
  41. package/dashboard/dist/assets/{flame-ByAsnNar.js → flame-vLBOq0X0.js} +1 -1
  42. package/dashboard/dist/assets/{format-tokens-Cu8JtuN4.js → format-tokens-C6Pidz3s.js} +1 -1
  43. package/dashboard/dist/assets/{icons-D9OB0N43.js → icons-BaaYJxUN.js} +1 -1
  44. package/dashboard/dist/assets/{info-Mu2CLf-A.js → info-B46Qt16h.js} +1 -1
  45. package/dashboard/dist/assets/limits-providers-13af4PEg.js +1 -0
  46. package/dashboard/dist/assets/{link-2-CSlVaUw9.js → link-2-DeN6MJpT.js} +1 -1
  47. package/dashboard/dist/assets/{loader-circle-CYck0YaS.js → loader-circle-ByEuaaSw.js} +1 -1
  48. package/dashboard/dist/assets/{provider-display-BB925tPa.js → provider-display-CKbOKeV4.js} +1 -1
  49. package/dashboard/dist/assets/{terminal-4YysOnTe.js → terminal-DyicX7lG.js} +1 -1
  50. package/dashboard/dist/assets/{trash-2-C8-ZfrZG.js → trash-2-CVCC3DtQ.js} +1 -1
  51. package/dashboard/dist/assets/{use-community-stats-Cxt-otko.js → use-community-stats-CExk3D6G.js} +1 -1
  52. package/dashboard/dist/assets/use-limits-display-prefs-CRl4uU95.js +1 -0
  53. package/dashboard/dist/assets/{use-native-settings-DbdPXxGf.js → use-native-settings-Bi6E9dsE.js} +1 -1
  54. package/dashboard/dist/assets/{use-ordered-list-BZMM-iIj.js → use-ordered-list-Dk0p2otw.js} +1 -1
  55. package/dashboard/dist/assets/use-session-efficiency-pref-YAG-OYIh.js +1 -0
  56. package/dashboard/dist/assets/{use-transform-CuAoUb8H.js → use-transform-lflyghWN.js} +1 -1
  57. package/dashboard/dist/assets/use-usage-limits-DJXvJ25Q.js +1 -0
  58. package/dashboard/dist/assets/{useCurrency-CpDnFC0N.js → useCurrency-BtHtcsO5.js} +1 -1
  59. package/dashboard/dist/assets/{useScrollLock-Vyaif-7C.js → useScrollLock-C2C-Yazq.js} +1 -1
  60. package/dashboard/dist/assets/{useTokenFormat-B8FrUarf.js → useTokenFormat-BdD057ih.js} +1 -1
  61. package/dashboard/dist/assets/{zap-CdeKJ6HL.js → zap-DWWma29E.js} +1 -1
  62. package/dashboard/dist/index.html +2 -2
  63. package/dashboard/dist/share.html +2 -2
  64. package/package.json +1 -1
  65. package/src/cli.js +6 -0
  66. package/src/commands/sessions.js +29 -0
  67. package/src/lib/context-health.js +124 -0
  68. package/src/lib/git-outcomes.js +147 -0
  69. package/src/lib/local-api.js +45 -3
  70. package/src/lib/outcomes-engine.js +23 -0
  71. package/src/lib/pricing/seed-snapshot.json +1 -1
  72. package/src/lib/session-analytics.js +612 -0
  73. package/src/lib/usage-limits.js +21 -0
  74. package/dashboard/dist/assets/DashboardPage-DBajsWEp.js +0 -1
  75. package/dashboard/dist/assets/DialogDescription-uQ4gVIv9.js +0 -1
  76. package/dashboard/dist/assets/DialogTitle-BvElfi0r.js +0 -1
  77. package/dashboard/dist/assets/LimitsPage-f0L0d15j.js +0 -4
  78. package/dashboard/dist/assets/ResetPasswordPage-vrcj6bBP.js +0 -1
  79. package/dashboard/dist/assets/SettingsPage-CVldAt69.js +0 -1
  80. package/dashboard/dist/assets/WidgetsPage-4dWjZkc9.js +0 -1
  81. package/dashboard/dist/assets/__vite-browser-external-CQxW1DuO.css +0 -1
  82. package/dashboard/dist/assets/agent-logos-CT9fumzx.js +0 -1
  83. package/dashboard/dist/assets/use-limits-display-prefs-BUFZh6fe.js +0 -1
  84. package/dashboard/dist/assets/use-quality-per-dollar-pref-DXoW5A0_.js +0 -1
  85. package/dashboard/dist/assets/use-usage-limits-BEc3QMzR.js +0 -1
@@ -1 +1 @@
1
- import{cb as Xe,cc as _t,b2 as Ot,b1 as Y,b4 as wt,bw as U,cd as Ct,ce as $e,j as Se,cf as ze,r as g,O as V,cg as ot,ch as Dt,b5 as it,bu as Ne,ci as Gt,cj as ct,ck as xt,by as x,bx as ke,bP as he,cl as Ve,cm as le,cn as ae,aK as C,bB as Kt,co as It,cp as Je,cq as Ut,bM as ut,bH as lt,bJ as Xt,cr as Vt,aJ as be,bL as qt,cs as jt,aH as Pe,bG as $t,ct as Ze,b7 as We,cu as zt,cv as Ye,bC as Jt,bt as Be,bD as Zt,bv as Ie,cw as _e,cx as Qt,cy as en,cz as tn,aL as nn,aA as Te,cA as me,cB as rn,ba as sn,aE as on,aB as De,cC as at,cD as cn,cE as Qe}from"./__vite-browser-external-CxN2E6q5.js";function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function un(e){e.preventDefault(),e.stopPropagation()}function ln(e){return"nativeEvent"in e}function an(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function fn(e){return _t?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function jn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function dn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(pn,e).current;return t.next=e,Y(t.effect),t}function pn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Le=0;function Ge(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Le);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Le=i,()=>{Le===i&&(cancelAnimationFrame(i),Le=0)}}const Ke={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ue=0;function gn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{$e(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function hn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],B=[];if(o){const b=Ke[o],T=gn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),Z=E!==null&&E!=="false",H=(b.get(y)||0)+1;b.set(y,H),k.push(y),H===1&&Z&&T.add(y),Z||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),B.push(b),T===1&&b.setAttribute(dt,"")}),Ue+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&B.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ue-=1,Ue||(Ke.inert=new WeakMap,Ke["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=U(e[0]).body;return hn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class mn{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function $n(e){const t=ze(),n=tt(e),r=et();return Y(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function zn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function Jn(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new mn).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function bn(e,t){const n=We(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&$e(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function En(e){return e?Ze(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=zt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Ze(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function Zn(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:B,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:Z,dataRef:H}=P.context,q=V(()=>H.current.floatingContext?.nodeId),J=s===!1,D=ot(y)&&J,se=Ae(s),F=Ae(o),j=Ae(f),ve=Ae(_),L=tt(T),R=Dt(),W=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),$=it(ye,R?.afterInsideRef),ie=Ne(),ce=Ne(),Oe=Gt(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Q=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(N){N.key==="Tab"&&C(p,ae(U(p)))&&ne().length===0&&!D&&un(N)}const I=U(p);return x(I,"keydown",m)},[r,p,u,D,ne]),g.useEffect(()=>{if(r||!_)return;const m=U(p);function I(){ee.current=!1}function N(z){const a=be(z),O=Q(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${qt}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function G(){de.current="keyboard"}return ke(x(m,"pointerdown",N,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",G,!0),I)},[r,E,y,p,_,R,ce,Q]),g.useEffect(()=>{if(r||!h)return;const m=U(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function N(O){const d=be(O);Ze(d)&&(te.current=d)}function G(O){const d=O.relatedTarget,M=O.currentTarget,K=be(O);u&&d==null&&K!=null&&C(E,K)&&Et(K),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Q(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(B),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||L&&(Fe(L.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(L.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!jt(K)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(H.current.insideReactTree){H.current.insideReactTree=!1;return}(D||!u)&&d&&X&&!oe.current&&(D||d!==yt())&&(W.current=!0,P.setOpen(!1,Pe($t,O)))})}function z(){ee.current||(H.current.insideReactTree=!0,ie.start(0,()=>{H.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",G),a&&x(a,"pointerdown",I),E&&x(E,"focusin",N),E&&x(E,"focusout",G),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,L,R,P,h,i,ne,D,q,H,ie,ce,Oe,k,B,Q]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),N=(L?ft(L.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Q()],N,le(B),le(k),D?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||D,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,D,L,q,k,B,Q]),Y(()=>{if(!_||r||!he(p))return;const m=U(p),I=ae(m);queueMicrotask(()=>{const N=se.current,G=typeof N=="function"?N(j.current||""):N;if(G===void 0||G===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;G===!0||G===null?d=O():d=le(G),d=d||O();const M=C(p,ae(m));Ge(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const K=ae(m);return!(K!==d&&C(p,K))}})})},[r,_,p,ne,se,j,ve]),Y(()=>{if(r||!p)return;const m=U(p),I=ae(m),N=j.current==null;Et(I);function G(a){if(a.open||(Ee.current=bn(a.nativeEvent,de.current)),a.reason===Kt&&a.nativeEvent.type==="mouseleave"&&(W.current=!0),a.reason===It)if(a.nested)W.current=!1;else if(an(a.nativeEvent)||fn(a.nativeEvent))W.current=!1;else{let O=!1;U(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?W.current=!1:W.current=!0}}Z.on("openchange",G);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&$e(I)!=="body"?I:null;let K=N?M||d:d||M;return K||(K=yt()||null),typeof O=="boolean"?K:le(O)||K||null}return()=>{Z.off("openchange",G);const a=ae(m),O=Q(),d=C(E,a)||O.some(w=>w===a||C(w,a))||L&&Fe(L.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,K=z();queueMicrotask(()=>{const w=En(K),Re=typeof M!="boolean";M&&!W.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),W.current=!1})}},[r,E,p,F,j,Z,L,y,q,Q]),Y(()=>{if(!Je||_||!E)return;const m=ae(U(E));!he(m)||!Ut(m)||C(E,m)&&m.blur()},[_,E]),Y(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),Y(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!D:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();Ge(I[I.length-1])}else R?.portalNode&&(W.current=!1,lt(m,R.portalNode)?Xt(y)?.focus():le(B??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:$,onFocus:m=>{u?Ge(ne()[0]):R?.portalNode&&(h&&(W.current=!0),lt(m,R.portalNode)?Vt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function yn(){return!1}function Rn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function Qn(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=yn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),B=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:Z}=Rn(u),H=g.useRef(!1),q=g.useRef(!1),J=g.useRef(!1),D=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),j=Ne(),ve=Ne(),L=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const $=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,$):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),W=V(S=>Ye(S,f.select("floatingElement"))||Ye(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Jt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||D.current||!E&&R("__escapeKeyBubbles"))return;const $=ln(S)?S.nativeEvent:S,ie=Pe(Zt,$);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,L)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const $=be(S.nativeEvent);C(f.select("floatingElement"),$)&&(H.current||(H.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&H.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=Z;const S=new Be,$=new Be;function ie(){S.clear(),D.current=!0}function ce(){S.start(Je?5:0,()=>{D.current=!1})}function Oe(){J.current=!0,$.start(0,()=>{J.current=!1})}function Me(){H.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Q(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>Ye(c,v.context?.elements.floating));return W(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!W(c)&&($.clear(),J.current=!1),L();return}if(b.current.insideReactTree){L();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:U(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=Qt(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!en(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),He=tn(l),st=/auto|scroll/,At=re||st.test(He.overflowX),Lt=re||st.test(He.overflowY),Nt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Bt=Lt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Wt=He.direction==="rtl",Ht=Bt&&(Wt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Yt=Nt&&c.offsetY>l.clientHeight;if(Ht||Yt)return}if(!Q(c)){if(p()==="intentional"&&J.current){$.clear(),J.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),L())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||W(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||W(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},j.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function N(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function G(c){se.current="touch",N(c,I)}function z(c){j.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&N(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!H.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Q(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||($.clear(),J.current=!0,L())}}}function O(c){if(p()!=="sloppy"||!F.current||W(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),j.clear(),F.current=null)}function d(c){N(c,O)}function M(c){p()!=="sloppy"||!F.current||W(c)||(F.current.dismissOnTouchEnd&&ge(c),j.clear(),F.current=null)}function K(c){N(c,M)}const w=U(B),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",G,!0),x(w,"touchmove",d,!0),x(w,"touchend",K,!0)));return()=>{Re(),S.clear(),$.clear(),Me(),J.current=!1}},[b,B,r,_,P,k,n,E,Z,ee,L,y,R,W,T,f,j]),g.useEffect(L,[P,L]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function Tn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const Sn={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class vn extends nn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},Sn),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&dn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function On(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,B=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new vn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:B,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),Y(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=B,T.context.nested=o,T}function wn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),Y(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),Y(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),Y(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const er={tabIndex:-1,[rn]:""};function tr(e){return t=>t==="touch"?e.current:!0}function nr(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return On({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function Cn(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function rr(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function sr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function or(e,t,n,r){Tn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function ir(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=Cn(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return Y(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function cr(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");Y(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,B]=f.value;i.activeTriggerId=k,i.activeTriggerElement=B}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function ur(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=wn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function lr(e,t){e.useSyncedValues(t),Y(()=>()=>{e.update({activeTriggerProps:De,inactiveTriggerProps:De,popupProps:De})},[e])}function ar(e,t){Y(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),Y(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class fr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),je=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const xn={[je.popupOpen]:""},In={[je.popupOpen]:"",[je.pressed]:""},kn={[rt.open]:""},Pn={[rt.closed]:""},Fn={[rt.anchorHidden]:""},dr={open(e){return e?xn:null}},pr={open(e){return e?In:null}},gr={open(e){return e?kn:Pn},anchorHidden(e){return e?Fn:null}};function hr(e){return ze(e,"base-ui")}const Mn="ArrowUp",An="ArrowDown",Ln="ArrowLeft",Nn="ArrowRight",Bn="Home",Wn="End",Hn=new Set([Ln,Nn]),Yn=new Set([Mn,An]),_n=new Set([...Hn,...Yn]),mr=new Set([..._n,Bn,Wn]),br=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Dn(e){if(typeof document>"u")return!1;const t=U(e);return We(t).innerWidth-t.documentElement.clientWidth>0}function Gn(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=U(e),r=n.documentElement,s=n.body,o=Qe(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Kn(e){const t=U(e),n=t.documentElement,r=t.body,s=Qe(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Un(e){const t=U(e),n=t.documentElement,r=t.body,s=We(n);let o=0,i=0,u=!1;const h=me.create();if(Je&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,Z=n.scrollWidth>n.clientWidth,H=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",J=Math.max(0,s.innerWidth-r.clientWidth),D=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),j=Qe(n)?n:r;if(u=Gn(e),u){n.style.scrollbarGutter=y,j.style.overflowY="hidden",j.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||H)&&(n.style.overflowY="scroll"),(Z||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||D?`calc(100dvh - ${se+D}px)`:"100dvh",width:F||J?`calc(100vw - ${F+J}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function B(){k(),h.request(f)}f();const b=x(s,"resize",B);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class Xn{lockCount=0;restore=null;timeoutLock=Be.create();timeoutUnlock=Be.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=U(t).documentElement,s=We(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=cn||!Dn(t);this.restore=o?Kn(t):Un(t)}}const Vn=new Xn;function Er(e=!0,t=null){Y(()=>{if(e)return Vn.acquire(t)},[e,t])}export{pr as A,$n as B,rt as C,zn as D,Ge as E,vn as F,un as G,an as H,br as I,fn as J,fr as P,er as a,mr as b,tr as c,Zn as d,ar as e,cr as f,ur as g,Qn as h,Er as i,lr as j,nr as k,Tn as l,wn as m,jn as n,tt as o,gr as p,et as q,Fe as r,rr as s,dr as t,hr as u,Ae as v,sr as w,Jn as x,or as y,ir as z};
1
+ import{cc as Xe,cd as _t,aO as Ot,aN as Y,aQ as wt,bx as U,ce as Ct,cf as $e,j as Se,cg as ze,r as g,K as V,ch as ot,ci as Dt,aR as it,bv as We,cj as Gt,ck as ct,cl as xt,bz as x,by as ke,bQ as he,cm as Ve,cn as le,co as ae,aL as C,bC as Kt,cp as It,cq as Je,cr as Ut,bN as ut,bI as lt,bK as Xt,cs as Vt,aK as be,bM as qt,ct as jt,aI as Pe,bH as $t,cu as Qe,aT as Be,cv as zt,cw as Ye,bD as Jt,bu as Le,bE as Qt,bw as Ie,cx as _e,cy as Zt,cz as en,cA as tn,aM as nn,aB as Te,cB as me,cC as rn,aW as sn,aF as on,aC as De,cD as at,cE as cn,cF as Ze}from"./__vite-browser-external-Eoyj4eG-.js";function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function un(e){e.preventDefault(),e.stopPropagation()}function ln(e){return"nativeEvent"in e}function an(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function fn(e){return _t?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function jn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function dn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(pn,e).current;return t.next=e,Y(t.effect),t}function pn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Ne=0;function Ge(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Ne);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Ne=i,()=>{Ne===i&&(cancelAnimationFrame(i),Ne=0)}}const Ke={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ue=0;function gn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{$e(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function hn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],L=[];if(o){const b=Ke[o],T=gn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),Q=E!==null&&E!=="false",H=(b.get(y)||0)+1;b.set(y,H),k.push(y),H===1&&Q&&T.add(y),Q||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),L.push(b),T===1&&b.setAttribute(dt,"")}),Ue+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&L.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ue-=1,Ue||(Ke.inert=new WeakMap,Ke["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=U(e[0]).body;return hn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class mn{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function $n(e){const t=ze(),n=tt(e),r=et();return Y(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function zn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function Jn(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new mn).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function bn(e,t){const n=Be(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&$e(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function En(e){return e?Qe(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=zt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Qe(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function Qn(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:L,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:Q,dataRef:H}=P.context,q=V(()=>H.current.floatingContext?.nodeId),J=s===!1,D=ot(y)&&J,se=Ae(s),F=Ae(o),j=Ae(f),ve=Ae(_),N=tt(T),R=Dt(),B=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),$=it(ye,R?.afterInsideRef),ie=We(),ce=We(),Oe=Gt(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Z=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(W){W.key==="Tab"&&C(p,ae(U(p)))&&ne().length===0&&!D&&un(W)}const I=U(p);return x(I,"keydown",m)},[r,p,u,D,ne]),g.useEffect(()=>{if(r||!_)return;const m=U(p);function I(){ee.current=!1}function W(z){const a=be(z),O=Z(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${qt}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function G(){de.current="keyboard"}return ke(x(m,"pointerdown",W,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",G,!0),I)},[r,E,y,p,_,R,ce,Z]),g.useEffect(()=>{if(r||!h)return;const m=U(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function W(O){const d=be(O);Qe(d)&&(te.current=d)}function G(O){const d=O.relatedTarget,M=O.currentTarget,K=be(O);u&&d==null&&K!=null&&C(E,K)&&Et(K),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Z(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(L),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||N&&(Fe(N.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(N.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!jt(K)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(H.current.insideReactTree){H.current.insideReactTree=!1;return}(D||!u)&&d&&X&&!oe.current&&(D||d!==yt())&&(B.current=!0,P.setOpen(!1,Pe($t,O)))})}function z(){ee.current||(H.current.insideReactTree=!0,ie.start(0,()=>{H.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",G),a&&x(a,"pointerdown",I),E&&x(E,"focusin",W),E&&x(E,"focusout",G),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,N,R,P,h,i,ne,D,q,H,ie,ce,Oe,k,L,Z]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),W=(N?ft(N.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Z()],W,le(L),le(k),D?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||D,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,D,N,q,k,L,Z]),Y(()=>{if(!_||r||!he(p))return;const m=U(p),I=ae(m);queueMicrotask(()=>{const W=se.current,G=typeof W=="function"?W(j.current||""):W;if(G===void 0||G===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;G===!0||G===null?d=O():d=le(G),d=d||O();const M=C(p,ae(m));Ge(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const K=ae(m);return!(K!==d&&C(p,K))}})})},[r,_,p,ne,se,j,ve]),Y(()=>{if(r||!p)return;const m=U(p),I=ae(m),W=j.current==null;Et(I);function G(a){if(a.open||(Ee.current=bn(a.nativeEvent,de.current)),a.reason===Kt&&a.nativeEvent.type==="mouseleave"&&(B.current=!0),a.reason===It)if(a.nested)B.current=!1;else if(an(a.nativeEvent)||fn(a.nativeEvent))B.current=!1;else{let O=!1;U(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?B.current=!1:B.current=!0}}Q.on("openchange",G);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&$e(I)!=="body"?I:null;let K=W?M||d:d||M;return K||(K=yt()||null),typeof O=="boolean"?K:le(O)||K||null}return()=>{Q.off("openchange",G);const a=ae(m),O=Z(),d=C(E,a)||O.some(w=>w===a||C(w,a))||N&&Fe(N.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,K=z();queueMicrotask(()=>{const w=En(K),Re=typeof M!="boolean";M&&!B.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),B.current=!1})}},[r,E,p,F,j,Q,N,y,q,Z]),Y(()=>{if(!Je||_||!E)return;const m=ae(U(E));!he(m)||!Ut(m)||C(E,m)&&m.blur()},[_,E]),Y(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),Y(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!D:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();Ge(I[I.length-1])}else R?.portalNode&&(B.current=!1,lt(m,R.portalNode)?Xt(y)?.focus():le(L??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:$,onFocus:m=>{u?Ge(ne()[0]):R?.portalNode&&(h&&(B.current=!0),lt(m,R.portalNode)?Vt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function yn(){return!1}function Rn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function Zn(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=yn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),L=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:Q}=Rn(u),H=g.useRef(!1),q=g.useRef(!1),J=g.useRef(!1),D=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),j=We(),ve=We(),N=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const $=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,$):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),B=V(S=>Ye(S,f.select("floatingElement"))||Ye(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Jt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||D.current||!E&&R("__escapeKeyBubbles"))return;const $=ln(S)?S.nativeEvent:S,ie=Pe(Qt,$);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,N)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const $=be(S.nativeEvent);C(f.select("floatingElement"),$)&&(H.current||(H.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&H.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=Q;const S=new Le,$=new Le;function ie(){S.clear(),D.current=!0}function ce(){S.start(Je?5:0,()=>{D.current=!1})}function Oe(){J.current=!0,$.start(0,()=>{J.current=!1})}function Me(){H.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Z(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>Ye(c,v.context?.elements.floating));return B(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!B(c)&&($.clear(),J.current=!1),N();return}if(b.current.insideReactTree){N();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:U(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=Zt(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!en(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),He=tn(l),st=/auto|scroll/,At=re||st.test(He.overflowX),Nt=re||st.test(He.overflowY),Wt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Lt=Nt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Bt=He.direction==="rtl",Ht=Lt&&(Bt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Yt=Wt&&c.offsetY>l.clientHeight;if(Ht||Yt)return}if(!Z(c)){if(p()==="intentional"&&J.current){$.clear(),J.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),N())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||B(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||B(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},j.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function W(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function G(c){se.current="touch",W(c,I)}function z(c){j.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&W(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!H.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Z(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||($.clear(),J.current=!0,N())}}}function O(c){if(p()!=="sloppy"||!F.current||B(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),j.clear(),F.current=null)}function d(c){W(c,O)}function M(c){p()!=="sloppy"||!F.current||B(c)||(F.current.dismissOnTouchEnd&&ge(c),j.clear(),F.current=null)}function K(c){W(c,M)}const w=U(L),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",G,!0),x(w,"touchmove",d,!0),x(w,"touchend",K,!0)));return()=>{Re(),S.clear(),$.clear(),Me(),J.current=!1}},[b,L,r,_,P,k,n,E,Q,ee,N,y,R,B,T,f,j]),g.useEffect(N,[P,N]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function Tn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const Sn={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class vn extends nn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},Sn),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&dn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function On(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,L=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new vn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:L,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),Y(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=L,T.context.nested=o,T}function wn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),Y(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),Y(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),Y(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const er={tabIndex:-1,[rn]:""};function tr(e){return t=>t==="touch"?e.current:!0}function nr(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return On({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function Cn(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function rr(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function sr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function or(e,t,n,r){Tn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function ir(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=Cn(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return Y(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function cr(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");Y(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,L]=f.value;i.activeTriggerId=k,i.activeTriggerElement=L}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function ur(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=wn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function lr(e,t){e.useSyncedValues(t),Y(()=>()=>{e.update({activeTriggerProps:De,inactiveTriggerProps:De,popupProps:De})},[e])}function ar(e,t){Y(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),Y(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class fr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),je=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const xn={[je.popupOpen]:""},In={[je.popupOpen]:"",[je.pressed]:""},kn={[rt.open]:""},Pn={[rt.closed]:""},Fn={[rt.anchorHidden]:""},dr={open(e){return e?xn:null}},pr={open(e){return e?In:null}},gr={open(e){return e?kn:Pn},anchorHidden(e){return e?Fn:null}};function hr(e){return ze(e,"base-ui")}const Mn="ArrowUp",An="ArrowDown",Nn="ArrowLeft",Wn="ArrowRight",Ln="Home",Bn="End",Hn=new Set([Nn,Wn]),Yn=new Set([Mn,An]),_n=new Set([...Hn,...Yn]),mr=new Set([..._n,Ln,Bn]),br=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Dn(e){if(typeof document>"u")return!1;const t=U(e);return Be(t).innerWidth-t.documentElement.clientWidth>0}function Gn(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=U(e),r=n.documentElement,s=n.body,o=Ze(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Kn(e){const t=U(e),n=t.documentElement,r=t.body,s=Ze(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Un(e){const t=U(e),n=t.documentElement,r=t.body,s=Be(n);let o=0,i=0,u=!1;const h=me.create();if(Je&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,Q=n.scrollWidth>n.clientWidth,H=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",J=Math.max(0,s.innerWidth-r.clientWidth),D=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),j=Ze(n)?n:r;if(u=Gn(e),u){n.style.scrollbarGutter=y,j.style.overflowY="hidden",j.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||H)&&(n.style.overflowY="scroll"),(Q||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||D?`calc(100dvh - ${se+D}px)`:"100dvh",width:F||J?`calc(100vw - ${F+J}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function L(){k(),h.request(f)}f();const b=x(s,"resize",L);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class Xn{lockCount=0;restore=null;timeoutLock=Le.create();timeoutUnlock=Le.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=U(t).documentElement,s=Be(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=cn||!Dn(t);this.restore=o?Kn(t):Un(t)}}const Vn=new Xn;function Er(e=!0,t=null){Y(()=>{if(e)return Vn.acquire(t)},[e,t])}export{pr as A,$n as B,rt as C,zn as D,Ge as E,vn as F,un as G,an as H,br as I,fn as J,fr as P,er as a,mr as b,tr as c,Qn as d,ar as e,cr as f,ur as g,Zn as h,Er as i,lr as j,nr as k,Tn as l,wn as m,jn as n,tt as o,gr as p,et as q,Fe as r,rr as s,dr as t,hr as u,Ae as v,sr as w,Jn as x,or as y,ir as z};
@@ -1 +1 @@
1
- import{r as e,T as r,m as n,n as a,o as s}from"./__vite-browser-external-CxN2E6q5.js";const T=Object.freeze({mode:n.COMPACT,setMode:()=>{},formatTokens:(o,t={})=>s(o,t),formatTokensTooltip:(o,t={})=>a(o,t)});function f(){return e.useContext(r)??T}export{f as u};
1
+ import{r as e,T as r,l as n,m as a,n as s}from"./__vite-browser-external-Eoyj4eG-.js";const T=Object.freeze({mode:n.COMPACT,setMode:()=>{},formatTokens:(o,t={})=>s(o,t),formatTokensTooltip:(o,t={})=>a(o,t)});function f(){return e.useContext(r)??T}export{f as u};
@@ -1 +1 @@
1
- import{l as a}from"./__vite-browser-external-CxN2E6q5.js";const o=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],e=a("zap",o);export{e as Z};
1
+ import{k as a}from"./__vite-browser-external-Eoyj4eG-.js";const o=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],e=a("zap",o);export{e as Z};
@@ -249,8 +249,8 @@
249
249
  ]
250
250
  }
251
251
  </script>
252
- <script type="module" crossorigin src="/assets/__vite-browser-external-CxN2E6q5.js"></script>
253
- <link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-CQxW1DuO.css">
252
+ <script type="module" crossorigin src="/assets/__vite-browser-external-Eoyj4eG-.js"></script>
253
+ <link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-C7JwykID.css">
254
254
  </head>
255
255
  <body>
256
256
  <main class="aeo-seed-content" aria-label="Token Tracker AI-readable summary">
@@ -75,8 +75,8 @@
75
75
  "description": "Shareable Token Tracker dashboard snapshot."
76
76
  }
77
77
  </script>
78
- <script type="module" crossorigin src="/assets/__vite-browser-external-CxN2E6q5.js"></script>
79
- <link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-CQxW1DuO.css">
78
+ <script type="module" crossorigin src="/assets/__vite-browser-external-Eoyj4eG-.js"></script>
79
+ <link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-C7JwykID.css">
80
80
  </head>
81
81
  <body>
82
82
  <main class="aeo-seed-content" aria-label="Token Tracker share page summary">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokentracker-cli",
3
- "version": "0.81.3",
3
+ "version": "0.82.0",
4
4
  "description": "Local-first AI coding token usage and cost tracker for 27 tools, with a dashboard, desktop pet, widgets, achievements, and native macOS/Windows apps.",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -7,6 +7,7 @@ const { cmdUninstall } = require("./commands/uninstall");
7
7
  const { cmdServe } = require("./commands/serve");
8
8
  const { cmdDeviceLogin } = require("./commands/device-login");
9
9
  const { cmdWrapped } = require("./commands/wrapped");
10
+ const { cmdSessions } = require("./commands/sessions");
10
11
 
11
12
  async function run(argv) {
12
13
  const [command, ...rest] = argv;
@@ -56,6 +57,9 @@ async function run(argv) {
56
57
  case "wrapped":
57
58
  await cmdWrapped(rest);
58
59
  return;
60
+ case "sessions":
61
+ await cmdSessions(rest);
62
+ return;
59
63
  default:
60
64
  throw new Error(`Unknown command: ${command}`);
61
65
  }
@@ -79,6 +83,7 @@ function printHelp() {
79
83
  " npx tokentracker [--debug] uninstall [--purge]",
80
84
  " npx tokentracker [--debug] device-login [--json] [--base-url <url>]",
81
85
  " npx tokentracker [--debug] wrapped [--year 2026] [--json]",
86
+ " npx tokentracker sessions [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--format json|csv] [--out file] [--refresh] [--no-git]",
82
87
  "",
83
88
  "Notes:",
84
89
  " - init: consent first, local setup next, browser sign-in last.",
@@ -93,6 +98,7 @@ function printHelp() {
93
98
  " - --from-openclaw marks sync runs triggered by the OpenClaw session plugin.",
94
99
  " - --debug shows original backend errors.",
95
100
  " - device-login pairs a headless CLI / SSH session with a browser sign-in (15-min code).",
101
+ " - sessions exports metadata-only Claude/Codex efficiency analytics; no prompt or response text is retained.",
96
102
  "",
97
103
  ].join("\n"),
98
104
  );
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const { buildSessionAnalytics, summarizeSessions, sessionsToCsv } = require("../lib/session-analytics");
5
+ const { buildGitOutcomes } = require("../lib/git-outcomes");
6
+
7
+ function option(args, name) {
8
+ const index = args.indexOf(name);
9
+ return index >= 0 ? args[index + 1] || "" : "";
10
+ }
11
+
12
+ async function cmdSessions(args = []) {
13
+ const format = option(args, "--format") || (args.includes("--csv") ? "csv" : "json");
14
+ const out = option(args, "--out");
15
+ const sessions = await buildSessionAnalytics({ force: args.includes("--refresh") });
16
+ if (!args.includes("--no-git")) await buildGitOutcomes(sessions);
17
+ const summary = summarizeSessions(sessions, { from: option(args, "--from"), to: option(args, "--to") });
18
+ const content = format === "csv"
19
+ ? sessionsToCsv(summary.sessions)
20
+ : `${JSON.stringify(summary, null, 2)}\n`;
21
+ if (out) {
22
+ fs.writeFileSync(out, content, { encoding: "utf8", mode: 0o600 });
23
+ process.stdout.write(`${out}\n`);
24
+ } else {
25
+ process.stdout.write(content);
26
+ }
27
+ }
28
+
29
+ module.exports = { cmdSessions };
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ // Estimates fixed context overhead without returning file contents, prompts,
4
+ // tool schemas, secrets, or command arguments.
5
+
6
+ const fs = require("node:fs");
7
+ const os = require("node:os");
8
+ const path = require("node:path");
9
+ const contextCache = new Map();
10
+
11
+ function estimateTokens(text) {
12
+ const value = String(text || "");
13
+ let cjk = 0;
14
+ for (const char of value) if (/\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana}/u.test(char)) cjk += 1;
15
+ return Math.ceil(cjk + (value.length - cjk) / 4);
16
+ }
17
+
18
+ function readMetadata(filePath, kind, root) {
19
+ try {
20
+ const text = fs.readFileSync(filePath, "utf8");
21
+ return { kind, name: path.relative(root, filePath) || path.basename(filePath), bytes: Buffer.byteLength(text), estimated_tokens: estimateTokens(text) };
22
+ } catch { return null; }
23
+ }
24
+
25
+ function walkNamedFiles(root, targetName, limit = 500) {
26
+ const out = [];
27
+ const stack = [root];
28
+ while (stack.length && out.length < limit) {
29
+ const dir = stack.pop();
30
+ let entries;
31
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { continue; }
32
+ for (const entry of entries) {
33
+ if ([".git", "node_modules", "dist", "build"].includes(entry.name)) continue;
34
+ const filePath = path.join(dir, entry.name);
35
+ if (entry.isDirectory()) stack.push(filePath);
36
+ else if (entry.isFile() && entry.name === targetName) out.push(filePath);
37
+ if (out.length >= limit) break;
38
+ }
39
+ }
40
+ return out;
41
+ }
42
+
43
+ function countMcpServers(home, cwd) {
44
+ const files = [
45
+ path.join(home, ".claude.json"),
46
+ path.join(home, ".claude", "settings.json"),
47
+ path.join(cwd, ".mcp.json"),
48
+ ];
49
+ const names = new Set();
50
+ for (const filePath of files) {
51
+ try {
52
+ const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
53
+ const servers = data.mcpServers || data.mcp_servers || {};
54
+ for (const name of Object.keys(servers)) names.add(name);
55
+ } catch { /* absent or not JSON */ }
56
+ }
57
+ try {
58
+ const toml = fs.readFileSync(path.join(home, ".codex", "config.toml"), "utf8");
59
+ for (const match of toml.matchAll(/^\s*\[mcp_servers\.([^\]]+)\]/gm)) names.add(match[1]);
60
+ } catch { /* absent */ }
61
+ return names.size;
62
+ }
63
+
64
+ function computeContextHealth({ home = os.homedir(), cwd = process.cwd(), env = process.env, cacheTtlMs = 5 * 60_000 } = {}) {
65
+ const cacheKey = `${home}\0${cwd}\0${env.TOKENTRACKER_MCP_TOOL_SCHEMA_TOKENS || ""}\0${env.TOKENTRACKER_MCP_TOOLS_PER_SERVER || ""}`;
66
+ const cached = contextCache.get(cacheKey);
67
+ if (cached && Date.now() - cached.at < cacheTtlMs) return cached.value;
68
+ const files = [];
69
+ const known = [
70
+ [path.join(home, ".claude", "CLAUDE.md"), "instruction", home],
71
+ [path.join(home, ".codex", "AGENTS.md"), "instruction", home],
72
+ [path.join(cwd, "CLAUDE.md"), "instruction", cwd],
73
+ [path.join(cwd, "AGENTS.md"), "instruction", cwd],
74
+ ];
75
+ for (const [filePath, kind, root] of known) {
76
+ const item = readMetadata(filePath, kind, root);
77
+ if (item) files.push(item);
78
+ }
79
+ const skillRoots = [
80
+ path.join(home, ".claude", "skills"),
81
+ path.join(home, ".codex", "skills"),
82
+ path.join(cwd, ".claude", "skills"),
83
+ path.join(cwd, ".agents", "skills"),
84
+ ];
85
+ for (const root of skillRoots) {
86
+ for (const filePath of walkNamedFiles(root, "SKILL.md")) {
87
+ const item = readMetadata(filePath, "skill", root);
88
+ if (item) files.push(item);
89
+ }
90
+ }
91
+ const instructionTokens = files.filter((row) => row.kind === "instruction").reduce((sum, row) => sum + row.estimated_tokens, 0);
92
+ const skillTokens = files.filter((row) => row.kind === "skill").reduce((sum, row) => sum + row.estimated_tokens, 0);
93
+ const mcpServers = countMcpServers(home, cwd);
94
+ const perToolSchemaTokens = Math.max(0, Number(env.TOKENTRACKER_MCP_TOOL_SCHEMA_TOKENS || 400));
95
+ const assumedToolsPerServer = Math.max(1, Number(env.TOKENTRACKER_MCP_TOOLS_PER_SERVER || 5));
96
+ const mcpSchemaTokens = mcpServers * perToolSchemaTokens * assumedToolsPerServer;
97
+ const total = instructionTokens + skillTokens + mcpSchemaTokens;
98
+ const severity = total >= 50_000 ? "high" : total >= 20_000 ? "medium" : "low";
99
+ const result = {
100
+ generated_at: new Date().toISOString(),
101
+ estimated_fixed_tokens: total,
102
+ severity,
103
+ breakdown: {
104
+ instruction_files: files.filter((row) => row.kind === "instruction").length,
105
+ instruction_tokens: instructionTokens,
106
+ skills: files.filter((row) => row.kind === "skill").length,
107
+ skill_tokens: skillTokens,
108
+ mcp_servers: mcpServers,
109
+ mcp_schema_tokens: mcpSchemaTokens,
110
+ },
111
+ largest_items: files.sort((a, b) => b.estimated_tokens - a.estimated_tokens).slice(0, 10),
112
+ provenance: {
113
+ confidence: "inferred",
114
+ source: "local-config-metadata",
115
+ mcp_assumption: { tools_per_server: assumedToolsPerServer, tokens_per_tool_schema: perToolSchemaTokens },
116
+ content_retained: false,
117
+ },
118
+ };
119
+ contextCache.set(cacheKey, { at: Date.now(), value: result });
120
+ if (contextCache.size > 8) contextCache.delete(contextCache.keys().next().value);
121
+ return result;
122
+ }
123
+
124
+ module.exports = { estimateTokens, computeContextHealth, countMcpServers };
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+
3
+ // Conservative, metadata-only Git attribution. A commit is attributed only
4
+ // when exactly one local AI session overlaps its author timestamp.
5
+
6
+ const { execFile } = require("node:child_process");
7
+ const fs = require("node:fs");
8
+ const fsp = require("node:fs/promises");
9
+ const os = require("node:os");
10
+ const path = require("node:path");
11
+ const crypto = require("node:crypto");
12
+
13
+ function resolveAutoOutcomesPath(home = os.homedir()) {
14
+ return path.join(home, ".tokentracker", "tracker", "auto-outcomes.jsonl");
15
+ }
16
+
17
+ function readJsonl(filePath) {
18
+ try { return fs.readFileSync(filePath, "utf8").split("\n").filter(Boolean).map((line) => JSON.parse(line)); }
19
+ catch { return []; }
20
+ }
21
+
22
+ // Async on purpose: this runs inside the local API request path, where a
23
+ // synchronous spawn would freeze every other endpoint for the duration of
24
+ // each git invocation.
25
+ function runGit(cwd, args) {
26
+ return new Promise((resolve) => {
27
+ execFile(
28
+ "git",
29
+ args,
30
+ { cwd, encoding: "utf8", timeout: 15_000, maxBuffer: 32 * 1024 * 1024 },
31
+ (error, stdout) => resolve(error ? "" : String(stdout).trim()),
32
+ );
33
+ });
34
+ }
35
+
36
+ async function repoRoot(cwd) {
37
+ if (!cwd || !fs.existsSync(cwd)) return null;
38
+ return (await runGit(cwd, ["rev-parse", "--show-toplevel"])) || null;
39
+ }
40
+
41
+ async function commitsForWindow(root, from, to) {
42
+ const format = "%H%x1f%aI%x1f%P%x1f%s%x1e";
43
+ const raw = await runGit(root, ["log", "--all", `--since=${from}`, `--until=${to}`, `--format=${format}`]);
44
+ if (!raw) return [];
45
+ return raw.split("\x1e").map((item) => item.trim()).filter(Boolean).map((item) => {
46
+ const [sha, timestamp, parents, subject] = item.split("\x1f");
47
+ return {
48
+ sha,
49
+ timestamp,
50
+ parent_count: String(parents || "").split(/\s+/).filter(Boolean).length,
51
+ reverted: /^revert\b/i.test(subject || ""),
52
+ };
53
+ }).filter((row) => row.sha && Number.isFinite(Date.parse(row.timestamp)));
54
+ }
55
+
56
+ async function writeAtomic(filePath, content) {
57
+ await fsp.mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });
58
+ const temp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
59
+ await fsp.writeFile(temp, content, { encoding: "utf8", mode: 0o600 });
60
+ await fsp.rename(temp, filePath);
61
+ }
62
+
63
+ async function buildGitOutcomesInternal(sessions, { home = os.homedir(), force = false, maxAgeDays = 90 } = {}) {
64
+ const groups = new Map();
65
+ const rootCache = new Map();
66
+ const cutoff = Date.now() - Math.max(1, Number(maxAgeDays) || 90) * 86400_000;
67
+ for (const session of sessions || []) {
68
+ if (!session?.project_ref || !session.started_at || !session.ended_at) continue;
69
+ if (Date.parse(session.ended_at) < cutoff) continue;
70
+ let root = rootCache.get(session.project_ref);
71
+ if (root === undefined) {
72
+ root = await repoRoot(session.project_ref);
73
+ rootCache.set(session.project_ref, root);
74
+ }
75
+ if (!root) continue;
76
+ if (!groups.has(root)) groups.set(root, []);
77
+ groups.get(root).push(session);
78
+ }
79
+
80
+ const outputPath = resolveAutoOutcomesPath(home);
81
+ const metaPath = `${outputPath}.meta.json`;
82
+ const signatureHash = crypto.createHash("sha256");
83
+ for (const [root, repoSessions] of [...groups.entries()].sort(([a], [b]) => a.localeCompare(b))) {
84
+ signatureHash.update(`${root}\0${await runGit(root, ["for-each-ref", "--format=%(objectname)"])}\n`);
85
+ for (const session of repoSessions) signatureHash.update(`${session.session_hash}\0${session.ended_at}\n`);
86
+ }
87
+ const signature = signatureHash.digest("hex");
88
+ if (!force) {
89
+ try {
90
+ const meta = JSON.parse(fs.readFileSync(metaPath, "utf8"));
91
+ if (meta.version === 1 && meta.signature === signature) return readJsonl(outputPath);
92
+ } catch { /* first run */ }
93
+ }
94
+
95
+ const outcomes = [];
96
+ for (const [root, repoSessions] of groups) {
97
+ const start = repoSessions.reduce((min, row) => !min || row.started_at < min ? row.started_at : min, "");
98
+ const endMs = Math.max(...repoSessions.map((row) => Date.parse(row.ended_at))) + 60 * 60 * 1000;
99
+ const commits = await commitsForWindow(root, start, new Date(endMs).toISOString());
100
+ for (const commit of commits) {
101
+ const commitMs = Date.parse(commit.timestamp);
102
+ const candidates = repoSessions.filter((session) => {
103
+ const sessionStart = Date.parse(session.started_at) - 10 * 60 * 1000;
104
+ const sessionEnd = Date.parse(session.ended_at) + 60 * 60 * 1000;
105
+ return commitMs >= sessionStart && commitMs <= sessionEnd;
106
+ });
107
+ if (candidates.length !== 1) continue;
108
+ const session = candidates[0];
109
+ outcomes.push({
110
+ timestamp: commit.timestamp,
111
+ model: session.model || "unknown",
112
+ tool: session.source || "unknown",
113
+ accepted: !commit.reverted,
114
+ task_type: "git_commit",
115
+ status: commit.reverted ? "reverted" : "committed",
116
+ session_hash: session.session_hash,
117
+ commit_hash: commit.sha.slice(0, 12),
118
+ parent_count: commit.parent_count,
119
+ confidence: "heuristic",
120
+ methodology: "single-overlapping-session",
121
+ });
122
+ }
123
+ }
124
+ outcomes.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
125
+ await writeAtomic(outputPath, outcomes.map((row) => JSON.stringify(row)).join("\n") + (outcomes.length ? "\n" : ""));
126
+ await writeAtomic(metaPath, `${JSON.stringify({ version: 1, signature, generated_at: new Date().toISOString(), max_age_days: maxAgeDays })}\n`);
127
+ return outcomes;
128
+ }
129
+
130
+ // Overlapping outcomes/session-insights requests must not spawn duplicate git
131
+ // scans nor race the atomic sidecar write; share one build per home.
132
+ const gitOutcomesBuilds = new Map();
133
+
134
+ function buildGitOutcomes(sessions, options = {}) {
135
+ const home = path.resolve(String(options.home || os.homedir()));
136
+ const existing = gitOutcomesBuilds.get(home);
137
+ if (existing) return existing;
138
+ const promise = buildGitOutcomesInternal(sessions, { ...options, home });
139
+ gitOutcomesBuilds.set(home, promise);
140
+ const clear = () => {
141
+ if (gitOutcomesBuilds.get(home) === promise) gitOutcomesBuilds.delete(home);
142
+ };
143
+ promise.then(clear, clear);
144
+ return promise;
145
+ }
146
+
147
+ module.exports = { resolveAutoOutcomesPath, buildGitOutcomes, repoRoot, commitsForWindow };
@@ -1949,11 +1949,20 @@ function createLocalApiHandler({ queuePath }) {
1949
1949
  const from = url.searchParams.get("from") || "";
1950
1950
  const to = url.searchParams.get("to") || "";
1951
1951
  const {
1952
- readOutcomesData,
1953
- resolveOutcomesPath,
1952
+ readAllOutcomesData,
1954
1953
  computeQualityPerDollar,
1955
1954
  } = require("./outcomes-engine");
1956
- const outcomes = readOutcomesData(resolveOutcomesPath());
1955
+ // Refresh the independent metadata-only sidecars before joining. Any
1956
+ // scanner failure degrades to the existing manual outcomes file.
1957
+ try {
1958
+ const { buildSessionAnalytics } = require("./session-analytics");
1959
+ const { buildGitOutcomes } = require("./git-outcomes");
1960
+ const sessions = await buildSessionAnalytics();
1961
+ await buildGitOutcomes(sessions);
1962
+ } catch (error) {
1963
+ console.error("[outcomes] automatic Git attribution failed:", error?.message || error);
1964
+ }
1965
+ const outcomes = readAllOutcomesData();
1957
1966
  if (!outcomes.length) {
1958
1967
  json(res, { available: false, from, to, by_model: [], by_tool: [], totals: null });
1959
1968
  return true;
@@ -1964,6 +1973,39 @@ function createLocalApiHandler({ queuePath }) {
1964
1973
  return true;
1965
1974
  }
1966
1975
 
1976
+ // --- metadata-only Claude/Codex session efficiency ---
1977
+ if (p === "/functions/tokentracker-session-insights") {
1978
+ const from = url.searchParams.get("from") || "";
1979
+ const to = url.searchParams.get("to") || "";
1980
+ const refresh = ["1", "true"].includes(url.searchParams.get("refresh"));
1981
+ try {
1982
+ const { buildSessionAnalytics, summarizeSessions, sessionsToCsv } = require("./session-analytics");
1983
+ const sessions = await buildSessionAnalytics({ force: refresh });
1984
+ const wantsCsv = url.searchParams.get("format") === "csv";
1985
+ const includeSessions = wantsCsv || ["1", "true"].includes(url.searchParams.get("include_sessions"));
1986
+ const result = summarizeSessions(sessions, { from, to, includeSessions });
1987
+ if (wantsCsv) {
1988
+ const content = sessionsToCsv(result.sessions);
1989
+ res.statusCode = 200;
1990
+ res.setHeader("Content-Type", "text/csv; charset=utf-8");
1991
+ res.setHeader("Content-Disposition", "attachment; filename=tokentracker-sessions.csv");
1992
+ res.end(content);
1993
+ return true;
1994
+ }
1995
+ json(res, { from, to, ...result });
1996
+ } catch (error) {
1997
+ json(res, { available: false, error: error?.message || "Session analytics failed" }, 500);
1998
+ }
1999
+ return true;
2000
+ }
2001
+
2002
+ // --- fixed context overhead audit (counts and estimates only) ---
2003
+ if (p === "/functions/tokentracker-context-health") {
2004
+ const { computeContextHealth } = require("./context-health");
2005
+ json(res, computeContextHealth({ home: os.homedir(), cwd: process.cwd(), env: process.env }));
2006
+ return true;
2007
+ }
2008
+
1967
2009
  // --- usage-heatmap ---
1968
2010
  if (p === "/functions/tokentracker-usage-heatmap") {
1969
2011
  const weeks = parseInt(url.searchParams.get("weeks") || "52", 10);
@@ -27,6 +27,10 @@ function resolveOutcomesPath() {
27
27
  return path.join(os.homedir(), ".tokentracker", "tracker", "outcomes.jsonl");
28
28
  }
29
29
 
30
+ function resolveAutoOutcomesPath() {
31
+ return path.join(os.homedir(), ".tokentracker", "tracker", "auto-outcomes.jsonl");
32
+ }
33
+
30
34
  // The ONLY fields ever lifted off an outcome record. Anything not on this list
31
35
  // — bodies, diffs, messages, arbitrary blobs — is dropped at read time. This is
32
36
  // the enforcement point for the metadata-only privacy invariant.
@@ -54,6 +58,10 @@ function sanitizeOutcome(raw) {
54
58
  if (typeof raw.task_type === "string" && raw.task_type.trim()) {
55
59
  out.task_type = raw.task_type.trim();
56
60
  }
61
+ for (const key of ["status", "session_hash", "commit_hash", "confidence", "methodology"]) {
62
+ if (typeof raw[key] === "string" && raw[key].trim()) out[key] = raw[key].trim();
63
+ }
64
+ if (Number.isFinite(Number(raw.parent_count))) out.parent_count = Number(raw.parent_count);
57
65
  return out;
58
66
  }
59
67
 
@@ -91,6 +99,19 @@ function readOutcomesData(outcomesPath) {
91
99
  return out;
92
100
  }
93
101
 
102
+ function readAllOutcomesData(paths = [resolveOutcomesPath(), resolveAutoOutcomesPath()]) {
103
+ const dedup = new Map();
104
+ for (const outcomePath of paths) {
105
+ for (const row of readOutcomesData(outcomePath)) {
106
+ const key = row.commit_hash
107
+ ? `commit:${row.commit_hash}`
108
+ : `${row.timestamp}|${row.model}|${row.tool}|${row.task_type || ""}`;
109
+ dedup.set(key, row);
110
+ }
111
+ }
112
+ return [...dedup.values()];
113
+ }
114
+
94
115
  function dayOf(value) {
95
116
  return typeof value === "string" ? value.slice(0, 10) : "";
96
117
  }
@@ -224,7 +245,9 @@ function computeQualityPerDollar(queueRows, outcomes, { from = "", to = "" } = {
224
245
 
225
246
  module.exports = {
226
247
  resolveOutcomesPath,
248
+ resolveAutoOutcomesPath,
227
249
  sanitizeOutcome,
228
250
  readOutcomesData,
251
+ readAllOutcomesData,
229
252
  computeQualityPerDollar,
230
253
  };