herm-tui 1.8.2-dev.1 → 1.8.2-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +11 -11
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4094,22 +4094,22 @@ tell application "System Events" to get value of property list item "CFBundleNam
|
|
|
4094
4094
|
`),found=!1,updated=lines2.map((line)=>{if(line.startsWith(`${key2}=`))return found=!0,`${key2}=${value}`;return line});if(!found)updated.push(`${key2}=${value}`);await Bun.write(ENV_PATH,updated.join(`
|
|
4095
4095
|
`))}async function removeEnvVar(key2){let text2="";try{text2=await Bun.file(ENV_PATH).text()}catch{return}let lines2=text2.split(`
|
|
4096
4096
|
`).filter((l)=>!l.startsWith(`${key2}=`));await Bun.write(ENV_PATH,lines2.join(`
|
|
4097
|
-
`))}var ENV_CATALOG=[{category:"LLM Providers",keys:["ANTHROPIC_API_KEY","OPENAI_API_KEY","GOOGLE_API_KEY","DEEPSEEK_API_KEY","OPENROUTER_API_KEY","GROQ_API_KEY","MISTRAL_API_KEY","XAI_API_KEY","TOGETHER_API_KEY","FIREWORKS_API_KEY","NOUS_API_KEY"]},{category:"Tool API Keys",keys:["FIRECRAWL_API_KEY","BROWSERBASE_API_KEY","BROWSERBASE_PROJECT_ID","TAVILY_API_KEY","EXA_API_KEY","ELEVENLABS_API_KEY"]},{category:"Messaging",keys:["TELEGRAM_BOT_TOKEN","DISCORD_BOT_TOKEN","SLACK_BOT_TOKEN","SLACK_APP_TOKEN"]},{category:"Agent",keys:["API_SERVER_KEY","MEM0_API_KEY"]}];var SLICES={config:{read:()=>readConfig(),watch:()=>[hermesPath("config.yaml")]},memory:{read:(d2)=>readMemoryFile("MEMORY.md",d2.config?.memory?.memory_char_limit??2200),deps:["config"],watch:()=>[hermesPath("memories/MEMORY.md")]},userProfile:{read:(d2)=>readMemoryFile("USER.md",d2.config?.memory?.user_char_limit??1375),deps:["config"],watch:()=>[hermesPath("memories/USER.md")]},memoryProviders:{read:(d2)=>readMemoryProviders(d2.config?.memory?.provider??""),deps:["config"]},memoryActivity:{read:()=>io.memoryActivity()},env:{read:()=>readEnvFile(),watch:()=>[hermesPath(".env")]},soul:{read:()=>readSoul(),watch:()=>[hermesPath("SOUL.md")]},liveSessions:{read:()=>readLiveSessions(),watch:()=>[hermesPath("sessions/sessions.json")]},recentSessions:{read:()=>io.roots(30)},systemPrompt:{read:()=>io.systemPrompt().then((r)=>r&&{source:makeSource("state.db"),sessionId:r.id,text:r.text,totalChars:r.text.length,tokenEstimate:count2(r.text)}).catch(()=>null)},toolsInfo:{read:()=>readToolsFromLatestSession(),watch:()=>[hermesPath("sessions")]},skillUsage:{read:()=>readSkillUsage(),watch:()=>[hermesPath("skills/.usage.json")]},curatorState:{read:()=>readCuratorState(),watch:()=>[hermesPath("skills/.curator_state")]}},DEPENDENTS=(()=>{let m2=new Map;for(let[k2,s]of Object.entries(SLICES))for(let d2 of s.deps??[]){let arr=m2.get(d2)??[];arr.push(k2),m2.set(d2,arr)}return m2})(),DEBOUNCE_MS=50;class HomeStore{data={};subs=new Map;inflight=new Map;watchers=new Map;debounce=new Map;get(k2){return this.data[k2]}subscribe(k2,cb){let set2=this.subs.get(k2);if(!set2)this.subs.set(k2,set2=new Set);return set2.add(cb),()=>set2.delete(cb)}ensure(k2){if(k2 in this.data)return Promise.resolve(this.data[k2]);let hit=this.inflight.get(k2);if(hit)return hit;let slice=SLICES[k2],p=(async()=>{let deps={};for(let d2 of slice.deps??[])deps[d2]=await this.ensure(d2);let v2=await slice.read(deps);return this.data[k2]=v2,this.startWatch(k2,slice.watch),this.notify(k2),v2})().finally(()=>this.inflight.delete(k2));return this.inflight.set(k2,p),p}invalidate(k2){if(!(k2 in this.data)&&!this.inflight.has(k2))return;if(delete this.data[k2],this.subs.get(k2)?.size)this.ensure(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}close(){for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.subs.clear(),this.inflight.clear(),this.data={}}reset(){for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.inflight.clear(),this.data={};for(let k2 of this.subs.keys())if(this.subs.get(k2)?.size)this.ensure(k2)}notify(k2){let set2=this.subs.get(k2);if(set2)for(let cb of set2)cb()}startWatch(k2,watchFn){if(!watchFn||this.watchers.has(k2))return;let paths=watchFn(),ws=[],fire=()=>{let prev=this.debounce.get(k2);if(prev)clearTimeout(prev);this.debounce.set(k2,setTimeout(()=>this.invalidate(k2),DEBOUNCE_MS))};for(let p of paths){let dir=dirname4(p),name=basename7(p);try{if(existsSync11(p)&&statSync3(p).isDirectory())dir=p,name=null}catch{}if(!existsSync11(dir))continue;try{ws.push(watch2(dir,{persistent:!1},(_ev,f)=>{if(name===null||f===name)fire()}))}catch{}}this.watchers.set(k2,ws)}}var home2=new HomeStore;function useHome(k2){let v2=import_react52.useSyncExternalStore((cb)=>home2.subscribe(k2,cb),()=>home2.get(k2));return import_react52.useEffect(()=>{home2.ensure(k2)},[k2]),v2}var cmp=(s)=>{let k2=(r)=>s==="started"?r.started_at:r.detail?.last_active??r.started_at;return(a,b2)=>k2(b2)-k2(a)},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,bar=(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?bar("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:bar("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",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?`${fmt(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt(d2.cache_read_tokens)} r / ${fmt(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment,{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($Fragment,{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 start=rest.indexOf(">>>");if(start<0){parts2.push({text:rest,hi:!1});break}if(start>0)parts2.push({text:rest.slice(0,start),hi:!1});let end=rest.indexOf("<<<",start+3);if(end<0){parts2.push({text:rest.slice(start+3),hi:!0});break}parts2.push({text:rest.slice(start+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",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((props)=>{let theme=useTheme().theme,fg2=theme.textMuted,on=theme.accent,by=props.sort;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:by==="started"?on:fg2,bold:!0,onClick:()=>props.onSort("started"),children:by==="started"?"Start \u25BE":"Start"}),$jsx(Col,{w:10,fg:by==="active"?on:fg2,bold:!0,right:!0,onClick:()=>props.onSort("active"),children:by==="active"?"Active \u25BE":"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??exports_sessions_db.remove,rename:props.io?.rename??exports_sessions_db.rename},[rows2,setRows]=import_react53.useState(cached2?last.rows:[]),[liveRows,setLiveRows]=import_react53.useState([]),[view,setView]=import_react53.useState("live"),[warn,setWarn]=import_react53.useState(""),[pending3,setPending]=import_react53.useState(rows2.length===0),sort=exports_preferences.usePref("sessions")?.sort??"active",setSort=import_react53.useCallback((s)=>exports_preferences.set("sessions",{sort:s}),[]),showingLive=view==="live"&&liveRows.length>0,listed=showingLive?liveRows:rows2,sorted=import_react53.useMemo(()=>showingLive?liveRows:[...rows2].sort(cmp(sort)),[showingLive,liveRows,rows2,sort]),[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&&sorted.find((r)=>r.id===anchor.id),owner=anchor?.indent?sorted.find((r)=>kids.get(r.id)?.some((c)=>c.id===anchor.id)):(anchored?.detail?.subagent_count??0)>0?anchored:void 0,visible=sorted.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:listed,visible,anchor,results,searching,showingLive,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId});live.current={rows:listed,visible,anchor,results,searching,showingLive,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,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}),toLiveRow=(s)=>({id:s.id,title:s.title||s.preview||s.id,preview:s.preview??"",message_count:s.message_count??0,started_at:s.started_at??s.last_active??0,source:"live",live:s}),load4=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})),active=gw.request("session.active_list",{current_session_id:props.currentId}).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(list2)=>{let ps=list2.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 a=await active;if(a.ok){let live2=(a.v.sessions??[]).map(toLiveRow);if(setLiveRows(live2),live2.length===0)setView((v2)=>v2==="live"?"history":v2)}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)}))];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,props.currentId]);import_react53.useEffect(()=>{load4()},[load4]),import_react53.useEffect(()=>{if(!anchor&&sorted.length)setAnchor({id:sorted[0].id,indent:!1})},[sorted,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)return;if(l.showingLive&&!l.searching)return l.onActivateLive?.(id);if(!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:`${trunc5(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
|
|
4097
|
+
`))}var ENV_CATALOG=[{category:"LLM Providers",keys:["ANTHROPIC_API_KEY","OPENAI_API_KEY","GOOGLE_API_KEY","DEEPSEEK_API_KEY","OPENROUTER_API_KEY","GROQ_API_KEY","MISTRAL_API_KEY","XAI_API_KEY","TOGETHER_API_KEY","FIREWORKS_API_KEY","NOUS_API_KEY"]},{category:"Tool API Keys",keys:["FIRECRAWL_API_KEY","BROWSERBASE_API_KEY","BROWSERBASE_PROJECT_ID","TAVILY_API_KEY","EXA_API_KEY","ELEVENLABS_API_KEY"]},{category:"Messaging",keys:["TELEGRAM_BOT_TOKEN","DISCORD_BOT_TOKEN","SLACK_BOT_TOKEN","SLACK_APP_TOKEN"]},{category:"Agent",keys:["API_SERVER_KEY","MEM0_API_KEY"]}];var SLICES={config:{read:()=>readConfig(),watch:()=>[hermesPath("config.yaml")]},memory:{read:(d2)=>readMemoryFile("MEMORY.md",d2.config?.memory?.memory_char_limit??2200),deps:["config"],watch:()=>[hermesPath("memories/MEMORY.md")]},userProfile:{read:(d2)=>readMemoryFile("USER.md",d2.config?.memory?.user_char_limit??1375),deps:["config"],watch:()=>[hermesPath("memories/USER.md")]},memoryProviders:{read:(d2)=>readMemoryProviders(d2.config?.memory?.provider??""),deps:["config"]},memoryActivity:{read:()=>io.memoryActivity()},env:{read:()=>readEnvFile(),watch:()=>[hermesPath(".env")]},soul:{read:()=>readSoul(),watch:()=>[hermesPath("SOUL.md")]},liveSessions:{read:()=>readLiveSessions(),watch:()=>[hermesPath("sessions/sessions.json")]},recentSessions:{read:()=>io.roots(30)},systemPrompt:{read:()=>io.systemPrompt().then((r)=>r&&{source:makeSource("state.db"),sessionId:r.id,text:r.text,totalChars:r.text.length,tokenEstimate:count2(r.text)}).catch(()=>null)},toolsInfo:{read:()=>readToolsFromLatestSession(),watch:()=>[hermesPath("sessions")]},skillUsage:{read:()=>readSkillUsage(),watch:()=>[hermesPath("skills/.usage.json")]},curatorState:{read:()=>readCuratorState(),watch:()=>[hermesPath("skills/.curator_state")]}},DEPENDENTS=(()=>{let m2=new Map;for(let[k2,s]of Object.entries(SLICES))for(let d2 of s.deps??[]){let arr=m2.get(d2)??[];arr.push(k2),m2.set(d2,arr)}return m2})(),DEBOUNCE_MS=50;class HomeStore{data={};subs=new Map;inflight=new Map;watchers=new Map;debounce=new Map;get(k2){return this.data[k2]}subscribe(k2,cb){let set2=this.subs.get(k2);if(!set2)this.subs.set(k2,set2=new Set);return set2.add(cb),()=>set2.delete(cb)}ensure(k2){if(k2 in this.data)return Promise.resolve(this.data[k2]);let hit=this.inflight.get(k2);if(hit)return hit;let slice=SLICES[k2],p=(async()=>{let deps={};for(let d2 of slice.deps??[])deps[d2]=await this.ensure(d2);let v2=await slice.read(deps);return this.data[k2]=v2,this.startWatch(k2,slice.watch),this.notify(k2),v2})().finally(()=>this.inflight.delete(k2));return this.inflight.set(k2,p),p}invalidate(k2){if(!(k2 in this.data)&&!this.inflight.has(k2))return;if(delete this.data[k2],this.subs.get(k2)?.size)this.ensure(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}close(){for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.subs.clear(),this.inflight.clear(),this.data={}}reset(){for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.inflight.clear(),this.data={};for(let k2 of this.subs.keys())if(this.subs.get(k2)?.size)this.ensure(k2)}notify(k2){let set2=this.subs.get(k2);if(set2)for(let cb of set2)cb()}startWatch(k2,watchFn){if(!watchFn||this.watchers.has(k2))return;let paths=watchFn(),ws=[],fire=()=>{let prev=this.debounce.get(k2);if(prev)clearTimeout(prev);this.debounce.set(k2,setTimeout(()=>this.invalidate(k2),DEBOUNCE_MS))};for(let p of paths){let dir=dirname4(p),name=basename7(p);try{if(existsSync11(p)&&statSync3(p).isDirectory())dir=p,name=null}catch{}if(!existsSync11(dir))continue;try{ws.push(watch2(dir,{persistent:!1},(_ev,f)=>{if(name===null||f===name)fire()}))}catch{}}this.watchers.set(k2,ws)}}var home2=new HomeStore;function useHome(k2){let v2=import_react52.useSyncExternalStore((cb)=>home2.subscribe(k2,cb),()=>home2.get(k2));return import_react52.useEffect(()=>{home2.ensure(k2)},[k2]),v2}var cmp=(s)=>{let k2=(r)=>s==="started"?r.started_at:r.detail?.last_active??r.started_at;return(a,b2)=>k2(b2)-k2(a)},badge=(src)=>({cli:"CLI",tui:"TUI",api_server:"API",discord:"Discord",telegram:"Telegram",slack:"Slack",whatsapp:"WhatsApp",signal:"Signal"}[src]??src)||"\u2014",label=(r)=>r.title.trim()||(r.live?"-":"Untitled"),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,bar=(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?bar("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:bar("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",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:label(r)})})})}),$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?`${fmt(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt(d2.cache_read_tokens)} r / ${fmt(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment,{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($Fragment,{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 start=rest.indexOf(">>>");if(start<0){parts2.push({text:rest,hi:!1});break}if(start>0)parts2.push({text:rest.slice(0,start),hi:!1});let end=rest.indexOf("<<<",start+3);if(end<0){parts2.push({text:rest.slice(start+3),hi:!0});break}parts2.push({text:rest.slice(start+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",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((props)=>{let theme=useTheme().theme,fg2=theme.textMuted,on=theme.accent,by=props.sort;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:by==="started"?on:fg2,bold:!0,onClick:()=>props.onSort("started"),children:by==="started"?"Start \u25BE":"Start"}),$jsx(Col,{w:10,fg:by==="active"?on:fg2,bold:!0,right:!0,onClick:()=>props.onSort("active"),children:by==="active"?"Active \u25BE":"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,locked=props.indent||Boolean(r.live),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:label(r)}),$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)}),locked?$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??exports_sessions_db.remove,rename:props.io?.rename??exports_sessions_db.rename},[rows2,setRows]=import_react53.useState(cached2?last.rows:[]),[liveRows,setLiveRows]=import_react53.useState([]),[warn,setWarn]=import_react53.useState(""),[pending3,setPending]=import_react53.useState(rows2.length===0),sort=exports_preferences.usePref("sessions")?.sort??"active",setSort=import_react53.useCallback((s)=>exports_preferences.set("sessions",{sort:s}),[]),active=import_react53.useMemo(()=>[...liveRows].sort((a,b2)=>Number(Boolean(b2.live?.current))-Number(Boolean(a.live?.current))||(b2.live?.last_active??b2.started_at)-(a.live?.last_active??a.started_at)),[liveRows]),ids=import_react53.useMemo(()=>new Set(active.map((r)=>r.id)),[active]),sorted=import_react53.useMemo(()=>rows2.filter((r)=>!ids.has(r.id)).sort(cmp(sort)),[rows2,ids,sort]),listed=import_react53.useMemo(()=>[...active,...sorted],[active,sorted]),[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),seen=import_react53.useRef(!1),anchored=anchor&&listed.find((r)=>r.id===anchor.id),owner=anchor?.indent?listed.find((r)=>kids.get(r.id)?.some((c)=>c.id===anchor.id)):(anchored?.detail?.subagent_count??0)>0?anchored:void 0,visible=listed.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:listed,visible,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId});live.current={rows:listed,visible,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,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}),toLiveRow=(s,d2,r)=>({id:s.id,title:s.title?.trim()||d2?.title||"",preview:s.preview??"",message_count:s.message_count??d2?.message_count??r?.message_count??0,started_at:s.started_at??d2?.started_at??r?.started_at??s.last_active??0,source:d2?.sessionSource??r?.source??s.source??"",detail:d2,live:s}),load4=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})),active2=gw.request("session.active_list",{current_session_id:props.currentId}).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(list2)=>{let ps=list2.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 a=await active2,live2=a.ok?a.v.sessions??[]:[];if(a.ok)setLiveRows(live2.map((s)=>toLiveRow(s,local.get(s.id))));let r=await rpc;if(r.ok&&r.v.sessions?.length){let seen2=new Set(diskRows.map((s)=>s.id)),merged=[...diskRows,...r.v.sessions.filter((s)=>(s.message_count??0)>0&&!seen2.has(s.id)).map((s)=>({...s,detail:local.get(s.id)}))];if(setRows(merged),cached2)last.rows=merged;let found=new Map(merged.map((s)=>[s.id,s]));if(live2.length)setLiveRows(live2.map((s)=>toLiveRow(s,local.get(s.id),found.get(s.id))));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,props.currentId]);import_react53.useEffect(()=>{load4()},[load4]),import_react53.useEffect(()=>{let on=active.length>0,fresh=on&&!seen.current;if(!listed.length){seen.current=on;return}if(!anchor||!visible.some((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)){setAnchor({id:listed[0].id,indent:!1}),seen.current=on;return}if(fresh&&active[0]&&sorted[0]?.id===anchor.id&&!anchor.indent)setAnchor({id:active[0].id,indent:!1});seen.current=on},[listed,active,sorted,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)return;if(!l.searching&&hit?.live){if(l.onActivateLive)return l.onActivateLive(id);return l.onSwitch?.(id)}if(!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:`${trunc5(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
|
|
4098
4098
|
|
|
4099
|
-
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 ${trunc5(sid,24)}?
|
|
4099
|
+
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&&!v2.row.live)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 ${trunc5(sid,24)}?
|
|
4100
4100
|
|
|
4101
|
-
Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid)})},[dialog]),confirmDeleteRef=import_react53.useRef(()=>{}),confirmDelete=import_react53.useCallback((r)=>{openConfirm(dialog,{title:"Delete Session?",body:trunc5(r
|
|
4101
|
+
Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid)})},[dialog]),confirmDeleteRef=import_react53.useRef(()=>{}),confirmDelete=import_react53.useCallback((r)=>{openConfirm(dialog,{title:"Delete Session?",body:trunc5(label(r),46),yes:"Delete",danger:!0}).then(async(ok)=>{if(!ok)return;if(!await gw.request("session.delete",{session_id:r.id}).then(()=>!0).catch((e)=>{if(/active session/i.test(e.message))return toast.show({variant:"error",message:"Can't delete the active session"}),!1;return io2.remove(r.id)}))return;home2.invalidate("recentSessions"),toast.show({variant:"success",message:"Session deleted"}),load4()})},[gw,dialog,toast,load4]);confirmDeleteRef.current=confirmDelete;let rename2=import_react53.useCallback(async()=>{let v2=live.current.visible[sel];if(!v2||v2.indent)return;let r=v2.row,name=await openTextPrompt(dialog,{title:`Rename: ${trunc5(label(r),42)}`,label:"Title",initial:r.title||""});if(name===null)return;Promise.resolve().then(()=>{if(!io2.rename(r.id,name))throw Error("not found");home2.invalidate("recentSessions"),setRows((prev)=>prev.map((row2)=>row2.id===r.id?{...row2,title:name}:row2)),toast.show({variant:"success",message:"Renamed"})}).catch((e)=>toast.show({variant:"error",message:`Rename failed: ${e.message}`}))},[dialog,toast,sel]),count3=searching?results.length:visible.length,rowId=(i)=>{if(searching)return`sess-s-${results[i]?.session_id??i}`;let v2=visible[i];return v2?`sess-${v2.indent?"c":"p"}-${v2.row.id}`:`sess-empty-${i}`},keys=useKeys();useKeyboard((key2)=>{if(!props.focused||dialog.open())return;if(searching){if(key2.name==="escape"){setSearching(!1),setQuery(""),setResults([]),setSearchSel(0);return}if(key2.name==="backspace")return setQuery((p)=>p.slice(0,-1));if(key2.name==="return")return rowActivate(searchSel);if(key2.name==="up")return setSearchSel((p)=>Math.max(0,p-1));if(key2.name==="down")return setSearchSel((p)=>Math.min(count3-1,p+1));if(key2.raw&&key2.raw.length===1&&key2.raw>=" ")return setQuery((p)=>p+key2.raw);return}if(handleListKey(keys,key2,{count:count3,setSel,page:Math.max(1,(vscroll.current?.viewport.height??10)-1),scrollTo:(n)=>vscroll.current?.scrollChildIntoView(rowId(n)),onActivate:()=>rowActivate(sel),onToggle:()=>setSort(sort==="active"?"started":"active"),onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})},onDelete:()=>{let v2=visible[sel];if(v2&&!v2.indent&&!v2.row.live)confirmDelete(v2.row)},onSearch:()=>{setSearching(!0),setQuery(""),setResults([]),setSearchSel(0)}}))return;if(keys.match("sessions.rename",key2))return void rename2();if(keys.match("sessions.prev",key2)||keys.match("sessions.next",key2)){let v2=visible[sel];if(!v2)return;Promise.resolve(io2.lineage(v2.row.id)).then((ln)=>{let target=keys.match("sessions.prev",key2)?ln.continuesFrom?.id:ln.compressedTo?.id;if(target)lineageSwitch(target)});return}});let empty=searching?results.length===0&&query.length>0:listed.length===0,action=visible[sel]?.row.live?"activate live":"switch",top=(i)=>Boolean(visible[i]?.row.live&&(i===0||!visible[i-1]?.row.live)),hist=(i)=>Boolean(visible[i]?.row.live&&visible[i+1]&&!visible[i+1].row.live),showDetailPanel=dims.width>=120;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs(TabShell,{title:searching?`Search Results (${results.length})`:`Sessions (${listed.length}${pending3?"\u2026":""})`,error:warn||null,grow:3,children:[searching?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"/ "}),$jsx("span",{fg:theme.text,children:query}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})}):null,empty?$jsx("box",{flexGrow:1,padding:2,children:pending3&&!searching?$jsx(Spinner,{color:theme.textMuted,label:"loading sessions\u2026"}):$jsx("text",{fg:theme.textMuted,children:searching?"No matching sessions found":"No sessions found"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[searching?$jsx(SearchHeaderRow,{}):$jsx(HeaderRow,{sort,onSort:setSort}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:vscroll,scrollY:!0,viewportCulling:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:searching?results.map((r,i)=>$jsx(SearchItem,{id:rowId(i),idx:i,result:r,selected:i===searchSel,onActivate:rowActivate,onHover:rowHover},r.session_id)):visible.map((v2,i)=>$jsxs("box",{flexDirection:"column",height:1+(top(i)?1:0)+(hist(i)?1:0),children:[top(i)?$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.textMuted,children:`\u2500\u2500 ${active.length===1?"Active Session":"Active Sessions"} \u2500\u2500`})}):null,$jsx(Item,{id:rowId(i),idx:i,row:v2.row,selected:i===sel,indent:v2.indent,onActivate:rowActivate,onHover:rowHover,onDelete:rowDelete}),hist(i)?$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.textMuted,children:"\u2500\u2500 History \u2500\u2500"})}):null]},`${v2.row.id}-${v2.indent?"c":"p"}`))})]},"table")]}),showDetailPanel&&searching&&results[searchSel]?$jsx(SearchDetail,{result:results[searchSel]}):showDetailPanel&&!searching&&visible[sel]?.row?$jsx(Detail,{row:visible[sel].row,lineage:io2.lineage,peek:io2.peek,onSwitch:lineageSwitch}):null]}),$jsx(HintBar,{pairs:searching?[["\u2191\u2193","navigate"],["Enter/click","switch"],["Esc","cancel"]]:[["\u2191\u2193","navigate"],["\u2190\u2192","lineage"],[`${keys.print("list.activate")}/click`,action],[keys.print("list.search"),"search"],[keys.print("list.toggle"),`sort: ${sort}`],[keys.print("sessions.rename"),"rename"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react56=__toESM(require_react_production(),1);var GRID=256,CPT=4,MEMORY_IDS=new Set(["soul","memory","user","mem0"]),SYSTEM_PROMPT_IDS=new Set(["project","meta","other"]);function parse4(text2){if(!text2)return[];let sections=[],used=Array(text2.length).fill(!1),mark2=(start2,end,id,label2,source)=>{let slice=text2.slice(start2,end);if(slice.trim().length===0)return;for(let i=start2;i<end;i++)used[i]=!0;sections.push({id,label:label2,chars:slice.length,tokens:count2(slice),text:slice,source})},bar1=text2.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550");if(bar1>0)mark2(0,bar1,"soul","SOUL.md",makeSource("SOUL.md"));let memH=text2.indexOf("MEMORY (your personal notes)");if(memH>=0){let s=text2.lastIndexOf("\u2550\u2550\u2550\u2550\u2550\u2550",memH),after=text2.indexOf(`
|
|
4102
4102
|
`,text2.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",memH+1)),next=text2.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",after>0?after:memH+40),e=next>0?text2.lastIndexOf(`
|
|
4103
4103
|
`,next)+1:text2.length;if(s>=0)mark2(s,e,"memory","Memory Notes",makeSource("memories/MEMORY.md","MEMORY.md"))}let userH=text2.indexOf("USER PROFILE (who the user is)");if(userH>=0){let s=text2.lastIndexOf("\u2550\u2550\u2550\u2550\u2550\u2550",userH),after=text2.indexOf(`
|
|
4104
4104
|
`,text2.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",userH+1)),next=text2.slice(after>0?after:userH+40).search(/\n#\s/),e=next>=0?(after>0?after:userH+40)+next+1:text2.length;if(s>=0)mark2(s,e,"user","User Profile",makeSource("memories/USER.md","USER.md"))}let m0=text2.indexOf("# Mem0 Memory");if(m0>=0){let next=text2.slice(m0+1).search(/\n##?\s/);mark2(m0,next>=0?m0+1+next+1:text2.length,"mem0","Mem0 Memory")}let skH=text2.indexOf("## Skills (mandatory)"),skE=text2.indexOf("</available_skills>");if(skH>=0&&skE>=0){let end=text2.indexOf(`
|
|
4105
4105
|
`,skE);while(end<text2.length&&end>=0){let nl=text2.indexOf(`
|
|
4106
4106
|
`,end+1);if(nl<0){end=text2.length;break}let line2=text2.slice(end+1,nl).trim();if(line2.startsWith("#"))break;if(line2===""){if(text2.slice(nl+1,text2.indexOf(`
|
|
4107
|
-
`,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 start=-1;for(let i=0;i<=text2.length;i++)if(i<text2.length&&!used[i]){if(start<0)start=i}else if(start>=0){let slice=text2.slice(start,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start=-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_react55=__toESM(require_react_production(),1);var FileLink=import_react55.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react55.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 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 fmt2=(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_react56.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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt2(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_react56.memo(({seg,theme,label,chars,limit,pct,entries:entries2,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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:
|
|
4108
|
-
`)){if(line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line2.match(/^\s{4}- \S+:/)){let last2=Object.keys(cats).pop();if(last2)cats[last2]++}}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 ",fmt2(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_react56.memo(({seg,theme,tools,kind:kind2})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label=kind2==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind2==="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(kind2,theme),children:"\u25FC"})," ",label," \u2014 ",fmt2(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," (",fmt2(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react56.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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt2(est(user.map((m2)=>text(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt2(est(asst.map((m2)=>text(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt2(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment,{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"})," ","(",fmt2(est(text(m2))),") ",text(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react56.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 ",fmt2(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt2(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt2(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt2(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment,{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:[" (",fmt2(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([]),toolsFromInfo=(info)=>{if(!info?.tools)return null;let tools=Object.entries(info.tools).flatMap(([group,names])=>names.map((name)=>({name,descriptionLength:0,paramsLength:group.length})));if(tools.length===0)return null;return{source:makeSource("state.db","session.info"),tools}},Context=import_react56.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_react56.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react56.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react56.useState(null),[selected,setSelected]=import_react56.useState(null),[drilled,setDrilled]=import_react56.useState(null);import_react56.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_react56.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react56.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text(m2)).join("")),[messages]),currentTools=import_react56.useMemo(()=>toolsFromInfo(info)??toolsInfo,[info,toolsInfo]),top=import_react56.useMemo(()=>build({contextLength:ctxLen,inputTokens:fill,sections,conversationTokens:convTok,tools:currentTools?.tools??[]}),[ctxLen,fill,sections,convTok,currentTools]),drilledGroup=drilled?top.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top,grid=import_react56.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_react56.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react56.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_react56.useRef(0),segs=view.filter((s)=>s.tokens>0),idx=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx):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"&¤tTools){let{system}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&¤tTools){let{mcp}=classifyTools(currentTools.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," (",fmt2(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 ",fmt2(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 ",fmt2(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("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:`Context \xB7 ${fmt2(fill)} / ${fmt2(ctxLen)} (${pct}%)`,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt2(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,row2)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row2*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=row2*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)})},row2))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]}),$jsx(HintBar,{raw:crumb+escHint})]})});var import_react58=__toESM(require_react_production(),1);init_hermes_analytics();var BLOCKS=" \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588",rows2=(vals,h2)=>{let peak=Math.max(1,...vals),ticks=vals.map((v2)=>Math.round(h2*8*v2/peak));return Array.from({length:h2},(_2,r)=>{let floor=(h2-1-r)*8;return ticks.map((t2)=>BLOCKS[Math.max(0,Math.min(8,t2-floor))]).join("")})},Chart=import_react58.memo((p)=>{let theme=useTheme().theme,days=p.data.byDay,vals=days.map((d2)=>d2.cost),peak=Math.max(...vals,0.01),axis=(v2)=>cost(v2).padStart(7),md=(s)=>s.slice(5);return $jsxs("box",{flexDirection:"column",children:[rows2(vals,p.h).map((line2,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:i===0?axis(peak):i===p.h-1?axis(0):""})}),$jsx("text",{fg:theme.primary,children:line2})]},i)),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0}),$jsx("text",{fg:theme.textMuted,children:days.length>0?`${md(days[0].date)}${" ".repeat(Math.max(0,days.length-10))}${md(days[days.length-1].date)}`:""})]})]})}),Rank=import_react58.memo((p)=>{let theme=useTheme().theme;if(p.rows===null)return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),$jsx("box",{height:1,children:$jsx(Spinner,{label:"aggregating\u2026"})})]});let top=p.rows.slice(0,p.n??10),peak=Math.max(1,...top.map((r)=>r.n)),total=p.rows.reduce((a,r)=>a+r.n,0);return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),top.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"\u2014"})}):top.map((r)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{w:18,children:trunc5(r.name,17)}),$jsx(Col,{w:12,fg:p.fg,children:"\u2587".repeat(Math.max(1,Math.round(10*r.n/peak)))}),$jsx(Col,{w:7,right:!0,children:fmt(r.n)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:total?`${Math.round(100*r.n/total)}%`:""})]},r.name))]})}),Analytics=import_react58.memo((props)=>{let theme=useTheme().theme,dims=useTerminalDimensions(),[days,setDays]=import_react58.useState(7),[data2,setData]=import_react58.useState(()=>cache3.get(days)??null),[tools,setTools]=import_react58.useState(()=>cache3.get(days)?.byTool??null),[tick2,setTick]=import_react58.useState(0),gen=import_react58.useRef(0);import_react58.useEffect(()=>{let hit=cache3.get(days);setData(hit??null),setTools(hit?.byTool??null);let g=++gen.current;return io.analytics(days,{tools:!1}).then((fast)=>{if(gen.current!==g)return;setData(fast),io.analytics(days).then((full)=>{if(gen.current!==g)return;cache3.set(days,full),setData(full),setTools(full.byTool)})}),()=>{gen.current++}},[days,tick2]);let keys=useKeys();useKeyboard((key2)=>{if(!props.focused)return;if(keys.match("list.refresh",key2))return cache3.delete(days),setTick((n)=>n+1);if(key2.raw==="1")return setDays(1);if(key2.raw==="7")return setDays(7);if(key2.raw==="3")return setDays(30);if(key2.raw==="9")return setDays(90)});let t2=data2?.total,tok=(t2?.input??0)+(t2?.output??0),title=import_react58.useMemo(()=>!t2?`Analytics \xB7 ${days}d`:`Analytics \xB7 ${days}d \xB7 ${t2.sessions} sess \xB7 ${fmt(tok)} tok \xB7 ${cost(t2.cost)}`,[days,t2,tok]),wide=dims.width>=110,chartH=dims.height>=40?8:6;if(!data2)return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsx("box",{height:1,children:$jsx(Spinner,{label:`aggregating ${days}d\u2026`})})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]});let nTools=8,nSrc=6,ranksH=wide?Math.max(nTools,nSrc)+1:nTools+nSrc+3;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,overflow:"hidden",children:[$jsxs("box",{flexShrink:0,flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`Cost per day \xB7 ${fmt(t2.input)} in \xB7 ${fmt(t2.output)} out \xB7 ${fmt(t2.cache)} cache \xB7 ${fmt(t2.calls)} tool calls`})}),$jsx(Chart,{data:data2,h:chartH})]}),$jsx("box",{height:1,flexShrink:0}),$jsx("box",{flexShrink:0,children:$jsxs(Hdr,{children:[$jsx(Col,{grow:!0,min:18,fg:theme.textMuted,children:"Model"}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:"sess"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"in"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"out"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cache"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cost"})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,flexShrink:1,minHeight:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.byModel.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"no sessions in range"})}):data2.byModel.map((m2)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{grow:!0,min:18,children:trunc5(m2.model,40)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:String(m2.sessions)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.input)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.output)}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:fmt(m2.cache)}),$jsx(Col,{w:9,right:!0,fg:theme.accent,children:cost(m2.cost)})]},m2.model))})}),$jsx("box",{height:1,flexShrink:0}),$jsxs("box",{flexShrink:0,height:ranksH,flexDirection:wide?"row":"column",gap:wide?2:1,children:[$jsx(Rank,{title:"Tools",rows:tools,fg:theme.success,n:nTools}),$jsx(Rank,{title:"Sources",rows:data2.bySource,fg:theme.info,n:nSrc})]})]})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]})});var import_react60=__toESM(require_react_production(),1);var SubTabBar=import_react60.memo((props)=>$jsx(TabStrip,{...props}));var TABS=[{name:"Chat",description:"Main chat interface"},{name:"Sessions",description:"Sessions, context, analytics"},{name:"Profiles & Automation",description:"Profiles, cron jobs, kanban boards"},{name:"Config",description:"Config, env, skills, toolsets, memory"},{name:"Eikon",description:"Avatar studio & gallery"}],TAB_MAX=TABS.length-1,CHAT_TAB=0,SESSIONS_TAB=1,AUTOMATION_TAB=2,CONFIG_TAB=3,EIKON_TAB=4,SUB_TABS={[1]:["List","Context","Analytics"],[2]:["Kanban","Profiles","Cron"],[3]:["Config","Skills","Toolsets","Env","Memory"],[4]:["Studio","Gallery"]},TAB_SLASH={chat:{tab:0,sub:0},sessions:{tab:1,sub:0},context:{tab:1,sub:1},analytics:{tab:1,sub:2},insights:{tab:1,sub:2},kanban:{tab:2,sub:0},automation:{tab:2,sub:0},profiles:{tab:2,sub:1},agents:{tab:2,sub:1},cron:{tab:2,sub:2},config:{tab:3,sub:0},skills:{tab:3,sub:1},toolsets:{tab:3,sub:2},env:{tab:3,sub:3},memory:{tab:3,sub:4},studio:{tab:4,sub:0},gallery:{tab:4,sub:1}};var SessionsGroup=import_react61.memo((props)=>{let keys=useKeys(),labels=SUB_TABS[SESSIONS_TAB];import_react61.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint=`${keys.print("tab.prev")}/${keys.print("tab.next")} group \xB7 shift+\u2190/\u2192 sub`;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane,{visible:props.sub===0,children:$jsx(Sessions,{focused:!!props.focused&&props.sub===0,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId})}),$jsx(Pane,{visible:props.sub===1,children:$jsx(Context,{focused:!!props.focused&&props.sub===1,messages:props.messages,sessionStart:props.sessionStart,info:props.info})}),$jsx(Pane,{visible:props.sub===2,children:$jsx(Analytics,{focused:!!props.focused&&props.sub===2})})]})]})}),Pane=({visible,children:children2})=>visible?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react82=__toESM(require_react_production(),1);var import_react73=__toESM(require_react_production(),1);var acc=new Map;function record(ev,p){let id=p.subagent_id;if(!id)return;let now=Date.now()/1000;if(ev==="start"){acc.set(id,{subagent_id:id,parent_id:p.parent_id??null,depth:p.depth??0,goal:p.goal,model:p.model,started_at:now,tool_count:0,status:"running",trail:[]});return}let r=acc.get(id);if(!r)return;if(ev==="tool"&&p.tool_name){r.tool_count++,r.trail=[...r.trail??[],{name:p.tool_name,preview:p.tool_preview}].slice(-20);return}if(ev==="complete")r.status=p.status??"completed",r.finished_at=now,r.input_tokens=p.input_tokens,r.output_tokens=p.output_tokens,r.cost_usd=p.cost_usd}function trail(id){return acc.get(id)?.trail??[]}function flush(gw,sessionId){if(acc.size===0)return;let subagents=[...acc.values()];acc.clear();let label=(subagents.filter((s)=>s.parent_id==null).slice(0,2).map((s)=>s.goal).join(" \xB7 ")||`${subagents.length} subagents`).slice(0,120),started=Math.min(...subagents.map((s)=>s.started_at));gw.request("spawn_tree.save",{session_id:sessionId,label,started_at:started,finished_at:Date.now()/1000,subagents}).catch(()=>{})}var import_react64=__toESM(require_react_production(),1);var import_react62=__toESM(require_react_production(),1);var DialogSelect=(props)=>{let filterable=props.filterable??!0,[filter,setFilter]=import_react62.useState(""),[cursor,setCursor]=import_react62.useState(0),mode=import_react62.useRef("kb"),moved=import_react62.useRef(!1),sb=import_react62.useRef(null),theme=useTheme().theme,filtered=import_react62.useMemo(()=>{let lower=filter.toLowerCase();return props.options.filter((o)=>o.title.toLowerCase().includes(lower)||(o.description??"").toLowerCase().includes(lower))},[filter,props.options]),groups=import_react62.useMemo(()=>{let map=new Map;return filtered.forEach((o)=>{let cat=o.category??"",arr=map.get(cat)??[];arr.push(o),map.set(cat,arr)}),map},[filtered]),rowId=(i)=>`ds-row-${i}`,scrollTo=(i)=>sb.current?.scrollChildIntoView(rowId(i));import_react62.useEffect(()=>{if(cursor>=filtered.length)setCursor(Math.max(0,filtered.length-1))},[filtered.length,cursor]),import_react62.useEffect(()=>{if(!props.current){setCursor(0);return}let i=filtered.findIndex((o)=>o.value===props.current),n=Math.max(0,i);setCursor(n),scrollTo(n)},[props.current,filtered]),import_react62.useEffect(()=>{if(!moved.current)return;moved.current=!1;let item=filtered[cursor];if(item&&props.onMove)props.onMove(item)},[cursor,filtered,props.onMove]);let keys=useKeys();useKeyboard((key2)=>{let onToggle=!filterable?()=>{let item=filtered[cursor];if(item)props.onSelect(item)}:void 0;if(handleListKey(keys,key2,{count:filtered.length,setSel:(fn)=>{mode.current="kb",moved.current=!0,setCursor(fn)},scrollTo,page:Math.max(1,(sb.current?.viewport.height??10)-1),onActivate:()=>{let item=filtered[cursor];if(item)props.onSelect(item)},onToggle}))return;if(props.onKey?.(key2))return});let idx=0,entries2=Array.from(groups.entries());return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),filterable?$jsxs($Fragment,{children:[$jsx("input",{value:filter,onInput:(v2)=>{mode.current="kb",setFilter(v2)},placeholder:props.placeholder??"Type to filter...",focused:!0,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}),$jsx("box",{height:1})]}):null,$jsxs("scrollbox",{ref:sb,scrollY:!0,maxHeight:16,focused:!filterable,contentOptions:{flexDirection:"column"},paddingRight:1,children:[filtered.length===0?$jsx("text",{fg:theme.textMuted,children:"No results found"}):null,entries2.map(([cat,items])=>{let elements=[];if(cat)elements.push($jsx("text",{fg:theme.textMuted,children:$jsx("strong",{children:cat})},`cat-${cat}`));return items.forEach((item)=>{let i=idx++,active=i===cursor,current=item.value===props.current;elements.push($jsxs("box",{id:rowId(i),flexDirection:"row",backgroundColor:active?theme.backgroundElement:void 0,onMouseMove:()=>{mode.current="mouse",moved.current=!0,setCursor((c)=>c===i?c:i)},onMouseOver:()=>{if(mode.current==="mouse")moved.current=!0,setCursor(i)},onMouseDown:()=>props.onSelect(item),paddingLeft:1,paddingRight:1,children:[$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsxs("text",{fg:active?theme.text:theme.textMuted,children:[current?"\u25CF ":" ",item.title,item.description?` \u2014 ${item.description}`:""]})}),item.hint?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:item.hint})}):null]},item.value))}),elements}).flat()]}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]})};var Ctx6=import_react64.createContext(null),CommandProvider=({children:children2})=>{let registry=import_react64.useRef(new Map),enabled2=import_react64.useRef(!0),dialog=useDialog(),keys=useKeys(),all=import_react64.useCallback(()=>{let out=[];return registry.current.forEach((cmds)=>cmds.forEach((c)=>out.push(c))),out},[]),register=import_react64.useCallback((cmds)=>{let id=String(Date.now())+Math.random();return registry.current.set(id,cmds),()=>{registry.current.delete(id)}},[]),setEnabled=import_react64.useCallback((val)=>{enabled2.current=val},[]),open2=import_react64.useCallback(()=>{let cmds=all(),options=cmds.map((c)=>({title:c.title,value:c.value,description:c.description,hint:c.action?keys.print(c.action):void 0,category:c.category}));dialog.replace($jsx(DialogSelect,{title:"Command Palette",options,onSelect:(opt)=>{dialog.clear();let found=cmds.find((c)=>c.value===opt.value);if(found)found.onSelect()},placeholder:"Search commands..."}))},[all,dialog,keys]);useKeyboard((key2)=>{if(!enabled2.current||dialog.open())return;if(keys.match("palette.open",key2))return open2();for(let c of all())if(c.action&&keys.match(c.action,key2))return c.onSelect()});let value=import_react64.useMemo(()=>({register,setEnabled}),[register,setEnabled]);return $jsx(Ctx6.Provider,{value,children:children2})},useCommand=makeUse(Ctx6,"useCommand");var Status=({s})=>{let theme=useTheme().theme,fg2=s==="completed"?theme.success:s==="failed"?theme.error:s==="error"?theme.error:s==="timeout"?theme.error:s==="interrupted"?theme.warning:theme.textMuted;return $jsx("span",{fg:fg2,children:s})},SnapshotView=(props)=>{let theme=useTheme().theme,subs2=props.snap.subagents??[],tok=subs2.reduce((n,s)=>n+(s.input_tokens??0)+(s.output_tokens??0),0),span2=props.snap.started_at&&props.snap.finished_at?dur2(props.snap.finished_at-props.snap.started_at):"\u2014";return $jsxs("box",{flexDirection:"column",width:80,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.entry.label||`${subs2.length} subagents`})}),$jsxs("text",{fg:theme.textMuted,children:[when(props.entry.finished_at)," \xB7 ",span2," \xB7 ",subs2.length," agents \xB7 ",fmt(tok)," tok"]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,contentOptions:{flexDirection:"column"},children:subs2.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "+"\xB7 ".repeat(s.depth)}),$jsx("span",{fg:theme.text,children:trunc5(s.goal.replace(/\s+/g," "),60)})]})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["\u2503 "+" ".repeat(2*s.depth+2),$jsx(Status,{s:s.status}),` \xB7 ${s.tool_count}t`,s.finished_at?` \xB7 ${dur2(s.finished_at-s.started_at)}`:"",s.model?` \xB7 ${s.model}`:""]})})]},s.subagent_id))})]})};function openSpawnHistory(dialog,gw,sessionId){gw.request("spawn_tree.list",{session_id:sessionId,limit:50}).then((r)=>{let entries2=r.entries??[];dialog.replace($jsx(DialogSelect,{title:"Spawn history",placeholder:entries2.length?"filter\u2026":"no saved spawn trees",options:entries2.map((e)=>({value:e.path,title:`${e.count.toString().padStart(2)}\xD7 ${trunc5(e.label||"(unlabeled)",40)}`,description:when(e.finished_at),category:e.session_id===sessionId?"This session":e.session_id})),onSelect:(opt)=>{let entry2=entries2.find((e)=>e.path===opt.value);gw.request("spawn_tree.load",{path:entry2.path}).then((snap)=>dialog.replace($jsx(SnapshotView,{entry:entry2,snap}))).catch(()=>dialog.clear())}}))}).catch(()=>dialog.clear())}var import_react67=__toESM(require_react_production(),1);var Dialog=(props)=>{let theme=useTheme().theme,keys=useKeys();useKeyboard((key2)=>{if(keys.match("dialog.cancel",key2)||keys.match("dialog.accept",key2))return props.onClose()});let d2=props.d,req=d2.env_requires.filter((e)=>e.required),opt=d2.env_requires.filter((e)=>!e.required),link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs("box",{flexDirection:"column",minWidth:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Distribution \xB7 ${props.profile}`})})}),$jsxs("box",{flexDirection:"column",children:[$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0],["Author",d2.author||void 0],["License",d2.license||void 0],["Description",d2.description||void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed",Number.isFinite(when2)?ago(when2/1000):void 0],["Owned",d2.distribution_owned.length?d2.distribution_owned.join(", "):void 0]]})]}),d2.env_requires.length?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Environment variables"})})}),req.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Required"})}),req.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null,opt.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Optional"})}),opt.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null]}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:`[${keys.print("dialog.cancel")}] close`})})]})},EnvRow=(props)=>{let theme=useTheme().theme,tail=[props.desc,props.fallback?`default: ${props.fallback}`:""].filter(Boolean).join(" \xB7 ");return $jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:" "})}),$jsx("box",{width:22,flexShrink:0,children:$jsx("text",{fg:theme.accent,children:props.name})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:tail})})]})};function openDistributionInfo(dialog,opts){dialog.replace($jsx(Dialog,{profile:opts.profile,d:opts.d,yaml:opts.yaml,onClose:()=>dialog.clear()}))}function openProfileMenu(dialog,p,ops){let opts=[...ops.switch&&!p.is_active?[{category:"Switch",value:"switch",title:`Switch to '${p.name}'`,description:"restart gateway under this HERMES_HOME \u2014 ends current session"}]:[],{category:"Open",value:"soul",title:"SOUL.md",description:"edit persona/system prompt"},{category:"Open",value:"config",title:"config.yaml",description:"model, provider, toolsets"},...p.has_env?[{category:"Open",value:"env",title:".env",description:"API keys + secrets"}]:[],{category:"Open",value:"dir",title:"Directory",description:p.path},...p.distribution?[{category:"Distribution",value:"dist-info",title:"Info",description:`v${p.distribution.version}${p.distribution.source?` \xB7 ${p.distribution.source}`:""}`},{category:"Distribution",value:"dist-update",title:"Update",description:`hermes profile update ${p.name}${p.is_active?" \xB7 ends current session":""}`}]:[],...p.is_sticky?[{category:"Default",value:"unsticky",title:"Clear sticky default",description:"hermes profile use --clear"}]:[{category:"Default",value:"sticky",title:"Set as sticky default",description:`hermes profile use ${p.name}`}],{category:"Manage",value:"export",title:"Export",description:`hermes profile export ${p.name}`},...p.is_default||p.is_active?[]:[{category:"Manage",value:"delete",title:"Delete",description:"irreversible \u2014 removes config, env, memory, sessions"}]];dialog.replace($jsx(DialogSelect,{title:`Profile \xB7 ${p.name}${p.is_active?" (active)":""}`,options:opts,onSelect:(o)=>{if(o.value==="dist-info"){if(!p.distribution)return dialog.clear();return openDistributionInfo(dialog,{profile:p.name,d:p.distribution,yaml:p.sources.distribution})}if(o.value==="dist-update"){if(!p.distribution)return dialog.clear();return openUpdateDistribution(dialog,p,(force)=>ops.update(p,force))}if(dialog.clear(),o.value==="switch")return ops.switch?.();if(o.value==="soul")return openFile(p.sources.soul.file);if(o.value==="config")return openFile(p.sources.config.file);if(o.value==="env")return openFile(p.sources.env.file);if(o.value==="dir")return openFile(p.path);if(o.value==="sticky")return ops.sticky(p);if(o.value==="unsticky")return ops.unsticky();if(o.value==="export")return ops.export(p);if(o.value==="delete")return ops.remove(p)}}))}var UpdateForm=(props)=>{let theme=useTheme().theme,keys=useKeys(),[force,setForce]=import_react67.useState(!1);useKeyboard((key2)=>{if(keys.match("dialog.cancel",key2)||keys.match("dialog.deny",key2))return props.done(null);if(keys.match("dialog.confirm",key2)||keys.match("dialog.accept",key2))return props.done(force);if(key2.name==="space"||key2.name===" ")return setForce((f)=>!f)});let d2=props.p.distribution;return $jsxs("box",{flexDirection:"column",width:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:"Update distribution?"})})}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:`'${props.p.name}' \xB7 v${d2.version}${d2.source?` \xB7 ${d2.source}`:""}`})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:"Re-pulls from source; distribution-owned files are overwritten."})}),props.p.is_active?$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.warning,children:"\u26A0 This is the active profile. The gateway will re-spawn "+"and the current session will end."})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:force?theme.warning:theme.textMuted,children:`${force?"[x]":"[ ]"} --force-config \xB7 also overwrite config.yaml`})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}] update [Space] toggle force [${keys.print("dialog.cancel")}] cancel`})})]})};function openUpdateDistribution(dialog,p,onConfirm){dialog.replace($jsx(UpdateForm,{p,done:(force)=>{if(dialog.clear(),force!==null)onConfirm(force)}}))}var import_react69=__toESM(require_react_production(),1);import{existsSync as existsSync12,readFileSync as readFileSync4}from"fs";import{readdir as readdir3}from"fs/promises";import{homedir as homedir6}from"os";import{join as join9,basename as basename8,dirname as dirname5}from"path";import{Database as Database2}from"bun:sqlite";var home3=()=>process.env.HOME||homedir6(),hermesHome=()=>process.env.HERMES_HOME||join9(home3(),".hermes");function root(){let hh=hermesHome(),parent2=dirname5(hh);return basename8(parent2)==="profiles"?dirname5(parent2):hh}function profileNameFrom(hh){let parent2=dirname5(hh);return basename8(parent2)==="profiles"?basename8(hh):"default"}function activeProfileName(){return profileNameFrom(hermesHome())}function stickyDefault(){try{return readFileSync4(join9(root(),"active_profile"),"utf-8").trim()||null}catch{return null}}var ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/;function readModel(dir){try{let raw=readFileSync4(join9(dir,"config.yaml"),"utf-8"),block=raw.split(/^model:\s*$/m)[1]?.split(/^\S/m)[0]??"",m2=block.match(/^\s+(?:default|model):\s*(.+)$/m)?.[1]?.trim()??raw.match(/^model:\s*(\S.+)$/m)?.[1]?.trim(),p=block.match(/^\s+provider:\s*(.+)$/m)?.[1]?.trim(),clean=(s)=>s?.replace(/^["']|["']$/g,"")??null;return[clean(m2),clean(p)]}catch{return[null,null]}}async function countSkills(dir){let glob=new Bun.Glob("**/SKILL.md"),n=0;try{for await(let _2 of glob.scan({cwd:join9(dir,"skills"),onlyFiles:!0}))n++}catch{}return n}function gatewayRunning(dir){try{let raw=readFileSync4(join9(dir,"gateway.pid"),"utf-8").trim(),pid2=raw.startsWith("{")?Number(JSON.parse(raw).pid):Number(raw);if(!Number.isFinite(pid2)||pid2<=0)return!1;return process.kill(pid2,0),!0}catch{return!1}}function soul(dir){try{return readFileSync4(join9(dir,"SOUL.md"),"utf-8").replace(/^#[^\n]*\n+/,"").replace(/^\s+/,"").slice(0,400)}catch{return""}}function readDistributionManifest(dir){let path7=join9(dir,"distribution.yaml");if(!existsSync12(path7))return null;let data2=(()=>{try{return $parse(readFileSync4(path7,"utf-8"))}catch{return null}})();if(!data2||typeof data2!=="object"||Array.isArray(data2))return null;let d2=data2,name=typeof d2.name==="string"?d2.name.trim():"";if(!name)return null;let envs=(Array.isArray(d2.env_requires)?d2.env_requires:[]).flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e,n=typeof r.name==="string"?r.name.trim():"";if(!n)return[];return[{name:n,description:typeof r.description==="string"?r.description:"",required:r.required===void 0?!0:Boolean(r.required),default:typeof r.default==="string"?r.default:null}]}),owned=(Array.isArray(d2.distribution_owned)?d2.distribution_owned:[]).map((p)=>typeof p==="string"?p.trim().replace(/\/+$/,""):"").filter((p)=>p.length>0);return{name,version:typeof d2.version==="string"?d2.version:"0.1.0",description:typeof d2.description==="string"?d2.description:"",hermes_requires:typeof d2.hermes_requires==="string"?d2.hermes_requires:"",author:typeof d2.author==="string"?d2.author:"",license:typeof d2.license==="string"?d2.license:"",env_requires:envs,distribution_owned:owned,source:typeof d2.source==="string"?d2.source:"",installed_at:typeof d2.installed_at==="string"?d2.installed_at:""}}var src=(file,label)=>({file,relative:file.replace(home3()+"/","~/"),label});async function info(name,dir,active,sticky){let[model,provider]=readModel(dir),alias=join9(home3(),".local","bin",name);return{name,path:dir,is_default:name==="default",is_active:name===active,is_sticky:name===sticky,gateway_running:gatewayRunning(dir),model,provider,has_env:existsSync12(join9(dir,".env")),skill_count:await countSkills(dir),has_alias:name!=="default"&&existsSync12(alias),soul_preview:soul(dir),distribution:readDistributionManifest(dir),sources:{dir:src(dir,dir.replace(home3()+"/","~/")),config:src(join9(dir,"config.yaml"),"config.yaml"),soul:src(join9(dir,"SOUL.md"),"SOUL.md"),env:src(join9(dir,".env"),".env"),distribution:src(join9(dir,"distribution.yaml"),"distribution.yaml")}}}async function listProfiles(activeHome){let r=root(),active=profileNameFrom(activeHome??hermesHome()),sticky=stickyDefault(),jobs=[];if(existsSync12(r))jobs.push(info("default",r,active,sticky));let pr=join9(r,"profiles");if(existsSync12(pr))for(let e of await readdir3(pr,{withFileTypes:!0})){if(!e.isDirectory()||!ID_RE.test(e.name))continue;jobs.push(info(e.name,join9(pr,e.name),active,sticky))}return Promise.all(jobs)}function validateName(name,existing){if(!ID_RE.test(name))return"must match [a-z0-9][a-z0-9_-]{0,63}";if(existing.includes(name))return"already exists";if(["hermes","default","test","tmp","root","sudo"].includes(name))return"reserved name";return null}function readPrefs(dir){try{let raw=JSON.parse(readFileSync4(join9(dir,"herm","tui.json"),"utf-8"));return{theme:raw.theme,eikon:raw.eikon??(raw.eikonPath?basename8(raw.eikonPath,".eikon"):void 0),keys:raw.keys?Object.keys(raw.keys).length:0}}catch{return null}}async function profileStats(dir){let sessions=null,messages=null,dbPath=join9(dir,"state.db");if(existsSync12(dbPath))try{let db=new Database2(dbPath,{readwrite:!0,create:!1}),r=db.query("SELECT COUNT(*) AS s FROM sessions WHERE message_count > 0").get(),m2=db.query("SELECT COALESCE(SUM(message_count), 0) AS m FROM sessions").get();sessions=r.s,messages=m2.m,db.close()}catch{}let crons=null;try{let jobs=await Bun.file(join9(dir,"cron","jobs.json")).json();crons=Array.isArray(jobs)?jobs.length:jobs&&typeof jobs==="object"&&Array.isArray(jobs.jobs)?jobs.jobs.length:0}catch{crons=existsSync12(join9(dir,"cron"))?0:null}return{sessions,messages,crons,prefs:readPrefs(dir)}}var ORDER2=["name","clone","alias"];function openCreateProfile(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form,{existing:opts.existing,done}))})}var Form=({existing,done})=>{let theme=useTheme().theme,[name,setName]=import_react69.useState(""),[cloneIdx,setCloneIdx]=import_react69.useState(0),[alias,setAlias]=import_react69.useState(!0),[field,setField]=import_react69.useState("name"),options=["(fresh)",...existing],err=name?validateName(name,existing):null,valid=!!name&&!err,submit=()=>{if(!valid)return;done({name,cloneFrom:cloneIdx===0?null:options[cloneIdx],alias})},moveField=(dir)=>{let i=ORDER2.indexOf(field);setField(ORDER2[(i+dir+ORDER2.length)%ORDER2.length])};useKeyboard((key2)=>{if(key2.name==="escape")return done(null);if(key2.name==="tab")return moveField(key2.shift?-1:1);if(key2.name==="return")return submit();if(field==="name"){if(key2.name==="backspace")return setName((n)=>n.slice(0,-1));if(key2.raw&&key2.raw.length===1&&/[a-z0-9_-]/.test(key2.raw))return setName((n)=>n+key2.raw);return}if(field==="clone"){if(key2.name==="up")return setCloneIdx((i)=>Math.max(0,i-1));if(key2.name==="down")return setCloneIdx((i)=>Math.min(options.length-1,i+1));return}if(field==="alias"){if(key2.name==="space"||key2.name===" ")return setAlias((a)=>!a)}});let focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New Profile"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:valid||!name?theme.text:theme.error,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" a-z 0-9 _ - \xB7 lowercase"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsx("text",{fg:theme.textMuted,children:"Clone from (\u2191\u2193)"})}),options.map((o,i)=>$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsxs("text",{fg:i===cloneIdx?theme.accent:theme.text,children:[i===cloneIdx?"\u25B8 ":" ",o]})},o)),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] shell alias":"[ ] shell alias"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:valid?"Enter create \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel":err??"type a name"})})]})};var import_react71=__toESM(require_react_production(),1);import{rmSync as rmSync2,mkdtempSync as mkdtempSync2}from"fs";import{join as join10}from"path";import{tmpdir as tmpdir2}from"os";var shq=(s)=>`'${s.replace(/'/g,"'\\''")}'`;function openInstallDistribution(dialog,gw){return new Promise((resolve4)=>{askSource(dialog,gw,(r)=>{dialog.clear(),resolve4(r)})})}function askSource(dialog,gw,done){dialog.replace($jsx(Step1,{onSubmit:(source)=>preview(dialog,gw,source,done),onCancel:()=>done(null)}))}async function preview(dialog,gw,source,done){let tmp=mkdtempSync2(join10(tmpdir2(),"herm-dist-preview-")),cleanup=()=>{try{rmSync2(tmp,{recursive:!0,force:!0})}catch{}},state2={cancelled:!1},cancel=()=>{state2.cancelled=!0,cleanup(),done(null)};dialog.replace($jsx(Loading,{label:`Cloning ${source}\u2026`,onCancel:cancel}),void 0,{ownCancel:!0});let cmd=`git clone --depth 1 --quiet ${shq(source)} ${shq(tmp)} 2>&1`,r=await gw.request("shell.exec",{command:cmd}).catch((e)=>({stdout:"",stderr:e.message,code:-1}));if(state2.cancelled)return;if(r.code!==0){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Clone failed",body:(r.stderr||r.stdout||`exit ${r.code}`).trim(),onClose:()=>done(null)}));return}let manifest=readDistributionManifest(tmp);if(!manifest){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Not a distribution",body:`No valid distribution.yaml at the root of ${source}. A manifest must declare at minimum a 'name:' key.`,onClose:()=>done(null)}));return}dialog.replace($jsx(ConfirmStep,{source,manifest,onConfirm:(r2)=>{cleanup(),done(r2)},onCancel:()=>{cleanup(),done(null)}}),void 0,{ownCancel:!0})}var Step1=(p)=>{let theme=useTheme().theme,[value,setValue]=import_react71.useState("");return useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Source \u2014 git URL, github.com/owner/repo, or local directory"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:setValue,onSubmit:()=>{let v2=value.trim();if(v2)p.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value.trim()?"Enter preview \xB7 Esc cancel":"Esc cancel"})})]})},Loading=(p)=>{let theme=useTheme().theme;return useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:p.label})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to cancel"})})]})},ErrorBox=(p)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key2)=>{if(keys.match("dialog.accept",key2)||keys.match("dialog.cancel",key2))return p.onClose()}),$jsxs("box",{flexDirection:"column",width:68,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter / Esc to close"})})]})},ORDER3=["name","alias"],ConfirmStep=(p)=>{let theme=useTheme().theme,keys=useKeys(),[name,setName]=import_react71.useState(""),[alias,setAlias]=import_react71.useState(!1),[field,setField]=import_react71.useState("name"),fire=()=>p.onConfirm({source:p.source,manifest:p.manifest,name:name.trim()||null,alias}),move=(dir)=>{let i=ORDER3.indexOf(field);setField(ORDER3[(i+dir+ORDER3.length)%ORDER3.length])};useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel();if(key2.name==="tab")return move(key2.shift?-1:1);if(field!=="name"&&keys.match("dialog.accept",key2))return fire();if(field==="alias"&&(key2.name==="space"||key2.name===" "))return setAlias((a)=>!a)});let m2=p.manifest,reqEnv=m2.env_requires.filter((e)=>e.required),optEnv=m2.env_requires.filter((e)=>!e.required),focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx(KV2,{label:"Name",value:`${m2.name}${m2.version?` v${m2.version}`:""}`,theme}),m2.description?$jsx(KV2,{label:"About",value:m2.description,theme,wrap:!0}):null,m2.author?$jsx(KV2,{label:"Author",value:m2.author,theme}):null,m2.license?$jsx(KV2,{label:"License",value:m2.license,theme}):null,m2.hermes_requires?$jsx(KV2,{label:"Requires",value:`hermes ${m2.hermes_requires}`,theme}):null,$jsx(KV2,{label:"Source",value:p.source,theme}),m2.distribution_owned.length>0?$jsx(KV2,{label:"Owns",value:m2.distribution_owned.join(", "),theme,wrap:!0}):null,m2.env_requires.length>0?$jsx(KV2,{label:"Env",value:envSummary(reqEnv,optEnv),theme}):null,$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name as"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:field==="name"?$jsx("input",{value:name,onInput:setName,onSubmit:fire,focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}):$jsx("text",{fg:name?theme.text:theme.textMuted,children:name||`(${m2.name})`})})]}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] create shell wrapper":"[ ] create shell wrapper"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter install \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel"})})]})},KV2=(p)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:11,flexShrink:0,children:$jsx("text",{fg:p.theme.textMuted,children:p.label})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:p.theme.text,wrapMode:p.wrap?"word":"none",children:p.value})})]});function envSummary(req,opt){return[req.length>0?`${req.length} required (${req.map((e)=>e.name).join(", ")})`:"",opt.length>0?`${opt.length} optional`:""].filter(Boolean).join(" \xB7 ")}var running=(s)=>!s||s==="running"||s==="queued";function tree(recs,live,now){let ids=new Set(recs.map((r)=>r.subagent_id)),by=new Map;for(let r of recs){let k2=r.parent_id&&ids.has(r.parent_id)?r.parent_id:"";(by.get(k2)??by.set(k2,[]).get(k2)).push(r)}let build2=(r)=>{let kids=(by.get(r.subagent_id)??[]).map(build2),lv=live.get(r.subagent_id)??{},dur3=r.started_at!=null?Math.max(0,now-r.started_at):0,a={agents:1,tools:lv.tool_count??r.tool_count??0,dur:dur3,tok:(lv.input_tokens??0)+(lv.output_tokens??0),cost:lv.cost_usd??0,active:running(lv.status??r.status)?1:0,depth:0,hot:0};for(let k2 of kids)a={agents:a.agents+k2.agg.agents,tools:a.tools+k2.agg.tools,dur:a.dur+k2.agg.dur,tok:a.tok+k2.agg.tok,cost:a.cost+k2.agg.cost,active:a.active+k2.agg.active,depth:Math.max(a.depth,k2.agg.depth+1),hot:0};return a.hot=a.dur>0?a.tools/a.dur:0,{rec:r,agg:a,kids}};return(by.get("")??[]).map(build2)}function totals(nodes){let z2={agents:0,tools:0,dur:0,tok:0,cost:0,active:0,depth:0,hot:0};for(let n of nodes)z2.agents+=n.agg.agents,z2.tools+=n.agg.tools,z2.dur+=n.agg.dur,z2.tok+=n.agg.tok,z2.cost+=n.agg.cost,z2.active+=n.agg.active,z2.depth=Math.max(z2.depth,n.agg.depth+1);return z2.hot=z2.dur>0?z2.tools/z2.dur:0,z2}var SPARK=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function spark(nodes){let w2=[],walk=(ns,d2)=>{if(ns.length===0)return;w2[d2]=(w2[d2]??0)+ns.length;for(let n of ns)walk(n.kids,d2+1)};if(walk(nodes,0),w2.length===0)return"";let max=Math.max(...w2);return w2.map((v2)=>v2<=0?" ":SPARK[Math.min(7,Math.ceil(v2/max*7))]).join("")}var tk=(n)=>n<1000?String(Math.round(n)):n<1e4?`${(n/1000).toFixed(1)}k`:`${Math.round(n/1000)}k`,$$=(n)=>n<=0?"":n<0.01?"<$0.01":n<10?`$${n.toFixed(2)}`:`$${n.toFixed(1)}`,sec=(s)=>{if(s<60)return`${Math.round(s)}s`;let m2=Math.floor(s/60),r=Math.round(s-m2*60);return r===0?`${m2}m`:`${m2}m${r}s`};function summary(a){let p=[`d${a.depth}`,`${a.agents} agent${a.agents===1?"":"s"}`];if(a.tools>0)p.push(`${a.tools} tools`);if(a.dur>0)p.push(sec(a.dur));if(a.tok>0)p.push(`${tk(a.tok)} tok`);if(a.cost>0)p.push($$(a.cost));if(a.active>0)p.push(`\u26A1${a.active}`);return p.join(" \xB7 ")}function heat(hot,peak,buckets){if(hot<=0||peak<=0||buckets<=1)return 0;return Math.min(buckets-1,Math.round(Math.min(1,hot/peak)*(buckets-1)))}function peak(nodes){let p=0,walk=(ns)=>{for(let n of ns)p=Math.max(p,n.agg.hot),walk(n.kids)};return walk(nodes),p}var ProfileRow=import_react73.memo((props)=>{let theme=useTheme().theme,{p,idx:i}=props,[x2,setX]=import_react73.useState(!1);return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),onMouseDown:()=>props.onEnter(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:p.is_active?theme.accent:theme.text,children:p.is_active?$jsx("strong",{children:p.name}):p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605"}):null,p.distribution?$jsx("span",{fg:theme.info,children:" \u2B22"}):null,p.gateway_running?$jsx("span",{fg:theme.success,children:" \u25CF"}):null]})}),$jsx("box",{width:4,height:1,children:$jsx("text",{fg:theme.textMuted,children:p.is_active?" you":""})}),p.is_default||p.is_active?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})}),DistBlock=import_react73.memo((props)=>{let theme=useTheme().theme,d2=props.d,req=d2.env_requires.filter((e)=>e.required).length,opt=d2.env_requires.length-req,link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Distribution"})})}),$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed at",Number.isFinite(when2)?ago(when2/1000):void 0],["Env vars",d2.env_requires.length?`${req} required, ${opt} optional`:void 0]]})]})}),ProfileDetail=import_react73.memo((props)=>{let{theme,syntaxStyle}=useTheme(),p=props.p,s=props.stats;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{height:1,children:$jsxs("text",{fg:theme.accent,children:[$jsx("strong",{children:p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605 sticky default"}):null]})}),$jsx("box",{height:1}),$jsx(KVLink,{label:"Path",source:p.sources.dir,text:p.sources.dir.relative}),$jsx(KV,{label:"Active",value:p.is_active?"yes (this session)":"no",fg:p.is_active?theme.accent:theme.textMuted}),$jsx(KV,{label:"Model",value:p.model??"\u2014"}),$jsx(KV,{label:"Provider",value:p.provider??"\u2014"}),$jsx(KV,{label:"Skills",value:String(p.skill_count)}),$jsx(KV,{label:"Sessions",value:s?s.sessions==null?"\u2014":`${fmt(s.sessions)} (${fmt(s.messages??0)} msgs)`:"\u2026"}),$jsx(KV,{label:"Cron jobs",value:s?s.crons==null?"\u2014":String(s.crons):"\u2026"}),$jsx(KV,{label:"Theme",value:s?s.prefs?.theme??"\u2014":"\u2026"}),$jsx(KV,{label:"Avatar",value:s?s.prefs?.eikon??"\u2014":"\u2026"}),s?.prefs?.keys?$jsx(KV,{label:"Keybinds",value:`${s.prefs.keys} overrides`}):null,$jsx(KV,{label:"Gateway",value:p.gateway_running?"running":"stopped",fg:p.gateway_running?theme.success:theme.textMuted}),p.has_alias?$jsx(KV,{label:"Alias",value:`${p.name} (shell)`}):null,p.distribution?$jsx(DistBlock,{d:p.distribution,yaml:p.sources.distribution}):null,$jsx("box",{height:1}),$jsx(KVLink,{label:"Config",source:p.sources.config}),$jsx(KVLink,{label:"Soul",source:p.sources.soul}),p.has_env?$jsx(KVLink,{label:"Env",source:p.sources.env}):$jsx(KV,{label:"Env",value:"\u2014"}),p.soul_preview?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"SOUL.md"})}),$jsx("markdown",{content:p.soul_preview,fg:theme.markdownText,syntaxStyle})]}):null]})})}),HOT=["\u2800","\u2801","\u2803","\u2807","\u280F","\u281F","\u283F","\u287F","\u28FF"],DelegRow=import_react73.memo((props)=>{let theme=useTheme().theme,{r,idx:i,now}=props,[x2,setX]=import_react73.useState(!1),up=r.started_at?dur2(now-r.started_at):"\u2014",hotFg=[theme.textMuted,theme.textMuted,theme.text,theme.info,theme.info,theme.accent,theme.accent,theme.warning,theme.error][props.hot]??theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{width:2,children:$jsxs("text",{fg:hotFg,children:[HOT[props.hot]," "]})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\xB7 ".repeat(r.depth)}),$jsx("span",{fg:theme.text,children:r.goal.replace(/\s+/g," ")})]})}),$jsx("box",{width:14,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:trunc5(r.model??"",13)})}),$jsx("box",{width:5,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:String(r.tool_count??0)})}),$jsx("box",{width:8,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:up})}),$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onKill(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})});function preorder(recs){let byParent=new Map;for(let r of recs){let k2=r.parent_id??null;(byParent.get(k2)??byParent.set(k2,[]).get(k2)).push(r)}let out=[],seen=new Set,walk=(k2)=>{for(let r of byParent.get(k2)??[]){if(seen.has(r.subagent_id))continue;seen.add(r.subagent_id),out.push(r),walk(r.subagent_id)}};walk(null);for(let r of recs)if(!seen.has(r.subagent_id))out.push(r);return out}var DelegDetail=import_react73.memo((props)=>{let theme=useTheme().theme,{r,live,agg,now}=props,tc=live?.tool_count??r.tool_count??0,tr=trail(r.subagent_id);return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.accent,wrapMode:"word",children:$jsx("strong",{children:r.goal})})}),agg&&agg.agents>1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:summary(agg)})}):null,$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",live?.status??r.status??"running"],["Model",r.model??"\u2014"],["Depth",String(r.depth)],["Parent",r.parent_id??"(root)"],["Uptime",r.started_at?dur2(now-r.started_at):"\u2014"],["Tools",String(tc)],["Tokens",live?`${fmt(live.input_tokens??0)} in / ${fmt(live.output_tokens??0)} out`:void 0],["Cost",live?.cost_usd!=null?`$${live.cost_usd.toFixed(4)}`:void 0]]}),live?.thinking?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"thinking"})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:trunc5(live.thinking,200)})})]}):null,tr.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"recent tools"})}),tr.slice(-8).map((t2,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:t2.name.padEnd(14)}),$jsx("span",{fg:theme.textMuted,children:t2.preview?trunc5(t2.preview.replace(/\s+/g," "),40):""})]})},i))]}):null]})})}),Agents=import_react73.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),[pane,setPane]=import_react73.useState("profiles"),[pView,setPView]=import_react73.useState("list"),[profiles,setProfiles]=import_react73.useState([]),[deleg,setDeleg]=import_react73.useState(null),[liveMap,setLiveMap]=import_react73.useState(()=>new Map),[now,setNow]=import_react73.useState(()=>Date.now()/1000),[pSel,setPSel]=import_react73.useState(0),[dSel,setDSel]=import_react73.useState(0),[err,setErr]=import_react73.useState(""),active=preorder(deleg?.active??[]),nodes=tree(deleg?.active??[],liveMap,now),all=totals(nodes),hotPeak=peak(nodes),aggOf=new Map;{let walk=(ns)=>{for(let n of ns)aggOf.set(n.rec.subagent_id,n.agg),walk(n.kids)};walk(nodes)}let live=import_react73.useRef({profiles,active});live.current={profiles,active};let gwHome=import_react73.useRef(void 0),[stats,setStats]=import_react73.useState(()=>new Map),[sticky,setSticky]=import_react73.useState(stickyDefault),loadProfiles=import_react73.useCallback(()=>{setStats(new Map),setSticky(stickyDefault()),listProfiles(gwHome.current).then((ps)=>{setProfiles(ps),setErr("")}).catch((e)=>setErr(`profiles: ${e.message}`))},[]);import_react73.useEffect(()=>{gw.request("config.get",{key:"profile"}).then((r)=>{gwHome.current=r.home}).catch(()=>{}).finally(loadProfiles)},[gw,loadProfiles]);let loadDeleg=import_react73.useCallback(()=>{gw.request("delegation.status").then((r)=>{setDeleg(r),setNow(Date.now()/1000)}).catch(()=>setDeleg({active:[],paused:!1,max_spawn_depth:0,max_concurrent_children:0}))},[gw]);import_react73.useEffect(loadDeleg,[loadDeleg]),import_react73.useEffect(()=>{if(!props.focused)return;let ms2=(deleg?.active.length??0)>0?1500:5000,t2=setInterval(loadDeleg,ms2);return()=>clearInterval(t2)},[props.focused,deleg?.active.length,loadDeleg]),useGatewayEvent((ev)=>{if(!ev.type.startsWith("subagent."))return;let p=ev.payload,id=p.subagent_id;if(!id)return;if(setLiveMap((prev)=>{let next=new Map(prev),cur=next.get(id)??{tool_count:0};switch(ev.type){case"subagent.start":next.set(id,{tool_count:0});break;case"subagent.tool":next.set(id,{...cur,tool_count:cur.tool_count+1,last_tool:p.tool_name,last_preview:p.tool_preview});break;case"subagent.thinking":next.set(id,{...cur,thinking:p.text});break;case"subagent.complete":next.set(id,{...cur,status:p.status,input_tokens:p.input_tokens,output_tokens:p.output_tokens,cost_usd:p.cost_usd});break}return next}),ev.type==="subagent.start"||ev.type==="subagent.complete")loadDeleg()});let sh=import_react73.useCallback((cmd2)=>gw.request("shell.exec",{command:cmd2}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||"exit "+r.code).trim());return r.stdout}),[gw]),pHover=import_react73.useCallback((i)=>setPSel(i),[]),dHover=import_react73.useCallback((i)=>setDSel(i),[]),pDelete=import_react73.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_default||p.is_active)return;let warn=p.gateway_running?`
|
|
4107
|
+
`,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 start=-1;for(let i=0;i<=text2.length;i++)if(i<text2.length&&!used[i]){if(start<0)start=i}else if(start>=0){let slice=text2.slice(start,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start=-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_react55=__toESM(require_react_production(),1);var FileLink=import_react55.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react55.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 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 fmt2=(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_react56.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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt2(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_react56.memo(({seg,theme,label:label2,chars,limit,pct,entries:entries2,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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:label2})}),source?$jsxs($Fragment,{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:[entries2.length," entries:"]}),entries2.map((e,i)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",e]},i))]})),SkillsPanel=import_react56.memo(({seg,theme})=>{let sec=seg.section;if(!sec)return null;let cats={};for(let line2 of sec.text.split(`
|
|
4108
|
+
`)){if(line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line2.match(/^\s{4}- \S+:/)){let last2=Object.keys(cats).pop();if(last2)cats[last2]++}}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 ",fmt2(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_react56.memo(({seg,theme,tools,kind:kind2})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label2=kind2==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind2==="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(kind2,theme),children:"\u25FC"})," ",label2," \u2014 ",fmt2(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," (",fmt2(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react56.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 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt2(est(user.map((m2)=>text(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt2(est(asst.map((m2)=>text(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt2(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment,{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"})," ","(",fmt2(est(text(m2))),") ",text(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react56.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 ",fmt2(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt2(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt2(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt2(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment,{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:[" (",fmt2(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([]),toolsFromInfo=(info)=>{if(!info?.tools)return null;let tools=Object.entries(info.tools).flatMap(([group,names])=>names.map((name)=>({name,descriptionLength:0,paramsLength:group.length})));if(tools.length===0)return null;return{source:makeSource("state.db","session.info"),tools}},Context=import_react56.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_react56.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react56.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react56.useState(null),[selected,setSelected]=import_react56.useState(null),[drilled,setDrilled]=import_react56.useState(null);import_react56.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_react56.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react56.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text(m2)).join("")),[messages]),currentTools=import_react56.useMemo(()=>toolsFromInfo(info)??toolsInfo,[info,toolsInfo]),top=import_react56.useMemo(()=>build({contextLength:ctxLen,inputTokens:fill,sections,conversationTokens:convTok,tools:currentTools?.tools??[]}),[ctxLen,fill,sections,convTok,currentTools]),drilledGroup=drilled?top.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top,grid=import_react56.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_react56.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react56.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_react56.useRef(0),segs=view.filter((s)=>s.tokens>0),idx=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx):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"&¤tTools){let{system}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&¤tTools){let{mcp}=classifyTools(currentTools.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," (",fmt2(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 ",fmt2(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 ",fmt2(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("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:`Context \xB7 ${fmt2(fill)} / ${fmt2(ctxLen)} (${pct}%)`,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt2(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,row2)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row2*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=row2*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)})},row2))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]}),$jsx(HintBar,{raw:crumb+escHint})]})});var import_react58=__toESM(require_react_production(),1);init_hermes_analytics();var BLOCKS=" \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588",rows2=(vals,h2)=>{let peak=Math.max(1,...vals),ticks=vals.map((v2)=>Math.round(h2*8*v2/peak));return Array.from({length:h2},(_2,r)=>{let floor=(h2-1-r)*8;return ticks.map((t2)=>BLOCKS[Math.max(0,Math.min(8,t2-floor))]).join("")})},Chart=import_react58.memo((p)=>{let theme=useTheme().theme,days=p.data.byDay,vals=days.map((d2)=>d2.cost),peak=Math.max(...vals,0.01),axis=(v2)=>cost(v2).padStart(7),md=(s)=>s.slice(5);return $jsxs("box",{flexDirection:"column",children:[rows2(vals,p.h).map((line2,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:i===0?axis(peak):i===p.h-1?axis(0):""})}),$jsx("text",{fg:theme.primary,children:line2})]},i)),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0}),$jsx("text",{fg:theme.textMuted,children:days.length>0?`${md(days[0].date)}${" ".repeat(Math.max(0,days.length-10))}${md(days[days.length-1].date)}`:""})]})]})}),Rank=import_react58.memo((p)=>{let theme=useTheme().theme;if(p.rows===null)return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),$jsx("box",{height:1,children:$jsx(Spinner,{label:"aggregating\u2026"})})]});let top=p.rows.slice(0,p.n??10),peak=Math.max(1,...top.map((r)=>r.n)),total=p.rows.reduce((a,r)=>a+r.n,0);return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),top.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"\u2014"})}):top.map((r)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{w:18,children:trunc5(r.name,17)}),$jsx(Col,{w:12,fg:p.fg,children:"\u2587".repeat(Math.max(1,Math.round(10*r.n/peak)))}),$jsx(Col,{w:7,right:!0,children:fmt(r.n)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:total?`${Math.round(100*r.n/total)}%`:""})]},r.name))]})}),Analytics=import_react58.memo((props)=>{let theme=useTheme().theme,dims=useTerminalDimensions(),[days,setDays]=import_react58.useState(7),[data2,setData]=import_react58.useState(()=>cache3.get(days)??null),[tools,setTools]=import_react58.useState(()=>cache3.get(days)?.byTool??null),[tick2,setTick]=import_react58.useState(0),gen=import_react58.useRef(0);import_react58.useEffect(()=>{let hit=cache3.get(days);setData(hit??null),setTools(hit?.byTool??null);let g=++gen.current;return io.analytics(days,{tools:!1}).then((fast)=>{if(gen.current!==g)return;setData(fast),io.analytics(days).then((full)=>{if(gen.current!==g)return;cache3.set(days,full),setData(full),setTools(full.byTool)})}),()=>{gen.current++}},[days,tick2]);let keys=useKeys();useKeyboard((key2)=>{if(!props.focused)return;if(keys.match("list.refresh",key2))return cache3.delete(days),setTick((n)=>n+1);if(key2.raw==="1")return setDays(1);if(key2.raw==="7")return setDays(7);if(key2.raw==="3")return setDays(30);if(key2.raw==="9")return setDays(90)});let t2=data2?.total,tok=(t2?.input??0)+(t2?.output??0),title=import_react58.useMemo(()=>!t2?`Analytics \xB7 ${days}d`:`Analytics \xB7 ${days}d \xB7 ${t2.sessions} sess \xB7 ${fmt(tok)} tok \xB7 ${cost(t2.cost)}`,[days,t2,tok]),wide=dims.width>=110,chartH=dims.height>=40?8:6;if(!data2)return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsx("box",{height:1,children:$jsx(Spinner,{label:`aggregating ${days}d\u2026`})})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]});let nTools=8,nSrc=6,ranksH=wide?Math.max(nTools,nSrc)+1:nTools+nSrc+3;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,overflow:"hidden",children:[$jsxs("box",{flexShrink:0,flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`Cost per day \xB7 ${fmt(t2.input)} in \xB7 ${fmt(t2.output)} out \xB7 ${fmt(t2.cache)} cache \xB7 ${fmt(t2.calls)} tool calls`})}),$jsx(Chart,{data:data2,h:chartH})]}),$jsx("box",{height:1,flexShrink:0}),$jsx("box",{flexShrink:0,children:$jsxs(Hdr,{children:[$jsx(Col,{grow:!0,min:18,fg:theme.textMuted,children:"Model"}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:"sess"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"in"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"out"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cache"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cost"})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,flexShrink:1,minHeight:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.byModel.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"no sessions in range"})}):data2.byModel.map((m2)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{grow:!0,min:18,children:trunc5(m2.model,40)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:String(m2.sessions)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.input)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.output)}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:fmt(m2.cache)}),$jsx(Col,{w:9,right:!0,fg:theme.accent,children:cost(m2.cost)})]},m2.model))})}),$jsx("box",{height:1,flexShrink:0}),$jsxs("box",{flexShrink:0,height:ranksH,flexDirection:wide?"row":"column",gap:wide?2:1,children:[$jsx(Rank,{title:"Tools",rows:tools,fg:theme.success,n:nTools}),$jsx(Rank,{title:"Sources",rows:data2.bySource,fg:theme.info,n:nSrc})]})]})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]})});var import_react60=__toESM(require_react_production(),1);var SubTabBar=import_react60.memo((props)=>$jsx(TabStrip,{...props}));var TABS=[{name:"Chat",description:"Main chat interface"},{name:"Sessions",description:"Sessions, context, analytics"},{name:"Profiles & Automation",description:"Profiles, cron jobs, kanban boards"},{name:"Config",description:"Config, env, skills, toolsets, memory"},{name:"Eikon",description:"Avatar studio & gallery"}],TAB_MAX=TABS.length-1,CHAT_TAB=0,SESSIONS_TAB=1,AUTOMATION_TAB=2,CONFIG_TAB=3,EIKON_TAB=4,SUB_TABS={[1]:["List","Context","Analytics"],[2]:["Kanban","Profiles","Cron"],[3]:["Config","Skills","Toolsets","Env","Memory"],[4]:["Studio","Gallery"]},TAB_SLASH={chat:{tab:0,sub:0},sessions:{tab:1,sub:0},context:{tab:1,sub:1},analytics:{tab:1,sub:2},insights:{tab:1,sub:2},kanban:{tab:2,sub:0},automation:{tab:2,sub:0},profiles:{tab:2,sub:1},agents:{tab:2,sub:1},cron:{tab:2,sub:2},config:{tab:3,sub:0},skills:{tab:3,sub:1},toolsets:{tab:3,sub:2},env:{tab:3,sub:3},memory:{tab:3,sub:4},studio:{tab:4,sub:0},gallery:{tab:4,sub:1}};var SessionsGroup=import_react61.memo((props)=>{let keys=useKeys(),labels=SUB_TABS[SESSIONS_TAB];import_react61.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint=`${keys.print("tab.prev")}/${keys.print("tab.next")} group \xB7 shift+\u2190/\u2192 sub`;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane,{visible:props.sub===0,children:$jsx(Sessions,{focused:!!props.focused&&props.sub===0,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId})}),$jsx(Pane,{visible:props.sub===1,children:$jsx(Context,{focused:!!props.focused&&props.sub===1,messages:props.messages,sessionStart:props.sessionStart,info:props.info})}),$jsx(Pane,{visible:props.sub===2,children:$jsx(Analytics,{focused:!!props.focused&&props.sub===2})})]})]})}),Pane=({visible,children:children2})=>visible?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react82=__toESM(require_react_production(),1);var import_react73=__toESM(require_react_production(),1);var acc=new Map;function record(ev,p){let id=p.subagent_id;if(!id)return;let now=Date.now()/1000;if(ev==="start"){acc.set(id,{subagent_id:id,parent_id:p.parent_id??null,depth:p.depth??0,goal:p.goal,model:p.model,started_at:now,tool_count:0,status:"running",trail:[]});return}let r=acc.get(id);if(!r)return;if(ev==="tool"&&p.tool_name){r.tool_count++,r.trail=[...r.trail??[],{name:p.tool_name,preview:p.tool_preview}].slice(-20);return}if(ev==="complete")r.status=p.status??"completed",r.finished_at=now,r.input_tokens=p.input_tokens,r.output_tokens=p.output_tokens,r.cost_usd=p.cost_usd}function trail(id){return acc.get(id)?.trail??[]}function flush(gw,sessionId){if(acc.size===0)return;let subagents=[...acc.values()];acc.clear();let label2=(subagents.filter((s)=>s.parent_id==null).slice(0,2).map((s)=>s.goal).join(" \xB7 ")||`${subagents.length} subagents`).slice(0,120),started=Math.min(...subagents.map((s)=>s.started_at));gw.request("spawn_tree.save",{session_id:sessionId,label:label2,started_at:started,finished_at:Date.now()/1000,subagents}).catch(()=>{})}var import_react64=__toESM(require_react_production(),1);var import_react62=__toESM(require_react_production(),1);var DialogSelect=(props)=>{let filterable=props.filterable??!0,[filter,setFilter]=import_react62.useState(""),[cursor,setCursor]=import_react62.useState(0),mode=import_react62.useRef("kb"),moved=import_react62.useRef(!1),sb=import_react62.useRef(null),theme=useTheme().theme,filtered=import_react62.useMemo(()=>{let lower=filter.toLowerCase();return props.options.filter((o)=>o.title.toLowerCase().includes(lower)||(o.description??"").toLowerCase().includes(lower))},[filter,props.options]),groups=import_react62.useMemo(()=>{let map=new Map;return filtered.forEach((o)=>{let cat=o.category??"",arr=map.get(cat)??[];arr.push(o),map.set(cat,arr)}),map},[filtered]),rowId=(i)=>`ds-row-${i}`,scrollTo=(i)=>sb.current?.scrollChildIntoView(rowId(i));import_react62.useEffect(()=>{if(cursor>=filtered.length)setCursor(Math.max(0,filtered.length-1))},[filtered.length,cursor]),import_react62.useEffect(()=>{if(!props.current){setCursor(0);return}let i=filtered.findIndex((o)=>o.value===props.current),n=Math.max(0,i);setCursor(n),scrollTo(n)},[props.current,filtered]),import_react62.useEffect(()=>{if(!moved.current)return;moved.current=!1;let item=filtered[cursor];if(item&&props.onMove)props.onMove(item)},[cursor,filtered,props.onMove]);let keys=useKeys();useKeyboard((key2)=>{let onToggle=!filterable?()=>{let item=filtered[cursor];if(item)props.onSelect(item)}:void 0;if(handleListKey(keys,key2,{count:filtered.length,setSel:(fn)=>{mode.current="kb",moved.current=!0,setCursor(fn)},scrollTo,page:Math.max(1,(sb.current?.viewport.height??10)-1),onActivate:()=>{let item=filtered[cursor];if(item)props.onSelect(item)},onToggle}))return;if(props.onKey?.(key2))return});let idx=0,entries2=Array.from(groups.entries());return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),filterable?$jsxs($Fragment,{children:[$jsx("input",{value:filter,onInput:(v2)=>{mode.current="kb",setFilter(v2)},placeholder:props.placeholder??"Type to filter...",focused:!0,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}),$jsx("box",{height:1})]}):null,$jsxs("scrollbox",{ref:sb,scrollY:!0,maxHeight:16,focused:!filterable,contentOptions:{flexDirection:"column"},paddingRight:1,children:[filtered.length===0?$jsx("text",{fg:theme.textMuted,children:"No results found"}):null,entries2.map(([cat,items])=>{let elements=[];if(cat)elements.push($jsx("text",{fg:theme.textMuted,children:$jsx("strong",{children:cat})},`cat-${cat}`));return items.forEach((item)=>{let i=idx++,active=i===cursor,current=item.value===props.current;elements.push($jsxs("box",{id:rowId(i),flexDirection:"row",backgroundColor:active?theme.backgroundElement:void 0,onMouseMove:()=>{mode.current="mouse",moved.current=!0,setCursor((c)=>c===i?c:i)},onMouseOver:()=>{if(mode.current==="mouse")moved.current=!0,setCursor(i)},onMouseDown:()=>props.onSelect(item),paddingLeft:1,paddingRight:1,children:[$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsxs("text",{fg:active?theme.text:theme.textMuted,children:[current?"\u25CF ":" ",item.title,item.description?` \u2014 ${item.description}`:""]})}),item.hint?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:item.hint})}):null]},item.value))}),elements}).flat()]}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]})};var Ctx6=import_react64.createContext(null),CommandProvider=({children:children2})=>{let registry=import_react64.useRef(new Map),enabled2=import_react64.useRef(!0),dialog=useDialog(),keys=useKeys(),all=import_react64.useCallback(()=>{let out=[];return registry.current.forEach((cmds)=>cmds.forEach((c)=>out.push(c))),out},[]),register=import_react64.useCallback((cmds)=>{let id=String(Date.now())+Math.random();return registry.current.set(id,cmds),()=>{registry.current.delete(id)}},[]),setEnabled=import_react64.useCallback((val)=>{enabled2.current=val},[]),open2=import_react64.useCallback(()=>{let cmds=all(),options=cmds.map((c)=>({title:c.title,value:c.value,description:c.description,hint:c.action?keys.print(c.action):void 0,category:c.category}));dialog.replace($jsx(DialogSelect,{title:"Command Palette",options,onSelect:(opt)=>{dialog.clear();let found=cmds.find((c)=>c.value===opt.value);if(found)found.onSelect()},placeholder:"Search commands..."}))},[all,dialog,keys]);useKeyboard((key2)=>{if(!enabled2.current||dialog.open())return;if(keys.match("palette.open",key2))return open2();for(let c of all())if(c.action&&keys.match(c.action,key2))return c.onSelect()});let value=import_react64.useMemo(()=>({register,setEnabled}),[register,setEnabled]);return $jsx(Ctx6.Provider,{value,children:children2})},useCommand=makeUse(Ctx6,"useCommand");var Status=({s})=>{let theme=useTheme().theme,fg2=s==="completed"?theme.success:s==="failed"?theme.error:s==="error"?theme.error:s==="timeout"?theme.error:s==="interrupted"?theme.warning:theme.textMuted;return $jsx("span",{fg:fg2,children:s})},SnapshotView=(props)=>{let theme=useTheme().theme,subs2=props.snap.subagents??[],tok=subs2.reduce((n,s)=>n+(s.input_tokens??0)+(s.output_tokens??0),0),span2=props.snap.started_at&&props.snap.finished_at?dur2(props.snap.finished_at-props.snap.started_at):"\u2014";return $jsxs("box",{flexDirection:"column",width:80,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.entry.label||`${subs2.length} subagents`})}),$jsxs("text",{fg:theme.textMuted,children:[when(props.entry.finished_at)," \xB7 ",span2," \xB7 ",subs2.length," agents \xB7 ",fmt(tok)," tok"]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,contentOptions:{flexDirection:"column"},children:subs2.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "+"\xB7 ".repeat(s.depth)}),$jsx("span",{fg:theme.text,children:trunc5(s.goal.replace(/\s+/g," "),60)})]})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["\u2503 "+" ".repeat(2*s.depth+2),$jsx(Status,{s:s.status}),` \xB7 ${s.tool_count}t`,s.finished_at?` \xB7 ${dur2(s.finished_at-s.started_at)}`:"",s.model?` \xB7 ${s.model}`:""]})})]},s.subagent_id))})]})};function openSpawnHistory(dialog,gw,sessionId){gw.request("spawn_tree.list",{session_id:sessionId,limit:50}).then((r)=>{let entries2=r.entries??[];dialog.replace($jsx(DialogSelect,{title:"Spawn history",placeholder:entries2.length?"filter\u2026":"no saved spawn trees",options:entries2.map((e)=>({value:e.path,title:`${e.count.toString().padStart(2)}\xD7 ${trunc5(e.label||"(unlabeled)",40)}`,description:when(e.finished_at),category:e.session_id===sessionId?"This session":e.session_id})),onSelect:(opt)=>{let entry2=entries2.find((e)=>e.path===opt.value);gw.request("spawn_tree.load",{path:entry2.path}).then((snap)=>dialog.replace($jsx(SnapshotView,{entry:entry2,snap}))).catch(()=>dialog.clear())}}))}).catch(()=>dialog.clear())}var import_react67=__toESM(require_react_production(),1);var Dialog=(props)=>{let theme=useTheme().theme,keys=useKeys();useKeyboard((key2)=>{if(keys.match("dialog.cancel",key2)||keys.match("dialog.accept",key2))return props.onClose()});let d2=props.d,req=d2.env_requires.filter((e)=>e.required),opt=d2.env_requires.filter((e)=>!e.required),link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs("box",{flexDirection:"column",minWidth:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Distribution \xB7 ${props.profile}`})})}),$jsxs("box",{flexDirection:"column",children:[$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0],["Author",d2.author||void 0],["License",d2.license||void 0],["Description",d2.description||void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed",Number.isFinite(when2)?ago(when2/1000):void 0],["Owned",d2.distribution_owned.length?d2.distribution_owned.join(", "):void 0]]})]}),d2.env_requires.length?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Environment variables"})})}),req.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Required"})}),req.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null,opt.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Optional"})}),opt.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null]}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:`[${keys.print("dialog.cancel")}] close`})})]})},EnvRow=(props)=>{let theme=useTheme().theme,tail=[props.desc,props.fallback?`default: ${props.fallback}`:""].filter(Boolean).join(" \xB7 ");return $jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:" "})}),$jsx("box",{width:22,flexShrink:0,children:$jsx("text",{fg:theme.accent,children:props.name})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:tail})})]})};function openDistributionInfo(dialog,opts){dialog.replace($jsx(Dialog,{profile:opts.profile,d:opts.d,yaml:opts.yaml,onClose:()=>dialog.clear()}))}function openProfileMenu(dialog,p,ops){let opts=[...ops.switch&&!p.is_active?[{category:"Switch",value:"switch",title:`Switch to '${p.name}'`,description:"restart gateway under this HERMES_HOME \u2014 ends current session"}]:[],{category:"Open",value:"soul",title:"SOUL.md",description:"edit persona/system prompt"},{category:"Open",value:"config",title:"config.yaml",description:"model, provider, toolsets"},...p.has_env?[{category:"Open",value:"env",title:".env",description:"API keys + secrets"}]:[],{category:"Open",value:"dir",title:"Directory",description:p.path},...p.distribution?[{category:"Distribution",value:"dist-info",title:"Info",description:`v${p.distribution.version}${p.distribution.source?` \xB7 ${p.distribution.source}`:""}`},{category:"Distribution",value:"dist-update",title:"Update",description:`hermes profile update ${p.name}${p.is_active?" \xB7 ends current session":""}`}]:[],...p.is_sticky?[{category:"Default",value:"unsticky",title:"Clear sticky default",description:"hermes profile use --clear"}]:[{category:"Default",value:"sticky",title:"Set as sticky default",description:`hermes profile use ${p.name}`}],{category:"Manage",value:"export",title:"Export",description:`hermes profile export ${p.name}`},...p.is_default||p.is_active?[]:[{category:"Manage",value:"delete",title:"Delete",description:"irreversible \u2014 removes config, env, memory, sessions"}]];dialog.replace($jsx(DialogSelect,{title:`Profile \xB7 ${p.name}${p.is_active?" (active)":""}`,options:opts,onSelect:(o)=>{if(o.value==="dist-info"){if(!p.distribution)return dialog.clear();return openDistributionInfo(dialog,{profile:p.name,d:p.distribution,yaml:p.sources.distribution})}if(o.value==="dist-update"){if(!p.distribution)return dialog.clear();return openUpdateDistribution(dialog,p,(force)=>ops.update(p,force))}if(dialog.clear(),o.value==="switch")return ops.switch?.();if(o.value==="soul")return openFile(p.sources.soul.file);if(o.value==="config")return openFile(p.sources.config.file);if(o.value==="env")return openFile(p.sources.env.file);if(o.value==="dir")return openFile(p.path);if(o.value==="sticky")return ops.sticky(p);if(o.value==="unsticky")return ops.unsticky();if(o.value==="export")return ops.export(p);if(o.value==="delete")return ops.remove(p)}}))}var UpdateForm=(props)=>{let theme=useTheme().theme,keys=useKeys(),[force,setForce]=import_react67.useState(!1);useKeyboard((key2)=>{if(keys.match("dialog.cancel",key2)||keys.match("dialog.deny",key2))return props.done(null);if(keys.match("dialog.confirm",key2)||keys.match("dialog.accept",key2))return props.done(force);if(key2.name==="space"||key2.name===" ")return setForce((f)=>!f)});let d2=props.p.distribution;return $jsxs("box",{flexDirection:"column",width:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:"Update distribution?"})})}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:`'${props.p.name}' \xB7 v${d2.version}${d2.source?` \xB7 ${d2.source}`:""}`})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:"Re-pulls from source; distribution-owned files are overwritten."})}),props.p.is_active?$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.warning,children:"\u26A0 This is the active profile. The gateway will re-spawn "+"and the current session will end."})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:force?theme.warning:theme.textMuted,children:`${force?"[x]":"[ ]"} --force-config \xB7 also overwrite config.yaml`})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}] update [Space] toggle force [${keys.print("dialog.cancel")}] cancel`})})]})};function openUpdateDistribution(dialog,p,onConfirm){dialog.replace($jsx(UpdateForm,{p,done:(force)=>{if(dialog.clear(),force!==null)onConfirm(force)}}))}var import_react69=__toESM(require_react_production(),1);import{existsSync as existsSync12,readFileSync as readFileSync4}from"fs";import{readdir as readdir3}from"fs/promises";import{homedir as homedir6}from"os";import{join as join9,basename as basename8,dirname as dirname5}from"path";import{Database as Database2}from"bun:sqlite";var home3=()=>process.env.HOME||homedir6(),hermesHome=()=>process.env.HERMES_HOME||join9(home3(),".hermes");function root(){let hh=hermesHome(),parent2=dirname5(hh);return basename8(parent2)==="profiles"?dirname5(parent2):hh}function profileNameFrom(hh){let parent2=dirname5(hh);return basename8(parent2)==="profiles"?basename8(hh):"default"}function activeProfileName(){return profileNameFrom(hermesHome())}function stickyDefault(){try{return readFileSync4(join9(root(),"active_profile"),"utf-8").trim()||null}catch{return null}}var ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/;function readModel(dir){try{let raw=readFileSync4(join9(dir,"config.yaml"),"utf-8"),block=raw.split(/^model:\s*$/m)[1]?.split(/^\S/m)[0]??"",m2=block.match(/^\s+(?:default|model):\s*(.+)$/m)?.[1]?.trim()??raw.match(/^model:\s*(\S.+)$/m)?.[1]?.trim(),p=block.match(/^\s+provider:\s*(.+)$/m)?.[1]?.trim(),clean=(s)=>s?.replace(/^["']|["']$/g,"")??null;return[clean(m2),clean(p)]}catch{return[null,null]}}async function countSkills(dir){let glob=new Bun.Glob("**/SKILL.md"),n=0;try{for await(let _2 of glob.scan({cwd:join9(dir,"skills"),onlyFiles:!0}))n++}catch{}return n}function gatewayRunning(dir){try{let raw=readFileSync4(join9(dir,"gateway.pid"),"utf-8").trim(),pid2=raw.startsWith("{")?Number(JSON.parse(raw).pid):Number(raw);if(!Number.isFinite(pid2)||pid2<=0)return!1;return process.kill(pid2,0),!0}catch{return!1}}function soul(dir){try{return readFileSync4(join9(dir,"SOUL.md"),"utf-8").replace(/^#[^\n]*\n+/,"").replace(/^\s+/,"").slice(0,400)}catch{return""}}function readDistributionManifest(dir){let path7=join9(dir,"distribution.yaml");if(!existsSync12(path7))return null;let data2=(()=>{try{return $parse(readFileSync4(path7,"utf-8"))}catch{return null}})();if(!data2||typeof data2!=="object"||Array.isArray(data2))return null;let d2=data2,name=typeof d2.name==="string"?d2.name.trim():"";if(!name)return null;let envs=(Array.isArray(d2.env_requires)?d2.env_requires:[]).flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e,n=typeof r.name==="string"?r.name.trim():"";if(!n)return[];return[{name:n,description:typeof r.description==="string"?r.description:"",required:r.required===void 0?!0:Boolean(r.required),default:typeof r.default==="string"?r.default:null}]}),owned=(Array.isArray(d2.distribution_owned)?d2.distribution_owned:[]).map((p)=>typeof p==="string"?p.trim().replace(/\/+$/,""):"").filter((p)=>p.length>0);return{name,version:typeof d2.version==="string"?d2.version:"0.1.0",description:typeof d2.description==="string"?d2.description:"",hermes_requires:typeof d2.hermes_requires==="string"?d2.hermes_requires:"",author:typeof d2.author==="string"?d2.author:"",license:typeof d2.license==="string"?d2.license:"",env_requires:envs,distribution_owned:owned,source:typeof d2.source==="string"?d2.source:"",installed_at:typeof d2.installed_at==="string"?d2.installed_at:""}}var src=(file,label2)=>({file,relative:file.replace(home3()+"/","~/"),label:label2});async function info(name,dir,active,sticky){let[model,provider]=readModel(dir),alias=join9(home3(),".local","bin",name);return{name,path:dir,is_default:name==="default",is_active:name===active,is_sticky:name===sticky,gateway_running:gatewayRunning(dir),model,provider,has_env:existsSync12(join9(dir,".env")),skill_count:await countSkills(dir),has_alias:name!=="default"&&existsSync12(alias),soul_preview:soul(dir),distribution:readDistributionManifest(dir),sources:{dir:src(dir,dir.replace(home3()+"/","~/")),config:src(join9(dir,"config.yaml"),"config.yaml"),soul:src(join9(dir,"SOUL.md"),"SOUL.md"),env:src(join9(dir,".env"),".env"),distribution:src(join9(dir,"distribution.yaml"),"distribution.yaml")}}}async function listProfiles(activeHome){let r=root(),active=profileNameFrom(activeHome??hermesHome()),sticky=stickyDefault(),jobs=[];if(existsSync12(r))jobs.push(info("default",r,active,sticky));let pr=join9(r,"profiles");if(existsSync12(pr))for(let e of await readdir3(pr,{withFileTypes:!0})){if(!e.isDirectory()||!ID_RE.test(e.name))continue;jobs.push(info(e.name,join9(pr,e.name),active,sticky))}return Promise.all(jobs)}function validateName(name,existing){if(!ID_RE.test(name))return"must match [a-z0-9][a-z0-9_-]{0,63}";if(existing.includes(name))return"already exists";if(["hermes","default","test","tmp","root","sudo"].includes(name))return"reserved name";return null}function readPrefs(dir){try{let raw=JSON.parse(readFileSync4(join9(dir,"herm","tui.json"),"utf-8"));return{theme:raw.theme,eikon:raw.eikon??(raw.eikonPath?basename8(raw.eikonPath,".eikon"):void 0),keys:raw.keys?Object.keys(raw.keys).length:0}}catch{return null}}async function profileStats(dir){let sessions=null,messages=null,dbPath=join9(dir,"state.db");if(existsSync12(dbPath))try{let db=new Database2(dbPath,{readwrite:!0,create:!1}),r=db.query("SELECT COUNT(*) AS s FROM sessions WHERE message_count > 0").get(),m2=db.query("SELECT COALESCE(SUM(message_count), 0) AS m FROM sessions").get();sessions=r.s,messages=m2.m,db.close()}catch{}let crons=null;try{let jobs=await Bun.file(join9(dir,"cron","jobs.json")).json();crons=Array.isArray(jobs)?jobs.length:jobs&&typeof jobs==="object"&&Array.isArray(jobs.jobs)?jobs.jobs.length:0}catch{crons=existsSync12(join9(dir,"cron"))?0:null}return{sessions,messages,crons,prefs:readPrefs(dir)}}var ORDER2=["name","clone","alias"];function openCreateProfile(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form,{existing:opts.existing,done}))})}var Form=({existing,done})=>{let theme=useTheme().theme,[name,setName]=import_react69.useState(""),[cloneIdx,setCloneIdx]=import_react69.useState(0),[alias,setAlias]=import_react69.useState(!0),[field,setField]=import_react69.useState("name"),options=["(fresh)",...existing],err=name?validateName(name,existing):null,valid=!!name&&!err,submit=()=>{if(!valid)return;done({name,cloneFrom:cloneIdx===0?null:options[cloneIdx],alias})},moveField=(dir)=>{let i=ORDER2.indexOf(field);setField(ORDER2[(i+dir+ORDER2.length)%ORDER2.length])};useKeyboard((key2)=>{if(key2.name==="escape")return done(null);if(key2.name==="tab")return moveField(key2.shift?-1:1);if(key2.name==="return")return submit();if(field==="name"){if(key2.name==="backspace")return setName((n)=>n.slice(0,-1));if(key2.raw&&key2.raw.length===1&&/[a-z0-9_-]/.test(key2.raw))return setName((n)=>n+key2.raw);return}if(field==="clone"){if(key2.name==="up")return setCloneIdx((i)=>Math.max(0,i-1));if(key2.name==="down")return setCloneIdx((i)=>Math.min(options.length-1,i+1));return}if(field==="alias"){if(key2.name==="space"||key2.name===" ")return setAlias((a)=>!a)}});let focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New Profile"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:valid||!name?theme.text:theme.error,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" a-z 0-9 _ - \xB7 lowercase"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsx("text",{fg:theme.textMuted,children:"Clone from (\u2191\u2193)"})}),options.map((o,i)=>$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsxs("text",{fg:i===cloneIdx?theme.accent:theme.text,children:[i===cloneIdx?"\u25B8 ":" ",o]})},o)),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] shell alias":"[ ] shell alias"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:valid?"Enter create \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel":err??"type a name"})})]})};var import_react71=__toESM(require_react_production(),1);import{rmSync as rmSync2,mkdtempSync as mkdtempSync2}from"fs";import{join as join10}from"path";import{tmpdir as tmpdir2}from"os";var shq=(s)=>`'${s.replace(/'/g,"'\\''")}'`;function openInstallDistribution(dialog,gw){return new Promise((resolve4)=>{askSource(dialog,gw,(r)=>{dialog.clear(),resolve4(r)})})}function askSource(dialog,gw,done){dialog.replace($jsx(Step1,{onSubmit:(source)=>preview(dialog,gw,source,done),onCancel:()=>done(null)}))}async function preview(dialog,gw,source,done){let tmp=mkdtempSync2(join10(tmpdir2(),"herm-dist-preview-")),cleanup=()=>{try{rmSync2(tmp,{recursive:!0,force:!0})}catch{}},state2={cancelled:!1},cancel=()=>{state2.cancelled=!0,cleanup(),done(null)};dialog.replace($jsx(Loading,{label:`Cloning ${source}\u2026`,onCancel:cancel}),void 0,{ownCancel:!0});let cmd=`git clone --depth 1 --quiet ${shq(source)} ${shq(tmp)} 2>&1`,r=await gw.request("shell.exec",{command:cmd}).catch((e)=>({stdout:"",stderr:e.message,code:-1}));if(state2.cancelled)return;if(r.code!==0){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Clone failed",body:(r.stderr||r.stdout||`exit ${r.code}`).trim(),onClose:()=>done(null)}));return}let manifest=readDistributionManifest(tmp);if(!manifest){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Not a distribution",body:`No valid distribution.yaml at the root of ${source}. A manifest must declare at minimum a 'name:' key.`,onClose:()=>done(null)}));return}dialog.replace($jsx(ConfirmStep,{source,manifest,onConfirm:(r2)=>{cleanup(),done(r2)},onCancel:()=>{cleanup(),done(null)}}),void 0,{ownCancel:!0})}var Step1=(p)=>{let theme=useTheme().theme,[value,setValue]=import_react71.useState("");return useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Source \u2014 git URL, github.com/owner/repo, or local directory"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:setValue,onSubmit:()=>{let v2=value.trim();if(v2)p.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value.trim()?"Enter preview \xB7 Esc cancel":"Esc cancel"})})]})},Loading=(p)=>{let theme=useTheme().theme;return useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:p.label})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to cancel"})})]})},ErrorBox=(p)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key2)=>{if(keys.match("dialog.accept",key2)||keys.match("dialog.cancel",key2))return p.onClose()}),$jsxs("box",{flexDirection:"column",width:68,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter / Esc to close"})})]})},ORDER3=["name","alias"],ConfirmStep=(p)=>{let theme=useTheme().theme,keys=useKeys(),[name,setName]=import_react71.useState(""),[alias,setAlias]=import_react71.useState(!1),[field,setField]=import_react71.useState("name"),fire=()=>p.onConfirm({source:p.source,manifest:p.manifest,name:name.trim()||null,alias}),move=(dir)=>{let i=ORDER3.indexOf(field);setField(ORDER3[(i+dir+ORDER3.length)%ORDER3.length])};useKeyboard((key2)=>{if(key2.name==="escape")return p.onCancel();if(key2.name==="tab")return move(key2.shift?-1:1);if(field!=="name"&&keys.match("dialog.accept",key2))return fire();if(field==="alias"&&(key2.name==="space"||key2.name===" "))return setAlias((a)=>!a)});let m2=p.manifest,reqEnv=m2.env_requires.filter((e)=>e.required),optEnv=m2.env_requires.filter((e)=>!e.required),focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx(KV2,{label:"Name",value:`${m2.name}${m2.version?` v${m2.version}`:""}`,theme}),m2.description?$jsx(KV2,{label:"About",value:m2.description,theme,wrap:!0}):null,m2.author?$jsx(KV2,{label:"Author",value:m2.author,theme}):null,m2.license?$jsx(KV2,{label:"License",value:m2.license,theme}):null,m2.hermes_requires?$jsx(KV2,{label:"Requires",value:`hermes ${m2.hermes_requires}`,theme}):null,$jsx(KV2,{label:"Source",value:p.source,theme}),m2.distribution_owned.length>0?$jsx(KV2,{label:"Owns",value:m2.distribution_owned.join(", "),theme,wrap:!0}):null,m2.env_requires.length>0?$jsx(KV2,{label:"Env",value:envSummary(reqEnv,optEnv),theme}):null,$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name as"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:field==="name"?$jsx("input",{value:name,onInput:setName,onSubmit:fire,focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}):$jsx("text",{fg:name?theme.text:theme.textMuted,children:name||`(${m2.name})`})})]}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] create shell wrapper":"[ ] create shell wrapper"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter install \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel"})})]})},KV2=(p)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:11,flexShrink:0,children:$jsx("text",{fg:p.theme.textMuted,children:p.label})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:p.theme.text,wrapMode:p.wrap?"word":"none",children:p.value})})]});function envSummary(req,opt){return[req.length>0?`${req.length} required (${req.map((e)=>e.name).join(", ")})`:"",opt.length>0?`${opt.length} optional`:""].filter(Boolean).join(" \xB7 ")}var running=(s)=>!s||s==="running"||s==="queued";function tree(recs,live,now){let ids=new Set(recs.map((r)=>r.subagent_id)),by=new Map;for(let r of recs){let k2=r.parent_id&&ids.has(r.parent_id)?r.parent_id:"";(by.get(k2)??by.set(k2,[]).get(k2)).push(r)}let build2=(r)=>{let kids=(by.get(r.subagent_id)??[]).map(build2),lv=live.get(r.subagent_id)??{},dur3=r.started_at!=null?Math.max(0,now-r.started_at):0,a={agents:1,tools:lv.tool_count??r.tool_count??0,dur:dur3,tok:(lv.input_tokens??0)+(lv.output_tokens??0),cost:lv.cost_usd??0,active:running(lv.status??r.status)?1:0,depth:0,hot:0};for(let k2 of kids)a={agents:a.agents+k2.agg.agents,tools:a.tools+k2.agg.tools,dur:a.dur+k2.agg.dur,tok:a.tok+k2.agg.tok,cost:a.cost+k2.agg.cost,active:a.active+k2.agg.active,depth:Math.max(a.depth,k2.agg.depth+1),hot:0};return a.hot=a.dur>0?a.tools/a.dur:0,{rec:r,agg:a,kids}};return(by.get("")??[]).map(build2)}function totals(nodes){let z2={agents:0,tools:0,dur:0,tok:0,cost:0,active:0,depth:0,hot:0};for(let n of nodes)z2.agents+=n.agg.agents,z2.tools+=n.agg.tools,z2.dur+=n.agg.dur,z2.tok+=n.agg.tok,z2.cost+=n.agg.cost,z2.active+=n.agg.active,z2.depth=Math.max(z2.depth,n.agg.depth+1);return z2.hot=z2.dur>0?z2.tools/z2.dur:0,z2}var SPARK=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function spark(nodes){let w2=[],walk=(ns,d2)=>{if(ns.length===0)return;w2[d2]=(w2[d2]??0)+ns.length;for(let n of ns)walk(n.kids,d2+1)};if(walk(nodes,0),w2.length===0)return"";let max=Math.max(...w2);return w2.map((v2)=>v2<=0?" ":SPARK[Math.min(7,Math.ceil(v2/max*7))]).join("")}var tk=(n)=>n<1000?String(Math.round(n)):n<1e4?`${(n/1000).toFixed(1)}k`:`${Math.round(n/1000)}k`,$$=(n)=>n<=0?"":n<0.01?"<$0.01":n<10?`$${n.toFixed(2)}`:`$${n.toFixed(1)}`,sec=(s)=>{if(s<60)return`${Math.round(s)}s`;let m2=Math.floor(s/60),r=Math.round(s-m2*60);return r===0?`${m2}m`:`${m2}m${r}s`};function summary(a){let p=[`d${a.depth}`,`${a.agents} agent${a.agents===1?"":"s"}`];if(a.tools>0)p.push(`${a.tools} tools`);if(a.dur>0)p.push(sec(a.dur));if(a.tok>0)p.push(`${tk(a.tok)} tok`);if(a.cost>0)p.push($$(a.cost));if(a.active>0)p.push(`\u26A1${a.active}`);return p.join(" \xB7 ")}function heat(hot,peak,buckets){if(hot<=0||peak<=0||buckets<=1)return 0;return Math.min(buckets-1,Math.round(Math.min(1,hot/peak)*(buckets-1)))}function peak(nodes){let p=0,walk=(ns)=>{for(let n of ns)p=Math.max(p,n.agg.hot),walk(n.kids)};return walk(nodes),p}var ProfileRow=import_react73.memo((props)=>{let theme=useTheme().theme,{p,idx:i}=props,[x2,setX]=import_react73.useState(!1);return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),onMouseDown:()=>props.onEnter(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:p.is_active?theme.accent:theme.text,children:p.is_active?$jsx("strong",{children:p.name}):p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605"}):null,p.distribution?$jsx("span",{fg:theme.info,children:" \u2B22"}):null,p.gateway_running?$jsx("span",{fg:theme.success,children:" \u25CF"}):null]})}),$jsx("box",{width:4,height:1,children:$jsx("text",{fg:theme.textMuted,children:p.is_active?" you":""})}),p.is_default||p.is_active?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})}),DistBlock=import_react73.memo((props)=>{let theme=useTheme().theme,d2=props.d,req=d2.env_requires.filter((e)=>e.required).length,opt=d2.env_requires.length-req,link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Distribution"})})}),$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed at",Number.isFinite(when2)?ago(when2/1000):void 0],["Env vars",d2.env_requires.length?`${req} required, ${opt} optional`:void 0]]})]})}),ProfileDetail=import_react73.memo((props)=>{let{theme,syntaxStyle}=useTheme(),p=props.p,s=props.stats;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{height:1,children:$jsxs("text",{fg:theme.accent,children:[$jsx("strong",{children:p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605 sticky default"}):null]})}),$jsx("box",{height:1}),$jsx(KVLink,{label:"Path",source:p.sources.dir,text:p.sources.dir.relative}),$jsx(KV,{label:"Active",value:p.is_active?"yes (this session)":"no",fg:p.is_active?theme.accent:theme.textMuted}),$jsx(KV,{label:"Model",value:p.model??"\u2014"}),$jsx(KV,{label:"Provider",value:p.provider??"\u2014"}),$jsx(KV,{label:"Skills",value:String(p.skill_count)}),$jsx(KV,{label:"Sessions",value:s?s.sessions==null?"\u2014":`${fmt(s.sessions)} (${fmt(s.messages??0)} msgs)`:"\u2026"}),$jsx(KV,{label:"Cron jobs",value:s?s.crons==null?"\u2014":String(s.crons):"\u2026"}),$jsx(KV,{label:"Theme",value:s?s.prefs?.theme??"\u2014":"\u2026"}),$jsx(KV,{label:"Avatar",value:s?s.prefs?.eikon??"\u2014":"\u2026"}),s?.prefs?.keys?$jsx(KV,{label:"Keybinds",value:`${s.prefs.keys} overrides`}):null,$jsx(KV,{label:"Gateway",value:p.gateway_running?"running":"stopped",fg:p.gateway_running?theme.success:theme.textMuted}),p.has_alias?$jsx(KV,{label:"Alias",value:`${p.name} (shell)`}):null,p.distribution?$jsx(DistBlock,{d:p.distribution,yaml:p.sources.distribution}):null,$jsx("box",{height:1}),$jsx(KVLink,{label:"Config",source:p.sources.config}),$jsx(KVLink,{label:"Soul",source:p.sources.soul}),p.has_env?$jsx(KVLink,{label:"Env",source:p.sources.env}):$jsx(KV,{label:"Env",value:"\u2014"}),p.soul_preview?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"SOUL.md"})}),$jsx("markdown",{content:p.soul_preview,fg:theme.markdownText,syntaxStyle})]}):null]})})}),HOT=["\u2800","\u2801","\u2803","\u2807","\u280F","\u281F","\u283F","\u287F","\u28FF"],DelegRow=import_react73.memo((props)=>{let theme=useTheme().theme,{r,idx:i,now}=props,[x2,setX]=import_react73.useState(!1),up=r.started_at?dur2(now-r.started_at):"\u2014",hotFg=[theme.textMuted,theme.textMuted,theme.text,theme.info,theme.info,theme.accent,theme.accent,theme.warning,theme.error][props.hot]??theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{width:2,children:$jsxs("text",{fg:hotFg,children:[HOT[props.hot]," "]})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\xB7 ".repeat(r.depth)}),$jsx("span",{fg:theme.text,children:r.goal.replace(/\s+/g," ")})]})}),$jsx("box",{width:14,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:trunc5(r.model??"",13)})}),$jsx("box",{width:5,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:String(r.tool_count??0)})}),$jsx("box",{width:8,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:up})}),$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onKill(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})});function preorder(recs){let byParent=new Map;for(let r of recs){let k2=r.parent_id??null;(byParent.get(k2)??byParent.set(k2,[]).get(k2)).push(r)}let out=[],seen=new Set,walk=(k2)=>{for(let r of byParent.get(k2)??[]){if(seen.has(r.subagent_id))continue;seen.add(r.subagent_id),out.push(r),walk(r.subagent_id)}};walk(null);for(let r of recs)if(!seen.has(r.subagent_id))out.push(r);return out}var DelegDetail=import_react73.memo((props)=>{let theme=useTheme().theme,{r,live,agg,now}=props,tc=live?.tool_count??r.tool_count??0,tr=trail(r.subagent_id);return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.accent,wrapMode:"word",children:$jsx("strong",{children:r.goal})})}),agg&&agg.agents>1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:summary(agg)})}):null,$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",live?.status??r.status??"running"],["Model",r.model??"\u2014"],["Depth",String(r.depth)],["Parent",r.parent_id??"(root)"],["Uptime",r.started_at?dur2(now-r.started_at):"\u2014"],["Tools",String(tc)],["Tokens",live?`${fmt(live.input_tokens??0)} in / ${fmt(live.output_tokens??0)} out`:void 0],["Cost",live?.cost_usd!=null?`$${live.cost_usd.toFixed(4)}`:void 0]]}),live?.thinking?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"thinking"})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:trunc5(live.thinking,200)})})]}):null,tr.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"recent tools"})}),tr.slice(-8).map((t2,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:t2.name.padEnd(14)}),$jsx("span",{fg:theme.textMuted,children:t2.preview?trunc5(t2.preview.replace(/\s+/g," "),40):""})]})},i))]}):null]})})}),Agents=import_react73.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),[pane,setPane]=import_react73.useState("profiles"),[pView,setPView]=import_react73.useState("list"),[profiles,setProfiles]=import_react73.useState([]),[deleg,setDeleg]=import_react73.useState(null),[liveMap,setLiveMap]=import_react73.useState(()=>new Map),[now,setNow]=import_react73.useState(()=>Date.now()/1000),[pSel,setPSel]=import_react73.useState(0),[dSel,setDSel]=import_react73.useState(0),[err,setErr]=import_react73.useState(""),active=preorder(deleg?.active??[]),nodes=tree(deleg?.active??[],liveMap,now),all=totals(nodes),hotPeak=peak(nodes),aggOf=new Map;{let walk=(ns)=>{for(let n of ns)aggOf.set(n.rec.subagent_id,n.agg),walk(n.kids)};walk(nodes)}let live=import_react73.useRef({profiles,active});live.current={profiles,active};let gwHome=import_react73.useRef(void 0),[stats,setStats]=import_react73.useState(()=>new Map),[sticky,setSticky]=import_react73.useState(stickyDefault),loadProfiles=import_react73.useCallback(()=>{setStats(new Map),setSticky(stickyDefault()),listProfiles(gwHome.current).then((ps)=>{setProfiles(ps),setErr("")}).catch((e)=>setErr(`profiles: ${e.message}`))},[]);import_react73.useEffect(()=>{gw.request("config.get",{key:"profile"}).then((r)=>{gwHome.current=r.home}).catch(()=>{}).finally(loadProfiles)},[gw,loadProfiles]);let loadDeleg=import_react73.useCallback(()=>{gw.request("delegation.status").then((r)=>{setDeleg(r),setNow(Date.now()/1000)}).catch(()=>setDeleg({active:[],paused:!1,max_spawn_depth:0,max_concurrent_children:0}))},[gw]);import_react73.useEffect(loadDeleg,[loadDeleg]),import_react73.useEffect(()=>{if(!props.focused)return;let ms2=(deleg?.active.length??0)>0?1500:5000,t2=setInterval(loadDeleg,ms2);return()=>clearInterval(t2)},[props.focused,deleg?.active.length,loadDeleg]),useGatewayEvent((ev)=>{if(!ev.type.startsWith("subagent."))return;let p=ev.payload,id=p.subagent_id;if(!id)return;if(setLiveMap((prev)=>{let next=new Map(prev),cur=next.get(id)??{tool_count:0};switch(ev.type){case"subagent.start":next.set(id,{tool_count:0});break;case"subagent.tool":next.set(id,{...cur,tool_count:cur.tool_count+1,last_tool:p.tool_name,last_preview:p.tool_preview});break;case"subagent.thinking":next.set(id,{...cur,thinking:p.text});break;case"subagent.complete":next.set(id,{...cur,status:p.status,input_tokens:p.input_tokens,output_tokens:p.output_tokens,cost_usd:p.cost_usd});break}return next}),ev.type==="subagent.start"||ev.type==="subagent.complete")loadDeleg()});let sh=import_react73.useCallback((cmd2)=>gw.request("shell.exec",{command:cmd2}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||"exit "+r.code).trim());return r.stdout}),[gw]),pHover=import_react73.useCallback((i)=>setPSel(i),[]),dHover=import_react73.useCallback((i)=>setDSel(i),[]),pDelete=import_react73.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_default||p.is_active)return;let warn=p.gateway_running?`
|
|
4109
4109
|
|
|
4110
4110
|
Its gateway is running and will be stopped first (may take up to ~10s).`:"";if(!await openConfirm(dialog,{title:"Delete Profile?",body:`'${p.name}' \u2014 config, env, memory, skills, and sessions will be removed. This cannot be undone.${warn}`,yes:"delete",danger:!0}))return;sh(`hermes profile delete ${p.name} -y`).then(()=>{toast.show({variant:"success",message:`Deleted '${p.name}'`}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),pSwitch=import_react73.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_active||!props.onSwitchProfile)return;if(await openConfirm(dialog,{title:`Switch to '${p.name}'?`,body:"The gateway restarts under this profile's HERMES_HOME. The current session ends (it stays in the outgoing profile's history).",yes:"switch"}))props.onSwitchProfile(p.path,p.name)},[dialog,props.onSwitchProfile]),pUpdate=import_react73.useCallback((p,force)=>{let cmd2=`hermes profile update ${p.name} -y${force?" --force-config":""}`;toast.show({variant:"info",message:`Updating '${p.name}'\u2026`}),sh(cmd2).then(()=>{if(toast.show({variant:"success",message:`Updated '${p.name}'`}),p.is_active&&props.onSwitchProfile){props.onSwitchProfile(p.path,p.name);return}loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,toast,loadProfiles,props.onSwitchProfile]),pEnter=import_react73.useCallback((i)=>{setPSel(i);let p=live.current.profiles[i];if(!p)return;openProfileMenu(dialog,p,{switch:props.onSwitchProfile?()=>pSwitch(i):void 0,sticky:(pp)=>sh(`hermes profile use ${pp.name}`).then(()=>{toast.show({variant:"success",message:`Sticky default \u2192 '${pp.name}'`}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message})),unsticky:()=>sh("hermes profile use --clear").then(()=>{toast.show({variant:"info",message:"Cleared sticky default"}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message})),export:(pp)=>sh(`hermes profile export ${pp.name}`).then((out)=>toast.show({variant:"success",message:trunc5(out.trim()||`Exported '${pp.name}'`,80)})).catch((e)=>toast.show({variant:"error",message:e.message})),remove:()=>pDelete(i),update:(pp,force)=>pUpdate(pp,force)})},[sh,dialog,toast,loadProfiles,pDelete,pSwitch,pUpdate,props.onSwitchProfile]),dKill=import_react73.useCallback(async(i)=>{let r=live.current.active[i];if(!r)return;if(!await openConfirm(dialog,{title:"Interrupt subagent?",body:`${trunc5(r.goal,120)}
|
|
4111
4111
|
|
|
4112
|
-
The child returns whatever partial result it has so far.`,yes:"interrupt",danger:!0}))return;gw.request("subagent.interrupt",{subagent_id:r.subagent_id}).then((res)=>{toast.show(res.found?{variant:"success",message:`Interrupted ${r.subagent_id}`}:{variant:"info",message:"Already finished"}),loadDeleg()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,loadDeleg]),create=import_react73.useCallback(()=>{openCreateProfile(dialog,{existing:live.current.profiles.map((p)=>p.name)}).then((r)=>{if(!r)return;let flags=[r.cloneFrom?`--clone --clone-from ${r.cloneFrom}`:"",r.alias?"":"--no-alias"].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Creating '${r.name}'\u2026`}),sh(`hermes profile create ${r.name} ${flags}`.trim()).then(()=>{toast.show({variant:"success",message:`Created '${r.name}'`}),loadProfiles()})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),install2=import_react73.useCallback(()=>{openInstallDistribution(dialog,gw).then((r)=>{if(!r)return;let shq2=(s)=>`'${s.replace(/'/g,"'\\''")}'`,flags=[r.name?`--name ${shq2(r.name)}`:"",r.alias?"--alias":""].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Installing '${r.manifest.name}'\u2026`}),sh(`hermes profile install ${shq2(r.source)} -y ${flags}`.trim()).then(()=>{let installed=r.name||r.manifest.name;toast.show({variant:"success",message:`Installed '${installed}'`}),loadProfiles();let reqs=r.manifest.env_requires.filter((e)=>e.required).map((e)=>e.name);if(reqs.length>0)toast.show({variant:"warning",title:"Env vars needed",message:`${reqs.join(", ")} \u2014 add to the profile's .env before using it`,duration:6000})})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,sh,dialog,toast,loadProfiles]),selected=profiles[pSel],statGen=import_react73.useRef(0);import_react73.useEffect(()=>{let path7=selected?.path;if(!path7||stats.has(path7))return;let g=++statGen.current;profileStats(path7).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path7,s))})},[selected?.path,stats]);let dims=useTerminalDimensions(),wide=dims.width>=130,pWide=dims.width>=170||!wide&&dims.width>=90,pFollow=useFollow("prof"),dFollow=useFollow("deleg"),keys=useKeys();useKeyboard((key2)=>{if(!props.focused||dialog.open())return;if(key2.name==="tab")return setPane((p)=>p==="profiles"?"deleg":"profiles");if(keys.match("list.refresh",key2)){loadProfiles(),loadDeleg(),toast.show({variant:"info",message:"Reloaded",duration:1000});return}if(pane==="profiles"){if(key2.name==="escape"&&!pWide&&pView==="detail")return setPView("list");if(key2.name==="s")return void pSwitch(pSel);if(keys.match("agents.install",key2))return install2();handleListKey(keys,key2,{count:profiles.length,setSel:setPSel,...pFollow.opts,onNew:create,onDelete:()=>pDelete(pSel),onActivate:()=>{if(!pWide&&pView==="list")return setPView("detail");pEnter(pSel)}});return}if(handleListKey(keys,key2,{count:active.length,setSel:setDSel,...dFollow.opts,onDelete:()=>dKill(dSel)}))return;if(keys.match("agents.kill",key2))return dKill(dSel);if(keys.match("agents.history",key2))return openSpawnHistory(dialog,gw,props.sessionId)});let showProfiles=wide||pane==="profiles",showDeleg=wide||pane==="deleg",showList=pWide||pView==="list",showDetail=pWide||pView==="detail",limits=deleg?`depth\u2264${deleg.max_spawn_depth} \xB7 conc\u2264${deleg.max_concurrent_children}`:"",dHint=active.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react73.useCallback(()=>{let next=!deleg?.paused;gw.request("delegation.pause",{paused:next}).then((r)=>{setDeleg((d2)=>d2?{...d2,paused:r.paused}:d2),toast.show({variant:"info",message:r.paused?"Delegation paused":"Delegation resumed"})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,deleg?.paused]);import_react73.useEffect(()=>cmd.register([{title:deleg?.paused?"Resume Delegation":"Pause Delegation",value:"deleg.pause",category:"Agents",onSelect:togglePause},{title:"Install Distribution\u2026",value:"profile.install",category:"Agents",description:"from git URL or local directory",onSelect:install2}]),[cmd,togglePause,deleg?.paused,install2]);let pair=(k2,v2)=>`[${k2}] ${v2}`,join11=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join11("[\u2191\u2193] nav",pair(keys.print("list.activate"),"actions"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("agents.install"),"install"),pair(keys.print("list.delete"),"delete"),pair(keys.print("list.refresh"),"refresh")):pView==="list"?join11("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join11(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join11("[\u2191\u2193] nav",pair(keys.print("agents.kill"),"interrupt"),pair(keys.print("agents.history"),"history"),pair(keys.print("list.refresh"),"refresh")),delegHint=dHint?`${delegKeys} \xB7 ${dHint}`:delegKeys,footerHint=wide?pane==="profiles"?`${profilesHint} \xB7 ${delegHint}`:`${delegHint} \xB7 ${profilesHint}`:pane==="profiles"?profilesHint:delegHint;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[showProfiles?$jsx(TabShell,{title:`Profiles (${profiles.length})${sticky?` \xB7 \u2605 ${sticky}`:""}`,error:err||null,focus:pane==="profiles",grow:3,children:$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[showList?$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:14,children:$jsx("scrollbox",{ref:pFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:profiles.length===0?$jsx("box",{height:1,children:err?$jsx("text",{fg:theme.textMuted,children:"\u2014"}):$jsx(Spinner,{color:theme.textMuted,label:"scanning profiles\u2026"})}):profiles.map((p,i)=>$jsx(ProfileRow,{id:pFollow.id(i),p,idx:i,selected:i===pSel,onHover:pHover,onEnter:pEnter,onDelete:pDelete},p.name))})}):null,showList&&showDetail?$jsx("box",{width:2}):null,showDetail?$jsx("box",{flexDirection:"column",flexGrow:2,flexBasis:0,minWidth:0,children:selected?$jsx(ProfileDetail,{p:selected,stats:stats.get(selected.path)}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No profiles"})})}):null]})}):null,showDeleg?$jsxs(TabShell,{title:`Delegation (${active.length})`,focus:pane==="deleg",grow:2,children:[$jsxs("box",{height:1,flexDirection:"row",marginBottom:1,children:[$jsx("box",{flexShrink:0,paddingX:1,backgroundColor:deleg?.paused?theme.warning:theme.backgroundElement,onMouseDown:togglePause,children:$jsx("text",{fg:deleg?.paused?theme.background:theme.text,children:deleg?.paused?"\u23F8 paused":"\u25B6 active"})}),$jsx("box",{flexGrow:1}),$jsxs("text",{fg:theme.textMuted,children:["click to ",deleg?.paused?"resume":"pause"]})]}),active.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:deleg?.paused?"Paused \u2014 new subagents will queue":"No subagents running \xB7 h for history"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx("scrollbox",{ref:dFollow.ref,scrollY:!0,flexGrow:3,flexBasis:0,verticalScrollbarOptions:VBAR,children:active.map((r,i)=>{let lv=liveMap.get(r.subagent_id),row2=lv?{...r,tool_count:lv.tool_count}:r,h2=heat(aggOf.get(r.subagent_id)?.hot??0,hotPeak,HOT.length);return $jsx(DelegRow,{id:dFollow.id(i),r:row2,idx:i,selected:i===dSel,now,hot:h2,onHover:dHover,onKill:dKill},r.subagent_id)})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.border,children:"\u2500".repeat(4)})}),$jsx("box",{flexGrow:2,flexBasis:0,minHeight:0,children:active[dSel]?$jsx(DelegDetail,{r:active[dSel],live:liveMap.get(active[dSel].subagent_id),agg:aggOf.get(active[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react75=__toESM(require_react_production(),1);var normalize=(j2)=>({id:j2.job_id??j2.id??"",name:j2.name??"",prompt:j2.prompt??j2.prompt_preview??"",schedule:j2.schedule??"",enabled:j2.enabled??!0,state:j2.state??"scheduled",deliver:j2.deliver??"local",repeat:j2.repeat,last_run:j2.last_run_at,next_run:j2.next_run_at,last_status:j2.last_status==="ok"||j2.last_status==="error"?j2.last_status:void 0,last_error:j2.last_delivery_error,paused_reason:j2.paused_reason,model:j2.model,skills:j2.skills,workdir:j2.workdir,script:j2.script}),sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last2=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react75.memo((props)=>{let theme=useTheme().theme,j2=props.job,bg2=props.selected?theme.backgroundElement:void 0,glyph=j2.enabled?"\u25CF":"\u25CB",glyphColor=!j2.enabled?theme.textMuted:j2.last_status==="error"?theme.error:j2.last_status==="ok"?theme.success:theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:bg2,onMouseDown:props.onSelect,onMouseMove:props.onHover,children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:glyphColor,children:`${glyph} `}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,children:j2.name||j2.id}),$jsx(Col,{w:18,fg:theme.textMuted,children:j2.schedule||"\u2014"}),$jsx(Col,{w:16,fg:theme.textMuted,children:`last: ${last2(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next(j2.next_run):"paused"}`})]})}),DetailPanel=import_react75.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react75.useState(null);return import_react75.useEffect(()=>{let live=!0;return readCronOutput(j2.id,30).then((o)=>{if(live)setOutput(o)}),()=>{live=!1}},[j2.id,props.reloadKey]),$jsx(TabShell,{title:"Job Detail",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:j2.name||j2.id})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",j2.id],["State",j2.enabled?"active":"paused",j2.enabled?theme.success:theme.warning],["Schedule",j2.schedule||"\u2014"],["Repeat",j2.repeat],["Deliver",j2.deliver??"local"],["Last Run",j2.last_run?`${last2(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next(j2.next_run):"paused"],["Model",j2.model],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Workdir",j2.workdir],["Script",j2.script],["Paused",j2.paused_reason],["Error",j2.last_error,theme.error]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Prompt"})}),$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:j2.prompt})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["Last Output",output?` \xB7 ${ago(output.at.getTime()/1000)}`:""]})}),output?$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:output.text})}):$jsx("text",{fg:theme.textMuted,children:"(none yet)"})]})})})}),Cron=import_react75.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react75.useState([]),[sel,setSel]=import_react75.useState(0),[err,setErr]=import_react75.useState(null),[reloadKey,setReloadKey]=import_react75.useState(0),live=import_react75.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react75.useCallback(()=>{gw.request("cron.manage",{action:"list"}).then((res)=>{setJobs((res.jobs??[]).map(normalize)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>setErr(e instanceof Error?e.message:String(e)))},[gw]);import_react75.useEffect(()=>{load4()},[load4]);let create=import_react75.useCallback(async()=>{let schedule=await openTextPrompt(dialog,{title:"New Cron Job",label:"Schedule (cron expr or 'every 30m')"});if(schedule===null)return;let prompt=await openTextPrompt(dialog,{title:"New Cron Job",label:"Prompt"});if(prompt===null)return;gw.request("cron.manage",{action:"add",name:"",schedule,prompt}).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),toggle=import_react75.useCallback(()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;let action=j2.enabled?"pause":"resume";gw.request("cron.manage",{action,name:j2.id}).then(()=>{toast.show({variant:"success",message:j2.enabled?"Paused":"Resumed"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,load4]),remove2=import_react75.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;if(!await openConfirm(dialog,{title:"Delete Job?",body:`Delete "${j2.name||j2.id}"? This cannot be undone.`,yes:"delete",danger:!0}))return;gw.request("cron.manage",{action:"remove",name:j2.id}).then(()=>{toast.show({variant:"success",message:"Deleted"}),setSel((s)=>Math.max(0,Math.min(s,live.current.jobs.length-2))),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),follow=useFollow("cron"),keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:jobs.length,setSel,...follow.opts,onToggle:toggle,onDelete:remove2,onNew:create,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}),job=jobs[sel]??null,showDetail=dims.width>=120&&job!==null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Cron Jobs (${jobs.length})`,error:err,grow:3,children:jobs.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:"No cron jobs. Press n to create one."})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(Hdr,{children:[$jsx(Col,{w:4,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,fg:theme.textMuted,bold:!0,children:"Name"}),$jsx(Col,{w:18,fg:theme.textMuted,bold:!0,children:"Schedule"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Last"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Next"})]}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:jobs.map((j2,i)=>$jsx(JobRow,{id:follow.id(i),job:j2,selected:i===sel,onSelect:()=>setSel(i),onHover:()=>setSel(i)},j2.id))})]},"table")}),showDetail?$jsx(DetailPanel,{job,reloadKey}):null]}),$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],[keys.print("list.new"),"new"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react80=__toESM(require_react_production(),1);import{Database as Database3}from"bun:sqlite";import{existsSync as existsSync13,readdirSync as readdirSync5,statSync as statSync4,openSync as openSync3,readSync as readSync3,closeSync as closeSync3,readFileSync as readFileSync5,fstatSync}from"fs";var STATUSES=["triage","todo","scheduled","ready","running","blocked","done"],SEV=new Set(["warning","error","critical"]);function parseDiagnostics(stdout){let trimmed=stdout.trim();if(!trimmed)return[];let raw;try{raw=JSON.parse(trimmed)}catch{return[]}if(!Array.isArray(raw))return[];return raw.flatMap((r)=>{if(!r||typeof r!=="object")return[];let rec=r,id=rec.task_id;if(typeof id!=="string"||!id)return[];let diags=Array.isArray(rec.diagnostics)?rec.diagnostics:[];return[{task_id:id,title:typeof rec.title==="string"?rec.title:void 0,status:typeof rec.status==="string"?rec.status:void 0,assignee:typeof rec.assignee==="string"?rec.assignee:null,diagnostics:diags.flatMap(toDiag)}]})}var toDiag=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,sev=r.severity;if(typeof sev!=="string"||!SEV.has(sev))return[];let actions=Array.isArray(r.actions)?r.actions.flatMap(toAction):[];return[{kind:String(r.kind??""),severity:sev,title:String(r.title??""),detail:String(r.detail??""),actions,first_seen_at:Number(r.first_seen_at)||0,last_seen_at:Number(r.last_seen_at)||0,count:Number(r.count)||1,run_id:typeof r.run_id==="number"?r.run_id:null,data:r.data&&typeof r.data==="object"?r.data:{}}]},toAction=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,kind2=r.kind,label=r.label;if(typeof kind2!=="string"||typeof label!=="string")return[];return[{kind:kind2,label,payload:r.payload&&typeof r.payload==="object"?r.payload:{},suggested:r.suggested===!0}]},SEV_RANK={critical:3,error:2,warning:1},maxSeverity=(ds)=>{let best=null;for(let d2 of ds)if(!best||SEV_RANK[d2.severity]>SEV_RANK[best])best=d2.severity;return best},sortDiags=(ds)=>[...ds].sort((a,b2)=>SEV_RANK[b2.severity]-SEV_RANK[a.severity]||a.kind.localeCompare(b2.kind)),DEFAULT2="default",SLUG=/^[a-z0-9][a-z0-9_-]{0,63}$/,kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve7=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync5(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve7(),handles=new Map,errors2=new Map,SQLITE_HEADER=Buffer.from("SQLite format 3\x00","binary"),CORRUPT_BACKUP=/^kanban\.db\.corrupt\..+\.bak$/,currentBoard=()=>slug,dbPath=(s)=>kp(s===DEFAULT2?"kanban.db":`kanban/boards/${s}/kanban.db`),dbDir=(s)=>kp(s===DEFAULT2?"":`kanban/boards/${s}`),logsDir=(s)=>kp(s===DEFAULT2?"kanban/logs":`kanban/boards/${s}/logs`),pair=(s)=>{let cached2=handles.get(s);if(cached2)return cached2;let next2={ro:null,rw:null};return handles.set(s,next2),next2},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path7,msg)=>({kind:kind2,path:path7,message:msg}),isCorrupt=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("not a database")||msg.includes("malformed")||msg.includes("database disk image")||msg.includes("file is not a database")},headerError=(path7)=>{let st;try{st=statSync4(path7)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path7,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync3(path7,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync3(fd,head,0,head.length,0);if(n>=SQLITE_HEADER.length&&head.subarray(0,SQLITE_HEADER.length).equals(SQLITE_HEADER))return null;return boardErr("corrupt",path7,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path7,String(e.message??e))}finally{if(fd>=0)try{closeSync3(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path7=dbPath(s);if(!existsSync13(path7))return errors2.delete(s),null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database3(path7,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e)))}return h2.ro},rwOf=(s)=>{let h2=pair(s);if(h2.rw)return h2.rw;let path7=dbPath(s);if(!existsSync13(path7))return null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{let db=new Database3(path7);try{db.exec("PRAGMA journal_mode=WAL")}catch{}return db.exec(["PRAGMA synchronous=FULL","PRAGMA wal_autocheckpoint=100","PRAGMA secure_delete=ON","PRAGMA cell_size_check=ON","PRAGMA foreign_keys=ON"].join(";")),h2.rw=db,errors2.delete(s),db}catch(e){return errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e))),null}},resetKanban=()=>{for(let h2 of handles.values())h2.ro?.close(),h2.rw?.close();handles.clear(),errors2.clear(),slug=resolve7()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync5(dir,{withFileTypes:!0}).filter((e)=>e.isFile()&&CORRUPT_BACKUP.test(e.name)).map((e)=>`${dir}/${e.name}`).sort()}catch{return[]}}function listBoards(){let out=new Map([[DEFAULT2,"Default"]]),dir=kp("kanban/boards");if(existsSync13(dir))for(let e of readdirSync5(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync5(`${dir}/${e.name}/board.json`,"utf-8")),n=typeof meta?.name==="string"?meta.name:typeof meta?.display_name==="string"?meta.display_name:null;if(n)name=n}catch{}out.set(e.name,name)}return[...out].map(([s,n])=>({slug:s,name:n})).sort((a,b2)=>a.slug===DEFAULT2?-1:b2.slug===DEFAULT2?1:a.slug.localeCompare(b2.slug))}var AT="COALESCE(completed_at, started_at, created_at)",cols=new WeakMap,colsOf=(conn2)=>{let cached2=cols.get(conn2);if(cached2)return cached2;let set2=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set2.add(r.name)}catch{}return cols.set(conn2,set2),set2},selectCol=(have,name,alias)=>{let a=alias??name;return have.has(name)?`${name} AS ${a}`:`NULL AS ${a}`},taskColumns=(have)=>["id","title",selectCol(have,"body"),selectCol(have,"assignee"),"status","priority",selectCol(have,"tenant"),selectCol(have,"created_at"),selectCol(have,"completed_at"),selectCol(have,"result"),selectCol(have,"last_spawn_error"),selectCol(have,"worker_pid"),selectCol(have,"workspace_kind"),selectCol(have,"workspace_path"),selectCol(have,"branch_name"),selectCol(have,"skills"),selectCol(have,"max_runtime_seconds"),selectCol(have,"max_retries"),selectCol(have,"model_override"),selectCol(have,"session_id"),selectCol(have,"last_heartbeat_at"),`${AT} AS updated_at`].join(", "),parseSkills=(raw)=>{if(typeof raw!=="string"||!raw)return[];try{let j2=JSON.parse(raw);return Array.isArray(j2)?j2.filter((v2)=>typeof v2==="string"&&!!v2):[]}catch{return[]}},toTask=(r)=>({id:String(r.id),title:String(r.title??""),body:r.body??null,assignee:r.assignee??null,status:r.status??"todo",priority:Number(r.priority)||0,created_at:Number(r.created_at)||0,updated_at:Number(r.updated_at)||0,completed_at:r.completed_at??null,result:r.result??null,error:r.last_spawn_error??null,tenant:r.tenant??null,pid:r.worker_pid??null,workspace_kind:r.workspace_kind??null,workspace_path:r.workspace_path??null,branch_name:r.branch_name??null,skills:parseSkills(r.skills),max_runtime_seconds:r.max_runtime_seconds??null,max_retries:r.max_retries??null,model_override:r.model_override??null,session_id:r.session_id??null,last_heartbeat_at:r.last_heartbeat_at??null}),toRun=(r)=>({id:Number(r.id),profile:r.profile??null,status:r.status??null,outcome:r.outcome??null,started_at:Number(r.started_at)||0,ended_at:r.ended_at??null,summary:r.summary??null,error:r.error??null,worker_pid:r.worker_pid??null}),toEvent=(r)=>{let raw=r.payload,payload=null;if(raw)try{payload=JSON.parse(raw)}catch{payload=raw}return{id:Number(r.id),kind:String(r.kind??""),payload,created_at:Number(r.created_at)||0,run_id:r.run_id??null}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
|
|
4112
|
+
The child returns whatever partial result it has so far.`,yes:"interrupt",danger:!0}))return;gw.request("subagent.interrupt",{subagent_id:r.subagent_id}).then((res)=>{toast.show(res.found?{variant:"success",message:`Interrupted ${r.subagent_id}`}:{variant:"info",message:"Already finished"}),loadDeleg()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,loadDeleg]),create=import_react73.useCallback(()=>{openCreateProfile(dialog,{existing:live.current.profiles.map((p)=>p.name)}).then((r)=>{if(!r)return;let flags=[r.cloneFrom?`--clone --clone-from ${r.cloneFrom}`:"",r.alias?"":"--no-alias"].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Creating '${r.name}'\u2026`}),sh(`hermes profile create ${r.name} ${flags}`.trim()).then(()=>{toast.show({variant:"success",message:`Created '${r.name}'`}),loadProfiles()})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),install2=import_react73.useCallback(()=>{openInstallDistribution(dialog,gw).then((r)=>{if(!r)return;let shq2=(s)=>`'${s.replace(/'/g,"'\\''")}'`,flags=[r.name?`--name ${shq2(r.name)}`:"",r.alias?"--alias":""].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Installing '${r.manifest.name}'\u2026`}),sh(`hermes profile install ${shq2(r.source)} -y ${flags}`.trim()).then(()=>{let installed=r.name||r.manifest.name;toast.show({variant:"success",message:`Installed '${installed}'`}),loadProfiles();let reqs=r.manifest.env_requires.filter((e)=>e.required).map((e)=>e.name);if(reqs.length>0)toast.show({variant:"warning",title:"Env vars needed",message:`${reqs.join(", ")} \u2014 add to the profile's .env before using it`,duration:6000})})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,sh,dialog,toast,loadProfiles]),selected=profiles[pSel],statGen=import_react73.useRef(0);import_react73.useEffect(()=>{let path7=selected?.path;if(!path7||stats.has(path7))return;let g=++statGen.current;profileStats(path7).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path7,s))})},[selected?.path,stats]);let dims=useTerminalDimensions(),wide=dims.width>=130,pWide=dims.width>=170||!wide&&dims.width>=90,pFollow=useFollow("prof"),dFollow=useFollow("deleg"),keys=useKeys();useKeyboard((key2)=>{if(!props.focused||dialog.open())return;if(key2.name==="tab")return setPane((p)=>p==="profiles"?"deleg":"profiles");if(keys.match("list.refresh",key2)){loadProfiles(),loadDeleg(),toast.show({variant:"info",message:"Reloaded",duration:1000});return}if(pane==="profiles"){if(key2.name==="escape"&&!pWide&&pView==="detail")return setPView("list");if(key2.name==="s")return void pSwitch(pSel);if(keys.match("agents.install",key2))return install2();handleListKey(keys,key2,{count:profiles.length,setSel:setPSel,...pFollow.opts,onNew:create,onDelete:()=>pDelete(pSel),onActivate:()=>{if(!pWide&&pView==="list")return setPView("detail");pEnter(pSel)}});return}if(handleListKey(keys,key2,{count:active.length,setSel:setDSel,...dFollow.opts,onDelete:()=>dKill(dSel)}))return;if(keys.match("agents.kill",key2))return dKill(dSel);if(keys.match("agents.history",key2))return openSpawnHistory(dialog,gw,props.sessionId)});let showProfiles=wide||pane==="profiles",showDeleg=wide||pane==="deleg",showList=pWide||pView==="list",showDetail=pWide||pView==="detail",limits=deleg?`depth\u2264${deleg.max_spawn_depth} \xB7 conc\u2264${deleg.max_concurrent_children}`:"",dHint=active.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react73.useCallback(()=>{let next=!deleg?.paused;gw.request("delegation.pause",{paused:next}).then((r)=>{setDeleg((d2)=>d2?{...d2,paused:r.paused}:d2),toast.show({variant:"info",message:r.paused?"Delegation paused":"Delegation resumed"})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,deleg?.paused]);import_react73.useEffect(()=>cmd.register([{title:deleg?.paused?"Resume Delegation":"Pause Delegation",value:"deleg.pause",category:"Agents",onSelect:togglePause},{title:"Install Distribution\u2026",value:"profile.install",category:"Agents",description:"from git URL or local directory",onSelect:install2}]),[cmd,togglePause,deleg?.paused,install2]);let pair=(k2,v2)=>`[${k2}] ${v2}`,join11=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join11("[\u2191\u2193] nav",pair(keys.print("list.activate"),"actions"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("agents.install"),"install"),pair(keys.print("list.delete"),"delete"),pair(keys.print("list.refresh"),"refresh")):pView==="list"?join11("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join11(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join11("[\u2191\u2193] nav",pair(keys.print("agents.kill"),"interrupt"),pair(keys.print("agents.history"),"history"),pair(keys.print("list.refresh"),"refresh")),delegHint=dHint?`${delegKeys} \xB7 ${dHint}`:delegKeys,footerHint=wide?pane==="profiles"?`${profilesHint} \xB7 ${delegHint}`:`${delegHint} \xB7 ${profilesHint}`:pane==="profiles"?profilesHint:delegHint;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[showProfiles?$jsx(TabShell,{title:`Profiles (${profiles.length})${sticky?` \xB7 \u2605 ${sticky}`:""}`,error:err||null,focus:pane==="profiles",grow:3,children:$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[showList?$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:14,children:$jsx("scrollbox",{ref:pFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:profiles.length===0?$jsx("box",{height:1,children:err?$jsx("text",{fg:theme.textMuted,children:"\u2014"}):$jsx(Spinner,{color:theme.textMuted,label:"scanning profiles\u2026"})}):profiles.map((p,i)=>$jsx(ProfileRow,{id:pFollow.id(i),p,idx:i,selected:i===pSel,onHover:pHover,onEnter:pEnter,onDelete:pDelete},p.name))})}):null,showList&&showDetail?$jsx("box",{width:2}):null,showDetail?$jsx("box",{flexDirection:"column",flexGrow:2,flexBasis:0,minWidth:0,children:selected?$jsx(ProfileDetail,{p:selected,stats:stats.get(selected.path)}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No profiles"})})}):null]})}):null,showDeleg?$jsxs(TabShell,{title:`Delegation (${active.length})`,focus:pane==="deleg",grow:2,children:[$jsxs("box",{height:1,flexDirection:"row",marginBottom:1,children:[$jsx("box",{flexShrink:0,paddingX:1,backgroundColor:deleg?.paused?theme.warning:theme.backgroundElement,onMouseDown:togglePause,children:$jsx("text",{fg:deleg?.paused?theme.background:theme.text,children:deleg?.paused?"\u23F8 paused":"\u25B6 active"})}),$jsx("box",{flexGrow:1}),$jsxs("text",{fg:theme.textMuted,children:["click to ",deleg?.paused?"resume":"pause"]})]}),active.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:deleg?.paused?"Paused \u2014 new subagents will queue":"No subagents running \xB7 h for history"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx("scrollbox",{ref:dFollow.ref,scrollY:!0,flexGrow:3,flexBasis:0,verticalScrollbarOptions:VBAR,children:active.map((r,i)=>{let lv=liveMap.get(r.subagent_id),row2=lv?{...r,tool_count:lv.tool_count}:r,h2=heat(aggOf.get(r.subagent_id)?.hot??0,hotPeak,HOT.length);return $jsx(DelegRow,{id:dFollow.id(i),r:row2,idx:i,selected:i===dSel,now,hot:h2,onHover:dHover,onKill:dKill},r.subagent_id)})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.border,children:"\u2500".repeat(4)})}),$jsx("box",{flexGrow:2,flexBasis:0,minHeight:0,children:active[dSel]?$jsx(DelegDetail,{r:active[dSel],live:liveMap.get(active[dSel].subagent_id),agg:aggOf.get(active[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react75=__toESM(require_react_production(),1);var normalize=(j2)=>({id:j2.job_id??j2.id??"",name:j2.name??"",prompt:j2.prompt??j2.prompt_preview??"",schedule:j2.schedule??"",enabled:j2.enabled??!0,state:j2.state??"scheduled",deliver:j2.deliver??"local",repeat:j2.repeat,last_run:j2.last_run_at,next_run:j2.next_run_at,last_status:j2.last_status==="ok"||j2.last_status==="error"?j2.last_status:void 0,last_error:j2.last_delivery_error,paused_reason:j2.paused_reason,model:j2.model,skills:j2.skills,workdir:j2.workdir,script:j2.script}),sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last2=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react75.memo((props)=>{let theme=useTheme().theme,j2=props.job,bg2=props.selected?theme.backgroundElement:void 0,glyph=j2.enabled?"\u25CF":"\u25CB",glyphColor=!j2.enabled?theme.textMuted:j2.last_status==="error"?theme.error:j2.last_status==="ok"?theme.success:theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:bg2,onMouseDown:props.onSelect,onMouseMove:props.onHover,children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:glyphColor,children:`${glyph} `}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,children:j2.name||j2.id}),$jsx(Col,{w:18,fg:theme.textMuted,children:j2.schedule||"\u2014"}),$jsx(Col,{w:16,fg:theme.textMuted,children:`last: ${last2(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next(j2.next_run):"paused"}`})]})}),DetailPanel=import_react75.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react75.useState(null);return import_react75.useEffect(()=>{let live=!0;return readCronOutput(j2.id,30).then((o)=>{if(live)setOutput(o)}),()=>{live=!1}},[j2.id,props.reloadKey]),$jsx(TabShell,{title:"Job Detail",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:j2.name||j2.id})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",j2.id],["State",j2.enabled?"active":"paused",j2.enabled?theme.success:theme.warning],["Schedule",j2.schedule||"\u2014"],["Repeat",j2.repeat],["Deliver",j2.deliver??"local"],["Last Run",j2.last_run?`${last2(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next(j2.next_run):"paused"],["Model",j2.model],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Workdir",j2.workdir],["Script",j2.script],["Paused",j2.paused_reason],["Error",j2.last_error,theme.error]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Prompt"})}),$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:j2.prompt})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["Last Output",output?` \xB7 ${ago(output.at.getTime()/1000)}`:""]})}),output?$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:output.text})}):$jsx("text",{fg:theme.textMuted,children:"(none yet)"})]})})})}),Cron=import_react75.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react75.useState([]),[sel,setSel]=import_react75.useState(0),[err,setErr]=import_react75.useState(null),[reloadKey,setReloadKey]=import_react75.useState(0),live=import_react75.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react75.useCallback(()=>{gw.request("cron.manage",{action:"list"}).then((res)=>{setJobs((res.jobs??[]).map(normalize)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>setErr(e instanceof Error?e.message:String(e)))},[gw]);import_react75.useEffect(()=>{load4()},[load4]);let create=import_react75.useCallback(async()=>{let schedule=await openTextPrompt(dialog,{title:"New Cron Job",label:"Schedule (cron expr or 'every 30m')"});if(schedule===null)return;let prompt=await openTextPrompt(dialog,{title:"New Cron Job",label:"Prompt"});if(prompt===null)return;gw.request("cron.manage",{action:"add",name:"",schedule,prompt}).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),toggle=import_react75.useCallback(()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;let action=j2.enabled?"pause":"resume";gw.request("cron.manage",{action,name:j2.id}).then(()=>{toast.show({variant:"success",message:j2.enabled?"Paused":"Resumed"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,load4]),remove2=import_react75.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;if(!await openConfirm(dialog,{title:"Delete Job?",body:`Delete "${j2.name||j2.id}"? This cannot be undone.`,yes:"delete",danger:!0}))return;gw.request("cron.manage",{action:"remove",name:j2.id}).then(()=>{toast.show({variant:"success",message:"Deleted"}),setSel((s)=>Math.max(0,Math.min(s,live.current.jobs.length-2))),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),follow=useFollow("cron"),keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:jobs.length,setSel,...follow.opts,onToggle:toggle,onDelete:remove2,onNew:create,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}),job=jobs[sel]??null,showDetail=dims.width>=120&&job!==null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Cron Jobs (${jobs.length})`,error:err,grow:3,children:jobs.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:"No cron jobs. Press n to create one."})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(Hdr,{children:[$jsx(Col,{w:4,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,fg:theme.textMuted,bold:!0,children:"Name"}),$jsx(Col,{w:18,fg:theme.textMuted,bold:!0,children:"Schedule"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Last"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Next"})]}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:jobs.map((j2,i)=>$jsx(JobRow,{id:follow.id(i),job:j2,selected:i===sel,onSelect:()=>setSel(i),onHover:()=>setSel(i)},j2.id))})]},"table")}),showDetail?$jsx(DetailPanel,{job,reloadKey}):null]}),$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],[keys.print("list.new"),"new"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react80=__toESM(require_react_production(),1);import{Database as Database3}from"bun:sqlite";import{existsSync as existsSync13,readdirSync as readdirSync5,statSync as statSync4,openSync as openSync3,readSync as readSync3,closeSync as closeSync3,readFileSync as readFileSync5,fstatSync}from"fs";var STATUSES=["triage","todo","scheduled","ready","running","blocked","done"],SEV=new Set(["warning","error","critical"]);function parseDiagnostics(stdout){let trimmed=stdout.trim();if(!trimmed)return[];let raw;try{raw=JSON.parse(trimmed)}catch{return[]}if(!Array.isArray(raw))return[];return raw.flatMap((r)=>{if(!r||typeof r!=="object")return[];let rec=r,id=rec.task_id;if(typeof id!=="string"||!id)return[];let diags=Array.isArray(rec.diagnostics)?rec.diagnostics:[];return[{task_id:id,title:typeof rec.title==="string"?rec.title:void 0,status:typeof rec.status==="string"?rec.status:void 0,assignee:typeof rec.assignee==="string"?rec.assignee:null,diagnostics:diags.flatMap(toDiag)}]})}var toDiag=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,sev=r.severity;if(typeof sev!=="string"||!SEV.has(sev))return[];let actions=Array.isArray(r.actions)?r.actions.flatMap(toAction):[];return[{kind:String(r.kind??""),severity:sev,title:String(r.title??""),detail:String(r.detail??""),actions,first_seen_at:Number(r.first_seen_at)||0,last_seen_at:Number(r.last_seen_at)||0,count:Number(r.count)||1,run_id:typeof r.run_id==="number"?r.run_id:null,data:r.data&&typeof r.data==="object"?r.data:{}}]},toAction=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,kind2=r.kind,label2=r.label;if(typeof kind2!=="string"||typeof label2!=="string")return[];return[{kind:kind2,label:label2,payload:r.payload&&typeof r.payload==="object"?r.payload:{},suggested:r.suggested===!0}]},SEV_RANK={critical:3,error:2,warning:1},maxSeverity=(ds)=>{let best=null;for(let d2 of ds)if(!best||SEV_RANK[d2.severity]>SEV_RANK[best])best=d2.severity;return best},sortDiags=(ds)=>[...ds].sort((a,b2)=>SEV_RANK[b2.severity]-SEV_RANK[a.severity]||a.kind.localeCompare(b2.kind)),DEFAULT2="default",SLUG=/^[a-z0-9][a-z0-9_-]{0,63}$/,kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve7=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync5(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve7(),handles=new Map,errors2=new Map,SQLITE_HEADER=Buffer.from("SQLite format 3\x00","binary"),CORRUPT_BACKUP=/^kanban\.db\.corrupt\..+\.bak$/,currentBoard=()=>slug,dbPath=(s)=>kp(s===DEFAULT2?"kanban.db":`kanban/boards/${s}/kanban.db`),dbDir=(s)=>kp(s===DEFAULT2?"":`kanban/boards/${s}`),logsDir=(s)=>kp(s===DEFAULT2?"kanban/logs":`kanban/boards/${s}/logs`),pair=(s)=>{let cached2=handles.get(s);if(cached2)return cached2;let next2={ro:null,rw:null};return handles.set(s,next2),next2},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path7,msg)=>({kind:kind2,path:path7,message:msg}),isCorrupt=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("not a database")||msg.includes("malformed")||msg.includes("database disk image")||msg.includes("file is not a database")},headerError=(path7)=>{let st;try{st=statSync4(path7)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path7,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync3(path7,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync3(fd,head,0,head.length,0);if(n>=SQLITE_HEADER.length&&head.subarray(0,SQLITE_HEADER.length).equals(SQLITE_HEADER))return null;return boardErr("corrupt",path7,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path7,String(e.message??e))}finally{if(fd>=0)try{closeSync3(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path7=dbPath(s);if(!existsSync13(path7))return errors2.delete(s),null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database3(path7,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e)))}return h2.ro},rwOf=(s)=>{let h2=pair(s);if(h2.rw)return h2.rw;let path7=dbPath(s);if(!existsSync13(path7))return null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{let db=new Database3(path7);try{db.exec("PRAGMA journal_mode=WAL")}catch{}return db.exec(["PRAGMA synchronous=FULL","PRAGMA wal_autocheckpoint=100","PRAGMA secure_delete=ON","PRAGMA cell_size_check=ON","PRAGMA foreign_keys=ON"].join(";")),h2.rw=db,errors2.delete(s),db}catch(e){return errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e))),null}},resetKanban=()=>{for(let h2 of handles.values())h2.ro?.close(),h2.rw?.close();handles.clear(),errors2.clear(),slug=resolve7()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync5(dir,{withFileTypes:!0}).filter((e)=>e.isFile()&&CORRUPT_BACKUP.test(e.name)).map((e)=>`${dir}/${e.name}`).sort()}catch{return[]}}function listBoards(){let out=new Map([[DEFAULT2,"Default"]]),dir=kp("kanban/boards");if(existsSync13(dir))for(let e of readdirSync5(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync5(`${dir}/${e.name}/board.json`,"utf-8")),n=typeof meta?.name==="string"?meta.name:typeof meta?.display_name==="string"?meta.display_name:null;if(n)name=n}catch{}out.set(e.name,name)}return[...out].map(([s,n])=>({slug:s,name:n})).sort((a,b2)=>a.slug===DEFAULT2?-1:b2.slug===DEFAULT2?1:a.slug.localeCompare(b2.slug))}var AT="COALESCE(completed_at, started_at, created_at)",cols=new WeakMap,colsOf=(conn2)=>{let cached2=cols.get(conn2);if(cached2)return cached2;let set2=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set2.add(r.name)}catch{}return cols.set(conn2,set2),set2},selectCol=(have,name,alias)=>{let a=alias??name;return have.has(name)?`${name} AS ${a}`:`NULL AS ${a}`},taskColumns=(have)=>["id","title",selectCol(have,"body"),selectCol(have,"assignee"),"status","priority",selectCol(have,"tenant"),selectCol(have,"created_at"),selectCol(have,"completed_at"),selectCol(have,"result"),selectCol(have,"last_spawn_error"),selectCol(have,"worker_pid"),selectCol(have,"workspace_kind"),selectCol(have,"workspace_path"),selectCol(have,"branch_name"),selectCol(have,"skills"),selectCol(have,"max_runtime_seconds"),selectCol(have,"max_retries"),selectCol(have,"model_override"),selectCol(have,"session_id"),selectCol(have,"last_heartbeat_at"),`${AT} AS updated_at`].join(", "),parseSkills=(raw)=>{if(typeof raw!=="string"||!raw)return[];try{let j2=JSON.parse(raw);return Array.isArray(j2)?j2.filter((v2)=>typeof v2==="string"&&!!v2):[]}catch{return[]}},toTask=(r)=>({id:String(r.id),title:String(r.title??""),body:r.body??null,assignee:r.assignee??null,status:r.status??"todo",priority:Number(r.priority)||0,created_at:Number(r.created_at)||0,updated_at:Number(r.updated_at)||0,completed_at:r.completed_at??null,result:r.result??null,error:r.last_spawn_error??null,tenant:r.tenant??null,pid:r.worker_pid??null,workspace_kind:r.workspace_kind??null,workspace_path:r.workspace_path??null,branch_name:r.branch_name??null,skills:parseSkills(r.skills),max_runtime_seconds:r.max_runtime_seconds??null,max_retries:r.max_retries??null,model_override:r.model_override??null,session_id:r.session_id??null,last_heartbeat_at:r.last_heartbeat_at??null}),toRun=(r)=>({id:Number(r.id),profile:r.profile??null,status:r.status??null,outcome:r.outcome??null,started_at:Number(r.started_at)||0,ended_at:r.ended_at??null,summary:r.summary??null,error:r.error??null,worker_pid:r.worker_pid??null}),toEvent=(r)=>{let raw=r.payload,payload=null;if(raw)try{payload=JSON.parse(raw)}catch{payload=raw}return{id:Number(r.id),kind:String(r.kind??""),payload,created_at:Number(r.created_at)||0,run_id:r.run_id??null}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
|
|
4113
4113
|
FROM tasks WHERE status != 'archived'
|
|
4114
4114
|
ORDER BY priority DESC, updated_at DESC`).all();for(let r of rows3){let t2=toTask(r);out.get(t2.status)?.push(t2)}errors2.delete(s)}catch(e){errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"query",dbPath(s),String(e.message??e)))}return out}function boardStateOf(s){return{columns:boardOf(s),error:errors2.get(s)??null,corruptBackups:corruptBackupsOf(s)}}var EVENT_TAIL=20;function detailOf(s,id){let conn2=dbOf(s);if(!conn2)return null;try{let row2=conn2.query(`SELECT ${taskColumns(colsOf(conn2))} FROM tasks WHERE id = ?`).get(id);if(!row2)return null;let parents=conn2.query("SELECT parent_id FROM task_links WHERE child_id = ?").all(id).map((r)=>r.parent_id),children2=conn2.query("SELECT child_id FROM task_links WHERE parent_id = ?").all(id).map((r)=>r.child_id),comments=conn2.query("SELECT author, body, created_at FROM task_comments WHERE task_id = ? ORDER BY created_at").all(id).map((c)=>({author:c.author,body:c.body,at:c.created_at})),runs=runsOf(conn2,id),events=eventsOf(conn2,id),latest2=latestSummary(conn2,id);return{...toTask(row2),parents,children:children2,comments,runs,events,latest_summary:latest2}}catch{return null}}var runsOf=(conn2,id)=>{try{return conn2.query(`SELECT id, profile, status, outcome, started_at, ended_at,
|
|
4115
4115
|
summary, error, worker_pid
|
|
@@ -4117,7 +4117,7 @@ The child returns whatever partial result it has so far.`,yes:"interrupt",danger
|
|
|
4117
4117
|
FROM task_events WHERE task_id = ? ORDER BY id DESC LIMIT ?`).all(id,EVENT_TAIL).map(toEvent).reverse()}catch{return[]}},latestSummary=(conn2,id)=>{try{return conn2.query(`SELECT summary FROM task_runs
|
|
4118
4118
|
WHERE task_id = ? AND summary IS NOT NULL AND summary != ''
|
|
4119
4119
|
ORDER BY id DESC LIMIT 1`).get(id)?.summary??null}catch{return null}};function tailLogOf(s,id,bytes=16384){let path7=`${logsDir(s)}/${id}.log`;if(!existsSync13(path7))return null;try{let size=statSync4(path7).size,want=Math.min(size,bytes),fd=openSync3(path7,"r"),buf=Buffer.alloc(want);readSync3(fd,buf,0,want,size-want),closeSync3(fd);let out=buf.toString("utf-8");if(size>bytes){let nl=out.indexOf(`
|
|
4120
|
-
`);if(nl>=0&&nl<out.length-1)out=out.slice(nl+1)}return out}catch{return null}}function assignees(s=slug){let seen=new Set,dir=kp("profiles");if(existsSync13(dir)){for(let e of readdirSync5(dir,{withFileTypes:!0}))if(e.isDirectory())seen.add(e.name)}let conn2=dbOf(s);if(conn2)try{for(let r of conn2.query("SELECT DISTINCT assignee FROM tasks WHERE assignee IS NOT NULL AND status != 'archived'").all())seen.add(r.assignee)}catch{}return[...seen].sort()}function checkFileLength(conn2){try{let row2=conn2.query("PRAGMA database_list").get(),path7=String(row2?.file??row2?.[2]??"");if(!path7)return;let pageRow=conn2.query("PRAGMA page_size").get(),pageSize=Number(Object.values(pageRow??{})[0]);if(!pageSize)return;let fd=openSync3(path7,"r");try{let buf=Buffer.alloc(4);if(readSync3(fd,buf,0,4,28)<4)return;let headerPages=buf.readUInt32BE(0);if(!headerPages)return;let actualPages=Math.floor(fstatSync(fd).size/pageSize);if(actualPages<headerPages)throw Error(`torn-extend detected: page count mismatch on ${path7}: header claims ${headerPages} pages, file has ${actualPages} pages`)}finally{closeSync3(fd)}}catch(err){if(err instanceof Error&&err.message.startsWith("torn-extend detected"))throw err}}function writeTxn(conn2,fn){conn2.exec("BEGIN IMMEDIATE");try{let out=fn();return conn2.exec("COMMIT"),checkFileLength(conn2),out}catch(err){try{conn2.exec("ROLLBACK")}catch{}throw err}}var now=()=>Math.floor(Date.now()/1000);function patchTask(s,id,patch){let conn2=rwOf(s);if(!conn2)return!1;if(!conn2.query("SELECT 1 FROM tasks WHERE id = ?").get(id))return!1;if(patch.priority!==void 0){let p=Math.max(0,Math.min(9,Math.floor(patch.priority)));writeTxn(conn2,()=>{conn2.query("UPDATE tasks SET priority = ? WHERE id = ?").run(p,id),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'reprioritized', ?, ?)").run(id,JSON.stringify({priority:p}),now())})}if(patch.title!==void 0||patch.body!==void 0){let sets=[],vals=[];if(patch.title!==void 0){let t2=patch.title.trim();if(!t2)throw Error("title cannot be empty");sets.push("title = ?"),vals.push(t2)}if(patch.body!==void 0)sets.push("body = ?"),vals.push(patch.body);vals.push(id),writeTxn(conn2,()=>{conn2.query(`UPDATE tasks SET ${sets.join(", ")} WHERE id = ?`).run(...vals),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'edited', NULL, ?)").run(id,now())})}return!0}var q3=(s)=>/^[A-Za-z0-9._\/:+=-]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`;var import_react77=__toESM(require_react_production(),1);var cycle=(t2)=>t2==="off"?"in":t2==="in"?"ex":"off",FilterChip=import_react77.memo((p)=>{let theme=useTheme().theme,bg2=p.state==="in"?theme.accent:p.state==="ex"?void 0:theme.backgroundElement,fg2=p.state==="in"?theme.background:p.state==="ex"?p.selected?theme.accent:theme.borderSubtle:p.selected?theme.accent:theme.text;return $jsx("box",{height:1,flexShrink:0,marginLeft:p.gap??1,paddingLeft:1,paddingRight:1,backgroundColor:bg2,onMouseDown:p.onMouseDown,children:$jsx("text",{fg:fg2,attributes:p.state==="ex"?TextAttributes.STRIKETHROUGH:TextAttributes.NONE,children:p.label})})});var import_react78=__toESM(require_react_production(),1);function openCreateTask(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form2,{pool:opts.assignees,parent:opts.parent,done}),void 0,{ownCancel:!0})})}var CORE=["title","body","assignee","priority","triage","more"],MORE=["tenant","workspace","maxRuntime","skills"],SELECTY=new Set(["assignee","priority","workspace"]),MAX_RUNTIME_RE=/^\d+[smhd]?$/,SKILL_MATCHES_MAX=6,wsLabel=(w2)=>w2.kind==="scratch"?"scratch":w2.kind==="worktree"?"worktree":`dir @ ${w2.path}`,Form2=(p)=>{let theme=useTheme().theme,gw=useGateway(),body=import_react78.useRef(null),[bodyText,setBodyText]=import_react78.useState(""),[field,setField]=import_react78.useState("title"),[more,setMore]=import_react78.useState(!1),[picker,setPicker]=import_react78.useState(null),[title,setTitle]=import_react78.useState(""),[assignee,setAssignee]=import_react78.useState(null),[priority,setPriority]=import_react78.useState(0),[triage,setTriage]=import_react78.useState(!1),[tenant,setTenant]=import_react78.useState(""),[workspace,setWorkspace]=import_react78.useState({kind:"scratch"}),[maxRuntime,setMaxRuntime]=import_react78.useState(""),[catalog2,setCatalog]=import_react78.useState([]),[skills,setSkills]=import_react78.useState([]),[filter,setFilter]=import_react78.useState(""),[matchIdx,setMatchIdx]=import_react78.useState(0);import_react78.useEffect(()=>{let live=!0;return gw.request("skills.manage",{action:"list"}).then((r)=>{if(!live)return;let raw=r.skills??{},out=[];for(let cat of Object.keys(raw))for(let name of raw[cat]??[])out.push({cat,name});out.sort((a,b2)=>a.name.localeCompare(b2.name)),setCatalog(out)}).catch(()=>{}),()=>{live=!1}},[gw]);let matches=import_react78.useMemo(()=>{if(!filter.trim())return[];let q4=filter.trim().toLowerCase(),picked=new Set(skills),hits=[];for(let s of catalog2){if(picked.has(s.name))continue;if(s.name.toLowerCase().includes(q4)||s.cat.toLowerCase().includes(q4))hits.push(s);if(hits.length>=SKILL_MATCHES_MAX)break}return hits},[catalog2,filter,skills]);import_react78.useEffect(()=>{if(matchIdx>0&&matchIdx>=matches.length)setMatchIdx(Math.max(0,matches.length-1))},[matches.length,matchIdx]);let order=()=>more?[...CORE,...MORE]:CORE,titleOk=title.trim().length>0,runtimeOk=maxRuntime.trim()===""||MAX_RUNTIME_RE.test(maxRuntime.trim()),valid=titleOk&&runtimeOk,submit=()=>{if(!valid)return;p.done({title:title.trim(),body:(body.current?.plainText??bodyText).trim(),assignee,priority,parent:p.parent?.id??null,triage,tenant:tenant.trim()||null,workspace,maxRuntime:maxRuntime.trim()||null,skills})},moveField=(dir)=>{let o=order(),i=o.indexOf(field),next2=o[(i+dir+o.length)%o.length];setField(next2)},openPicker=()=>{if(field==="assignee")return setPicker({kind:"assignee"});if(field==="priority")return setPicker({kind:"priority"});if(field==="workspace")return setPicker({kind:"workspace"})},commitMatch=()=>{let hit=matches[matchIdx];if(!hit)return!1;return setSkills((s)=>s.includes(hit.name)?s:[...s,hit.name]),setFilter(""),setMatchIdx(0),!0},popSkill=()=>setSkills((s)=>s.slice(0,-1));if(useKeyboard((key2)=>{if(picker){if(key2.name==="escape")setPicker(picker.kind==="dirPath"?{kind:"workspace"}:null);return}if(key2.name==="escape")return p.done(null);if(key2.name==="return"){if(key2.ctrl)return submit();if(field!=="body")return submit();return}if(field==="skills"){if(key2.name==="tab"){if(!key2.shift&&commitMatch())return;return moveField(key2.shift?-1:1)}if(key2.name==="backspace"){if(filter.length>0)return setFilter((f)=>f.slice(0,-1));return popSkill()}if(key2.name==="up"){if(matches.length>0)return setMatchIdx((i)=>Math.max(0,i-1));return moveField(-1)}if(key2.name==="down"){if(matches.length>0)return setMatchIdx((i)=>Math.min(matches.length-1,i+1));return moveField(1)}if(key2.raw&&key2.raw.length===1&&/[A-Za-z0-9_\-/ ]/.test(key2.raw))setFilter((f)=>f+key2.raw),setMatchIdx(0);return}if(key2.name==="tab")return moveField(key2.shift?-1:1);if(key2.name==="up"){if(field==="body"){if((body.current?.logicalCursor.row??0)>0)return}return moveField(-1)}if(key2.name==="down"){if(field==="body"){let row2=body.current?.logicalCursor.row??0,last3=(body.current?.lineCount??1)-1;if(row2<last3)return}return moveField(1)}if(field==="more"){if(key2.name==="return"||key2.name==="space")return setMore((m2)=>!m2);return}if(field==="triage"&&key2.name==="space")return setTriage((t2)=>!t2);if(SELECTY.has(field)&&key2.name==="space")return openPicker()}),picker?.kind==="assignee"){let opts=[{title:"(unassigned)",value:""},...p.pool.map((n)=>({title:n,value:n}))];return $jsx(DialogSelect,{title:"Assignee",options:opts,placeholder:"Search profiles\u2026",current:assignee??"",onSelect:(o)=>{setAssignee(o.value||null),setPicker(null)}})}if(picker?.kind==="priority"){let opts=Array.from({length:10},(_2,n)=>({title:n===0?"P0 (none)":`P${n}`,value:String(n),description:n===0?"default":n<=2?"normal":n<=5?"elevated":"high"}));return $jsx(DialogSelect,{title:"Priority",options:opts,filterable:!1,current:String(priority),onSelect:(o)=>{setPriority(Number(o.value)),setPicker(null)}})}if(picker?.kind==="workspace")return $jsx(DialogSelect,{title:"Workspace",options:[{title:"scratch",value:"scratch",description:"isolated temp dir under the board root (default)"},{title:"worktree",value:"worktree",description:"git worktree at .worktrees/<task-id> \u2014 worker runs `git worktree add`"},{title:"dir:\u2026",value:"dir",description:"an exact absolute path (prompts next)"}],filterable:!1,current:workspace.kind,onSelect:(o)=>{if(o.value==="scratch")return setWorkspace({kind:"scratch"}),setPicker(null);if(o.value==="worktree")return setWorkspace({kind:"worktree"}),setPicker(null);return setPicker({kind:"dirPath",value:workspace.kind==="dir"?workspace.path:""})}});if(picker?.kind==="dirPath"){let val=picker.value,ok=val.trim().length>0&&val.trim().startsWith("/");return $jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Directory path"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"absolute path (required)"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value:val,onInput:(v2)=>setPicker({kind:"dirPath",value:v2}),onSubmit:()=>{if(!ok)return;setWorkspace({kind:"dir",path:val.trim()}),setPicker(null)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement},"dirpath")})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:ok?"Enter confirm \xB7 Esc back":"absolute path required \xB7 Esc back"})})]})}let lbl=(f,text2)=>$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field===f?theme.accent:theme.textMuted,children:[field===f?"\u25B8 ":" ",text2]})}),textRow=(f,label,value,set2,placeholder)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:set2,onSubmit:submit,focused:field===f,placeholder,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field===f?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement},`field-${f}`)})]}),valRow=(f,label,value,hint)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.text,children:value})}),field===f?$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),skillsRows=()=>{let focused=field==="skills",empty=skills.length===0&&!focused;return $jsxs($Fragment,{children:[$jsxs("box",{height:1,flexDirection:"row",children:[lbl("skills","Skills"),$jsxs("box",{flexGrow:1,minWidth:0,height:1,flexDirection:"row",overflow:"hidden",children:[skills.map((n)=>$jsx(FilterChip,{label:n,state:"in",gap:0},n)),empty?$jsx("text",{fg:theme.textMuted,children:"(none \u2014 focus field to pick)"}):$jsxs("box",{flexDirection:"row",marginLeft:skills.length>0?1:0,children:[$jsx("text",{fg:theme.text,children:filter}),focused?$jsx("text",{fg:theme.accent,children:"\u2588"}):null]})]})]}),focused&&matches.length>0?$jsx("box",{flexDirection:"column",children:matches.map((s,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:i===matchIdx?theme.accent:theme.textMuted,children:i===matchIdx?" \u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:i===matchIdx?theme.accent:theme.text,children:s.name}),$jsx("span",{fg:theme.textMuted,children:` ${s.cat}`})]})})]},`${s.cat}/${s.name}`))}):null]})},footer=!valid?!titleOk?"type a title":"fix runtime (e.g. 30m, 2h, 1800)":field==="body"?"Ctrl+Enter create \xB7 Tab leave \xB7 \u2191\u2193 cursor \xB7 Esc cancel":field==="more"?`Space ${more?"collapse":"expand"} \xB7 Ctrl+Enter create \xB7 \u2191\u2193/Tab \xB7 Esc`:field==="skills"?(()=>{if(matches.length>0)return"Tab add \xB7 \u2191\u2193 pick \xB7 Bksp remove \xB7 Enter create \xB7 Esc";if(skills.length>0)return"type to filter \xB7 Bksp remove last \xB7 Enter create \xB7 \u2191\u2193/Tab \xB7 Esc";return"type to filter \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel"})():SELECTY.has(field)?"Space pick \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel":field==="triage"?"Space toggle \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc":"Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel";return $jsxs("box",{flexDirection:"column",width:66,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:p.parent?`New Task \xB7 child of ${p.parent.id}`:"New Task"})})}),p.parent?$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[" ",p.parent.title]})}):null,$jsx("box",{height:1}),textRow("title","Title",title,setTitle,"one-line summary"),$jsxs("box",{flexDirection:"row",children:[lbl("body","Body"),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("textarea",{ref:body,initialValue:bodyText,onContentChange:()=>{if(body.current)setBodyText(body.current.plainText)},focused:field==="body",placeholder:"longer spec \u2014 markdown ok (Enter for newline)",textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field==="body"?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement,minHeight:5,maxHeight:5},"field-body")})]}),valRow("assignee","Assignee",assignee??"(unassigned)","Space pick \u25BE"),valRow("priority","Priority",priority?`P${priority}`:"P0 (none)","Space pick \u25BE"),valRow("triage","Triage",triage?"yes \u2014 park for a specifier":"no","Space toggle"),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field==="more"?theme.accent:theme.textMuted,children:[field==="more"?"\u25B8 ":" ",more?"More \u25BE":"More \u25B8"]})}),!more?$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:"tenant \xB7 workspace \xB7 runtime \xB7 skills"})}):null]}),more?textRow("tenant","Tenant",tenant,setTenant,"namespace (optional)"):null,more?valRow("workspace","Workspace",wsLabel(workspace),"Space pick \u25BE"):null,more?textRow("maxRuntime","Runtime",maxRuntime,setMaxRuntime,"e.g. 30m, 2h, 1800 (optional)"):null,more?skillsRows():null,$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:footer})})]})};var NOBAR={visible:!1},RULE=["bottom"],HEAD={triage:"triage",todo:"todo",scheduled:"scheduled",ready:"ready",running:"running",blocked:"blocked",done:"done"},EMPTY2={who:new Map,pri:new Map,status:new Map},EMPTY_DIAG=new Map,EMPTY_DIAGS=[],chipId=(c)=>c.kind==="who"?`who:${c.v}`:c.kind==="pri"?`pri:${c.v}`:`st:${c.v}`,chipLabel=(c)=>c.kind==="who"?c.v:c.kind==="pri"?`P${c.v}`:HEAD[c.v],triOf=(c,m2)=>c.kind==="who"?m2.who.get(c.v)??"off":c.kind==="pri"?m2.pri.get(c.v)??"off":m2.status.get(c.v)??"off";function admits(g,v2){let t2=g.get(v2);if(t2==="ex")return!1;if(t2==="in")return!0;for(let s of g.values())if(s==="in")return!1;return!0}var pass=(t2,m2)=>admits(m2.who,t2.assignee??null)&&admits(m2.pri,t2.priority),indexDiags=(rows3)=>{let out=new Map;for(let r of rows3)if(r.diagnostics.length>0)out.set(r.task_id,sortDiags(r.diagnostics));return out},maskFromPrefs=(raw)=>{let out=new Map;if(!raw)return out;for(let slug2 of Object.keys(raw)){let g=raw[slug2];out.set(slug2,{who:new Map(g.who??[]),pri:new Map(g.pri??[]),status:new Map(g.status??[])})}return out},maskToPrefs=(masks)=>{let out={};for(let[slug2,m2]of masks){let filt=(xs)=>xs.filter(([,t2])=>t2==="in"||t2==="ex"),who=filt([...m2.who]),pri=filt([...m2.pri]),status=filt([...m2.status]);if(who.length||pri.length||status.length)out[slug2]={who,pri,status}}return out},persist=(masks,open2)=>{let cur=load2().kanban??{};set("kanban",{...cur,open:[...open2],masks:maskToPrefs(masks)})},SEV_GLYPH={warning:"\u26A0",error:"!!",critical:"\u203C"},sevColor=(sev,theme)=>sev==="warning"?theme.warning:theme.error,Card=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{id:p.id,height:2,flexDirection:"row",paddingLeft:1,border:RULE,borderStyle:"single",borderColor:theme.borderSubtle,backgroundColor:p.on?theme.backgroundElement:void 0,onMouseDown:p.onPick,onMouseMove:p.onHover,children:$jsxs(Ticker,{active:p.on||p.hov,fg:p.on?theme.accent:theme.text,children:[p.sev?$jsxs($Fragment,{children:[$jsx("span",{fg:sevColor(p.sev,theme),children:SEV_GLYPH[p.sev]})," "]}):null,p.t.title]})})}),Column=import_react80.memo((p)=>{let theme=useTheme().theme,box=import_react80.useRef(null),[hov,setHov]=import_react80.useState(-1),id=(i)=>`kb-${p.slug}-${p.status}-${i}`;import_react80.useEffect(()=>{if(p.on&&p.tasks.length>0)box.current?.scrollChildIntoView(id(p.sel))},[p.on,p.sel,p.tasks.length]);let tint=p.status==="blocked"?theme.warning:p.status==="running"?theme.success:p.status==="scheduled"?theme.textMuted:p.status==="done"?theme.textMuted:theme.primary;return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:18,border:!0,borderColor:p.on?theme.primary:theme.border,onMouseOut:()=>setHov(-1),children:[$jsx("box",{height:1,paddingLeft:1,children:$jsxs("text",{children:[$jsx("span",{fg:tint,children:$jsx("strong",{children:HEAD[p.status]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.tasks.length}`})]})}),$jsx("scrollbox",{ref:box,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:p.tasks.map((t2,i)=>$jsx(Card,{id:id(i),t:t2,on:p.on&&i===p.sel,hov:i===hov,sev:maxSeverity(p.diags.get(t2.id)??[]),onHover:()=>{if(hov!==i)setHov(i)},onPick:()=>p.onPick(i)},t2.id))})})]})}),ErrorBanner=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",marginLeft:2,marginBottom:1,paddingLeft:1,border:!0,borderColor:theme.error,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.error,children:$jsxs("strong",{children:["Kanban DB ",p.error.kind]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.error.path}`})]})}),$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.error.message}),p.backups.length>0?$jsx("text",{wrapMode:"word",fg:theme.warning,children:`quarantine backup${p.backups.length===1?"":"s"}: ${p.backups.join(", ")}`}):null]})}),FilterBar=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{height:1,flexDirection:"row",flexWrap:"no-wrap",overflow:"hidden",marginBottom:1,children:p.chips.flatMap((c,i)=>{let chip=$jsx(FilterChip,{label:chipLabel(c),state:triOf(c,p.mask),selected:p.on&&i===p.sel,onMouseDown:()=>p.onPick(i)},chipId(c));if(i===0||p.chips[i-1].kind===c.kind)return[chip];return[$jsx("box",{height:1,flexShrink:0,marginLeft:1,children:$jsx("text",{fg:theme.borderSubtle,children:"|"})},`sep:${chipId(c)}`),chip]})})}),FIELDS=["title","body","assignee","priority","status","parents","result","comment"],fieldsFor=(t2)=>FIELDS.filter((f)=>{if(f==="result")return t2.status==="done";return!0}),SidePane=import_react80.memo((p)=>{let{theme,syntaxStyle}=useTheme();if(p.pane.kind==="log")return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:p.pane.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 worker log (tail)`})]})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.pane.text||"(empty)"})})]});let d2=p.pane.d,fields=fieldsFor(d2),cur=p.on?fields[Math.min(p.sel,fields.length-1)]:null,srow=(f,label,value,hint)=>{let active=cur===f;return $jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:active?theme.text:theme.textMuted,children:value})}),hint?$jsx("box",{flexShrink:0,paddingLeft:1,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]},f)},mrow=(f,label,content,hint)=>{let active=cur===f;return $jsxs("box",{flexDirection:"column",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label})}),hint?$jsx("box",{flexGrow:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),$jsx("box",{paddingLeft:10,flexShrink:0,children:content})]},f)},resultText=d2.result||d2.latest_summary||"";return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:d2.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${d2.status} \xB7 ${ago(d2.updated_at)}`})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[srow("title","Title",d2.title,p.on&&cur==="title"?"Enter edit":void 0),mrow("body","Body",d2.body?cur==="body"?$jsx("text",{wrapMode:"word",fg:theme.text,children:d2.body}):$jsx("markdown",{content:d2.body,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="body"?"Enter edit (raw)":void 0),srow("assignee","Assignee",d2.assignee??"\u2014",p.on&&cur==="assignee"?"Enter pick":void 0),srow("priority","Priority",d2.priority?`P${d2.priority}`:"\u2014",p.on&&cur==="priority"?"\u2191\u2193 / Enter":void 0),srow("status","Status",d2.status,p.on&&cur==="status"?"Enter change":void 0),srow("parents","Parents",d2.parents.length?d2.parents.join(", "):"\u2014",p.on&&cur==="parents"?"Enter add/remove":void 0),d2.children.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Children"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.children.join(", ")})})]}):null,d2.workspace_kind?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Workspace"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,children:[d2.workspace_kind,d2.workspace_path?` @ ${d2.workspace_path}`:""]})})]}):null,d2.branch_name?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Branch"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.branch_name})})]}):null,d2.skills.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Skills"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.skills.join(", ")})})]}):null,d2.model_override?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Model"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.model_override})})]}):null,d2.max_retries!==null?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Retries"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.max_retries)})})]}):null,d2.pid?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"PID"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.pid)})})]}):null,d2.last_heartbeat_at&&d2.status==="running"?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Heartbeat"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:ago(d2.last_heartbeat_at)})})]}):null,d2.session_id?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Session"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.session_id})})]}):null,d2.error?$jsxs("box",{flexDirection:"column",paddingLeft:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:"Error"})}),$jsx("box",{paddingLeft:2,children:$jsx("text",{fg:theme.error,wrapMode:"word",children:d2.error})})]}):null,d2.status==="done"?mrow("result","Result",resultText?cur==="result"?$jsx("text",{wrapMode:"word",fg:theme.text,children:resultText}):$jsx("markdown",{content:resultText,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="result"?"Enter edit":void 0):null,p.diags.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"Diagnostics "}),$jsx("span",{fg:sevColor(p.diags[0].severity,theme),children:`(${p.diags.length})`})]})}),p.diags.map((dx,i)=>$jsxs("box",{flexDirection:"column",marginTop:i===0?0:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:sevColor(dx.severity,theme),children:SEV_GLYPH[dx.severity]}),$jsx("span",{fg:theme.text,children:` [${dx.severity}] ${dx.kind}`}),dx.count>1?$jsx("span",{fg:theme.textMuted,children:` \xD7${dx.count}`}):null]})}),$jsxs("box",{paddingLeft:2,flexDirection:"column",children:[$jsx("text",{wrapMode:"word",fg:theme.text,children:dx.title}),dx.detail?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:dx.detail}):null,dx.actions.map((a,j2)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:a.suggested?theme.accent:theme.textMuted,children:a.suggested?"\u2192 ":"\xB7 "}),$jsx("span",{fg:a.suggested?theme.text:theme.textMuted,children:a.label})]})},j2))]})]},`${dx.kind}-${i}`))]}):null,d2.runs.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Runs (${d2.runs.length})`})}),d2.runs.map((r)=>{let outcome=r.outcome||r.status||(r.ended_at?"ended":"active"),elapsed=r.ended_at?`${Math.max(0,r.ended_at-r.started_at)}s`:"active";return $jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:`#${r.id} `}),$jsx("span",{fg:theme.text,children:outcome}),$jsx("span",{fg:theme.textMuted,children:` @${r.profile??"-"} ${elapsed} ${ago(r.started_at)}`})]})}),r.summary?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:` \u2192 ${r.summary.split(`
|
|
4120
|
+
`);if(nl>=0&&nl<out.length-1)out=out.slice(nl+1)}return out}catch{return null}}function assignees(s=slug){let seen=new Set,dir=kp("profiles");if(existsSync13(dir)){for(let e of readdirSync5(dir,{withFileTypes:!0}))if(e.isDirectory())seen.add(e.name)}let conn2=dbOf(s);if(conn2)try{for(let r of conn2.query("SELECT DISTINCT assignee FROM tasks WHERE assignee IS NOT NULL AND status != 'archived'").all())seen.add(r.assignee)}catch{}return[...seen].sort()}function checkFileLength(conn2){try{let row2=conn2.query("PRAGMA database_list").get(),path7=String(row2?.file??row2?.[2]??"");if(!path7)return;let pageRow=conn2.query("PRAGMA page_size").get(),pageSize=Number(Object.values(pageRow??{})[0]);if(!pageSize)return;let fd=openSync3(path7,"r");try{let buf=Buffer.alloc(4);if(readSync3(fd,buf,0,4,28)<4)return;let headerPages=buf.readUInt32BE(0);if(!headerPages)return;let actualPages=Math.floor(fstatSync(fd).size/pageSize);if(actualPages<headerPages)throw Error(`torn-extend detected: page count mismatch on ${path7}: header claims ${headerPages} pages, file has ${actualPages} pages`)}finally{closeSync3(fd)}}catch(err){if(err instanceof Error&&err.message.startsWith("torn-extend detected"))throw err}}function writeTxn(conn2,fn){conn2.exec("BEGIN IMMEDIATE");try{let out=fn();return conn2.exec("COMMIT"),checkFileLength(conn2),out}catch(err){try{conn2.exec("ROLLBACK")}catch{}throw err}}var now=()=>Math.floor(Date.now()/1000);function patchTask(s,id,patch){let conn2=rwOf(s);if(!conn2)return!1;if(!conn2.query("SELECT 1 FROM tasks WHERE id = ?").get(id))return!1;if(patch.priority!==void 0){let p=Math.max(0,Math.min(9,Math.floor(patch.priority)));writeTxn(conn2,()=>{conn2.query("UPDATE tasks SET priority = ? WHERE id = ?").run(p,id),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'reprioritized', ?, ?)").run(id,JSON.stringify({priority:p}),now())})}if(patch.title!==void 0||patch.body!==void 0){let sets=[],vals=[];if(patch.title!==void 0){let t2=patch.title.trim();if(!t2)throw Error("title cannot be empty");sets.push("title = ?"),vals.push(t2)}if(patch.body!==void 0)sets.push("body = ?"),vals.push(patch.body);vals.push(id),writeTxn(conn2,()=>{conn2.query(`UPDATE tasks SET ${sets.join(", ")} WHERE id = ?`).run(...vals),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'edited', NULL, ?)").run(id,now())})}return!0}var q3=(s)=>/^[A-Za-z0-9._\/:+=-]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`;var import_react77=__toESM(require_react_production(),1);var cycle=(t2)=>t2==="off"?"in":t2==="in"?"ex":"off",FilterChip=import_react77.memo((p)=>{let theme=useTheme().theme,bg2=p.state==="in"?theme.accent:p.state==="ex"?void 0:theme.backgroundElement,fg2=p.state==="in"?theme.background:p.state==="ex"?p.selected?theme.accent:theme.borderSubtle:p.selected?theme.accent:theme.text;return $jsx("box",{height:1,flexShrink:0,marginLeft:p.gap??1,paddingLeft:1,paddingRight:1,backgroundColor:bg2,onMouseDown:p.onMouseDown,children:$jsx("text",{fg:fg2,attributes:p.state==="ex"?TextAttributes.STRIKETHROUGH:TextAttributes.NONE,children:p.label})})});var import_react78=__toESM(require_react_production(),1);function openCreateTask(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form2,{pool:opts.assignees,parent:opts.parent,done}),void 0,{ownCancel:!0})})}var CORE=["title","body","assignee","priority","triage","more"],MORE=["tenant","workspace","maxRuntime","skills"],SELECTY=new Set(["assignee","priority","workspace"]),MAX_RUNTIME_RE=/^\d+[smhd]?$/,SKILL_MATCHES_MAX=6,wsLabel=(w2)=>w2.kind==="scratch"?"scratch":w2.kind==="worktree"?"worktree":`dir @ ${w2.path}`,Form2=(p)=>{let theme=useTheme().theme,gw=useGateway(),body=import_react78.useRef(null),[bodyText,setBodyText]=import_react78.useState(""),[field,setField]=import_react78.useState("title"),[more,setMore]=import_react78.useState(!1),[picker,setPicker]=import_react78.useState(null),[title,setTitle]=import_react78.useState(""),[assignee,setAssignee]=import_react78.useState(null),[priority,setPriority]=import_react78.useState(0),[triage,setTriage]=import_react78.useState(!1),[tenant,setTenant]=import_react78.useState(""),[workspace,setWorkspace]=import_react78.useState({kind:"scratch"}),[maxRuntime,setMaxRuntime]=import_react78.useState(""),[catalog2,setCatalog]=import_react78.useState([]),[skills,setSkills]=import_react78.useState([]),[filter,setFilter]=import_react78.useState(""),[matchIdx,setMatchIdx]=import_react78.useState(0);import_react78.useEffect(()=>{let live=!0;return gw.request("skills.manage",{action:"list"}).then((r)=>{if(!live)return;let raw=r.skills??{},out=[];for(let cat of Object.keys(raw))for(let name of raw[cat]??[])out.push({cat,name});out.sort((a,b2)=>a.name.localeCompare(b2.name)),setCatalog(out)}).catch(()=>{}),()=>{live=!1}},[gw]);let matches=import_react78.useMemo(()=>{if(!filter.trim())return[];let q4=filter.trim().toLowerCase(),picked=new Set(skills),hits=[];for(let s of catalog2){if(picked.has(s.name))continue;if(s.name.toLowerCase().includes(q4)||s.cat.toLowerCase().includes(q4))hits.push(s);if(hits.length>=SKILL_MATCHES_MAX)break}return hits},[catalog2,filter,skills]);import_react78.useEffect(()=>{if(matchIdx>0&&matchIdx>=matches.length)setMatchIdx(Math.max(0,matches.length-1))},[matches.length,matchIdx]);let order=()=>more?[...CORE,...MORE]:CORE,titleOk=title.trim().length>0,runtimeOk=maxRuntime.trim()===""||MAX_RUNTIME_RE.test(maxRuntime.trim()),valid=titleOk&&runtimeOk,submit=()=>{if(!valid)return;p.done({title:title.trim(),body:(body.current?.plainText??bodyText).trim(),assignee,priority,parent:p.parent?.id??null,triage,tenant:tenant.trim()||null,workspace,maxRuntime:maxRuntime.trim()||null,skills})},moveField=(dir)=>{let o=order(),i=o.indexOf(field),next2=o[(i+dir+o.length)%o.length];setField(next2)},openPicker=()=>{if(field==="assignee")return setPicker({kind:"assignee"});if(field==="priority")return setPicker({kind:"priority"});if(field==="workspace")return setPicker({kind:"workspace"})},commitMatch=()=>{let hit=matches[matchIdx];if(!hit)return!1;return setSkills((s)=>s.includes(hit.name)?s:[...s,hit.name]),setFilter(""),setMatchIdx(0),!0},popSkill=()=>setSkills((s)=>s.slice(0,-1));if(useKeyboard((key2)=>{if(picker){if(key2.name==="escape")setPicker(picker.kind==="dirPath"?{kind:"workspace"}:null);return}if(key2.name==="escape")return p.done(null);if(key2.name==="return"){if(key2.ctrl)return submit();if(field!=="body")return submit();return}if(field==="skills"){if(key2.name==="tab"){if(!key2.shift&&commitMatch())return;return moveField(key2.shift?-1:1)}if(key2.name==="backspace"){if(filter.length>0)return setFilter((f)=>f.slice(0,-1));return popSkill()}if(key2.name==="up"){if(matches.length>0)return setMatchIdx((i)=>Math.max(0,i-1));return moveField(-1)}if(key2.name==="down"){if(matches.length>0)return setMatchIdx((i)=>Math.min(matches.length-1,i+1));return moveField(1)}if(key2.raw&&key2.raw.length===1&&/[A-Za-z0-9_\-/ ]/.test(key2.raw))setFilter((f)=>f+key2.raw),setMatchIdx(0);return}if(key2.name==="tab")return moveField(key2.shift?-1:1);if(key2.name==="up"){if(field==="body"){if((body.current?.logicalCursor.row??0)>0)return}return moveField(-1)}if(key2.name==="down"){if(field==="body"){let row2=body.current?.logicalCursor.row??0,last3=(body.current?.lineCount??1)-1;if(row2<last3)return}return moveField(1)}if(field==="more"){if(key2.name==="return"||key2.name==="space")return setMore((m2)=>!m2);return}if(field==="triage"&&key2.name==="space")return setTriage((t2)=>!t2);if(SELECTY.has(field)&&key2.name==="space")return openPicker()}),picker?.kind==="assignee"){let opts=[{title:"(unassigned)",value:""},...p.pool.map((n)=>({title:n,value:n}))];return $jsx(DialogSelect,{title:"Assignee",options:opts,placeholder:"Search profiles\u2026",current:assignee??"",onSelect:(o)=>{setAssignee(o.value||null),setPicker(null)}})}if(picker?.kind==="priority"){let opts=Array.from({length:10},(_2,n)=>({title:n===0?"P0 (none)":`P${n}`,value:String(n),description:n===0?"default":n<=2?"normal":n<=5?"elevated":"high"}));return $jsx(DialogSelect,{title:"Priority",options:opts,filterable:!1,current:String(priority),onSelect:(o)=>{setPriority(Number(o.value)),setPicker(null)}})}if(picker?.kind==="workspace")return $jsx(DialogSelect,{title:"Workspace",options:[{title:"scratch",value:"scratch",description:"isolated temp dir under the board root (default)"},{title:"worktree",value:"worktree",description:"git worktree at .worktrees/<task-id> \u2014 worker runs `git worktree add`"},{title:"dir:\u2026",value:"dir",description:"an exact absolute path (prompts next)"}],filterable:!1,current:workspace.kind,onSelect:(o)=>{if(o.value==="scratch")return setWorkspace({kind:"scratch"}),setPicker(null);if(o.value==="worktree")return setWorkspace({kind:"worktree"}),setPicker(null);return setPicker({kind:"dirPath",value:workspace.kind==="dir"?workspace.path:""})}});if(picker?.kind==="dirPath"){let val=picker.value,ok=val.trim().length>0&&val.trim().startsWith("/");return $jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Directory path"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"absolute path (required)"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value:val,onInput:(v2)=>setPicker({kind:"dirPath",value:v2}),onSubmit:()=>{if(!ok)return;setWorkspace({kind:"dir",path:val.trim()}),setPicker(null)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement},"dirpath")})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:ok?"Enter confirm \xB7 Esc back":"absolute path required \xB7 Esc back"})})]})}let lbl=(f,text2)=>$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field===f?theme.accent:theme.textMuted,children:[field===f?"\u25B8 ":" ",text2]})}),textRow=(f,label2,value,set2,placeholder)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label2),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:set2,onSubmit:submit,focused:field===f,placeholder,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field===f?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement},`field-${f}`)})]}),valRow=(f,label2,value,hint)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label2),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.text,children:value})}),field===f?$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),skillsRows=()=>{let focused=field==="skills",empty=skills.length===0&&!focused;return $jsxs($Fragment,{children:[$jsxs("box",{height:1,flexDirection:"row",children:[lbl("skills","Skills"),$jsxs("box",{flexGrow:1,minWidth:0,height:1,flexDirection:"row",overflow:"hidden",children:[skills.map((n)=>$jsx(FilterChip,{label:n,state:"in",gap:0},n)),empty?$jsx("text",{fg:theme.textMuted,children:"(none \u2014 focus field to pick)"}):$jsxs("box",{flexDirection:"row",marginLeft:skills.length>0?1:0,children:[$jsx("text",{fg:theme.text,children:filter}),focused?$jsx("text",{fg:theme.accent,children:"\u2588"}):null]})]})]}),focused&&matches.length>0?$jsx("box",{flexDirection:"column",children:matches.map((s,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:i===matchIdx?theme.accent:theme.textMuted,children:i===matchIdx?" \u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:i===matchIdx?theme.accent:theme.text,children:s.name}),$jsx("span",{fg:theme.textMuted,children:` ${s.cat}`})]})})]},`${s.cat}/${s.name}`))}):null]})},footer=!valid?!titleOk?"type a title":"fix runtime (e.g. 30m, 2h, 1800)":field==="body"?"Ctrl+Enter create \xB7 Tab leave \xB7 \u2191\u2193 cursor \xB7 Esc cancel":field==="more"?`Space ${more?"collapse":"expand"} \xB7 Ctrl+Enter create \xB7 \u2191\u2193/Tab \xB7 Esc`:field==="skills"?(()=>{if(matches.length>0)return"Tab add \xB7 \u2191\u2193 pick \xB7 Bksp remove \xB7 Enter create \xB7 Esc";if(skills.length>0)return"type to filter \xB7 Bksp remove last \xB7 Enter create \xB7 \u2191\u2193/Tab \xB7 Esc";return"type to filter \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel"})():SELECTY.has(field)?"Space pick \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel":field==="triage"?"Space toggle \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc":"Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel";return $jsxs("box",{flexDirection:"column",width:66,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:p.parent?`New Task \xB7 child of ${p.parent.id}`:"New Task"})})}),p.parent?$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[" ",p.parent.title]})}):null,$jsx("box",{height:1}),textRow("title","Title",title,setTitle,"one-line summary"),$jsxs("box",{flexDirection:"row",children:[lbl("body","Body"),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("textarea",{ref:body,initialValue:bodyText,onContentChange:()=>{if(body.current)setBodyText(body.current.plainText)},focused:field==="body",placeholder:"longer spec \u2014 markdown ok (Enter for newline)",textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field==="body"?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement,minHeight:5,maxHeight:5},"field-body")})]}),valRow("assignee","Assignee",assignee??"(unassigned)","Space pick \u25BE"),valRow("priority","Priority",priority?`P${priority}`:"P0 (none)","Space pick \u25BE"),valRow("triage","Triage",triage?"yes \u2014 park for a specifier":"no","Space toggle"),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field==="more"?theme.accent:theme.textMuted,children:[field==="more"?"\u25B8 ":" ",more?"More \u25BE":"More \u25B8"]})}),!more?$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:"tenant \xB7 workspace \xB7 runtime \xB7 skills"})}):null]}),more?textRow("tenant","Tenant",tenant,setTenant,"namespace (optional)"):null,more?valRow("workspace","Workspace",wsLabel(workspace),"Space pick \u25BE"):null,more?textRow("maxRuntime","Runtime",maxRuntime,setMaxRuntime,"e.g. 30m, 2h, 1800 (optional)"):null,more?skillsRows():null,$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:footer})})]})};var NOBAR={visible:!1},RULE=["bottom"],HEAD={triage:"triage",todo:"todo",scheduled:"scheduled",ready:"ready",running:"running",blocked:"blocked",done:"done"},EMPTY2={who:new Map,pri:new Map,status:new Map},EMPTY_DIAG=new Map,EMPTY_DIAGS=[],chipId=(c)=>c.kind==="who"?`who:${c.v}`:c.kind==="pri"?`pri:${c.v}`:`st:${c.v}`,chipLabel=(c)=>c.kind==="who"?c.v:c.kind==="pri"?`P${c.v}`:HEAD[c.v],triOf=(c,m2)=>c.kind==="who"?m2.who.get(c.v)??"off":c.kind==="pri"?m2.pri.get(c.v)??"off":m2.status.get(c.v)??"off";function admits(g,v2){let t2=g.get(v2);if(t2==="ex")return!1;if(t2==="in")return!0;for(let s of g.values())if(s==="in")return!1;return!0}var pass=(t2,m2)=>admits(m2.who,t2.assignee??null)&&admits(m2.pri,t2.priority),indexDiags=(rows3)=>{let out=new Map;for(let r of rows3)if(r.diagnostics.length>0)out.set(r.task_id,sortDiags(r.diagnostics));return out},maskFromPrefs=(raw)=>{let out=new Map;if(!raw)return out;for(let slug2 of Object.keys(raw)){let g=raw[slug2];out.set(slug2,{who:new Map(g.who??[]),pri:new Map(g.pri??[]),status:new Map(g.status??[])})}return out},maskToPrefs=(masks)=>{let out={};for(let[slug2,m2]of masks){let filt=(xs)=>xs.filter(([,t2])=>t2==="in"||t2==="ex"),who=filt([...m2.who]),pri=filt([...m2.pri]),status=filt([...m2.status]);if(who.length||pri.length||status.length)out[slug2]={who,pri,status}}return out},persist=(masks,open2)=>{let cur=load2().kanban??{};set("kanban",{...cur,open:[...open2],masks:maskToPrefs(masks)})},SEV_GLYPH={warning:"\u26A0",error:"!!",critical:"\u203C"},sevColor=(sev,theme)=>sev==="warning"?theme.warning:theme.error,Card=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{id:p.id,height:2,flexDirection:"row",paddingLeft:1,border:RULE,borderStyle:"single",borderColor:theme.borderSubtle,backgroundColor:p.on?theme.backgroundElement:void 0,onMouseDown:p.onPick,onMouseMove:p.onHover,children:$jsxs(Ticker,{active:p.on||p.hov,fg:p.on?theme.accent:theme.text,children:[p.sev?$jsxs($Fragment,{children:[$jsx("span",{fg:sevColor(p.sev,theme),children:SEV_GLYPH[p.sev]})," "]}):null,p.t.title]})})}),Column=import_react80.memo((p)=>{let theme=useTheme().theme,box=import_react80.useRef(null),[hov,setHov]=import_react80.useState(-1),id=(i)=>`kb-${p.slug}-${p.status}-${i}`;import_react80.useEffect(()=>{if(p.on&&p.tasks.length>0)box.current?.scrollChildIntoView(id(p.sel))},[p.on,p.sel,p.tasks.length]);let tint=p.status==="blocked"?theme.warning:p.status==="running"?theme.success:p.status==="scheduled"?theme.textMuted:p.status==="done"?theme.textMuted:theme.primary;return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:18,border:!0,borderColor:p.on?theme.primary:theme.border,onMouseOut:()=>setHov(-1),children:[$jsx("box",{height:1,paddingLeft:1,children:$jsxs("text",{children:[$jsx("span",{fg:tint,children:$jsx("strong",{children:HEAD[p.status]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.tasks.length}`})]})}),$jsx("scrollbox",{ref:box,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:p.tasks.map((t2,i)=>$jsx(Card,{id:id(i),t:t2,on:p.on&&i===p.sel,hov:i===hov,sev:maxSeverity(p.diags.get(t2.id)??[]),onHover:()=>{if(hov!==i)setHov(i)},onPick:()=>p.onPick(i)},t2.id))})})]})}),ErrorBanner=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",marginLeft:2,marginBottom:1,paddingLeft:1,border:!0,borderColor:theme.error,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.error,children:$jsxs("strong",{children:["Kanban DB ",p.error.kind]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.error.path}`})]})}),$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.error.message}),p.backups.length>0?$jsx("text",{wrapMode:"word",fg:theme.warning,children:`quarantine backup${p.backups.length===1?"":"s"}: ${p.backups.join(", ")}`}):null]})}),FilterBar=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{height:1,flexDirection:"row",flexWrap:"no-wrap",overflow:"hidden",marginBottom:1,children:p.chips.flatMap((c,i)=>{let chip=$jsx(FilterChip,{label:chipLabel(c),state:triOf(c,p.mask),selected:p.on&&i===p.sel,onMouseDown:()=>p.onPick(i)},chipId(c));if(i===0||p.chips[i-1].kind===c.kind)return[chip];return[$jsx("box",{height:1,flexShrink:0,marginLeft:1,children:$jsx("text",{fg:theme.borderSubtle,children:"|"})},`sep:${chipId(c)}`),chip]})})}),FIELDS=["title","body","assignee","priority","status","parents","result","comment"],fieldsFor=(t2)=>FIELDS.filter((f)=>{if(f==="result")return t2.status==="done";return!0}),SidePane=import_react80.memo((p)=>{let{theme,syntaxStyle}=useTheme();if(p.pane.kind==="log")return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:p.pane.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 worker log (tail)`})]})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.pane.text||"(empty)"})})]});let d2=p.pane.d,fields=fieldsFor(d2),cur=p.on?fields[Math.min(p.sel,fields.length-1)]:null,srow=(f,label2,value,hint)=>{let active=cur===f;return $jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:active?theme.text:theme.textMuted,children:value})}),hint?$jsx("box",{flexShrink:0,paddingLeft:1,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]},f)},mrow=(f,label2,content,hint)=>{let active=cur===f;return $jsxs("box",{flexDirection:"column",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),hint?$jsx("box",{flexGrow:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),$jsx("box",{paddingLeft:10,flexShrink:0,children:content})]},f)},resultText=d2.result||d2.latest_summary||"";return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:d2.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${d2.status} \xB7 ${ago(d2.updated_at)}`})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[srow("title","Title",d2.title,p.on&&cur==="title"?"Enter edit":void 0),mrow("body","Body",d2.body?cur==="body"?$jsx("text",{wrapMode:"word",fg:theme.text,children:d2.body}):$jsx("markdown",{content:d2.body,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="body"?"Enter edit (raw)":void 0),srow("assignee","Assignee",d2.assignee??"\u2014",p.on&&cur==="assignee"?"Enter pick":void 0),srow("priority","Priority",d2.priority?`P${d2.priority}`:"\u2014",p.on&&cur==="priority"?"\u2191\u2193 / Enter":void 0),srow("status","Status",d2.status,p.on&&cur==="status"?"Enter change":void 0),srow("parents","Parents",d2.parents.length?d2.parents.join(", "):"\u2014",p.on&&cur==="parents"?"Enter add/remove":void 0),d2.children.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Children"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.children.join(", ")})})]}):null,d2.workspace_kind?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Workspace"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,children:[d2.workspace_kind,d2.workspace_path?` @ ${d2.workspace_path}`:""]})})]}):null,d2.branch_name?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Branch"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.branch_name})})]}):null,d2.skills.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Skills"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.skills.join(", ")})})]}):null,d2.model_override?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Model"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.model_override})})]}):null,d2.max_retries!==null?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Retries"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.max_retries)})})]}):null,d2.pid?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"PID"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.pid)})})]}):null,d2.last_heartbeat_at&&d2.status==="running"?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Heartbeat"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:ago(d2.last_heartbeat_at)})})]}):null,d2.session_id?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Session"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.session_id})})]}):null,d2.error?$jsxs("box",{flexDirection:"column",paddingLeft:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:"Error"})}),$jsx("box",{paddingLeft:2,children:$jsx("text",{fg:theme.error,wrapMode:"word",children:d2.error})})]}):null,d2.status==="done"?mrow("result","Result",resultText?cur==="result"?$jsx("text",{wrapMode:"word",fg:theme.text,children:resultText}):$jsx("markdown",{content:resultText,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="result"?"Enter edit":void 0):null,p.diags.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"Diagnostics "}),$jsx("span",{fg:sevColor(p.diags[0].severity,theme),children:`(${p.diags.length})`})]})}),p.diags.map((dx,i)=>$jsxs("box",{flexDirection:"column",marginTop:i===0?0:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:sevColor(dx.severity,theme),children:SEV_GLYPH[dx.severity]}),$jsx("span",{fg:theme.text,children:` [${dx.severity}] ${dx.kind}`}),dx.count>1?$jsx("span",{fg:theme.textMuted,children:` \xD7${dx.count}`}):null]})}),$jsxs("box",{paddingLeft:2,flexDirection:"column",children:[$jsx("text",{wrapMode:"word",fg:theme.text,children:dx.title}),dx.detail?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:dx.detail}):null,dx.actions.map((a,j2)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:a.suggested?theme.accent:theme.textMuted,children:a.suggested?"\u2192 ":"\xB7 "}),$jsx("span",{fg:a.suggested?theme.text:theme.textMuted,children:a.label})]})},j2))]})]},`${dx.kind}-${i}`))]}):null,d2.runs.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Runs (${d2.runs.length})`})}),d2.runs.map((r)=>{let outcome=r.outcome||r.status||(r.ended_at?"ended":"active"),elapsed=r.ended_at?`${Math.max(0,r.ended_at-r.started_at)}s`:"active";return $jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:`#${r.id} `}),$jsx("span",{fg:theme.text,children:outcome}),$jsx("span",{fg:theme.textMuted,children:` @${r.profile??"-"} ${elapsed} ${ago(r.started_at)}`})]})}),r.summary?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:` \u2192 ${r.summary.split(`
|
|
4121
4121
|
`)[0].slice(0,200)}`}):null,r.error?$jsx("text",{wrapMode:"word",fg:theme.error,children:` \u2716 ${r.error.split(`
|
|
4122
4122
|
`)[0].slice(0,200)}`}):null]},r.id)})]}):null,d2.events.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Events (${d2.events.length})`})}),d2.events.map((e)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:`${ago(e.created_at).padEnd(10)} `}),$jsx("span",{fg:theme.text,children:e.kind}),e.payload?$jsx("span",{fg:theme.textMuted,children:` ${JSON.stringify(e.payload)}`}):null]})},e.id))]}):null,d2.comments.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Comments (${d2.comments.length})`})}),d2.comments.map((c,i)=>$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${c.author} \xB7 ${ago(c.at)}`})}),$jsx("text",{wrapMode:"word",children:c.body})]},i))]}):null,p.on&&cur==="comment"?$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.accent,children:"Enter add comment"})}):null]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.on?"Tab/\u2191\u2193 field Enter edit Esc grid a assign c comment l log":"Tab into pane a assign c comment u unblock d archive l log N child"})})]})}),Kanban=import_react80.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),keys=useKeys(),[boards,setBoards]=import_react80.useState(listBoards),[data2,setData]=import_react80.useState(()=>new Map(boards.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),[diags,setDiags]=import_react80.useState(()=>new Map),[masks,setMasks]=import_react80.useState(()=>maskFromPrefs(load2().kanban?.masks)),[open2,setOpen]=import_react80.useState(()=>{let saved=load2().kanban?.open;if(saved)return new Set(saved);let init=currentBoard();return new Set(listBoards().filter((b2)=>{let state2=boardStateOf(b2.slug);return b2.slug===init||[...state2.columns.values()].some((v2)=>v2.length>0)||!!state2.error}).map((b2)=>b2.slug))}),[at,setAt]=import_react80.useState(currentBoard),[tier,setTier]=import_react80.useState("grid"),[col,setCol]=import_react80.useState(0),[row2,setRow]=import_react80.useState(0),[chip,setChip]=import_react80.useState(0),[paneSel,setPaneSel]=import_react80.useState(0),[pane,setPane]=import_react80.useState(null),outer=import_react80.useRef(null),load4=import_react80.useCallback(()=>{let bs=listBoards();setBoards(bs),setData(new Map(bs.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),setPane((p)=>p?.kind==="detail"?((d2)=>d2?{...p,d:d2}:null)(detailOf(p.slug,p.d.id)):p),Promise.all(bs.map((b2)=>gw.request("shell.exec",{command:`hermes kanban --board ${q3(b2.slug)} diagnostics --json`}).then((r)=>r.code===0?parseDiagnostics(r.stdout):[]).catch(()=>[]).then((rows3)=>[b2.slug,indexDiags(rows3)]))).then((pairs)=>setDiags(new Map(pairs)))},[gw]);import_react80.useEffect(load4,[load4]),import_react80.useEffect(()=>{persist(masks,open2)},[masks,open2]);let maskOf=(s)=>masks.get(s)??EMPTY2,wide=dims.width>=160,maxH=Math.max(8,dims.height-16),sections=import_react80.useMemo(()=>{let built=boards.map((b2)=>{let state2=data2.get(b2.slug)??boardStateOf(b2.slug),d2=state2.columns,flat=STATUSES.flatMap((s)=>d2.get(s)??[]),total=flat.length,who=[...new Set(flat.map((t2)=>t2.assignee).filter((v2)=>!!v2))].sort(),pri=[...new Set(flat.map((t2)=>t2.priority).filter((n)=>n>0))].sort((a,z2)=>z2-a),chips=[...who.map((v2)=>({kind:"who",v:v2})),...pri.map((v2)=>({kind:"pri",v:v2})),...STATUSES.map((v2)=>({kind:"status",v:v2}))],m2=maskOf(b2.slug),cols3=STATUSES.filter((s)=>admits(m2.status,s)).map((s)=>({status:s,tasks:(d2.get(s)??[]).filter((t2)=>pass(t2,m2))})).filter((c)=>wide||c.tasks.length>0),shown=cols3.reduce((a,c)=>a+c.tasks.length,0),tall=cols3.reduce((a,c)=>Math.max(a,c.tasks.length),0);return{board:b2,cols:cols3,chips,total,shown,running:d2.get("running")?.length??0,cap:Math.min(maxH,Math.max(5,3+2*tall)),error:state2.error,corruptBackups:state2.corruptBackups}});return[...built.filter((s)=>s.total>0),...built.filter((s)=>s.total===0)]},[boards,data2,masks,wide,maxH]),idx=sections.findIndex((s)=>s.board.slug===at),sec3=sections[idx]??sections[0],cols2=sec3?.cols??[],clampCol=Math.min(col,Math.max(0,cols2.length-1)),cur=cols2[clampCol],task=tier==="grid"||tier==="pane"?cur?.tasks[Math.min(row2,Math.max(0,(cur?.tasks.length??1)-1))]:void 0,grand=sections.reduce((a,s)=>a+s.total,0),running2=sections.reduce((a,s)=>a+s.running,0);import_react80.useEffect(()=>{if(pane?.kind!=="detail")return;if(tier!=="grid"&&tier!=="pane"){setPane(null);return}if(!task){setPane(null);return}if(pane.slug===at&&pane.d.id===task.id)return;let d2=detailOf(at,task.id);setPane(d2?{kind:"detail",slug:at,d:d2}:null),setPaneSel(0)},[task?.id,at,tier]),import_react80.useEffect(()=>{if(!props.focused||running2===0)return;let t2=setInterval(load4,3000);return()=>clearInterval(t2)},[props.focused,running2,load4]),import_react80.useEffect(()=>{outer.current?.scrollChildIntoView(`kb-sec-${at}`)},[at,open2]);let sh=import_react80.useCallback((argv,ok)=>gw.request("shell.exec",{command:`hermes kanban --board ${q3(at)} ${argv}`}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());if(ok)toast.show({variant:"success",message:ok});return resetKanban(),load4(),r.stdout}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)})),[gw,toast,load4,at]),patchDirect=import_react80.useCallback((id,p,ok)=>{try{if(!patchTask(at,id,p))return void toast.show({variant:"error",message:`no such task: ${id}`});toast.show({variant:"success",message:ok}),load4()}catch(e){toast.show({variant:"error",message:trunc5(e.message,120)})}},[at,toast,load4]),enterTop=(s)=>{setAt(s.board.slug),setTier("head"),setChip(0),setRow(0)},enterBottom=(s)=>{if(setAt(s.board.slug),setChip(Math.max(0,s.chips.length-1)),open2.has(s.board.slug)&&s.shown>0){let nc=Math.min(col,Math.max(0,s.cols.length-1));setTier("grid"),setCol(nc),setRow(Math.max(0,(s.cols[nc]?.tasks.length??1)-1));return}if(open2.has(s.board.slug)){setTier("filter");return}setTier("head")},stepBoard=(d2)=>{let n=idx+d2;return n<0||n>=sections.length?null:sections[n]},goBoard=import_react80.useCallback((d2)=>{let n=(idx+d2+sections.length)%sections.length,s=sections[n];setAt(s.board.slug),setTier("head"),setCol(0),setRow(0),setChip(0),setOpen((o)=>o.has(s.board.slug)?o:new Set(o).add(s.board.slug))},[idx,sections]),flip=import_react80.useCallback((c)=>setMasks((m2)=>{let cur2=m2.get(at)??EMPTY2,who=new Map(cur2.who),pri=new Map(cur2.pri),status=new Map(cur2.status),g=c.kind==="who"?who:c.kind==="pri"?pri:status,next2=cycle(g.get(c.v)??"off");next2==="off"?g.delete(c.v):g.set(c.v,next2);let out=new Map(m2);return out.set(at,{who,pri,status}),setRow(0),out}),[at]),toggle=import_react80.useCallback((s)=>setOpen((o)=>{let n=new Set(o);return n.has(s)?n.delete(s):n.add(s),n}),[]),newBoard=import_react80.useCallback(()=>openTextPrompt(dialog,{title:"New board",label:"Slug (a-z, 0-9, -_)"}).then((v2)=>{if(!v2)return;return gw.request("shell.exec",{command:`hermes kanban boards create ${q3(v2)}`}).then((r)=>r.code===0?(toast.show({variant:"success",message:`Board '${v2}' created`}),resetKanban(),load4(),setAt(v2),setTier("head")):Promise.reject(Error((r.stderr||r.stdout).trim()))).catch((e)=>toast.show({variant:"error",message:trunc5(e.message,120)}))}),[dialog,gw,toast,load4]),live=import_react80.useRef({task,at,sec:sec3});live.current={task,at,sec:sec3};let create=import_react80.useCallback((parent2)=>openCreateTask(dialog,{assignees:assignees(live.current.at),parent:parent2?{id:parent2.id,title:parent2.title}:void 0}).then((d2)=>{if(!d2)return;let ws=d2.workspace.kind==="scratch"?"":d2.workspace.kind==="worktree"?"--workspace worktree":`--workspace ${q3(`dir:${d2.workspace.path}`)}`,flags=[d2.assignee?`--assignee ${q3(d2.assignee)}`:"",d2.body?`--body ${q3(d2.body)}`:"",d2.priority?`--priority ${d2.priority}`:"",d2.parent?`--parent ${q3(d2.parent)}`:"",d2.triage?"--triage":"",d2.tenant?`--tenant ${q3(d2.tenant)}`:"",ws,d2.maxRuntime?`--max-runtime ${q3(d2.maxRuntime)}`:"",...d2.skills.map((s)=>`--skill ${q3(s)}`)].filter(Boolean).join(" ");return sh(`create ${q3(d2.title)} ${flags}`.trim(),`Created${d2.triage?" (triage)":""}${d2.assignee?` \u2192 ${d2.assignee}`:""}`)}),[dialog,sh]),assign=import_react80.useCallback((t2)=>{let opts=[{title:"(unassigned)",value:"none"},...assignees(live.current.at).map((n)=>({title:n,value:n}))];dialog.replace($jsx(DialogSelect,{title:`Assign ${t2.id}`,options:opts,current:t2.assignee??"none",placeholder:"Search profiles\u2026",onSelect:(o)=>{dialog.clear(),sh(`assign ${q3(t2.id)} ${q3(o.value)}`,o.value==="none"?`Unassigned ${t2.id}`:`${t2.id} \u2192 ${o.value}`)}}))},[dialog,sh]),comment=import_react80.useCallback((t2)=>openTextPrompt(dialog,{title:`Comment on ${t2.id}`,label:t2.title}).then((v2)=>v2&&sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`,"Comment added")),[dialog,sh]),unblock=import_react80.useCallback((t2)=>{if(t2.status!=="blocked"&&t2.status!=="scheduled")return void toast.show({variant:"info",message:`${t2.id} is ${t2.status}, not blocked/scheduled`});if(t2.status==="scheduled")return void sh(`unblock ${q3(t2.id)}`,`Released ${t2.id}`);return openTextPrompt(dialog,{title:`Unblock ${t2.id}`,label:"Answer (posted as comment, then task \u2192 ready)"}).then((v2)=>{if(v2)return sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`)}).then(()=>sh(`unblock ${q3(t2.id)}`,`Unblocked ${t2.id}`))},[dialog,sh,toast]),archive=import_react80.useCallback((t2)=>openConfirm(dialog,{title:"Archive task?",danger:!0,yes:"archive",body:`${t2.id} \xB7 ${trunc5(t2.title,60)}
|
|
4123
4123
|
|
|
@@ -4162,7 +4162,7 @@ ${r.skipped.slice(0,8).join(", ")}${r.skipped.length>8?", \u2026":""}`:""}`,yes:
|
|
|
4162
4162
|
`,"utf-8")}function push2(text2){let list3=load4(),at=Math.max(Date.now(),(list3[list3.length-1]?.at??0)+1);if(list3.push({text:text2,at}),list3.length>MAX)list3.shift();return save3(list3),list3.length}function pop2(){let list3=load4(),e=list3.pop();if(!e)return null;return save3(list3),e}function all(){return load4().reverse()}function drop(at){save3(load4().filter((e)=>e.at!==at))}var import_react121=__toESM(require_react_production(),1);var ctx=import_react121.createContext(null),BackgroundProvider=({children:children2})=>{let[set2,setSet]=import_react121.useState(()=>new Set),register2=import_react121.useCallback((id)=>{if(!id)return;setSet((prev)=>prev.has(id)?prev:new Set(prev).add(id))},[]),unregister=import_react121.useCallback((id)=>{setSet((prev)=>{if(!prev.has(id))return prev;let next2=new Set(prev);return next2.delete(id),next2})},[]),ids=import_react121.useMemo(()=>Array.from(set2),[set2]),value=import_react121.useMemo(()=>({count:ids.length,ids,register:register2,unregister}),[ids,register2,unregister]);return $jsx(ctx.Provider,{value,children:children2})},useBackground=makeUse(ctx,"useBackground");var initialTurn={messages:[],streaming:!1,hasContent:!1,toolActive:!1};function turnReducer(state2,a){switch(a.kind){case"reset":return initialTurn;case"load":return{...initialTurn,messages:a.messages};case"load.live":return{...initialTurn,messages:a.messages,streaming:a.streaming,hasContent:a.streaming&&Boolean(joinText(a.messages.at(-1)?.parts??[]))};case"push":return{...state2,messages:[...state2.messages,a.message]};case"user":return{...state2,messages:[...state2.messages,userMessage(a.text)]};case"system":return{...state2,messages:[...state2.messages,systemMessage(sanitize(a.text))]};case"message.start":return{...state2,streaming:!0,hasContent:!1,toolActive:!1};case"message.delta":{let chunk=sanitize(a.chunk);if(!chunk)return state2;return{...state2,hasContent:!0,toolActive:!1,messages:appendText(state2.messages,chunk)}}case"message.complete":return{...state2,streaming:!1,hasContent:!1,toolActive:!1,messages:finalize(state2.messages,a.text!=null?sanitize(a.text):void 0,a.usage)};case"tool.start":{let preview2=sanitize(a.preview),args=sanitize(a.args),raw2=args||preview2,json=raw2&&/^\s*\{/.test(raw2),part={type:"tool",id:a.id,name:a.name,args:json?raw2:"",status:"running",startedAt:Date.now(),preview:preview2||void 0,verboseArgs:args||void 0};return{...state2,toolActive:!0,hasContent:!1,messages:appendPart(state2.messages,part,!0)}}case"tool.progress":return{...state2,messages:updateRunningTool(state2.messages,a.name,(p)=>({...p,preview:sanitize(a.preview)||p.preview}))};case"tool.generating":return{...state2,messages:updateRunningTool(state2.messages,a.name,(p)=>({...p,preview:p.preview??"generating\u2026"}))};case"tool.complete":{let summary2=sanitize(a.summary),error=sanitize(a.error),diff=sanitize(a.inline_diff),result=sanitize(a.result);return{...state2,toolActive:!1,messages:updateToolById(state2.messages,a.id,(p)=>({...p,status:a.error?"error":"done",duration:a.duration??(p.startedAt?Date.now()-p.startedAt:void 0),preview:summary2||diff||p.preview,result:error||summary2||void 0,verboseResult:result||void 0,diff:diff||void 0}))}}case"thinking":return{...state2,messages:upsertThinking(state2.messages,sanitize(a.text),a.final,a.verbose)};case"subagent":return{...state2,messages:renderSubagent(state2.messages,a.event,a.payload)};case"prompt":{let part={type:"prompt",id:a.id,variant:a.req.variant,req:a.req};return{...state2,messages:appendPart(state2.messages,part,!0)}}case"prompt.answered":return{...state2,messages:updatePrompt(state2.messages,a.id,(p)=>({...p,answered:{label:a.label,ok:a.ok,at:Date.now()}}))};case"error":return{...state2,streaming:!1,hasContent:!1,toolActive:!1,messages:[...state2.messages,systemMessage(`Error: ${sanitize(a.text)}`)]};case"interrupt.notice":{let clean=sanitize(a.text),last3=state2.messages[state2.messages.length-1];if(last3?.role==="system"&&last3.parts[0]?.type==="text"&&last3.parts[0].content.includes(clean))return state2;return{...state2,messages:[...state2.messages,systemMessage(clean)]}}}}function userMessage(text2){return{id:mid(),role:"user",parts:[{type:"text",content:text2,streaming:!1}],timestamp:Date.now()/1000}}function systemMessage(text2){return{id:mid(),role:"system",parts:[{type:"text",content:text2,streaming:!1}],timestamp:Date.now()/1000}}function flatten3(text2){if(typeof text2==="string")return text2;if(!Array.isArray(text2))return"";let out=[];for(let p of text2)if(p&&typeof p==="object"&&"type"in p&&p.type==="text"&&"text"in p&&typeof p.text==="string")out.push(p.text);return out.join(`
|
|
4163
4163
|
`)}function transcriptToMessages(rows3){return rows3.filter((r)=>r.role==="user"||r.role==="assistant").map((r)=>({role:r.role,content:sanitize(flatten3(r.text))})).filter((r)=>r.content).map((r)=>({id:mid(),role:r.role,parts:[{type:"text",content:r.content,streaming:!1}],timestamp:Date.now()/1000}))}function assistant(parts2){return{id:mid(),role:"assistant",parts:parts2,timestamp:Date.now()/1000}}function withLastAssistant(messages,fn,otherwise){let last3=messages[messages.length-1];if(last3?.role==="assistant")return[...messages.slice(0,-1),fn(last3)];return[...messages,otherwise()]}function seal(parts2){let last3=parts2[parts2.length-1];if(last3?.type==="text"&&last3.streaming)return[...parts2.slice(0,-1),{...last3,streaming:!1}];return parts2}function appendText(messages,chunk){return withLastAssistant(messages,(m2)=>{let last3=m2.parts[m2.parts.length-1];if(last3?.type==="text"&&last3.streaming){let part={...last3,content:last3.content+chunk};return{...m2,parts:[...m2.parts.slice(0,-1),part]}}return{...m2,parts:[...m2.parts,{type:"text",key:pid(),content:chunk,streaming:!0}]}},()=>assistant([{type:"text",key:pid(),content:chunk,streaming:!0}]))}function appendPart(messages,part,close){return withLastAssistant(messages,(m2)=>({...m2,parts:[...close?seal(m2.parts):m2.parts,part]}),()=>assistant([part]))}function finalize(messages,final,usage){let last3=messages[messages.length-1];if(last3?.role==="assistant"){let tail=last3.parts[last3.parts.length-1],dup=final&&last3.parts.some((p)=>p.type==="text"&&sameText(p.content,final)),text2=tail?.type==="text"&&final&&sameText(tail.content,final)?tail.content:final,parts2=tail?.type==="text"&&tail.streaming?[...last3.parts.slice(0,-1),{...tail,content:text2||tail.content,streaming:!1}]:final&&!dup&&!sameText(joinText(last3.parts),final)?[...last3.parts,{type:"text",content:final,streaming:!1}]:seal(last3.parts);return[...messages.slice(0,-1),{...last3,parts:parts2,usage}]}if(!final)return messages;return[...messages,{...assistant([{type:"text",content:final,streaming:!1}]),usage}]}function joinText(parts2){return parts2.filter((p)=>p.type==="text").map((p)=>p.content).join("")}function sameText(a,b2){return a.trim()===b2.trim()}function updateRunningTool(messages,name,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;for(let i=last3.parts.length-1;i>=0;i--){let p=last3.parts[i];if(p.type!=="tool"||p.status!=="running")continue;if(name&&p.name!==name)continue;let parts2=[...last3.parts];return parts2[i]=fn(p),[...messages.slice(0,-1),{...last3,parts:parts2}]}return messages}function updateToolById(messages,id,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;let parts2=last3.parts.map((p)=>p.type==="tool"&&p.id===id?fn(p):p);return[...messages.slice(0,-1),{...last3,parts:parts2}]}function updatePrompt(messages,id,fn){return messages.map((m2)=>{if(m2.role!=="assistant")return m2;if(!m2.parts.some((p)=>p.type==="prompt"&&p.id===id))return m2;return{...m2,parts:m2.parts.map((p)=>p.type==="prompt"&&p.id===id?fn(p):p)}})}function upsertThinking(messages,text2,final,verbose2){return withLastAssistant(messages,(m2)=>{let idx=m2.parts.findIndex((p)=>p.type==="thinking");if(idx>=0){let prev=m2.parts[idx],content=final?prev.content.trim()||text2:prev.content+text2,parts2=[...m2.parts];return parts2[idx]={...prev,content,streaming:!final,verbose:prev.verbose||verbose2||void 0},{...m2,parts:parts2}}return{...m2,parts:[{type:"thinking",key:pid(),content:text2,streaming:!final,verbose:verbose2},...m2.parts]}},()=>assistant([{type:"thinking",key:pid(),content:text2,streaming:!final,verbose:verbose2}]))}function renderSubagent(messages,event,p){let id=p.subagent_id?`sub-${p.subagent_id}`:`sub-${p.task_index}`;if(event==="start"){let goal=sanitize(p.goal),part={type:"tool",id,name:"delegate_task",args:"",status:"running",startedAt:Date.now(),preview:goal||void 0,goal:goal||void 0,depth:p.depth??0,trail:[]};return appendPart(messages,part,!0)}if(event==="tool"&&p.tool_name){let tname=sanitize(p.tool_name),tprev=sanitize(p.tool_preview);return updateToolById(messages,id,(t2)=>({...t2,trail:[...t2.trail??[],{name:tname,preview:tprev||void 0}],preview:tprev?`${tname}: ${tprev}`:tname}))}if(event==="complete"){let tokens3=(p.input_tokens??0)+(p.output_tokens??0),extra=tokens3?` \xB7 ${(tokens3/1000).toFixed(1)}k tok`:"",summary2=sanitize(p.summary);return updateToolById(messages,id,(t2)=>({...t2,status:p.status==="failed"||p.status==="error"||p.status==="timeout"||p.status==="interrupted"?"error":"done",duration:p.duration_seconds?p.duration_seconds*1000:t2.startedAt?Date.now()-t2.startedAt:void 0,result:summary2?summary2+extra:void 0,preview:t2.goal??t2.preview}))}return updateToolById(messages,id,(t2)=>({...t2,preview:sanitize(p.text)||t2.preview}))}function useSlash(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),themeCtx=useTheme(),cmd=useCommand(),renderer=useRenderer(),cfg=useHome("config"),bg2=useBackground(),ctx2=import_react122.useRef(c);ctx2.current=c;let gate=import_react122.useRef(cfg);gate.current=cfg;let destructive=import_react122.useCallback((arg,opts,action)=>{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",bypass=!(gate.current?.approvals?.destructive_slash_confirm??!0)||process.env.HERMES_TUI_NO_CONFIRM==="1",persist2=a==="always",fire=()=>{if(persist2)Promise.resolve().then(() => (init_lane(),exports_lane)).then(({writeConfig:writeConfig2})=>writeConfig2(gw,[{key:"approvals.destructive_slash_confirm",to:!1}]).then((r)=>{if(r.failed.length){toast.show({variant:"warning",message:`couldn't persist: ${r.failed[0].err}`});return}home2.invalidate("config"),toast.show({variant:"success",message:`${opts.yes} \xB7 future runs silent`})}).catch((e)=>toast.show({variant:"error",message:e.message})));action()};if(skip||bypass)return fire();openConfirm(dialog,{title:opts.title,body:opts.body,yes:opts.yes,danger:!0}).then((ok)=>{if(ok)fire()})},[gw,dialog,toast]),pickEikon=import_react122.useCallback(()=>openEikonPicker(dialog,(n)=>set("eikon",n)),[dialog]),applyTitle=import_react122.useCallback((t2)=>{gw.request("session.title",{title:t2}).then((r)=>{ctx2.current.setTitle(r.title),ctx2.current.dispatch({kind:"system",text:`Title: ${r.title}`})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),runCompress=import_react122.useCallback(async()=>{toast.show({variant:"info",message:"Compressing session\u2026"});let r=await ctx2.current.session.compress();if(!r)return;if(r.info)ctx2.current.setInfo(r.info);if(ctx2.current.setUsage((u3)=>{let base2=r.usage??u3,max=r.usage?.context_max??u3?.context_max;if(typeof r.after_tokens!=="number"||typeof max!=="number")return base2;return{...base2??{input:0,output:0,total:0},context_used:r.after_tokens,context_max:max}}),Array.isArray(r.messages))ctx2.current.dispatch({kind:"load",messages:transcriptToMessages(r.messages)});if(!r.summary)return;let s=r.summary;if(s.noop){toast.show({variant:"info",message:s.headline??`No changes \xB7 ~${r.before_tokens??0} tokens`});return}let lines2=[s.headline,s.token_line,s.note].filter(Boolean).join(`
|
|
4164
4164
|
`);if(lines2)ctx2.current.dispatch({kind:"system",text:lines2});toast.show({variant:"success",message:s.headline??`Compressed ${r.before_messages??0}\u2192${r.after_messages??0} messages`})},[toast]),run=import_react122.useCallback((c2,arg="")=>{let x2=ctx2.current;if(c2.target==="local")switch(c2.name){case"clear":destructive(arg,{title:"Clear session?",body:"Discards the in-memory transcript. Your session on disk is unchanged; reload to restore.",yes:"clear"},()=>x2.dispatch({kind:"reset"}));return;case"new":destructive(arg,{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{x2.newSession()});return;case"theme":openThemePicker(dialog,themeCtx);return;case"help":dialog.replace($jsx(HelpDialog,{}));return;case"keys":openKeys(dialog);return;case"logs":openLogs(dialog);return;case"title":if(arg){applyTitle(arg);return}openTextPrompt(dialog,{title:"Session Title",initial:x2.title}).then((v2)=>{if(v2)applyTitle(v2)});return;case"rollback":openRollback(dialog,gw,toast);return;case"history":openHistory(dialog,gw);return;case"status":openStatus(dialog,x2.info,x2.sid);return;case"usage":openUsage(dialog,gw);return;case"profile":openProfile(dialog);return;case"chafa":if(!arg.trim()){toast.show({variant:"info",message:"usage: /chafa <path>"});return}openChafa(dialog,arg.trim());return;case"splash":x2.summoned.current=!0,x2.setSplash(!0);return;case"skin":{let name=arg.trim();if(!name){x2.dispatch({kind:"system",text:`skin: ${x2.skin.skin?.name??"\u2014"}
|
|
4165
|
-
${SKINS.join(" ")}`});return}if(!SKINS.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name))themeCtx.set(name);set("eikon",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":x2.session.branch(arg||void 0).then((id)=>id?void x2.switchSession(id):toast.show({variant:"error",message:"branch failed"}));return;case"compress":runCompress();return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user");if(at>=0)x2.undone.current.push(msgs.slice(at));x2.session.undo().then(()=>gw.request("session.history").then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch(()=>{}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text(head));return}case"retry":{let last3=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last3){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last3).then(()=>x2.sendRef.current(text(last3)));return}case"model":if(!arg){openModelPicker(dialog,gw);return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text2=arg||comp?.value().trim()||"";if(!text2)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text2);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text(m2);copy(body2),toast.show({variant:"success",message:`copied ${body2.length} chars`});return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){toast.show({variant:"info",message:"usage: /background <prompt>"});return}gw.request("prompt.background",{text:arg}).then((r)=>{if(r.task_id)bg2.register(r.task_id);toast.show(r.task_id?{variant:"success",message:`background ${r.task_id} started`}:{variant:"error",message:"background start failed"})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub2=parts2[0]?.toLowerCase()||"connect",url=parts2[1];if(!["connect","disconnect","status"].includes(sub2)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload={action:sub2};if(sub2==="connect"&&url)payload.url=url;gw.request("browser.manage",payload).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub2==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub2==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"compact":case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text2)=>gw.request("session.steer",{text:text2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text2)=>{if(text2)fire(text2)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.sid)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress]);return import_react122.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>ctx2.current.session.branch()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,run]),run}var import_react126=__toESM(require_react_production(),1);var import_react124=__toESM(require_react_production(),1);function openAlert(dialog,title,body2){dialog.replace($jsx(Alert,{title,body:body2,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied,setCopied]=import_react124.useState(!1),doCopy=()=>{copy(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied?theme.success:theme.textMuted,children:$jsx("u",{children:copied?"copied":"copy"})})})]})]})};init_perf();function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function formatProcessNotification(text2){let body2=text2.replace(/^\[IMPORTANT: /,"").replace(/\]$/,""),done2=body2.match(/^Background process (\S+) completed \(exit code (\S+)\)\.\nCommand: (.+?)(?:\n|$)/);if(done2)return`${done2[1]} exited ${done2[2]} \xB7 ${done2[3]}`;let hit2=body2.match(/^Background process (\S+) matched watch pattern "([^"]+)"\.\nCommand: (.+?)(?:\n|$)/);if(hit2)return`${hit2[1]} matched "${hit2[2]}" \xB7 ${hit2[3]}`;return body2.slice(0,100)}function mapEvent(ev,side){switch(ev.type){case"gateway.ready":if(side.onReady?.(),ev.payload?.skin)side.onSkin?.(ev.payload.skin);return null;case"session.info":{let si=ev.payload;side.onSessionInfo?.(si);let label=si.model?`Connected \u2014 ${si.model} \xB7 ${count3(si.tools)} tools \xB7 ${count3(si.skills)} skills`:"Connected to Hermes";if(si.credential_warning)side.onStatus?.(si.credential_warning);return{kind:"system",text:label}}case"message.start":return count("stream:start"),mem("stream-start"),{kind:"message.start"};case"message.delta":{let chunk=ev.payload?.text??"";if(!chunk)return null;return count("stream:chunk"),{kind:"message.delta",chunk}}case"message.complete":{count("stream:done"),mem("stream-done");let p=ev.payload;if(p?.usage)side.onUsage?.(p.usage);if(side.onTurnComplete?.(),p?.status==="error")return{kind:"error",text:p.text||"request failed \u2014 see messages above"};if(p?.status==="interrupted")return{kind:"message.complete",text:(p.text||"")+`
|
|
4165
|
+
${SKINS.join(" ")}`});return}if(!SKINS.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name))themeCtx.set(name);set("eikon",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":x2.session.branch(arg||void 0).then((id)=>id?void x2.switchSession(id):toast.show({variant:"error",message:"branch failed"}));return;case"compress":runCompress();return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user");if(at>=0)x2.undone.current.push(msgs.slice(at));x2.session.undo().then(()=>gw.request("session.history").then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch(()=>{}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text(head));return}case"retry":{let last3=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last3){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last3).then(()=>x2.sendRef.current(text(last3)));return}case"model":if(!arg){openModelPicker(dialog,gw);return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text2=arg||comp?.value().trim()||"";if(!text2)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text2);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text(m2);copy(body2),toast.show({variant:"success",message:`copied ${body2.length} chars`});return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){toast.show({variant:"info",message:"usage: /background <prompt>"});return}gw.request("prompt.background",{text:arg}).then((r)=>{if(r.task_id)bg2.register(r.task_id);toast.show(r.task_id?{variant:"success",message:`background ${r.task_id} started`}:{variant:"error",message:"background start failed"})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub2=parts2[0]?.toLowerCase()||"connect",url=parts2[1];if(!["connect","disconnect","status"].includes(sub2)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload={action:sub2};if(sub2==="connect"&&url)payload.url=url;gw.request("browser.manage",payload).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub2==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub2==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"compact":case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text2)=>gw.request("session.steer",{text:text2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text2)=>{if(text2)fire(text2)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.sid)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress]);return import_react122.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>ctx2.current.session.branch()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,run]),run}var import_react126=__toESM(require_react_production(),1);var import_react124=__toESM(require_react_production(),1);function openAlert(dialog,title,body2){dialog.replace($jsx(Alert,{title,body:body2,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied,setCopied]=import_react124.useState(!1),doCopy=()=>{copy(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied?theme.success:theme.textMuted,children:$jsx("u",{children:copied?"copied":"copy"})})})]})]})};init_perf();function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function formatProcessNotification(text2){let body2=text2.replace(/^\[IMPORTANT: /,"").replace(/\]$/,""),done2=body2.match(/^Background process (\S+) completed \(exit code (\S+)\)\.\nCommand: (.+?)(?:\n|$)/);if(done2)return`${done2[1]} exited ${done2[2]} \xB7 ${done2[3]}`;let hit2=body2.match(/^Background process (\S+) matched watch pattern "([^"]+)"\.\nCommand: (.+?)(?:\n|$)/);if(hit2)return`${hit2[1]} matched "${hit2[2]}" \xB7 ${hit2[3]}`;return body2.slice(0,100)}function mapEvent(ev,side){switch(ev.type){case"gateway.ready":if(side.onReady?.(),ev.payload?.skin)side.onSkin?.(ev.payload.skin);return null;case"session.info":{let si=ev.payload;side.onSessionInfo?.(si);let label2=si.model?`Connected \u2014 ${si.model} \xB7 ${count3(si.tools)} tools \xB7 ${count3(si.skills)} skills`:"Connected to Hermes";if(si.credential_warning)side.onStatus?.(si.credential_warning);return{kind:"system",text:label2}}case"message.start":return count("stream:start"),mem("stream-start"),{kind:"message.start"};case"message.delta":{let chunk=ev.payload?.text??"";if(!chunk)return null;return count("stream:chunk"),{kind:"message.delta",chunk}}case"message.complete":{count("stream:done"),mem("stream-done");let p=ev.payload;if(p?.usage)side.onUsage?.(p.usage);if(side.onTurnComplete?.(),p?.status==="error")return{kind:"error",text:p.text||"request failed \u2014 see messages above"};if(p?.status==="interrupted")return{kind:"message.complete",text:(p.text||"")+`
|
|
4166
4166
|
|
|
4167
4167
|
*[interrupted]*`,usage:p?.usage};return{kind:"message.complete",text:p?.text??void 0,usage:p?.usage}}case"tool.start":return{kind:"tool.start",id:ev.payload.tool_id,name:ev.payload.name??"unknown",preview:ev.payload.context,args:ev.payload.args_text};case"tool.progress":return{kind:"tool.progress",name:ev.payload.name,preview:ev.payload.preview};case"tool.generating":return{kind:"tool.generating",name:ev.payload.name};case"tool.complete":return{kind:"tool.complete",id:ev.payload.tool_id,summary:ev.payload.summary,error:ev.payload.error,inline_diff:ev.payload.inline_diff,duration:typeof ev.payload.duration_s==="number"?ev.payload.duration_s*1000:void 0,result:ev.payload.result_text};case"thinking.delta":return side.onStatus?.(ev.payload?.text??""),null;case"reasoning.delta":case"reasoning.available":{let text2=ev.payload?.text;if(!text2)return null;return{kind:"thinking",text:text2,final:ev.type==="reasoning.available",verbose:ev.payload?.verbose}}case"subagent.start":case"subagent.thinking":case"subagent.tool":case"subagent.progress":case"subagent.complete":{let sub2=ev.type.slice(9);return record(sub2,ev.payload),{kind:"subagent",event:sub2,payload:ev.payload}}case"error":return{kind:"error",text:ev.payload?.message??"Unknown error"};case"clarify.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"clarify",...ev.payload}};case"approval.request":return{kind:"prompt",id:`approval-${pid()}`,req:{variant:"approval",...ev.payload}};case"sudo.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"sudo",...ev.payload}};case"secret.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"secret",...ev.payload}};case"background.complete":return side.onBackground?.(ev.payload.task_id,ev.payload.text),null;case"review.summary":{let text2=String(ev.payload?.text??"").trim();if(!text2)return null;return{kind:"system",text:text2}}case"btw.complete":return side.onBtw?.(ev.payload.text),null;case"gateway.stderr":{let line3=ev.payload.line;if(/error|fail|traceback|exception|\b[45]\d\d\b|refused|denied|unauthori/i.test(line3))return{kind:"error",text:line3};return null}case"skin.changed":return side.onSkin?.(ev.payload),null;case"gateway.start_timeout":return{kind:"error",text:`gateway startup timed out (${ev.payload?.python??"python"} @ ${ev.payload?.cwd??"?"})`};case"gateway.protocol_error":return{kind:"system",text:`protocol error: ${ev.payload?.preview??"?"}`};case"browser.progress":{let text2=ev.payload?.message??"";if(!text2)return null;return ev.payload?.level==="error"?{kind:"error",text:text2}:{kind:"system",text:`\xB7 ${text2}`}}case"status.update":{let kind2=ev.payload?.kind,text2=ev.payload?.text??"";if(side.onStatus?.(text2),!kind2||kind2==="status")return null;if(kind2==="process")return side.onProcessNotification?.(text2),null;return{kind:"system",text:text2}}case"voice.status":{let state2=String(ev.payload?.state??"");return side.onVoiceStatus?.(state2),null}case"voice.transcript":{if(ev.payload?.no_speech_limit===!0)return side.onVoiceTranscript?.("",!0),null;let text2=String(ev.payload?.text??"").trim();if(!text2)return null;return side.onVoiceTranscript?.(text2,!1),null}}return null}var STREAM_EVENTS=new Set(["message.start","message.delta","reasoning.delta","reasoning.available","thinking.delta","tool.start","tool.progress","tool.generating"]);function useStream(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),bg2=useBackground(),ctx2=import_react126.useRef(c);ctx2.current=c;let interrupted=import_react126.useRef(!1),deltas=import_react126.useRef({text:"",think:"",timer:null}),procs=import_react126.useRef({texts:[],timer:null}),flush2=import_react126.useCallback(()=>{let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;if(d2.think)ctx2.current.dispatch({kind:"thinking",text:d2.think,final:!1}),d2.think="";if(d2.text)ctx2.current.dispatch({kind:"message.delta",chunk:d2.text}),d2.text=""},[]),flushProcs=import_react126.useCallback(()=>{let n=procs.current;if(n.timer)clearTimeout(n.timer),n.timer=null;if(!n.texts.length)return;let batch=n.texts.splice(0),lines2=batch.map((t2)=>` ${formatProcessNotification(t2)}`);ctx2.current.dispatch({kind:"system",text:batch.length===1?`\u25C6 background ${lines2[0].trim()}`:`\u25C6 ${batch.length} background notifications
|
|
4168
4168
|
${lines2.join(`
|
|
@@ -4192,9 +4192,9 @@ ${lines2.join(`
|
|
|
4192
4192
|
`,t2.cursorOffset-1)>=0)return!1;if(buf2.includes(`
|
|
4193
4193
|
`)&&t2.cursorOffset!==0)return t2.cursorOffset=0,!0;return hist.up(),!0},historyDown:()=>{let t2=ta.current;if(!t2||modeRef.current==="shell")return!1;let buf2=live.current.input;if(buf2.indexOf(`
|
|
4194
4194
|
`,t2.cursorOffset)>=0)return!1;if(buf2.includes(`
|
|
4195
|
-
`)&&t2.cursorOffset!==buf2.length)return t2.cursorOffset=buf2.length,!0;return hist.down(),!0}}),[hist.up,hist.down,pop3.setCursor,write]);let sidsRef=import_react139.useRef(sids);sidsRef.current=sids;let taRef=import_react139.useCallback((r)=>{if(ta.current=r,r&&!buf.current)buf.current=new PartsBuffer(r,sidsRef.current);if(!r)buf.current=null},[]),
|
|
4196
|
-
`).length)),lift=rows3+3;return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,children:$jsx(SlashPopover,{commands:pop3.popover,cursor:pop3.cursor,onCursor:pop3.setCursor,onSelect:select2})}):props.focused&&at.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):null,(props.queue?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,children:props.queue.map((q5,i)=>$jsx("box",{height:1,onMouseDown:()=>props.onDequeue?.(i),children:$jsxs("text",{children:[$jsxs("span",{fg:theme.borderSubtle,children:[i===0?"\u256D":"\u2502"," "]}),$jsxs("span",{fg:theme.textMuted,children:["\u23F8 ",i+1,". ",trunc5(q5,60)]})]})},i))}):null,(props.attachments?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,gap:1,children:props.attachments.map((a)=>a.path?$jsx(ChafaImage,{path:a.path,width:60},`p-${a.path}`):null)}):null,(props.attachments?.length??0)>0?$jsx("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingBottom:1,children:props.attachments.map((a,i)=>$jsxs("text",{children:[$jsx("span",{bg:theme.accent,fg:theme.background,children:" img "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`image ${i+1}`," "]}),a.width&&a.height?$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[a.width,"\xD7",a.height," "]}):null,a.token_estimate?$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:["~",fmt4(a.token_estimate),"t "]}):null,$jsx("span",{fg:theme.textMuted,children:" "}),$jsx("span",{fg:theme.textMuted,children:"\u232B to detach"})]},a.path??i))}):null,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"row",position:"relative",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode==="shell"?"$":">"})}),$jsx("box",{width:1}),$jsx("textarea",{ref:taRef,syntaxStyle,onContentChange:()=>{let t2=ta.current;setInput(t2?.plainText??""),setCaret(t2?.cursorOffset??0)},onCursorChange:()=>{if(!live.current.input.includes("@"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode==="shell"?"Run a shell command (30s cap, cwd) \u2014 esc or \u232B to exit":props.streaming?"Type to queue... (Enter queues, click chip to edit)":"Message Hermes... (/ for commands, Shift+Enter for newline)",focused:props.focused,textColor:theme.text,focusedTextColor:theme.text,placeholderColor:theme.textMuted,cursorColor:theme.text,backgroundColor:"transparent",focusedBackgroundColor:"transparent",flexGrow:1}),pop3.ghost&&props.focused&&rows3===1?$jsx("box",{position:"absolute",top:0,left:2+input.length,height:1,children:$jsx("text",{fg:theme.textMuted,children:pop3.ghost})}):null]}),$jsxs("box",{height:1,flexDirection:"row",paddingX:1,children:[$jsxs("text",{children:[$jsx("span",{fg:dot,children:"\u25CF "}),$jsx("span",{fg:theme.textMuted,children:mode==="shell"?"Shell":label}),mode==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.streaming&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to interrupt"}):props.streaming?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 interrupt"}):null]}),$jsx("box",{flexGrow:1}),props.streaming&&(props.queue?.length??0)>0?$jsxs("text",{fg:theme.textMuted,children:[keys.print("queue.flush")," to send queued now "]}):null,$jsx("box",{height:1,flexDirection:"row",onMouseDown:()=>props.onSteer?.(),children:$jsxs("text",{children:[$jsx("span",{fg:theme.borderSubtle,children:"\u25C7 "}),$jsx("span",{fg:theme.textMuted,children:"steer "}),$jsx("span",{fg:theme.accent,children:keys.print("session.steer")})]})}),$jsx("text",{fg:theme.textMuted,children:" "}),bg2.count>0?$jsxs("text",{fg:theme.text,children:["\u25B6 ",bg2.count," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react140=__toESM(require_react_production(),1);init_sessions_db();var spec2=(row2)=>{if(!row2?.model)return null;if(!row2.billing_provider)return row2.model;return`${row2.model} --provider ${row2.billing_provider}`},normalize2=(sid)=>sid.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user)messages.push(...transcriptToMessages([{role:"user",text:user}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react140.useCallback(async(sid)=>{let target=normalize2(sid),row2=byId(target),res=await gw.request("session.resume",{session_id:target}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target);let model=spec2(row2);if(model)await gw.request("config.set",{key:"model",value:model}).catch(()=>{});let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react140.useCallback(async()=>{let res=await gw.request("session.create",{});return gw.setSession(res.session_id),{id:res.session_id,info:res.info}},[gw]),activate=import_react140.useCallback(async(sid)=>{let target=normalize2(sid),res=await gw.request("session.activate",{session_id:target}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.session_key??id);let history=res.messages?.length?transcriptToMessages(res.messages):[],running2=Boolean(res.running||res.status==="working"||res.status==="waiting");return{id,info:res.info,messages:[...history,...inflightMessages(res.inflight)],running:running2,startedAt:res.started_at?res.started_at*1000:void 0,status:res.status}},[gw]),close=import_react140.useCallback(async(sid)=>{if(!sid)return;try{await gw.request("session.close",{session_id:sid})}catch{}},[gw]),boot2=import_react140.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target=launch.sid??exports_sessions_db.lastReal()?.id;if(!target)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target} failed: ${msg} \u2014 starting fresh`)}}let last3=get2("lastSessionId"),row2=last3?exports_sessions_db.byId(last3):null;if(row2?.message_count===0&&row2.parent_session_id==null)try{return await resume(row2.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react140.useCallback(async()=>{try{await gw.request("session.interrupt")}catch{}},[gw]),branch2=import_react140.useCallback(async(name)=>{try{return(await gw.request("session.branch",name?{name}:{})).session_id??null}catch{return null}},[gw]),compress=import_react140.useCallback(async()=>{try{return await gw.request("session.compress")}catch{return null}},[gw]),undo=import_react140.useCallback(async()=>{try{await gw.request("session.undo")}catch{}},[gw]);return import_react140.useMemo(()=>({boot:boot2,create,resume,activate,close,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close,interrupt,branch2,compress,undo])}init_sessions_db();init_hermes_analytics();function rehome(newHome){process.env.HERMES_HOME=newHome,setHome2(newHome),setHome(newHome),cache3.clear(),resetKanban(),exports_preferences.reload(),home2.reset()}var import_react141=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react141.useState(p.seconds);import_react141.useEffect(()=>{if(n<=0){p.onFire();return}let t2=setTimeout(()=>setN((v2)=>v2-1),1000);return()=>clearTimeout(t2)},[n,p.onFire]),useKeyboard(()=>p.onCancel());let bar3="\u2588".repeat(n)+"\u2591".repeat(Math.max(0,p.seconds-n));return $jsxs("box",{flexDirection:"column",width:58,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.warning,children:[bar3," ",n,"s"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.action})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"press any key to cancel"})})]})};function openCountdown(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Countdown,{...opts,onFire:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}),()=>resolve4(!1))})}var SECONDS=10,SUSPEND=process.platform==="darwin"?"pmset sleepnow":"systemctl suspend",run=(cmd)=>Bun.spawn(["sh","-c",cmd],{stdout:"ignore",stderr:"ignore"}),fired=new Map;function makeGoalHook(dialog,toast){let act=(goal,done2,total)=>{let pref=(exports_preferences.get("onGoalDone")??"toast").trim(),head=goal.length>60?goal.slice(0,57)+"\u2026":goal,n=total&&total>0?` ${done2}/${total} items`:"";if(toast.show({variant:"success",title:"Goal complete",message:head+n,duration:8000}),pref==="toast")return;let cmd=pref==="suspend"?SUSPEND:pref;openCountdown(dialog,{title:"Goal complete \u2014 "+(pref==="suspend"?"suspending":"running hook"),body:head,action:`\u2192 ${cmd}`,seconds:SECONDS}).then((ok)=>{if(ok)run(cmd)})};return{check:(sid)=>{if(!sid)return;io.goalState(sid).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid)===s.goal)return;fired.set(sid,s.goal);let list3=s.checklist??[],done2=list3.filter((i)=>i.status==="completed"||i.status==="impossible").length;act(s.goal,done2,list3.length)}).catch(()=>{})}}}var import_react143=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react143.useState(!1),[recording,setRecording]=import_react143.useState(!1),[processing,setProcessing]=import_react143.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react143.useState(),[tts,setTts]=import_react143.useState(!1),[onTranscript,setTranscript]=import_react143.useState(null),setOnTranscript=import_react143.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),recordKey=import_react143.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react143.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state2=import_react143.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react143.useCallback(async(action,sid)=>{try{let r=await gw("voice.toggle",{action,session_id:sid});if(r.enabled!==void 0)setEnabled(r.enabled);if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label}]`)}catch(e){sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react143.useCallback(async(sid)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}let starting=!recording,action=starting?"start":"stop";if(starting)setRecording(!0);else setRecording(!1),setProcessing(!1);try{let r=await gw("voice.record",{action,session_id:sid});if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(starting)setRecording(!1);sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}},[enabled3,recording,gw,sys]);return{state:state2,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text2,fg2=theme.text;if(voice.recording)text2="\u25CF recording",fg2=theme.error;else if(voice.processing)text2="\u25CC transcribing",fg2=theme.warning;else text2=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text2," "]})})}var App=(props)=>$jsx(ThemeProvider,{initial:props.initialTheme,children:$jsx(GatewayProvider,{client:props.gateway,children:$jsx(ToastProvider,{children:$jsx(KeysProvider,{overrides:props.keyOverrides,children:$jsx(DialogProvider,{children:$jsx(CommandProvider,{children:$jsx(PluginProvider,{children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react145.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react145.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react145.useState(!1),[sid,setSid]=import_react145.useState(""),sidRef=import_react145.useRef(sid);sidRef.current=sid;let[tab,setTab]=import_react145.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react145.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react145.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react145.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react145.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react145.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react145.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react145.useState(!1),[usage,setUsage]=import_react145.useState(void 0),[info2,setInfo]=import_react145.useState(null),[title,setTitle]=import_react145.useState(""),titleRef=import_react145.useRef(title);titleRef.current=title,import_react145.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react145.useEffect(()=>{let w2=warning();if(!w2)return;toast.show({variant:"warning",title:"control server exposed",message:w2.message,duration:15000})},[toast]);let[focusRegion,setFocusRegion]=import_react145.useState("input"),goToTab=import_react145.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react145.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status,setStatus]=import_react145.useState(""),[escHint,setEscHint]=import_react145.useState(!1),[eikon,setEikon]=import_react145.useState(void 0),[queue,setQueue]=import_react145.useState([]),[busy,setBusy]=import_react145.useState("queue"),turnRef=import_react145.useRef(turn);turnRef.current=turn;let queueRef=import_react145.useRef(queue);queueRef.current=queue;let launchRef=import_react145.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react145.useState(launch.splash!==!1),[switching,setSwitching]=import_react145.useState(!1),summoned=import_react145.useRef(!1),[composing,setComposing]=import_react145.useState(!1),splashLast=import_react145.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react145.useMemo(()=>info2?{agentVersion:info2.version,behind:info2.update_behind,model:info2.model}:void 0,[info2?.version,info2?.update_behind,info2?.model]),splashLastProp=import_react145.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react145.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react145.useState([]),[cloudH,setCloudH]=import_react145.useState(CLOUD_MIN),[pick2,setPick]=import_react145.useState(void 0),[skin,setSkin]=import_react145.useState(()=>deriveSkin(void 0)),inflight=import_react145.useRef(!1),undone=import_react145.useRef([]),sessionStart=import_react145.useRef(Date.now()),composer2=import_react145.useRef(null),promptRef=import_react145.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react145.useRef(cmds);cmdsRef.current=cmds;let sys=import_react145.useCallback((text2)=>dispatch({kind:"system",text:text2}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react145.useEffect(()=>{voice.setOnTranscript((text2)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text2),0)})},[]);let[errorPulse,setErrorPulse]=import_react145.useState(!1),agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":turn.streaming?"thinking":composing?"listening":"idle",onAvatarHold=import_react145.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react145.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react145.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react145.useRef(turn.streaming);import_react145.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react145.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react145.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react145.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react145.useRef(()=>{}),steer=import_react145.useCallback((text2)=>{let v2=text2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),openSteer=import_react145.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react145.useCallback((t2)=>{if(busy==="steer"){let v2=t2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"Queued \u2014 lands on next tool result"});setQueue((q5)=>[...q5,t2]),toast.show({variant:"info",message:"steer rejected \u2014 queued for next turn"})}).catch(()=>setQueue((q5)=>[...q5,t2]));return}if(busy==="interrupt")return intr.current(),setQueue((q5)=>[t2,...q5]);setQueue((q5)=>[...q5,t2])},[busy,gw,toast]),onAttach=import_react145.useCallback((r)=>setAttachments((a)=>[...a,r]),[]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setUsage,setStatus,setSkin,setErrorPulse});intr.current=stream.doInterrupt;let reset3=import_react145.useCallback(()=>{stream.interrupted.current=!1,undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStatus(""),setTitle(""),setAttachments([])},[]),newSession=import_react145.useCallback(async()=>{let prev=sidRef.current;if(reset3(),summoned.current=!0,setSplash(!0),gw.setSession(""),setSid(""),prev)session.close(prev);try{let r=await session.create();if(setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);sessionStart.current=Date.now()}catch{}},[reset3,session,gw]),switchSession=import_react145.useCallback(async(target)=>{let prev=sidRef.current;reset3(),summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target);if(setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(setReady(!0),sessionStart.current=Date.now(),res.messages.length)dispatch({kind:"load",messages:res.messages});if(prev&&prev!==res.id)session.close(prev);setSplash(!1),summoned.current=!1}catch(err){dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset3,session,goToTab,gw]),liveStatus=(state2,running2=!1)=>{if(state2==="waiting")return"waiting for input\u2026";if(state2==="starting")return"starting agent\u2026";return running2||state2==="working"?"running\u2026":"ready"},activateSession=import_react145.useCallback(async(target)=>{let prev=sidRef.current;reset3(),summoned.current=!0,setSplash(!0),setSwitching(!0),goToTab(CHAT_TAB);try{let res=await session.activate(target);if(setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(sessionStart.current=res.startedAt??Date.now(),dispatch({kind:"load.live",messages:res.messages,streaming:res.running}),setStatus(liveStatus(res.status,res.running)),setReady(!0),setSplash(!1),summoned.current=!1,prev&&prev!==res.id)toast.show({variant:"info",message:"switched live session"})}catch(err){dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset3,session,goToTab,toast]),switchProfile=import_react145.useCallback((newHome,name)=>{rehome(newHome),reset3(),gw.setSession(""),setSid(""),setInfo(null),setSkin(deriveSkin(void 0)),summoned.current=!0,setSplash(!0),launchRef.current={mode:"new",splash:!0},toast.show({variant:"info",message:`Switching to '${name}'\u2026`}),goToTab(CHAT_TAB),gwRestart()},[reset3,goToTab,gwRestart,toast,gw]),loadEikon=import_react145.useCallback((path7)=>{Bun.file(path7).text().then((t2)=>setEikon(parseEikon(t2))).catch(()=>{})},[]),eikonName=usePref("eikon"),eikonRev=import_react145.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react145.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin.skin?.name,loadEikon]);let turnsFrom=(m2)=>{let msgs=turnRef.current.messages,at=msgs.findIndex((x2)=>x2.id===m2.id);return at<0?0:msgs.slice(at).filter((x2)=>x2.role==="user").length},rewind=import_react145.useCallback(async(m2)=>{if(turnRef.current.streaming)return;let n=turnsFrom(m2);if(n===0)return;let text2=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");for(let i=0;i<n;i++)await gw.request("session.undo").catch(()=>{});let r=await gw.request("session.history").catch(()=>null),msgs=turnRef.current.messages,at=msgs.findIndex((x2)=>x2.id===m2.id);dispatch({kind:"load",messages:r?transcriptToMessages(r.messages??[]):msgs.slice(0,at)}),composer2.current?.set(text2),setFocusRegion("input")},[gw]),fork2=import_react145.useCallback(async(m2)=>{if(turnRef.current.streaming)return;let n=turnsFrom(m2),text2=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join(""),res=await gw.request("session.branch",{}).catch((e)=>{return toast.show({variant:"error",message:`branch failed: ${e.message}`}),null});if(!res?.session_id)return;for(let i=0;i<n;i++)await gw.request("session.undo",{session_id:res.session_id}).catch(()=>{});await switchSession(res.session_id),composer2.current?.set(text2),setFocusRegion("input"),toast.show({variant:"success",message:`forked \u2192 ${res.title??res.session_id}`})},[gw,toast,switchSession]),msgMenu=import_react145.useCallback((m2)=>{if(turnRef.current.streaming)return;openMessage(dialog,m2,{rewind,fork:fork2})},[dialog,rewind,fork2]),attachClipboard=import_react145.useCallback(()=>{gw.request("clipboard.paste").then((r)=>r.attached?setAttachments((a)=>[...a,r]):toast.show({variant:"info",message:r.message??"No image in clipboard"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),sendRef=import_react145.useRef(()=>{}),slash=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,ready,info:info2,sid,title,skin,setQueue,setFocusRegion,setSplash,setAttachments,setInfo,setUsage,setTitle,newSession,switchSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react145.useCallback(async(raw2)=>{if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sid,title,gw);let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve8(cmdsRef.current,name);if("hit"in r)return slash(r.hit,arg.trim());if("ambiguous"in r){let head=r.ambiguous.slice(0,6).join(", ");return dispatch({kind:"system",text:`ambiguous: /${name} \u2192 ${head}${r.ambiguous.length>6?", \u2026":""}`})}}let text2=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text2=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let withMedia=attachments.length?[...attachments.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text2].filter(Boolean).join(`
|
|
4195
|
+
`)&&t2.cursorOffset!==buf2.length)return t2.cursorOffset=buf2.length,!0;return hist.down(),!0}}),[hist.up,hist.down,pop3.setCursor,write]);let sidsRef=import_react139.useRef(sids);sidsRef.current=sids;let taRef=import_react139.useCallback((r)=>{if(ta.current=r,r&&!buf.current)buf.current=new PartsBuffer(r,sidsRef.current);if(!r)buf.current=null},[]),label2=!props.ready?"Connecting...":props.streaming?props.status||"Generating...":"Ready",dot=props.ready?props.streaming?theme.warning:theme.success:theme.error,rows3=Math.min(MAX_ROWS,Math.max(1,input.split(`
|
|
4196
|
+
`).length)),lift=rows3+3;return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,children:$jsx(SlashPopover,{commands:pop3.popover,cursor:pop3.cursor,onCursor:pop3.setCursor,onSelect:select2})}):props.focused&&at.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):null,(props.queue?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,children:props.queue.map((q5,i)=>$jsx("box",{height:1,onMouseDown:()=>props.onDequeue?.(i),children:$jsxs("text",{children:[$jsxs("span",{fg:theme.borderSubtle,children:[i===0?"\u256D":"\u2502"," "]}),$jsxs("span",{fg:theme.textMuted,children:["\u23F8 ",i+1,". ",trunc5(q5,60)]})]})},i))}):null,(props.attachments?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,gap:1,children:props.attachments.map((a)=>a.path?$jsx(ChafaImage,{path:a.path,width:60},`p-${a.path}`):null)}):null,(props.attachments?.length??0)>0?$jsx("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingBottom:1,children:props.attachments.map((a,i)=>$jsxs("text",{children:[$jsx("span",{bg:theme.accent,fg:theme.background,children:" img "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`image ${i+1}`," "]}),a.width&&a.height?$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[a.width,"\xD7",a.height," "]}):null,a.token_estimate?$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:["~",fmt4(a.token_estimate),"t "]}):null,$jsx("span",{fg:theme.textMuted,children:" "}),$jsx("span",{fg:theme.textMuted,children:"\u232B to detach"})]},a.path??i))}):null,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"row",position:"relative",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode==="shell"?"$":">"})}),$jsx("box",{width:1}),$jsx("textarea",{ref:taRef,syntaxStyle,onContentChange:()=>{let t2=ta.current;setInput(t2?.plainText??""),setCaret(t2?.cursorOffset??0)},onCursorChange:()=>{if(!live.current.input.includes("@"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode==="shell"?"Run a shell command (30s cap, cwd) \u2014 esc or \u232B to exit":props.streaming?"Type to queue... (Enter queues, click chip to edit)":"Message Hermes... (/ for commands, Shift+Enter for newline)",focused:props.focused,textColor:theme.text,focusedTextColor:theme.text,placeholderColor:theme.textMuted,cursorColor:theme.text,backgroundColor:"transparent",focusedBackgroundColor:"transparent",flexGrow:1}),pop3.ghost&&props.focused&&rows3===1?$jsx("box",{position:"absolute",top:0,left:2+input.length,height:1,children:$jsx("text",{fg:theme.textMuted,children:pop3.ghost})}):null]}),$jsxs("box",{height:1,flexDirection:"row",paddingX:1,children:[$jsxs("text",{children:[$jsx("span",{fg:dot,children:"\u25CF "}),$jsx("span",{fg:theme.textMuted,children:mode==="shell"?"Shell":label2}),mode==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.streaming&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to interrupt"}):props.streaming?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 interrupt"}):null]}),$jsx("box",{flexGrow:1}),props.streaming&&(props.queue?.length??0)>0?$jsxs("text",{fg:theme.textMuted,children:[keys.print("queue.flush")," to send queued now "]}):null,$jsx("box",{height:1,flexDirection:"row",onMouseDown:()=>props.onSteer?.(),children:$jsxs("text",{children:[$jsx("span",{fg:theme.borderSubtle,children:"\u25C7 "}),$jsx("span",{fg:theme.textMuted,children:"steer "}),$jsx("span",{fg:theme.accent,children:keys.print("session.steer")})]})}),$jsx("text",{fg:theme.textMuted,children:" "}),bg2.count>0?$jsxs("text",{fg:theme.text,children:["\u25B6 ",bg2.count," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react140=__toESM(require_react_production(),1);init_sessions_db();var spec2=(row2)=>{if(!row2?.model)return null;if(!row2.billing_provider)return row2.model;return`${row2.model} --provider ${row2.billing_provider}`},normalize2=(sid)=>sid.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user)messages.push(...transcriptToMessages([{role:"user",text:user}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react140.useCallback(async(sid)=>{let target=normalize2(sid),row2=byId(target),res=await gw.request("session.resume",{session_id:target}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target);let model=spec2(row2);if(model)await gw.request("config.set",{key:"model",value:model}).catch(()=>{});let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react140.useCallback(async()=>{let res=await gw.request("session.create",{});return gw.setSession(res.session_id),{id:res.session_id,info:res.info}},[gw]),activate=import_react140.useCallback(async(sid)=>{let target=normalize2(sid),res=await gw.request("session.activate",{session_id:target}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.session_key??id);let history=res.messages?.length?transcriptToMessages(res.messages):[],running2=Boolean(res.running||res.status==="working"||res.status==="waiting");return{id,info:res.info,messages:[...history,...inflightMessages(res.inflight)],running:running2,startedAt:res.started_at?res.started_at*1000:void 0,status:res.status}},[gw]),close=import_react140.useCallback(async(sid)=>{if(!sid)return;try{await gw.request("session.close",{session_id:sid})}catch{}},[gw]),boot2=import_react140.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target=launch.sid??exports_sessions_db.lastReal()?.id;if(!target)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target} failed: ${msg} \u2014 starting fresh`)}}let last3=get2("lastSessionId"),row2=last3?exports_sessions_db.byId(last3):null;if(row2?.message_count===0&&row2.parent_session_id==null)try{return await resume(row2.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react140.useCallback(async()=>{try{await gw.request("session.interrupt")}catch{}},[gw]),branch2=import_react140.useCallback(async(name)=>{try{return(await gw.request("session.branch",name?{name}:{})).session_id??null}catch{return null}},[gw]),compress=import_react140.useCallback(async()=>{try{return await gw.request("session.compress")}catch{return null}},[gw]),undo=import_react140.useCallback(async()=>{try{await gw.request("session.undo")}catch{}},[gw]);return import_react140.useMemo(()=>({boot:boot2,create,resume,activate,close,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close,interrupt,branch2,compress,undo])}init_sessions_db();init_hermes_analytics();function rehome(newHome){process.env.HERMES_HOME=newHome,setHome2(newHome),setHome(newHome),cache3.clear(),resetKanban(),exports_preferences.reload(),home2.reset()}var import_react141=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react141.useState(p.seconds);import_react141.useEffect(()=>{if(n<=0){p.onFire();return}let t2=setTimeout(()=>setN((v2)=>v2-1),1000);return()=>clearTimeout(t2)},[n,p.onFire]),useKeyboard(()=>p.onCancel());let bar3="\u2588".repeat(n)+"\u2591".repeat(Math.max(0,p.seconds-n));return $jsxs("box",{flexDirection:"column",width:58,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.warning,children:[bar3," ",n,"s"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.action})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"press any key to cancel"})})]})};function openCountdown(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Countdown,{...opts,onFire:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}),()=>resolve4(!1))})}var SECONDS=10,SUSPEND=process.platform==="darwin"?"pmset sleepnow":"systemctl suspend",run=(cmd)=>Bun.spawn(["sh","-c",cmd],{stdout:"ignore",stderr:"ignore"}),fired=new Map;function makeGoalHook(dialog,toast){let act=(goal,done2,total)=>{let pref=(exports_preferences.get("onGoalDone")??"toast").trim(),head=goal.length>60?goal.slice(0,57)+"\u2026":goal,n=total&&total>0?` ${done2}/${total} items`:"";if(toast.show({variant:"success",title:"Goal complete",message:head+n,duration:8000}),pref==="toast")return;let cmd=pref==="suspend"?SUSPEND:pref;openCountdown(dialog,{title:"Goal complete \u2014 "+(pref==="suspend"?"suspending":"running hook"),body:head,action:`\u2192 ${cmd}`,seconds:SECONDS}).then((ok)=>{if(ok)run(cmd)})};return{check:(sid)=>{if(!sid)return;io.goalState(sid).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid)===s.goal)return;fired.set(sid,s.goal);let list3=s.checklist??[],done2=list3.filter((i)=>i.status==="completed"||i.status==="impossible").length;act(s.goal,done2,list3.length)}).catch(()=>{})}}}var import_react143=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react143.useState(!1),[recording,setRecording]=import_react143.useState(!1),[processing,setProcessing]=import_react143.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react143.useState(),[tts,setTts]=import_react143.useState(!1),[onTranscript,setTranscript]=import_react143.useState(null),setOnTranscript=import_react143.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),recordKey=import_react143.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react143.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state2=import_react143.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react143.useCallback(async(action,sid)=>{try{let r=await gw("voice.toggle",{action,session_id:sid});if(r.enabled!==void 0)setEnabled(r.enabled);if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label2=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label2}]`)}catch(e){sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react143.useCallback(async(sid)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}let starting=!recording,action=starting?"start":"stop";if(starting)setRecording(!0);else setRecording(!1),setProcessing(!1);try{let r=await gw("voice.record",{action,session_id:sid});if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(starting)setRecording(!1);sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}},[enabled3,recording,gw,sys]);return{state:state2,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text2,fg2=theme.text;if(voice.recording)text2="\u25CF recording",fg2=theme.error;else if(voice.processing)text2="\u25CC transcribing",fg2=theme.warning;else text2=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text2," "]})})}var App=(props)=>$jsx(ThemeProvider,{initial:props.initialTheme,children:$jsx(GatewayProvider,{client:props.gateway,children:$jsx(ToastProvider,{children:$jsx(KeysProvider,{overrides:props.keyOverrides,children:$jsx(DialogProvider,{children:$jsx(CommandProvider,{children:$jsx(PluginProvider,{children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react145.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react145.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react145.useState(!1),[sid,setSid]=import_react145.useState(""),sidRef=import_react145.useRef(sid);sidRef.current=sid;let[tab,setTab]=import_react145.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react145.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react145.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react145.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react145.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react145.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react145.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react145.useState(!1),[usage,setUsage]=import_react145.useState(void 0),[info2,setInfo]=import_react145.useState(null),[title,setTitle]=import_react145.useState(""),titleRef=import_react145.useRef(title);titleRef.current=title,import_react145.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react145.useEffect(()=>{let w2=warning();if(!w2)return;toast.show({variant:"warning",title:"control server exposed",message:w2.message,duration:15000})},[toast]);let[focusRegion,setFocusRegion]=import_react145.useState("input"),goToTab=import_react145.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react145.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status,setStatus]=import_react145.useState(""),[escHint,setEscHint]=import_react145.useState(!1),[eikon,setEikon]=import_react145.useState(void 0),[queue,setQueue]=import_react145.useState([]),[busy,setBusy]=import_react145.useState("queue"),turnRef=import_react145.useRef(turn);turnRef.current=turn;let queueRef=import_react145.useRef(queue);queueRef.current=queue;let launchRef=import_react145.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react145.useState(launch.splash!==!1),[switching,setSwitching]=import_react145.useState(!1),summoned=import_react145.useRef(!1),[composing,setComposing]=import_react145.useState(!1),splashLast=import_react145.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react145.useMemo(()=>info2?{agentVersion:info2.version,behind:info2.update_behind,model:info2.model}:void 0,[info2?.version,info2?.update_behind,info2?.model]),splashLastProp=import_react145.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react145.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react145.useState([]),[cloudH,setCloudH]=import_react145.useState(CLOUD_MIN),[pick2,setPick]=import_react145.useState(void 0),[skin,setSkin]=import_react145.useState(()=>deriveSkin(void 0)),inflight=import_react145.useRef(!1),undone=import_react145.useRef([]),sessionStart=import_react145.useRef(Date.now()),composer2=import_react145.useRef(null),promptRef=import_react145.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react145.useRef(cmds);cmdsRef.current=cmds;let sys=import_react145.useCallback((text2)=>dispatch({kind:"system",text:text2}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react145.useEffect(()=>{voice.setOnTranscript((text2)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text2),0)})},[]);let[errorPulse,setErrorPulse]=import_react145.useState(!1),agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":turn.streaming?"thinking":composing?"listening":"idle",onAvatarHold=import_react145.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react145.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react145.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react145.useRef(turn.streaming);import_react145.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react145.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react145.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react145.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react145.useRef(()=>{}),steer=import_react145.useCallback((text2)=>{let v2=text2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),openSteer=import_react145.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react145.useCallback((t2)=>{if(busy==="steer"){let v2=t2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"Queued \u2014 lands on next tool result"});setQueue((q5)=>[...q5,t2]),toast.show({variant:"info",message:"steer rejected \u2014 queued for next turn"})}).catch(()=>setQueue((q5)=>[...q5,t2]));return}if(busy==="interrupt")return intr.current(),setQueue((q5)=>[t2,...q5]);setQueue((q5)=>[...q5,t2])},[busy,gw,toast]),onAttach=import_react145.useCallback((r)=>setAttachments((a)=>[...a,r]),[]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setUsage,setStatus,setSkin,setErrorPulse});intr.current=stream.doInterrupt;let reset3=import_react145.useCallback(()=>{stream.interrupted.current=!1,undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStatus(""),setTitle(""),setAttachments([])},[]),newSession=import_react145.useCallback(async()=>{let prev=sidRef.current;if(reset3(),summoned.current=!0,setSplash(!0),gw.setSession(""),setSid(""),prev)session.close(prev);try{let r=await session.create();if(setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);sessionStart.current=Date.now()}catch{}},[reset3,session,gw]),switchSession=import_react145.useCallback(async(target)=>{let prev=sidRef.current;reset3(),summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target);if(setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(setReady(!0),sessionStart.current=Date.now(),res.messages.length)dispatch({kind:"load",messages:res.messages});if(prev&&prev!==res.id)session.close(prev);setSplash(!1),summoned.current=!1}catch(err){dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset3,session,goToTab,gw]),liveStatus=(state2,running2=!1)=>{if(state2==="waiting")return"waiting for input\u2026";if(state2==="starting")return"starting agent\u2026";return running2||state2==="working"?"running\u2026":"ready"},activateSession=import_react145.useCallback(async(target)=>{let prev=sidRef.current;reset3(),summoned.current=!0,setSplash(!0),setSwitching(!0),goToTab(CHAT_TAB);try{let res=await session.activate(target);if(setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(sessionStart.current=res.startedAt??Date.now(),dispatch({kind:"load.live",messages:res.messages,streaming:res.running}),setStatus(liveStatus(res.status,res.running)),setReady(!0),setSplash(!1),summoned.current=!1,prev&&prev!==res.id)toast.show({variant:"info",message:"switched live session"})}catch(err){dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset3,session,goToTab,toast]),switchProfile=import_react145.useCallback((newHome,name)=>{rehome(newHome),reset3(),gw.setSession(""),setSid(""),setInfo(null),setSkin(deriveSkin(void 0)),summoned.current=!0,setSplash(!0),launchRef.current={mode:"new",splash:!0},toast.show({variant:"info",message:`Switching to '${name}'\u2026`}),goToTab(CHAT_TAB),gwRestart()},[reset3,goToTab,gwRestart,toast,gw]),loadEikon=import_react145.useCallback((path7)=>{Bun.file(path7).text().then((t2)=>setEikon(parseEikon(t2))).catch(()=>{})},[]),eikonName=usePref("eikon"),eikonRev=import_react145.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react145.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin.skin?.name,loadEikon]);let turnsFrom=(m2)=>{let msgs=turnRef.current.messages,at=msgs.findIndex((x2)=>x2.id===m2.id);return at<0?0:msgs.slice(at).filter((x2)=>x2.role==="user").length},rewind=import_react145.useCallback(async(m2)=>{if(turnRef.current.streaming)return;let n=turnsFrom(m2);if(n===0)return;let text2=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");for(let i=0;i<n;i++)await gw.request("session.undo").catch(()=>{});let r=await gw.request("session.history").catch(()=>null),msgs=turnRef.current.messages,at=msgs.findIndex((x2)=>x2.id===m2.id);dispatch({kind:"load",messages:r?transcriptToMessages(r.messages??[]):msgs.slice(0,at)}),composer2.current?.set(text2),setFocusRegion("input")},[gw]),fork2=import_react145.useCallback(async(m2)=>{if(turnRef.current.streaming)return;let n=turnsFrom(m2),text2=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join(""),res=await gw.request("session.branch",{}).catch((e)=>{return toast.show({variant:"error",message:`branch failed: ${e.message}`}),null});if(!res?.session_id)return;for(let i=0;i<n;i++)await gw.request("session.undo",{session_id:res.session_id}).catch(()=>{});await switchSession(res.session_id),composer2.current?.set(text2),setFocusRegion("input"),toast.show({variant:"success",message:`forked \u2192 ${res.title??res.session_id}`})},[gw,toast,switchSession]),msgMenu=import_react145.useCallback((m2)=>{if(turnRef.current.streaming)return;openMessage(dialog,m2,{rewind,fork:fork2})},[dialog,rewind,fork2]),attachClipboard=import_react145.useCallback(()=>{gw.request("clipboard.paste").then((r)=>r.attached?setAttachments((a)=>[...a,r]):toast.show({variant:"info",message:r.message??"No image in clipboard"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),sendRef=import_react145.useRef(()=>{}),slash=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,ready,info:info2,sid,title,skin,setQueue,setFocusRegion,setSplash,setAttachments,setInfo,setUsage,setTitle,newSession,switchSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react145.useCallback(async(raw2)=>{if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sid,title,gw);let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve8(cmdsRef.current,name);if("hit"in r)return slash(r.hit,arg.trim());if("ambiguous"in r){let head=r.ambiguous.slice(0,6).join(", ");return dispatch({kind:"system",text:`ambiguous: /${name} \u2192 ${head}${r.ambiguous.length>6?", \u2026":""}`})}}let text2=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text2=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let withMedia=attachments.length?[...attachments.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text2].filter(Boolean).join(`
|
|
4197
4197
|
`):text2;dispatch({kind:"user",text:withMedia}),setAttachments([]),undone.current=[],gw.request("prompt.submit",{text:text2}).catch(()=>{inflight.current=!1}),setTab(CHAT_TAB)},[gw,slash,attachments]);sendRef.current=send;let onShell=import_react145.useCallback((command)=>{setSplash(!1),dispatch({kind:"system",text:`$ ${command}`}),setStatus("running\u2026"),gw.request("shell.exec",{command}).then((r)=>{let out=(r.stdout??"").trimEnd(),err=(r.stderr??"").trimEnd(),body2=[out,err&&`stderr:
|
|
4198
4198
|
${err}`].filter(Boolean).join(`
|
|
4199
|
-
`);if(dispatch({kind:"system",text:body2||`(exit ${r.code??0})`}),(r.code??0)!==0)toast.show({variant:"warning",message:`exit ${r.code}`})}).catch((e)=>dispatch({kind:"system",text:`error: ${e.message}`})).finally(()=>setStatus(""))},[gw,toast]),onSend=import_react145.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react145.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react145.useEffect(()=>{if(turn.streaming)inflight.current=!1},[turn.streaming]),import_react145.useEffect(()=>{if(turn.streaming||inflight.current||!ready||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[turn.streaming,ready,queue,send]);let dequeue=import_react145.useCallback((i)=>{let item=queueRef.current[i];if(item===void 0)return;setQueue((q5)=>q5.filter((_2,j2)=>j2!==i)),composer2.current?.set(item),setFocusRegion("input")},[]),extra=plugins.routes,all2=import_react145.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),tabMax=all2.length-1;import_react145.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react145.useCallback((dir2)=>{let labels=SUB_TABS[tab];if(!labels||labels.length===0)return;setSubTabs((prev)=>{let cur=prev[tab]??0,next2=(cur+dir2+labels.length)%labels.length;return next2===cur?prev:{...prev,[tab]:next2}})},[tab]);useAppKeys({tab,tabMax,chatTab:CHAT_TAB,setTab,subCount,cycleSub,focusRegion,setFocusRegion,streaming:turn.streaming,dialogOpen:dialog.open,composer:composer2,onPromptKey:(k2)=>promptRef.current?.feed(k2)??!1,onEscape:()=>{if(!splash||!summoned.current)return!1;return setSplash(!1),summoned.current=!1,!0},onInterrupt:stream.doInterrupt,queued:queue.length,onFlushQueue:stream.doInterrupt,onQuit:()=>quit(renderer,sid,title,gw),onQuitArm:(
|
|
4199
|
+
`);if(dispatch({kind:"system",text:body2||`(exit ${r.code??0})`}),(r.code??0)!==0)toast.show({variant:"warning",message:`exit ${r.code}`})}).catch((e)=>dispatch({kind:"system",text:`error: ${e.message}`})).finally(()=>setStatus(""))},[gw,toast]),onSend=import_react145.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react145.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react145.useEffect(()=>{if(turn.streaming)inflight.current=!1},[turn.streaming]),import_react145.useEffect(()=>{if(turn.streaming||inflight.current||!ready||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[turn.streaming,ready,queue,send]);let dequeue=import_react145.useCallback((i)=>{let item=queueRef.current[i];if(item===void 0)return;setQueue((q5)=>q5.filter((_2,j2)=>j2!==i)),composer2.current?.set(item),setFocusRegion("input")},[]),extra=plugins.routes,all2=import_react145.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),tabMax=all2.length-1;import_react145.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react145.useCallback((dir2)=>{let labels=SUB_TABS[tab];if(!labels||labels.length===0)return;setSubTabs((prev)=>{let cur=prev[tab]??0,next2=(cur+dir2+labels.length)%labels.length;return next2===cur?prev:{...prev,[tab]:next2}})},[tab]);useAppKeys({tab,tabMax,chatTab:CHAT_TAB,setTab,subCount,cycleSub,focusRegion,setFocusRegion,streaming:turn.streaming,dialogOpen:dialog.open,composer:composer2,onPromptKey:(k2)=>promptRef.current?.feed(k2)??!1,onEscape:()=>{if(!splash||!summoned.current)return!1;return setSplash(!1),summoned.current=!1,!0},onInterrupt:stream.doInterrupt,queued:queue.length,onFlushQueue:stream.doInterrupt,onQuit:()=>quit(renderer,sid,title,gw),onQuitArm:(label2)=>toast.show({variant:"info",message:`${label2} again to quit`}),onInterruptNotice:()=>{setEscHint(!0),setTimeout(()=>setEscHint(!1),5000)},onCopyLast:()=>{let m2=[...turnRef.current.messages].reverse().find((x2)=>x2.role==="assistant"&&text(x2));if(m2)copy(text(m2))},onAttachClipboard:attachClipboard,onDetachLast:()=>{if(attachments.length===0)return!1;return setAttachments((a)=>a.slice(0,-1)),!0},onNotice:(text2)=>dispatch({kind:"system",text:text2}),onToggleSidebar:()=>setHideSidebar((v2)=>!v2),onSteer:openSteer,onStash:()=>{let c=composer2.current,v2=c?.value().trim()??"";if(!v2){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});c?.set(e.text);return}let n=exports_stash.push(v2);c?.set(""),toast.show({variant:"info",message:`stashed (${n})`})},voiceRecordKey:voice.state.recordKey,voiceEnabled:voice.state.enabled,onVoiceRecord:()=>voice.record(sidRef.current)}),useBridge({tab,ready,streaming:turn.streaming,messages:turn.messages,sid,focusRegion,setTab,setFocusRegion,dispatch,composer:composer2});let contentFocused=focusRegion==="content"&&!turn.streaming,promptAnswer=import_react145.useCallback((id,label2,ok)=>dispatch({kind:"prompt.answered",id,label:label2,ok}),[]),promptWire=import_react145.useMemo(()=>({ref:promptRef,onAnswer:promptAnswer}),[promptAnswer]);import_react145.useEffect(()=>{if(prompt&&tab!==CHAT_TAB)setTab(CHAT_TAB)},[prompt?.id]);let content=()=>{let inner=(()=>{switch(tab){case CHAT_TAB:return $jsx(Chat,{messages:turn.messages,streaming:turn.streaming,prompt:promptWire,cloud,cloudH,pick:pick2,onResize:setCloudH,onPick,onClose:closeCloud,onRewind:msgMenu});case SESSIONS_TAB:return $jsx(SessionsGroup,{focused:contentFocused,sub:subTabs[SESSIONS_TAB]??0,setSub:sessSub,onSwitch:switchSession,onActivateLive:activateSession,currentId:sid,messages:turn.messages,sessionStart:sessionStart.current,info:info2??void 0});case AUTOMATION_TAB:return $jsx(Automation,{focused:contentFocused,sub:subTabs[AUTOMATION_TAB]??0,setSub:autoSub,sessionId:sid,onSwitchProfile:switchProfile});case CONFIG_TAB:return $jsx(ConfigGroup,{focused:contentFocused,sub:subTabs[CONFIG_TAB]??0,setSub:cfgSub});case EIKON_TAB:return $jsx(EikonGroup,{focused:contentFocused,sub:subTabs[EIKON_TAB]??0,setSub:eikSub});default:{let r=extra[tab-TABS.length];return r?r.render():null}}})(),name=all2[tab]?.name??"unknown";return $jsx(import_react145.Profiler,{id:`tab:${name}`,onRender,children:inner})},theme=themeCtx.theme,onMouseUp=import_react145.useCallback(()=>copySelection(renderer),[renderer]),inputFocused=focusRegion==="input"&&!prompt;return $jsx(import_react145.Profiler,{id:"shell",onRender,children:$jsx(SkinProvider,{value:skin,children:$jsxs("box",{width:"100%",height:"100%",flexDirection:"column",backgroundColor:theme.background,onMouseUp,children:[$jsx(TabBar,{tabs:all2,activeTab:tab,onTabChange:goToTab}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsxs("box",{flexGrow:1,position:"relative",children:[content(),splash&&tab===CHAT_TAB?$jsx(Splash,{info:splashInfo,last:summoned.current?void 0:splashLastProp,composing,news,loading:switching||!info2}):null]}),$jsxs("box",{flexShrink:0,zIndex:1,children:[$jsx(VoiceIndicator,{voice:voice.state,keyLabel:voice.keyLabel}),$jsx(Composer,{ref:composer2,focused:inputFocused,connected:!!sid,ready,streaming:turn.streaming,status,model:info2?.model,escHint,queue,attachments,cmds,onSend,onSlash:slash,onShell,onAttach,onAttachClipboard:attachClipboard,onEnqueue,onDequeue:dequeue,onSteer:openSteer,onDirty:setComposing,onEmptyEnter})]})]}),dims.width>=(tab===CHAT_TAB?120:140)&&!hideSidebar?$jsx(import_react145.Profiler,{id:"sidebar",onRender,children:$jsx(Sidebar,{agentState,info:info2,usage,eikon,profile:activeProfileName(),title,cloud:tab===0&&cloud,pulse:turn.streaming,onAvatar,onAvatarHold})}):null]}),plugins.has("app_bottom")?$jsx("box",{height:1,flexShrink:0,paddingX:1,overflow:"hidden",children:$jsx(plugins.Slot,{name:"app_bottom",mode:"single_winner",sid,tab,streaming:turn.streaming})}):null]})})})};init_perf();var exports_bundled_skills={};__export(exports_bundled_skills,{sync:()=>sync,skills:()=>exports_bundled_skills});import{existsSync as existsSync23,mkdirSync as mkdirSync8,readdirSync as readdirSync8,cpSync}from"fs";import{dirname as dirname9,join as join23}from"path";var locate4=()=>{let d2=import.meta.dir;for(let i=0;i<5;i++){let p=join23(d2,"assets/skills");if(existsSync23(p))return p;let up=dirname9(d2);if(up===d2)break;d2=up}return};function has(root2,n){if(existsSync23(join23(root2,n,"SKILL.md")))return!0;if(!existsSync23(root2))return!1;return readdirSync8(root2,{withFileTypes:!0}).some((e)=>e.isDirectory()&&existsSync23(join23(root2,e.name,n,"SKILL.md")))}function sync(){let src2=locate4();if(!src2)return[];let root2=hermesPath("skills"),dst=join23(root2,"creative"),out=[];for(let e of readdirSync8(src2,{withFileTypes:!0})){if(!e.isDirectory())continue;if(has(root2,e.name))continue;mkdirSync8(dst,{recursive:!0}),cpSync(join23(src2,e.name),join23(dst,e.name),{recursive:!0}),out.push(e.name)}return out}import{writeSync as writeSync2}from"fs";var TERMINAL_MODE_RESET="\x1B[0'z\x1B[0'{\x1B[?2029l\x1B[?1016l\x1B[?1015l\x1B[?1006l\x1B[?1005l\x1B[?1003l\x1B[?1002l\x1B[?1001l\x1B[?1000l\x1B[?9l\x1B[?1004l\x1B[?2004l\x1B[?1049l\x1B[<u\x1B[>4;0m\x1B[0m\x1B[?25h";function resetTerminalModes(stream=process.stdout){if(!stream.isTTY)return!1;let fd=typeof stream.fd==="number"?stream.fd:stream===process.stdout?1:void 0;if(fd!==void 0)try{return writeSync2(fd,TERMINAL_MODE_RESET),!0}catch{}try{return stream.write(TERMINAL_MODE_RESET),!0}catch{return!1}}var wired=!1;function installExitResetHooks(){if(wired)return;wired=!0,process.on("exit",()=>{resetTerminalModes()});let codes={SIGHUP:129,SIGINT:130,SIGTERM:143};for(let sig of["SIGINT","SIGTERM","SIGHUP"])process.on(sig,()=>{resetTerminalModes(),process.exit(codes[sig])});process.on("uncaughtException",(err)=>{resetTerminalModes(),console.error(err),process.exit(1)}),process.on("unhandledRejection",(reason)=>{resetTerminalModes(),console.error(reason),process.exit(1)})}boot("import-graph",Bun.nanoseconds()/1e6);var argv=Bun.argv.slice(2);if(argv.includes("--help")||argv.includes("-h"))process.stdout.write(HELP2),process.exit(0);if(argv.includes("--version")||argv.includes("-v"))process.stdout.write(VERSION+`
|
|
4200
4200
|
`),process.exit(0);var launch=parseLaunch(argv),main2=async()=>{resetTerminalModes(),installExitResetHooks(),mem("pre-renderer");let prefs=load2(),end=mark("renderer-init"),renderer=await createCliRenderer({exitOnCtrlC:!1,useMouse:prefs.mouse??!0,targetFps:prefs.targetFps??30,gatherStats:!1});end();let bump3=()=>renderer.capabilities?.kitty_keyboard||process.stdout.isTTY&&process.stdout.write("\x1B[>4;2m");bump3(),renderer.on("focus",bump3),mem("post-renderer"),await prime(prefs.theme??DEFAULT_THEME);let root2=createRoot(renderer),endRender=mark("first-render");root2.render($jsx(App,{initialTheme:prefs.theme,launch})),endRender(),boot("first-render",Bun.nanoseconds()/1e6),warmup(),warm(),exports_bundled_skills.sync(),mem("post-first-render"),monitor(15000),start()};main2().catch(console.error);
|