herm-tui 1.8.0-dev.1 → 1.8.1-dev.1
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 +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4193,7 +4193,7 @@ ${lines2.join(`
|
|
|
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
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},[]),label=!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":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,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}},[gw]),create=import_react140.useCallback(async()=>{let res=await gw.request("session.create",{});return gw.setSession(res.session_id),res.session_id},[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)=>({id: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(()=>{}),onEnqueue=import_react145.useCallback((t2)=>{if(busy==="steer"){gw.request("session.steer",{text:t2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"steered \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{setSid(await session.create()),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),goToTab(CHAT_TAB);try{let res=await session.resume(target);if(setSid(res.id),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]),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(`
|
|
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,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),res.session_id},[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)=>({id: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(()=>{}),onEnqueue=import_react145.useCallback((t2)=>{if(busy==="steer"){gw.request("session.steer",{text:t2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"steered \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{setSid(await session.create()),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
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:(label)=>toast.show({variant:"info",message:`${label} 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),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,label,ok)=>dispatch({kind:"prompt.answered",id,label,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,ready,streaming:turn.streaming,status,model:info2?.model,escHint,queue,attachments,cmds,onSend,onSlash:slash,onShell,onAttach,onAttachClipboard:attachClipboard,onEnqueue,onDequeue:dequeue,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 join22}from"path";var locate4=()=>{let d2=import.meta.dir;for(let i=0;i<5;i++){let p=join22(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(join22(root2,n,"SKILL.md")))return!0;if(!existsSync23(root2))return!1;return readdirSync8(root2,{withFileTypes:!0}).some((e)=>e.isDirectory()&&existsSync23(join22(root2,e.name,n,"SKILL.md")))}function sync(){let src2=locate4();if(!src2)return[];let root2=hermesPath("skills"),dst=join22(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(join22(src2,e.name),join22(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+`
|