herm-tui 1.11.0-dev.6 → 1.11.0-dev.7
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 +3 -3
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4207,10 +4207,10 @@ ${body2}`:head}function formatProcessNotification(text5){let body2=text5.replace
|
|
|
4207
4207
|
`)&&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(`
|
|
4208
4208
|
`,t2.cursorOffset)>=0)return!1;if(buf2.includes(`
|
|
4209
4209
|
`)&&t2.cursorOffset!==buf2.length)return t2.cursorOffset=buf2.length,!0;return hist.down(),!0}}),[hist.up,hist.down,pop3.setCursor,write]);let sidsRef=import_react156.useRef(sids);sidsRef.current=sids;let taRef=import_react156.useCallback((r)=>{if(ta.current=r,r&&!buf.current)buf.current=new PartsBuffer(r,sidsRef.current);if(!r)buf.current=null},[]),label3=!props.ready?"Connecting...":props.starting?props.status||"Starting agent...":props.streaming?props.status||"Generating...":"Ready",dot=props.ready?props.streaming?theme.warning:theme.success:theme.error,resume=resumeHint(props.subagents,props.streaming),rows3=Math.min(MAX_ROWS,Math.max(1,input.split(`
|
|
4210
|
-
`).length)),all2=props.attachments??[],previews=all2.filter((a)=>a.path&&classify(a.path)==="img").slice(0,MAX_PREVIEWS),chips=all2.filter((a)=>!previews.includes(a)).slice(0,MAX_PREVIEWS),shown=new Set([...previews,...chips]),attRows=all2.length>0?previews.length>0?2:1:0,lift=rows3+attRows+3,more=all2.filter((a)=>!shown.has(a)).length,bits=[props.hidden?.profile,props.hidden?.title,props.hidden?.place,props.hidden?.context].filter(Boolean);return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,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,zIndex:2,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):props.focused&&comp.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:comp.items,cursor:comp.cursor,onCursor:comp.setCursor,onSelect:(idx2)=>{let it=comp.items[idx2];if(it?.text)write(acceptCompletion(input,it,comp.replaceFrom,comp.replaceTo))}})}):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,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode2==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"column",position:"relative",children:[previews.length>0?$jsx("box",{flexDirection:"column",paddingX:1,maxHeight:MAX_PREVIEWS,overflow:"hidden",children:previews.map((a)=>$jsx(ChafaImage,{path:a.path,width:60,bare:!0},`p-${a.path}`))}):null,chips.length>0?$jsxs("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingTop:previews.length>0?0:1,paddingBottom:1,children:[chips.map((a,i)=>{if(a.path){let kind2=classify(a.path);return $jsxs("box",{flexDirection:"row",height:1,children:[$jsx(MediaChip,{path:a.path,bare:kind2==="img"}),kind2!=="img"&&a.token_estimate?$jsxs("text",{fg:theme.textMuted,children:[" ~",fmt5(a.token_estimate),"t"]}):null]},a.path)}return $jsxs("text",{children:[$jsx("span",{bg:theme.secondary,fg:theme.background,children:" file "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`file ${i+1}`," "]})]},a.name??i)}),more>0?$jsxs("text",{fg:theme.textMuted,children:["+",more]}):null]}):null,$jsxs("box",{flexDirection:"row",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode2==="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("@")&&!live.current.input.includes("/"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit4,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode2==="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&&pop3.spot?.whole?$jsx("box",{position:"absolute",top:attRows,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:[props.streaming?$jsx(SpinGlyph,{fg:dot}):$jsx("span",{fg:dot,children:"\u25CF"}),$jsxs("span",{fg:theme.textMuted,children:[" ",mode2==="shell"?"Shell":label3]}),mode2==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.starting&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to cancel"}):props.starting?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 cancel"}):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,resume?$jsxs("text",{fg:theme.textMuted,children:[resume," "]}):null,bits.length>0?$jsxs("text",{fg:theme.textMuted,children:[trunc5(bits.join(" \xB7 "),56)," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react157=__toESM(require_react_production(),1);init_sessions_db();var normalize3=(sid2)=>sid2.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user2=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user2)messages.push(...transcriptToMessages([{role:"user",text:user2}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.resume",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target2);let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react157.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_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.activate",{session_id:target2}),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]),busy2=import_react157.useCallback(async()=>{try{return(await gw.request("agents.list")).processes?.some((p)=>p.status==="running")??!1}catch{return!0}},[gw]),close2=import_react157.useCallback(async(sid2,opts)=>{if(!sid2)return!1;if(opts?.preserveBackground&&await busy2())return!1;try{return await gw.request("session.close",{session_id:sid2}),!0}catch{return!1}},[gw,busy2]),boot2=import_react157.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target2=launch.sid??exports_sessions_db.lastReal()?.id;if(!target2)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target2)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target2} failed: ${msg} \u2014 starting fresh`)}}let last4=get2("lastSessionId"),row4=last4?exports_sessions_db.byId(last4):null;if(row4?.message_count===0&&row4.parent_session_id==null)try{return await resume(row4.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react157.useCallback(async()=>{await gw.request("session.interrupt")},[gw]),branch2=import_react157.useCallback(async(name)=>{return(await gw.request("session.branch",name?{name}:{})).session_id??null},[gw]),compress=import_react157.useCallback(async(arg="")=>{let raw2=arg.trim(),params=raw2?{raw_args:raw2,focus_topic:raw2}:{};return gw.request("session.compress",params)},[gw]),undo=import_react157.useCallback(async()=>{await gw.request("session.undo")},[gw]);return import_react157.useMemo(()=>({boot:boot2,create,resume,activate,close:close2,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close2,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(),close(),exports_preferences.reload(),home3.reset()}var import_react158=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react158.useState(p.seconds);import_react158.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:(sid2)=>{if(!sid2)return;io.goalState(sid2).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid2)===s.goal)return;fired.set(sid2,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_react160=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react160.useState(!1),[recording,setRecording]=import_react160.useState(!1),[processing,setProcessing]=import_react160.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react160.useState(),[tts,setTts]=import_react160.useState(!1),[onTranscript,setTranscript]=import_react160.useState(null),pending3=import_react160.useRef(0),recordGen=import_react160.useRef(0),toggleGen=import_react160.useRef(0),setOnTranscript=import_react160.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),reset4=import_react160.useCallback(()=>{toggleGen.current++,recordGen.current++,pending3.current=0,setEnabled(!1),setRecording(!1),setProcessing(!1),setTts(!1)},[]),recordKey=import_react160.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react160.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state3=import_react160.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react160.useCallback(async(action,sid2)=>{let current2=++toggleGen.current;try{let r=await gw("voice.toggle",{action,session_id:sid2});if(toggleGen.current!==current2)return;if(r.enabled!==void 0){if(setEnabled(r.enabled),!r.enabled)recordGen.current++,setRecording(!1),setProcessing(!1)}if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label3=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"",details2=action==="status"&&r.details?.trim()?` \xB7 ${r.details.trim()}`:"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label3}]${details2}`)}catch(e){if(toggleGen.current!==current2)return;sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react160.useCallback(async(sid2)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}if(pending3.current)return;let current2=++recordGen.current;pending3.current=current2;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:sid2});if(recordGen.current!==current2)return;if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(recordGen.current!==current2)return;setRecording(!starting),sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}finally{if(pending3.current===current2)pending3.current=0}},[enabled3,recording,gw,sys]);return{state:state3,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,reset:reset4,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text5,fg2=theme.text;if(voice.recording)text5="\u25CF recording",fg2=theme.error;else if(voice.processing)text5="\u25CC transcribing",fg2=theme.warning;else text5=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text5," "]})})}function sessionCapabilities(input){let sessionConnected=Boolean(input.sid),metadataHydrated=input.ready;return{sessionConnected,metadataHydrated,canSubmitPrompt:sessionConnected,canDispatchGatewayCommand:sessionConnected,canDrainQueue:sessionConnected&&!input.streaming}}var import_react161=__toESM(require_react_production(),1);function openMessage(dialog,m2,ops){let text5=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");dialog.replace($jsx(DialogSelect,{title:"Message Actions",options:[{title:"Copy",value:"copy",description:"message text to clipboard"},{title:"Rewind here",value:"rewind",description:"undo back to this turn (destructive)"},{title:"Fork here",value:"fork",description:"branch a new session at this point"}],onSelect:(o)=>{if(dialog.clear(),o.value==="copy")return void copyText(text5,ops.toast);if(o.value==="rewind")return ops.rewind(m2);if(o.value==="fork")return ops.fork(m2)}}))}async function undo(gw,count4,sid2){for(let i=0;i<count4;i++)await gw.request("session.undo",sid2?{session_id:sid2}:{})}var textOf=(message2)=>message2.parts.filter((part)=>part.type==="text").map((part)=>part.content).join("");function useMessageActions(args){let turns=import_react161.useCallback((message2)=>{let messages=args.turn.current.messages,at=messages.findIndex((item)=>item.id===message2.id);return at<0?0:messages.slice(at).filter((item)=>item.role==="user").length},[args.turn]),rewind=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return!1;let count4=turns(message2);if(!count4)return!1;try{await undo(args.gw,count4);let result=await args.gw.request("session.history");return args.dispatch({kind:"load",messages:transcriptToMessages(result.messages??[])}),args.composer.current?.set(textOf(message2)),args.focus("input"),!0}catch(err){return args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)}),!1}},[args.gw,args.toast,args.turn,args.dispatch,args.composer,args.focus,turns]),fork2=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return;let result=await args.gw.request("session.branch",{}).catch((err)=>{return args.toast.show({variant:"error",message:`branch failed: ${err.message}`}),null});if(!result?.session_id)return;try{if(await undo(args.gw,turns(message2),result.session_id),!await args.activate(result.session_id)){await args.session.close(result.session_id);return}args.composer.current?.set(textOf(message2)),args.focus("input"),args.toast.show({variant:"success",message:`forked \u2192 ${result.title??result.session_id}`})}catch(err){await args.session.close(result.session_id),args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)})}},[args.gw,args.toast,args.turn,args.activate,args.session,args.composer,args.focus,turns]),menu=import_react161.useCallback((message2)=>{if(args.turn.current.streaming)return;openMessage(args.dialog,message2,{rewind,fork:fork2,toast:args.toast})},[args.dialog,args.toast,args.turn,rewind,fork2]);return{rewind,fork:fork2,menu}}var BUSY_RE=/session busy|waiting for model response/i,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,{plugins:props.plugins,children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),dialogOpen=useDialogOpen(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react163.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react163.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react163.useState(!1),[sid2,setSid]=import_react163.useState(""),sidRef=import_react163.useRef(sid2);sidRef.current=sid2;let[starting,setStarting]=import_react163.useState(!1),startRef=import_react163.useRef(starting);startRef.current=starting;let active=turn.streaming||starting,capabilities=sessionCapabilities({sid:sid2,ready,streaming:active}),[tab,setTab]=import_react163.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react163.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react163.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react163.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react163.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react163.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react163.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react163.useState(!1),[usage,setUsage]=import_react163.useState(void 0),[info3,setInfo]=import_react163.useState(null),[title,setTitle]=import_react163.useState(""),caption=title.trim(),titleRef=import_react163.useRef(caption);titleRef.current=caption,import_react163.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react163.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_react163.useState("input"),goToTab=import_react163.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react163.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status2,setStatus]=import_react163.useState(""),[escHint,setEscHint]=import_react163.useState(!1),[eikon,setEikon]=import_react163.useState(void 0),[queue,setQueue]=import_react163.useState([]),[busy2,setBusy]=import_react163.useState("queue"),turnRef=import_react163.useRef(turn);turnRef.current=turn;let queueRef=import_react163.useRef(queue);queueRef.current=queue;let launchRef=import_react163.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react163.useState(launch.splash!==!1),[switching,setSwitching]=import_react163.useState(!1),summoned=import_react163.useRef(!1),creating=import_react163.useRef(!1),[composing,setComposing]=import_react163.useState(!1),splashLast=import_react163.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react163.useMemo(()=>info3?{agentVersion:info3.version,behind:info3.update_behind,model:info3.model}:void 0,[info3?.version,info3?.update_behind,info3?.model]),splashLastProp=import_react163.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react163.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react163.useState([]),[cloudH,setCloudH]=import_react163.useState(CLOUD_MIN),[pick2,setPick]=import_react163.useState(void 0),[skin2,setSkin]=import_react163.useState(()=>deriveSkin(void 0)),inflight=import_react163.useRef(!1),hold=import_react163.useRef(!1),pending3=import_react163.useRef(!1),[pulse,setPulse]=import_react163.useState(0),start2=import_react163.useCallback(()=>{inflight.current=!1,pending3.current=!1,setPulse((n)=>n+1)},[]),settle=import_react163.useCallback(()=>{if(!hold.current)return;hold.current=!1,setPulse((n)=>n+1)},[]),undone=import_react163.useRef([]),sessionStart=import_react163.useRef(Date.now()),composer2=import_react163.useRef(null),promptRef=import_react163.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react163.useRef(cmds);cmdsRef.current=cmds;let sys=import_react163.useCallback((text5)=>dispatch({kind:"system",text:text5}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react163.useEffect(()=>{voice.setOnTranscript((text5)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text5),0)})},[]);let[errorPulse,setErrorPulse]=import_react163.useState(!1);import_react163.useEffect(()=>{let restart=(mode2="resume")=>{let sid3=sidRef.current;if(mode2==="resume"&&sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus("gateway restarting"),voice.reset()},exit=(code2)=>{let text5=`gateway exited${code2===null?"":` (${code2})`}`,sid3=sidRef.current;if(sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus(text5),setErrorPulse(!0),voice.reset(),dispatch({kind:"system",text:text5})};return gw.on("restart",restart),gw.on("exit",exit),()=>{gw.off("restart",restart),gw.off("exit",exit)}},[gw]);let agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":active?"thinking":composing?"listening":"idle",onAvatarHold=import_react163.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react163.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react163.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react163.useRef(turn.streaming);import_react163.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react163.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react163.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react163.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react163.useRef(()=>{}),steer=import_react163.useCallback((text5)=>{let v2=text5.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_react163.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react163.useCallback((t2)=>{if(busy2==="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(busy2==="interrupt"){hold.current=!0,setQueue((q5)=>[t2,...q5]),intr.current();return}setQueue((q5)=>[...q5,t2])},[busy2,gw,toast]),onAttach=import_react163.useCallback((r)=>setAttachments((a)=>[...a,r]),[]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setStarting,setUsage,setStatus,setSkin,setErrorPulse,settle,onVoiceStatus:(state3)=>{voice.setRecording(state3==="listening"||state3==="recording"),voice.setProcessing(state3==="transcribing"||state3==="processing")},onVoiceTranscript:(text5,noSpeechLimit)=>{if(voice.setRecording(!1),voice.setProcessing(!1),noSpeechLimit){voice.setEnabled(!1),sys("voice: disabled after repeated silence");return}voice.onTranscript?.(text5)},start:start2}),interrupt=import_react163.useCallback(()=>{if(startRef.current&&!turnRef.current.streaming)hold.current=!0;stream.doInterrupt()},[stream.doInterrupt]);intr.current=interrupt;let reset4=import_react163.useCallback(()=>{stream.interrupted.current=!1,hold.current=!1,pending3.current=!1,toast.clear("credits.depleted"),undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStarting(!1),setStatus(""),setTitle(""),setAttachments([])},[toast]),newSession=import_react163.useCallback(async()=>{if(creating.current)return;creating.current=!0,setSwitching(!0);let prev=sidRef.current;summoned.current=!0,setSplash(!0),setReady(!1),gw.setSession("");try{let r=await session.create();if(reset4(),setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);if(setReady(!0),setStarting(!1),setStatus(""),sessionStart.current=Date.now(),prev)session.close(prev,{preserveBackground:!0})}catch(err){if(prev)gw.setSession(prev),setReady(!0);setSplash(!1),summoned.current=!1,dispatch({kind:"system",text:`Failed to create session: ${err instanceof Error?err.message:String(err)}`})}finally{creating.current=!1,setSwitching(!1)}},[reset4,session,gw]),switchSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target2);if(reset4(),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,{preserveBackground:!0});setSplash(!1),summoned.current=!1}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset4,session,goToTab,gw]),liveStatus=(state3,running2=!1)=>{if(state3==="waiting")return"waiting for input\u2026";if(state3==="starting")return"starting agent\u2026";return running2||state3==="working"?"running\u2026":"ready"},activateSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.activate(target2);if(reset4(),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"});return!0}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);return dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1,!1}finally{setSwitching(!1)}},[reset4,session,goToTab,toast,gw]),switchProfile=import_react163.useCallback((newHome,name)=>{voice.reset(),rehome(newHome),reset4(),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("new")},[reset4,goToTab,gwRestart,toast,gw]),loadEikon=import_react163.useCallback((path4)=>{try{setEikon(parseEikonFile(path4))}catch{setEikon(void 0)}},[]),eikonName=usePref("eikon"),eikonRev=import_react163.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react163.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin2.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin2.skin?.name,loadEikon]);let messageActions=useMessageActions({gw,dialog,toast,session,activate:activateSession,composer:composer2,turn:turnRef,dispatch,focus:setFocusRegion}),rewind=messageActions.rewind,msgMenu=messageActions.menu,attachClipboard=import_react163.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_react163.useRef(()=>{}),slash3=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,capabilities,info:info3,sid:sid2,title:caption,skin:skin2,setQueue,setFocusRegion,setSplash,setAttachments,setInfo,setUsage,setTitle,newSession,switchSession,activateSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react163.useCallback(async(raw2)=>{if(creating.current)return;if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sidRef.current,titleRef.current,gw);let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve9(cmdsRef.current,name);if("hit"in r)return slash3(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 text5=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text5=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let withMedia=attachments.length?[...attachments.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text5].filter(Boolean).join(`
|
|
4211
|
-
`):text5;if(pending3.current){setQueue((q5)=>[...q5,raw2]),setStatus("queued for next turn");return}pending3.current=!0,setPulse((n)=>n+1),gw.request("prompt.submit",{text:text5}).then((r)=>{if(dispatch({kind:"user",text:withMedia}),r.status==="streaming"&&!turnRef.current.streaming)setStarting(!0),setStatus("starting agent\u2026");
|
|
4210
|
+
`).length)),all2=props.attachments??[],previews=all2.filter((a)=>a.path&&classify(a.path)==="img").slice(0,MAX_PREVIEWS),chips=all2.filter((a)=>!previews.includes(a)).slice(0,MAX_PREVIEWS),shown=new Set([...previews,...chips]),attRows=all2.length>0?previews.length>0?2:1:0,lift=rows3+attRows+3,more=all2.filter((a)=>!shown.has(a)).length,bits=[props.hidden?.profile,props.hidden?.title,props.hidden?.place,props.hidden?.context].filter(Boolean);return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,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,zIndex:2,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):props.focused&&comp.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:comp.items,cursor:comp.cursor,onCursor:comp.setCursor,onSelect:(idx2)=>{let it=comp.items[idx2];if(it?.text)write(acceptCompletion(input,it,comp.replaceFrom,comp.replaceTo))}})}):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,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode2==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"column",position:"relative",children:[previews.length>0?$jsx("box",{flexDirection:"column",paddingX:1,maxHeight:MAX_PREVIEWS,overflow:"hidden",children:previews.map((a)=>$jsx(ChafaImage,{path:a.path,width:60,bare:!0},`p-${a.path}`))}):null,chips.length>0?$jsxs("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingTop:previews.length>0?0:1,paddingBottom:1,children:[chips.map((a,i)=>{if(a.path){let kind2=classify(a.path);return $jsxs("box",{flexDirection:"row",height:1,children:[$jsx(MediaChip,{path:a.path,bare:kind2==="img"}),kind2!=="img"&&a.token_estimate?$jsxs("text",{fg:theme.textMuted,children:[" ~",fmt5(a.token_estimate),"t"]}):null]},a.path)}return $jsxs("text",{children:[$jsx("span",{bg:theme.secondary,fg:theme.background,children:" file "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`file ${i+1}`," "]})]},a.name??i)}),more>0?$jsxs("text",{fg:theme.textMuted,children:["+",more]}):null]}):null,$jsxs("box",{flexDirection:"row",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode2==="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("@")&&!live.current.input.includes("/"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit4,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode2==="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&&pop3.spot?.whole?$jsx("box",{position:"absolute",top:attRows,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:[props.streaming?$jsx(SpinGlyph,{fg:dot}):$jsx("span",{fg:dot,children:"\u25CF"}),$jsxs("span",{fg:theme.textMuted,children:[" ",mode2==="shell"?"Shell":label3]}),mode2==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.starting&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to cancel"}):props.starting?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 cancel"}):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,resume?$jsxs("text",{fg:theme.textMuted,children:[resume," "]}):null,bits.length>0?$jsxs("text",{fg:theme.textMuted,children:[trunc5(bits.join(" \xB7 "),56)," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react157=__toESM(require_react_production(),1);init_sessions_db();var normalize3=(sid2)=>sid2.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user2=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user2)messages.push(...transcriptToMessages([{role:"user",text:user2}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.resume",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target2);let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react157.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_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.activate",{session_id:target2}),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]),busy2=import_react157.useCallback(async()=>{try{return(await gw.request("agents.list")).processes?.some((p)=>p.status==="running")??!1}catch{return!0}},[gw]),close2=import_react157.useCallback(async(sid2,opts)=>{if(!sid2)return!1;if(opts?.preserveBackground&&await busy2())return!1;try{return await gw.request("session.close",{session_id:sid2}),!0}catch{return!1}},[gw,busy2]),boot2=import_react157.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target2=launch.sid??exports_sessions_db.lastReal()?.id;if(!target2)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target2)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target2} failed: ${msg} \u2014 starting fresh`)}}let last4=get2("lastSessionId"),row4=last4?exports_sessions_db.byId(last4):null;if(row4?.message_count===0&&row4.parent_session_id==null)try{return await resume(row4.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react157.useCallback(async()=>{await gw.request("session.interrupt")},[gw]),branch2=import_react157.useCallback(async(name)=>{return(await gw.request("session.branch",name?{name}:{})).session_id??null},[gw]),compress=import_react157.useCallback(async(arg="")=>{let raw2=arg.trim(),params=raw2?{raw_args:raw2,focus_topic:raw2}:{};return gw.request("session.compress",params)},[gw]),undo=import_react157.useCallback(async()=>{await gw.request("session.undo")},[gw]);return import_react157.useMemo(()=>({boot:boot2,create,resume,activate,close:close2,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close2,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(),close(),exports_preferences.reload(),home3.reset()}var import_react158=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react158.useState(p.seconds);import_react158.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:(sid2)=>{if(!sid2)return;io.goalState(sid2).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid2)===s.goal)return;fired.set(sid2,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_react160=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react160.useState(!1),[recording,setRecording]=import_react160.useState(!1),[processing,setProcessing]=import_react160.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react160.useState(),[tts,setTts]=import_react160.useState(!1),[onTranscript,setTranscript]=import_react160.useState(null),pending3=import_react160.useRef(0),recordGen=import_react160.useRef(0),toggleGen=import_react160.useRef(0),setOnTranscript=import_react160.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),reset4=import_react160.useCallback(()=>{toggleGen.current++,recordGen.current++,pending3.current=0,setEnabled(!1),setRecording(!1),setProcessing(!1),setTts(!1)},[]),recordKey=import_react160.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react160.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state3=import_react160.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react160.useCallback(async(action,sid2)=>{let current2=++toggleGen.current;try{let r=await gw("voice.toggle",{action,session_id:sid2});if(toggleGen.current!==current2)return;if(r.enabled!==void 0){if(setEnabled(r.enabled),!r.enabled)recordGen.current++,setRecording(!1),setProcessing(!1)}if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label3=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"",details2=action==="status"&&r.details?.trim()?` \xB7 ${r.details.trim()}`:"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label3}]${details2}`)}catch(e){if(toggleGen.current!==current2)return;sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react160.useCallback(async(sid2)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}if(pending3.current)return;let current2=++recordGen.current;pending3.current=current2;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:sid2});if(recordGen.current!==current2)return;if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(recordGen.current!==current2)return;setRecording(!starting),sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}finally{if(pending3.current===current2)pending3.current=0}},[enabled3,recording,gw,sys]);return{state:state3,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,reset:reset4,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text5,fg2=theme.text;if(voice.recording)text5="\u25CF recording",fg2=theme.error;else if(voice.processing)text5="\u25CC transcribing",fg2=theme.warning;else text5=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text5," "]})})}function sessionCapabilities(input){let sessionConnected=Boolean(input.sid),metadataHydrated=input.ready;return{sessionConnected,metadataHydrated,canSubmitPrompt:sessionConnected,canDispatchGatewayCommand:sessionConnected,canDrainQueue:sessionConnected&&!input.streaming}}var import_react161=__toESM(require_react_production(),1);function openMessage(dialog,m2,ops){let text5=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");dialog.replace($jsx(DialogSelect,{title:"Message Actions",options:[{title:"Copy",value:"copy",description:"message text to clipboard"},{title:"Rewind here",value:"rewind",description:"undo back to this turn (destructive)"},{title:"Fork here",value:"fork",description:"branch a new session at this point"}],onSelect:(o)=>{if(dialog.clear(),o.value==="copy")return void copyText(text5,ops.toast);if(o.value==="rewind")return ops.rewind(m2);if(o.value==="fork")return ops.fork(m2)}}))}async function undo(gw,count4,sid2){for(let i=0;i<count4;i++)await gw.request("session.undo",sid2?{session_id:sid2}:{})}var textOf=(message2)=>message2.parts.filter((part)=>part.type==="text").map((part)=>part.content).join("");function useMessageActions(args){let turns=import_react161.useCallback((message2)=>{let messages=args.turn.current.messages,at=messages.findIndex((item)=>item.id===message2.id);return at<0?0:messages.slice(at).filter((item)=>item.role==="user").length},[args.turn]),rewind=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return!1;let count4=turns(message2);if(!count4)return!1;try{await undo(args.gw,count4);let result=await args.gw.request("session.history");return args.dispatch({kind:"load",messages:transcriptToMessages(result.messages??[])}),args.composer.current?.set(textOf(message2)),args.focus("input"),!0}catch(err){return args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)}),!1}},[args.gw,args.toast,args.turn,args.dispatch,args.composer,args.focus,turns]),fork2=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return;let result=await args.gw.request("session.branch",{}).catch((err)=>{return args.toast.show({variant:"error",message:`branch failed: ${err.message}`}),null});if(!result?.session_id)return;try{if(await undo(args.gw,turns(message2),result.session_id),!await args.activate(result.session_id)){await args.session.close(result.session_id);return}args.composer.current?.set(textOf(message2)),args.focus("input"),args.toast.show({variant:"success",message:`forked \u2192 ${result.title??result.session_id}`})}catch(err){await args.session.close(result.session_id),args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)})}},[args.gw,args.toast,args.turn,args.activate,args.session,args.composer,args.focus,turns]),menu=import_react161.useCallback((message2)=>{if(args.turn.current.streaming)return;openMessage(args.dialog,message2,{rewind,fork:fork2,toast:args.toast})},[args.dialog,args.toast,args.turn,rewind,fork2]);return{rewind,fork:fork2,menu}}var BUSY_RE=/session busy|waiting for model response/i,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,{plugins:props.plugins,children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),dialogOpen=useDialogOpen(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react163.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react163.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react163.useState(!1),[sid2,setSid]=import_react163.useState(""),sidRef=import_react163.useRef(sid2);sidRef.current=sid2;let[starting,setStarting]=import_react163.useState(!1),startRef=import_react163.useRef(starting);startRef.current=starting;let active=turn.streaming||starting,capabilities=sessionCapabilities({sid:sid2,ready,streaming:active}),[tab,setTab]=import_react163.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react163.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react163.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react163.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react163.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react163.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react163.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react163.useState(!1),[usage,setUsage]=import_react163.useState(void 0),[info3,setInfo]=import_react163.useState(null),[title,setTitle]=import_react163.useState(""),caption=title.trim(),titleRef=import_react163.useRef(caption);titleRef.current=caption,import_react163.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react163.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_react163.useState("input"),goToTab=import_react163.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react163.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status2,setStatus]=import_react163.useState(""),[escHint,setEscHint]=import_react163.useState(!1),[eikon,setEikon]=import_react163.useState(void 0),[queue,setQueue]=import_react163.useState([]),[busy2,setBusy]=import_react163.useState("queue"),turnRef=import_react163.useRef(turn);turnRef.current=turn;let queueRef=import_react163.useRef(queue);queueRef.current=queue;let launchRef=import_react163.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react163.useState(launch.splash!==!1),[switching,setSwitching]=import_react163.useState(!1),summoned=import_react163.useRef(!1),creating=import_react163.useRef(!1),[composing,setComposing]=import_react163.useState(!1),splashLast=import_react163.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react163.useMemo(()=>info3?{agentVersion:info3.version,behind:info3.update_behind,model:info3.model}:void 0,[info3?.version,info3?.update_behind,info3?.model]),splashLastProp=import_react163.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react163.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react163.useState([]),attachmentsRef=import_react163.useRef(attachments);attachmentsRef.current=attachments;let[cloudH,setCloudH]=import_react163.useState(CLOUD_MIN),[pick2,setPick]=import_react163.useState(void 0),[skin2,setSkin]=import_react163.useState(()=>deriveSkin(void 0)),inflight=import_react163.useRef(!1),hold=import_react163.useRef(!1),pending3=import_react163.useRef(!1),detaching=import_react163.useRef(0),[pulse,setPulse]=import_react163.useState(0),start2=import_react163.useCallback(()=>{inflight.current=!1,pending3.current=!1,setPulse((n)=>n+1)},[]),settle=import_react163.useCallback(()=>{if(!hold.current)return;hold.current=!1,setPulse((n)=>n+1)},[]),undone=import_react163.useRef([]),sessionStart=import_react163.useRef(Date.now()),composer2=import_react163.useRef(null),promptRef=import_react163.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react163.useRef(cmds);cmdsRef.current=cmds;let sys=import_react163.useCallback((text5)=>dispatch({kind:"system",text:text5}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react163.useEffect(()=>{voice.setOnTranscript((text5)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text5),0)})},[]);let[errorPulse,setErrorPulse]=import_react163.useState(!1);import_react163.useEffect(()=>{let restart=(mode2="resume")=>{let sid3=sidRef.current;if(mode2==="resume"&&sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus("gateway restarting"),voice.reset()},exit=(code2)=>{let text5=`gateway exited${code2===null?"":` (${code2})`}`,sid3=sidRef.current;if(sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus(text5),setErrorPulse(!0),voice.reset(),dispatch({kind:"system",text:text5})};return gw.on("restart",restart),gw.on("exit",exit),()=>{gw.off("restart",restart),gw.off("exit",exit)}},[gw]);let agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":active?"thinking":composing?"listening":"idle",onAvatarHold=import_react163.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react163.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react163.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react163.useRef(turn.streaming);import_react163.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react163.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react163.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react163.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react163.useRef(()=>{}),steer=import_react163.useCallback((text5)=>{let v2=text5.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_react163.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react163.useCallback((t2)=>{if(busy2==="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(busy2==="interrupt"){hold.current=!0,setQueue((q5)=>[t2,...q5]),intr.current();return}setQueue((q5)=>[...q5,t2])},[busy2,gw,toast]),updateAttachments=import_react163.useCallback((next2)=>{let value2=typeof next2==="function"?next2(attachmentsRef.current):next2;attachmentsRef.current=value2,setAttachments(value2)},[]),onAttach=import_react163.useCallback((r)=>updateAttachments((a)=>[...a,r]),[updateAttachments]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setStarting,setUsage,setStatus,setSkin,setErrorPulse,settle,onVoiceStatus:(state3)=>{voice.setRecording(state3==="listening"||state3==="recording"),voice.setProcessing(state3==="transcribing"||state3==="processing")},onVoiceTranscript:(text5,noSpeechLimit)=>{if(voice.setRecording(!1),voice.setProcessing(!1),noSpeechLimit){voice.setEnabled(!1),sys("voice: disabled after repeated silence");return}voice.onTranscript?.(text5)},start:start2}),interrupt=import_react163.useCallback(()=>{if(startRef.current&&!turnRef.current.streaming)hold.current=!0;stream.doInterrupt()},[stream.doInterrupt]);intr.current=interrupt;let reset4=import_react163.useCallback(()=>{stream.interrupted.current=!1,hold.current=!1,pending3.current=!1,toast.clear("credits.depleted"),undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStarting(!1),setStatus(""),setTitle(""),updateAttachments([])},[toast,updateAttachments]),newSession=import_react163.useCallback(async()=>{if(creating.current)return;creating.current=!0,setSwitching(!0);let prev=sidRef.current;summoned.current=!0,setSplash(!0),setReady(!1),gw.setSession("");try{let r=await session.create();if(reset4(),setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);if(setReady(!0),setStarting(!1),setStatus(""),sessionStart.current=Date.now(),prev)session.close(prev,{preserveBackground:!0})}catch(err){if(prev)gw.setSession(prev),setReady(!0);setSplash(!1),summoned.current=!1,dispatch({kind:"system",text:`Failed to create session: ${err instanceof Error?err.message:String(err)}`})}finally{creating.current=!1,setSwitching(!1)}},[reset4,session,gw]),switchSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target2);if(reset4(),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,{preserveBackground:!0});setSplash(!1),summoned.current=!1}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset4,session,goToTab,gw]),liveStatus=(state3,running2=!1)=>{if(state3==="waiting")return"waiting for input\u2026";if(state3==="starting")return"starting agent\u2026";return running2||state3==="working"?"running\u2026":"ready"},activateSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.activate(target2);if(reset4(),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"});return!0}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);return dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1,!1}finally{setSwitching(!1)}},[reset4,session,goToTab,toast,gw]),switchProfile=import_react163.useCallback((newHome,name)=>{voice.reset(),rehome(newHome),reset4(),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("new")},[reset4,goToTab,gwRestart,toast,gw]),loadEikon=import_react163.useCallback((path4)=>{try{setEikon(parseEikonFile(path4))}catch{setEikon(void 0)}},[]),eikonName=usePref("eikon"),eikonRev=import_react163.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react163.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin2.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin2.skin?.name,loadEikon]);let messageActions=useMessageActions({gw,dialog,toast,session,activate:activateSession,composer:composer2,turn:turnRef,dispatch,focus:setFocusRegion}),rewind=messageActions.rewind,msgMenu=messageActions.menu,attachClipboard=import_react163.useCallback(()=>{gw.request("clipboard.paste").then((r)=>r.attached?updateAttachments((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,updateAttachments]),sendRef=import_react163.useRef(()=>{}),slash3=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,capabilities,info:info3,sid:sid2,title:caption,skin:skin2,setQueue,setFocusRegion,setSplash,setAttachments:updateAttachments,setInfo,setUsage,setTitle,newSession,switchSession,activateSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react163.useCallback(async(raw2)=>{if(creating.current)return;if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sidRef.current,titleRef.current,gw);if(detaching.current>0){if(raw2.trim())composer2.current?.set(raw2);setStatus("detaching image\u2026");return}let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve9(cmdsRef.current,name);if("hit"in r)return slash3(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 text5=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text5=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let att=attachmentsRef.current,withMedia=att.length?[...att.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text5].filter(Boolean).join(`
|
|
4211
|
+
`):text5;if(pending3.current){setQueue((q5)=>[...q5,raw2]),setStatus("queued for next turn");return}pending3.current=!0,setPulse((n)=>n+1),gw.request("prompt.submit",{text:text5}).then((r)=>{if(dispatch({kind:"user",text:withMedia}),r.status==="streaming"&&!turnRef.current.streaming)setStarting(!0),setStatus("starting agent\u2026");updateAttachments([]),undone.current=[],setTab(CHAT_TAB)}).catch((e)=>{let msg=e instanceof Error?e.message:String(e);if(BUSY_RE.test(msg)){pending3.current=!1,setPulse((n)=>n+1),inflight.current=!0,setQueue((q5)=>[text5,...q5]),setStatus("queued for next turn"),toast.show({variant:"info",message:"queued for next turn"}),setTimeout(()=>{inflight.current=!1,setPulse((n)=>n+1)},400);return}pending3.current=!1,setPulse((n)=>n+1),inflight.current=!1,setStarting(!1),dispatch({kind:"system",text:`submit failed: ${msg}`}),toast.show({variant:"error",message:msg})})},[gw,slash3,toast,updateAttachments]);sendRef.current=send;let onShell=import_react163.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:
|
|
4212
4212
|
${err}`].filter(Boolean).join(`
|
|
4213
|
-
`);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_react163.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react163.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react163.useEffect(()=>{if(turn.streaming)start2()},[turn.streaming,start2]),import_react163.useEffect(()=>{if(!capabilities.canDrainQueue||inflight.current||hold.current||pending3.current||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[capabilities.canDrainQueue,queue,send,pulse]);let dequeue=import_react163.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_react163.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),routeName=import_react163.useRef(void 0),routesRef=import_react163.useRef(extra),tabMax=all2.length-1;import_react163.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]),import_react163.useEffect(()=>{let changed2=routesRef.current!==extra;if(routesRef.current=extra,changed2&&tab>=TABS.length){let next2=extra.findIndex((route2)=>route2.name===routeName.current);if(next2<0){goToTab(CHAT_TAB);return}let index4=TABS.length+next2;if(index4!==tab){goToTab(index4);return}}routeName.current=all2[tab]?.name},[extra,all2,tab,goToTab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react163.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,starting,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:interrupt,queued:queue.length,onFlushQueue:()=>{hold.current=!0,interrupt()},onQuit:()=>quit(renderer,sid2,caption,gw),onQuitArm:(label3)=>toast.show({variant:"info",message:`${label3} again to quit`}),onInterruptNotice:()=>{setEscHint(!0),setTimeout(()=>setEscHint(!1),5000)},onCopyLast:()=>{let m2=[...turnRef.current.messages].reverse().find((x2)=>x2.role==="assistant"&&text2(x2));if(m2)copyText(text2(m2),toast)},onCopyToast:toast.show,onAttachClipboard:attachClipboard,onDetachLast:()=>{if(
|
|
4213
|
+
`);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_react163.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react163.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react163.useEffect(()=>{if(turn.streaming)start2()},[turn.streaming,start2]),import_react163.useEffect(()=>{if(!capabilities.canDrainQueue||inflight.current||hold.current||pending3.current||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[capabilities.canDrainQueue,queue,send,pulse]);let dequeue=import_react163.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_react163.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),routeName=import_react163.useRef(void 0),routesRef=import_react163.useRef(extra),tabMax=all2.length-1;import_react163.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]),import_react163.useEffect(()=>{let changed2=routesRef.current!==extra;if(routesRef.current=extra,changed2&&tab>=TABS.length){let next2=extra.findIndex((route2)=>route2.name===routeName.current);if(next2<0){goToTab(CHAT_TAB);return}let index4=TABS.length+next2;if(index4!==tab){goToTab(index4);return}}routeName.current=all2[tab]?.name},[extra,all2,tab,goToTab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react163.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,starting,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:interrupt,queued:queue.length,onFlushQueue:()=>{hold.current=!0,interrupt()},onQuit:()=>quit(renderer,sid2,caption,gw),onQuitArm:(label3)=>toast.show({variant:"info",message:`${label3} again to quit`}),onInterruptNotice:()=>{setEscHint(!0),setTimeout(()=>setEscHint(!1),5000)},onCopyLast:()=>{let m2=[...turnRef.current.messages].reverse().find((x2)=>x2.role==="assistant"&&text2(x2));if(m2)copyText(text2(m2),toast)},onCopyToast:toast.show,onAttachClipboard:attachClipboard,onDetachLast:()=>{if(detaching.current>0)return setStatus("detaching image\u2026"),!0;let target2=attachmentsRef.current.at(-1);if(!target2?.path)return!1;return detaching.current+=1,setStatus("detaching image\u2026"),setPulse((n)=>n+1),gw.request("image.detach",{path:target2.path}).then(()=>updateAttachments((a)=>a.filter((x2)=>x2.path!==target2.path))).catch((e)=>toast.show({variant:"error",message:e.message})).finally(()=>{detaching.current=Math.max(0,detaching.current-1),setStatus(""),setPulse((n)=>n+1)}),!0},onNotice:(text5)=>dispatch({kind:"system",text:text5}),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:active,messages:turn.messages,sid:sid2,focusRegion,setTab,setFocusRegion,dispatch,composer:composer2});let contentFocused=focusRegion==="content"&&!active&&!dialogOpen,promptAnswer=import_react163.useCallback((id,label3,ok)=>dispatch({kind:"prompt.answered",id,label:label3,ok}),[]),promptWire=import_react163.useMemo(()=>({ref:promptRef,onAnswer:promptAnswer}),[promptAnswer]);import_react163.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:sid2,messages:turn.messages,sessionStart:sessionStart.current,info:info3??void 0,usage});case AUTOMATION_TAB:return $jsx(Automation,{focused:contentFocused,sub:subTabs[AUTOMATION_TAB]??0,setSub:autoSub,sessionId:sid2,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({focused:contentFocused}):null}}})(),name=all2[tab]?.name??"unknown";return $jsx(import_react163.Profiler,{id:`tab:${name}`,onRender,children:inner})},theme=themeCtx.theme,onMouseUp=import_react163.useCallback(()=>copySelection(renderer,toast),[renderer,toast]),inputFocused=focusRegion==="input"&&!prompt&&!dialogOpen,sidebarVisible=dims.width>=(tab===CHAT_TAB?120:140)&&!hideSidebar,branch2=useGitBranch(info3?.cwd),hidden3=!sidebarVisible?hidden2({info:info3,usage,profile:activeProfileName(),title:caption,branch:branch2}):void 0;return $jsx(import_react163.Profiler,{id:"shell",onRender,children:$jsx(SkinProvider,{value:skin2,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||!info3}):null]}),$jsxs("box",{flexShrink:0,zIndex:1,children:[$jsx(VoiceIndicator,{voice:voice.state,keyLabel:voice.keyLabel}),$jsx(Composer,{ref:composer2,focused:inputFocused,canSubmitPrompt:capabilities.canSubmitPrompt&&detaching.current===0,ready,streaming:active||pending3.current,starting,status:status2,model:info3?.model,subagents:usage?.active_subagents??info3?.usage?.active_subagents,hidden:hidden3,escHint,queue,attachments,cmds,onSend,onSlash:slash3,onShell,onAttach,onAttachClipboard:attachClipboard,onEnqueue,onDequeue:dequeue,onDirty:setComposing,onEmptyEnter})]})]}),sidebarVisible?$jsx(import_react163.Profiler,{id:"sidebar",onRender,children:$jsx(Sidebar,{agentState,info:info3,usage,eikon,profile:activeProfileName(),title:caption,cloud:tab===0&&cloud,pulse:active,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:sid2,tab,streaming:active})}):null]})})})};var EIKON_CLI_USAGE=`herm eikon \u2014 install and manage Herm avatars
|
|
4214
4214
|
|
|
4215
4215
|
Usage:
|
|
4216
4216
|
herm eikon search [query] [--json]
|