hermium 0.3.6 → 0.3.8

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 (41) hide show
  1. package/bin/hermium.mjs +66 -0
  2. package/dist/api.mjs +58 -27
  3. package/dist/public/assets/css/styles-6YpiHgz7.css +1 -0
  4. package/dist/public/assets/js/{ChatInputBlock-BYpIR_ls.js → ChatInputBlock-CjzfB3kg.js} +1 -1
  5. package/dist/{server/public/assets/js/MarkdownMessage-DL1aUod4.js → public/assets/js/MarkdownMessage-BvEwByae.js} +1 -1
  6. package/dist/{server/public/assets/js/chat._sessionId-YaowVhVf.js → public/assets/js/chat._sessionId-CHAIu0ue.js} +1 -1
  7. package/dist/public/assets/js/{chat.index-B64jjuMw.js → chat.index-B6cbfDDD.js} +1 -1
  8. package/dist/public/assets/js/{index-DnOJbmz0.js → index-CyG4dGLZ.js} +1 -1
  9. package/dist/public/assets/js/{index-DsMUdp1X.js → index-i-jDCacv.js} +22 -22
  10. package/dist/public/assets/js/{memory-B_Uy_WUi.js → memory-DNJsQEy1.js} +1 -1
  11. package/dist/public/assets/js/{settings-ZdgGJLcS.js → settings-CATsDWsM.js} +1 -1
  12. package/dist/public/assets/js/{skills-Bg3vZgl2.js → skills-vv2f_qsa.js} +1 -1
  13. package/dist/public/assets/js/usage-B1WUX7rU.js +1 -0
  14. package/dist/server/_ssr/{ChatInputBlock-BONgzml9.mjs → ChatInputBlock-CXWe3ifU.mjs} +1 -1
  15. package/dist/server/_ssr/{MarkdownMessage-y8GThg94.mjs → MarkdownMessage-oVY8VCm_.mjs} +1 -1
  16. package/dist/server/_ssr/{chat._sessionId-BSlHY8-3.mjs → chat._sessionId-D2hr9ls7.mjs} +4 -4
  17. package/dist/server/_ssr/{chat.index-DaPRZ2yS.mjs → chat.index-DBot9MtY.mjs} +1 -1
  18. package/dist/server/_ssr/{index-D-zP2Zbh.mjs → index-BK5D6j0H.mjs} +2 -2
  19. package/dist/server/_ssr/{index-B6Q_iKG1.mjs → index-DUbc2UZb.mjs} +2 -2
  20. package/dist/server/_ssr/{memory-CeEgICRt.mjs → memory-B0Mc8Ya3.mjs} +3 -3
  21. package/dist/server/_ssr/{router-BwJ9sLwD.mjs → router-8wMdk9c_.mjs} +34 -32
  22. package/dist/server/_ssr/{skills-BgBDh_7P.mjs → skills-DFrwiw0D.mjs} +3 -3
  23. package/dist/server/_ssr/{usage-BRFRmZxm.mjs → usage-CKlYz3IL.mjs} +41 -11
  24. package/dist/server/{_tanstack-start-manifest_v-C1EEhhb2.mjs → _tanstack-start-manifest_v-D6URtbys.mjs} +1 -1
  25. package/dist/server/index.mjs +104 -104
  26. package/dist/server/public/assets/css/styles-6YpiHgz7.css +1 -0
  27. package/dist/server/public/assets/js/{ChatInputBlock-BYpIR_ls.js → ChatInputBlock-CjzfB3kg.js} +1 -1
  28. package/dist/{public/assets/js/MarkdownMessage-DL1aUod4.js → server/public/assets/js/MarkdownMessage-BvEwByae.js} +1 -1
  29. package/dist/{public/assets/js/chat._sessionId-YaowVhVf.js → server/public/assets/js/chat._sessionId-CHAIu0ue.js} +1 -1
  30. package/dist/server/public/assets/js/{chat.index-B64jjuMw.js → chat.index-B6cbfDDD.js} +1 -1
  31. package/dist/server/public/assets/js/{index-DnOJbmz0.js → index-CyG4dGLZ.js} +1 -1
  32. package/dist/server/public/assets/js/{index-DsMUdp1X.js → index-i-jDCacv.js} +22 -22
  33. package/dist/server/public/assets/js/{memory-B_Uy_WUi.js → memory-DNJsQEy1.js} +1 -1
  34. package/dist/server/public/assets/js/{settings-ZdgGJLcS.js → settings-CATsDWsM.js} +1 -1
  35. package/dist/server/public/assets/js/{skills-Bg3vZgl2.js → skills-vv2f_qsa.js} +1 -1
  36. package/dist/server/public/assets/js/usage-B1WUX7rU.js +1 -0
  37. package/package.json +2 -2
  38. package/dist/public/assets/css/styles-YqYDZ89Q.css +0 -1
  39. package/dist/public/assets/js/usage-DXPIAwzR.js +0 -1
  40. package/dist/server/public/assets/css/styles-YqYDZ89Q.css +0 -1
  41. package/dist/server/public/assets/js/usage-DXPIAwzR.js +0 -1
@@ -1,3 +1,3 @@
1
- import{G as y,D as n,L as w,C as e,h as g,S as z,x as k,b as j,B as u,n as C,j as I,q as M,p as E}from"./index-DsMUdp1X.js";import{M as A}from"./MarkdownMessage-DL1aUod4.js";async function D(){return y("/api/hermes/memory")}async function L(s,o){await y("/api/hermes/memory",{method:"POST",body:JSON.stringify({section:s,content:o})})}const P={memory:{title:"My Notes",icon:e.jsx(E,{className:"size-4"}),empty:"No notes yet. Write down things you want the AI to remember.",placeholder:"Write anything you want the AI to remember about this conversation, context, or preferences..."},user:{title:"User Profile",icon:e.jsx(M,{className:"size-4"}),empty:"No user profile. Add details about yourself.",placeholder:"Describe yourself — your role, expertise, preferences, communication style..."},soul:{title:"Soul",icon:e.jsx(j,{className:"size-4"}),empty:"No soul defined. Set the AI's personality and behavior.",placeholder:"Define the AI's personality, tone, expertise, and how it should behave..."}};function R(s){if(!s)return"";try{return new Date(s).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}}function p({section:s,data:o,onSave:f}){const[l,i]=n.useState(!1),[c,m]=n.useState(""),[d,r]=n.useState(!1),a=P[s],t=o[s],x=o[`${s}_mtime`],N=!t.trim(),v=()=>{m(t),i(!0)},b=()=>{i(!1),m("")},S=async()=>{r(!0);try{await f(s,c),i(!1)}catch(h){console.error("Failed to save memory:",h)}finally{r(!1)}};return e.jsxs("div",{className:"flex flex-col border rounded-lg overflow-hidden h-full min-h-0",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-2.5 bg-muted/50 border-b shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-muted-foreground",children:a.icon}),e.jsx("span",{className:"text-sm font-medium",children:a.title}),x?e.jsx("span",{className:"text-[10px] text-muted-foreground/60 ml-1",children:R(x)}):null]}),l?e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(u,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:b,disabled:d,children:"Cancel"}),e.jsx(u,{size:"sm",className:"h-7 px-3 text-xs",onClick:S,disabled:d,children:d?e.jsx(g,{className:"size-3 animate-spin"}):"Save"})]}):e.jsxs(u,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:v,children:[e.jsx(I,{className:"size-3 mr-1"}),"Edit"]})]}),l?e.jsx("textarea",{value:c,onChange:h=>m(h.target.value),placeholder:a.placeholder,spellCheck:!1,className:"flex-1 min-h-0 w-full resize-none border-0 bg-transparent px-3 py-3 text-sm leading-relaxed outline-none focus-visible:ring-0 font-mono"}):e.jsx("div",{className:"flex-1 overflow-y-auto p-3 min-h-0",children:N?e.jsx("p",{className:"text-sm text-muted-foreground italic",children:a.empty}):e.jsx(A,{content:t.replace(/§/g,`
1
+ import{G as y,D as n,L as w,C as e,h as g,S as z,x as k,b as j,B as u,n as C,j as I,q as M,p as E}from"./index-i-jDCacv.js";import{M as A}from"./MarkdownMessage-BvEwByae.js";async function D(){return y("/api/hermes/memory")}async function L(s,o){await y("/api/hermes/memory",{method:"POST",body:JSON.stringify({section:s,content:o})})}const P={memory:{title:"My Notes",icon:e.jsx(E,{className:"size-4"}),empty:"No notes yet. Write down things you want the AI to remember.",placeholder:"Write anything you want the AI to remember about this conversation, context, or preferences..."},user:{title:"User Profile",icon:e.jsx(M,{className:"size-4"}),empty:"No user profile. Add details about yourself.",placeholder:"Describe yourself — your role, expertise, preferences, communication style..."},soul:{title:"Soul",icon:e.jsx(j,{className:"size-4"}),empty:"No soul defined. Set the AI's personality and behavior.",placeholder:"Define the AI's personality, tone, expertise, and how it should behave..."}};function R(s){if(!s)return"";try{return new Date(s).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}}function p({section:s,data:o,onSave:f}){const[l,i]=n.useState(!1),[c,m]=n.useState(""),[d,r]=n.useState(!1),a=P[s],t=o[s],x=o[`${s}_mtime`],N=!t.trim(),v=()=>{m(t),i(!0)},b=()=>{i(!1),m("")},S=async()=>{r(!0);try{await f(s,c),i(!1)}catch(h){console.error("Failed to save memory:",h)}finally{r(!1)}};return e.jsxs("div",{className:"flex flex-col border rounded-lg overflow-hidden h-full min-h-0",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-2.5 bg-muted/50 border-b shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-muted-foreground",children:a.icon}),e.jsx("span",{className:"text-sm font-medium",children:a.title}),x?e.jsx("span",{className:"text-[10px] text-muted-foreground/60 ml-1",children:R(x)}):null]}),l?e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(u,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:b,disabled:d,children:"Cancel"}),e.jsx(u,{size:"sm",className:"h-7 px-3 text-xs",onClick:S,disabled:d,children:d?e.jsx(g,{className:"size-3 animate-spin"}):"Save"})]}):e.jsxs(u,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:v,children:[e.jsx(I,{className:"size-3 mr-1"}),"Edit"]})]}),l?e.jsx("textarea",{value:c,onChange:h=>m(h.target.value),placeholder:a.placeholder,spellCheck:!1,className:"flex-1 min-h-0 w-full resize-none border-0 bg-transparent px-3 py-3 text-sm leading-relaxed outline-none focus-visible:ring-0 font-mono"}):e.jsx("div",{className:"flex-1 overflow-y-auto p-3 min-h-0",children:N?e.jsx("p",{className:"text-sm text-muted-foreground italic",children:a.empty}):e.jsx(A,{content:t.replace(/§/g,`
2
2
 
3
3
  `)})})]})}function T(){const[s,o]=n.useState(null),[f,l]=n.useState(!0),[i,c]=n.useState(!1),{state:m}=w(),d=m==="collapsed",r=n.useCallback(async()=>{try{const t=await D();o(t)}catch(t){console.error("Failed to load memory:",t)}},[]);n.useEffect(()=>{l(!0),r().finally(()=>l(!1))},[r]);const a=async(t,x)=>{await L(t,x),await r()};return f?e.jsx("div",{className:"flex flex-1 items-center justify-center",children:e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(g,{className:"size-4 animate-spin"}),"Loading memory…"]})}):s?e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("header",{className:"flex items-center justify-between border-b px-4 py-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[d&&e.jsx(z,{className:k("mr-1 -ml-1 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0")}),e.jsx(j,{className:"size-5 text-muted-foreground"}),e.jsx("h2",{className:"text-sm font-medium",children:"Memory"})]}),e.jsxs(u,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>{c(!0),r().finally(()=>c(!1))},disabled:i,children:[i?e.jsx(g,{className:"size-3 animate-spin"}):e.jsx(C,{className:"size-3"}),"Refresh"]})]}),e.jsx("div",{className:"flex-1 min-h-0 p-4 overflow-hidden",children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 h-full min-h-0",children:[e.jsx(p,{section:"memory",data:s,onSave:a}),e.jsx(p,{section:"user",data:s,onSave:a}),e.jsx(p,{section:"soul",data:s,onSave:a})]})})]}):e.jsx("div",{className:"flex flex-1 items-center justify-center",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:"Failed to load memory."})})}export{T as component};
@@ -1 +1 @@
1
- import{C as e}from"./index-DsMUdp1X.js";function t(){return e.jsxs("div",{className:"p-6",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:"Settings"}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:"Configure profiles, models, and preferences."})]})}export{t as component};
1
+ import{C as e}from"./index-i-jDCacv.js";function t(){return e.jsxs("div",{className:"p-6",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:"Settings"}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:"Configure profiles, models, and preferences."})]})}export{t as component};
@@ -1 +1 @@
1
- import{C as e,v as ee,w as se,x as m,L as te,R as ae,D as r,z as w,A as R,S as M,B as y,I as P,h as S,n as B,g as le,r as T,o as re,t as ie,e as E,d as q,l as ne,H as oe}from"./index-DsMUdp1X.js";import{M as H}from"./MarkdownMessage-DL1aUod4.js";function ce({className:d,size:x="default",...n}){return e.jsx(ee,{"data-slot":"switch","data-size":x,className:m("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",d),...n,children:e.jsx(se,{"data-slot":"switch-thumb",className:"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"})})}function K({source:d}){const x=d==="builtin"?"bg-muted-foreground":d==="hub"?"bg-blue-400":"bg-emerald-400";return e.jsx("span",{className:m("size-2 rounded-full shrink-0",x)})}function me(){const{state:d}=te(),x=d==="collapsed",n=ae.useLoaderData(),[g,z]=r.useState(!1),[o,O]=r.useState(""),[c,V]=r.useState("all"),[C,W]=r.useState(new Set),[j,G]=r.useState(!0),[l,v]=r.useState(null),[J,u]=r.useState(""),[L,N]=r.useState([]),[F,h]=r.useState(!1),[I,b]=r.useState(null),[Q,f]=r.useState(""),[,$]=r.useState(!1);r.useEffect(()=>{if(!l){u(""),N([]),b(null),f("");return}h(!0);const s=`${l.category}/${l.skill}/SKILL.md`;Promise.all([w(s),R(l.category,l.skill)]).then(([t,a])=>{u(t),N(a.filter(i=>!i.isDir))}).catch(t=>{u(`Failed to load skill: ${t.message}`)}).finally(()=>h(!1))},[l]);const A=r.useMemo(()=>{if(!n)return[];let s=n.categories;if(c!=="all"&&(s=s.map(t=>({...t,skills:t.skills.filter(a=>(a.source||"local")===c)})).filter(t=>t.skills.length>0)),o.trim()){const t=o.toLowerCase();s=s.map(a=>({...a,skills:a.skills.filter(i=>i.name.toLowerCase().includes(t)||i.description.toLowerCase().includes(t))})).filter(a=>a.skills.length>0||a.name.toLowerCase().includes(t))}return s},[n,c,o]),D=r.useMemo(()=>{if(!n)return[];let s=n.archived;if(c!=="all"&&(s=s.filter(t=>(t.source||"local")===c)),o.trim()){const t=o.toLowerCase();s=s.filter(a=>a.name.toLowerCase().includes(t)||a.description.toLowerCase().includes(t))}return s},[n,c,o]),U=s=>{W(t=>{const a=new Set(t);return a.has(s)?a.delete(s):a.add(s),a})},X=async(s,t,a)=>{try{await oe(t,a),setData(i=>i&&{...i,categories:i.categories.map(p=>p.name===s?{...p,skills:p.skills.map(k=>k.name===t?{...k,enabled:a}:k)}:p)})}catch(i){console.error("Toggle failed:",i)}},Y=async s=>{if(l){$(!0),b(s);try{const t=`${l.category}/${l.skill}/`,a=await w(`${t}${s}`);f(a)}catch(t){f(`Failed to load file: ${t.message}`)}finally{$(!1)}}},Z=()=>{b(null),f("")},_=[{label:"All",value:"all"},{label:"Builtin",value:"builtin"},{label:"Hub",value:"hub"},{label:"Local",value:"local"}];return l?e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("header",{className:"flex items-center justify-between border-b px-4 py-3 shrink-0 relative",children:[e.jsxs("div",{className:"flex items-center gap-2 z-10",children:[x&&e.jsx(M,{className:m("mr-1 -ml-1 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0")}),e.jsxs(y,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>v(null),children:[e.jsx(P,{className:"size-3.5 mr-1"}),"Back"]})]}),e.jsxs("div",{className:"absolute left-1/2 -translate-x-1/2 flex items-center gap-2 max-w-[50%]",children:[e.jsx("span",{className:"text-muted-foreground text-sm truncate",children:l.category}),e.jsx("span",{className:"text-muted-foreground shrink-0",children:"/"}),e.jsx("span",{className:"text-sm font-medium truncate",children:l.skill})]}),e.jsx("div",{className:"z-10",children:e.jsxs(y,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>{h(!0);const s=`${l.category}/${l.skill}/SKILL.md`;Promise.all([w(s),R(l.category,l.skill)]).then(([t,a])=>{u(t),N(a.filter(i=>!i.isDir))}).finally(()=>h(!1))},disabled:F,children:[F?e.jsx(S,{className:"size-3 animate-spin"}):e.jsx(B,{className:"size-3"}),"Refresh"]})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:e.jsx("div",{className:"max-w-3xl mx-auto flex flex-col gap-4",children:I?e.jsxs(e.Fragment,{children:[e.jsxs("button",{onClick:Z,className:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline w-fit",children:[e.jsx(P,{className:"size-3"}),"Back to ",l.skill]}),e.jsx("div",{className:"text-sm text-muted-foreground mb-1",children:I}),e.jsx(H,{content:Q})]}):e.jsxs(e.Fragment,{children:[e.jsx(H,{content:J}),L.length>0&&e.jsxs("div",{className:"border-t pt-4 mt-2",children:[e.jsx("div",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider mb-2",children:"Attached Files"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsxs("button",{onClick:()=>Y(s.path),className:"inline-flex items-center gap-1.5 rounded-md border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",children:[e.jsx(le,{className:"size-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"truncate max-w-[180px]",children:s.path})]},s.path))})]})]})})})]}):e.jsxs("div",{className:"flex h-full",children:[e.jsxs("div",{className:"w-80 border-r flex flex-col h-full shrink-0",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b px-3 py-3 shrink-0",children:[x&&e.jsx(M,{className:m("mr-1 -ml-1 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0")}),e.jsx(T,{className:"size-5 text-muted-foreground"}),e.jsx("h2",{className:"text-sm font-medium",children:"Skills"}),e.jsx(y,{variant:"ghost",size:"sm",className:"ml-auto h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>{z(!0),load().finally(()=>z(!1))},disabled:g,children:g?e.jsx(S,{className:"size-3 animate-spin"}):e.jsx(B,{className:"size-3"})})]}),e.jsxs("div",{className:"px-3 py-2 border-b flex flex-col gap-2 shrink-0",children:[e.jsxs("div",{className:"relative",children:[e.jsx(re,{className:"absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground"}),e.jsx(ie,{value:o,onChange:s=>O(s.target.value),placeholder:"Search skills...",className:"h-8 pl-7 text-xs"})]}),e.jsx("div",{className:"flex items-center gap-1",children:_.map(s=>e.jsx("button",{onClick:()=>V(s.value),className:m("px-2 py-0.5 text-[11px] rounded-sm transition-colors",c===s.value?"bg-primary text-primary-foreground font-medium":"text-muted-foreground hover:text-foreground hover:bg-muted"),children:s.label},s.value))})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(S,{className:"size-4 animate-spin text-muted-foreground"})}):!n||A.length===0?e.jsx("p",{className:"text-xs text-muted-foreground text-center py-8",children:o?"No skills match your search.":"No skills found."}):e.jsxs("div",{className:"flex flex-col gap-1",children:[A.map(s=>e.jsxs("div",{className:"flex flex-col",children:[e.jsxs("button",{onClick:()=>U(s.name),className:"flex items-center gap-1.5 px-2 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider rounded-md hover:bg-muted/50 transition-colors",children:[C.has(s.name)?e.jsx(E,{className:"size-3 shrink-0"}):e.jsx(q,{className:"size-3 shrink-0"}),e.jsx("span",{className:"truncate",children:s.name}),e.jsx("span",{className:"ml-auto text-[10px] bg-muted px-1.5 py-0.5 rounded-full",children:s.skills.length})]}),!C.has(s.name)&&e.jsx("div",{className:"flex flex-col",children:s.skills.map(t=>e.jsxs("div",{className:"group flex items-center gap-2 px-2 py-1.5 pl-7 rounded-md hover:bg-muted/50 cursor-pointer transition-colors",onClick:()=>v({category:s.name,skill:t.name}),children:[e.jsx(K,{source:t.source}),e.jsxs("div",{className:"flex flex-col min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-xs font-medium truncate",children:t.name}),t.modified&&e.jsx("span",{className:"text-[10px] text-amber-500",title:"Modified",children:"✎"}),t.pinned&&e.jsx(ne,{className:"size-3 text-amber-500 shrink-0"})]}),t.description&&e.jsx("span",{className:"text-[10px] text-muted-foreground truncate",children:t.description})]}),e.jsx(ce,{checked:t.enabled!==!1,onCheckedChange:a=>X(s.name,t.name,a),className:"scale-75 shrink-0",onClick:a=>a.stopPropagation()})]},t.name))})]},s.name)),(D.length>0||(n?.archived.length??0)>0)&&e.jsxs("div",{className:"flex flex-col mt-2 pt-2 border-t",children:[e.jsxs("button",{onClick:()=>G(!j),className:"flex items-center gap-1.5 px-2 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider rounded-md hover:bg-muted/50 transition-colors",children:[j?e.jsx(E,{className:"size-3 shrink-0"}):e.jsx(q,{className:"size-3 shrink-0"}),e.jsx("span",{children:"Archived"}),e.jsx("span",{className:"ml-auto text-[10px] bg-muted px-1.5 py-0.5 rounded-full",children:n?.archived.length??0})]}),!j&&D.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-2 py-1.5 pl-7 rounded-md hover:bg-muted/50 cursor-pointer transition-colors opacity-60",onClick:()=>v({category:".archive",skill:s.name}),children:[e.jsx(K,{source:s.source}),e.jsxs("div",{className:"flex flex-col min-w-0 flex-1",children:[e.jsx("span",{className:"text-xs font-medium truncate",children:s.name}),s.description&&e.jsx("span",{className:"text-[10px] text-muted-foreground truncate",children:s.description})]})]},s.name))]})]})})]}),e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center",children:e.jsxs("div",{className:"flex flex-col items-center gap-3 text-muted-foreground",children:[e.jsx(T,{className:"size-12 opacity-20"}),e.jsx("p",{className:"text-sm",children:"Select a skill to view its details"})]})})]})}export{me as component};
1
+ import{C as e,v as ee,w as se,x as m,L as te,R as ae,D as r,z as w,A as R,S as M,B as y,I as P,h as S,n as B,g as le,r as T,o as re,t as ie,e as E,d as q,l as ne,H as oe}from"./index-i-jDCacv.js";import{M as H}from"./MarkdownMessage-BvEwByae.js";function ce({className:d,size:x="default",...n}){return e.jsx(ee,{"data-slot":"switch","data-size":x,className:m("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",d),...n,children:e.jsx(se,{"data-slot":"switch-thumb",className:"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"})})}function K({source:d}){const x=d==="builtin"?"bg-muted-foreground":d==="hub"?"bg-blue-400":"bg-emerald-400";return e.jsx("span",{className:m("size-2 rounded-full shrink-0",x)})}function me(){const{state:d}=te(),x=d==="collapsed",n=ae.useLoaderData(),[g,z]=r.useState(!1),[o,O]=r.useState(""),[c,V]=r.useState("all"),[C,W]=r.useState(new Set),[j,G]=r.useState(!0),[l,v]=r.useState(null),[J,u]=r.useState(""),[L,N]=r.useState([]),[F,h]=r.useState(!1),[I,b]=r.useState(null),[Q,f]=r.useState(""),[,$]=r.useState(!1);r.useEffect(()=>{if(!l){u(""),N([]),b(null),f("");return}h(!0);const s=`${l.category}/${l.skill}/SKILL.md`;Promise.all([w(s),R(l.category,l.skill)]).then(([t,a])=>{u(t),N(a.filter(i=>!i.isDir))}).catch(t=>{u(`Failed to load skill: ${t.message}`)}).finally(()=>h(!1))},[l]);const A=r.useMemo(()=>{if(!n)return[];let s=n.categories;if(c!=="all"&&(s=s.map(t=>({...t,skills:t.skills.filter(a=>(a.source||"local")===c)})).filter(t=>t.skills.length>0)),o.trim()){const t=o.toLowerCase();s=s.map(a=>({...a,skills:a.skills.filter(i=>i.name.toLowerCase().includes(t)||i.description.toLowerCase().includes(t))})).filter(a=>a.skills.length>0||a.name.toLowerCase().includes(t))}return s},[n,c,o]),D=r.useMemo(()=>{if(!n)return[];let s=n.archived;if(c!=="all"&&(s=s.filter(t=>(t.source||"local")===c)),o.trim()){const t=o.toLowerCase();s=s.filter(a=>a.name.toLowerCase().includes(t)||a.description.toLowerCase().includes(t))}return s},[n,c,o]),U=s=>{W(t=>{const a=new Set(t);return a.has(s)?a.delete(s):a.add(s),a})},X=async(s,t,a)=>{try{await oe(t,a),setData(i=>i&&{...i,categories:i.categories.map(p=>p.name===s?{...p,skills:p.skills.map(k=>k.name===t?{...k,enabled:a}:k)}:p)})}catch(i){console.error("Toggle failed:",i)}},Y=async s=>{if(l){$(!0),b(s);try{const t=`${l.category}/${l.skill}/`,a=await w(`${t}${s}`);f(a)}catch(t){f(`Failed to load file: ${t.message}`)}finally{$(!1)}}},Z=()=>{b(null),f("")},_=[{label:"All",value:"all"},{label:"Builtin",value:"builtin"},{label:"Hub",value:"hub"},{label:"Local",value:"local"}];return l?e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("header",{className:"flex items-center justify-between border-b px-4 py-3 shrink-0 relative",children:[e.jsxs("div",{className:"flex items-center gap-2 z-10",children:[x&&e.jsx(M,{className:m("mr-1 -ml-1 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0")}),e.jsxs(y,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>v(null),children:[e.jsx(P,{className:"size-3.5 mr-1"}),"Back"]})]}),e.jsxs("div",{className:"absolute left-1/2 -translate-x-1/2 flex items-center gap-2 max-w-[50%]",children:[e.jsx("span",{className:"text-muted-foreground text-sm truncate",children:l.category}),e.jsx("span",{className:"text-muted-foreground shrink-0",children:"/"}),e.jsx("span",{className:"text-sm font-medium truncate",children:l.skill})]}),e.jsx("div",{className:"z-10",children:e.jsxs(y,{variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>{h(!0);const s=`${l.category}/${l.skill}/SKILL.md`;Promise.all([w(s),R(l.category,l.skill)]).then(([t,a])=>{u(t),N(a.filter(i=>!i.isDir))}).finally(()=>h(!1))},disabled:F,children:[F?e.jsx(S,{className:"size-3 animate-spin"}):e.jsx(B,{className:"size-3"}),"Refresh"]})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:e.jsx("div",{className:"max-w-3xl mx-auto flex flex-col gap-4",children:I?e.jsxs(e.Fragment,{children:[e.jsxs("button",{onClick:Z,className:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline w-fit",children:[e.jsx(P,{className:"size-3"}),"Back to ",l.skill]}),e.jsx("div",{className:"text-sm text-muted-foreground mb-1",children:I}),e.jsx(H,{content:Q})]}):e.jsxs(e.Fragment,{children:[e.jsx(H,{content:J}),L.length>0&&e.jsxs("div",{className:"border-t pt-4 mt-2",children:[e.jsx("div",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider mb-2",children:"Attached Files"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsxs("button",{onClick:()=>Y(s.path),className:"inline-flex items-center gap-1.5 rounded-md border bg-muted/50 px-2.5 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",children:[e.jsx(le,{className:"size-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"truncate max-w-[180px]",children:s.path})]},s.path))})]})]})})})]}):e.jsxs("div",{className:"flex h-full",children:[e.jsxs("div",{className:"w-80 border-r flex flex-col h-full shrink-0",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b px-3 py-3 shrink-0",children:[x&&e.jsx(M,{className:m("mr-1 -ml-1 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0")}),e.jsx(T,{className:"size-5 text-muted-foreground"}),e.jsx("h2",{className:"text-sm font-medium",children:"Skills"}),e.jsx(y,{variant:"ghost",size:"sm",className:"ml-auto h-7 px-2 text-xs text-muted-foreground hover:text-foreground",onClick:()=>{z(!0),load().finally(()=>z(!1))},disabled:g,children:g?e.jsx(S,{className:"size-3 animate-spin"}):e.jsx(B,{className:"size-3"})})]}),e.jsxs("div",{className:"px-3 py-2 border-b flex flex-col gap-2 shrink-0",children:[e.jsxs("div",{className:"relative",children:[e.jsx(re,{className:"absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground"}),e.jsx(ie,{value:o,onChange:s=>O(s.target.value),placeholder:"Search skills...",className:"h-8 pl-7 text-xs"})]}),e.jsx("div",{className:"flex items-center gap-1",children:_.map(s=>e.jsx("button",{onClick:()=>V(s.value),className:m("px-2 py-0.5 text-[11px] rounded-sm transition-colors",c===s.value?"bg-primary text-primary-foreground font-medium":"text-muted-foreground hover:text-foreground hover:bg-muted"),children:s.label},s.value))})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(S,{className:"size-4 animate-spin text-muted-foreground"})}):!n||A.length===0?e.jsx("p",{className:"text-xs text-muted-foreground text-center py-8",children:o?"No skills match your search.":"No skills found."}):e.jsxs("div",{className:"flex flex-col gap-1",children:[A.map(s=>e.jsxs("div",{className:"flex flex-col",children:[e.jsxs("button",{onClick:()=>U(s.name),className:"flex items-center gap-1.5 px-2 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider rounded-md hover:bg-muted/50 transition-colors",children:[C.has(s.name)?e.jsx(E,{className:"size-3 shrink-0"}):e.jsx(q,{className:"size-3 shrink-0"}),e.jsx("span",{className:"truncate",children:s.name}),e.jsx("span",{className:"ml-auto text-[10px] bg-muted px-1.5 py-0.5 rounded-full",children:s.skills.length})]}),!C.has(s.name)&&e.jsx("div",{className:"flex flex-col",children:s.skills.map(t=>e.jsxs("div",{className:"group flex items-center gap-2 px-2 py-1.5 pl-7 rounded-md hover:bg-muted/50 cursor-pointer transition-colors",onClick:()=>v({category:s.name,skill:t.name}),children:[e.jsx(K,{source:t.source}),e.jsxs("div",{className:"flex flex-col min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-xs font-medium truncate",children:t.name}),t.modified&&e.jsx("span",{className:"text-[10px] text-amber-500",title:"Modified",children:"✎"}),t.pinned&&e.jsx(ne,{className:"size-3 text-amber-500 shrink-0"})]}),t.description&&e.jsx("span",{className:"text-[10px] text-muted-foreground truncate",children:t.description})]}),e.jsx(ce,{checked:t.enabled!==!1,onCheckedChange:a=>X(s.name,t.name,a),className:"scale-75 shrink-0",onClick:a=>a.stopPropagation()})]},t.name))})]},s.name)),(D.length>0||(n?.archived.length??0)>0)&&e.jsxs("div",{className:"flex flex-col mt-2 pt-2 border-t",children:[e.jsxs("button",{onClick:()=>G(!j),className:"flex items-center gap-1.5 px-2 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider rounded-md hover:bg-muted/50 transition-colors",children:[j?e.jsx(E,{className:"size-3 shrink-0"}):e.jsx(q,{className:"size-3 shrink-0"}),e.jsx("span",{children:"Archived"}),e.jsx("span",{className:"ml-auto text-[10px] bg-muted px-1.5 py-0.5 rounded-full",children:n?.archived.length??0})]}),!j&&D.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-2 py-1.5 pl-7 rounded-md hover:bg-muted/50 cursor-pointer transition-colors opacity-60",onClick:()=>v({category:".archive",skill:s.name}),children:[e.jsx(K,{source:s.source}),e.jsxs("div",{className:"flex flex-col min-w-0 flex-1",children:[e.jsx("span",{className:"text-xs font-medium truncate",children:s.name}),s.description&&e.jsx("span",{className:"text-[10px] text-muted-foreground truncate",children:s.description})]})]},s.name))]})]})})]}),e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center",children:e.jsxs("div",{className:"flex flex-col items-center gap-3 text-muted-foreground",children:[e.jsx(T,{className:"size-12 opacity-20"}),e.jsx("p",{className:"text-sm",children:"Select a skill to view its details"})]})})]})}export{me as component};
@@ -0,0 +1 @@
1
+ import{G as b,D as i,C as e}from"./index-i-jDCacv.js";async function k(t=30){const a=new URLSearchParams({days:String(t)});return b(`/api/hermes/usage/stats?${a}`)}const x=["#4fd1c5","#63b3ed","#f6ad55","#b794f4","#68d391","#fc8181","#f687b3","#90cdf4","#fbd38d","#9ae6b4"];function m(t){return(t||"").trim()||"unknown"}function N(t){const a=m(t);let n=0;for(let s=0;s<a.length;s++)n=(n<<5)-n+a.charCodeAt(s),n|=0;return x[Math.abs(n)%x.length]}function r(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}function u(t){return t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}function c(t,a){return a<=0?0:t/a*100}function h(t,a){const n=t+a;return n===0?"--":(a/n*100).toFixed(1)+"%"}const p=[{label:"Today",days:1},{label:"7 Days",days:7},{label:"30 Days",days:30},{label:"All Time",days:0}];function v(t=30){const[a,n]=i.useState(null),[s,l]=i.useState(!1);return i.useEffect(()=>{l(!0),k(t).then(n).catch(console.error).finally(()=>l(!1))},[t]),{stats:a,loading:s}}function d({label:t,value:a,sub:n}){return e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:t}),e.jsx("div",{className:"text-xl font-semibold",children:a}),n&&e.jsx("div",{className:"text-[11px] text-muted-foreground mt-1",children:n})]})}function _({stats:t}){const a=t.total_input_tokens+t.total_output_tokens,n=a+t.total_cache_read_tokens,s=t.total_cache_read_tokens,l=t.total_input_tokens+s>0?(s/(t.total_input_tokens+s)*100).toFixed(1)+"%":"--",o=t.daily_usage.filter(j=>j.sessions>0).length,f=o>0?(t.total_sessions/o).toFixed(1):"0.0",g=[`${r(t.total_input_tokens)} input`,`${r(t.total_output_tokens)} output`,s>0&&`${r(s)} cache`].filter(Boolean).join(" / ");return e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-3 mb-5",children:[e.jsx(d,{label:"Total Tokens",value:r(n),sub:g}),e.jsx(d,{label:"Total Sessions",value:String(t.total_sessions),sub:`${f} avg/day`}),e.jsx(d,{label:"Estimated Cost",value:u(t.total_cost??0),sub:`${r(a)} billed`}),e.jsx(d,{label:"Cache Hit Rate",value:l,sub:s>0?`${r(s)} tokens`:void 0})]})}function y({stats:t}){const a=i.useMemo(()=>(t.daily_usage??[]).map(s=>{const l=s.input_tokens+s.output_tokens+s.cache_read_tokens;return{...s,visualTokens:l,inputPercent:c(s.input_tokens,l),outputPercent:c(s.output_tokens,l),cachePercent:c(s.cache_read_tokens,l)}}),[t]),n=i.useMemo(()=>Math.max(...a.map(s=>s.visualTokens),1),[a]);return a.length===0?null:e.jsxs("div",{className:"rounded-lg border bg-card p-4 mb-5",children:[e.jsx("h3",{className:"text-sm font-semibold text-secondary-foreground mb-3",children:"Daily Trend"}),e.jsx("div",{className:"flex gap-0.5 mb-2",children:a.map(s=>e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col items-center relative group",children:[e.jsx("div",{className:"w-full h-36 bg-muted/40 rounded-t-sm flex items-end overflow-hidden",children:e.jsxs("div",{className:"w-full flex flex-col-reverse justify-start transition-all",style:{height:`${s.visualTokens/n*100}%`},children:[s.output_tokens>0&&e.jsx("div",{className:"w-full bg-emerald-500/80",style:{height:`${s.outputPercent}%`}}),s.input_tokens>0&&e.jsx("div",{className:"w-full bg-indigo-500/80",style:{height:`${s.inputPercent}%`}}),s.cache_read_tokens>0&&e.jsx("div",{className:"w-full bg-amber-400/80",style:{height:`${s.cachePercent}%`}})]})}),e.jsxs("div",{className:"hidden group-hover:block absolute bottom-[calc(100%+8px)] left-1/2 -translate-x-1/2 bg-popover text-popover-foreground text-[11px] whitespace-nowrap z-10 rounded-md border px-2 py-1.5 shadow-md",children:[e.jsx("div",{className:"font-semibold mb-0.5",children:s.date}),e.jsxs("div",{children:["Input: ",r(s.input_tokens)]}),e.jsxs("div",{children:["Output: ",r(s.output_tokens)]}),e.jsxs("div",{children:["Cache read: ",r(s.cache_read_tokens)]}),e.jsxs("div",{children:["Cache write: ",r(s.cache_write_tokens)]}),e.jsxs("div",{children:["Hit rate: ",h(s.input_tokens,s.cache_read_tokens)]}),e.jsxs("div",{children:["Sessions: ",s.sessions]}),e.jsxs("div",{children:["Cost: ",u(s.cost??0)]})]})]},s.date))}),e.jsxs("div",{className:"flex justify-between text-[10px] text-muted-foreground mb-3",children:[e.jsx("span",{children:a[0]?.date.slice(5)}),e.jsx("span",{children:a[a.length-1]?.date.slice(5)})]}),e.jsxs("div",{className:"flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground mb-4",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-indigo-500/80"})," Input"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-emerald-500/80"})," Output"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-amber-400/80"})," Cache read"]})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-[11px] border-collapse",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-muted-foreground text-left",children:[e.jsx("th",{className:"pb-1.5 pr-2 font-medium",children:"Date"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Input"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Output"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Cache read"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Cache write"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Hit rate"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Sessions"}),e.jsx("th",{className:"pb-1.5 pr-2 font-medium text-right",children:"Cost"})]})}),e.jsx("tbody",{children:[...a].reverse().map(s=>e.jsxs("tr",{className:"border-t",children:[e.jsx("td",{className:"py-1.5 pr-2",children:s.date}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:r(s.input_tokens)}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:r(s.output_tokens)}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:r(s.cache_read_tokens)}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:r(s.cache_write_tokens)}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:h(s.input_tokens,s.cache_read_tokens)}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:s.sessions}),e.jsx("td",{className:"py-1.5 pr-2 text-right",children:u(s.cost??0)})]},s.date))})]})})]})}function w({stats:t}){const a=i.useMemo(()=>(t.model_usage??[]).map(s=>{const l=s.input_tokens+s.output_tokens,o=l+s.cache_read_tokens;return{model:m(s.model),inputTokens:s.input_tokens,outputTokens:s.output_tokens,cacheTokens:s.cache_read_tokens,cacheWriteTokens:s.cache_write_tokens,totalTokens:l,visualTokens:o,sessions:s.sessions,color:N(s.model),inputPercent:c(s.input_tokens,o),outputPercent:c(s.output_tokens,o),cachePercent:c(s.cache_read_tokens,o)}}).sort((s,l)=>l.visualTokens-s.visualTokens),[t]),n=i.useMemo(()=>Math.max(...a.map(s=>s.visualTokens),1),[a]);return a.length===0?null:e.jsxs("div",{className:"rounded-lg border bg-card p-4 mb-5",children:[e.jsx("h3",{className:"text-sm font-semibold text-secondary-foreground mb-3",children:"Model Breakdown"}),e.jsxs("div",{className:"flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground mb-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-indigo-500/80"})," Input"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-emerald-500/80"})," Output"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm bg-amber-400/80"})," Cache read"]})]}),e.jsx("div",{className:"flex flex-col gap-2",children:a.map(s=>e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm shrink-0",style:{background:s.color}}),e.jsx("span",{className:"text-xs font-mono text-secondary-foreground w-32 shrink-0 truncate",title:s.model,children:s.model}),e.jsx("div",{className:"flex-1 h-4 bg-muted/40 rounded-sm overflow-hidden",children:e.jsxs("div",{className:"h-full flex min-w-[2px] transition-all",style:{width:`${s.visualTokens/n*100}%`},children:[s.inputTokens>0&&e.jsx("div",{className:"h-full bg-indigo-500/80",style:{width:`${s.inputPercent}%`}}),s.outputTokens>0&&e.jsx("div",{className:"h-full bg-emerald-500/80",style:{width:`${s.outputPercent}%`}}),s.cacheTokens>0&&e.jsx("div",{className:"h-full bg-amber-400/80",style:{width:`${s.cachePercent}%`}})]})}),e.jsxs("span",{className:"text-xs text-muted-foreground w-20 text-right shrink-0",children:[r(s.totalTokens),s.cacheTokens>0&&e.jsxs("span",{className:"text-[10px] text-amber-500 ml-1",children:["+",r(s.cacheTokens)]})]})]},s.model))})]})}function T({active:t,onChange:a}){return e.jsx("div",{className:"inline-flex rounded-lg border bg-muted/40 p-0.5",children:p.map(n=>e.jsx("button",{onClick:()=>a(n.days),className:"px-3 py-1 text-xs font-medium rounded-md transition-colors "+(t===n.days?"bg-card text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),children:n.label},n.label))})}function $(){const[t,a]=i.useState(30),{stats:n,loading:s}=v(t),l=p.find(o=>o.days===t)?.label??"Custom";return e.jsx("div",{className:"flex-1 overflow-y-auto p-4 md:p-6",children:e.jsxs("div",{className:"mx-auto max-w-5xl",children:[e.jsxs("header",{className:"mb-5 flex items-center justify-between flex-wrap gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-lg font-semibold",children:"Usage"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Token consumption and cost estimates",t>0?` over the last ${l.toLowerCase()}`:" (all time)","."]})]}),e.jsx(T,{active:t,onChange:a})]}),s&&e.jsx("div",{className:"text-sm text-muted-foreground py-8",children:"Loading usage stats…"}),!s&&!n&&e.jsx("div",{className:"text-sm text-muted-foreground py-8",children:"Failed to load usage data."}),!s&&n&&n.total_sessions===0&&e.jsx("div",{className:"text-sm text-muted-foreground py-8",children:"No usage data for this period."}),!s&&n&&n.total_sessions>0&&e.jsxs(e.Fragment,{children:[e.jsx(_,{stats:n}),e.jsx(w,{stats:n}),e.jsx(y,{stats:n})]})]})})}export{$ as component};
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useChatStore, B as Button, c as cn } from "./router-BwJ9sLwD.mjs";
2
+ import { u as useChatStore, B as Button, c as cn } from "./router-8wMdk9c_.mjs";
3
3
  import { k as IconFile, C as IconX, o as IconPaperclip, q as IconPhotoScan, t as IconPlayerStop, a as IconArrowUp } from "../_libs/tabler__icons-react.mjs";
4
4
  function Textarea({ className, ...props }) {
5
5
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -1,5 +1,5 @@
1
1
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import "./index-D-zP2Zbh.mjs";
2
+ import "./index-BK5D6j0H.mjs";
3
3
  import { M as Markdown } from "../_libs/react-markdown.mjs";
4
4
  import { r as rehypeHighlight } from "../_libs/rehype-highlight.mjs";
5
5
  import { r as remarkGfm } from "../_libs/remark-gfm.mjs";
@@ -1,8 +1,8 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { a as Route, u as useChatStore, g as useSidebar, S as SidebarTrigger, c as cn } from "./router-BwJ9sLwD.mjs";
3
- import { M as MarkdownMessage } from "./MarkdownMessage-y8GThg94.mjs";
4
- import { C as ChatInputBlock } from "./ChatInputBlock-BONgzml9.mjs";
5
- import "./index-D-zP2Zbh.mjs";
2
+ import { a as Route, u as useChatStore, g as useSidebar, S as SidebarTrigger, c as cn } from "./router-8wMdk9c_.mjs";
3
+ import { M as MarkdownMessage } from "./MarkdownMessage-oVY8VCm_.mjs";
4
+ import { C as ChatInputBlock } from "./ChatInputBlock-CXWe3ifU.mjs";
5
+ import "./index-BK5D6j0H.mjs";
6
6
  import { k as IconFile, f as IconChevronRight, m as IconLoader2, d as IconCheck, i as IconCopy } from "../_libs/tabler__icons-react.mjs";
7
7
  import "../_libs/tanstack__react-router.mjs";
8
8
  import "../_libs/tanstack__router-core.mjs";
@@ -1,6 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
2
  import { d as useNavigate } from "../_libs/tanstack__react-router.mjs";
3
- import { u as useChatStore, b as createSession } from "./router-BwJ9sLwD.mjs";
3
+ import { u as useChatStore, b as createSession } from "./router-8wMdk9c_.mjs";
4
4
  import "../_libs/tanstack__router-core.mjs";
5
5
  import "../_libs/tanstack__history.mjs";
6
6
  import "node:stream/web";
@@ -3096,7 +3096,7 @@ const defaultSerovalPlugins = [
3096
3096
  p
3097
3097
  ];
3098
3098
  async function getStartManifest(matchedRoutes) {
3099
- const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-C1EEhhb2.mjs");
3099
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-D6URtbys.mjs");
3100
3100
  const startManifest = tsrStartManifest();
3101
3101
  const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
3102
3102
  rootRoute.assets = rootRoute.assets || [];
@@ -4575,7 +4575,7 @@ var getBaseManifest = getProdBaseManifest;
4575
4575
  var createEarlyHintsForRequest = createEarlyHintsCollector;
4576
4576
  async function loadEntries() {
4577
4577
  const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
4578
- import("./router-BwJ9sLwD.mjs").then((n2) => n2.e),
4578
+ import("./router-8wMdk9c_.mjs").then((n2) => n2.e),
4579
4579
  Promise.resolve().then(() => start),
4580
4580
  import("../__23tanstack-start-plugin-adapters-Cwee5PKy.mjs")
4581
4581
  ]);
@@ -1,7 +1,7 @@
1
1
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
2
2
  import { d as useNavigate } from "../_libs/tanstack__react-router.mjs";
3
- import { C as ChatInputBlock } from "./ChatInputBlock-BONgzml9.mjs";
4
- import "./router-BwJ9sLwD.mjs";
3
+ import { C as ChatInputBlock } from "./ChatInputBlock-CXWe3ifU.mjs";
4
+ import "./router-8wMdk9c_.mjs";
5
5
  import "../_libs/tanstack__router-core.mjs";
6
6
  import "../_libs/tanstack__history.mjs";
7
7
  import "node:stream/web";
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { g as useSidebar, S as SidebarTrigger, c as cn, B as Button, r as request } from "./router-BwJ9sLwD.mjs";
3
- import { M as MarkdownMessage } from "./MarkdownMessage-y8GThg94.mjs";
4
- import "./index-D-zP2Zbh.mjs";
2
+ import { g as useSidebar, S as SidebarTrigger, c as cn, B as Button, r as request } from "./router-8wMdk9c_.mjs";
3
+ import { M as MarkdownMessage } from "./MarkdownMessage-oVY8VCm_.mjs";
4
+ import "./index-BK5D6j0H.mjs";
5
5
  import { m as IconLoader2, b as IconBrain, u as IconRefresh, p as IconPencil, A as IconUser, x as IconSparkles } from "../_libs/tabler__icons-react.mjs";
6
6
  import "../_libs/tanstack__react-router.mjs";
7
7
  import "../_libs/tanstack__router-core.mjs";
@@ -1145,33 +1145,35 @@ const useChatStore = create((set, get) => ({
1145
1145
  }
1146
1146
  },
1147
1147
  updateSessionTitle(sessionId) {
1148
- set((s) => {
1149
- const session = s.sessions.find((sess) => sess.id === sessionId);
1150
- const hasRealTitle = !!session?.title && session.title !== "New Session";
1151
- if (!session || hasRealTitle) return s;
1152
- const firstUser = s.messages.find((m) => m.role === "user");
1153
- if (!firstUser) return s;
1154
- const raw = firstUser.content.trim();
1155
- let title = raw;
1156
- if (raw.length > 40) {
1157
- const sentenceMatch = raw.slice(0, 60).match(/^[^.!?]+[.!?]/);
1158
- if (sentenceMatch) {
1159
- title = sentenceMatch[0].trim();
1160
- } else {
1161
- const slice = raw.slice(0, 40);
1162
- const lastSpace = slice.lastIndexOf(" ");
1163
- title = lastSpace > 20 ? slice.slice(0, lastSpace) : slice;
1164
- }
1148
+ const state = get();
1149
+ const session = state.sessions.find((sess) => sess.id === sessionId);
1150
+ const hasRealTitle = !!session?.title && session.title !== "New Session";
1151
+ if (!session || hasRealTitle) return;
1152
+ const firstUser = state.messages.find((m) => m.role === "user");
1153
+ if (!firstUser) return;
1154
+ const raw = firstUser.content.trim();
1155
+ let title = raw;
1156
+ if (raw.length > 40) {
1157
+ const sentenceMatch = raw.slice(0, 60).match(/^[^.!?]+[.!?]/);
1158
+ if (sentenceMatch) {
1159
+ title = sentenceMatch[0].trim();
1160
+ } else {
1161
+ const slice = raw.slice(0, 40);
1162
+ const lastSpace = slice.lastIndexOf(" ");
1163
+ title = lastSpace > 20 ? slice.slice(0, lastSpace) : slice;
1165
1164
  }
1166
- title = title.replace(/[,:;\-]+$/, "").trim();
1167
- if (title.length < raw.length) title += "";
1168
- title = title.charAt(0).toUpperCase() + title.slice(1);
1169
- return {
1170
- sessions: s.sessions.map(
1171
- (sess) => sess.id === sessionId ? { ...sess, title, updatedAt: Date.now() } : sess
1172
- )
1173
- };
1165
+ }
1166
+ title = title.replace(/[,:;\-]+$/, "").trim();
1167
+ if (title.length < raw.length) title += "…";
1168
+ title = title.charAt(0).toUpperCase() + title.slice(1);
1169
+ renameSession(sessionId, title).catch((err) => {
1170
+ console.error("[store] Failed to persist session title:", err);
1174
1171
  });
1172
+ set((s) => ({
1173
+ sessions: s.sessions.map(
1174
+ (sess) => sess.id === sessionId ? { ...sess, title, updatedAt: Date.now() } : sess
1175
+ )
1176
+ }));
1175
1177
  },
1176
1178
  updateSession(id, patch) {
1177
1179
  set((s) => ({
@@ -1888,7 +1890,7 @@ function LayoutInner({ children }) {
1888
1890
  function DashboardLayout({ children }) {
1889
1891
  return /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(LayoutInner, { children }) });
1890
1892
  }
1891
- const appCss = "/assets/css/styles-YqYDZ89Q.css";
1893
+ const appCss = "/assets/css/styles-6YpiHgz7.css";
1892
1894
  const themeScript = `
1893
1895
  (function() {
1894
1896
  try {
@@ -1929,7 +1931,7 @@ function RootDocument({ children }) {
1929
1931
  ] })
1930
1932
  ] });
1931
1933
  }
1932
- const $$splitComponentImporter$6 = () => import("./usage-BRFRmZxm.mjs");
1934
+ const $$splitComponentImporter$6 = () => import("./usage-CKlYz3IL.mjs");
1933
1935
  const Route$6 = createFileRoute("/usage")({
1934
1936
  component: lazyRouteComponent($$splitComponentImporter$6, "component")
1935
1937
  });
@@ -1950,7 +1952,7 @@ async function toggleSkill(name, enabled) {
1950
1952
  body: JSON.stringify({ name, enabled })
1951
1953
  });
1952
1954
  }
1953
- const $$splitComponentImporter$5 = () => import("./skills-BgBDh_7P.mjs");
1955
+ const $$splitComponentImporter$5 = () => import("./skills-DFrwiw0D.mjs");
1954
1956
  const Route$5 = createFileRoute("/skills")({
1955
1957
  loader: async () => {
1956
1958
  const data = await fetchSkills();
@@ -1962,19 +1964,19 @@ const $$splitComponentImporter$4 = () => import("./settings-DoXurzvn.mjs");
1962
1964
  const Route$4 = createFileRoute("/settings")({
1963
1965
  component: lazyRouteComponent($$splitComponentImporter$4, "component")
1964
1966
  });
1965
- const $$splitComponentImporter$3 = () => import("./memory-CeEgICRt.mjs");
1967
+ const $$splitComponentImporter$3 = () => import("./memory-B0Mc8Ya3.mjs");
1966
1968
  const Route$3 = createFileRoute("/memory")({
1967
1969
  component: lazyRouteComponent($$splitComponentImporter$3, "component")
1968
1970
  });
1969
- const $$splitComponentImporter$2 = () => import("./index-B6Q_iKG1.mjs");
1971
+ const $$splitComponentImporter$2 = () => import("./index-DUbc2UZb.mjs");
1970
1972
  const Route$2 = createFileRoute("/")({
1971
1973
  component: lazyRouteComponent($$splitComponentImporter$2, "component")
1972
1974
  });
1973
- const $$splitComponentImporter$1 = () => import("./chat.index-DaPRZ2yS.mjs");
1975
+ const $$splitComponentImporter$1 = () => import("./chat.index-DBot9MtY.mjs");
1974
1976
  const Route$1 = createFileRoute("/chat/")({
1975
1977
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
1976
1978
  });
1977
- const $$splitComponentImporter = () => import("./chat._sessionId-BSlHY8-3.mjs");
1979
+ const $$splitComponentImporter = () => import("./chat._sessionId-D2hr9ls7.mjs");
1978
1980
  const Route = createFileRoute("/chat/$sessionId")({
1979
1981
  component: lazyRouteComponent($$splitComponentImporter, "component")
1980
1982
  });
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { g as useSidebar, R as Route$5, f as fetchSkillContent, d as fetchSkillFiles, S as SidebarTrigger, c as cn, B as Button, t as toggleSkill } from "./router-BwJ9sLwD.mjs";
3
- import { M as MarkdownMessage } from "./MarkdownMessage-y8GThg94.mjs";
4
- import "./index-D-zP2Zbh.mjs";
2
+ import { g as useSidebar, R as Route$5, f as fetchSkillContent, d as fetchSkillFiles, S as SidebarTrigger, c as cn, B as Button, t as toggleSkill } from "./router-8wMdk9c_.mjs";
3
+ import { M as MarkdownMessage } from "./MarkdownMessage-oVY8VCm_.mjs";
4
+ import "./index-BK5D6j0H.mjs";
5
5
  import { I as IconArrowLeft, m as IconLoader2, u as IconRefresh, k as IconFile, B as IconWand, v as IconSearch, f as IconChevronRight, e as IconChevronDown, r as IconPin } from "../_libs/tabler__icons-react.mjs";
6
6
  import { I as Input$1, S as SwitchRoot, n as SwitchThumb } from "../_libs/base-ui__react.mjs";
7
7
  import "../_libs/tanstack__react-router.mjs";
@@ -1,5 +1,5 @@
1
- import { j as jsxRuntimeExports, r as reactExports } from "../_libs/react.mjs";
2
- import { r as request } from "./router-BwJ9sLwD.mjs";
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { r as request } from "./router-8wMdk9c_.mjs";
3
3
  import "../_libs/tanstack__react-router.mjs";
4
4
  import "../_libs/tanstack__router-core.mjs";
5
5
  import "../_libs/tanstack__history.mjs";
@@ -59,6 +59,19 @@ function cacheHitRate(input, cacheRead) {
59
59
  if (total === 0) return "--";
60
60
  return (cacheRead / total * 100).toFixed(1) + "%";
61
61
  }
62
+ const PERIODS = [{
63
+ label: "Today",
64
+ days: 1
65
+ }, {
66
+ label: "7 Days",
67
+ days: 7
68
+ }, {
69
+ label: "30 Days",
70
+ days: 30
71
+ }, {
72
+ label: "All Time",
73
+ days: 0
74
+ }];
62
75
  function useUsageStats(days = 30) {
63
76
  const [stats, setStats] = reactExports.useState(null);
64
77
  const [loading, setLoading] = reactExports.useState(false);
@@ -85,15 +98,17 @@ function StatCard({
85
98
  function StatCards({
86
99
  stats
87
100
  }) {
88
- const totalTokens = stats.total_input_tokens + stats.total_output_tokens;
101
+ const billedTokens = stats.total_input_tokens + stats.total_output_tokens;
102
+ const totalTokens = billedTokens + stats.total_cache_read_tokens;
89
103
  const totalCache = stats.total_cache_read_tokens;
90
- const cacheRate = totalTokens + totalCache > 0 ? (totalCache / (stats.total_input_tokens + totalCache) * 100).toFixed(1) + "%" : "--";
104
+ const cacheRate = stats.total_input_tokens + totalCache > 0 ? (totalCache / (stats.total_input_tokens + totalCache) * 100).toFixed(1) + "%" : "--";
91
105
  const daysWithActivity = stats.daily_usage.filter((d) => d.sessions > 0).length;
92
106
  const avgPerDay = daysWithActivity > 0 ? (stats.total_sessions / daysWithActivity).toFixed(1) : "0.0";
107
+ const tokenSub = [`${formatTokens(stats.total_input_tokens)} input`, `${formatTokens(stats.total_output_tokens)} output`, totalCache > 0 && `${formatTokens(totalCache)} cache`].filter(Boolean).join(" / ");
93
108
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 mb-5", children: [
94
- /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Total Tokens", value: formatTokens(totalTokens), sub: `${formatTokens(stats.total_input_tokens)} input / ${formatTokens(stats.total_output_tokens)} output` }),
109
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Total Tokens", value: formatTokens(totalTokens), sub: tokenSub }),
95
110
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Total Sessions", value: String(stats.total_sessions), sub: `${avgPerDay} avg/day` }),
96
- /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Estimated Cost", value: formatCost(stats.total_cost ?? 0) }),
111
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Estimated Cost", value: formatCost(stats.total_cost ?? 0), sub: `${formatTokens(billedTokens)} billed` }),
97
112
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatCard, { label: "Cache Hit Rate", value: cacheRate, sub: totalCache > 0 ? `${formatTokens(totalCache)} tokens` : void 0 })
98
113
  ] });
99
114
  }
@@ -273,19 +288,34 @@ function ModelBreakdown({
273
288
  ] }, m.model)) })
274
289
  ] });
275
290
  }
291
+ function PeriodTabs({
292
+ active,
293
+ onChange
294
+ }) {
295
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex rounded-lg border bg-muted/40 p-0.5", children: PERIODS.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => onChange(p.days), className: "px-3 py-1 text-xs font-medium rounded-md transition-colors " + (active === p.days ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"), children: p.label }, p.label)) });
296
+ }
276
297
  function UsagePage() {
298
+ const [days, setDays] = reactExports.useState(30);
277
299
  const {
278
300
  stats,
279
301
  loading
280
- } = useUsageStats(30);
302
+ } = useUsageStats(days);
303
+ const periodLabel = PERIODS.find((p) => p.days === days)?.label ?? "Custom";
281
304
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto p-4 md:p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-5xl", children: [
282
- /* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "mb-5", children: [
283
- /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-semibold", children: "Usage" }),
284
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "Token consumption and cost estimates over the last 30 days." })
305
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "mb-5 flex items-center justify-between flex-wrap gap-3", children: [
306
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
307
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-semibold", children: "Usage" }),
308
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-muted-foreground", children: [
309
+ "Token consumption and cost estimates",
310
+ days > 0 ? ` over the last ${periodLabel.toLowerCase()}` : " (all time)",
311
+ "."
312
+ ] })
313
+ ] }),
314
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PeriodTabs, { active: days, onChange: setDays })
285
315
  ] }),
286
316
  loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground py-8", children: "Loading usage stats…" }),
287
317
  !loading && !stats && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground py-8", children: "Failed to load usage data." }),
288
- !loading && stats && stats.total_sessions === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground py-8", children: "No usage data yet." }),
318
+ !loading && stats && stats.total_sessions === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground py-8", children: "No usage data for this period." }),
289
319
  !loading && stats && stats.total_sessions > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
290
320
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatCards, { stats }),
291
321
  /* @__PURE__ */ jsxRuntimeExports.jsx(ModelBreakdown, { stats }),
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ routes: { __root__: { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/__root.tsx", children: ["/", "/memory", "/settings", "/skills", "/usage", "/chat/$sessionId", "/chat/"], assets: [{ tag: "link", attrs: { rel: "stylesheet", href: "/assets/css/index-Dfs9RUU9.css", type: "text/css" } }], preloads: ["/assets/js/index-DsMUdp1X.js"] }, "/": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/index.tsx", children: void 0, assets: [], preloads: ["/assets/js/index-DnOJbmz0.js", "/assets/js/ChatInputBlock-BYpIR_ls.js"] }, "/memory": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/memory.tsx", children: void 0, assets: [], preloads: ["/assets/js/memory-B_Uy_WUi.js", "/assets/js/MarkdownMessage-DL1aUod4.js"] }, "/settings": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/settings.tsx", children: void 0, assets: [], preloads: ["/assets/js/settings-ZdgGJLcS.js"] }, "/skills": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/skills.tsx", children: void 0, assets: [], preloads: ["/assets/js/skills-Bg3vZgl2.js", "/assets/js/MarkdownMessage-DL1aUod4.js"] }, "/usage": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/usage.tsx", children: void 0, assets: [], preloads: ["/assets/js/usage-DXPIAwzR.js"] }, "/chat/$sessionId": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/chat.$sessionId.tsx", children: void 0, assets: [], preloads: ["/assets/js/chat._sessionId-YaowVhVf.js", "/assets/js/MarkdownMessage-DL1aUod4.js", "/assets/js/ChatInputBlock-BYpIR_ls.js"] }, "/chat/": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/chat.index.tsx", children: void 0, assets: [], preloads: ["/assets/js/chat.index-B64jjuMw.js"] } }, clientEntry: "/assets/js/index-DsMUdp1X.js" });
1
+ const tsrStartManifest = () => ({ routes: { __root__: { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/__root.tsx", children: ["/", "/memory", "/settings", "/skills", "/usage", "/chat/$sessionId", "/chat/"], assets: [{ tag: "link", attrs: { rel: "stylesheet", href: "/assets/css/index-Dfs9RUU9.css", type: "text/css" } }], preloads: ["/assets/js/index-i-jDCacv.js"] }, "/": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/index.tsx", children: void 0, assets: [], preloads: ["/assets/js/index-CyG4dGLZ.js", "/assets/js/ChatInputBlock-CjzfB3kg.js"] }, "/memory": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/memory.tsx", children: void 0, assets: [], preloads: ["/assets/js/memory-DNJsQEy1.js", "/assets/js/MarkdownMessage-BvEwByae.js"] }, "/settings": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/settings.tsx", children: void 0, assets: [], preloads: ["/assets/js/settings-CATsDWsM.js"] }, "/skills": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/skills.tsx", children: void 0, assets: [], preloads: ["/assets/js/skills-vv2f_qsa.js", "/assets/js/MarkdownMessage-BvEwByae.js"] }, "/usage": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/usage.tsx", children: void 0, assets: [], preloads: ["/assets/js/usage-B1WUX7rU.js"] }, "/chat/$sessionId": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/chat.$sessionId.tsx", children: void 0, assets: [], preloads: ["/assets/js/chat._sessionId-CHAIu0ue.js", "/assets/js/MarkdownMessage-BvEwByae.js", "/assets/js/ChatInputBlock-CjzfB3kg.js"] }, "/chat/": { filePath: "/home/abbskhnv/Desktop/hermium-new/packages/web/src/routes/chat.index.tsx", children: void 0, assets: [], preloads: ["/assets/js/chat.index-B6cbfDDD.js"] } }, clientEntry: "/assets/js/index-i-jDCacv.js" });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };