herm-tui 1.9.0-dev.8 → 1.9.0-dev.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +1 -1
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -4173,7 +4173,7 @@ ${r.skipped.slice(0,8).join(", ")}${r.skipped.length>8?", \u2026":""}`:""}`,yes:
4173
4173
  `).filter(Boolean).map((l)=>JSON.parse(l)).slice(-MAX)}function save3(list3){mkdirSync5(configDir(),{recursive:!0}),writeFileSync5(file2(),list3.map((e)=>JSON.stringify(e)).join(`
4174
4174
  `)+`
4175
4175
  `,"utf-8")}function push2(text3){let list3=load5(),at=Math.max(Date.now(),(list3[list3.length-1]?.at??0)+1);if(list3.push({text:text3,at}),list3.length>MAX)list3.shift();return save3(list3),list3.length}function pop2(){let list3=load5(),e=list3.pop();if(!e)return null;return save3(list3),e}function all(){return load5().reverse()}function drop(at){save3(load5().filter((e)=>e.at!==at))}var import_react125=__toESM(require_react_production(),1);var ctx=import_react125.createContext(null),BackgroundProvider=({children:children2})=>{let[set2,setSet]=import_react125.useState(()=>new Set),register2=import_react125.useCallback((id)=>{if(!id)return;setSet((prev)=>prev.has(id)?prev:new Set(prev).add(id))},[]),unregister=import_react125.useCallback((id)=>{setSet((prev)=>{if(!prev.has(id))return prev;let next2=new Set(prev);return next2.delete(id),next2})},[]),ids=import_react125.useMemo(()=>Array.from(set2),[set2]),value=import_react125.useMemo(()=>({count:ids.length,ids,register:register2,unregister}),[ids,register2,unregister]);return $jsx(ctx.Provider,{value,children:children2})},useBackground=makeUse(ctx,"useBackground");var initialTurn={messages:[],streaming:!1,hasContent:!1,toolActive:!1};function turnReducer(state2,a){switch(a.kind){case"reset":return initialTurn;case"load":return{...initialTurn,messages:a.messages};case"load.live":return{...initialTurn,messages:a.messages,streaming:a.streaming,hasContent:a.streaming&&Boolean(joinText(a.messages.at(-1)?.parts??[]))};case"push":return{...state2,messages:[...state2.messages,a.message]};case"user":return{...state2,messages:[...state2.messages,userMessage(a.text)]};case"system":return{...state2,messages:[...state2.messages,systemMessage(sanitize(a.text))]};case"message.start":return{...state2,streaming:!0,hasContent:!1,toolActive:!1};case"message.delta":{let chunk2=sanitize(a.chunk);if(!chunk2)return state2;return{...state2,hasContent:!0,toolActive:!1,messages:appendText(state2.messages,chunk2)}}case"message.complete":return{...state2,streaming:!1,hasContent:!1,toolActive:!1,messages:finalize(state2.messages,a.text!=null?sanitize(a.text):void 0,a.usage)};case"tool.start":{let preview3=sanitize(a.preview),args=sanitize(a.args),raw2=args||preview3,json=raw2&&/^\s*\{/.test(raw2),part={type:"tool",id:a.id,name:a.name,args:json?raw2:"",status:"running",startedAt:Date.now(),preview:preview3||void 0,verboseArgs:args||void 0};return{...state2,toolActive:!0,hasContent:!1,messages:appendPart(state2.messages,part,!0)}}case"tool.progress":return{...state2,messages:updateRunningTool(state2.messages,a.name,(p)=>({...p,preview:sanitize(a.preview)||p.preview}))};case"tool.generating":return{...state2,messages:updateRunningTool(state2.messages,a.name,(p)=>({...p,preview:p.preview??"generating\u2026"}))};case"tool.complete":{let summary2=sanitize(a.summary),error=sanitize(a.error),diff=sanitize(a.inline_diff),result=sanitize(a.result);return{...state2,toolActive:!1,messages:updateToolById(state2.messages,a.id,(p)=>({...p,status:a.error?"error":"done",duration:a.duration??(p.startedAt?Date.now()-p.startedAt:void 0),preview:summary2||diff||p.preview,result:error||summary2||void 0,verboseResult:result||void 0,diff:diff||void 0}))}}case"thinking":return{...state2,messages:upsertThinking(state2.messages,sanitize(a.text),a.final,a.verbose)};case"subagent":return{...state2,messages:renderSubagent(state2.messages,a.event,a.payload)};case"prompt":{let part={type:"prompt",id:a.id,variant:a.req.variant,req:a.req};return{...state2,messages:appendPart(state2.messages,part,!0)}}case"prompt.answered":return{...state2,messages:updatePrompt(state2.messages,a.id,(p)=>({...p,answered:{label:a.label,ok:a.ok,at:Date.now()}}))};case"error":{let msg=systemMessage(`Error: ${sanitize(a.text)}`);if(a.fatal===!1)return{...state2,messages:[...state2.messages,msg]};return{...state2,streaming:!1,hasContent:!1,toolActive:!1,messages:[...state2.messages,msg]}}case"interrupt.notice":{let clean2=sanitize(a.text),last3=state2.messages[state2.messages.length-1];if(last3?.role==="system"&&last3.parts[0]?.type==="text"&&last3.parts[0].content.includes(clean2))return state2;return{...state2,messages:[...state2.messages,systemMessage(clean2)]}}}}function userMessage(text3){return{id:mid(),role:"user",parts:[{type:"text",content:text3,streaming:!1}],timestamp:Date.now()/1000}}function systemMessage(text3){return{id:mid(),role:"system",parts:[{type:"text",content:text3,streaming:!1}],timestamp:Date.now()/1000}}function flatten3(text3){if(typeof text3==="string")return text3;if(!Array.isArray(text3))return"";let out=[];for(let p of text3)if(p&&typeof p==="object"&&"type"in p&&p.type==="text"&&"text"in p&&typeof p.text==="string")out.push(p.text);return out.join(`
4176
- `)}function transcriptToMessages(rows3){return rows3.filter((r)=>r.role==="user"||r.role==="assistant").map((r)=>({role:r.role,content:sanitize(flatten3(r.text))})).filter((r)=>r.content).map((r)=>({id:mid(),role:r.role,parts:[{type:"text",content:r.content,streaming:!1}],timestamp:Date.now()/1000}))}function assistant(parts2){return{id:mid(),role:"assistant",parts:parts2,timestamp:Date.now()/1000}}function withLastAssistant(messages,fn,otherwise){let last3=messages[messages.length-1];if(last3?.role==="assistant")return[...messages.slice(0,-1),fn(last3)];return[...messages,otherwise()]}function seal(parts2){let last3=parts2[parts2.length-1];if(last3?.type==="text"&&last3.streaming)return[...parts2.slice(0,-1),{...last3,streaming:!1}];return parts2}function appendText(messages,chunk2){return withLastAssistant(messages,(m2)=>{let last3=m2.parts[m2.parts.length-1];if(last3?.type==="text"&&last3.streaming){let part={...last3,content:last3.content+chunk2};return{...m2,parts:[...m2.parts.slice(0,-1),part]}}return{...m2,parts:[...m2.parts,{type:"text",key:pid(),content:chunk2,streaming:!0}]}},()=>assistant([{type:"text",key:pid(),content:chunk2,streaming:!0}]))}function appendPart(messages,part,close){return withLastAssistant(messages,(m2)=>({...m2,parts:[...close?seal(m2.parts):m2.parts,part]}),()=>assistant([part]))}function finalize(messages,final,usage){let last3=messages[messages.length-1];if(last3?.role==="assistant"){let tail=last3.parts[last3.parts.length-1],dup=final&&last3.parts.some((p)=>p.type==="text"&&sameText(p.content,final)),text3=tail?.type==="text"&&final&&sameText(tail.content,final)?tail.content:final,parts2=tail?.type==="text"&&tail.streaming?[...last3.parts.slice(0,-1),{...tail,content:text3||tail.content,streaming:!1}]:final&&!dup&&!sameText(joinText(last3.parts),final)?[...last3.parts,{type:"text",content:final,streaming:!1}]:seal(last3.parts);return[...messages.slice(0,-1),{...last3,parts:parts2,usage}]}if(!final)return messages;return[...messages,{...assistant([{type:"text",content:final,streaming:!1}]),usage}]}function joinText(parts2){return parts2.filter((p)=>p.type==="text").map((p)=>p.content).join("")}function sameText(a,b2){return a.trim()===b2.trim()}function updateRunningTool(messages,name,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;for(let i=last3.parts.length-1;i>=0;i--){let p=last3.parts[i];if(p.type!=="tool"||p.status!=="running")continue;if(name&&p.name!==name)continue;let parts2=[...last3.parts];return parts2[i]=fn(p),[...messages.slice(0,-1),{...last3,parts:parts2}]}return messages}function updateToolById(messages,id,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;let parts2=last3.parts.map((p)=>p.type==="tool"&&p.id===id?fn(p):p);return[...messages.slice(0,-1),{...last3,parts:parts2}]}function updatePrompt(messages,id,fn){return messages.map((m2)=>{if(m2.role!=="assistant")return m2;if(!m2.parts.some((p)=>p.type==="prompt"&&p.id===id))return m2;return{...m2,parts:m2.parts.map((p)=>p.type==="prompt"&&p.id===id?fn(p):p)}})}function upsertThinking(messages,text3,final,verbose2){return withLastAssistant(messages,(m2)=>{let idx=m2.parts.findIndex((p)=>p.type==="thinking");if(idx>=0){let prev=m2.parts[idx],content=final?prev.content.trim()||text3:prev.content+text3,parts2=[...m2.parts];return parts2[idx]={...prev,content,streaming:!final,verbose:prev.verbose||verbose2||void 0},{...m2,parts:parts2}}return{...m2,parts:[{type:"thinking",key:pid(),content:text3,streaming:!final,verbose:verbose2},...m2.parts]}},()=>assistant([{type:"thinking",key:pid(),content:text3,streaming:!final,verbose:verbose2}]))}function renderSubagent(messages,event,p){let id=p.subagent_id?`sub-${p.subagent_id}`:`sub-${p.task_index}`;if(event==="start"){let goal=sanitize(p.goal),part={type:"tool",id,name:"delegate_task",args:"",status:"running",startedAt:Date.now(),preview:goal||void 0,goal:goal||void 0,depth:p.depth??0,trail:[]};return appendPart(messages,part,!0)}if(event==="tool"&&p.tool_name){let tname=sanitize(p.tool_name),tprev=sanitize(p.tool_preview);return updateToolById(messages,id,(t2)=>({...t2,trail:[...t2.trail??[],{name:tname,preview:tprev||void 0}],preview:tprev?`${tname}: ${tprev}`:tname}))}if(event==="complete"){let tokens3=(p.input_tokens??0)+(p.output_tokens??0),extra=tokens3?` \xB7 ${(tokens3/1000).toFixed(1)}k tok`:"",summary2=sanitize(p.summary);return updateToolById(messages,id,(t2)=>({...t2,status:p.status==="failed"||p.status==="error"||p.status==="timeout"||p.status==="interrupted"?"error":"done",duration:p.duration_seconds?p.duration_seconds*1000:t2.startedAt?Date.now()-t2.startedAt:void 0,result:summary2?summary2+extra:void 0,preview:t2.goal??t2.preview}))}return updateToolById(messages,id,(t2)=>({...t2,preview:sanitize(p.text)||t2.preview}))}function useSlash(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),themeCtx=useTheme(),cmd=useCommand(),renderer=useRenderer(),cfg=useHome("config"),bg2=useBackground(),ctx2=import_react126.useRef(c);ctx2.current=c;let gate=import_react126.useRef(cfg);gate.current=cfg;let destructive=import_react126.useCallback((arg,opts,action)=>{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",bypass=!(gate.current?.approvals?.destructive_slash_confirm??!0)||process.env.HERMES_TUI_NO_CONFIRM==="1",persist2=a==="always",fire=()=>{if(persist2)Promise.resolve().then(() => (init_lane(),exports_lane)).then(({writeConfig:writeConfig2})=>writeConfig2(gw,[{key:"approvals.destructive_slash_confirm",to:!1}]).then((r)=>{if(r.failed.length){toast.show({variant:"warning",message:`couldn't persist: ${r.failed[0].err}`});return}home2.invalidate("config"),toast.show({variant:"success",message:`${opts.yes} \xB7 future runs silent`})}).catch((e)=>toast.show({variant:"error",message:e.message})));action()};if(skip||bypass)return fire();openConfirm(dialog,{title:opts.title,body:opts.body,yes:opts.yes,danger:!0}).then((ok)=>{if(ok)fire()})},[gw,dialog,toast]),pickEikon=import_react126.useCallback(()=>openEikonPicker(dialog,(n)=>set("eikon",n)),[dialog]),applyTitle=import_react126.useCallback((t2)=>{gw.request("session.title",{title:t2}).then((r)=>{ctx2.current.setTitle(r.title),ctx2.current.dispatch({kind:"system",text:`Title: ${r.title}`})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),runCompress=import_react126.useCallback(async()=>{toast.show({variant:"info",message:"Compressing session\u2026"});let r=await ctx2.current.session.compress();if(!r)return;if(r.info)ctx2.current.setInfo(r.info);if(ctx2.current.setUsage((u3)=>{let base2=r.usage??u3,max=r.usage?.context_max??u3?.context_max;if(typeof r.after_tokens!=="number"||typeof max!=="number")return base2;return{...base2??{input:0,output:0,total:0},context_used:r.after_tokens,context_max:max}}),Array.isArray(r.messages))ctx2.current.dispatch({kind:"load",messages:transcriptToMessages(r.messages)});if(!r.summary)return;let s=r.summary;if(s.noop){toast.show({variant:"info",message:s.headline??`No changes \xB7 ~${r.before_tokens??0} tokens`});return}let lines2=[s.headline,s.token_line,s.note].filter(Boolean).join(`
4176
+ `)}function transcriptToMessages(rows3){return rows3.filter((r)=>r.role==="user"||r.role==="assistant").map((r)=>({role:r.role,content:sanitize(flatten3(r.text))})).filter((r)=>r.content).map((r)=>({id:mid(),role:r.role,parts:[{type:"text",content:r.content,streaming:!1}],timestamp:Date.now()/1000}))}function assistant(parts2){return{id:mid(),role:"assistant",parts:parts2,timestamp:Date.now()/1000}}function withLastAssistant(messages,fn,otherwise){let last3=messages[messages.length-1];if(last3?.role==="assistant")return[...messages.slice(0,-1),fn(last3)];return[...messages,otherwise()]}function seal(parts2){let last3=parts2[parts2.length-1];if(last3?.type==="text"&&last3.streaming)return[...parts2.slice(0,-1),{...last3,streaming:!1}];return parts2}function appendText(messages,chunk2){return withLastAssistant(messages,(m2)=>{let last3=m2.parts[m2.parts.length-1];if(last3?.type==="text"&&last3.streaming){let part={...last3,content:last3.content+chunk2};return{...m2,parts:[...m2.parts.slice(0,-1),part]}}return{...m2,parts:[...m2.parts,{type:"text",key:pid(),content:chunk2,streaming:!0}]}},()=>assistant([{type:"text",key:pid(),content:chunk2,streaming:!0}]))}function appendPart(messages,part,close){return withLastAssistant(messages,(m2)=>({...m2,parts:[...close?seal(m2.parts):m2.parts,part]}),()=>assistant([part]))}function finalize(messages,final,usage){let last3=messages[messages.length-1];if(last3?.role==="assistant"){let tail=last3.parts[last3.parts.length-1],dup=final&&last3.parts.some((p)=>p.type==="text"&&sameText(p.content,final)),text3=tail?.type==="text"&&final&&sameText(tail.content,final)?tail.content:final,parts2=tail?.type==="text"&&tail.streaming?[...last3.parts.slice(0,-1),{...tail,content:text3||tail.content,streaming:!1}]:final&&!dup&&!sameText(joinText(last3.parts),final)?[...last3.parts,{type:"text",content:final,streaming:!1}]:seal(last3.parts);return[...messages.slice(0,-1),{...last3,parts:parts2,usage}]}if(!final)return messages;return[...messages,{...assistant([{type:"text",content:final,streaming:!1}]),usage}]}function joinText(parts2){return parts2.filter((p)=>p.type==="text").map((p)=>p.content).join("")}function sameText(a,b2){return a.trim()===b2.trim()}function updateRunningTool(messages,name,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;for(let i=last3.parts.length-1;i>=0;i--){let p=last3.parts[i];if(p.type!=="tool"||p.status!=="running")continue;if(name&&p.name!==name)continue;let parts2=[...last3.parts];return parts2[i]=fn(p),[...messages.slice(0,-1),{...last3,parts:parts2}]}return messages}function updateToolById(messages,id,fn){let last3=messages[messages.length-1];if(!last3||last3.role!=="assistant")return messages;let parts2=last3.parts.map((p)=>p.type==="tool"&&p.id===id?fn(p):p);return[...messages.slice(0,-1),{...last3,parts:parts2}]}function updatePrompt(messages,id,fn){return messages.map((m2)=>{if(m2.role!=="assistant")return m2;if(!m2.parts.some((p)=>p.type==="prompt"&&p.id===id))return m2;return{...m2,parts:m2.parts.map((p)=>p.type==="prompt"&&p.id===id?fn(p):p)}})}function upsertThinking(messages,text3,final,verbose2){return withLastAssistant(messages,(m2)=>{let idx=m2.parts.findIndex((p)=>p.type==="thinking");if(idx>=0){let prev=m2.parts[idx],content=final?prev.content.trim()||text3:prev.content+text3,parts2=[...m2.parts];return parts2[idx]={...prev,content,streaming:!final,verbose:prev.verbose||verbose2||void 0},{...m2,parts:parts2}}return{...m2,parts:[{type:"thinking",key:pid(),content:text3,streaming:!final,verbose:verbose2},...m2.parts]}},()=>assistant([{type:"thinking",key:pid(),content:text3,streaming:!final,verbose:verbose2}]))}function renderSubagent(messages,event,p){let id=p.subagent_id?`sub-${p.subagent_id}`:`sub-${p.task_index}`;if(event==="start"){let goal=sanitize(p.goal),part={type:"tool",id,name:"delegate_task",args:"",status:"running",startedAt:Date.now(),preview:goal||void 0,goal:goal||void 0,depth:p.depth??0,trail:[]};return appendPart(messages,part,!0)}if(event==="tool"&&p.tool_name){let tname=sanitize(p.tool_name),tprev=sanitize(p.tool_preview);return updateToolById(messages,id,(t2)=>({...t2,trail:[...t2.trail??[],{name:tname,preview:tprev||void 0}],preview:tprev?`${tname}: ${tprev}`:tname}))}if(event==="complete"){let tokens3=(p.input_tokens??0)+(p.output_tokens??0),extra=tokens3?` \xB7 ${(tokens3/1000).toFixed(1)}k tok`:"",summary2=sanitize(p.summary);return updateToolById(messages,id,(t2)=>({...t2,status:p.status==="failed"||p.status==="error"||p.status==="timeout"||p.status==="interrupted"?"error":"done",duration:p.duration_seconds?p.duration_seconds*1000:t2.startedAt?Date.now()-t2.startedAt:void 0,result:summary2?summary2+extra:void 0,preview:t2.goal??t2.preview}))}return updateToolById(messages,id,(t2)=>({...t2,preview:sanitize(p.text)||t2.preview}))}function useSlash(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),themeCtx=useTheme(),cmd=useCommand(),renderer=useRenderer(),cfg=useHome("config"),bg2=useBackground(),ctx2=import_react126.useRef(c);ctx2.current=c;let gate=import_react126.useRef(cfg);gate.current=cfg;let destructive=import_react126.useCallback((arg,opts,action)=>{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",bypass=!(gate.current?.approvals?.destructive_slash_confirm??!0)||process.env.HERMES_TUI_NO_CONFIRM==="1",persist2=a==="always",fire=()=>{if(persist2)Promise.resolve().then(() => (init_lane(),exports_lane)).then(({writeConfig:writeConfig2})=>writeConfig2(gw,[{key:"approvals.destructive_slash_confirm",to:!1}]).then((r)=>{if(r.failed.length){toast.show({variant:"warning",message:`couldn't persist: ${r.failed[0].err}`});return}home2.invalidate("config"),toast.show({variant:"success",message:`${opts.yes} \xB7 future runs silent`})}).catch((e)=>toast.show({variant:"error",message:e.message})));action()};if(skip||bypass)return fire();openConfirm(dialog,{title:opts.title,body:opts.body,yes:opts.yes,danger:!0}).then((ok)=>{if(ok)fire()})},[gw,dialog,toast]),pickEikon=import_react126.useCallback(()=>openEikonPicker(dialog,(n)=>set("eikon",n)),[dialog]),applyTitle=import_react126.useCallback((t2)=>{gw.request("session.title",{title:t2}).then((r)=>{ctx2.current.setTitle(r.title),ctx2.current.dispatch({kind:"system",text:`Title: ${r.title}`})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),runCompress=import_react126.useCallback(async()=>{toast.show({variant:"info",message:"Compressing session\u2026"});let r=await ctx2.current.session.compress();if(!r)return;if(r.info)ctx2.current.setInfo(r.info);if(ctx2.current.setUsage((u3)=>{let base2=r.usage??u3,max=r.usage?.context_max??u3?.context_max;if(typeof r.after_tokens!=="number"||typeof max!=="number")return base2;return{...base2??{input:0,output:0,total:0},context_used:r.after_tokens,context_max:max}}),!r.summary)return;let s=r.summary;if(s.noop){toast.show({variant:"info",message:s.headline??`No changes \xB7 ~${r.before_tokens??0} tokens`});return}let lines2=[s.headline,s.token_line,s.note].filter(Boolean).join(`
4177
4177
  `);if(lines2)ctx2.current.dispatch({kind:"system",text:lines2});toast.show({variant:"success",message:s.headline??`Compressed ${r.before_messages??0}\u2192${r.after_messages??0} messages`})},[toast]),run=import_react126.useCallback((c2,arg="")=>{let x2=ctx2.current;if(c2.target==="local")switch(c2.name){case"clear":destructive(arg,{title:"Clear session?",body:"Discards the in-memory transcript. Your session on disk is unchanged; reload to restore.",yes:"clear"},()=>x2.dispatch({kind:"reset"}));return;case"new":destructive(arg,{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{x2.newSession()});return;case"theme":openThemePicker(dialog,themeCtx);return;case"help":dialog.replace($jsx(HelpDialog,{}));return;case"keys":openKeys(dialog);return;case"logs":openLogs(dialog);return;case"title":if(arg){applyTitle(arg);return}openTextPrompt(dialog,{title:"Session Title",initial:x2.title}).then((v2)=>{if(v2)applyTitle(v2)});return;case"rollback":openRollback(dialog,gw,toast);return;case"history":openHistory(dialog,gw);return;case"status":openStatus(dialog,x2.info,x2.sid);return;case"usage":openUsage(dialog,gw);return;case"profile":openProfile(dialog);return;case"chafa":if(!arg.trim()){toast.show({variant:"info",message:"usage: /chafa <path>"});return}openChafa(dialog,arg.trim());return;case"splash":x2.summoned.current=!0,x2.setSplash(!0);return;case"skin":{let name=arg.trim();if(!name){x2.dispatch({kind:"system",text:`skin: ${x2.skin.skin?.name??"\u2014"}
4178
4178
  ${SKINS.join(" ")}`});return}if(!SKINS.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name))themeCtx.set(name);set("eikon",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":x2.session.branch(arg||void 0).then((id)=>id?void x2.switchSession(id):toast.show({variant:"error",message:"branch failed"}));return;case"compress":runCompress();return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user");if(at>=0)x2.undone.current.push(msgs.slice(at));x2.session.undo().then(()=>gw.request("session.history").then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch(()=>{}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text(head));return}case"retry":{let last3=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last3){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last3).then(()=>x2.sendRef.current(text(last3)));return}case"model":if(!arg){openModelPicker(dialog,gw);return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text3=arg||comp?.value().trim()||"";if(!text3)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text3);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text(m2);copy(body2),toast.show({variant:"success",message:`copied ${body2.length} chars`});return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){toast.show({variant:"info",message:"usage: /background <prompt>"});return}gw.request("prompt.background",{text:arg}).then((r)=>{if(r.task_id)bg2.register(r.task_id);toast.show(r.task_id?{variant:"success",message:`background ${r.task_id} started`}:{variant:"error",message:"background start failed"})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub2=parts2[0]?.toLowerCase()||"connect",url2=parts2[1];if(!["connect","disconnect","status"].includes(sub2)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload={action:sub2};if(sub2==="connect"&&url2)payload.url=url2;gw.request("browser.manage",payload).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub2==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub2==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"compact":case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text3)=>gw.request("session.steer",{text:text3}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text3)=>{if(text3)fire(text3)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.capabilities.canDispatchGatewayCommand)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress]);return import_react126.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>ctx2.current.session.branch()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,run]),run}var import_react130=__toESM(require_react_production(),1);var import_react128=__toESM(require_react_production(),1);function openAlert(dialog,title,body2){dialog.replace($jsx(Alert,{title,body:body2,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied,setCopied]=import_react128.useState(!1),doCopy=()=>{copy(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied?theme.success:theme.textMuted,children:$jsx("u",{children:copied?"copied":"copy"})})})]})]})};init_perf();function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function formatProcessNotification(text3){let body2=text3.replace(/^\[IMPORTANT: /,"").replace(/\]$/,""),done2=body2.match(/^Background process (\S+) completed \(exit code (\S+)\)\.\nCommand: (.+?)(?:\n|$)/);if(done2)return`${done2[1]} exited ${done2[2]} \xB7 ${done2[3]}`;let hit2=body2.match(/^Background process (\S+) matched watch pattern "([^"]+)"\.\nCommand: (.+?)(?:\n|$)/);if(hit2)return`${hit2[1]} matched "${hit2[2]}" \xB7 ${hit2[3]}`;return body2.slice(0,100)}function mapEvent(ev,side){switch(ev.type){case"gateway.ready":if(side.onReady?.(),ev.payload?.skin)side.onSkin?.(ev.payload.skin);return null;case"session.info":{let si=ev.payload;side.onSessionInfo?.(si);let label2=si.model?`Connected \u2014 ${si.model} \xB7 ${count3(si.tools)} tools \xB7 ${count3(si.skills)} skills`:"Connected to Hermes";if(si.credential_warning)side.onStatus?.(si.credential_warning);return{kind:"system",text:label2}}case"message.start":return count("stream:start"),mem("stream-start"),{kind:"message.start"};case"message.delta":{let chunk2=ev.payload?.text??"";if(!chunk2)return null;return count("stream:chunk"),{kind:"message.delta",chunk:chunk2}}case"message.complete":{count("stream:done"),mem("stream-done");let p=ev.payload;if(p?.usage)side.onUsage?.(p.usage);if(side.onTurnComplete?.(),p?.status==="error")return{kind:"error",text:p.text||"request failed \u2014 see messages above"};if(p?.status==="interrupted")return{kind:"message.complete",text:(p.text||"")+`
4179
4179
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "herm-tui",
3
- "version": "1.9.0-dev.8",
3
+ "version": "1.9.0-dev.9",
4
4
  "description": "A modern TUI for Hermes Agent",
5
5
  "license": "MIT",
6
6
  "repository": {