copilot-usage-studio 0.2.0 → 0.2.2

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 (38) hide show
  1. package/CHANGELOG.md +30 -2
  2. package/README.md +46 -13
  3. package/data/github-copilot-pricing.json +34 -6
  4. package/dist/copilot-usage-studio/browser/chunk-23NLHIOR.js +1 -0
  5. package/dist/copilot-usage-studio/browser/chunk-5JYQJM5G.js +1 -0
  6. package/dist/copilot-usage-studio/browser/chunk-7I2HDBC6.js +1 -0
  7. package/dist/copilot-usage-studio/browser/{chunk-TVSYR63W.js → chunk-OS2XPCVW.js} +2 -2
  8. package/dist/copilot-usage-studio/browser/{chunk-J47KKACI.js → chunk-QMNOUQ2X.js} +1 -1
  9. package/dist/copilot-usage-studio/browser/{chunk-NXH37FKU.js → chunk-RTOXDOOI.js} +1 -1
  10. package/dist/copilot-usage-studio/browser/chunk-TICIZRSM.js +1 -0
  11. package/dist/copilot-usage-studio/browser/chunk-WOIYAEKB.js +4 -0
  12. package/dist/copilot-usage-studio/browser/{chunk-QQOFM3HF.js → chunk-WWU6QMJC.js} +1 -1
  13. package/dist/copilot-usage-studio/browser/chunk-XMVGLQQH.js +1 -0
  14. package/dist/copilot-usage-studio/browser/index.html +2 -2
  15. package/dist/copilot-usage-studio/browser/main-XFPP45VE.js +1 -0
  16. package/dist/copilot-usage-studio/browser/styles-7RDDQXQV.css +1 -0
  17. package/docs/local-deployment.md +92 -17
  18. package/docs/pricing.md +5 -3
  19. package/docs/scanner-api.md +40 -0
  20. package/lib/cli.mjs +15 -1
  21. package/lib/local-runtime.mjs +499 -19
  22. package/lib/scanner-worker.mjs +25 -0
  23. package/package.json +20 -2
  24. package/scripts/pricing-utils.mjs +5 -0
  25. package/scripts/scan-vscode-sessions.mjs +387 -1475
  26. package/scripts/scanner-customization-evidence.mjs +613 -0
  27. package/scripts/scanner-customization-inventory.mjs +1022 -0
  28. package/scripts/scanner-memory.mjs +229 -0
  29. package/scripts/scanner-session-parser.mjs +1237 -0
  30. package/scripts/scanner-traversal.mjs +203 -0
  31. package/scripts/scanner-workspace.mjs +237 -0
  32. package/dist/copilot-usage-studio/browser/chunk-CUKTUQ6W.js +0 -1
  33. package/dist/copilot-usage-studio/browser/chunk-EYAHOEVS.js +0 -1
  34. package/dist/copilot-usage-studio/browser/chunk-FXNLFSUB.js +0 -1
  35. package/dist/copilot-usage-studio/browser/chunk-HJNYITFH.js +0 -1
  36. package/dist/copilot-usage-studio/browser/chunk-KDAJN6DF.js +0 -4
  37. package/dist/copilot-usage-studio/browser/main-TL27ZSEQ.js +0 -1
  38. package/dist/copilot-usage-studio/browser/styles-GZOQ5QIH.css +0 -1
@@ -1 +1 @@
1
- import{a as Y,b as Z,c as ee,d as te,e as ne,g as V}from"./chunk-NXH37FKU.js";import{f as L,q as A,r as E,s as U}from"./chunk-FXNLFSUB.js";import{$a as y,Ca as u,Da as x,Ea as R,Fa as M,Ga as P,Ha as g,Ia as i,Ja as n,Ka as w,Na as O,O as b,P as f,Pa as v,Ra as p,Sa as D,U as z,Ua as a,Va as _,Wa as m,Xa as N,Ya as T,Z as S,Za as c,_a as C,cb as k,ka as l,nb as W,rb as H,sa as G,tb as j,ub as q,vb as J,wb as K,xb as Q,yb as X}from"./chunk-KDAJN6DF.js";var ie=(o,t)=>t.value,me=(o,t)=>t.model+t.pricingModel,ge=(o,t)=>t.size,_e=(o,t)=>t.key,ue=(o,t)=>t.label,xe=(o,t)=>t.session.id;function Ce(o,t){if(o&1&&a(0),o&2){let e=p();m(" ",e.analyticsExcludedCount," excluded by these filters. ")}}function ye(o,t){if(o&1){let e=O();i(0,"button",11),v("click",function(){b(e);let r=p(2);return f(r.resetAnalyticsFilters())}),a(1,"Reset filters"),n()}}function he(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e.value),l(),_(e.label)}}function be(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e),l(),_(e==="all"?"All workspaces":e)}}function fe(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e),l(),_(e==="all"?"All models":e)}}function ve(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e.value),l(),_(e.label)}}function Me(o,t){if(o&1){let e=O();i(0,"button",11),v("click",function(){b(e);let r=p(3);return f(r.resetAnalyticsFilters())}),a(1,"Reset filters"),n()}}function Pe(o,t){if(o&1&&(i(0,"section",10)(1,"h3"),a(2),n(),i(3,"p"),a(4),n(),u(5,Me,2,0,"button",5),n()),o&2){let e=p();l(2),_(e.emptyTitle),l(2),_(e.emptyDetail),l(),x(e.analyticsFiltersActive?5:-1)}}function Oe(o,t){o&1&&(i(0,"em",27),a(1,"fallback pricing"),n())}function Se(o,t){if(o&1&&(a(0),c(1,"number")),o&2){let e=p().$implicit;m(" / ",C(1,1,e.cachedInput)," cached in ")}}function we(o,t){if(o&1&&(a(0),c(1,"number")),o&2){let e=p().$implicit;m(" / ",C(1,1,e.cacheWrite)," cache write ")}}function ke(o,t){if(o&1&&(i(0,"div",17)(1,"strong"),a(2),i(3,"em"),a(4),n(),u(5,Oe,2,0,"em",27),n(),i(6,"span"),a(7),c(8,"number"),n(),i(9,"span"),a(10),c(11,"number"),i(12,"em"),a(13),c(14,"number"),u(15,Se,2,3),u(16,we,2,3),a(17),c(18,"number"),n()(),i(19,"span"),a(20),c(21,"number"),i(22,"em"),a(23),c(24,"number"),n()(),i(25,"span"),a(26),c(27,"number"),n(),i(28,"span",28),a(29),c(30,"number"),w(31,"i"),n()()),o&2){let e=t.$implicit,s=p(3);l(2),m(" ",e.model," "),l(2),_(e.pricingModel),l(),x(e.usesFallbackPrice?5:-1),l(2),_(C(8,15,e.sessionCount)),l(3),m(" ",C(11,17,e.tokens)," "),l(3),m(" ",C(14,19,e.input)," normal in "),l(2),x(e.cachedInput?15:-1),l(),x(e.cacheWrite?16:-1),l(),m(" / ",C(18,21,e.output)," out "),l(3),m(" $",y(21,23,e.cost,"1.2-4")," "),l(3),m("",y(24,26,s.aiCredits(e.cost),"1.0-1")," credits"),l(3),m("$",y(27,29,e.costPer1k,"1.4-4")),l(3),m(" ",y(30,32,e.share,"1.0-0"),"% "),l(2),D("width",e.share,"%")}}function Ee(o,t){o&1&&(i(0,"p",18),a(1,"No model rows for the current Insights cohort."),n())}function Te(o,t){if(o&1&&(i(0,"small"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),m("Top run: ",e.topSession.title)}}function Ae(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.topSession))}),i(1,"span"),a(2),n(),i(3,"strong"),a(4),c(5,"number"),n(),i(6,"em"),a(7),c(8,"number"),c(9,"number"),c(10,"number"),n(),u(11,Te,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.topSession),l(2),_(e.size),l(2),m("",C(5,7,e.count)," runs"),l(3),T(" ",y(8,9,e.credits,"1.0-1")," credits \xB7 $",y(9,12,e.cost,"1.2-4")," \xB7 ",y(10,15,e.share,"1.0-0"),"% of cohort "),l(4),x(e.topSession?11:-1)}}function Ie(o,t){if(o&1&&(i(0,"small"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),m("Top run: ",e.topSession.title)}}function Fe(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.topSession))}),i(1,"span"),a(2),n(),i(3,"strong"),a(4),c(5,"number"),n(),i(6,"em"),a(7),c(8,"number"),c(9,"number"),c(10,"number"),n(),u(11,Ie,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.topSession),l(2),_(e.label),l(2),m("",C(5,7,e.count)," runs"),l(3),T(" ",y(8,9,e.credits,"1.0-1")," credits \xB7 $",y(9,12,e.cost,"1.2-4")," \xB7 ",C(10,15,e.tokens)," tokens "),l(4),x(e.topSession?11:-1)}}function Be(o,t){o&1&&(i(0,"p",18),a(1,"No trend rows for the current Insights cohort."),n())}function $e(o,t){if(o&1&&(i(0,"em"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),_(e.session.title)}}function Re(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.session))}),i(1,"span",31),a(2),w(3,"app-help-popover",32),n(),i(4,"strong"),a(5),n(),u(6,$e,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.session),l(2),m(" ",e.label," "),l(),g("text",e.help)("label","Explain "+e.label)("interactive",!1),l(2),_(e.value),l(),x(e.session?6:-1)}}function Ve(o,t){if(o&1){let e=O();i(0,"button",33),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.session))}),i(1,"span"),a(2),c(3,"number"),c(4,"number"),c(5,"number"),n(),i(6,"strong"),a(7),n(),i(8,"em"),a(9),n(),i(10,"span",30),a(11,"Open run"),n()()}if(o&2){let e=t.$implicit,s=p(3);l(2),T(" ",C(3,5,e.tokens)," tokens \xB7 $",y(4,7,s.usageUsd(e.session),"1.2-4")," \xB7 ",y(5,10,s.usageCredits(e.session),"1.0-1")," credits "),l(5),_(e.session.title),l(2),_(e.reason)}}function ze(o,t){o&1&&(i(0,"p",18),a(1,"No outliers in the current Insights cohort."),n())}function Ge(o,t){if(o&1&&(i(0,"section",12)(1,"div",13)(2,"div",14)(3,"div")(4,"h3"),a(5,"Model breakdown"),n(),i(6,"p"),a(7,"Model mix and priced token shape for this cohort."),n()(),i(8,"span"),a(9),c(10,"number"),n()(),i(11,"div",15)(12,"div",16)(13,"span"),a(14,"Model"),n(),i(15,"span"),a(16,"Sessions"),n(),i(17,"span"),a(18,"Tokens"),n(),i(19,"span"),a(20,"Cost"),n(),i(21,"span"),a(22,"Cost / 1k"),n(),i(23,"span"),a(24,"Share"),n()(),M(25,ke,32,35,"div",17,me,!1,Ee,2,0,"p",18),n()(),i(28,"aside",19)(29,"div",20)(30,"div",21)(31,"h3"),a(32,"Run size mix"),n(),i(33,"p"),a(34,"How runs are distributed by size."),n()(),i(35,"div",22),M(36,Ae,12,18,"button",23,ge),n()(),i(38,"div",20)(39,"div",21)(40,"h3"),a(41,"Usage trend"),n(),i(42,"p"),a(43),n()(),i(44,"div",22),M(45,Fe,12,17,"button",23,_e,!1,Be,2,0,"p",18),n()()()(),i(48,"section",24)(49,"div",20)(50,"div",21)(51,"h3"),a(52,"Runs to inspect"),n(),i(53,"p"),a(54,"Open the largest runs in this cohort."),n()(),i(55,"div",25),M(56,Re,7,7,"button",23,ue),n()(),i(58,"div",20)(59,"div",21)(60,"h3"),a(61,"Outlier signals"),n(),i(62,"p"),a(63,"Runs that stand apart from this cohort."),n()(),i(64,"div",25),M(65,Ve,12,13,"button",26,xe,!1,ze,2,0,"p",18),n()()()),o&2){let e=p();l(9),m("",C(10,5,e.modelRows.length)," rows"),l(16),P(e.modelRows),l(11),P(e.distribution),l(7),m("",e.groupingLabel,"."),l(2),P(e.trendRows),l(11),P(e.highlights),l(9),P(e.outliers)}}function De(o,t){if(o&1){let e=O();i(0,"section",0)(1,"div",1)(2,"div")(3,"p",2),a(4,"Cohort insights"),n(),i(5,"h2"),a(6,"Run patterns"),n(),i(7,"p",3),a(8),u(9,Ce,1,1),w(10,"app-help-popover",4),n()(),u(11,ye,2,0,"button",5),n(),i(12,"section",6)(13,"label")(14,"span"),a(15," Time range "),n(),i(16,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsTimeRange(r))}),M(17,he,2,2,"option",8,ie),n()(),i(19,"label")(20,"span"),a(21,"Workspace"),n(),i(22,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsWorkspaceFilter(r))}),M(23,be,2,2,"option",8,R),n()(),i(25,"label")(26,"span"),a(27,"Model"),n(),i(28,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsModelFilter(r))}),M(29,fe,2,2,"option",8,R),n()(),i(31,"label")(32,"span"),a(33," Group trend by "),w(34,"app-help-popover",9),n(),i(35,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsGrouping(r))}),M(36,ve,2,2,"option",8,ie),n()()(),u(38,Pe,6,3,"section",10)(39,Ge,68,7),n()}if(o&2){let e=t,s=p();l(8),N(" ",e.count," of ",e.importedCount," imported sessions included. "),l(),x(e.analyticsExcludedCount>0?9:-1),l(),g("text",s.help.analyticsScope),l(),x(e.analyticsFiltersActive?11:-1),l(5),g("ngModel",s.analyticsTimeRange()),l(),P(s.analyticsTimeOptions),l(5),g("ngModel",s.analyticsWorkspaceFilter()),l(),P(s.analyticsWorkspaceOptions()),l(5),g("ngModel",s.analyticsModelFilter()),l(),P(s.analyticsModelOptions()),l(5),g("text",s.help.trendGrouping),l(),g("ngModel",s.analyticsGrouping()),l(),P(s.analyticsGroupingOptions),l(2),x(e.count===0?38:39)}}var oe=class o{sessionsInput=S([]);openSession=new z;set sessions(t){this.sessionsInput.set(t??[])}analyticsTimeRange=S("all");analyticsWorkspaceFilter=S("all");analyticsModelFilter=S("all");analyticsGrouping=S("day");help={analyticsScope:"Insights use imported sessions and the time, workspace, and model filters on this page.",trendGrouping:"Time range chooses which sessions are included. Grouping only changes how those sessions are bucketed in the trend panel."};sizeOptions=["Small","Medium","Large","Very large"];analyticsTimeOptions=[{value:"all",label:"All time"},{value:"current-month",label:"Current month"},{value:"previous-month",label:"Previous month"},{value:"7d",label:"Last 7 days"},{value:"30d",label:"Last 30 days"},{value:"90d",label:"Last 90 days"}];analyticsGroupingOptions=[{value:"day",label:"By day"},{value:"week",label:"By week"},{value:"month",label:"By month"}];analyticsWorkspaceOptions=k(()=>{let t=new Set(this.sessionsInput().map(s=>s.workspace).filter(Boolean)),e=this.analyticsWorkspaceFilter();return e!=="all"&&t.add(e),["all",...[...t].sort()]});analyticsModelOptions=k(()=>{let t=new Set;for(let s of this.sessionsInput())for(let r of s.modelBreakdown)t.add(r.pricingModel||r.model);let e=this.analyticsModelFilter();return e!=="all"&&t.add(e),["all",...[...t].sort()]});analyticsSessions=k(()=>Y(this.sessionsInput(),this.analyticsTimeRange(),this.analyticsWorkspaceFilter(),this.analyticsModelFilter()));analytics=k(()=>{let t=this.analyticsSessions(),e=t.length,s=this.sessionsInput().length,r=t.reduce((h,$)=>h+A($),0),d=t.reduce((h,$)=>h+E($),0),ae=e?r/e:0,le=e?d/e:0,I=V(t,h=>A(h)),F=V(t,h=>E(h)),se=Z(t,d),re=ee(t,this.analyticsGrouping()),ce=te(t,d),pe=ne(t,le,ae),de=this.analyticsTimeRange()!=="all"||this.analyticsWorkspaceFilter()!=="all"||this.analyticsModelFilter()!=="all"||this.analyticsGrouping()!=="day",B=Math.max(s-e,0);return{count:e,importedCount:s,analyticsFiltersActive:de,analyticsExcludedCount:B,emptyTitle:s===0?"No imported sessions":"No sessions in this Insights cohort",emptyDetail:s===0?"Import VS Code sessions to explore model mix, run sizes, trends, and outliers.":`${B.toLocaleString()} imported session${B===1?"":"s"} excluded by the Insights controls. Reset the filters to return to all imported sessions.`,timeRangeLabel:this.analyticsTimeOptions.find(h=>h.value===this.analyticsTimeRange())?.label??"All time",workspaceLabel:this.analyticsWorkspaceFilter()==="all"?"All workspaces":this.analyticsWorkspaceFilter(),modelLabel:this.analyticsModelFilter()==="all"?"All models":this.analyticsModelFilter(),groupingLabel:this.analyticsGroupingOptions.find(h=>h.value===this.analyticsGrouping())?.label??"By day",highlights:[{label:"Highest-token run",session:I,value:I?`${A(I).toLocaleString()} tokens`:"n/a",help:"The included session with the largest imported token total."},{label:"Most expensive run",session:F,value:F?`$${E(F).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:4})}`:"n/a",help:"The included session with the highest GitHub source usage, falling back to token estimate when source usage is absent."}],modelRows:se,trendRows:re,distribution:ce,outliers:pe}});setAnalyticsTimeRange(t){this.analyticsTimeRange.set(t)}setAnalyticsWorkspaceFilter(t){this.analyticsWorkspaceFilter.set(t)}setAnalyticsModelFilter(t){this.analyticsModelFilter.set(t)}setAnalyticsGrouping(t){this.analyticsGrouping.set(t)}resetAnalyticsFilters(){this.analyticsTimeRange.set("all"),this.analyticsWorkspaceFilter.set("all"),this.analyticsModelFilter.set("all"),this.analyticsGrouping.set("day")}emitOpenSession(t){t&&this.openSession.emit(t)}aiCredits(t){return t/L}usageUsd(t){return E(t)}usageCredits(t){return U(t)}static \u0275fac=function(e){return new(e||o)};static \u0275cmp=G({type:o,selectors:[["app-analytics-page"]],inputs:{sessions:"sessions"},outputs:{openSession:"openSession"},decls:1,vars:1,consts:[[1,"pricing-page","analytics-page"],[1,"pricing-header"],[1,"eyebrow"],[1,"analytics-cohort"],["label","Explain analytics scope",3,"text"],["type","button",1,"ghost-button"],["aria-label","Analytics cohort controls",1,"analytics-controls"],[3,"ngModelChange","ngModel"],[3,"value"],["label","Explain trend grouping",3,"text"],[1,"analytics-empty"],["type","button",1,"ghost-button",3,"click"],[1,"analytics-primary"],[1,"analytics-panel","model-panel"],[1,"panel-heading"],["role","table","aria-label","Model breakdown",1,"cost-table","compact-table"],[1,"cost-row","analytics-model-row","cost-row-heading"],[1,"cost-row","analytics-model-row"],[1,"empty"],[1,"analytics-side"],[1,"analytics-panel"],[1,"panel-heading","compact-heading"],[1,"stat-list","compact"],["type","button",3,"disabled"],[1,"analytics-split"],[1,"highlight-list"],["type","button"],[1,"warning-text"],[1,"share-cell"],["type","button",3,"click","disabled"],[1,"open-cue"],[1,"row-kicker"],[3,"text","label","interactive"],["type","button",3,"click"]],template:function(e,s){if(e&1&&u(0,De,40,11,"section",0),e&2){let r;x((r=s.analytics())?0:-1,r)}},dependencies:[X,K,Q,J,j,q,H,W],styles:[".analytics-page[_ngcontent-%COMP%]{display:grid;gap:10px}.pricing-header[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.pricing-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{margin:3px 0 0;color:var(--text-strong);font-size:21px;font-weight:760;letter-spacing:0}.pricing-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px;max-width:820px;margin:6px 0 0;color:var(--muted);font-size:12px;line-height:1.45}.analytics-cohort[_ngcontent-%COMP%]{opacity:.86}.ghost-button[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:9px;padding:7px 10px;color:var(--text);background:var(--surface-soft);font-size:13px;font-weight:720;cursor:pointer}.ghost-button[_ngcontent-%COMP%]:hover{border-color:var(--line-strong)}.analytics-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr));gap:7px;border:1px solid var(--line);border-radius:12px;padding:8px;background:linear-gradient(135deg,#0c9f830e,#6f5cff09),var(--surface);box-shadow:var(--shadow-soft, 0 12px 30px rgba(15, 23, 42, .08))}.analytics-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{display:grid;gap:5px;min-width:0;color:var(--muted);font-size:10px;font-weight:720}.analytics-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:4px}.analytics-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%], .analytics-controls[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{width:100%;min-height:30px;border:1px solid var(--line);border-radius:7px;padding:6px 9px;background:var(--surface-soft);color:var(--text);font:inherit;font-size:12px;font-weight:720}.analytics-empty[_ngcontent-%COMP%], .analytics-panel[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:12px;background:var(--surface);box-shadow:var(--shadow-soft, 0 12px 30px rgba(15, 23, 42, .08))}.analytics-empty[_ngcontent-%COMP%]{display:grid;gap:8px;justify-items:start;padding:18px}.analytics-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{max-width:720px;margin:0;color:var(--muted);font-size:12px}.analytics-primary[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr;gap:10px;align-items:start}.analytics-side[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.analytics-split[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:start}.analytics-panel[_ngcontent-%COMP%]{display:grid;gap:8px;min-width:0;padding:11px}.analytics-panel[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .analytics-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{margin:0;color:var(--text-strong);font-size:15px;font-weight:760}.panel-heading[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.compact-heading[_ngcontent-%COMP%]{align-items:baseline}.panel-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:3px 0 0;color:var(--muted);font-size:12px}.compact-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:0;text-align:right}.panel-note[_ngcontent-%COMP%]{margin:-3px 0 0;color:var(--muted);font-size:12px}.panel-heading[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{flex:0 0 auto;border:1px solid var(--line);border-radius:999px;padding:3px 7px;color:var(--muted);background:var(--surface-soft);font-size:11px;font-weight:720}.highlight-list[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%]{display:grid;gap:6px}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] div[_ngcontent-%COMP%]{display:grid;gap:5px;width:100%;min-width:0;border:1px solid var(--line);border-radius:9px;padding:8px 9px;background:var(--surface-soft);color:var(--text);text-align:left}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{cursor:pointer}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover, .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover{border-color:var(--line-strong)}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled, .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled{cursor:default;opacity:.65}.highlight-list[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .highlight-list[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .empty[_ngcontent-%COMP%]{color:var(--muted);font-size:12px;font-style:normal;line-height:1.35}.stat-list[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row-kicker[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:5px}.highlight-list[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-strong);font-size:14px;font-weight:760;line-height:1.25}.open-cue[_ngcontent-%COMP%]{justify-self:start;border:1px solid var(--line);border-radius:999px;padding:3px 7px;background:#0c9f8314;color:var(--accent-strong, var(--accent))!important;font-size:10px!important;font-weight:760;text-transform:uppercase;letter-spacing:.04em}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover .open-cue[_ngcontent-%COMP%], .highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:focus-visible .open-cue[_ngcontent-%COMP%]{border-color:color-mix(in srgb,var(--accent) 45%,var(--line));background:#0c9f8324}.stat-list.compact[_ngcontent-%COMP%] div[_ngcontent-%COMP%], .stat-list.compact[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{grid-template-columns:minmax(110px,.35fr) minmax(0,1fr) auto;gap:4px 10px;align-items:center;padding:8px 9px}.stat-list.compact[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .stat-list.compact[_ngcontent-%COMP%] .open-cue[_ngcontent-%COMP%]{grid-column:2 / -1}.cost-table[_ngcontent-%COMP%]{overflow-x:auto;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.cost-row[_ngcontent-%COMP%]{display:grid;align-items:start;gap:8px;min-width:650px;border-bottom:1px solid var(--line);padding:8px 10px}.cost-row[_ngcontent-%COMP%]:last-child{border-bottom:0}.cost-row-heading[_ngcontent-%COMP%]{color:var(--muted);background:var(--surface-soft);font-size:11px;font-weight:760;letter-spacing:.04em;text-transform:uppercase}.analytics-model-row[_ngcontent-%COMP%]{grid-template-columns:minmax(170px,1.25fr) minmax(62px,.36fr) minmax(180px,1fr) minmax(86px,.48fr) minmax(84px,.46fr) minmax(80px,.45fr)}.analytics-model-row[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{display:grid;gap:3px}.analytics-model-row[_ngcontent-%COMP%] em[_ngcontent-%COMP%]{display:block;margin-top:2px}.warning-text[_ngcontent-%COMP%]{color:var(--warning-text, #ffcf91)!important}.share-cell[_ngcontent-%COMP%]{display:grid;gap:5px}.share-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{display:block;width:0;max-width:100%;height:4px;border-radius:999px;background:linear-gradient(90deg,var(--accent),var(--accent-2))}@media(max-width:1200px){.analytics-side[_ngcontent-%COMP%], .analytics-split[_ngcontent-%COMP%]{grid-template-columns:1fr}}@media(max-width:960px){.analytics-primary[_ngcontent-%COMP%]{grid-template-columns:1fr}}@media(max-width:900px){.pricing-header[_ngcontent-%COMP%], .analytics-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr}}@media(max-width:600px){.analytics-panel[_ngcontent-%COMP%]{padding:11px}.cost-row[_ngcontent-%COMP%]{min-width:620px}}"]})};export{oe as AnalyticsPageComponent};
1
+ import{a as Y,b as Z,c as ee,d as te,e as ne,g as V}from"./chunk-RTOXDOOI.js";import{f as L,q as A,r as E,s as U}from"./chunk-TICIZRSM.js";import{$a as C,Ca as u,Da as x,Ea as R,Fa as M,Ga as P,Ha as g,Ia as i,Ja as n,Ka as w,O as b,Oa as O,P as f,Qa as v,Sa as p,Ta as D,U as z,Va as a,Wa as _,Xa as m,Ya as N,Z as S,Za as T,_a as c,ab as y,db as k,ka as l,ob as W,sa as G,sb as H,ub as j,vb as q,wb as J,xb as K,yb as Q,zb as X}from"./chunk-WOIYAEKB.js";var ie=(o,t)=>t.value,me=(o,t)=>t.model+t.pricingModel,ge=(o,t)=>t.size,_e=(o,t)=>t.key,ue=(o,t)=>t.label,xe=(o,t)=>t.session.id;function Ce(o,t){if(o&1&&a(0),o&2){let e=p();m(" ",e.analyticsExcludedCount," excluded by these filters. ")}}function ye(o,t){if(o&1){let e=O();i(0,"button",11),v("click",function(){b(e);let r=p(2);return f(r.resetAnalyticsFilters())}),a(1,"Reset filters"),n()}}function he(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e.value),l(),_(e.label)}}function be(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e),l(),_(e==="all"?"All workspaces":e)}}function fe(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e),l(),_(e==="all"?"All models":e)}}function ve(o,t){if(o&1&&(i(0,"option",8),a(1),n()),o&2){let e=t.$implicit;g("value",e.value),l(),_(e.label)}}function Me(o,t){if(o&1){let e=O();i(0,"button",11),v("click",function(){b(e);let r=p(3);return f(r.resetAnalyticsFilters())}),a(1,"Reset filters"),n()}}function Pe(o,t){if(o&1&&(i(0,"section",10)(1,"h3"),a(2),n(),i(3,"p"),a(4),n(),u(5,Me,2,0,"button",5),n()),o&2){let e=p();l(2),_(e.emptyTitle),l(2),_(e.emptyDetail),l(),x(e.analyticsFiltersActive?5:-1)}}function Oe(o,t){o&1&&(i(0,"em",27),a(1,"fallback pricing"),n())}function Se(o,t){if(o&1&&(a(0),c(1,"number")),o&2){let e=p().$implicit;m(" / ",C(1,1,e.cachedInput)," cached in ")}}function we(o,t){if(o&1&&(a(0),c(1,"number")),o&2){let e=p().$implicit;m(" / ",C(1,1,e.cacheWrite)," cache write ")}}function ke(o,t){if(o&1&&(i(0,"div",17)(1,"strong"),a(2),i(3,"em"),a(4),n(),u(5,Oe,2,0,"em",27),n(),i(6,"span"),a(7),c(8,"number"),n(),i(9,"span"),a(10),c(11,"number"),i(12,"em"),a(13),c(14,"number"),u(15,Se,2,3),u(16,we,2,3),a(17),c(18,"number"),n()(),i(19,"span"),a(20),c(21,"number"),i(22,"em"),a(23),c(24,"number"),n()(),i(25,"span"),a(26),c(27,"number"),n(),i(28,"span",28),a(29),c(30,"number"),w(31,"i"),n()()),o&2){let e=t.$implicit,s=p(3);l(2),m(" ",e.model," "),l(2),_(e.pricingModel),l(),x(e.usesFallbackPrice?5:-1),l(2),_(C(8,15,e.sessionCount)),l(3),m(" ",C(11,17,e.tokens)," "),l(3),m(" ",C(14,19,e.input)," normal in "),l(2),x(e.cachedInput?15:-1),l(),x(e.cacheWrite?16:-1),l(),m(" / ",C(18,21,e.output)," out "),l(3),m(" $",y(21,23,e.cost,"1.2-4")," "),l(3),m("",y(24,26,s.aiCredits(e.cost),"1.0-1")," credits"),l(3),m("$",y(27,29,e.costPer1k,"1.4-4")),l(3),m(" ",y(30,32,e.share,"1.0-0"),"% "),l(2),D("width",e.share,"%")}}function Ee(o,t){o&1&&(i(0,"p",18),a(1,"No model rows for the current Insights cohort."),n())}function Te(o,t){if(o&1&&(i(0,"small"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),m("Top run: ",e.topSession.title)}}function Ae(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.topSession))}),i(1,"span"),a(2),n(),i(3,"strong"),a(4),c(5,"number"),n(),i(6,"em"),a(7),c(8,"number"),c(9,"number"),c(10,"number"),n(),u(11,Te,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.topSession),l(2),_(e.size),l(2),m("",C(5,7,e.count)," runs"),l(3),T(" ",y(8,9,e.credits,"1.0-1")," credits \xB7 $",y(9,12,e.cost,"1.2-4")," \xB7 ",y(10,15,e.share,"1.0-0"),"% of cohort "),l(4),x(e.topSession?11:-1)}}function Ie(o,t){if(o&1&&(i(0,"small"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),m("Top run: ",e.topSession.title)}}function Fe(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.topSession))}),i(1,"span"),a(2),n(),i(3,"strong"),a(4),c(5,"number"),n(),i(6,"em"),a(7),c(8,"number"),c(9,"number"),c(10,"number"),n(),u(11,Ie,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.topSession),l(2),_(e.label),l(2),m("",C(5,7,e.count)," runs"),l(3),T(" ",y(8,9,e.credits,"1.0-1")," credits \xB7 $",y(9,12,e.cost,"1.2-4")," \xB7 ",C(10,15,e.tokens)," tokens "),l(4),x(e.topSession?11:-1)}}function Be(o,t){o&1&&(i(0,"p",18),a(1,"No trend rows for the current Insights cohort."),n())}function $e(o,t){if(o&1&&(i(0,"em"),a(1),n(),i(2,"span",30),a(3,"Open run"),n()),o&2){let e=p().$implicit;l(),_(e.session.title)}}function Re(o,t){if(o&1){let e=O();i(0,"button",29),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.session))}),i(1,"span",31),a(2),w(3,"app-help-popover",32),n(),i(4,"strong"),a(5),n(),u(6,$e,4,1),n()}if(o&2){let e=t.$implicit;g("disabled",!e.session),l(2),m(" ",e.label," "),l(),g("text",e.help)("label","Explain "+e.label)("interactive",!1),l(2),_(e.value),l(),x(e.session?6:-1)}}function Ve(o,t){if(o&1){let e=O();i(0,"button",33),v("click",function(){let r=b(e).$implicit,d=p(3);return f(d.emitOpenSession(r.session))}),i(1,"span"),a(2),c(3,"number"),c(4,"number"),c(5,"number"),n(),i(6,"strong"),a(7),n(),i(8,"em"),a(9),n(),i(10,"span",30),a(11,"Open run"),n()()}if(o&2){let e=t.$implicit,s=p(3);l(2),T(" ",C(3,5,e.tokens)," tokens \xB7 $",y(4,7,s.usageUsd(e.session),"1.2-4")," \xB7 ",y(5,10,s.usageCredits(e.session),"1.0-1")," credits "),l(5),_(e.session.title),l(2),_(e.reason)}}function ze(o,t){o&1&&(i(0,"p",18),a(1,"No outliers in the current Insights cohort."),n())}function Ge(o,t){if(o&1&&(i(0,"section",12)(1,"div",13)(2,"div",14)(3,"div")(4,"h3"),a(5,"Model breakdown"),n(),i(6,"p"),a(7,"Model mix and priced token shape for this cohort."),n()(),i(8,"span"),a(9),c(10,"number"),n()(),i(11,"div",15)(12,"div",16)(13,"span"),a(14,"Model"),n(),i(15,"span"),a(16,"Sessions"),n(),i(17,"span"),a(18,"Tokens"),n(),i(19,"span"),a(20,"Cost"),n(),i(21,"span"),a(22,"Cost / 1k"),n(),i(23,"span"),a(24,"Share"),n()(),M(25,ke,32,35,"div",17,me,!1,Ee,2,0,"p",18),n()(),i(28,"aside",19)(29,"div",20)(30,"div",21)(31,"h3"),a(32,"Run size mix"),n(),i(33,"p"),a(34,"How runs are distributed by size."),n()(),i(35,"div",22),M(36,Ae,12,18,"button",23,ge),n()(),i(38,"div",20)(39,"div",21)(40,"h3"),a(41,"Usage trend"),n(),i(42,"p"),a(43),n()(),i(44,"div",22),M(45,Fe,12,17,"button",23,_e,!1,Be,2,0,"p",18),n()()()(),i(48,"section",24)(49,"div",20)(50,"div",21)(51,"h3"),a(52,"Runs to inspect"),n(),i(53,"p"),a(54,"Open the largest runs in this cohort."),n()(),i(55,"div",25),M(56,Re,7,7,"button",23,ue),n()(),i(58,"div",20)(59,"div",21)(60,"h3"),a(61,"Outlier signals"),n(),i(62,"p"),a(63,"Runs that stand apart from this cohort."),n()(),i(64,"div",25),M(65,Ve,12,13,"button",26,xe,!1,ze,2,0,"p",18),n()()()),o&2){let e=p();l(9),m("",C(10,5,e.modelRows.length)," rows"),l(16),P(e.modelRows),l(11),P(e.distribution),l(7),m("",e.groupingLabel,"."),l(2),P(e.trendRows),l(11),P(e.highlights),l(9),P(e.outliers)}}function De(o,t){if(o&1){let e=O();i(0,"section",0)(1,"div",1)(2,"div")(3,"p",2),a(4,"Cohort insights"),n(),i(5,"h2"),a(6,"Run patterns"),n(),i(7,"p",3),a(8),u(9,Ce,1,1),w(10,"app-help-popover",4),n()(),u(11,ye,2,0,"button",5),n(),i(12,"section",6)(13,"label")(14,"span"),a(15," Time range "),n(),i(16,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsTimeRange(r))}),M(17,he,2,2,"option",8,ie),n()(),i(19,"label")(20,"span"),a(21,"Workspace"),n(),i(22,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsWorkspaceFilter(r))}),M(23,be,2,2,"option",8,R),n()(),i(25,"label")(26,"span"),a(27,"Model"),n(),i(28,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsModelFilter(r))}),M(29,fe,2,2,"option",8,R),n()(),i(31,"label")(32,"span"),a(33," Group trend by "),w(34,"app-help-popover",9),n(),i(35,"select",7),v("ngModelChange",function(r){b(e);let d=p();return f(d.setAnalyticsGrouping(r))}),M(36,ve,2,2,"option",8,ie),n()()(),u(38,Pe,6,3,"section",10)(39,Ge,68,7),n()}if(o&2){let e=t,s=p();l(8),N(" ",e.count," of ",e.importedCount," imported sessions included. "),l(),x(e.analyticsExcludedCount>0?9:-1),l(),g("text",s.help.analyticsScope),l(),x(e.analyticsFiltersActive?11:-1),l(5),g("ngModel",s.analyticsTimeRange()),l(),P(s.analyticsTimeOptions),l(5),g("ngModel",s.analyticsWorkspaceFilter()),l(),P(s.analyticsWorkspaceOptions()),l(5),g("ngModel",s.analyticsModelFilter()),l(),P(s.analyticsModelOptions()),l(5),g("text",s.help.trendGrouping),l(),g("ngModel",s.analyticsGrouping()),l(),P(s.analyticsGroupingOptions),l(2),x(e.count===0?38:39)}}var oe=class o{sessionsInput=S([]);openSession=new z;set sessions(t){this.sessionsInput.set(t??[])}analyticsTimeRange=S("all");analyticsWorkspaceFilter=S("all");analyticsModelFilter=S("all");analyticsGrouping=S("day");help={analyticsScope:"Insights use imported sessions and the time, workspace, and model filters on this page.",trendGrouping:"Time range chooses which sessions are included. Grouping only changes how those sessions are bucketed in the trend panel."};sizeOptions=["Small","Medium","Large","Very large"];analyticsTimeOptions=[{value:"all",label:"All time"},{value:"current-month",label:"Current month"},{value:"previous-month",label:"Previous month"},{value:"7d",label:"Last 7 days"},{value:"30d",label:"Last 30 days"},{value:"90d",label:"Last 90 days"}];analyticsGroupingOptions=[{value:"day",label:"By day"},{value:"week",label:"By week"},{value:"month",label:"By month"}];analyticsWorkspaceOptions=k(()=>{let t=new Set(this.sessionsInput().map(s=>s.workspace).filter(Boolean)),e=this.analyticsWorkspaceFilter();return e!=="all"&&t.add(e),["all",...[...t].sort()]});analyticsModelOptions=k(()=>{let t=new Set;for(let s of this.sessionsInput())for(let r of s.modelBreakdown)t.add(r.pricingModel||r.model);let e=this.analyticsModelFilter();return e!=="all"&&t.add(e),["all",...[...t].sort()]});analyticsSessions=k(()=>Y(this.sessionsInput(),this.analyticsTimeRange(),this.analyticsWorkspaceFilter(),this.analyticsModelFilter()));analytics=k(()=>{let t=this.analyticsSessions(),e=t.length,s=this.sessionsInput().length,r=t.reduce((h,$)=>h+A($),0),d=t.reduce((h,$)=>h+E($),0),ae=e?r/e:0,le=e?d/e:0,I=V(t,h=>A(h)),F=V(t,h=>E(h)),se=Z(t,d),re=ee(t,this.analyticsGrouping()),ce=te(t,d),pe=ne(t,le,ae),de=this.analyticsTimeRange()!=="all"||this.analyticsWorkspaceFilter()!=="all"||this.analyticsModelFilter()!=="all"||this.analyticsGrouping()!=="day",B=Math.max(s-e,0);return{count:e,importedCount:s,analyticsFiltersActive:de,analyticsExcludedCount:B,emptyTitle:s===0?"No imported sessions":"No sessions in this Insights cohort",emptyDetail:s===0?"Import VS Code sessions to explore model mix, run sizes, trends, and outliers.":`${B.toLocaleString()} imported session${B===1?"":"s"} excluded by the Insights controls. Reset the filters to return to all imported sessions.`,timeRangeLabel:this.analyticsTimeOptions.find(h=>h.value===this.analyticsTimeRange())?.label??"All time",workspaceLabel:this.analyticsWorkspaceFilter()==="all"?"All workspaces":this.analyticsWorkspaceFilter(),modelLabel:this.analyticsModelFilter()==="all"?"All models":this.analyticsModelFilter(),groupingLabel:this.analyticsGroupingOptions.find(h=>h.value===this.analyticsGrouping())?.label??"By day",highlights:[{label:"Highest-token run",session:I,value:I?`${A(I).toLocaleString()} tokens`:"n/a",help:"The included session with the largest imported token total."},{label:"Most expensive run",session:F,value:F?`$${E(F).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:4})}`:"n/a",help:"The included session with the highest GitHub source usage, falling back to token estimate when source usage is absent."}],modelRows:se,trendRows:re,distribution:ce,outliers:pe}});setAnalyticsTimeRange(t){this.analyticsTimeRange.set(t)}setAnalyticsWorkspaceFilter(t){this.analyticsWorkspaceFilter.set(t)}setAnalyticsModelFilter(t){this.analyticsModelFilter.set(t)}setAnalyticsGrouping(t){this.analyticsGrouping.set(t)}resetAnalyticsFilters(){this.analyticsTimeRange.set("all"),this.analyticsWorkspaceFilter.set("all"),this.analyticsModelFilter.set("all"),this.analyticsGrouping.set("day")}emitOpenSession(t){t&&this.openSession.emit(t)}aiCredits(t){return t/L}usageUsd(t){return E(t)}usageCredits(t){return U(t)}static \u0275fac=function(e){return new(e||o)};static \u0275cmp=G({type:o,selectors:[["app-analytics-page"]],inputs:{sessions:"sessions"},outputs:{openSession:"openSession"},decls:1,vars:1,consts:[[1,"pricing-page","analytics-page"],[1,"pricing-header"],[1,"eyebrow"],[1,"analytics-cohort"],["label","Explain analytics scope",3,"text"],["type","button",1,"ghost-button"],["aria-label","Analytics cohort controls",1,"analytics-controls"],[3,"ngModelChange","ngModel"],[3,"value"],["label","Explain trend grouping",3,"text"],[1,"analytics-empty"],["type","button",1,"ghost-button",3,"click"],[1,"analytics-primary"],[1,"analytics-panel","model-panel"],[1,"panel-heading"],["role","table","aria-label","Model breakdown",1,"cost-table","compact-table"],[1,"cost-row","analytics-model-row","cost-row-heading"],[1,"cost-row","analytics-model-row"],[1,"empty"],[1,"analytics-side"],[1,"analytics-panel"],[1,"panel-heading","compact-heading"],[1,"stat-list","compact"],["type","button",3,"disabled"],[1,"analytics-split"],[1,"highlight-list"],["type","button"],[1,"warning-text"],[1,"share-cell"],["type","button",3,"click","disabled"],[1,"open-cue"],[1,"row-kicker"],[3,"text","label","interactive"],["type","button",3,"click"]],template:function(e,s){if(e&1&&u(0,De,40,11,"section",0),e&2){let r;x((r=s.analytics())?0:-1,r)}},dependencies:[X,K,Q,J,j,q,H,W],styles:[".analytics-page[_ngcontent-%COMP%]{display:grid;gap:10px}.pricing-header[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.pricing-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{margin:3px 0 0;color:var(--text-strong);font-size:21px;font-weight:760;letter-spacing:0}.pricing-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px;max-width:820px;margin:6px 0 0;color:var(--muted);font-size:12px;line-height:1.45}.analytics-cohort[_ngcontent-%COMP%]{opacity:.86}.ghost-button[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:9px;padding:7px 10px;color:var(--text);background:var(--surface-soft);font-size:13px;font-weight:720;cursor:pointer}.ghost-button[_ngcontent-%COMP%]:hover{border-color:var(--line-strong)}.analytics-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr));gap:7px;border:1px solid var(--line);border-radius:12px;padding:8px;background:linear-gradient(135deg,#0c9f830e,#6f5cff09),var(--surface);box-shadow:var(--shadow-soft, 0 12px 30px rgba(15, 23, 42, .08))}.analytics-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{display:grid;gap:5px;min-width:0;color:var(--muted);font-size:10px;font-weight:720}.analytics-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:4px}.analytics-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%], .analytics-controls[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{width:100%;min-height:30px;border:1px solid var(--line);border-radius:7px;padding:6px 9px;background:var(--surface-soft);color:var(--text);font:inherit;font-size:12px;font-weight:720}.analytics-empty[_ngcontent-%COMP%], .analytics-panel[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:12px;background:var(--surface);box-shadow:var(--shadow-soft, 0 12px 30px rgba(15, 23, 42, .08))}.analytics-empty[_ngcontent-%COMP%]{display:grid;gap:8px;justify-items:start;padding:18px}.analytics-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{max-width:720px;margin:0;color:var(--muted);font-size:12px}.analytics-primary[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr;gap:10px;align-items:start}.analytics-side[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.analytics-split[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:start}.analytics-panel[_ngcontent-%COMP%]{display:grid;gap:8px;min-width:0;padding:11px}.analytics-panel[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .analytics-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{margin:0;color:var(--text-strong);font-size:15px;font-weight:760}.panel-heading[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.compact-heading[_ngcontent-%COMP%]{align-items:baseline}.panel-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:3px 0 0;color:var(--muted);font-size:12px}.compact-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:0;text-align:right}.panel-note[_ngcontent-%COMP%]{margin:-3px 0 0;color:var(--muted);font-size:12px}.panel-heading[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{flex:0 0 auto;border:1px solid var(--line);border-radius:999px;padding:3px 7px;color:var(--muted);background:var(--surface-soft);font-size:11px;font-weight:720}.highlight-list[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%]{display:grid;gap:6px}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] div[_ngcontent-%COMP%]{display:grid;gap:5px;width:100%;min-width:0;border:1px solid var(--line);border-radius:9px;padding:8px 9px;background:var(--surface-soft);color:var(--text);text-align:left}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{cursor:pointer}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover, .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover{border-color:var(--line-strong)}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled, .stat-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled{cursor:default;opacity:.65}.highlight-list[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .highlight-list[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .empty[_ngcontent-%COMP%]{color:var(--muted);font-size:12px;font-style:normal;line-height:1.35}.stat-list[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row-kicker[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:5px}.highlight-list[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .stat-list[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .cost-row[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-strong);font-size:14px;font-weight:760;line-height:1.25}.open-cue[_ngcontent-%COMP%]{justify-self:start;border:1px solid var(--line);border-radius:999px;padding:3px 7px;background:#0c9f8314;color:var(--accent-strong, var(--accent))!important;font-size:10px!important;font-weight:760;text-transform:uppercase;letter-spacing:.04em}.highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover .open-cue[_ngcontent-%COMP%], .highlight-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:focus-visible .open-cue[_ngcontent-%COMP%]{border-color:color-mix(in srgb,var(--accent) 45%,var(--line));background:#0c9f8324}.stat-list.compact[_ngcontent-%COMP%] div[_ngcontent-%COMP%], .stat-list.compact[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{grid-template-columns:minmax(110px,.35fr) minmax(0,1fr) auto;gap:4px 10px;align-items:center;padding:8px 9px}.stat-list.compact[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .stat-list.compact[_ngcontent-%COMP%] .open-cue[_ngcontent-%COMP%]{grid-column:2 / -1}.cost-table[_ngcontent-%COMP%]{overflow-x:auto;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.cost-row[_ngcontent-%COMP%]{display:grid;align-items:start;gap:8px;min-width:650px;border-bottom:1px solid var(--line);padding:8px 10px}.cost-row[_ngcontent-%COMP%]:last-child{border-bottom:0}.cost-row-heading[_ngcontent-%COMP%]{color:var(--muted);background:var(--surface-soft);font-size:11px;font-weight:760;letter-spacing:.04em;text-transform:uppercase}.analytics-model-row[_ngcontent-%COMP%]{grid-template-columns:minmax(170px,1.25fr) minmax(62px,.36fr) minmax(180px,1fr) minmax(86px,.48fr) minmax(84px,.46fr) minmax(80px,.45fr)}.analytics-model-row[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{display:grid;gap:3px}.analytics-model-row[_ngcontent-%COMP%] em[_ngcontent-%COMP%]{display:block;margin-top:2px}.warning-text[_ngcontent-%COMP%]{color:var(--warning-text, #ffcf91)!important}.share-cell[_ngcontent-%COMP%]{display:grid;gap:5px}.share-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{display:block;width:0;max-width:100%;height:4px;border-radius:999px;background:linear-gradient(90deg,var(--accent),var(--accent-2))}@media(max-width:1200px){.analytics-side[_ngcontent-%COMP%], .analytics-split[_ngcontent-%COMP%]{grid-template-columns:1fr}}@media(max-width:960px){.analytics-primary[_ngcontent-%COMP%]{grid-template-columns:1fr}}@media(max-width:900px){.pricing-header[_ngcontent-%COMP%], .analytics-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr}}@media(max-width:600px){.analytics-panel[_ngcontent-%COMP%]{padding:11px}.cost-row[_ngcontent-%COMP%]{min-width:620px}}"]})};export{oe as AnalyticsPageComponent};
@@ -1 +1 @@
1
- import{p as M,q as p,r as d,s as h,w as U}from"./chunk-FXNLFSUB.js";import{a as D,b as T}from"./chunk-KDAJN6DF.js";function P(t,r,o,e){let n=O(t,r);return t.filter(s=>{let i=new Date(s.startedAt).getTime();return n.start!==null&&i<n.start||n.end!==null&&i>=n.end||o!=="all"&&s.workspace!==o?!1:e==="all"||s.modelBreakdown.some(u=>u.pricingModel===e||u.model===e)})}function V(t,r){let o=new Map;for(let e of t)for(let n of e.modelBreakdown){let s=`${n.model}::${n.pricingModel}`,i=o.get(s)??{model:n.model,pricingModel:n.pricingModel,turns:0,sessions:new Set,tokens:0,input:0,cachedInput:0,cacheWrite:0,output:0,cost:0};i.turns+=n.turns,i.sessions.add(e.id),i.tokens+=M(n.tokens),i.input+=n.tokens.input,i.cachedInput+=n.tokens.cachedInput,i.cacheWrite+=n.tokens.cacheWrite,i.output+=n.tokens.output,i.cost+=n.cost.usd,o.set(s,i)}return[...o.values()].map(e=>T(D({},e),{sessionCount:e.sessions.size,costPer1k:e.tokens?e.cost/e.tokens*1e3:0,share:r>0?e.cost/r*100:0,usesFallbackPrice:U(e.model,e.pricingModel)})).sort((e,n)=>n.cost-e.cost)}function B(t,r){let o=new Map;for(let e of t){let n=W(e.startedAt,r),s=o.get(n.key)??T(D({},n),{count:0,tokens:0,cost:0,credits:0,topSession:null,topSessionCost:0});s.count+=1,s.tokens+=p(e);let i=d(e);s.cost+=i,s.credits+=h(e),(!s.topSession||i>s.topSessionCost)&&(s.topSession=e,s.topSessionCost=i),o.set(n.key,s)}return[...o.values()].sort((e,n)=>n.key.localeCompare(e.key)).slice(0,8)}function G(t,r){return["Small","Medium","Large","Very large"].map(e=>{let n=t.filter(a=>v(p(a))===e),s=n.reduce((a,c)=>a+p(c),0),i=n.reduce((a,c)=>a+d(c),0),u=n.reduce((a,c)=>a+h(c),0),l=S(n,a=>d(a));return{size:e,count:n.length,tokens:s,cost:i,share:r>0?i/r*100:0,credits:u,topSession:l,topSessionCost:l?d(l):0}})}function E(t,r,o){if(!t.length)return[];let e=F(t.map(s=>d(s))),n=F(t.map(s=>p(s)));return t.map(s=>{let i=p(s),u=e>0?(d(s)-r)/e:0,l=n>0?(i-o)/n:0,a=Math.max(u,l),c=I(s,u,l);return{session:s,tokens:i,score:a,reason:c}}).filter(s=>s.score>=1||t.length<=5).sort((s,i)=>i.score-s.score||d(i.session)-d(s.session)).slice(0,5)}function H(t,r,o=new Date){let e=Number.isFinite(o.getTime())?o:new Date,n=S(t,L=>Date.parse(L.startedAt)||0),s=$(e),i=b(s,1),u=N(e),l=b(s,1),a=R(e),c=Y(e),m=w(t,s,i),g=w(t,u,l),k=w(t,a,c),x=n?z(n.startedAt):null;return[f("last-session","Last session",n?[n]:[],r,n?.title??"No imported sessions",x?y(x):"No imported sessions"),f("today","Today",m,r,"Imported sessions from today",y(s)),f("week","This week",g,r,"Week so far",A(u,b(l,-1))),f("month","Calendar month",k,r,"Current calendar month",A(a,b(c,-1))),f("visible","Selected scope",t,r,"Sessions matching Usage filters","All imported dates in this view")]}function O(t,r){if(r==="all"||!t.length)return{start:null,end:null,anchor:null};let o=Math.max(...t.map(s=>new Date(s.startedAt).getTime()).filter(Number.isFinite));if(!Number.isFinite(o))return{start:null,end:null,anchor:null};let e=new Date(o);if(r==="current-month"||r==="previous-month"){let s=r==="current-month"?0:-1,i=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+s,1)),u=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+s+1,1));return{start:i.getTime(),end:u.getTime(),anchor:e}}return{start:o-(r==="7d"?7:r==="30d"?30:90)*24*60*60*1e3,end:null,anchor:e}}function W(t,r){let o=new Date(t);if(!Number.isFinite(o.getTime()))return{key:"unknown",label:"Unknown date"};let e=C(o);if(r==="day")return{key:e,label:e};if(r==="month")return{key:e.slice(0,7),label:e.slice(0,7)};let n=new Date(Date.UTC(o.getUTCFullYear(),o.getUTCMonth(),o.getUTCDate())),s=n.getUTCDay()||7;return n.setUTCDate(n.getUTCDate()-s+1),{key:C(n),label:`Week of ${C(n)}`}}function v(t){return t>=15e5?"Very large":t>=5e5?"Large":t>=1e5?"Medium":"Small"}function S(t,r){return t.reduce((o,e)=>!o||r(e)>r(o)?e:o,null)}function I(t,r,o){let e=p(t),n=t.tokens.input+t.tokens.cachedInput+t.tokens.cacheWrite,s=e?n/e*100:0,i=S(t.modelBreakdown,k=>k.cost.usd),u=d(t),l=i&&u>0?i.cost.usd/u*100:0,a=t.traceSummary.modelTurns,c=t.traceSummary.toolCalls,m=a+c;return Math.max(r,o)>=2&&m<=3&&e>=1e5?`Suspicious spike: ${e.toLocaleString()} tokens with only ${m.toLocaleString()} imported model/tool events. Inspect the largest model call and source log shape.`:s>=85&&n>=1e5?`Mostly input/context tokens (${s.toFixed(0)}% of imported tokens). Check prompt context, repo reads, prior conversation, and tool results.`:i&&l>=70?`${i.pricingModel} produced ${l.toFixed(0)}% of this run's estimate. Model mix is the first thing to inspect.`:c>=20?`${c.toLocaleString()} tool calls may have added results back into later model input.`:t.traceSummary.errors===0&&a>=8&&c>=8?`Large but plausible long agent run: ${a.toLocaleString()} model turns and ${c.toLocaleString()} tool calls with no imported errors. Inspect input/context and tool activity before treating it as waste.`:r>=o?`Cost is ${r.toFixed(1)} standard deviations above this cohort. Check model price rows and output mix.`:`Tokens are ${o.toFixed(1)} standard deviations above this cohort. Check input context and model-turn count.`}function f(t,r,o,e,n,s){let i=o.reduce((m,g)=>m+h(g),0),u=o.reduce((m,g)=>m+d(g),0),l=S(o,m=>d(m)),a=o.filter(m=>!m.sourceUsage).length,c=e>0?i/e*100:0;return{id:t,label:r,period:s,credits:i,usd:u,count:o.length,allowanceShare:c,fallbackCount:a,session:l,detail:o.length?`${o.length.toLocaleString()} session${o.length===1?"":"s"}`:n,actionLabel:l?t==="last-session"?"Open run":"Open top run":"No run to open"}}function w(t,r,o){let e=r.getTime(),n=o.getTime();return t.filter(s=>{let i=Date.parse(s.startedAt);return Number.isFinite(i)&&i>=e&&i<n})}function $(t){return new Date(t.getFullYear(),t.getMonth(),t.getDate())}function N(t){let r=t.getDay()||7,o=$(t);return o.setDate(o.getDate()-r+1),o}function R(t){return new Date(t.getFullYear(),t.getMonth(),1)}function Y(t){return new Date(t.getFullYear(),t.getMonth()+1,1)}function b(t,r){let o=new Date(t);return o.setDate(o.getDate()+r),o}function z(t){let r=Date.parse(t);return Number.isFinite(r)?new Date(r):null}function y(t){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric"}).format(t)}function A(t,r){return t.getFullYear()===r.getFullYear()&&t.getMonth()===r.getMonth()?`${new Intl.DateTimeFormat("en-US",{month:"short"}).format(t)} ${t.getDate()}-${r.getDate()}, ${t.getFullYear()}`:`${y(t)} - ${y(r)}`}function F(t){if(t.length<2)return 0;let r=t.reduce((e,n)=>e+n,0)/t.length,o=t.reduce((e,n)=>e+(n-r)**2,0)/t.length;return Math.sqrt(o)}function C(t){return t.toISOString().slice(0,10)}export{P as a,V as b,B as c,G as d,E as e,H as f,S as g};
1
+ import{p as M,q as p,r as d,s as h,w as U}from"./chunk-TICIZRSM.js";import{a as D,b as T}from"./chunk-WOIYAEKB.js";function P(t,r,o,e){let n=O(t,r);return t.filter(s=>{let i=new Date(s.startedAt).getTime();return n.start!==null&&i<n.start||n.end!==null&&i>=n.end||o!=="all"&&s.workspace!==o?!1:e==="all"||s.modelBreakdown.some(u=>u.pricingModel===e||u.model===e)})}function V(t,r){let o=new Map;for(let e of t)for(let n of e.modelBreakdown){let s=`${n.model}::${n.pricingModel}`,i=o.get(s)??{model:n.model,pricingModel:n.pricingModel,turns:0,sessions:new Set,tokens:0,input:0,cachedInput:0,cacheWrite:0,output:0,cost:0};i.turns+=n.turns,i.sessions.add(e.id),i.tokens+=M(n.tokens),i.input+=n.tokens.input,i.cachedInput+=n.tokens.cachedInput,i.cacheWrite+=n.tokens.cacheWrite,i.output+=n.tokens.output,i.cost+=n.cost.usd,o.set(s,i)}return[...o.values()].map(e=>T(D({},e),{sessionCount:e.sessions.size,costPer1k:e.tokens?e.cost/e.tokens*1e3:0,share:r>0?e.cost/r*100:0,usesFallbackPrice:U(e.model,e.pricingModel)})).sort((e,n)=>n.cost-e.cost)}function B(t,r){let o=new Map;for(let e of t){let n=W(e.startedAt,r),s=o.get(n.key)??T(D({},n),{count:0,tokens:0,cost:0,credits:0,topSession:null,topSessionCost:0});s.count+=1,s.tokens+=p(e);let i=d(e);s.cost+=i,s.credits+=h(e),(!s.topSession||i>s.topSessionCost)&&(s.topSession=e,s.topSessionCost=i),o.set(n.key,s)}return[...o.values()].sort((e,n)=>n.key.localeCompare(e.key)).slice(0,8)}function G(t,r){return["Small","Medium","Large","Very large"].map(e=>{let n=t.filter(a=>v(p(a))===e),s=n.reduce((a,c)=>a+p(c),0),i=n.reduce((a,c)=>a+d(c),0),u=n.reduce((a,c)=>a+h(c),0),l=S(n,a=>d(a));return{size:e,count:n.length,tokens:s,cost:i,share:r>0?i/r*100:0,credits:u,topSession:l,topSessionCost:l?d(l):0}})}function E(t,r,o){if(!t.length)return[];let e=F(t.map(s=>d(s))),n=F(t.map(s=>p(s)));return t.map(s=>{let i=p(s),u=e>0?(d(s)-r)/e:0,l=n>0?(i-o)/n:0,a=Math.max(u,l),c=I(s,u,l);return{session:s,tokens:i,score:a,reason:c}}).filter(s=>s.score>=1||t.length<=5).sort((s,i)=>i.score-s.score||d(i.session)-d(s.session)).slice(0,5)}function H(t,r,o=new Date){let e=Number.isFinite(o.getTime())?o:new Date,n=S(t,L=>Date.parse(L.startedAt)||0),s=$(e),i=b(s,1),u=N(e),l=b(s,1),a=R(e),c=Y(e),m=w(t,s,i),g=w(t,u,l),k=w(t,a,c),x=n?z(n.startedAt):null;return[f("last-session","Last session",n?[n]:[],r,n?.title??"No imported sessions",x?y(x):"No imported sessions"),f("today","Today",m,r,"Imported sessions from today",y(s)),f("week","This week",g,r,"Week so far",A(u,b(l,-1))),f("month","Calendar month",k,r,"Current calendar month",A(a,b(c,-1))),f("visible","Selected scope",t,r,"Sessions matching Usage filters","All imported dates in this view")]}function O(t,r){if(r==="all"||!t.length)return{start:null,end:null,anchor:null};let o=Math.max(...t.map(s=>new Date(s.startedAt).getTime()).filter(Number.isFinite));if(!Number.isFinite(o))return{start:null,end:null,anchor:null};let e=new Date(o);if(r==="current-month"||r==="previous-month"){let s=r==="current-month"?0:-1,i=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+s,1)),u=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+s+1,1));return{start:i.getTime(),end:u.getTime(),anchor:e}}return{start:o-(r==="7d"?7:r==="30d"?30:90)*24*60*60*1e3,end:null,anchor:e}}function W(t,r){let o=new Date(t);if(!Number.isFinite(o.getTime()))return{key:"unknown",label:"Unknown date"};let e=C(o);if(r==="day")return{key:e,label:e};if(r==="month")return{key:e.slice(0,7),label:e.slice(0,7)};let n=new Date(Date.UTC(o.getUTCFullYear(),o.getUTCMonth(),o.getUTCDate())),s=n.getUTCDay()||7;return n.setUTCDate(n.getUTCDate()-s+1),{key:C(n),label:`Week of ${C(n)}`}}function v(t){return t>=15e5?"Very large":t>=5e5?"Large":t>=1e5?"Medium":"Small"}function S(t,r){return t.reduce((o,e)=>!o||r(e)>r(o)?e:o,null)}function I(t,r,o){let e=p(t),n=t.tokens.input+t.tokens.cachedInput+t.tokens.cacheWrite,s=e?n/e*100:0,i=S(t.modelBreakdown,k=>k.cost.usd),u=d(t),l=i&&u>0?i.cost.usd/u*100:0,a=t.traceSummary.modelTurns,c=t.traceSummary.toolCalls,m=a+c;return Math.max(r,o)>=2&&m<=3&&e>=1e5?`Suspicious spike: ${e.toLocaleString()} tokens with only ${m.toLocaleString()} imported model/tool events. Inspect the largest model call and source log shape.`:s>=85&&n>=1e5?`Mostly input/context tokens (${s.toFixed(0)}% of imported tokens). Check prompt context, repo reads, prior conversation, and tool results.`:i&&l>=70?`${i.pricingModel} produced ${l.toFixed(0)}% of this run's estimate. Model mix is the first thing to inspect.`:c>=20?`${c.toLocaleString()} tool calls may have added results back into later model input.`:t.traceSummary.errors===0&&a>=8&&c>=8?`Large but plausible long agent run: ${a.toLocaleString()} model turns and ${c.toLocaleString()} tool calls with no imported errors. Inspect input/context and tool activity before treating it as waste.`:r>=o?`Cost is ${r.toFixed(1)} standard deviations above this cohort. Check model price rows and output mix.`:`Tokens are ${o.toFixed(1)} standard deviations above this cohort. Check input context and model-turn count.`}function f(t,r,o,e,n,s){let i=o.reduce((m,g)=>m+h(g),0),u=o.reduce((m,g)=>m+d(g),0),l=S(o,m=>d(m)),a=o.filter(m=>!m.sourceUsage).length,c=e>0?i/e*100:0;return{id:t,label:r,period:s,credits:i,usd:u,count:o.length,allowanceShare:c,fallbackCount:a,session:l,detail:o.length?`${o.length.toLocaleString()} session${o.length===1?"":"s"}`:n,actionLabel:l?t==="last-session"?"Open run":"Open top run":"No run to open"}}function w(t,r,o){let e=r.getTime(),n=o.getTime();return t.filter(s=>{let i=Date.parse(s.startedAt);return Number.isFinite(i)&&i>=e&&i<n})}function $(t){return new Date(t.getFullYear(),t.getMonth(),t.getDate())}function N(t){let r=t.getDay()||7,o=$(t);return o.setDate(o.getDate()-r+1),o}function R(t){return new Date(t.getFullYear(),t.getMonth(),1)}function Y(t){return new Date(t.getFullYear(),t.getMonth()+1,1)}function b(t,r){let o=new Date(t);return o.setDate(o.getDate()+r),o}function z(t){let r=Date.parse(t);return Number.isFinite(r)?new Date(r):null}function y(t){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric"}).format(t)}function A(t,r){return t.getFullYear()===r.getFullYear()&&t.getMonth()===r.getMonth()?`${new Intl.DateTimeFormat("en-US",{month:"short"}).format(t)} ${t.getDate()}-${r.getDate()}, ${t.getFullYear()}`:`${y(t)} - ${y(r)}`}function F(t){if(t.length<2)return 0;let r=t.reduce((e,n)=>e+n,0)/t.length,o=t.reduce((e,n)=>e+(n-r)**2,0)/t.length;return Math.sqrt(o)}function C(t){return t.toISOString().slice(0,10)}export{P as a,V as b,B as c,G as d,E as e,H as f,S as g};
@@ -0,0 +1 @@
1
+ import{a as c,b as l}from"./chunk-WOIYAEKB.js";var u={version:"github-copilot-usage-pricing-2026-07-05",sourceUrl:"https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing",sourceLabel:"GitHub Docs: Models and pricing for GitHub Copilot",snapshotDate:"2026-07-05",importedAt:"2026-07-05",fallbackModel:"GPT-5.4",models:{"GPT-5 mini":{provider:"OpenAI",releaseStatus:"GA",category:"Lightweight",input:.25,cachedInput:.025,output:2},"GPT-5.3-Codex":{provider:"OpenAI",releaseStatus:"GA",category:"Powerful",input:1.75,cachedInput:.175,output:14},"GPT-5.4":{provider:"OpenAI",releaseStatus:"GA",category:"Versatile",input:2.5,cachedInput:.25,output:15,tierLabel:"Default",tierThresholdLabel:"Up to 272K input tokens",tiers:[{id:"long-context",label:"Long context",thresholdInputTokensExclusive:272e3,thresholdLabel:"Over 272K input tokens",input:5,cachedInput:.5,output:22.5}]},"GPT-5.4 mini":{provider:"OpenAI",releaseStatus:"GA",category:"Lightweight",input:.75,cachedInput:.075,output:4.5},"GPT-5.4 nano":{provider:"OpenAI",releaseStatus:"GA",category:"Lightweight",input:.2,cachedInput:.02,output:1.25},"GPT-5.5":{provider:"OpenAI",releaseStatus:"GA",category:"Powerful",input:5,cachedInput:.5,output:30,tierLabel:"Default",tierThresholdLabel:"Up to 272K input tokens",tiers:[{id:"long-context",label:"Long context",thresholdInputTokensExclusive:272e3,thresholdLabel:"Over 272K input tokens",input:10,cachedInput:1,output:45}]},"Claude Haiku 4.5":{provider:"Anthropic",releaseStatus:"GA",category:"Versatile",input:1,cachedInput:.1,cacheWrite:1.25,output:5},"Claude Sonnet 4":{provider:"Anthropic",releaseStatus:"GA",category:"Versatile",input:3,cachedInput:.3,cacheWrite:3.75,output:15},"Claude Sonnet 4.5":{provider:"Anthropic",releaseStatus:"GA",category:"Versatile",input:3,cachedInput:.3,cacheWrite:3.75,output:15},"Claude Sonnet 4.6":{provider:"Anthropic",releaseStatus:"GA",category:"Versatile",input:3,cachedInput:.3,cacheWrite:3.75,output:15},"Claude Opus 4.5":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:5,cachedInput:.5,cacheWrite:6.25,output:25},"Claude Opus 4.6":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:5,cachedInput:.5,cacheWrite:6.25,output:25},"Claude Opus 4.7":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:5,cachedInput:.5,cacheWrite:6.25,output:25},"Claude Opus 4.8":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:5,cachedInput:.5,cacheWrite:6.25,output:25},"Claude Sonnet 5":{provider:"Anthropic",releaseStatus:"GA",category:"Versatile",input:2,cachedInput:.2,cacheWrite:2.5,output:10,note:"GitHub documents this promotional pricing through August 31, 2026."},"Claude Opus 4.8 (fast mode)":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:10,cachedInput:1,cacheWrite:12.5,output:50,aliases:["Claude Opus 4.8 fast","claude-opus-4.8-fast"],note:"GitHub's table includes '(preview)' in the model label."},"Claude Fable 5":{provider:"Anthropic",releaseStatus:"GA",category:"Powerful",input:10,cachedInput:1,cacheWrite:12.5,output:50},"Gemini 2.5 Pro":{provider:"Google",releaseStatus:"GA",category:"Powerful",input:1.25,cachedInput:.125,output:10},"Gemini 3 Flash":{provider:"Google",releaseStatus:"Public preview",category:"Lightweight",input:.5,cachedInput:.05,output:3},"Gemini 3.1 Pro":{provider:"Google",releaseStatus:"Public preview",category:"Powerful",input:2,cachedInput:.2,output:12,tierLabel:"Default",tierThresholdLabel:"Up to 200K input tokens",tiers:[{id:"long-context",label:"Long context",thresholdInputTokensExclusive:2e5,thresholdLabel:"Over 200K input tokens",input:4,cachedInput:.4,output:18}]},"Gemini 3.5 Flash":{provider:"Google",releaseStatus:"GA",category:"Lightweight",input:1.5,cachedInput:.15,output:9},"Raptor mini":{provider:"Fine-tuned (GitHub)",releaseStatus:"GA",category:"Versatile",input:.25,cachedInput:.025,output:2},"MAI-Code-1-Flash":{provider:"Microsoft",releaseStatus:"GA",category:"Lightweight",input:.75,cachedInput:.075,output:4.5},"Kimi K2.7 Code":{provider:"Moonshot AI",releaseStatus:"GA",category:"Versatile",input:.95,cachedInput:.19,output:4}}};var v=u.version,U=u.sourceUrl,M=u.sourceLabel,_=u.snapshotDate,E=u.importedAt,A=u.fallbackModel,P=.01,O="https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises",a=u.models,y=[{id:"business-standard",label:"Copilot Business",shortLabel:"Business",creditsPerUserMonthly:1900,period:"Standard monthly allowance",note:"Included AI credits are pooled at the billing entity level."},{id:"enterprise-standard",label:"Copilot Enterprise",shortLabel:"Enterprise",creditsPerUserMonthly:3900,period:"Standard monthly allowance",note:"Included AI credits are pooled at the billing entity level."},{id:"business-promo",label:"Copilot Business promo",shortLabel:"Business promo",creditsPerUserMonthly:3e3,period:"Existing-customer promo, Jun 1-Sep 1 2026",note:"GitHub documents this temporary higher allowance for existing Business customers."},{id:"enterprise-promo",label:"Copilot Enterprise promo",shortLabel:"Enterprise promo",creditsPerUserMonthly:7e3,period:"Existing-customer promo, Jun 1-Sep 1 2026",note:"GitHub documents this temporary higher allowance for existing Enterprise customers."}];function p(e){return String(e??"").replace(/^copilot\//i,"").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}function g(e){let r=String(e??"").replace(/^copilot\//i,"").trim(),n=p(r),t=Object.keys(a),i=t.flatMap(o=>(a[o].aliases??[]).map(s=>({name:o,aliasKey:p(s)})));return t.find(o=>p(o)===n)??i.find(({aliasKey:o})=>o===n)?.name??t.find(o=>n.includes(p(o)))??i.find(({aliasKey:o})=>n.includes(o))?.name??(r||"Unknown model")}function x(e){let r=g(e);return a[r]?r:A}function S(e){return a[e||""]??a[A]}function k(e,r){let n=S(e),t=Math.max(0,r.input)+Math.max(0,r.cachedInput),i=[...n.tiers??[]].sort((o,s)=>s.thresholdInputTokensExclusive-o.thresholdInputTokensExclusive).find(o=>t>o.thresholdInputTokensExclusive);return i?l(c(c({},n),i),{tiers:n.tiers}):n}function d(e,r){let n=g(e);return(r||x(n))!==n||!a[n]}function G(e,r){let n=g(e),t=r||x(n);return d(n,t)?`${n||"Unknown model"} is a raw VS Code model id that does not have a GitHub pricing row in the local table. The estimate keeps that model label visible and uses ${t} pricing as an explicit assumption.`:"This model matched a GitHub price row directly."}function D(e,r){let n=e.pricingModel||e.model,t=k(n,e.tokens),i=e.costBreakdown?.inputUsd??h(e.tokens.input,t.input),o=e.costBreakdown?.cachedInputUsd??h(e.tokens.cachedInput,t.cachedInput),s=e.costBreakdown?.cacheWriteUsd??h(e.tokens.cacheWrite,t.cacheWrite??0),m=e.costBreakdown?.outputUsd??h(e.tokens.output,t.output),I=i+o+s+m,f=e.pricingTiers?.length?e.pricingTiers:[t.label??t.tierLabel??"Default"];return l(c({},e),{provider:t.provider,releaseStatus:t.releaseStatus,category:t.category,inputRate:t.input,cachedInputRate:t.cachedInput,cacheWriteRate:t.cacheWrite??0,outputRate:t.output,inputUsd:i,cachedInputUsd:o,cacheWriteUsd:s,outputUsd:m,totalUsd:I,share:r>0?I/r*100:0,usesFallbackPrice:d(e.model,n),pricingTierLabel:f.join(" + "),hasMixedPricingTiers:f.length>1})}function h(e,r){return e/1e6*r}function T(e){return e.input+e.cachedInput+e.cacheWrite+e.output}function H(e){return T(e.tokens)}function N(e){return b(e.sourceUsage?.usd)??e.cost.usd}function K(e){return b(e.sourceUsage?.credits)??e.cost.usd/P}function V(e){return e.sourceUsage?"GitHub usage":"Estimate fallback"}function z(e){return b(e.sourceUsage?.usd)}function j(e,r){return e===0?null:(r-e)/e*100}var J=d;function $(e,r){return e.size!==r.size?!0:[...e].some(n=>!r.has(n))}function b(e){return typeof e=="number"&&Number.isFinite(e)?e:null}export{v as a,U as b,M as c,_ as d,E as e,P as f,O as g,a as h,y as i,p as j,x as k,k as l,d as m,G as n,D as o,T as p,H as q,N as r,K as s,V as t,z as u,j as v,J as w,$ as x};