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.
- package/dashboard/dist/assets/{AchievementBadge-DiSoAalB.js → AchievementBadge-D6iPEEbz.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-DI_cvzqy.js → AchievementsPage-Jry355YE.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-ClWZZNvc.js → AchievementsSection-ah-kG00E.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-DpQeG_6H.js → BadgeDetailModal-FyvUrVvF.js} +1 -1
- package/dashboard/dist/assets/{Card-B0hyofoy.js → Card-C3nLScju.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-DZJGQ3-9.js → ClawdAnimated-CLHhE26z.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-Dcikt0kT.js → CommunityStatsModal-DA3PHLV5.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-DCfRP4oI.js → ConfirmModal-CTDarLrD.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-DZIiWc3Y.js +1 -0
- package/dashboard/dist/assets/{DevicePage-De6KuFaJ.js → DevicePage-CyXjUO8W.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-ahxSNUcB.js +1 -0
- package/dashboard/dist/assets/DialogTitle-z86PHHyk.js +1 -0
- package/dashboard/dist/assets/{FadeIn-DZoN7vbQ.js → FadeIn-BDWtfIsO.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-C9HQnEsI.js → HeaderGithubStar-DE1USQbb.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-82zniXwO.js → IpCheckPage-B2SkgT0P.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-Df9fdR0n.js → LandingPage-PU5gxsfY.js} +14 -14
- package/dashboard/dist/assets/{LeaderboardAvatar-CjfEgoR8.js → LeaderboardAvatar-CaOV_hFE.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-BdbE6Nhj.js → LeaderboardPage-B0JtEyRP.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProfileModal-CDTK21dp.js → LeaderboardProfileModal-DtNEbVH8.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-B6QWnwB1.js → LeaderboardProfilePage-DRklax3-.js} +3 -3
- package/dashboard/dist/assets/LimitsPage-Dg0cJa40.js +4 -0
- package/dashboard/dist/assets/{LocalOnlyNotice-DOcSDrOy.js → LocalOnlyNotice-si9PMKya.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-WY_sRA7I.js → LoginPage-DgLwhXKo.js} +1 -1
- package/dashboard/dist/assets/{PetPage-CNbgNE6f.js → PetPage-DEZbjk99.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-Cv525-dF.js → PopoverPopup-DX7v1XfE.js} +1 -1
- package/dashboard/dist/assets/ResetPasswordPage-C6NvRO-Q.js +1 -0
- package/dashboard/dist/assets/{Select-3HkgkO8y.js → Select-CH2xVU8X.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-Bz8FAKEv.js → SelectItemText-CCW6JeeN.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-Cm3uT11D.js +1 -0
- package/dashboard/dist/assets/{SkillsPage-Dnz3eGcE.js → SkillsPage-CljRL6yF.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-OopQ06B8.js → TrendMonitor-DM1_WNfw.js} +2 -2
- package/dashboard/dist/assets/WidgetsPage-mJ1j6hly.js +1 -0
- package/dashboard/dist/assets/{WrappedPage-Dbd-8EKD.js → WrappedPage-Dz71ln4t.js} +1 -1
- package/dashboard/dist/assets/__vite-browser-external-C7JwykID.css +1 -0
- package/dashboard/dist/assets/{__vite-browser-external-CxN2E6q5.js → __vite-browser-external-Eoyj4eG-.js} +47 -18
- package/dashboard/dist/assets/agent-logos-D3K_ZRUj.js +1 -0
- package/dashboard/dist/assets/{arrow-up-right-CGnVz9Km.js → arrow-up-right-CT4-gmOS.js} +1 -1
- package/dashboard/dist/assets/{check-CkI3WNti.js → check-B87_qvAg.js} +1 -1
- package/dashboard/dist/assets/{copy-Bh3g2_O-.js → copy-Dtr68epm.js} +1 -1
- package/dashboard/dist/assets/{download-BITw7nKX.js → download-DaWsA_Gj.js} +1 -1
- package/dashboard/dist/assets/{flame-ByAsnNar.js → flame-vLBOq0X0.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-Cu8JtuN4.js → format-tokens-C6Pidz3s.js} +1 -1
- package/dashboard/dist/assets/{icons-D9OB0N43.js → icons-BaaYJxUN.js} +1 -1
- package/dashboard/dist/assets/{info-Mu2CLf-A.js → info-B46Qt16h.js} +1 -1
- package/dashboard/dist/assets/limits-providers-13af4PEg.js +1 -0
- package/dashboard/dist/assets/{link-2-CSlVaUw9.js → link-2-DeN6MJpT.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-CYck0YaS.js → loader-circle-ByEuaaSw.js} +1 -1
- package/dashboard/dist/assets/{provider-display-BB925tPa.js → provider-display-CKbOKeV4.js} +1 -1
- package/dashboard/dist/assets/{terminal-4YysOnTe.js → terminal-DyicX7lG.js} +1 -1
- package/dashboard/dist/assets/{trash-2-C8-ZfrZG.js → trash-2-CVCC3DtQ.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-Cxt-otko.js → use-community-stats-CExk3D6G.js} +1 -1
- package/dashboard/dist/assets/use-limits-display-prefs-CRl4uU95.js +1 -0
- package/dashboard/dist/assets/{use-native-settings-DbdPXxGf.js → use-native-settings-Bi6E9dsE.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-BZMM-iIj.js → use-ordered-list-Dk0p2otw.js} +1 -1
- package/dashboard/dist/assets/use-session-efficiency-pref-YAG-OYIh.js +1 -0
- package/dashboard/dist/assets/{use-transform-CuAoUb8H.js → use-transform-lflyghWN.js} +1 -1
- package/dashboard/dist/assets/use-usage-limits-DJXvJ25Q.js +1 -0
- package/dashboard/dist/assets/{useCurrency-CpDnFC0N.js → useCurrency-BtHtcsO5.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-Vyaif-7C.js → useScrollLock-C2C-Yazq.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-B8FrUarf.js → useTokenFormat-BdD057ih.js} +1 -1
- package/dashboard/dist/assets/{zap-CdeKJ6HL.js → zap-DWWma29E.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/cli.js +6 -0
- package/src/commands/sessions.js +29 -0
- package/src/lib/context-health.js +124 -0
- package/src/lib/git-outcomes.js +147 -0
- package/src/lib/local-api.js +45 -3
- package/src/lib/outcomes-engine.js +23 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/session-analytics.js +612 -0
- package/src/lib/usage-limits.js +21 -0
- package/dashboard/dist/assets/DashboardPage-DBajsWEp.js +0 -1
- package/dashboard/dist/assets/DialogDescription-uQ4gVIv9.js +0 -1
- package/dashboard/dist/assets/DialogTitle-BvElfi0r.js +0 -1
- package/dashboard/dist/assets/LimitsPage-f0L0d15j.js +0 -4
- package/dashboard/dist/assets/ResetPasswordPage-vrcj6bBP.js +0 -1
- package/dashboard/dist/assets/SettingsPage-CVldAt69.js +0 -1
- package/dashboard/dist/assets/WidgetsPage-4dWjZkc9.js +0 -1
- package/dashboard/dist/assets/__vite-browser-external-CQxW1DuO.css +0 -1
- package/dashboard/dist/assets/agent-logos-CT9fumzx.js +0 -1
- package/dashboard/dist/assets/use-limits-display-prefs-BUFZh6fe.js +0 -1
- package/dashboard/dist/assets/use-quality-per-dollar-pref-DXoW5A0_.js +0 -1
- 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,
|
|
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{
|
|
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-
|
|
253
|
-
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-
|
|
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-
|
|
79
|
-
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-
|
|
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.
|
|
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 };
|
package/src/lib/local-api.js
CHANGED
|
@@ -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
|
-
|
|
1953
|
-
resolveOutcomesPath,
|
|
1952
|
+
readAllOutcomesData,
|
|
1954
1953
|
computeQualityPerDollar,
|
|
1955
1954
|
} = require("./outcomes-engine");
|
|
1956
|
-
|
|
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
|
};
|