herm-tui 1.3.0-dev.5 → 1.3.0-dev.6

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 (2) hide show
  1. package/index.js +1 -1
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -4101,7 +4101,7 @@ tell application "System Events" to get value of property list item "CFBundleNam
4101
4101
  `,skE);while(end<text2.length&&end>=0){let nl=text2.indexOf(`
4102
4102
  `,end+1);if(nl<0){end=text2.length;break}let line=text2.slice(end+1,nl).trim();if(line.startsWith("#"))break;if(line===""){if(text2.slice(nl+1,text2.indexOf(`
4103
4103
  `,nl+1)).trim().startsWith("#")){end=nl;break}}end=nl}mark2(skH,end+1,"skills","Skills Catalog",makeSource("skills","skills/"))}let proj=text2.indexOf("# Project Context");if(proj>=0){let conv2=text2.indexOf("Conversation started:");mark2(proj,conv2>proj?conv2:text2.length,"project","Project Context",makeSource("AGENTS.md"))}let conv=text2.indexOf("Conversation started:");if(conv>=0)mark2(conv,text2.length,"meta","Session Metadata");let start2=-1;for(let i=0;i<=text2.length;i++)if(i<text2.length&&!used[i]){if(start2<0)start2=i}else if(start2>=0){let slice=text2.slice(start2,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start2=-1}return sections.sort((a,b2)=>text2.indexOf(a.text)-text2.indexOf(b2.text))}function classifyTools(tools){let system=[],mcp=[];for(let t2 of tools)if(t2.name.startsWith("mcp_"))mcp.push(t2);else system.push(t2);return{system,mcp}}function toolTokens(tool){return Math.ceil((tool.descriptionLength+tool.paramsLength)/CPT)}function build(opts){let pct=(t2)=>opts.contextLength>0?t2/opts.contextLength*100:0,result=[],byId2=new Map;for(let s of opts.sections)byId2.set(s.id,s);let promptChildren=opts.sections.filter((sec)=>SYSTEM_PROMPT_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),promptTok=promptChildren.reduce((s,c)=>s+c.tokens,0);if(promptTok>0)result.push({id:"system_prompt",label:"System Prompt",tokens:promptTok,percent:pct(promptTok),children:promptChildren});let{system:sysTools,mcp:mcpTools}=classifyTools(opts.tools),sysToolsTok=sysTools.reduce((s,t2)=>s+toolTokens(t2),0);if(sysToolsTok>0)result.push({id:"system_tools",label:"System Tools",tokens:sysToolsTok,percent:pct(sysToolsTok)});let mcpToolsTok=mcpTools.reduce((s,t2)=>s+toolTokens(t2),0);if(mcpToolsTok>0)result.push({id:"mcp_tools",label:"MCP Tools",tokens:mcpToolsTok,percent:pct(mcpToolsTok)});let memChildren=opts.sections.filter((sec)=>MEMORY_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),memTok=memChildren.reduce((s,c)=>s+c.tokens,0);if(memTok>0)result.push({id:"memory",label:"Memory",tokens:memTok,percent:pct(memTok),children:memChildren});let skillsSec=byId2.get("skills"),skillsTok=skillsSec?.tokens??opts.skillsTokens??0;if(skillsTok>0)result.push({id:"skills",label:"Skills",tokens:skillsTok,percent:pct(skillsTok),section:skillsSec});if(opts.conversationTokens>0){let ct=Math.min(opts.conversationTokens,opts.inputTokens||opts.conversationTokens);result.push({id:"conversation",label:"Conversation",tokens:ct,percent:pct(ct)})}let taken=result.reduce((s,g)=>s+g.tokens,0),free=Math.max(0,opts.contextLength-taken);return result.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),result}function drill(group){if(!group.children||group.children.length===0)return[];let total=group.tokens;return group.children.map((c)=>({...c,percent:total>0?c.tokens/total*100:0}))}function cells(segments,fallback="free"){let filled=segments.flatMap((seg)=>Array.from({length:Math.round(seg.percent/100*GRID)},()=>({id:seg.id}))),pad=Array.from({length:Math.max(0,GRID-filled.length)},()=>({id:fallback}));return[...filled,...pad].slice(0,GRID)}var import_react47=__toESM(require_react_production(),1);var FileLink=import_react47.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react47.useState(!1);return $jsx("box",{height:1,onMouseDown:()=>openFile(source.file),onMouseOver:()=>setHovered(!0),onMouseOut:()=>setHovered(!1),children:$jsx("text",{fg:theme.info,attributes:hovered?TextAttributes.UNDERLINE:TextAttributes.NONE,children:children2??source.label})})}),KVLink=(props)=>{let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx(FileLink,{source:props.source,children:props.text??props.source.label})})]})};var TabShell=(props)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",flexGrow:props.grow??1,flexBasis:0,minWidth:0,border:!0,borderColor:props.focus?theme.primary:theme.border,backgroundColor:theme.backgroundPanel,padding:1,children:[$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:props.title})})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:` ${props.hint}`})})]}),props.error?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:`\u26A0 ${props.error}`})}):null,$jsx("box",{height:1}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:props.children})]})};var GOLDEN_ANGLE=137.50776405003785;function luminance(c){return 0.299*c.r+0.587*c.g+0.114*c.b}function rgbaToHsl(c){let{r,g,b:b2}=c,max=Math.max(r,g,b2),min=Math.min(r,g,b2),l=(max+min)/2,d2=max-min;if(d2===0)return[0,0,l];let s=l>0.5?d2/(2-max-min):d2/(max+min),h2;switch(max){case r:h2=(g-b2)/d2+(g<b2?6:0);break;case g:h2=(b2-r)/d2+2;break;default:h2=(r-g)/d2+4}return[h2*60,s,l]}function hslToRgba(h2,s,l){if(h2=(h2%360+360)%360/360,s===0)return RGBA.fromValues(l,l,l,1);let q3=l<0.5?l*(1+s):l+s-l*s,p=2*l-q3,ch=(t2)=>{if(t2<0)t2+=1;if(t2>1)t2-=1;if(t2<0.16666666666666666)return p+(q3-p)*6*t2;if(t2<0.5)return q3;if(t2<0.6666666666666666)return p+(q3-p)*(0.6666666666666666-t2)*6;return p};return RGBA.fromValues(ch(h2+0.3333333333333333),ch(h2),ch(h2-0.3333333333333333),1)}function categorical(seed,bg2,n){let[h0]=rgbaToHsl(seed),dark=luminance(bg2)<0.5,s=dark?0.6:0.7,l=dark?0.62:0.42,out=[];for(let i=0;i<n;i++)out.push(hslToRgba(h0+i*GOLDEN_ANGLE,s,l));return out}var DEFAULT_CTX=128000,COLS2=16,SLOTS2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation","soul","mem0","user","project","meta","other"],SLOT=Object.fromEntries(SLOTS2.map((id,i)=>[id,i])),rampCache=new WeakMap;function ramp2(theme){let r=rampCache.get(theme);if(!r)rampCache.set(theme,r=categorical(theme.primary,theme.background,SLOTS2.length));return r}function clr(id,theme){if(id==="free")return theme.borderSubtle;return ramp2(theme)[SLOT[id]??SLOT.other]}var fmt=(n)=>{if(n>=1e6)return`${(n/1e6).toFixed(1)}M`;if(n>=1e4)return`${Math.round(n/1000)}k`;if(n>=1000)return`${(n/1000).toFixed(1)}k`;return String(n)},est=(s)=>s?count2(s):0,bar=(pct,w2=20)=>{let f=Math.round(Math.max(0,Math.min(100,pct))/100*w2);return`[${"\u2588".repeat(f)}${"\u2591".repeat(Math.max(0,w2-f))}]`},SectionPanel=import_react48.memo(({seg,theme})=>{let{syntaxStyle}=useTheme(),sec=seg.section;if(!sec)return null;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt(sec.tokens)," tokens"]}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsx("markdown",{content:sec.text,fg:theme.markdownText,syntaxStyle})]})}),MemoryPanel=import_react48.memo(({seg,theme,label,chars,limit,pct,entries,source})=>$jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:label})}),source?$jsxs($Fragment2,{children:[$jsx("text",{children:" ("}),$jsx(FileLink,{source}),$jsx("text",{children:")"})]}):null]}),$jsxs("text",{children:[chars.toLocaleString()," / ",limit.toLocaleString()," chars (",pct,"%)"]}),$jsxs("text",{children:[bar(pct,25),pct>=95?" \u26A0 near limit":""]}),$jsx("text",{children:" "}),$jsxs("text",{children:[entries.length," entries:"]}),entries.map((e,i)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",e]},i))]})),SkillsPanel=import_react48.memo(({seg,theme})=>{let sec=seg.section;if(!sec)return null;let cats={};for(let line of sec.text.split(`
4104
- `)){if(line.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line.match(/^\s{4}- \S+:/)){let last=Object.keys(cats).pop();if(last)cats[last]++}}let sorted=Object.entries(cats).sort((a,b2)=>b2[1]-a[1]),total=sorted.reduce((s,[,n])=>s+n,0);return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("skills",theme),children:"\u25FC"})," Skills Catalog \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsxs("text",{children:[total," skills in ",sorted.length," categories \xB7 ",sec.chars.toLocaleString()," chars"]}),$jsx("text",{fg:theme.textMuted,children:"Largest context section \u2014 skill names + descriptions injected every turn."}),$jsx("text",{children:" "}),sorted.map(([cat,n])=>$jsxs("text",{fg:theme.text,children:["\xB7 ",cat," (",n,")"]},cat))]})}),ToolsPanel=import_react48.memo(({seg,theme,tools,kind})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label=kind==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind==="mcp_tools"?"MCP-loaded tools \u2014 schemas injected via mcp_ prefix.":"Built-in tool schemas sent with every API call.";return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(kind,theme),children:"\u25FC"})," ",label," \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:[tools.length," tools \u2014 ",blurb]}),$jsx("text",{children:" "}),sorted.map((t2)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",t2.name," (",fmt(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react48.memo(({seg,theme,messages,output})=>{let user=messages.filter((m2)=>m2.role==="user"),asst=messages.filter((m2)=>m2.role==="assistant"),non=messages.filter((m2)=>m2.role!=="system");return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("conversation",theme),children:"\u25FC"})," Conversation \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt(est(user.map((m2)=>text(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt(est(asst.map((m2)=>text(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment2,{children:[$jsx("text",{fg:theme.info,children:"Messages:"}),$jsx("text",{children:" "}),non.map((m2,i)=>$jsxs("text",{children:[$jsx("span",{fg:m2.role==="user"?theme.info:theme.success,children:m2.role==="user"?"\u25B8 You":"\u25C2 Agent"})," ","(",fmt(est(text(m2))),") ",text(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react48.memo(({seg,theme,ctxLen,comp,onEditThreshold})=>{let used=ctxLen-seg.tokens,threshold=Math.round(ctxLen*(comp?.threshold??0.5)),pct=threshold>0?Math.min(100,Math.round(used/threshold*100)):0;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("free",theme),children:"\u25FB"})," Free Space \u2014 ",fmt(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment2,{children:[$jsx("text",{children:$jsx("strong",{children:"Compression"})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsxs("text",{children:[comp.enabled?"\u2713 Enabled":"\u2717 Disabled"," \xB7 threshold "]}),$jsx("box",{flexShrink:0,onMouseDown:onEditThreshold,children:$jsx("text",{fg:theme.info,children:$jsxs("u",{children:[Math.round(comp.threshold*100),"%"]})})}),$jsxs("text",{children:[" (",fmt(threshold),")"]})]}),$jsxs("text",{children:[bar(pct)," ",pct,"%"]}),$jsxs("text",{children:["Protect last ",comp.protect_last_n," messages \xB7 target ratio ",Math.round(comp.target_ratio*100),"%"]}),comp.summary_model?$jsxs("text",{children:["Summary model: ",comp.summary_model]}):null]}):null]})}),NO_MESSAGES=Object.freeze([]),Context=import_react48.memo(({messages=NO_MESSAGES,info,focused})=>{let config=useHome("config"),memory=useHome("memory"),userProfile=useHome("userProfile"),gw=useGateway(),dialog=useDialog(),toast=useToast(),systemPrompt2=useHome("systemPrompt"),toolsInfo=useHome("toolsInfo"),soul=useHome("soul"),recentSessions=useHome("recentSessions"),liveSessions=useHome("liveSessions"),[wire,setWire]=import_react48.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react48.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react48.useState(null),[selected,setSelected]=import_react48.useState(null),[drilled,setDrilled]=import_react48.useState(null);import_react48.useEffect(()=>{let input=0,output2=0,total=0,calls=0;for(let m2 of messages)if(m2.usage)input+=m2.usage.input,output2+=m2.usage.output,total+=m2.usage.total,calls++;let next={input,output:output2,total,calls};wireRef.current=next,setWire(next)},[messages]);let session=recentSessions?.[0],ctxLen=info?.context_max??DEFAULT_CTX,lastPrompt=(session?Object.values(liveSessions??{}).find((ls)=>ls.session_id===session.id):void 0)?.last_prompt_tokens??0,fill=wire.calls>0?wire.input:lastPrompt>0?lastPrompt:session?.input_tokens??0,cumulative=wire.calls===0&&lastPrompt===0&&(session?.input_tokens??0)>0,output=wire.calls>0?wire.output:session?.output_tokens??0,pct=ctxLen>0?Math.round(fill/ctxLen*100):0,thresholdPct=config?.compression?.threshold??0.5,thresholdIdx=Math.min(COLS2*COLS2,Math.max(0,Math.round(thresholdPct*COLS2*COLS2))),compressions=info?.usage?.compressions??0,promptText=info?.system_prompt??systemPrompt2?.text??"",sections=import_react48.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react48.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text(m2)).join("")),[messages]),top=import_react48.useMemo(()=>build({contextLength:ctxLen,inputTokens:fill,sections,conversationTokens:convTok,tools:toolsInfo?.tools??[]}),[ctxLen,fill,sections,convTok,toolsInfo?.tools]),drilledGroup=drilled?top.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top,grid=import_react48.useMemo(()=>cells(view,drilledGroup?drilledGroup.children?.[0]?.id??"other":"free"),[view,drilledGroup]),findSeg=(id)=>{if(drilledGroup)return view.find((s)=>s.id===id);return top.find((s)=>s.id===id)},memEntries=import_react48.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react48.useMemo(()=>(userProfile?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[userProfile?.content]),click=(id)=>{if(drilled){setSelected(selected===id?null:id);return}let seg=top.find((s)=>s.id===id);if(seg?.children&&seg.children.length>0){setDrilled(id),setSelected(null);return}setSelected(selected===id?null:id)},lastEsc=import_react48.useRef(0),segs=view.filter((s)=>s.tokens>0),idx3=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx3):v2));setSelected(segs[n]?.id??null)},keys=useKeys();useKeyboard((key2)=>{if(!focused||dialog.open())return;if(handleListKey(keys,key2,{count:segs.length,setSel,onActivate:()=>{if(drilled||!selected)return;if(top.find((s)=>s.id===selected)?.children?.length)setDrilled(selected),setSelected(null)}}))return;if(key2.name==="right")return setSel((p)=>p+1);if(key2.name==="left")return setSel((p)=>p-1);if(key2.name!=="escape")return;let now=Date.now();if(now-lastEsc.current<400){setSelected(null),setDrilled(null),lastEsc.current=0;return}if(lastEsc.current=now,selected)return setSelected(null);if(drilled)return setDrilled(null)});let editThreshold=async()=>{let cur=Math.round((config?.compression?.threshold??0.5)*100),v2=await openTextPrompt(dialog,{title:"Compression threshold",label:"Percent (10\u201395)",initial:String(cur)});if(v2===null)return;let n=Math.max(10,Math.min(95,Number(v2)||cur)),{writeConfig:writeConfig2}=await Promise.resolve().then(() => (init_lane(),exports_lane)),r=await writeConfig2(gw,[{key:"compression.threshold",to:n/100}]);if(r.failed.length)return toast.show({variant:"error",message:r.failed[0].err});home2.invalidate("config"),toast.show({variant:"success",message:`Threshold \u2192 ${n}%`})},detail=()=>{if(!selected)return null;let seg=findSeg(selected);if(!seg)return null;if(selected==="memory"&&drilled==="memory"&&memory)return $jsx(MemoryPanel,{seg,theme,label:"Agent Notes",chars:memory.charCount,limit:memory.charLimit,pct:memory.usagePercent,entries:memEntries,source:memory.source});if(selected==="user"&&userProfile)return $jsx(MemoryPanel,{seg,theme,label:"User Profile",chars:userProfile.charCount,limit:userProfile.charLimit,pct:userProfile.usagePercent,entries:userEntries,source:userProfile.source});if(selected==="skills")return $jsx(SkillsPanel,{seg,theme});if(selected==="system_tools"&&toolsInfo){let{system}=classifyTools(toolsInfo.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&&toolsInfo){let{mcp}=classifyTools(toolsInfo.tools);return $jsx(ToolsPanel,{seg,theme,tools:mcp,kind:"mcp_tools"})}if(selected==="soul"&&soul){let soulSeg={...seg,section:{id:"soul",label:"SOUL.md",chars:soul.charCount,tokens:soul.tokenEstimate,text:soul.content,source:soul.source}};return $jsx(SectionPanel,{seg:soulSeg,theme})}if(selected==="conversation")return $jsx(ConvPanel,{seg,theme,messages,output});if(selected==="free")return $jsx(FreePanel,{seg,theme,ctxLen,comp:config?.compression,onEditThreshold:editThreshold});return $jsx(SectionPanel,{seg,theme})},breakdown=()=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsxs("text",{children:[$jsx("strong",{children:"Breakdown"}),drilledGroup?$jsxs("span",{fg:theme.info,children:[" \xB7 ",drilledGroup.label," (",fmt(drilledGroup.tokens)," tok)"]}):$jsx("span",{fg:theme.info,children:" (click group to expand)"})]}),view.filter((s)=>s.tokens>0).map((s)=>$jsxs("text",{children:[$jsx("span",{fg:clr(s.id,theme),children:s.id==="free"?"\u25FB":"\u25FC"})," ",s.label," \u2014 ",fmt(s.tokens)," (",s.percent.toFixed(1),"%)",s.children?$jsx("span",{fg:theme.textMuted,children:" \u25B8"}):null]},s.id)),output>0&&!drilled?$jsxs("text",{children:[$jsx("span",{fg:theme.success,children:"\u25FC"})," Output \u2014 ",fmt(output)," tokens"]}):null,$jsx("text",{children:$jsxs("span",{fg:theme.textMuted,children:["\u25FC Beyond compression threshold (",Math.round(thresholdPct*100),"%)"]})})]}),crumb=drilled?`${drilledGroup?.label}${selected?` \xB7 ${findSeg(selected)?.label}`:""}`:wire.calls===0&&fill===0?"[no data]":cumulative?"[cumulative \u2014 not current fill]":wire.calls===0&&fill>0?"[live session]":"\u2191\u2193 nav \xB7 click a group to drill in",escHint=selected||drilled?" \xB7 Esc back":"",focus=selected||hovered,focusSeg=focus?findSeg(focus):null;return $jsxs(TabShell,{title:`Context \xB7 ${fmt(fill)} / ${fmt(ctxLen)} (${pct}%)`,hint:crumb+escHint,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt(focusSeg.tokens)," tok (",focusSeg.percent.toFixed(1),"%)"]}):$jsx("text",{children:" "})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs("box",{flexDirection:"column",marginRight:2,flexShrink:0,children:[compressions>0?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{fg:theme.warning,children:["\xD7",compressions," compressed"]})}):null,$jsx("box",{border:!0,customBorderChars:CORNERS,borderColor:theme.border,children:[...Array(COLS2)].map((_2,row)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=row*COLS2+col>=thresholdIdx,glyph=!past&&cell.id==="free"?"\u25FB":"\u25FC";return $jsx("box",{height:1,width:2,backgroundColor:hl?clr(cell.id,theme):void 0,onMouseOver:()=>setHovered(cell.id),onMouseOut:()=>setHovered(null),onMouseDown:()=>click(cell.id),children:$jsx("text",{fg:past?theme.textMuted:clr(cell.id,theme),children:glyph})},col)})},row))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]})});var import_react53=__toESM(require_react_production(),1);init_sessions_db();var KV=(props)=>{let theme=useTheme().theme;return $jsxs("box",{minHeight:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:props.wrap?void 0:1,overflow:props.wrap?void 0:"hidden",children:$jsx("text",{wrapMode:props.wrap?"word":void 0,fg:props.fg??theme.text,children:props.value})})]})},KVBlock=(props)=>props.rows.map(([k2,v2,fg2])=>v2===void 0?null:$jsx(KV,{label:k2,value:v2,fg:fg2},k2));var import_react50=__toESM(require_react_production(),1);var VBAR_W=1,VBAR={visible:!0},Col=(p)=>{let theme=useTheme().theme,fg2=p.fg??theme.text;return $jsx("box",{width:p.w,flexGrow:p.grow?1:0,flexShrink:p.grow?1:0,minWidth:p.grow?p.min??12:p.w,height:1,overflow:"hidden",flexDirection:"row",justifyContent:p.right?"flex-end":"flex-start",children:$jsx("text",{children:p.bold?$jsx("span",{fg:fg2,children:$jsx("strong",{children:p.children})}):$jsx("span",{fg:fg2,children:p.children})})})},Hdr=(p)=>$jsx("box",{flexDirection:"row",height:1,paddingRight:VBAR_W,children:p.children}),Marquee=(p)=>{let theme=useTheme().theme,fg2=p.fg??theme.text,text2=p.children,box=import_react50.useRef(null),node=import_react50.useRef(null),animate=get("animations")!==!1&&p.active;return import_react50.useEffect(()=>{let tn=node.current;if(!tn)return;if(!animate){tn.scrollX=0;return}let id,period=text2.length+GAP.length,hold=setTimeout(()=>{id=setInterval(()=>{let w2=box.current?.width??0;if(text2.length<=w2){tn.scrollX=0;return}tn.scrollX=(tn.scrollX+1)%period},p.speed??180)},p.hold??600);return()=>{if(clearTimeout(hold),id)clearInterval(id);if(node.current)node.current.scrollX=0}},[animate,text2,p.speed,p.hold]),$jsx("box",{ref:box,width:p.w,flexGrow:p.grow?1:0,flexShrink:p.grow?1:0,minWidth:p.grow?p.min??12:p.w,height:1,overflow:"hidden",children:$jsx("text",{ref:node,wrapMode:"none",children:p.bold?$jsx("span",{fg:fg2,children:$jsx("strong",{children:text2+GAP+text2})}):$jsx("span",{fg:fg2,children:text2+GAP+text2})})})},GAP=" ";var import_react51=__toESM(require_react_production(),1);var Ticker=(p)=>{let ref=import_react51.useRef(null),animate=get("animations")!==!1&&p.active,speed=p.speed??180,hold=p.hold??600,endHold=p.endHold??3000;return import_react51.useEffect(()=>{let node=ref.current;if(!node)return;if(!animate){node.scrollX=0;return}let dir=1,tick2,wait,step=()=>{let max=node.maxScrollX;if(max<=0)return;if(node.scrollX=Math.max(0,Math.min(max,node.scrollX+dir)),!(dir>0?node.scrollX>=max:node.scrollX<=0))return;if(tick2)clearInterval(tick2),tick2=void 0;dir=-dir,wait=setTimeout(()=>{tick2=setInterval(step,speed)},endHold)};return wait=setTimeout(()=>{tick2=setInterval(step,speed)},hold),()=>{if(wait)clearTimeout(wait);if(tick2)clearInterval(tick2);if(ref.current)ref.current.scrollX=0}},[animate,speed,hold,endHold]),$jsx("box",{flexGrow:1,flexShrink:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{ref,wrapMode:"none",fg:p.fg,children:p.children})})},RX=/(`[^`]+`)|(\*\*[^*]+\*\*)|(__[^_]+__)|((?<![\w*])\*[^*\s][^*]*\*(?![\w*]))|((?<!\w)_[^_\s][^_]*_(?!\w))/g,inline=(s)=>{let out=[],last=0;for(let m2 of s.matchAll(RX)){let at=m2.index??0;if(at>last)out.push({t:s.slice(last,at)});let hit=m2[0];if(hit.startsWith("`"))out.push({t:hit.slice(1,-1),c:!0});else if(hit.startsWith("**")||hit.startsWith("__"))out.push({t:hit.slice(2,-2),b:!0});else out.push({t:hit.slice(1,-1),i:!0});last=at+hit.length}if(last<s.length)out.push({t:s.slice(last)});return out.map((seg)=>seg.c?seg:{...seg,t:seg.t.replace(/^#{1,6}\s+/,"")})};var Confirm=(props)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key2)=>{if(keys.match("dialog.confirm",key2)||keys.match("dialog.accept",key2))return props.onConfirm();if(keys.match("dialog.deny",key2)||keys.match("dialog.cancel",key2))return props.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:props.danger?theme.warning:theme.primary,children:$jsx("strong",{children:props.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:props.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}/${keys.print("dialog.accept")}] ${props.yes??"confirm"} [${keys.print("dialog.deny")}] ${props.no??"cancel"}`})})]})};function openConfirm(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Confirm,{...opts,onConfirm:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}))})}var h12=()=>get("timeFormat")==="12h",abs=()=>get("timeStyle")==="absolute",trunc4=(s,max)=>s.length<=max?s:s.slice(0,max-1)+"\u2026",fmt2=(n)=>n>=1e6?`${(n/1e6).toFixed(2)}M`:n>=1000?`${(n/1000).toFixed(1)}k`:String(n),cost=(c)=>c==null?"\u2014":`$${c.toFixed(2)}`,clock=(d2)=>d2.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:h12()}),stamp=(ts)=>{let d2=new Date(ts*1000);return d2.toDateString()===new Date().toDateString()?clock(d2):d2.toLocaleDateString(void 0,{month:"short",day:"numeric"})},rel=(ts)=>{let s=Math.floor(Date.now()/1000-ts);if(s<60)return"just now";if(s<3600)return`${Math.floor(s/60)}m ago`;if(s<86400)return`${Math.floor(s/3600)}h ago`;return`${Math.floor(s/86400)}d ago`},ago=(ts)=>abs()?stamp(ts):rel(ts),until=(ts)=>{if(abs())return ts<=Date.now()/1000?"due":stamp(ts);let s=Math.floor(ts-Date.now()/1000);if(s<=0)return"due";if(s<60)return`in ${s}s`;if(s<3600)return`in ${Math.floor(s/60)}m`;if(s<86400)return`in ${Math.floor(s/3600)}h`;return`in ${Math.floor(s/86400)}d`},when=(ts)=>{let d2=new Date(ts*1000);return`${d2.toLocaleDateString()} ${clock(d2)}`},span=(start2,end)=>{let s=Math.round(end-start2);if(s<0)return"\u2014";if(s>=3600)return`${Math.floor(s/3600)}h ${Math.floor(s%3600/60)}m`;if(s>=60)return`${Math.floor(s/60)}m`;return`${s}s`},dur2=(s)=>s>=3600?`${Math.floor(s/3600)}h${Math.floor(s%3600/60)}m`:s>=60?`${Math.floor(s/60)}m${Math.floor(s%60)}s`:`${Math.floor(s)}s`;var badge=(src)=>({cli:"CLI",tui:"TUI",api_server:"API",discord:"Discord",telegram:"Telegram",slack:"Slack",whatsapp:"WhatsApp",signal:"Signal"})[src]??src,line=(s)=>(s??"").replace(/\s+/g," ").trim(),fold=(msgs)=>{let turns=[],tools=0;for(let m2 of msgs){if(m2.role==="tool"){tools++;continue}if(m2.role!=="user"&&m2.role!=="assistant")continue;let text2=line(m2.content);if(!text2)continue;turns.push({role:m2.role,text:text2})}return{turns,tools}},PeekRow=import_react53.memo((props)=>{let theme=useTheme().theme,[hot,setHot]=import_react53.useState(!1),left=props.row.role==="user",color=left?theme.primary:theme.accent,fg2=left?theme.text:theme.markdownText,bar2=(side)=>$jsx("box",{width:2,flexShrink:0,height:1,border:[side],borderColor:color,customBorderChars:SIDE_PIPE});return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:hot?theme.backgroundElement:void 0,onMouseOver:()=>setHot(!0),onMouseOut:()=>setHot(!1),children:[left?bar2("left"):null,$jsx(Ticker,{active:hot,speed:35,hold:150,fg:fg2,children:inline(props.row.text).map((s,i)=>s.c?$jsx("span",{fg:theme.warning,children:s.t},i):s.b?$jsx("span",{fg:fg2,children:$jsx("strong",{children:s.t})},i):s.i?$jsx("span",{fg:fg2,children:$jsx("u",{children:s.t})},i):$jsx("span",{fg:fg2,children:s.t},i))}),left?null:bar2("right")]})}),Peek=import_react53.memo((props)=>{let theme=useTheme().theme,[data2,setData]=import_react53.useState(null),sb=import_react53.useRef(null);if(import_react53.useEffect(()=>{Promise.resolve(props.peek(props.sid,60)).then((m2)=>setData(fold(m2)))},[props.sid,props.peek]),import_react53.useEffect(()=>{if(data2&&sb.current)sb.current.scrollTop=sb.current.scrollHeight},[data2]),data2===null)return null;if(data2.turns.length===0&&data2.tools===0)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local transcript)"})});let more=Math.max(0,props.total-60);return $jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:5,border:!0,borderStyle:"single",borderColor:theme.border,title:` Transcript${more>0?` \xB7 ${more} earlier`:""} `,titleAlignment:"left",children:[$jsx("scrollbox",{ref:sb,scrollY:!0,flexGrow:1,minHeight:3,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.turns.map((r,i)=>$jsx(PeekRow,{row:r},i))})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${data2.turns.length} turn${data2.turns.length===1?"":"s"} \xB7 ${data2.tools} tool call${data2.tools===1?"":"s"}`})})]})}),Detail=import_react53.memo((props)=>{let theme=useTheme().theme,r=props.row,d2=r.detail,lastActive=d2?.last_active??d2?.ended_at??null,subs2=d2?.subagent_count??0,[info,setInfo]=import_react53.useState({});import_react53.useEffect(()=>{Promise.resolve(props.lineage(r.id)).then(setInfo)},[r.id,props.lineage]);let hasLineage=info.continuesFrom||info.compressedTo||subs2>0,go=(sid)=>()=>props.onSwitch?.(sid);return $jsx(TabShell,{title:"Session Detail",hint:"",grow:2,children:$jsxs("box",{flexDirection:"column",width:"100%",flexGrow:1,overflow:"hidden",children:[$jsxs("box",{flexDirection:"column",flexShrink:0,children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title||"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",r.id],["Source",badge(r.source??"")],["Model",d2?.model??"\u2014"],["Started",when(r.started_at)],["Last active",lastActive?`${when(lastActive)} (${ago(lastActive)})`:"\u2014"],["Duration",lastActive?span(r.started_at,lastActive):"\u2014"],["Ended",d2?.ended_at?`${when(d2.ended_at)} \xB7 ${d2.end_reason??"\u2014"}`:void 0]]}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Messages",String(r.message_count)],["Tool calls",d2?String(d2.tool_call_count):void 0],["Input",d2?`${fmt2(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt2(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt2(d2.cache_read_tokens)} r / ${fmt2(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt2(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment2,{children:[$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,children:"Lineage"})}),info.continuesFrom?$jsx("box",{height:1,onMouseDown:go(info.continuesFrom.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2190 continues from "}),$jsx("span",{fg:theme.accent,children:info.continuesFrom.title||info.continuesFrom.id})]})}):null,info.compressedTo?$jsx("box",{height:1,onMouseDown:go(info.compressedTo.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2192 compressed to "}),$jsx("span",{fg:theme.accent,children:info.compressedTo.title||info.compressedTo.id})]})}):null,subs2>0?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2387 spawned "}),$jsx("span",{fg:theme.text,children:String(subs2)}),$jsx("span",{fg:theme.textMuted,children:` subagent${subs2===1?"":"s"}`})]})}):null]}):null,!d2?$jsxs($Fragment2,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local detail \u2014 state.db mismatch)"})})]}):null,$jsx("box",{height:1})]}),$jsx(Peek,{sid:r.id,total:r.message_count,peek:props.peek})]})})}),SearchDetail=import_react53.memo((props)=>{let theme=useTheme().theme,r=props.result,parts2=[],rest=r.snippet;while(rest.length){let start2=rest.indexOf(">>>");if(start2<0){parts2.push({text:rest,hi:!1});break}if(start2>0)parts2.push({text:rest.slice(0,start2),hi:!1});let end=rest.indexOf("<<<",start2+3);if(end<0){parts2.push({text:rest.slice(start2+3),hi:!0});break}parts2.push({text:rest.slice(start2+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",hint:"",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title??"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Source",badge(r.source)],["Model",r.model??"\u2014"],["Time",when(r.started_at)]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Snippet"})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:parts2.map((p,i)=>p.hi?$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:p.text})},i):$jsx("span",{fg:theme.text,children:p.text},i))})})]})})})}),HeaderRow=import_react53.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:8,fg:fg2,bold:!0,children:"Start"}),$jsx(Col,{w:10,fg:fg2,bold:!0,right:!0,children:"Active"}),$jsx(Col,{w:7,fg:fg2,bold:!0,right:!0,children:"Msgs"}),$jsx("box",{width:3})]})}),Item=import_react53.memo((props)=>{let theme=useTheme().theme,{row:r,idx:i}=props,[x2,setX]=import_react53.useState(!1),active=r.detail?.last_active??r.detail?.ended_at??null,leader=props.indent?"\u2514\u2500":props.selected?"\u25B8 ":" ",muted=props.indent&&!props.selected?theme.textMuted:void 0;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:muted??theme.text,children:leader}),$jsx(Marquee,{grow:!0,active:props.selected,fg:props.selected?theme.accent:muted??theme.text,bold:props.selected,children:r.title||"Untitled"}),$jsx(Col,{w:9,fg:muted??theme.info,children:badge(r.source??"")}),$jsx(Col,{w:8,fg:theme.textMuted,children:stamp(r.started_at)}),$jsx(Col,{w:10,fg:theme.textMuted,right:!0,children:active?ago(active):"\u2014"}),$jsx(Col,{w:7,fg:theme.textMuted,right:!0,children:String(r.message_count)}),props.indent?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{children:$jsx("span",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})})]})}),SearchHeaderRow=import_react53.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:10,fg:fg2,bold:!0,children:"When"}),$jsx(Col,{w:20,fg:fg2,bold:!0,children:"Model"})]})}),SearchItem=import_react53.memo((props)=>{let theme=useTheme().theme,{result:r,idx:i}=props;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,bold:props.selected,children:r.title??"Untitled"}),$jsx(Col,{w:9,fg:theme.info,children:badge(r.source)}),$jsx(Col,{w:10,fg:theme.textMuted,children:ago(r.started_at)}),$jsx(Col,{w:20,fg:theme.textMuted,children:r.model??"\u2014"})]})}),last={rows:[],kids:new Map},Sessions=import_react53.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),cached2=props.io==null,io2={list:props.io?.list??io.roots,search:props.io?.search??io.search,subagents:props.io?.subagents??io.children,lineage:props.io?.lineage??io.lineage,peek:props.io?.peek??io.peek,remove:props.io?.remove??remove,rename:props.io?.rename??rename},[rows2,setRows]=import_react53.useState(cached2?last.rows:[]),[warn,setWarn]=import_react53.useState(""),[pending2,setPending]=import_react53.useState(rows2.length===0),[anchor,setAnchor]=import_react53.useState(null),[searching,setSearching]=import_react53.useState(!1),[query,setQuery]=import_react53.useState(""),[results,setResults]=import_react53.useState([]),[searchSel,setSearchSel]=import_react53.useState(0),[kids,setKids]=import_react53.useState(cached2?last.kids:new Map),debounce=import_react53.useRef(null),vscroll=import_react53.useRef(null),anchored=anchor&&rows2.find((r)=>r.id===anchor.id),owner=anchor?.indent?rows2.find((r)=>kids.get(r.id)?.some((c)=>c.id===anchor.id)):(anchored?.detail?.subagent_count??0)>0?anchored:void 0,visible=rows2.flatMap((r,i)=>r.id===owner?.id?[{row:r,indent:!1,parentIdx:i},...(kids.get(r.id)??[]).map((c)=>({row:c,indent:!0,parentIdx:i}))]:[{row:r,indent:!1,parentIdx:i}]),sel=anchor?Math.max(0,visible.findIndex((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)):0,live=import_react53.useRef({rows:rows2,visible,anchor,results,searching,onSwitch:props.onSwitch,currentId:props.currentId});live.current={rows:rows2,visible,anchor,results,searching,onSwitch:props.onSwitch,currentId:props.currentId};let setSel=import_react53.useCallback((arg)=>{let cur=live.current,prev=cur.visible.findIndex((v3)=>v3.row.id===cur.anchor?.id&&v3.indent===cur.anchor.indent),n=typeof arg==="function"?arg(Math.max(0,prev)):arg,v2=cur.visible[Math.max(0,Math.min(cur.visible.length-1,n))];if(v2)setAnchor({id:v2.row.id,indent:v2.indent})},[]),LIMIT=2000,toRow2=(d2)=>({id:d2.id,title:d2.title??"",preview:d2.lastMessage??"",message_count:d2.message_count,started_at:d2.started_at,source:d2.sessionSource,detail:d2}),load3=import_react53.useCallback(async()=>{setPending(!0);let rpc=gw.request("session.list",{limit:LIMIT}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),disk=await Promise.resolve(io2.list(LIMIT)).catch(()=>[]),local=new Map(disk.map((r2)=>[r2.id,r2])),diskRows=disk.filter((d2)=>d2.message_count>0).map(toRow2);if(setRows(diskRows),cached2)last.rows=diskRows;let fillKids=async(list)=>{let ps=list.filter((r2)=>(r2.detail?.subagent_count??0)>0),cs=await Promise.all(ps.map((r2)=>io2.subagents(r2.id))),m2=new Map(ps.map((r2,i)=>[r2.id,cs[i].map(toRow2)]));if(setKids(m2),cached2)last.kids=m2};fillKids(diskRows);let r=await rpc;if(r.ok&&r.v.sessions?.length){let seen=new Set(diskRows.map((s)=>s.id)),merged=[...diskRows,...r.v.sessions.filter((s)=>(s.message_count??0)>0&&!seen.has(s.id)).map((s)=>({...s,detail:local.get(s.id)}))].sort((a,b2)=>b2.started_at-a.started_at);if(setRows(merged),cached2)last.rows=merged;fillKids(merged)}setPending(!1),setWarn(!r.ok?local.size?`gateway session.list failed (${r.e.message}) \u2014 listing state.db directly; rows may not resume`:r.e.message:"")},[gw]);import_react53.useEffect(()=>{load3()},[load3]),import_react53.useEffect(()=>{if(!anchor&&rows2.length)setAnchor({id:rows2[0].id,indent:!1})},[rows2,anchor]),import_react53.useEffect(()=>{if(!searching||!query.trim()){setResults([]);return}return debounce.current=setTimeout(()=>{Promise.resolve(io2.search(query,30)).then((r)=>{setResults(r),setSearchSel(0)})},150),()=>{if(debounce.current)clearTimeout(debounce.current)}},[query,searching]);let rowHover=import_react53.useCallback((i)=>{live.current.searching?setSearchSel(i):setSel(i)},[setSel]),rowActivate=import_react53.useCallback((i)=>{let l=live.current;l.searching?setSearchSel(i):setSel(i);let hit=l.searching?l.results[i]:l.visible[i]?.row,id=l.searching?hit?.session_id:hit?.id;if(!id||!l.onSwitch)return;if(id===l.currentId)return l.onSwitch(id);let title=hit?.title||"Untitled",n=l.searching?void 0:hit.message_count;openConfirm(dialog,{title:"Load session?",body:`${trunc4(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
4104
+ `)){if(line.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line.match(/^\s{4}- \S+:/)){let last=Object.keys(cats).pop();if(last)cats[last]++}}let sorted=Object.entries(cats).sort((a,b2)=>b2[1]-a[1]),total=sorted.reduce((s,[,n])=>s+n,0);return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("skills",theme),children:"\u25FC"})," Skills Catalog \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsxs("text",{children:[total," skills in ",sorted.length," categories \xB7 ",sec.chars.toLocaleString()," chars"]}),$jsx("text",{fg:theme.textMuted,children:"Largest context section \u2014 skill names + descriptions injected every turn."}),$jsx("text",{children:" "}),sorted.map(([cat,n])=>$jsxs("text",{fg:theme.text,children:["\xB7 ",cat," (",n,")"]},cat))]})}),ToolsPanel=import_react48.memo(({seg,theme,tools,kind})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label=kind==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind==="mcp_tools"?"MCP-loaded tools \u2014 schemas injected via mcp_ prefix.":"Built-in tool schemas sent with every API call.";return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(kind,theme),children:"\u25FC"})," ",label," \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:[tools.length," tools \u2014 ",blurb]}),$jsx("text",{children:" "}),sorted.map((t2)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",t2.name," (",fmt(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react48.memo(({seg,theme,messages,output})=>{let user=messages.filter((m2)=>m2.role==="user"),asst=messages.filter((m2)=>m2.role==="assistant"),non=messages.filter((m2)=>m2.role!=="system");return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("conversation",theme),children:"\u25FC"})," Conversation \u2014 ",fmt(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt(est(user.map((m2)=>text(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt(est(asst.map((m2)=>text(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment2,{children:[$jsx("text",{fg:theme.info,children:"Messages:"}),$jsx("text",{children:" "}),non.map((m2,i)=>$jsxs("text",{children:[$jsx("span",{fg:m2.role==="user"?theme.info:theme.success,children:m2.role==="user"?"\u25B8 You":"\u25C2 Agent"})," ","(",fmt(est(text(m2))),") ",text(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react48.memo(({seg,theme,ctxLen,comp,onEditThreshold})=>{let used=ctxLen-seg.tokens,threshold=Math.round(ctxLen*(comp?.threshold??0.5)),pct=threshold>0?Math.min(100,Math.round(used/threshold*100)):0;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("free",theme),children:"\u25FB"})," Free Space \u2014 ",fmt(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment2,{children:[$jsx("text",{children:$jsx("strong",{children:"Compression"})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsxs("text",{children:[comp.enabled?"\u2713 Enabled":"\u2717 Disabled"," \xB7 threshold "]}),$jsx("box",{flexShrink:0,onMouseDown:onEditThreshold,children:$jsx("text",{fg:theme.info,children:$jsxs("u",{children:[Math.round(comp.threshold*100),"%"]})})}),$jsxs("text",{children:[" (",fmt(threshold),")"]})]}),$jsxs("text",{children:[bar(pct)," ",pct,"%"]}),$jsxs("text",{children:["Protect last ",comp.protect_last_n," messages \xB7 target ratio ",Math.round(comp.target_ratio*100),"%"]}),comp.summary_model?$jsxs("text",{children:["Summary model: ",comp.summary_model]}):null]}):null]})}),NO_MESSAGES=Object.freeze([]),Context=import_react48.memo(({messages=NO_MESSAGES,info,focused})=>{let config=useHome("config"),memory=useHome("memory"),userProfile=useHome("userProfile"),gw=useGateway(),dialog=useDialog(),toast=useToast(),systemPrompt2=useHome("systemPrompt"),toolsInfo=useHome("toolsInfo"),soul=useHome("soul"),recentSessions=useHome("recentSessions"),liveSessions=useHome("liveSessions"),[wire,setWire]=import_react48.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react48.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react48.useState(null),[selected,setSelected]=import_react48.useState(null),[drilled,setDrilled]=import_react48.useState(null);import_react48.useEffect(()=>{let input=0,output2=0,total=0,calls=0;for(let m2 of messages)if(m2.usage)input+=m2.usage.input,output2+=m2.usage.output,total+=m2.usage.total,calls++;let next={input,output:output2,total,calls};wireRef.current=next,setWire(next)},[messages]);let session=recentSessions?.[0],ctxLen=info?.context_max??DEFAULT_CTX,lastPrompt=(session?Object.values(liveSessions??{}).find((ls)=>ls.session_id===session.id):void 0)?.last_prompt_tokens??0,fill=wire.calls>0?wire.input:lastPrompt>0?lastPrompt:session?.input_tokens??0,cumulative=wire.calls===0&&lastPrompt===0&&(session?.input_tokens??0)>0,output=wire.calls>0?wire.output:session?.output_tokens??0,pct=ctxLen>0?Math.round(fill/ctxLen*100):0,thresholdPct=config?.compression?.threshold??0.5,thresholdIdx=Math.min(COLS2*COLS2,Math.max(0,Math.round(thresholdPct*COLS2*COLS2))),compressions=info?.usage?.compressions??0,promptText=info?.system_prompt??systemPrompt2?.text??"",sections=import_react48.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react48.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text(m2)).join("")),[messages]),top=import_react48.useMemo(()=>build({contextLength:ctxLen,inputTokens:fill,sections,conversationTokens:convTok,tools:toolsInfo?.tools??[]}),[ctxLen,fill,sections,convTok,toolsInfo?.tools]),drilledGroup=drilled?top.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top,grid=import_react48.useMemo(()=>cells(view,drilledGroup?drilledGroup.children?.[0]?.id??"other":"free"),[view,drilledGroup]),findSeg=(id)=>{if(drilledGroup)return view.find((s)=>s.id===id);return top.find((s)=>s.id===id)},memEntries=import_react48.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react48.useMemo(()=>(userProfile?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[userProfile?.content]),click=(id)=>{if(drilled){setSelected(selected===id?null:id);return}let seg=top.find((s)=>s.id===id);if(seg?.children&&seg.children.length>0){setDrilled(id),setSelected(null);return}setSelected(selected===id?null:id)},lastEsc=import_react48.useRef(0),segs=view.filter((s)=>s.tokens>0),idx3=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx3):v2));setSelected(segs[n]?.id??null)},keys=useKeys();useKeyboard((key2)=>{if(!focused||dialog.open())return;if(handleListKey(keys,key2,{count:segs.length,setSel,onActivate:()=>{if(drilled||!selected)return;if(top.find((s)=>s.id===selected)?.children?.length)setDrilled(selected),setSelected(null)}}))return;if(key2.name==="right")return setSel((p)=>p+1);if(key2.name==="left")return setSel((p)=>p-1);if(key2.name!=="escape")return;let now=Date.now();if(now-lastEsc.current<400){setSelected(null),setDrilled(null),lastEsc.current=0;return}if(lastEsc.current=now,selected)return setSelected(null);if(drilled)return setDrilled(null)});let editThreshold=async()=>{let cur=Math.round((config?.compression?.threshold??0.5)*100),v2=await openTextPrompt(dialog,{title:"Compression threshold",label:"Percent (10\u201395)",initial:String(cur)});if(v2===null)return;let n=Math.max(10,Math.min(95,Number(v2)||cur)),{writeConfig:writeConfig2}=await Promise.resolve().then(() => (init_lane(),exports_lane)),r=await writeConfig2(gw,[{key:"compression.threshold",to:n/100}]);if(r.failed.length)return toast.show({variant:"error",message:r.failed[0].err});home2.invalidate("config"),toast.show({variant:"success",message:`Threshold \u2192 ${n}%`})},detail=()=>{if(!selected)return null;let seg=findSeg(selected);if(!seg)return null;if(selected==="memory"&&drilled==="memory"&&memory)return $jsx(MemoryPanel,{seg,theme,label:"Agent Notes",chars:memory.charCount,limit:memory.charLimit,pct:memory.usagePercent,entries:memEntries,source:memory.source});if(selected==="user"&&userProfile)return $jsx(MemoryPanel,{seg,theme,label:"User Profile",chars:userProfile.charCount,limit:userProfile.charLimit,pct:userProfile.usagePercent,entries:userEntries,source:userProfile.source});if(selected==="skills")return $jsx(SkillsPanel,{seg,theme});if(selected==="system_tools"&&toolsInfo){let{system}=classifyTools(toolsInfo.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&&toolsInfo){let{mcp}=classifyTools(toolsInfo.tools);return $jsx(ToolsPanel,{seg,theme,tools:mcp,kind:"mcp_tools"})}if(selected==="soul"&&soul){let soulSeg={...seg,section:{id:"soul",label:"SOUL.md",chars:soul.charCount,tokens:soul.tokenEstimate,text:soul.content,source:soul.source}};return $jsx(SectionPanel,{seg:soulSeg,theme})}if(selected==="conversation")return $jsx(ConvPanel,{seg,theme,messages,output});if(selected==="free")return $jsx(FreePanel,{seg,theme,ctxLen,comp:config?.compression,onEditThreshold:editThreshold});return $jsx(SectionPanel,{seg,theme})},breakdown=()=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsxs("text",{children:[$jsx("strong",{children:"Breakdown"}),drilledGroup?$jsxs("span",{fg:theme.info,children:[" \xB7 ",drilledGroup.label," (",fmt(drilledGroup.tokens)," tok)"]}):$jsx("span",{fg:theme.info,children:" (click group to expand)"})]}),view.filter((s)=>s.tokens>0).map((s)=>$jsxs("text",{children:[$jsx("span",{fg:clr(s.id,theme),children:s.id==="free"?"\u25FB":"\u25FC"})," ",s.label," \u2014 ",fmt(s.tokens)," (",s.percent.toFixed(1),"%)",s.children?$jsx("span",{fg:theme.textMuted,children:" \u25B8"}):null]},s.id)),output>0&&!drilled?$jsxs("text",{children:[$jsx("span",{fg:theme.success,children:"\u25FC"})," Output \u2014 ",fmt(output)," tokens"]}):null,$jsx("text",{children:$jsxs("span",{fg:theme.textMuted,children:["\u25FC Beyond compression threshold (",Math.round(thresholdPct*100),"%)"]})})]}),crumb=drilled?`${drilledGroup?.label}${selected?` \xB7 ${findSeg(selected)?.label}`:""}`:wire.calls===0&&fill===0?"[no data]":cumulative?"[cumulative \u2014 not current fill]":wire.calls===0&&fill>0?"[live session]":"\u2191\u2193 nav \xB7 click a group to drill in",escHint=selected||drilled?" \xB7 Esc back":"",focus=selected||hovered,focusSeg=focus?findSeg(focus):null;return $jsxs(TabShell,{title:`Context \xB7 ${fmt(fill)} / ${fmt(ctxLen)} (${pct}%)`,hint:crumb+escHint,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt(focusSeg.tokens)," tok (",focusSeg.percent.toFixed(1),"%)"]}):$jsx("text",{children:" "})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs("box",{flexDirection:"column",marginRight:2,flexShrink:0,children:[compressions>0?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{fg:theme.warning,children:["\xD7",compressions," compressed"]})}):null,$jsx("box",{border:!0,customBorderChars:CORNERS,borderColor:theme.border,children:[...Array(COLS2)].map((_2,row)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=row*COLS2+col>=thresholdIdx,glyph=!past&&cell.id==="free"?"\u25FB":"\u25FC";return $jsx("box",{height:1,width:2,backgroundColor:hl?clr(cell.id,theme):void 0,onMouseOver:()=>setHovered(cell.id),onMouseOut:()=>setHovered(null),onMouseDown:()=>click(cell.id),children:$jsx("text",{fg:past?theme.textMuted:clr(cell.id,theme),children:glyph})},col)})},row))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]})});var import_react53=__toESM(require_react_production(),1);init_sessions_db();var KV=(props)=>{let theme=useTheme().theme;return $jsxs("box",{minHeight:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:props.wrap?void 0:1,overflow:props.wrap?void 0:"hidden",children:$jsx("text",{wrapMode:props.wrap?"word":void 0,fg:props.fg??theme.text,children:props.value})})]})},KVBlock=(props)=>props.rows.map(([k2,v2,fg2])=>v2===void 0?null:$jsx(KV,{label:k2,value:v2,fg:fg2},k2));var import_react50=__toESM(require_react_production(),1);var VBAR_W=1,VBAR={visible:!0},Col=(p)=>{let theme=useTheme().theme,fg2=p.fg??theme.text;return $jsx("box",{width:p.w,flexGrow:p.grow?1:0,flexShrink:p.grow?1:0,minWidth:p.grow?p.min??12:p.w,height:1,overflow:"hidden",flexDirection:"row",justifyContent:p.right?"flex-end":"flex-start",children:$jsx("text",{children:p.bold?$jsx("span",{fg:fg2,children:$jsx("strong",{children:p.children})}):$jsx("span",{fg:fg2,children:p.children})})})},Hdr=(p)=>$jsx("box",{flexDirection:"row",height:1,paddingRight:VBAR_W,children:p.children}),Marquee=(p)=>{let theme=useTheme().theme,fg2=p.fg??theme.text,text2=p.children,box=import_react50.useRef(null),node=import_react50.useRef(null),animate=get("animations")!==!1&&p.active,[wraps,setWraps]=import_react50.useState(!1);import_react50.useEffect(()=>{let tn=node.current;if(!tn)return;let w2=box.current?.width??0;if(setWraps(text2.length>w2),!animate){tn.scrollX=0;return}let id,period=text2.length+GAP.length,hold=setTimeout(()=>{id=setInterval(()=>{let cur=box.current?.width??0;if(text2.length<=cur){tn.scrollX=0;return}tn.scrollX=(tn.scrollX+1)%period},p.speed??180)},p.hold??600);return()=>{if(clearTimeout(hold),id)clearInterval(id);if(node.current)node.current.scrollX=0}},[animate,text2,p.speed,p.hold]);let body=wraps?text2+GAP+text2:text2;return $jsx("box",{ref:box,width:p.w,flexGrow:p.grow?1:0,flexShrink:p.grow?1:0,minWidth:p.grow?p.min??12:p.w,height:1,overflow:"hidden",children:$jsx("text",{ref:node,wrapMode:"none",children:p.bold?$jsx("span",{fg:fg2,children:$jsx("strong",{children:body})}):$jsx("span",{fg:fg2,children:body})})})},GAP=" ";var import_react51=__toESM(require_react_production(),1);var Ticker=(p)=>{let ref=import_react51.useRef(null),animate=get("animations")!==!1&&p.active,speed=p.speed??180,hold=p.hold??600,endHold=p.endHold??3000;return import_react51.useEffect(()=>{let node=ref.current;if(!node)return;if(!animate){node.scrollX=0;return}let dir=1,tick2,wait,step=()=>{let max=node.maxScrollX;if(max<=0)return;if(node.scrollX=Math.max(0,Math.min(max,node.scrollX+dir)),!(dir>0?node.scrollX>=max:node.scrollX<=0))return;if(tick2)clearInterval(tick2),tick2=void 0;dir=-dir,wait=setTimeout(()=>{tick2=setInterval(step,speed)},endHold)};return wait=setTimeout(()=>{tick2=setInterval(step,speed)},hold),()=>{if(wait)clearTimeout(wait);if(tick2)clearInterval(tick2);if(ref.current)ref.current.scrollX=0}},[animate,speed,hold,endHold]),$jsx("box",{flexGrow:1,flexShrink:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{ref,wrapMode:"none",fg:p.fg,children:p.children})})},RX=/(`[^`]+`)|(\*\*[^*]+\*\*)|(__[^_]+__)|((?<![\w*])\*[^*\s][^*]*\*(?![\w*]))|((?<!\w)_[^_\s][^_]*_(?!\w))/g,inline=(s)=>{let out=[],last=0;for(let m2 of s.matchAll(RX)){let at=m2.index??0;if(at>last)out.push({t:s.slice(last,at)});let hit=m2[0];if(hit.startsWith("`"))out.push({t:hit.slice(1,-1),c:!0});else if(hit.startsWith("**")||hit.startsWith("__"))out.push({t:hit.slice(2,-2),b:!0});else out.push({t:hit.slice(1,-1),i:!0});last=at+hit.length}if(last<s.length)out.push({t:s.slice(last)});return out.map((seg)=>seg.c?seg:{...seg,t:seg.t.replace(/^#{1,6}\s+/,"")})};var Confirm=(props)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key2)=>{if(keys.match("dialog.confirm",key2)||keys.match("dialog.accept",key2))return props.onConfirm();if(keys.match("dialog.deny",key2)||keys.match("dialog.cancel",key2))return props.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:props.danger?theme.warning:theme.primary,children:$jsx("strong",{children:props.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:props.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}/${keys.print("dialog.accept")}] ${props.yes??"confirm"} [${keys.print("dialog.deny")}] ${props.no??"cancel"}`})})]})};function openConfirm(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Confirm,{...opts,onConfirm:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}))})}var h12=()=>get("timeFormat")==="12h",abs=()=>get("timeStyle")==="absolute",trunc4=(s,max)=>s.length<=max?s:s.slice(0,max-1)+"\u2026",fmt2=(n)=>n>=1e6?`${(n/1e6).toFixed(2)}M`:n>=1000?`${(n/1000).toFixed(1)}k`:String(n),cost=(c)=>c==null?"\u2014":`$${c.toFixed(2)}`,clock=(d2)=>d2.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:h12()}),stamp=(ts)=>{let d2=new Date(ts*1000);return d2.toDateString()===new Date().toDateString()?clock(d2):d2.toLocaleDateString(void 0,{month:"short",day:"numeric"})},rel=(ts)=>{let s=Math.floor(Date.now()/1000-ts);if(s<60)return"just now";if(s<3600)return`${Math.floor(s/60)}m ago`;if(s<86400)return`${Math.floor(s/3600)}h ago`;return`${Math.floor(s/86400)}d ago`},ago=(ts)=>abs()?stamp(ts):rel(ts),until=(ts)=>{if(abs())return ts<=Date.now()/1000?"due":stamp(ts);let s=Math.floor(ts-Date.now()/1000);if(s<=0)return"due";if(s<60)return`in ${s}s`;if(s<3600)return`in ${Math.floor(s/60)}m`;if(s<86400)return`in ${Math.floor(s/3600)}h`;return`in ${Math.floor(s/86400)}d`},when=(ts)=>{let d2=new Date(ts*1000);return`${d2.toLocaleDateString()} ${clock(d2)}`},span=(start2,end)=>{let s=Math.round(end-start2);if(s<0)return"\u2014";if(s>=3600)return`${Math.floor(s/3600)}h ${Math.floor(s%3600/60)}m`;if(s>=60)return`${Math.floor(s/60)}m`;return`${s}s`},dur2=(s)=>s>=3600?`${Math.floor(s/3600)}h${Math.floor(s%3600/60)}m`:s>=60?`${Math.floor(s/60)}m${Math.floor(s%60)}s`:`${Math.floor(s)}s`;var badge=(src)=>({cli:"CLI",tui:"TUI",api_server:"API",discord:"Discord",telegram:"Telegram",slack:"Slack",whatsapp:"WhatsApp",signal:"Signal"})[src]??src,line=(s)=>(s??"").replace(/\s+/g," ").trim(),fold=(msgs)=>{let turns=[],tools=0;for(let m2 of msgs){if(m2.role==="tool"){tools++;continue}if(m2.role!=="user"&&m2.role!=="assistant")continue;let text2=line(m2.content);if(!text2)continue;turns.push({role:m2.role,text:text2})}return{turns,tools}},PeekRow=import_react53.memo((props)=>{let theme=useTheme().theme,[hot,setHot]=import_react53.useState(!1),left=props.row.role==="user",color=left?theme.primary:theme.accent,fg2=left?theme.text:theme.markdownText,bar2=(side)=>$jsx("box",{width:2,flexShrink:0,height:1,border:[side],borderColor:color,customBorderChars:SIDE_PIPE});return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:hot?theme.backgroundElement:void 0,onMouseOver:()=>setHot(!0),onMouseOut:()=>setHot(!1),children:[left?bar2("left"):null,$jsx(Ticker,{active:hot,speed:35,hold:150,fg:fg2,children:inline(props.row.text).map((s,i)=>s.c?$jsx("span",{fg:theme.warning,children:s.t},i):s.b?$jsx("span",{fg:fg2,children:$jsx("strong",{children:s.t})},i):s.i?$jsx("span",{fg:fg2,children:$jsx("u",{children:s.t})},i):$jsx("span",{fg:fg2,children:s.t},i))}),left?null:bar2("right")]})}),Peek=import_react53.memo((props)=>{let theme=useTheme().theme,[data2,setData]=import_react53.useState(null),sb=import_react53.useRef(null);if(import_react53.useEffect(()=>{Promise.resolve(props.peek(props.sid,60)).then((m2)=>setData(fold(m2)))},[props.sid,props.peek]),import_react53.useEffect(()=>{if(data2&&sb.current)sb.current.scrollTop=sb.current.scrollHeight},[data2]),data2===null)return null;if(data2.turns.length===0&&data2.tools===0)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local transcript)"})});let more=Math.max(0,props.total-60);return $jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:5,border:!0,borderStyle:"single",borderColor:theme.border,title:` Transcript${more>0?` \xB7 ${more} earlier`:""} `,titleAlignment:"left",children:[$jsx("scrollbox",{ref:sb,scrollY:!0,flexGrow:1,minHeight:3,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.turns.map((r,i)=>$jsx(PeekRow,{row:r},i))})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${data2.turns.length} turn${data2.turns.length===1?"":"s"} \xB7 ${data2.tools} tool call${data2.tools===1?"":"s"}`})})]})}),Detail=import_react53.memo((props)=>{let theme=useTheme().theme,r=props.row,d2=r.detail,lastActive=d2?.last_active??d2?.ended_at??null,subs2=d2?.subagent_count??0,[info,setInfo]=import_react53.useState({});import_react53.useEffect(()=>{Promise.resolve(props.lineage(r.id)).then(setInfo)},[r.id,props.lineage]);let hasLineage=info.continuesFrom||info.compressedTo||subs2>0,go=(sid)=>()=>props.onSwitch?.(sid);return $jsx(TabShell,{title:"Session Detail",hint:"",grow:2,children:$jsxs("box",{flexDirection:"column",width:"100%",flexGrow:1,overflow:"hidden",children:[$jsxs("box",{flexDirection:"column",flexShrink:0,children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title||"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",r.id],["Source",badge(r.source??"")],["Model",d2?.model??"\u2014"],["Started",when(r.started_at)],["Last active",lastActive?`${when(lastActive)} (${ago(lastActive)})`:"\u2014"],["Duration",lastActive?span(r.started_at,lastActive):"\u2014"],["Ended",d2?.ended_at?`${when(d2.ended_at)} \xB7 ${d2.end_reason??"\u2014"}`:void 0]]}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Messages",String(r.message_count)],["Tool calls",d2?String(d2.tool_call_count):void 0],["Input",d2?`${fmt2(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt2(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt2(d2.cache_read_tokens)} r / ${fmt2(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt2(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment2,{children:[$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,children:"Lineage"})}),info.continuesFrom?$jsx("box",{height:1,onMouseDown:go(info.continuesFrom.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2190 continues from "}),$jsx("span",{fg:theme.accent,children:info.continuesFrom.title||info.continuesFrom.id})]})}):null,info.compressedTo?$jsx("box",{height:1,onMouseDown:go(info.compressedTo.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2192 compressed to "}),$jsx("span",{fg:theme.accent,children:info.compressedTo.title||info.compressedTo.id})]})}):null,subs2>0?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2387 spawned "}),$jsx("span",{fg:theme.text,children:String(subs2)}),$jsx("span",{fg:theme.textMuted,children:` subagent${subs2===1?"":"s"}`})]})}):null]}):null,!d2?$jsxs($Fragment2,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local detail \u2014 state.db mismatch)"})})]}):null,$jsx("box",{height:1})]}),$jsx(Peek,{sid:r.id,total:r.message_count,peek:props.peek})]})})}),SearchDetail=import_react53.memo((props)=>{let theme=useTheme().theme,r=props.result,parts2=[],rest=r.snippet;while(rest.length){let start2=rest.indexOf(">>>");if(start2<0){parts2.push({text:rest,hi:!1});break}if(start2>0)parts2.push({text:rest.slice(0,start2),hi:!1});let end=rest.indexOf("<<<",start2+3);if(end<0){parts2.push({text:rest.slice(start2+3),hi:!0});break}parts2.push({text:rest.slice(start2+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",hint:"",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title??"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Source",badge(r.source)],["Model",r.model??"\u2014"],["Time",when(r.started_at)]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Snippet"})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:parts2.map((p,i)=>p.hi?$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:p.text})},i):$jsx("span",{fg:theme.text,children:p.text},i))})})]})})})}),HeaderRow=import_react53.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:8,fg:fg2,bold:!0,children:"Start"}),$jsx(Col,{w:10,fg:fg2,bold:!0,right:!0,children:"Active"}),$jsx(Col,{w:7,fg:fg2,bold:!0,right:!0,children:"Msgs"}),$jsx("box",{width:3})]})}),Item=import_react53.memo((props)=>{let theme=useTheme().theme,{row:r,idx:i}=props,[x2,setX]=import_react53.useState(!1),active=r.detail?.last_active??r.detail?.ended_at??null,leader=props.indent?"\u2514\u2500":props.selected?"\u25B8 ":" ",muted=props.indent&&!props.selected?theme.textMuted:void 0;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:muted??theme.text,children:leader}),$jsx(Marquee,{grow:!0,active:props.selected,fg:props.selected?theme.accent:muted??theme.text,bold:props.selected,children:r.title||"Untitled"}),$jsx(Col,{w:9,fg:muted??theme.info,children:badge(r.source??"")}),$jsx(Col,{w:8,fg:theme.textMuted,children:stamp(r.started_at)}),$jsx(Col,{w:10,fg:theme.textMuted,right:!0,children:active?ago(active):"\u2014"}),$jsx(Col,{w:7,fg:theme.textMuted,right:!0,children:String(r.message_count)}),props.indent?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{children:$jsx("span",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})})]})}),SearchHeaderRow=import_react53.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:10,fg:fg2,bold:!0,children:"When"}),$jsx(Col,{w:20,fg:fg2,bold:!0,children:"Model"})]})}),SearchItem=import_react53.memo((props)=>{let theme=useTheme().theme,{result:r,idx:i}=props;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,bold:props.selected,children:r.title??"Untitled"}),$jsx(Col,{w:9,fg:theme.info,children:badge(r.source)}),$jsx(Col,{w:10,fg:theme.textMuted,children:ago(r.started_at)}),$jsx(Col,{w:20,fg:theme.textMuted,children:r.model??"\u2014"})]})}),last={rows:[],kids:new Map},Sessions=import_react53.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),cached2=props.io==null,io2={list:props.io?.list??io.roots,search:props.io?.search??io.search,subagents:props.io?.subagents??io.children,lineage:props.io?.lineage??io.lineage,peek:props.io?.peek??io.peek,remove:props.io?.remove??remove,rename:props.io?.rename??rename},[rows2,setRows]=import_react53.useState(cached2?last.rows:[]),[warn,setWarn]=import_react53.useState(""),[pending2,setPending]=import_react53.useState(rows2.length===0),[anchor,setAnchor]=import_react53.useState(null),[searching,setSearching]=import_react53.useState(!1),[query,setQuery]=import_react53.useState(""),[results,setResults]=import_react53.useState([]),[searchSel,setSearchSel]=import_react53.useState(0),[kids,setKids]=import_react53.useState(cached2?last.kids:new Map),debounce=import_react53.useRef(null),vscroll=import_react53.useRef(null),anchored=anchor&&rows2.find((r)=>r.id===anchor.id),owner=anchor?.indent?rows2.find((r)=>kids.get(r.id)?.some((c)=>c.id===anchor.id)):(anchored?.detail?.subagent_count??0)>0?anchored:void 0,visible=rows2.flatMap((r,i)=>r.id===owner?.id?[{row:r,indent:!1,parentIdx:i},...(kids.get(r.id)??[]).map((c)=>({row:c,indent:!0,parentIdx:i}))]:[{row:r,indent:!1,parentIdx:i}]),sel=anchor?Math.max(0,visible.findIndex((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)):0,live=import_react53.useRef({rows:rows2,visible,anchor,results,searching,onSwitch:props.onSwitch,currentId:props.currentId});live.current={rows:rows2,visible,anchor,results,searching,onSwitch:props.onSwitch,currentId:props.currentId};let setSel=import_react53.useCallback((arg)=>{let cur=live.current,prev=cur.visible.findIndex((v3)=>v3.row.id===cur.anchor?.id&&v3.indent===cur.anchor.indent),n=typeof arg==="function"?arg(Math.max(0,prev)):arg,v2=cur.visible[Math.max(0,Math.min(cur.visible.length-1,n))];if(v2)setAnchor({id:v2.row.id,indent:v2.indent})},[]),LIMIT=2000,toRow2=(d2)=>({id:d2.id,title:d2.title??"",preview:d2.lastMessage??"",message_count:d2.message_count,started_at:d2.started_at,source:d2.sessionSource,detail:d2}),load3=import_react53.useCallback(async()=>{setPending(!0);let rpc=gw.request("session.list",{limit:LIMIT}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),disk=await Promise.resolve(io2.list(LIMIT)).catch(()=>[]),local=new Map(disk.map((r2)=>[r2.id,r2])),diskRows=disk.filter((d2)=>d2.message_count>0).map(toRow2);if(setRows(diskRows),cached2)last.rows=diskRows;let fillKids=async(list)=>{let ps=list.filter((r2)=>(r2.detail?.subagent_count??0)>0),cs=await Promise.all(ps.map((r2)=>io2.subagents(r2.id))),m2=new Map(ps.map((r2,i)=>[r2.id,cs[i].map(toRow2)]));if(setKids(m2),cached2)last.kids=m2};fillKids(diskRows);let r=await rpc;if(r.ok&&r.v.sessions?.length){let seen=new Set(diskRows.map((s)=>s.id)),merged=[...diskRows,...r.v.sessions.filter((s)=>(s.message_count??0)>0&&!seen.has(s.id)).map((s)=>({...s,detail:local.get(s.id)}))].sort((a,b2)=>b2.started_at-a.started_at);if(setRows(merged),cached2)last.rows=merged;fillKids(merged)}setPending(!1),setWarn(!r.ok?local.size?`gateway session.list failed (${r.e.message}) \u2014 listing state.db directly; rows may not resume`:r.e.message:"")},[gw]);import_react53.useEffect(()=>{load3()},[load3]),import_react53.useEffect(()=>{if(!anchor&&rows2.length)setAnchor({id:rows2[0].id,indent:!1})},[rows2,anchor]),import_react53.useEffect(()=>{if(!searching||!query.trim()){setResults([]);return}return debounce.current=setTimeout(()=>{Promise.resolve(io2.search(query,30)).then((r)=>{setResults(r),setSearchSel(0)})},150),()=>{if(debounce.current)clearTimeout(debounce.current)}},[query,searching]);let rowHover=import_react53.useCallback((i)=>{live.current.searching?setSearchSel(i):setSel(i)},[setSel]),rowActivate=import_react53.useCallback((i)=>{let l=live.current;l.searching?setSearchSel(i):setSel(i);let hit=l.searching?l.results[i]:l.visible[i]?.row,id=l.searching?hit?.session_id:hit?.id;if(!id||!l.onSwitch)return;if(id===l.currentId)return l.onSwitch(id);let title=hit?.title||"Untitled",n=l.searching?void 0:hit.message_count;openConfirm(dialog,{title:"Load session?",body:`${trunc4(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
4105
4105
 
4106
4106
  Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(id)})},[dialog]),rowDelete=import_react53.useCallback((i)=>{let v2=live.current.visible[i];if(v2&&!v2.indent)confirmDeleteRef.current(v2.row)},[]),lineageSwitch=import_react53.useCallback((sid)=>{let l=live.current;if(!l.onSwitch)return;if(sid===l.currentId)return l.onSwitch(sid);openConfirm(dialog,{title:"Load session?",body:`Switch to ${trunc4(sid,24)}?
4107
4107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "herm-tui",
3
- "version": "1.3.0-dev.5",
3
+ "version": "1.3.0-dev.6",
4
4
  "description": "A modern TUI for Hermes Agent",
5
5
  "license": "MIT",
6
6
  "repository": {