@lelouchhe/webagent 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -110,6 +110,7 @@ Frontend source lives in `public/js/*.ts`, bundled by esbuild into a single cont
110
110
  | **[Attachments](docs/uploads.md)** | Upload pipeline, on-disk layout, lifecycle, permission auto-approve, observability |
111
111
  | **[ACP Integration](docs/acp.md)** | Client extensions, protocol scope, current limits |
112
112
  | **[Client Architecture](docs/client-architecture.md)** | Frontend modules, data flow, conventions |
113
+ | **[Streaming Render Performance](docs/performance.md)** | rAF coalescing, incremental lex, per-block memo, single-token fast path |
113
114
  | **[Slash Menu](docs/slash-menu.md)** | Walker pipeline, `CmdNode` tree, Tab/Enter/Click contract, how to add commands |
114
115
  | **[Messages / Inbox](docs/messages.md)** | `/inbox` slash command, POST ingress, bound vs unbound messages |
115
116
  | **[Share Links](docs/share.md)** | Public read-only session snapshots via `/share` + `/s/<token>` |
package/config.toml CHANGED
@@ -3,6 +3,15 @@
3
3
  # HTTP server port (default: 6800)
4
4
  port = 6800
5
5
 
6
+ # Network interface to bind. Default "127.0.0.1" = loopback only
7
+ # (not reachable from LAN; pair with a reverse proxy / tunnel like
8
+ # cloudflared for external access). Set to "0.0.0.0" to listen on all
9
+ # IPv4 interfaces, "::" for IPv6/dual-stack, or a specific NIC IP
10
+ # (e.g. "192.168.1.10") on a multi-homed host. Prefer the explicit
11
+ # "127.0.0.1" form over "localhost" — the latter goes through DNS
12
+ # resolution and may pick IPv6 (`::1`) depending on /etc/hosts order.
13
+ host = "127.0.0.1"
14
+
6
15
  # SQLite + uploads directory (default: "data")
7
16
  data_dir = "data"
8
17
 
@@ -65,10 +74,10 @@ global_visibility_suppression = true
65
74
  # - "flash" → Google Gemini (gemini-*-flash)
66
75
  # - "lite" → Cohere, generic
67
76
  #
68
- # Set model = [] to disable matching entirely and always inherit the
77
+ # Set models = [] to disable matching entirely and always inherit the
69
78
  # agent's default model. To pin one specific model, use a single-element
70
- # array, e.g. model = ["claude-haiku-4.5"].
71
- model = ["haiku", "flash-lite", "nano", "mini", "flash", "lite"]
79
+ # array, e.g. models = ["claude-haiku-4.5"].
80
+ models = ["haiku", "flash-lite", "nano", "mini", "flash", "lite"]
72
81
 
73
82
  [debug]
74
83
  # Frontend log level. One of: off | debug | info | warn | error.
Binary file
package/dist/index.html CHANGED
@@ -24,9 +24,9 @@
24
24
  <meta name="apple-mobile-web-app-capable" content="yes" />
25
25
  <meta name="apple-mobile-web-app-status-bar-style" content="default" />
26
26
  <script src="/theme-init.js"></script>
27
- <link rel="stylesheet" href="/styles.012p32dz.css" />
28
- <link rel="modulepreload" href="/js/chunk.D4ZYHJAM.js">
29
- <link rel="modulepreload" href="/js/chunk.CGWFHJI2.js">
27
+ <link rel="stylesheet" href="/styles.00xfh3e6.css" />
28
+ <link rel="modulepreload" href="/js/chunk.IJM5DBCO.js">
29
+ <link rel="modulepreload" href="/js/chunk.D4ZYHJAM.js">
30
30
  <link rel="modulepreload" href="/js/chunk.AJZBJBMO.js">
31
31
  </head>
32
32
  <body>
@@ -65,6 +65,6 @@
65
65
  </div>
66
66
  <div id="status-bar"></div>
67
67
 
68
- <script type="module" src="/js/app.GSAIYHML.js"></script>
68
+ <script type="module" src="/js/app.3OEVQXHK.js"></script>
69
69
  </body>
70
70
  </html>
@@ -0,0 +1,4 @@
1
+ import{a as Et,b as F,c as Lt,d as Ct,e as we,f as Pt,g as _,h as At,i as R,j as J,k as $t,l as k,m as ve,n as je,o as We,p as Mt,q as Ke}from"./chunk.IJM5DBCO.js";import{a as D}from"./chunk.D4ZYHJAM.js";import"./chunk.AJZBJBMO.js";var Se=null;function Yn(e){location.replace(e)}function Zn(e){let t;try{if(e.startsWith("/"))t=e.split("?")[0];else{let s=new URL(e);if(s.origin!==location.origin)return!1;t=s.pathname}}catch{return!1}return t.startsWith("/api/")}function Xn(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function _t(e={}){let t=e.baseFetch??globalThis.fetch.bind(globalThis),s=e.onUnauthorized??Yn;Se??=globalThis.fetch;let r=async(i,a)=>{let c=Xn(i),u=Zn(c),d=a;if(u){let m=localStorage.getItem(D);if(m){let p=a?.headers??(i instanceof Request?i.headers:void 0),g=new Headers(p);g.has("Authorization")||g.set("Authorization",`Bearer ${m}`),d={...a??{},headers:g}}}let f=await t(i,d);if(u&&f.status===401){try{localStorage.removeItem(D)}catch{}s("/login")}return f};return globalThis.fetch=r,es}function es(){Se&&(globalThis.fetch=Se,Se=null)}var ts=new Set(["plan","read-only"]),ns=new Set(["autopilot","bypassPermissions","full-access","yolo"]),ss=new Set(["agent","default","build"]);function be(e){if(!e)return"";let t=e.match(/[#/]([^#/]+)$/);return t?t[1]:e}function Rt(e){return ts.has(be(e))}function Nt(e){return ns.has(be(e))}function qt(e){let t=be(e);return t?!ss.has(t):!1}function Ht(e){return be(e).replace(/([A-Z])/g," $1").trim()}var Ge=class extends Error{name="ApiError";status;constructor(t,s){super(s),this.status=t}};async function C(e,t){let s=await fetch(e,t);if(!s.ok){let i=`HTTP ${s.status}`;try{let a=await s.json();a.error&&(i=typeof a.error=="string"?a.error:JSON.stringify(a.error))}catch{}throw new Ge(s.status,i)}let r=await s.text();if(r)return JSON.parse(r)}function P(e,t,s){let r={"Content-Type":"application/json"};return s&&(r["X-Client-Op-Id"]=s),C(e,{method:"POST",headers:r,body:JSON.stringify(t)})}function ke(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"op-"+Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,10)}function Te(e){let t={};return e?.cwd&&(t.cwd=e.cwd),e?.inheritFromSessionId&&(t.inheritFromSessionId=e.inheritFromSessionId),P("/api/v1/sessions",t)}function ne(e){return C("/api/v1/sessions/"+e,{method:"DELETE"})}function Ie(){return C("/api/v1/sessions")}function A(e){return C("/api/v1/sessions/"+e)}function Ot(e){return C("/api/v1/sessions/"+e+"/snapshot")}function Je(e,t,s){let r={text:t};return s?.length&&(r.attachments=s),P("/api/v1/sessions/"+e+"/prompt",r,ke())}function Bt(e){return P("/api/v1/sessions/"+e+"/cancel",{},ke())}function Dt(e,t,s){return P("/api/v1/sessions/"+e+"/permissions/"+t,{optionId:s},ke())}function Ft(e,t){return P("/api/v1/sessions/"+e+"/permissions/"+t,{denied:!0},ke())}function se(e,t,s){let r=t.replace(/_/g,"-");return C("/api/v1/sessions/"+e+"/"+r,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:s})})}function xe(e,t){return C("/api/v1/sessions/"+e+"/title",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:t})})}function Ut(e,t){return P("/api/v1/sessions/"+e+"/bash",{command:t})}function re(e,t,s){let r={visible:t};return s&&(r.sessionId=s),P("/api/beta/clients/"+e+"/visibility",r)}function Ee(){return P("/api/v1/bridge/reload",{})}function Vt(){return P("/api/v1/sse-ticket",{})}function ue(){return C("/api/v1/messages")}function jt(e){return P(`/api/v1/messages/${encodeURIComponent(e)}/consume`,{})}function Le(e){return C(`/api/v1/messages/${encodeURIComponent(e)}`,{method:"DELETE"})}function Ce(){return C("/api/v1/tokens")}function Pe(e){return P("/api/v1/tokens",{name:e})}function Ae(e){return C("/api/v1/tokens/"+encodeURIComponent(e),{method:"DELETE"})}var I=e=>document.querySelector(e),l={messages:I("#messages"),input:I("#input"),sendBtn:I("#send-btn"),prompt:I("#input-prompt"),status:I("#status"),sessionInfo:I("#session-info"),attachBtn:I("#attach-btn"),fileInput:I("#file-input"),attachPreview:I("#attach-preview"),themeBtn:I("#theme-btn"),slashMenu:I("#slash-menu"),inputArea:I("#input-area"),modePill:I("#mode-pill"),statusBar:I("#status-bar")};function N(e){l.input.value=e,l.input.dispatchEvent(new window.Event("input",{bubbles:!0}))}var n={eventSource:null,clientId:null,sessionId:null,sessionSwitchGen:0,sessionCwd:null,sessionTitle:null,awaitingNewSession:!1,configOptions:[],sessionMode:null,sessionModel:null,currentAssistantEl:null,currentAssistantText:"",assistantRafToken:null,currentThinkingEl:null,currentThinkingText:"",busy:!1,pendingAttachments:[],currentBashEl:null,followMessages:!0,pendingToolCallIds:new Set,pendingPermissionRequestIds:new Set,pendingPromptDone:!1,turnEnded:!1,newTurnStarted:!1,sentMessageForSession:null,sentBashForSession:null,cancelTimeout:1e4,serverVersion:null,agentName:null,agentVersion:null,_cancelTimerId:null,_onCancelTimeout:null,lastEventSeq:0,lastStateSeq:0,oldestLoadedSeq:0,hasMoreHistory:!1,loadingOlderEvents:!1,replayInProgress:!1,replayTarget:null,replayQueue:[],agentReloading:!1,recentPathsLimit:10,previewToken:null},rs={disconnected:"is-disconnected",connecting:"is-connecting",connected:"is-connected"};function Z(e,t=e){l.status.textContent="",l.status.className=`status-dot ${rs[e]}`,l.status.dataset.state=e,l.status.setAttribute("aria-label",t),l.status.setAttribute("title",t)}function $(e){return n.configOptions.find(t=>t.id===e)}function $e(e){return $(e)?.currentValue??null}function Wt(e,t){let s=$(e);s&&(s.currentValue=t)}function ze(e){n.configOptions=e,e.length>0&&Kt(),T(),q()}function is(e){n.configOptions.length>0||(n.sessionMode=e.session.mode??null,n.sessionModel=e.session.model??null)}function Kt(){n.sessionMode=null,n.sessionModel=null}function Gt(e){return e==="mode"?n.sessionMode:n.sessionModel}function T(){if(l.inputArea.classList.remove("plan-mode","autopilot-mode","preview-mode"),n.previewToken){l.inputArea.classList.add("preview-mode"),l.input.placeholder="publish or cancel",l.modePill.textContent="preview",ie();return}l.input.placeholder="Message or ?";let e=$e("mode")||Gt("mode")||"";Rt(e)?l.inputArea.classList.add("plan-mode"):Nt(e)&&l.inputArea.classList.add("autopilot-mode"),l.modePill.textContent=qt(e)?Ht(e):"",ie()}function q(){let e=$e("model")||Gt("model"),t=n.sessionCwd??"";if(l.statusBar.textContent="",t){e&&l.statusBar.appendChild(document.createTextNode(e+" \xB7 "));let s=document.createElement("span");s.className="status-cwd",s.textContent=t,l.statusBar.appendChild(s)}else e&&(l.statusBar.textContent=e)}function os(e){n.lastStateSeq=e.seq;let t=e.runtime.busy;w(t!=null),t==null&&oe(),is(e),T(),q()}function Jt(e){if(e.seq!==n.lastStateSeq+1)return!1;n.lastStateSeq=e.seq;let t=e.patch.runtime;if(t&&"busy"in t){let s=t.busy??null;w(s!=null),s==null&&oe()}return!0}async function H(e){let t=n.sessionSwitchGen;try{let s=await Ot(e);return n.sessionSwitchGen!==t?null:(os(s),s)}catch{return null}}function w(e){n.busy=e,e?l.prompt.classList.add("busy"):l.prompt.classList.remove("busy"),ie()}function U({cwd:e,inheritFromSessionId:t=n.sessionId}={}){n.awaitingNewSession=!0,Te({cwd:e,inheritFromSessionId:t}).catch(()=>{})}var zt=[];function Qt(e){zt.push(e)}var Yt=()=>{};function Zt(e){Yt=e}function ie(){Yt()}function v(){for(let e of zt)e();l.messages.innerHTML="",n.assistantRafToken!=null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(n.assistantRafToken),n.assistantRafToken=null),n.currentAssistantEl=null,n.currentAssistantText="",n.currentThinkingEl=null,n.currentThinkingText="",n.pendingAttachments.length=0,n.followMessages=!0,n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,n.turnEnded=!1,n.newTurnStarted=!1,n._cancelTimerId!=null&&clearTimeout(n._cancelTimerId),n._cancelTimerId=null,n.lastEventSeq=0,n.lastStateSeq=0,n.oldestLoadedSeq=0,n.hasMoreHistory=!1,n.loadingOlderEvents=!1,n.replayInProgress=!1,n.replayQueue=[],n.previewToken=null,l.attachPreview.innerHTML="",l.attachPreview.classList.remove("active"),l.input.disabled=!1,l.sendBtn.disabled=!1,T(),w(!1),n.sessionTitle=null,n.sessionCwd=null,n.configOptions=[],Kt(),Me(null,null),l.statusBar.textContent=""}function O(){return!n.busy||!n.sessionId?!1:(Bt(n.sessionId).catch(()=>{}),!0)}function oe(){n._cancelTimerId!=null&&(clearTimeout(n._cancelTimerId),n._cancelTimerId=null)}function Xt(){return location.hash.slice(1)||null}function Qe(e){history.replaceState(null,"",`#${e}`)}function Me(e,t){l.sessionInfo.textContent=t??(e?e.slice(0,8)+"\u2026":""),document.title=t??">_"}Z("disconnected");function _e(e,t){let s=document.createElement("div");return s.className=`msg ${e}`,e==="user"?s.innerHTML=_(t).replace(/\n/g,"<br>"):R(s,t),b(s),s}function o(e){let t=document.createElement("div");return t.className="system-msg",t.textContent=e,b(t),t}function V(){let e=n.currentAssistantEl,t=n.currentAssistantText;n.currentAssistantEl=null,n.currentAssistantText="",n.assistantRafToken!=null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(n.assistantRafToken),n.assistantRafToken=null,e&&R(e,t)),e&&typeof e.querySelector=="function"&&(e.removeAttribute("data-primed"),F(e),J(e))}function M(){if(n.currentThinkingEl){let e=n.currentThinkingEl.querySelector("summary");e.textContent="\u283F thought",e.classList.remove("active"),e.style.animation="none",n.currentThinkingEl.removeAttribute("data-primed"),n.currentThinkingEl=null,n.currentThinkingText=""}}var X=null,as=80;function Ze(e){return e.scrollHeight-e.scrollTop-e.clientHeight<as}function ls(){n.followMessages=Ze(l.messages)}l.messages.addEventListener("scroll",ls);function cs(){return n.followMessages||Ze(l.messages)}function b(e,t=!1){if(n.replayTarget)return n.replayTarget.appendChild(e),e;let s=t||cs();return l.messages.appendChild(e),S(s),e}function en(){j(),X=document.createElement("div"),X.id="waiting",X.innerHTML='<span class="cursor">\u258C</span>',b(X,!0)}function j(){X&&(X.remove(),X=null)}var Ye=!1;function S(e){let t=l.messages;if(e||n.followMessages){typeof requestAnimationFrame=="function"?Ye||(Ye=!0,requestAnimationFrame(()=>{Ye=!1,t.scrollTop=t.scrollHeight})):t.scrollTop=t.scrollHeight,n.followMessages=!0;return}n.followMessages=Ze(t)}function E(e){if(e==null||e==="")return"";let t;if(typeof e=="number")t=new Date(e);else{let r=String(e);t=new Date(r.endsWith("Z")||/[+-]\d{2}:?\d{2}$/.test(r)?r:r+"Z")}if(isNaN(t.getTime()))return"";let s=r=>String(r).padStart(2,"0");return`${t.getFullYear()}-${s(t.getMonth()+1)}-${s(t.getDate())} ${s(t.getHours())}:${s(t.getMinutes())}`}function tn(e,t=!1){let s=document.createElement("div");return s.className="bash-block",s.innerHTML=`<span class="bash-cmd${t?" running":""}">${_(e)}</span><div class="bash-output"></div>`,s.querySelector(".bash-cmd").addEventListener("click",()=>{let r=s.querySelector(".bash-output");r.style.display==="none"?r.style.display="block":r.classList.contains("has-content")&&(r.style.display="none")}),b(s),t&&(n.currentBashEl=s),s}function Re(e,t,s){if(!e)return;let r=e.querySelector(".bash-cmd");r.classList.remove("running");let i="";if(s?i=`[signal: ${s}]`:t!==0&&t!=null&&(i=`[exit: ${t}]`),i){let a=document.createElement("span");a.className=`bash-exit ${t===0?"ok":"fail"}`,a.textContent=i,r.after(a)}e===n.currentBashEl&&(n.currentBashEl=null)}function Xe(e,t){let s=e.replace(/^\s+/,"");if(s==="")return{node:t,pathPrefix:"",tailQuery:""};let r=/\s$/.test(s),i=s.split(/\s+/).filter(g=>g.length>0),a=r?i:i.slice(0,-1),c=r?"":i[i.length-1]??"",u=t,d="",f=0;for(let g of a){let h=u.children?.find(y=>y.name===g);if(!h)break;d=d?`${d} ${h.name}`:h.name,u=h,f++}let m=a.slice(f);c&&m.push(c);let p=m.join(" ");return{node:u,pathPrefix:d,tailQuery:p}}function nn(e,t,s){let r=[],i=t.trim().toLowerCase(),a=[];if(e.children){let g=e.name==="<root>"?[...e.children].sort((h,y)=>h.name.localeCompare(y.name)):e.children;for(let h of g){if(i&&!h.name.toLowerCase().includes(i))continue;let Qn=(h.children?.length??0)>0||h.fetch||h.freeform;a.push({spec:{primary:h.name,secondary:h.desc},prefix:Qn?"\u203A":"",kind:"subcommand",node:h})}}r.push(...a);let c=[],u="none",d="";if(e.fetch&&e.toSpec){if(s==="loading")u="loading";else if(s&&typeof s=="object"&&!Array.isArray(s)&&"error"in s)u="error",d=typeof s.error=="string"?s.error:"";else if(Array.isArray(s))if(s.length===0)u="empty";else{let h=(i?s.filter(y=>e.matches?e.matches(y,i):e.toSpec(y).primary.toLowerCase().includes(i)):s).map(y=>e.toSpec(y));h.length===0?u="no-match":(u="ok",c=h)}}let f=null;if(e.freeform){let g=t.trim();if(!(g.length>0&&c.some(y=>y.primary.toLowerCase()===g.toLowerCase()))){let y=e.freeform(t);y&&(f={spec:y,prefix:"\u21B5",kind:"freeform"},r.push(f))}}if((a.length>0||f!==null)&&u!=="none"&&r.push({spec:{primary:""},prefix:"",kind:"separator"}),u==="loading")r.push({spec:{primary:"(loading...)"},prefix:"",kind:"placeholder"});else if(u==="error")r.push({spec:{primary:`(${d||"error"})`},prefix:"",kind:"placeholder"});else if(u==="empty")r.push({spec:{primary:"(none)"},prefix:"",kind:"placeholder"});else if(u==="no-match")r.push({spec:{primary:"(no match)"},prefix:"",kind:"placeholder"});else if(u==="ok")for(let g of c)r.push({spec:g,prefix:g.current?"*":"",kind:"data"});return r}function sn(e,t,s){let r=document.createElement("div");r.className="slash-item"+(t?" selected":"");let i=e.path!==void 0,a=document.createElement("div");a.className="slash-row-l1";let c=document.createElement("span");c.className="slash-prefix",c.textContent=s,a.appendChild(c);let u=document.createElement("span");if(u.className="slash-primary"+(e.current?" slash-current":""),u.textContent=e.primary,a.appendChild(u),e.secondary!==void 0){let d=document.createElement("span");d.className="slash-secondary",d.textContent=e.secondary,a.appendChild(d)}if(r.appendChild(a),i){let d=document.createElement("div");d.className="slash-row-l2";let f=document.createElement("span");if(f.className="slash-path",f.textContent=e.path,d.appendChild(f),e.pathSecondary!==void 0){let m=document.createElement("span");m.className="slash-path-secondary",m.textContent=e.pathSecondary,d.appendChild(m)}r.appendChild(d)}return r}var tt={debug:0,info:1,warn:2,error:3,off:99},de=new Set(["off","debug","info","warn","error"]),rn=4096;function on(e){try{let t=new WeakSet,s=JSON.stringify(e,(r,i)=>{if(i instanceof Error)return{name:i.name,message:i.message,stack:i.stack};if(typeof i=="function")return`[Function ${i.name??"anonymous"}]`;if(typeof i=="bigint")return i.toString()+"n";if(typeof i=="symbol")return i.toString();if(typeof i=="object"&&i!==null){if(t.has(i))return"[Circular]";t.add(i)}return i});return typeof s!="string"?String(e):s.length>rn?s.slice(0,rn)+`\u2026(truncated, ${s.length} bytes)`:s}catch{try{return String(e)}catch{return"[unserializable]"}}}function et(e){return e<10?"0"+e:String(e)}function us(e){return e<10?"00"+e:e<100?"0"+e:String(e)}function an(e){let t=new Date(e);return`${et(t.getHours())}:${et(t.getMinutes())}:${et(t.getSeconds())}.${us(t.getMilliseconds())}`}var st="off",ln="default",cn,nt=null;function Ne(e,t="runtime"){de.has(e)&&(st=e,ln=t)}function rt(){return st}function un(){return ln}function qe(e){cn=e;let t=pn(e);Ne(t.level,t.source)}function dn(e){nt=e}function fn(e){try{let s=new URL(e).searchParams.get("debug");return s===null||!de.has(s)?null:s}catch{return null}}function ds(){return typeof location>"u"?null:fn(location.href)}function fs(){if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(ve);return!e||!de.has(e)?null:e}catch{return null}}function pn(e,t=typeof location>"u"?null:location.href){let s=t?fn(t):null;if(s)return{level:s,source:"url"};let r=fs();return r?{level:r,source:"local"}:e&&de.has(e)?{level:e,source:"config"}:{level:"off",source:"default"}}function mn(e){typeof localStorage<"u"&&localStorage.setItem(ve,e);let t={level:e,source:"local"};return Ne(e,"local"),t}function gn(){typeof localStorage<"u"&&localStorage.removeItem(ve);let e=pn(cn);return Ne(e.level,e.source),e}function hn(e){let t=(s,r,i)=>{if(tt[s]<tt[st])return;let a=e?`[${e}] `:"";try{let c=console[s];i!==void 0?c(a+r,i):c(a+r)}catch{}if(nt)try{let c=an(Date.now()),u=e?` [${e}]`:"",d=i!==void 0?" "+on(i):"";nt(`${c}${u} ${s.toUpperCase()} ${r}${d}`)}catch{}};return{debug:(s,r)=>{t("debug",s,r)},info:(s,r)=>{t("info",s,r)},warn:(s,r)=>{t("warn",s,r)},error:(s,r)=>{t("error",s,r)},scope:s=>hn(e?`${e}.${s}`:s)}}var x=hn();{let e=ds();e&&Ne(e)}if(typeof window<"u"){let e=x.scope("window");window.addEventListener("error",t=>{e.error(t.message||"uncaught error",{filename:t.filename,lineno:t.lineno,colno:t.colno,stack:t.error instanceof Error?t.error.stack:void 0})}),window.addEventListener("unhandledrejection",t=>{let s=t.reason;e.error("unhandled rejection",{reason:s instanceof Error?{name:s.name,message:s.message,stack:s.stack}:s})})}async function W(e,t){n.sessionSwitchGen++;let s=n.sessionSwitchGen;try{let r=await Ie();if(s!==n.sessionSwitchGen)return;let i=r.find(a=>a.id!==e);if(i){v(),n.sessionId=null,Qe(i.id);let[a,c]=await Promise.all([A(i.id),K(i.id)]);if(s!==n.sessionSwitchGen)return;L({type:"session_created",sessionId:a.id,cwd:a.cwd,title:a.title,configOptions:a.configOptions}),c&&S(!0);return}}catch{}s===n.sessionSwitchGen&&(v(),n.sessionId=null,U({cwd:t??void 0}))}function ot(e){return n.replayTarget?.querySelector(`[id="${e}"]`)??document.getElementById(e)}function ps(e){return n.replayTarget?.querySelector(e)??document.querySelector(e)}function vn(e){e.querySelectorAll(".plan[open]").forEach(t=>{t.open=!1})}function yn(e){(typeof navigator<"u"?navigator.serviceWorker:void 0)?.controller?.postMessage({type:"close-notification",tag:e})}function ms(){if(typeof Notification>"u"||n.replayInProgress)return;let e=Notification.permission;if(e!=="granted"){if(e==="denied"){if(localStorage.getItem(We))return;localStorage.setItem(We,"1"),o("tip: notifications are blocked \u2014 allow in browser site settings to enable");return}localStorage.getItem(je)||(localStorage.setItem(je,"1"),o("tip: use /notify to enable background notifications"))}}function He(){Pt(n.pendingPromptDone,n.pendingToolCallIds.size,n.pendingPermissionRequestIds.size)&&(j(),M(),V(),w(!1),n.pendingPromptDone=!1,ms())}function gs(){for(let e of n.pendingToolCallIds){let t=document.getElementById(`tc-${e}`);if(!t)continue;t.className="tool-call failed";let s=t.querySelector(".icon");s&&(s.textContent="\u2717")}for(let e of n.pendingPermissionRequestIds){let t=document.querySelector(`.permission[data-request-id="${e}"]`);if(!t?.querySelector("button"))continue;let r=t.querySelector(".title")?.textContent??"\u26BF";t.innerHTML=`<span class="dim">${_(r)} \u2014 cancelled</span>`}n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear()}function hs(){for(let e of n.pendingToolCallIds){let t=document.getElementById(`tc-${e}`);if(!t)continue;t.className="tool-call completed";let s=t.querySelector(".icon");s&&(s.textContent="\u2713")}n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear()}var Sn=200;async function K(e){n.replayInProgress=!0,n.replayQueue=[];try{let t=await fetch(`/api/v1/sessions/${e}/events?limit=${Sn}`);if(!t.ok)return!1;let s=await t.json(),{events:r,streaming:i,hasMore:a}=we(s),c=document.createDocumentFragment(),u=ct(r);n.replayTarget=c;for(let d=0;d<r.length;d++){let f=JSON.parse(r[d].data);ut(r[d].type,f,r,d,u)}return n.replayTarget=null,l.messages.style.display="none",l.messages.appendChild(c),l.messages.style.display="",r.length&&(n.lastEventSeq=r[r.length-1].seq,n.oldestLoadedSeq=r[0].seq),n.hasMoreHistory=a===!0,n.hasMoreHistory&&ws(),bn(),at(r,i),!0}catch{return!1}finally{n.replayTarget=null,n.replayInProgress=!1,In()}}function at(e,t){if(n.assistantRafToken!=null&&x.warn("primeStreamingState: assistantRafToken non-null at entry (missing flush upstream)"),t.thinking){let s;if(e.length){for(let r=e.length-1;r>=0;r--)if(e[r].type==="thinking"){let i=l.messages.querySelectorAll(".thinking");s=i[i.length-1];break}}else{let r=l.messages.querySelectorAll(".thinking");s=r[r.length-1]}if(s){n.currentThinkingEl=s,n.currentThinkingText=s.getAttribute("data-raw")??"",s.setAttribute("data-primed","");let r=s.querySelector("summary");r&&(r.textContent="\u283F thinking...",r.classList.add("active"))}}if(t.assistant){let s;if(e.length){for(let r=e.length-1;r>=0;r--)if(e[r].type==="assistant_message"){let i=l.messages.querySelectorAll(".msg.assistant");s=i[i.length-1];break}}else{let r=l.messages.querySelectorAll(".msg.assistant");s=r[r.length-1]}s&&(n.currentAssistantEl=s,n.currentAssistantText=s.getAttribute("data-raw")??"",s.setAttribute("data-primed",""))}}function bn(){let e=l.messages.querySelector("[data-sync-boundary]");e&&e.removeAttribute("data-sync-boundary");let t=l.messages.lastElementChild;t&&t.setAttribute("data-sync-boundary","")}var it=new Map;function lt(e){let t=it.get(e);if(t)return t;let s=ys(e);return it.set(e,s),s.finally(()=>{it.delete(e)}).catch(()=>{}),s}async function ys(e){n.replayInProgress=!0,n.replayQueue=[],n.assistantRafToken!=null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(n.assistantRafToken),n.assistantRafToken=null);try{let t=`/api/v1/sessions/${e}/events?after=${n.lastEventSeq}`,s=await fetch(t);if(!s.ok||n.sessionId&&e!==n.sessionId)return!1;let r=await s.json(),{events:i,streaming:a}=we(r);for(let p of l.messages.querySelectorAll("[data-primed]")){let g=p.getAttribute("data-raw")??"";if(p.removeAttribute("data-primed"),p.classList.contains("msg")&&p.classList.contains("assistant"))J(p),p.replaceChildren(),R(p,g),F(p);else if(p.classList.contains("thinking")){let h=p.querySelector(".thinking-content");h&&(h.textContent=g);let y=p.querySelector("summary");y&&(y.textContent="\u283F thought",y.classList.remove("active"),y.style.animation="none")}}let c=l.messages.querySelector("[data-sync-boundary]");if(c)for(;c.nextElementSibling;)c.nextElementSibling.remove();if(n.currentAssistantEl&&J(n.currentAssistantEl),n.currentAssistantEl=null,n.currentAssistantText="",n.currentThinkingEl=null,n.currentThinkingText="",n.currentBashEl=null,i.length===0)return at(i,a),!0;let u=document.createDocumentFragment(),d=ct(i);n.replayTarget=u;for(let p=0;p<i.length;p++){let g=JSON.parse(i[p].data);ut(i[p].type,g,i,p,d)}n.replayTarget=null;let f=l.messages.lastElementChild,m=u.firstElementChild;if(f&&m){if(f.classList.contains("msg")&&f.classList.contains("assistant")&&m.classList.contains("msg")&&m.classList.contains("assistant")){let p=f.getAttribute("data-raw")??"",g=m.getAttribute("data-raw")??"",h=p+g;f.setAttribute("data-raw",h),J(f),f.replaceChildren(),R(f,h),F(f),m.remove()}else if(f.classList.contains("thinking")&&m.classList.contains("thinking")){let p=f.getAttribute("data-raw")??"",g=m.getAttribute("data-raw")??"",h=p+`
2
+ `+g;f.setAttribute("data-raw",h);let y=f.querySelector(".thinking-content");y&&(y.textContent=h),m.remove()}}return l.messages.appendChild(u),n.lastEventSeq=i[i.length-1].seq,bn(),at(i,a),!0}catch{return!1}finally{n.replayTarget=null,n.replayInProgress=!1,In()}}var fe=null;function ws(){Oe();let e=document.createElement("div");e.id="history-sentinel",e.className="history-sentinel",e.textContent="\u2191 loading\u2026",l.messages.prepend(e),typeof IntersectionObserver=="function"&&(fe=new IntersectionObserver(t=>{t[0].isIntersecting&&!n.loadingOlderEvents&&n.hasMoreHistory&&n.sessionId&&vs(n.sessionId)},{root:l.messages,rootMargin:"200px 0px 0px 0px"}),fe.observe(e))}function Oe(){fe&&(fe.disconnect(),fe=null),document.getElementById("history-sentinel")?.remove()}Qt(Oe);async function vs(e){if(n.loadingOlderEvents||!n.hasMoreHistory||n.oldestLoadedSeq<=0)return!1;n.loadingOlderEvents=!0;try{let t=await fetch(`/api/v1/sessions/${e}/events?limit=${Sn}&before=${n.oldestLoadedSeq}`);if(!t.ok||e!==n.sessionId)return!1;let s=await t.json(),{events:r,hasMore:i}=we(s);if(r.length===0)return n.hasMoreHistory=!1,Oe(),!0;let a=document.createDocumentFragment(),c=ct(r);n.replayTarget=a;for(let m=0;m<r.length;m++){let p=JSON.parse(r[m].data);ut(r[m].type,p,r,m,c)}n.replayTarget=null;let u=l.messages,d=u.scrollHeight,f=document.getElementById("history-sentinel");return f?f.after(a):u.prepend(a),u.scrollTop+=u.scrollHeight-d,n.oldestLoadedSeq=r[0].seq,n.hasMoreHistory=i===!0,n.hasMoreHistory||Oe(),!0}catch{return!1}finally{n.loadingOlderEvents=!1}}function ct(e){let t=new Set;for(let s of e)if(s.type==="permission_response"){let r=JSON.parse(s.data);t.add(r.requestId)}return{toolCalls:new Map,permissions:new Map,resolvedPermissions:t,currentBashEl:null}}function kn(e){let t=document.createElement("details");t.className="message",t.open=!0,t.setAttribute("data-message-id",e.message_id),t.setAttribute("data-raw",e.body);let s=e.from_label??e.from_ref,r=e.title?` \xB7 ${_(e.title)}`:"";t.innerHTML=`<summary>\u2709\uFE0E ${_(s)}${r}</summary><div class="message-content"></div>`;let i=t.querySelector(".message-content");i&&R(i,e.body),b(t),i&&F(i)}function ut(e,t,s,r,i){let a=t;if($t(e)){bs(e,a,s,r,i);return}switch(e){case"prompt_done":n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,w(!1);break;case"message":kn(a);break}}function ee(){return{findToolCallEl:e=>document.getElementById(`tc-${e}`),findPermissionEl:e=>document.querySelector(`.permission[data-request-id="${e}"]`),findBashEl:()=>n.currentBashEl,enhanceMarkdown:F}}function Ss(e,t,s){return{findToolCallEl:r=>e?e.toolCalls.get(r)??null:ot(`tc-${r}`),findPermissionEl:r=>e?e.permissions.get(r)??null:ps(`.permission[data-request-id="${r}"]`),findBashEl:()=>e?e.currentBashEl:ot("bash-replay-pending"),isPermissionResolved:r=>e?e.resolvedPermissions.has(r):t.slice(s+1).some(i=>{let a=JSON.parse(i.data);return i.type==="permission_response"&&a.requestId===r}),enhanceMarkdown:F}}function Tn(e,t,s,r){e.querySelectorAll("button").forEach(a=>{let c=a.dataset.optionId??"",u=a.dataset.optionKind??"",d=a.textContent||"";a.onclick=()=>{Ct(u).apiAction==="deny"?Ft(n.sessionId,t).catch(()=>{}):Dt(n.sessionId,t,c).catch(()=>{}),e.innerHTML=`<span class="dim">\u26BF ${_(s)} \u2014 ${_(d)}</span>`,r?.()}})}function bs(e,t,s,r,i){let a=Ss(i,s,r);switch(e){case"assistant_message":{let u=(n.replayTarget??l.messages).lastElementChild,d=t.text??"";if(u?.classList.contains("msg")&&u.classList.contains("assistant")){let p=(u.getAttribute("data-raw")??"")+d;u.setAttribute("data-raw",p),J(u),u.replaceChildren(),R(u,p),F(u);break}let f=k(e,t,a);f&&b(f);break}case"thinking":{let u=(n.replayTarget??l.messages).lastElementChild,d=t.text??"";if(u?.classList.contains("thinking")){let m=u.querySelector(".thinking-content");if(m){let g=(u.getAttribute("data-raw")??"")+`
3
+ `+d;u.setAttribute("data-raw",g),m.textContent=g;break}}let f=k(e,t,a);f&&b(f);break}case"tool_call":{let c=k(e,t,a);c&&(b(c),i&&i.toolCalls.set(t.id,c));break}case"tool_call_update":{k(e,t,a),(t.status==="completed"||t.status==="failed")&&n.pendingToolCallIds.delete(t.id);break}case"permission_request":{let c=t.requestId,u=t.title??"",d=k(e,t,a);d&&((a.isPermissionResolved?.(c)??!1)||Tn(d,c,u),b(d),i&&i.permissions.set(c,d));break}case"bash_command":{let c=k(e,t,a);c&&(i?i.currentBashEl=c:c.id="bash-replay-pending",b(c));break}case"bash_result":{let c=i?i.currentBashEl:ot("bash-replay-pending");c&&!i&&c.removeAttribute("id"),k(e,t,a),i&&(i.currentBashEl=null);break}case"user_message":case"plan":case"permission_response":{let c=k(e,t,a);c&&(e==="plan"&&vn(n.replayTarget??l.messages),b(c));break}}}function In(){let e=n.replayQueue;n.replayQueue=[];for(let t of e)ks(t)||L(t)}function ks(e){switch(e.type){case"tool_call":return!!document.getElementById(`tc-${e.id}`);case"permission_request":return!!document.querySelector(`.permission[data-request-id="${e.requestId}"]`);case"thought_chunk":return!!n.currentThinkingEl;case"message_chunk":return!!n.currentAssistantEl;default:return!1}}function wn(){let e=n.currentAssistantEl;if(!e)return;let t=performance.now();R(e,n.currentAssistantText);let s=performance.now(),r=s-t;if(r>8){let a=At(),c=d=>Math.round(d*10)/10,u={ms:c(r),len:n.currentAssistantText.length,seq:a.seq,blocks:a.blocks,hits:a.hits,misses:a.misses,fastPath:a.fastPath,lex:{total:c(a.lex),prefix:c(a.lexPrefix),tail:c(a.lexTail),prefixBlocks:a.prefixBlocks,prefixLen:a.prefixLen,tailLen:a.tailLen,mathRelex:a.mathRelex,mathRelexLen:a.mathRelexLen,tailBlocks:a.tailBlocks,tailRawBlocks:a.tailRawBlocks},parse:c(a.parse),sanitize:c(a.sanitize),dom:c(a.dom),subList:a.subList,subTable:a.subTable,defsAbsorbed:a.defsAbsorbed,linkMemoSize:a.linkMemoSize,missDetails:a.missDetails.slice(0,5).map(d=>({type:d.type,len:d.len,snip:d.snip,parseMs:c(d.parseMs),sanMs:c(d.sanMs),domMs:c(d.domMs),path:d.path,...d.items!==void 0?{items:d.items}:{}}))};r>16?x.warn("md-render budget",u):x.debug("md-render slow",u)}S();let i=performance.now();try{performance.measure("doAssistantRender",{start:t,end:i}),performance.measure("scrollToBottom",{start:s,end:i})}catch{}}function Ts(){if(n.assistantRafToken==null){if(typeof requestAnimationFrame!="function"){wn();return}n.assistantRafToken=requestAnimationFrame(()=>{n.assistantRafToken=null,wn()})}}function L(e){if(n.replayInProgress){n.replayQueue.push(e);return}let t="sessionId"in e?e.sessionId:void 0;if(!(t&&e.type!=="session_created"&&e.type!=="session_deleted"&&(!n.sessionId||t!==n.sessionId)))switch(e.type){case"connected":if(e.cancelTimeout!=null&&(n.cancelTimeout=e.cancelTimeout),e.recentPathsLimit!=null&&(n.recentPathsLimit=e.recentPathsLimit),qe(e.debugLevel),n.agentReloading){n.agentReloading=!1;let s=e.agent.name,r=e.agent.version,i=s&&r?`${s} ${r}`:"Agent";o(`${i} reloaded.`),w(!1)}break;case"state_patch":{!Jt({seq:e.seq,patch:e.patch})&&n.sessionId===e.sessionId&&H(n.sessionId);break}case"session_created":if(!n.awaitingNewSession&&n.sessionId&&e.sessionId!==n.sessionId)break;n.awaitingNewSession=!1,n.sessionId=e.sessionId,n.sessionCwd=e.cwd??n.sessionCwd,n.sessionTitle=e.title??null,e.configOptions&&e.configOptions.length&&ze(e.configOptions),T(),q(),Qe(n.sessionId),n.clientId&&re(n.clientId,!document.hidden,n.sessionId).catch(()=>{}),Me(n.sessionId,n.sessionTitle),Z("connected","connected"),l.input.disabled=!1,l.sendBtn.disabled=!1,n.newTurnStarted=!1;{let s=document.getElementById("bash-replay-pending");s?(s.removeAttribute("id"),s.querySelector(".bash-cmd")?.classList.add("running"),n.currentBashEl=s):n.currentBashEl=null}l.messages.children.length===0&&o(`Session created: ${n.sessionTitle??e.sessionId.slice(0,8)+"\u2026"}`),q();break;case"user_message":{if(n.sentMessageForSession===e.sessionId){n.sentMessageForSession=null;break}if(M(),V(),n.newTurnStarted=!0,n.turnEnded=!1,e.sessionId===n.sessionId){let s=k("user_message",e,ee());s&&b(s)}break}case"message_chunk":if(n.turnEnded)break;j(),M(),n.currentAssistantEl||(n.currentAssistantEl=_e("assistant",""),n.currentAssistantText=""),n.currentAssistantText+=e.text,Ts();break;case"thought_chunk":if(n.turnEnded)break;j(),n.currentThinkingEl||(n.currentThinkingEl=document.createElement("details"),n.currentThinkingEl.className="thinking",n.currentThinkingEl.innerHTML='<summary class="active">\u283F thinking...</summary><div class="thinking-content"></div>',n.currentThinkingText="",b(n.currentThinkingEl)),n.currentThinkingText+=e.text,n.currentThinkingEl.querySelector(".thinking-content").textContent=n.currentThinkingText,S();break;case"tool_call":{if(n.turnEnded)break;n.pendingToolCallIds.add(e.id),w(!0),j(),M(),V();let s=k("tool_call",e,ee());s&&b(s);break}case"tool_call_update":{(e.status==="completed"||e.status==="failed")&&n.pendingToolCallIds.delete(e.id),k("tool_call_update",e,ee()),He(),S();break}case"plan":{M(),V();let s=k("plan",e,ee());s&&(vn(l.messages),b(s));break}case"permission_request":{if(n.turnEnded||document.querySelector(`.permission[data-request-id="${e.requestId}"]`))break;n.pendingPermissionRequestIds.add(e.requestId),w(!0),M();let s=k("permission_request",e,ee());if(s){let r=e.requestId;Tn(s,r,e.title,()=>{n.pendingPermissionRequestIds.delete(r),He()}),b(s)}break}case"permission_response":{n.pendingPermissionRequestIds.delete(e.requestId),e.sessionId===n.sessionId&&k("permission_response",e,ee()),He();break}case"bash_command":{if(n.sentBashForSession===e.sessionId){n.sentBashForSession=null;break}if(e.sessionId===n.sessionId){let s=k("bash_command",e,ee());s&&(s.querySelector(".bash-cmd").classList.add("running"),b(s),n.currentBashEl=s),w(!0)}break}case"bash_output":{if(e.sessionId!==n.sessionId)break;if(n.currentBashEl){let s=n.currentBashEl.querySelector(".bash-output");if(!s)break;if(e.stream==="stderr"){let r=document.createElement("span");r.className="stderr",r.textContent=e.text,s.appendChild(r)}else s.appendChild(document.createTextNode(e.text));s.classList.add("has-content"),s.scrollTop=s.scrollHeight,S()}break}case"bash_done":{if(e.sessionId!==n.sessionId)break;Re(n.currentBashEl,e.code,e.signal),e.error&&o(`err: ${e.error}`),w(!1);break}case"prompt_done":{if(oe(),e.stopReason==="cancelled"&&n.newTurnStarted){n.newTurnStarted=!1,M(),V();break}n.newTurnStarted=!1,e.stopReason==="cancelled"?gs():hs(),n.turnEnded=!0,n.pendingPromptDone=!0,He();break}case"session_deleted":e.sessionId===n.sessionId&&W(e.sessionId,n.sessionCwd??void 0);break;case"session_expired":{W(n.sessionId,n.sessionCwd??void 0);break}case"config_set":{Wt(e.configId,e.value);let s=$(e.configId),r=s?.name??e.configId,i=s?.options.find(a=>a.value===e.value)?.name??e.value;o(`ok: ${r}: ${i}`),e.configId==="mode"&&T(),q();break}case"config_option_update":e.configOptions.length&&ze(e.configOptions);break;case"session_title_updated":e.sessionId===n.sessionId&&(n.sessionTitle=e.title,Me(n.sessionId,n.sessionTitle));break;case"agent_reloading":n.agentReloading=!0,o("Agent reloading\u2026"),w(!0);break;case"agent_reloading_failed":o(`err: Agent reload failed: ${e.error}`),w(!1);break;case"error":n.awaitingNewSession=!1,n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,j(),M(),V(),o(`err: ${e.message}`),w(!1);break;case"message_created":o(`inbox: new message ${e.messageId} \u2014 /inbox to view`);break;case"message_consumed":o(`inbox: ${e.messageId} consumed \u2192 session ${e.sessionId}`),yn(`msg-${e.messageId}`);break;case"message_acked":o(`inbox: ${e.messageId} dismissed`),yn(`msg-${e.messageId}`);break;case"message":e.sessionId===n.sessionId&&(kn(e),S());break;default:break}}async function pe({cwd:e,showCwd:t=!1}={}){if(!n.sessionId){o("warn: No active session");return}let s=n.sessionId,r=e??n.sessionCwd??void 0;n.busy&&O(),v(),o(t&&r?`Clearing session and starting at ${r}\u2026`:"Clearing session\u2026"),n.awaitingNewSession=!0;try{await Te({cwd:r,inheritFromSessionId:s})}catch{n.awaitingNewSession=!1,o("err: Failed to clear session");return}ne(s).catch(()=>{})}var me=x.scope("share");function Is(e,t){return e.startsWith("http")?e:e?`${location.origin}${e}`:`${location.origin}/s/${t}`}async function Be(){if(!n.sessionId){o("share: no active session");return}let e=n.sessionId;try{let t=await fetch(`/api/v1/sessions/${encodeURIComponent(e)}/share`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({}),credentials:"same-origin"});if(!t.ok){let i=await t.text();t.status===409?o("share: session busy (agent streaming) \u2014 retry after the response completes"):t.status===403?o("share: forbidden (not owner)"):t.status===400&&i.includes("sanitize")?o(`share: \u2717 sanitize blocked this session \u2014 ${i}`):o(`share: create failed ${t.status} \u2014 ${i.slice(0,200)}`);return}let s=await t.json();n.previewToken=s.token,T();let r=s.reused?"reused":"ready";o(`share: preview ${r} \u2014 ^P publish \xB7 ^C cancel`)}catch(t){me.error("preview create error",{err:t}),o(`share: network error \u2014 ${String(t)}`)}}async function dt(){if(!n.sessionId){o("share: no active session");return}if(!n.previewToken){o("share: no preview to publish \u2014 run /share first");return}let e=n.sessionId,t=n.previewToken;try{let s=await fetch(`/api/v1/sessions/${encodeURIComponent(e)}/share/publish`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t}),credentials:"same-origin"});if(!s.ok){let u=await s.text();s.status===403?o("share: forbidden (not owner)"):s.status===404?o("share: token not found (already revoked?)"):o(`share: publish failed ${s.status} \u2014 ${u.slice(0,200)}`);return}let r=await s.json(),i=Is(r.public_url,r.token);n.previewToken=null,T();let a=o(`share: published
4
+ `),c=document.createElement("a");c.href=i,c.textContent=i,c.target="_blank",c.rel="noopener noreferrer",a.appendChild(c)}catch(s){me.error("publish error",{err:s}),o(`share: network error \u2014 ${String(s)}`)}}function ft(){if(!n.previewToken){o("share: no preview active");return}n.previewToken=null,T(),o("share: preview canceled")}async function pt(){let e=await fetch("/api/v1/shares",{credentials:"same-origin"});if(!e.ok)throw new Error(`list failed ${e.status}`);return(await e.json()).shares.filter(s=>s.shared_at!=null)}async function De(e){if(!e){o("share: usage \u2014 /share revoke <token>");return}try{let s=(await xs()).find(a=>a.token===e);if(!s){o("share: token not found (already revoked?)");return}let r=await fetch(`/api/v1/sessions/${encodeURIComponent(s.session_id)}/share`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:e}),credentials:"same-origin"});if(!r.ok){r.status===403?o("share: forbidden (not owner)"):r.status===404?o(`share: ${e} already revoked`):o(`share: revoke failed ${r.status}`);return}let i=await r.json();o(i.revoked?`share: revoked ${e}`:`share: ${e} already revoked`)}catch(t){me.error("revoke error",{err:t}),o(`share: network error \u2014 ${String(t)}`)}}async function xs(){let e=await fetch("/api/v1/shares",{credentials:"same-origin"});if(!e.ok)throw new Error(`list failed ${e.status}`);return(await e.json()).shares.filter(s=>s.shared_at!=null)}function ge(e){let t=`${location.origin}/s/${e}`;window.open(t,"_blank","noopener"),o(`share: opened ${t}`)}async function xn(){try{let e=await fetch("/api/v1/share/by",{credentials:"same-origin"});return e.ok?(await e.json()).value:null}catch{return null}}async function he(e){try{let t=await fetch("/api/v1/share/by",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:e}),credentials:"same-origin"});if(!t.ok){let r=await t.text();o(`share: set author failed ${t.status} \u2014 ${r.slice(0,200)}`);return}let s=await t.json();if(n.previewToken&&n.sessionId)try{await fetch(`/api/v1/sessions/${encodeURIComponent(n.sessionId)}/share`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:n.previewToken,display_name:s.value??""}),credentials:"same-origin"})}catch(r){me.warn("by: preview patch failed",{err:r})}o(s.value?`share: author set to '${s.value}'`:"share: author cleared (publish anonymously)")}catch(t){me.error("by error",{err:t}),o(`share: network error \u2014 ${String(t)}`)}}var ae=!1;async function An(){try{ae=await(await navigator.serviceWorker.ready).pushManager.getSubscription()!==null}catch{ae=!1}}function Es(e){let t="=".repeat((4-e.length%4)%4),s=(e+t).replace(/-/g,"+").replace(/_/g,"/"),r=atob(s),i=new Uint8Array(r.length);for(let a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return i}async function Ls(){try{let e=await navigator.serviceWorker.ready,t=await fetch("/api/beta/push/vapid-key");if(!t.ok)return;let{publicKey:s}=await t.json(),i=(await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:Es(s)})).toJSON();await fetch("/api/beta/push/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:i.endpoint,keys:i.keys,clientId:n.clientId})})}catch(e){x.scope("push").error("subscribe failed",{err:e})}}async function Cs(){try{let t=await(await navigator.serviceWorker.ready).pushManager.getSubscription();if(!t)return;let s=t.endpoint;await t.unsubscribe(),await fetch("/api/beta/push/unsubscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:s})})}catch(e){x.scope("push").error("unsubscribe failed",{err:e})}}async function Ps(){return(await fetch("/api/v1/sessions")).json()}async function En(){let e=n.recentPathsLimit,t=e>0?`/api/v1/recent-paths?limit=${e}`:"/api/v1/recent-paths";return(await(await fetch(t)).json()).map(i=>({cwd:i.cwd,time:i.last_used_at}))}var Ln=async()=>{let{messages:e}=await ue();return e},Cn=async()=>Ce();function gt(){return`log: ${rt()} (${un()})`}function $n(){o(`${gt()} \u2014 use /log <off|debug|info|warn|error|reset>`)}function ht(e){mn(e),o(`${gt()} saved`),e!=="off"&&x.info("log enabled",{level:e})}function yt(){gn(),o(`${gt()} reset`)}async function wt(){o("Resetting local state\u2026");let e=await Mt();e.errors.length&&o(`warn: reset had issues: ${e.errors.join("; ")}`),location.reload()}async function Mn(e){n.sessionSwitchGen++;let t=n.sessionSwitchGen;v(),n.sessionId=null;try{let[s,r]=await Promise.all([A(e),K(e),H(e)]);if(t!==n.sessionSwitchGen)return;L({type:"session_created",sessionId:s.id,cwd:s.cwd,title:s.title,configOptions:s.configOptions}),r&&S(!0)}catch{v(),n.sessionId=null,o("err: Failed to switch session")}}async function As(e,t,s){let r=$(e);r&&(r.currentValue=t),T(),q(),o(`${r?.name??e} \u2192 ${s}`),n.sessionId&&await se(n.sessionId,e,t).catch(()=>{})}async function vt(e){try{let t=await jt(e.id);t.alreadyConsumed?o(`inbox: already consumed \u2192 switching to ${t.sessionId}`):o(`inbox: opened as ${t.sessionId}`),await Mn(t.sessionId)}catch(t){o(`err: consume failed (${t.message})`)}}async function $s(e){try{await Le(e.id),o(`inbox: ack ${e.id}`)}catch(t){o(`err: ack failed (${t.message})`)}}async function Ms(e){if(!/^[A-Za-z0-9_-]{1,64}$/.test(e)){o("err: token name must match [A-Za-z0-9_-]{1,64}");return}try{let t=await Pe(e);o(`token: created ${t.name} (${t.scope})`),o(`${t.token}`),o("\u2014 save this now; it will never be shown again")}catch(t){let s=t;s.status===409?o(`err: token "${e}" already exists`):s.status===403?o("err: admin scope required to manage tokens"):o(`err: create failed (${s.message})`)}}async function _s(e){try{await Ae(e),o(`token: revoked ${e}`)}catch(t){let s=t;s.status===404?o(`err: no token named "${e}"`):s.status===403?o("err: admin scope required to manage tokens"):s.status===400&&/using|yourself|cannot/i.test(s.message)?o("err: can't revoke the token you're signed in with \u2014 use another admin token"):o(`err: revoke failed (${s.message})`)}}async function Rs(){if(typeof Notification>"u"){o("err: notifications not supported in this browser");return}if(Notification.permission==="denied"){o("notify: blocked \u2014 allow in browser site settings to enable");return}if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted"){o("notify: blocked \u2014 allow in browser site settings to enable");return}await An();let e=ae;await Ls(),ae=!0,o(e?"notify: already enabled":"notify: enabled")}async function Ns(){await Cs(),ae=!1,o("notify: disabled")}function Pn(e,t){let s=e.shared_at?E(e.shared_at):"\u2014";return{primary:e.token,secondary:e.session_title??void 0,path:`/s/${e.token}`,pathSecondary:s,onSelect:()=>{t==="open"?ge(e.token):De(e.token)}}}var Q={name:"<root>",children:[{name:"/cancel",desc:"Cancel current response",onSelect:()=>{n.busy?(O(),o("^C")):o("Nothing to cancel.")}},{name:"/clear",desc:"Clear current session",fetch:En,toSpec:e=>{let t=e,s=t.cwd.toLowerCase()===(n.sessionCwd??"").toLowerCase();return{primary:t.cwd,current:s,onSelect:()=>{pe({cwd:t.cwd,showCwd:!0})}}},freeform:e=>{let t=e.trim();return t?{primary:`clear and start at '${t}'`,onSelect:()=>{pe({cwd:t,showCwd:!0})}}:null}},{name:"/log",desc:"Set log level",fetch:()=>[{value:"reset",name:"reset",desc:"Follow config/default"},{value:"off",name:"off",desc:"Disable logging"},{value:"error",name:"error",desc:"Show errors only"},{value:"warn",name:"warn",desc:"Show warnings and errors"},{value:"info",name:"info",desc:"Show info, warnings, errors"},{value:"debug",name:"debug",desc:"Show all messages"}],toSpec:e=>{let t=e;return{primary:t.name,secondary:t.desc,current:t.value!=="reset"&&t.value===rt(),onSelect:()=>{if(t.value==="reset"){yt();return}ht(t.value)}}}},{name:"/reset",desc:"Reset local state",onSelect:()=>{wt()}},{name:"/exit",desc:"End current session",onSelect:async()=>{if(!n.sessionId){o("warn: No active session");return}let e=n.sessionId;try{n.busy&&O(),ne(e).catch(()=>{}),await W(e,n.sessionCwd??void 0)}catch{o("err: Failed to exit session")}}},{name:"/help",desc:"Show help",onSelect:()=>{qs()}},{name:"/inbox",desc:"Manage inbox",fetch:Ln,toSpec:e=>{let t=e,s=t.from_label??t.from_ref,r=E(t.created_at);return{primary:t.title,secondary:r,path:t.cwd??"",pathSecondary:s,onSelect:()=>vt(t)}},children:[{name:"dismiss",desc:"Dismiss only",fetch:Ln,toSpec:e=>{let t=e,s=t.from_label??t.from_ref,r=E(t.created_at);return{primary:t.title,secondary:r,path:t.cwd??"",pathSecondary:s,onSelect:()=>$s(t)}}}]},{name:"/logout",desc:"Log out",onSelect:()=>{try{localStorage.removeItem(D)}catch{}try{n.eventSource?.close()}catch{}o("Logged out."),location.replace("/login")}},mt("/mode","Switch mode","mode"),mt("/model","Switch model","model"),{name:"/new",desc:"Create new session",fetch:En,toSpec:e=>{let t=e,s=t.cwd.toLowerCase()===(n.sessionCwd??"").toLowerCase();return{primary:t.cwd,current:s,onSelect:()=>{v(),o("Creating new session\u2026"),U({cwd:t.cwd})}}},freeform:e=>{let t=e.trim();return t?{primary:`create session at '${t}'`,onSelect:()=>{v(),o("Creating new session\u2026"),U({cwd:t})}}:null}},{name:"/notify",desc:"Toggle notifications",fetch:async()=>(await An(),[{value:"on",name:"on",desc:"Enable notifications"},{value:"off",name:"off",desc:"Disable notifications"}]),toSpec:e=>{let t=e,s=t.value==="on"===ae;return{primary:t.name,secondary:t.desc,current:s,onSelect:t.value==="on"?Rs:Ns}}},{name:"/reload",desc:"Reload agent",onSelect:()=>{o("Reloading agent\u2026"),Ee().catch(e=>{o(`err: ${e instanceof Error?e.message:"Failed to reload agent"}`)})}},{name:"/rename",desc:"Rename session",freeform:e=>{let t=e.trim();return t?{primary:`rename to '${t}'`,onSelect:async()=>{if(!n.sessionId){o("err: No active session");return}try{await xe(n.sessionId,t),o(`Renamed \u2192 ${t}`)}catch{o("err: Failed to rename session")}}}:null}},{name:"/share",desc:"Share a read-only snapshot",fetch:pt,toSpec:e=>Pn(e,"open"),freeform:e=>{let t=e.trim();return t?{primary:`open share '${t}'`,onSelect:()=>{ge(t)}}:{primary:"create new share preview",onSelect:()=>Be()}},children:[{name:"by",desc:"Set author",fetch:async()=>[{value:await xn()}],toSpec:e=>{let t=e.value;return{primary:t??"(none)",secondary:t?"current \u2014 Enter to clear":"currently anonymous",onSelect:()=>he(null)}},freeform:e=>{let t=e.trim();return t?{primary:`set author to '${t}'`,onSelect:()=>he(t)}:null}},{name:"revoke",desc:"Revoke a share",fetch:pt,toSpec:e=>Pn(e,"revoke")}]},{name:"/switch",desc:"Switch session",fetch:Ps,matches:(e,t)=>{let s=e;return(s.title??"").toLowerCase().includes(t)||s.id.startsWith(t)},toSpec:e=>{let t=e,s=t.title??t.id,r=E(t.last_active_at);return{primary:s,secondary:r,path:t.cwd,current:t.id===n.sessionId,onSelect:()=>Mn(t.id)}}},mt("/think","Set thinking effort","reasoning_effort"),{name:"/token",desc:"Manage API tokens",fetch:Cn,toSpec:e=>{let t=e,s=t.lastUsedAt?E(t.lastUsedAt):"never";return{primary:t.name,secondary:`last used ${s}`,path:`${t.scope} \xB7 created ${E(t.createdAt)}`,current:t.isSelf,onSelect:t.isSelf?void 0:()=>{o(`\u2014 use /token revoke ${t.name} to revoke`)}}},freeform:e=>{let t=e.trim();return/^[A-Za-z0-9_-]{1,64}$/.test(t)?{primary:`create token '${t}'`,onSelect:()=>Ms(t)}:null},children:[{name:"revoke",desc:"Revoke token",fetch:async()=>(await Cn()).filter(e=>!e.isSelf),toSpec:e=>{let t=e,s=t.lastUsedAt?E(t.lastUsedAt):"never";return{primary:t.name,secondary:`last used ${s}`,path:`${t.scope} \xB7 created ${E(t.createdAt)}`,onSelect:()=>_s(t.name)}}}]}]};function mt(e,t,s){return{name:e,desc:t,fetch:()=>{let r=$(s);return r?r.options:[]},toSpec:r=>{let i=r,a=$e(s);return{primary:i.name,current:i.value===a,onSelect:()=>As(s,i.value,i.name)}}}}function qs(){let e=[];n.serverVersion&&e.push(`WebAgent ${n.serverVersion}`),n.agentName&&n.agentVersion&&e.push(`${n.agentName} ${n.agentVersion}`),e.length&&o(e.join(" \xB7 ")),o("\u203A has next step * current value"),o("Tab completes \xB7 Enter sends raw text"),o("? \u2014 Show help"),o("!<command> \u2014 Run bash command");for(let t of Q.children)o(`${t.name} \u2014 ${t.desc??""}`);o("--- Shortcuts ---");for(let t of Hs)o(`${t.key} \u2014 ${t.desc}`);o("--- Tips ---");for(let t of Os)o(t.text)}var Hs=[{key:"Enter",desc:"Send message"},{key:"Shift+Enter",desc:"New line"},{key:"^C",desc:"Cancel current response"},{key:"^M",desc:"Cycle mode (Agent \u2192 Plan \u2192 Autopilot)"},{key:"^U",desc:"Attach file (any type)"}],Os=[{text:"Tap \u276F prompt to cycle mode"}];async function Bs(){try{let e=await navigator.serviceWorker.ready,t=await fetch("/api/beta/push/vapid-key");if(!t.ok)return;let{publicKey:s}=await t.json(),i=(await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:Fs(s)})).toJSON();await fetch("/api/beta/push/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:i.endpoint,keys:i.keys,clientId:n.clientId})})}catch(e){x.scope("push").error("subscribe failed",{err:e})}}async function Ds(){try{let t=await(await navigator.serviceWorker.ready).pushManager.getSubscription();if(!t)return;let s=t.endpoint;await t.unsubscribe(),await fetch("/api/beta/push/unsubscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:s})})}catch(e){x.scope("push").error("unsubscribe failed",{err:e})}}function Fs(e){let t="=".repeat((4-e.length%4)%4),s=(e+t).replace(/-/g,"+").replace(/_/g,"/"),r=atob(s),i=new Uint8Array(r.length);for(let a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return i}async function _n(){try{return await(await navigator.serviceWorker.ready).pushManager.getSubscription()!==null}catch{return!1}}async function St(e){let t=e.split(/\s+/),s=t[0].toLowerCase(),r=t.slice(1).join(" ").trim();switch(s){case"/share":{let i=r.split(/\s+/),a=(i[0]??"").toLowerCase();if(a==="")return await Be(),!0;if(a==="revoke"){let u=i[1]??"";return await De(u),!0}if(a==="by"){let u=r.replace(/^by(\s+|$)/i,"").trim();return await he(u===""?null:u),!0}let c=i[0]??"";return/^[A-Za-z0-9_-]{24}$/.test(c)?(ge(c),!0):(o(`share: unknown subcommand '${a}' \u2014 try /share, /share by <name>, /share <token>, or /share revoke <token>`),!0)}case"/new":{let i=r||n.sessionCwd||void 0,a=n.sessionId;return v(),n.sessionId=null,o("Creating new session\u2026"),U({cwd:i,inheritFromSessionId:a}),!0}case"/rename":{if(!n.sessionId)return o("err: No active session"),!0;if(!r)return o(`Current: ${n.sessionTitle??"(untitled)"}`),o("Usage: /rename <new title>"),!0;try{await xe(n.sessionId,r),o(`Renamed \u2192 ${r}`)}catch{o("err: Failed to rename session")}return!0}case"/sessions":return o("Removed. Use /switch to see all sessions."),!0;case"/clear":return await pe({cwd:r||void 0,showCwd:!!r}),!0;case"/exit":{if(!n.sessionId)return o("warn: No active session"),!0;let i=n.sessionId;try{n.busy&&O(),ne(i).catch(()=>{}),await W(i,n.sessionCwd??void 0)}catch{o("err: Failed to exit session")}return!0}case"/logout":{try{localStorage.removeItem(D)}catch{}try{n.eventSource?.close()}catch{}return o("Logged out."),location.replace("/login"),!0}case"/token":{let i=r.trim().split(/\s+/).filter(Boolean),a=i[0];if(!a){try{let u=await Ce();if(u.length===0)return o("token: (none)"),!0;for(let d of u){let f=d.lastUsedAt?E(d.lastUsedAt):"never";o(`${d.name} (${d.scope}) \u2014 created ${E(d.createdAt)}, last used ${f}`)}o("\u2014 /token <name> to create \xB7 /token revoke <name> to revoke")}catch(u){let d=u;d.status===403?o("err: admin scope required to manage tokens"):o(`err: token list failed (${d.message})`)}return!0}if(a==="revoke"){let u=i[1];if(!u)return o("err: usage /token revoke <name>"),!0;try{await Ae(u),o(`token: revoked ${u}`)}catch(d){let f=d;f.status===404?o(`err: no token named "${u}"`):f.status===403?o("err: admin scope required to manage tokens"):f.status===400&&/using|yourself|cannot/i.test(f.message)?o("err: can't revoke the token you're signed in with \u2014 use another admin token"):o(`err: revoke failed (${f.message})`)}return!0}let c=a;if(!/^[A-Za-z0-9_-]{1,64}$/.test(c))return o("err: token name must match [A-Za-z0-9_-]{1,64}"),!0;try{let u=await Pe(c);o(`token: created ${u.name} (${u.scope})`),o(`${u.token}`),o("\u2014 save this now; it will never be shown again")}catch(u){let d=u;d.status===409?o(`err: token "${c}" already exists`):d.status===403?o("err: admin scope required to manage tokens"):o(`err: create failed (${d.message})`)}return!0}case"/switch":{if(!r)return o("Usage: /switch <title or id prefix>"),!0;try{let a=await(await fetch("/api/v1/sessions")).json(),c=r.toLowerCase(),u=a.find(m=>m.id.startsWith(r)||m.title?.toLowerCase().includes(c));if(!u)return o(`err: No session matching "${r}"`),!0;n.sessionSwitchGen++;let d=n.sessionSwitchGen;v(),n.sessionId=null;let[f]=await Promise.all([A(u.id),K(u.id),H(u.id)]);if(d!==n.sessionSwitchGen)return!0;L({type:"session_created",sessionId:f.id,cwd:f.cwd,title:f.title,configOptions:f.configOptions}),S(!0)}catch{v(),n.sessionId=null,o("err: Failed to switch session")}return!0}case"/cancel":return n.busy?(O(),o("^C")):o("Nothing to cancel."),!0;case"/reload":return o("Reloading agent\u2026"),Ee().then(()=>{}).catch(i=>{o(`err: ${i instanceof Error?i.message:"Failed to reload agent"}`)}),!0;case"/help":case"?":{let i=[];n.serverVersion&&i.push(`WebAgent ${n.serverVersion}`),n.agentName&&n.agentVersion&&i.push(`${n.agentName} ${n.agentVersion}`),i.length&&o(i.join(" \xB7 ")),o("\u203A has next step * current value"),o("Tab completes \xB7 Enter sends raw text"),o("? \u2014 Show help"),o("!<command> \u2014 Run bash command");for(let a of Q.children)o(`${a.name} \u2014 ${a.desc??""}`);return o("--- Shortcuts ---"),o("Enter \u2014 Send message"),o("Shift+Enter \u2014 New line"),o("^C \u2014 Cancel current response"),o("^M \u2014 Cycle mode (Agent \u2192 Plan \u2192 Autopilot)"),o("^U \u2014 Attach file (any type)"),o("--- Tips ---"),o("Tap \u276F prompt to cycle mode"),!0}case"/model":case"/mode":case"/think":{let a={"/model":"model","/mode":"mode","/think":"reasoning_effort"}[s],c=$(a);if(!r){let p=c?.options.find(g=>g.value===c.currentValue)?.name??c?.currentValue??"unknown";return o(`${c?.name??a}: ${p}`),o(`Type ${s} + space to pick from list`),!0}if(!c)return o(`err: ${s.slice(1)} is not available.`),!0;let u=r.trim(),d=p=>p.toLowerCase().replace(/[\s_]+/g,"-"),f=d(u),m=c.options.find(p=>d(p.value)===f||d(p.name)===f);if(!m){let p=c.options.filter(g=>d(g.value).includes(f)||d(g.name).includes(f));if(p.length===1)m=p[0];else if(p.length>1)return o(`err: Ambiguous "${r}". Type ${s} + space to see options.`),!0}return m?(c.currentValue=m.value,T(),q(),o(`${c.name} \u2192 ${m.name}`),await se(n.sessionId,a,m.value).catch(()=>{}),!0):(o(`err: Unknown "${r}". Type ${s} + space to see options.`),!0)}case"/inbox":{let i=r.trim().split(/\s+/).filter(Boolean),a=i[0];if(!a){try{let{messages:p}=await ue();if(p.length===0)return o("inbox: empty"),!0;for(let g of p){let h=g.from_label??g.from_ref,y=E(g.created_at);o(`${g.id} \xB7 ${g.title} \xB7 ${h} \xB7 ${y}`)}o("\u2014 /inbox <id> to open \xB7 /inbox dismiss <id> to dismiss only")}catch(p){o(`err: inbox list failed (${p.message})`)}return!0}let c=a==="dismiss",u=c?i[1]:a;if(!u)return o("err: usage /inbox <id> | /inbox dismiss <id>"),!0;let d;try{({messages:d}=await ue())}catch(p){return o(`err: inbox list failed (${p.message})`),!0}let f=u.toLowerCase(),m=d.find(p=>p.id===u)??d.find(p=>p.id.toLowerCase().startsWith(f))??d.find(p=>p.title.toLowerCase().includes(f));if(!m)return o(`err: no inbox message matching "${u}"`),!0;if(c){try{await Le(m.id),o(`inbox: dismissed ${m.id}`)}catch(p){o(`err: dismiss failed (${p.message})`)}return!0}try{await vt(m)}catch(p){o(`err: consume failed (${p.message})`)}return!0}case"/notify":{if(typeof Notification>"u")return o("err: notifications not supported in this browser"),!0;let i=r.toLowerCase();if(i==="on"){if(Notification.permission==="denied")return o("notify: blocked \u2014 allow in browser site settings to enable"),!0;if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted")return o("notify: blocked \u2014 allow in browser site settings to enable"),!0;let c=await _n();return await Bs(),o(c?"notify: already enabled":"notify: enabled"),!0}if(i==="off")return await Ds(),o("notify: disabled"),!0;let a=Notification.permission;return a==="denied"?o("notify: blocked \u2014 allow in browser site settings to enable"):a==="granted"&&await _n()?o("notify: enabled"):o("notify: off \u2014 use /notify on to enable"),!0}case"/log":{let i=r.toLowerCase().trim();return i===""?($n(),!0):i==="reset"?(yt(),!0):["off","debug","info","warn","error"].includes(i)?(ht(i),!0):(o(`err: invalid level '${i}' (use off|debug|info|warn|error|reset)`),!0)}case"/reset":return await wt(),!0;default:return!1}}var ye=null,Fe=Q,te,G=[],Y=-1,le=null;function Tt(){let e=l.input.value;if(le!==null){if(e===le)return;le=null}if(!e.startsWith("/")){B();return}let{node:t,pathPrefix:s,tailQuery:r}=Xe(e,Q);if(s!==ye)if(ye=s,Fe=t,t.fetch&&t.toSpec){let i=t.fetch();if(i instanceof Promise){te="loading";let a=s;i.then(c=>{ye===a&&(te=c,bt(Rn(),s))},c=>{if(ye!==a)return;te={error:c instanceof Error&&c.message?c.message:"fetch failed"},bt(Rn(),s)})}else te=i}else te=void 0;else Fe=t;bt(r,s)}function Rn(){let{tailQuery:e}=Xe(l.input.value,Q);return e}function bt(e,t){let s=nn(Fe,e,te);if(G=s,s.length===0){B();return}let r=s.findIndex(i=>i.kind!=="separator"&&i.kind!=="placeholder");Y=r>=0?r:0,kt(t),l.slashMenu.classList.add("active")}function kt(e){l.slashMenu.innerHTML="",l.slashMenu.classList.toggle("slash-menu-root",e===""),G.forEach((s,r)=>{if(s.kind==="separator"){let c=document.createElement("div");c.className="slash-separator",c.dataset.idx=String(r),l.slashMenu.appendChild(c);return}let i=r===Y,a=sn(s.spec,i,s.prefix);s.prefix==="\u203A"&&a.classList.add("slash-arrow"),s.kind==="placeholder"&&a.classList.add("slash-placeholder"),a.dataset.idx=String(r),l.slashMenu.appendChild(a)}),l.slashMenu.dataset.pathPrefix=e;let t=l.slashMenu.querySelector(".slash-item.selected");t&&t.scrollIntoView({block:"nearest"})}function B(){l.slashMenu.classList.remove("active"),l.slashMenu.innerHTML="",Y=-1,G=[],ye=null,Fe=Q,te=void 0,le=l.input.value}function Us(){let e=G[Y];if(!e)return;let t=l.slashMenu.dataset.pathPrefix??"";if(!(e.kind==="separator"||e.kind==="placeholder")){if(e.kind==="subcommand"&&e.node){let r=(e.node.children??[]).length>0||!!e.node.fetch||!!e.node.freeform;N(`${t}${t?" ":""}${e.node.name}${r?" ":""}`),r?(le=null,Tt()):B()}else e.kind==="data"?(N(`${t}${t?" ":""}${e.spec.primary}`),B()):e.kind==="freeform"&&B();l.input.focus()}}async function Vs(e){let t=G[e];if(!t)return;let s=l.slashMenu.dataset.pathPrefix??"";if(!(t.kind==="separator"||t.kind==="placeholder")){if(t.kind==="subcommand"&&t.node){if((t.node.children??[]).length>0||!!t.node.fetch||!!t.node.freeform){N(`${s}${s?" ":""}${t.node.name} `),le=null,Tt(),l.input.focus();return}B(),N(""),t.node.onSelect&&await t.node.onSelect();return}B(),N(""),t.spec.onSelect?await t.spec.onSelect():o("Read-only entry \u2014 no action.")}}function qn(e){return!l.slashMenu.classList.contains("active")||G.length===0?!1:e.key==="ArrowDown"?(Y=Nn(Y,1),kt(l.slashMenu.dataset.pathPrefix??""),!0):e.key==="ArrowUp"?(Y=Nn(Y,-1),kt(l.slashMenu.dataset.pathPrefix??""),!0):e.key==="Tab"?(Us(),!0):!1}function Nn(e,t){let s=G.length;for(let r=1;r<=s;r++){let i=(e+t*r+s)%s;if(G[i].kind!=="separator"&&G[i].kind!=="placeholder")return i}return e}l.slashMenu.addEventListener("mousedown",e=>{e.preventDefault();let s=e.target?.closest(".slash-item");s?.dataset.idx!==void 0&&Vs(Number(s.dataset.idx))});l.input.addEventListener("input",()=>{Tt(),l.inputArea.classList.toggle("bash-mode",l.input.value.startsWith("!"))});function js(e){return new Promise(t=>{let s=new FileReader;s.onload=()=>{t(s.result)},s.readAsDataURL(e)})}async function Hn(e){let t=e.type.startsWith("image/"),s={kind:t?"image":"file",file:e,mimeType:e.type||"application/octet-stream",name:e.name||(t?"image":"file")};return t&&(s.previewUrl=await js(e)),s}function On(e){n.pendingAttachments.push(e),Ue()}function Ue(){if(l.attachPreview.innerHTML="",n.pendingAttachments.length===0){l.attachPreview.classList.remove("active");return}l.attachPreview.classList.add("active"),n.pendingAttachments.forEach((e,t)=>{let s=document.createElement("span");if(s.className="attach-thumb",e.kind==="image"&&e.previewUrl){let i=document.createElement("img");i.src=e.previewUrl,s.appendChild(i)}else{s.classList.add("attach-file");let i=document.createElement("span");i.className="attach-file-name",i.textContent=e.name,s.appendChild(i)}let r=document.createElement("button");r.className="remove",r.textContent="\xD7",r.addEventListener("click",()=>{n.pendingAttachments.splice(t,1),Ue()}),s.appendChild(r),l.attachPreview.appendChild(s)})}l.fileInput.onchange=async()=>{for(let e of l.fileInput.files)On(await Hn(e));l.fileInput.value=""};l.input.addEventListener("paste",e=>{let t=e.clipboardData?.items;if(t)for(let s of t)s.type.startsWith("image/")&&(e.preventDefault(),(async()=>{let r=s.getAsFile();r&&On(await Hn(r))})())});var ce={send:()=>{},cancel:()=>{},attach:()=>{},publish:()=>{},cancelPreview:()=>{}};function Fn(e){ce=e}function Bn(){let e=l.input.value.trim();return e.startsWith("/")||e.startsWith("!")||e==="?"||e.startsWith("? ")}function Ws(){if(n.previewToken)return[{label:"^P",title:"Publish preview (Ctrl+P)",className:"publish",onClick:()=>{ce.publish()}},{label:"^C",title:"Cancel preview (Ctrl+C)",className:"cancel",onClick:()=>{ce.cancelPreview()}}];let e={label:"^U",title:"Attach file (Ctrl+U)",onClick:()=>{ce.attach()}},t=()=>{n.busy&&!Bn()?ce.cancel():ce.send()};return n.busy&&!Bn()?[e,{label:"^C",title:"Cancel (Ctrl+C)",className:"cancel",onClick:t}]:[e,{label:"\u21B5",title:"Send (Enter)",onClick:t}]}var Ks=["cancel","publish"];function Dn(e,t){e.textContent=t.label,e.title=t.title,e.disabled=t.disabled??!1,e.onclick=t.onClick;for(let s of Ks)e.classList.remove(s);t.className&&e.classList.add(t.className)}function Gs(){let[e,t]=Ws();Dn(l.attachBtn,e),Dn(l.sendBtn,t),l.input.disabled=!!n.previewToken}Zt(Gs);function It(){return n.clientId!==null}n._onCancelTimeout=()=>o("warn: Agent not responding to cancel");function jn(){let e=l.input.value.trim();if(!e&&n.pendingAttachments.length===0)return;if((e.startsWith("/")||e==="?"||e.startsWith("? "))&&n.pendingAttachments.length===0){N(""),l.input.style.height="auto",St(e);return}if(e.startsWith("!")&&n.pendingAttachments.length===0){let i=e.slice(1).trim();if(!i)return;if(!n.sessionId){o("warn: Session not ready yet, please wait\u2026");return}if(!It()){o("warn: Not connected, please retry");return}N(""),l.input.style.height="auto",l.inputArea.classList.remove("bash-mode"),tn(i,!0),n.sentBashForSession=n.sessionId,Ut(n.sessionId,i).catch(()=>{}),w(!0);return}if(n.busy)return;if(N(""),l.input.style.height="auto",l.inputArea.classList.remove("bash-mode"),!n.sessionId){o("warn: Session not ready yet, please wait\u2026");return}if(!It()){o("warn: Not connected, please retry");return}let t=_e("user",e||"(attachment)"),s=[];for(let i of n.pendingAttachments)if(i.kind==="image"&&i.previewUrl){let a=document.createElement("img");a.className="user-image",a.src=i.previewUrl,a.alt=i.name,t.appendChild(a),s.push(null)}else{let a=document.createElement("div");a.className="user-attachment",a.textContent=`[${i.kind}: ${i.name}]`,t.appendChild(a),s.push(a)}let r=n.pendingAttachments.slice();n.pendingAttachments.length=0,Ue(),r.length>0?Promise.all(r.map(i=>{let a=new FormData;return a.append("file",i.file,i.name),fetch(`/api/v1/sessions/${n.sessionId}/attachments`,{method:"POST",body:a}).then(c=>c.json()).then(c=>({kind:c.kind,attachmentId:c.attachmentId,displayName:c.displayName,mimeType:c.mimeType,url:c.url}))})).then(i=>{if(!It()){t.remove(),o("warn: Not connected, please retry"),w(!1);return}for(let c=0;c<i.length;c++){let u=s[c];if(!u)continue;let d=i[c];if(d.kind==="image"||!d.url)continue;let f=document.createElement("a");f.className="user-file",f.href=d.url,f.target="_blank",f.rel="noopener",f.download=d.displayName,f.textContent=d.displayName,u.replaceWith(f)}let a=i.map(({kind:c,attachmentId:u,displayName:d,mimeType:f})=>({kind:c,attachmentId:u,displayName:d,mimeType:f}));Je(n.sessionId,e||"What is in this attachment?",a).catch(Un)}):Je(n.sessionId,e).catch(Un),n.turnEnded=!1,n.sentMessageForSession=n.sessionId,w(!0),en()}function Un(e){w(!1),j();let t=e instanceof Error?e.message:String(e);o(`err: ${t}`)}function Wn(){O()&&o("^C")}Fn({send:jn,cancel:Wn,attach:()=>{l.fileInput.click()},publish:()=>{dt()},cancelPreview:ft});ie();l.input.addEventListener("keydown",e=>{if(qn(e)){e.preventDefault();return}if(e.key==="Enter"&&!e.shiftKey){e.preventDefault(),B(),jn();return}if(e.key==="u"&&(e.ctrlKey||e.metaKey)&&!e.shiftKey){e.preventDefault(),l.fileInput.click();return}});document.addEventListener("keydown",e=>{if(e.key==="c"&&(e.ctrlKey||e.metaKey)&&!e.shiftKey&&!(!!window.getSelection()?.toString()||l.input.selectionStart!==l.input.selectionEnd)){if(n.previewToken){e.preventDefault(),ft();return}if(n.busy){e.preventDefault(),Wn();return}}e.key==="Escape"&&l.slashMenu.classList.contains("active")&&(e.preventDefault(),B(),l.input.focus())});var Vn=0;function Kn(){let e=$("mode");if(!e?.options.length){Date.now()-Vn>3e3&&(o("Mode switcher temporarily unavailable. Try `/new` to start a fresh session."),Vn=Date.now());return}let t=e.options.findIndex(r=>r.value===e.currentValue),s=e.options[(t+1)%e.options.length];e.currentValue=s.value,se(n.sessionId,"mode",s.value).catch(()=>{}),o(`Mode \u2192 ${s.name}`),T()}document.addEventListener("keydown",e=>{e.key==="m"&&(e.ctrlKey||e.metaKey)&&!e.shiftKey&&(e.preventDefault(),Kn())});document.addEventListener("keydown",e=>{n.previewToken&&(!(e.ctrlKey||e.metaKey)||e.shiftKey||e.key==="p"&&(e.preventDefault(),dt()))});l.prompt.addEventListener("click",Kn);l.input.addEventListener("input",ie);l.input.addEventListener("input",()=>{l.input.style.height="auto",l.input.style.height=Math.min(l.input.scrollHeight,200)+"px"});async function Js(e){try{let s=await(await navigator.serviceWorker.ready).pushManager.getSubscription();if(!s)return;await fetch("/api/beta/push/register-client",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({clientId:e,endpoint:s.endpoint})})}catch{}}function Ve(){Z("connecting","connecting"),zs()}async function zs(){let e;try{e=(await Vt()).ticket}catch{setTimeout(Ve,3e3);return}let t=new EventSource(`/api/v1/events/stream?ticket=${encodeURIComponent(e)}`);n.eventSource=t,t.onmessage=s=>{let r=JSON.parse(s.data);r.type==="connected"&&r.clientId&&(n.clientId=r.clientId,qe(r.debugLevel),re(r.clientId,!document.hidden,n.sessionId??void 0),Js(r.clientId),!r.agent)||L(r)},t.onerror=()=>{t.close(),Ys(),setTimeout(Ve,3e3)},t.addEventListener("heartbeat",()=>{n.clientId&&(document.hidden||re(n.clientId,!0,n.sessionId??void 0))}),Qs()}async function Qs(){Z("connecting","session loading");let e=n.sessionSwitchGen,t=Xt();if(t&&t===n.sessionId&&n.lastEventSeq>0){if(await xt(t,!0,e),e!==n.sessionSwitchGen)return;S(!1);return}if(t){if(v(),await xt(t,!1,e),e!==n.sessionSwitchGen)return;S(!0);return}try{let s=await Ie();if(e!==n.sessionSwitchGen)return;if(s.length>0){if(v(),await xt(s[0].id,!1,e),e!==n.sessionSwitchGen)return;S(!0);return}}catch{}e===n.sessionSwitchGen&&U()}async function xt(e,t,s){if(t){try{let r=await A(e);if(s!==n.sessionSwitchGen)return;L({type:"session_created",sessionId:r.id,cwd:r.cwd,title:r.title,configOptions:r.configOptions})}catch{if(s!==n.sessionSwitchGen)return;await W(e,n.sessionCwd??void 0);return}if(s!==n.sessionSwitchGen)return;await Promise.all([H(e),lt(e)])}else{n.sessionId=null;let r=K(e),i=H(e),a;try{let[c,u]=await Promise.all([A(e),r]);if(await i,s!==n.sessionSwitchGen)return;a=c,u||o("warn: Failed to load history.")}catch{if(s!==n.sessionSwitchGen)return;await W(e,n.sessionCwd??void 0);return}L({type:"session_created",sessionId:a.id,cwd:a.cwd,title:a.title,configOptions:a.configOptions})}}function Ys(){Z("disconnected","disconnected"),n.eventSource=null,n.clientId=null,M(),V(),n.currentBashEl&&Re(n.currentBashEl,null,"disconnected"),n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,n.turnEnded=!1,oe(),w(!1)}function Gn(e,t){let s=`/api/beta/clients/${encodeURIComponent(e)}/visibility`,r=JSON.stringify({visible:!1,sessionId:t});try{fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:r,keepalive:!0}).catch(()=>{})}catch{}}document.addEventListener("visibilitychange",()=>{if(n.clientId&&(document.hidden?Gn(n.clientId,n.sessionId??null):re(n.clientId,!0,n.sessionId??void 0)),!document.hidden&&n.sessionId&&n.lastEventSeq>0&&!n.replayInProgress){let e=n.sessionId;Promise.all([H(e),lt(e)]).then(()=>{S(!1)})}});window.addEventListener("pagehide",()=>{n.clientId&&Gn(n.clientId,n.sessionId??null)});var Zs=80,Jn=!1;function Xs(){return typeof window.visualViewport>"u"?null:window.visualViewport}function er(){let e=Xs();return e?e.offsetTop>0||window.innerHeight-e.height>Zs:!0}function tr(e){return e===l.input||e===l.inputArea}function nr(e){e.pointerType==="touch"&&tr(e.target)&&document.activeElement===l.input&&(l.input.disabled||er()||l.input.blur())}function zn(){Jn||(Jn=!0,document.addEventListener("pointerdown",nr,{capture:!0}))}if(!localStorage.getItem(D))throw location.replace("/login"),new Error("redirecting to /login");_t();dn(o);zn();l.messages.addEventListener("click",Et);Ke(Lt);Ve();fetch("/api/v1/version").then(e=>e.json()).then(e=>{typeof e.server=="string"&&(n.serverVersion=e.server);let t=e.agent;t&&(n.agentName=typeof t.name=="string"?t.name:null,n.agentVersion=typeof t.version=="string"?t.version:null)}).catch(()=>{});"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.js"),navigator.serviceWorker.addEventListener("message",e=>{let t=e.data;if(t?.type==="navigate"&&t.sessionId){let s=t.sessionId;if(n.sessionId===s)return;n.sessionSwitchGen++;let r=n.sessionSwitchGen;history.replaceState(null,"",`#${s}`),v(),n.sessionId=null,o("Switching\u2026"),Promise.all([A(s),K(s)]).then(([i,a])=>{r===n.sessionSwitchGen&&(L({type:"session_created",sessionId:i.id,cwd:i.cwd,title:i.title,configOptions:i.configOptions}),a&&S(!0))}).catch(()=>{v(),n.sessionId=null,o("err: Failed to switch session")})}}));