@lelouchhe/webagent 0.4.0 → 0.6.0
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 +1 -0
- package/config.toml +12 -3
- package/dist/fonts/temml/Temml.woff2 +0 -0
- package/dist/index.html +4 -4
- package/dist/js/app.HJKQURHR.js +4 -0
- package/dist/js/chunk.ON2W5X2T.js +173 -0
- package/dist/js/viewer.VY4PO2O5.js +1 -0
- package/dist/login.html +1 -1
- package/dist/share-viewer.html +4 -3
- package/dist/{styles.012p32dz.css → styles.01ky3cex.css} +416 -3
- package/lib/auth-middleware.js +3 -0
- package/lib/bridge-event-config.js +29 -0
- package/lib/bridge.js +9 -7
- package/lib/client-registry.js +104 -15
- package/lib/config.js +12 -5
- package/lib/event-handler.js +3 -1
- package/lib/image-dimensions.js +64 -0
- package/lib/model-picker.js +17 -0
- package/lib/preflight.js +41 -22
- package/lib/push-service.js +21 -69
- package/lib/routes.js +140 -19
- package/lib/server.js +19 -23
- package/lib/session-manager.js +1 -1
- package/lib/startup-checks.js +1 -0
- package/lib/store.js +15 -3
- package/lib/title-service.js +3 -19
- package/package.json +3 -2
- package/dist/js/app.GSAIYHML.js +0 -4
- package/dist/js/chunk.CGWFHJI2.js +0 -76
- package/dist/js/viewer.6DT53STL.js +0 -1
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
|
|
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.
|
|
71
|
-
|
|
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.
|
|
28
|
-
<link rel="modulepreload" href="/js/chunk.
|
|
29
|
-
<link rel="modulepreload" href="/js/chunk.
|
|
27
|
+
<link rel="stylesheet" href="/styles.01ky3cex.css" />
|
|
28
|
+
<link rel="modulepreload" href="/js/chunk.ON2W5X2T.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.
|
|
68
|
+
<script type="module" src="/js/app.HJKQURHR.js"></script>
|
|
69
69
|
</body>
|
|
70
70
|
</html>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{a as Ot,b as D,c as qt,d as Bt,e as be,f as Dt,g as $,h as Ft,i as R,j as J,k as Ut,l as k,m as Se,n as Je,o as Ye,p as Vt,q as Qe}from"./chunk.ON2W5X2T.js";import{a as B}from"./chunk.D4ZYHJAM.js";import"./chunk.AJZBJBMO.js";var ke=null;function ys(e){location.replace(e)}function vs(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 ws(e){return typeof e=="string"?e:e instanceof URL?e.toString():e.url}function jt(e={}){let t=e.baseFetch??globalThis.fetch.bind(globalThis),s=e.onUnauthorized??ys;ke??=globalThis.fetch;let r=async(o,a)=>{let c=ws(o),u=vs(c),d=a;if(u){let m=localStorage.getItem(B);if(m){let p=a?.headers??(o instanceof Request?o.headers:void 0),g=new Headers(p);g.has("Authorization")||g.set("Authorization",`Bearer ${m}`),d={...a??{},headers:g}}}let f=await t(o,d);if(u&&f.status===401){try{localStorage.removeItem(B)}catch{}s("/login")}return f};return globalThis.fetch=r,bs}function bs(){ke&&(globalThis.fetch=ke,ke=null)}var Ss=new Set(["plan","read-only"]),ks=new Set(["autopilot","bypassPermissions","full-access","yolo"]),Ts=new Set(["agent","default","build"]);function Te(e){if(!e)return"";let t=e.match(/[#/]([^#/]+)$/);return t?t[1]:e}function Wt(e){return Ss.has(Te(e))}function Kt(e){return ks.has(Te(e))}function Gt(e){let t=Te(e);return t?!Ts.has(t):!1}function zt(e){return Te(e).replace(/([A-Z])/g," $1").trim()}var Xe=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 o=`HTTP ${s.status}`;try{let a=await s.json();a.error&&(o=typeof a.error=="string"?a.error:JSON.stringify(a.error))}catch{}throw new Xe(s.status,o)}let r=await s.text();if(r)return JSON.parse(r)}function A(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 Ie(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"op-"+Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,10)}function Ee(e){let t={};return e?.cwd&&(t.cwd=e.cwd),e?.inheritFromSessionId&&(t.inheritFromSessionId=e.inheritFromSessionId),A("/api/v1/sessions",t)}function re(e){return C("/api/v1/sessions/"+e,{method:"DELETE"})}function xe(){return C("/api/v1/sessions")}function P(e){return C("/api/v1/sessions/"+e)}function Jt(e){return C("/api/v1/sessions/"+e+"/snapshot")}function Ze(e,t,s){let r={text:t};return s?.length&&(r.attachments=s),A("/api/v1/sessions/"+e+"/prompt",r,Ie())}function Yt(e){return A("/api/v1/sessions/"+e+"/cancel",{},Ie())}function Qt(e,t,s){return A("/api/v1/sessions/"+e+"/permissions/"+t,{optionId:s},Ie())}function Xt(e,t){return A("/api/v1/sessions/"+e+"/permissions/"+t,{denied:!0},Ie())}function oe(e,t,s){let r=t.replace(/_/g,"-"),o=typeof s=="boolean"?"config/"+r:r;return C("/api/v1/sessions/"+e+"/"+o,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:s})})}function Le(e,t){return C("/api/v1/sessions/"+e+"/title",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:t})})}function Zt(e,t){return A("/api/v1/sessions/"+e+"/bash",{command:t})}function ie(e,t,s){let r={visible:t};return s&&(r.sessionId=s),A("/api/beta/clients/"+e+"/visibility",r)}function Ce(){return A("/api/v1/bridge/reload",{})}function en(){return A("/api/v1/sse-ticket",{})}function fe(){return C("/api/v1/messages")}function tn(e){return A(`/api/v1/messages/${encodeURIComponent(e)}/consume`,{})}function Ae(e){return C(`/api/v1/messages/${encodeURIComponent(e)}`,{method:"DELETE"})}function Pe(){return C("/api/v1/tokens")}function Me(e){return A("/api/v1/tokens",{name:e})}function $e(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 _(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},Is={disconnected:"is-disconnected",connecting:"is-connecting",connected:"is-connected"};function Z(e,t=e){l.status.textContent="",l.status.className=`status-dot ${Is[e]}`,l.status.dataset.state=e,l.status.setAttribute("aria-label",t),l.status.setAttribute("title",t)}function et(e){return n.configOptions.find(t=>t.id===e)}function F(e){let t=et(e);return t&&"options"in t?t:null}function tt(e){return et(e)?.currentValue??null}function nn(e){let t=tt(e);return typeof t=="string"?t:null}function sn(e,t){let s=et(e);s&&("options"in s&&typeof t=="string"||s.type==="boolean"&&typeof t=="boolean")&&(s.currentValue=t)}function nt(e){n.configOptions=e,e.length>0&&rn(),T(),N()}function Es(e){n.configOptions.length>0||(n.sessionMode=e.session.mode??null,n.sessionModel=e.session.model??null)}function rn(){n.sessionMode=null,n.sessionModel=null}function on(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",ae();return}l.input.placeholder="Message or ?";let e=nn("mode")||on("mode")||"";Wt(e)?l.inputArea.classList.add("plan-mode"):Kt(e)&&l.inputArea.classList.add("autopilot-mode"),l.modePill.textContent=Gt(e)?zt(e):"",ae()}function N(){let e=nn("model")||on("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 xs(e){n.lastStateSeq=e.seq;let t=e.runtime.busy;v(t!=null),t==null&&le(),Es(e),T(),N()}function an(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;v(s!=null),s==null&&le()}return!0}async function H(e){let t=n.sessionSwitchGen;try{let s=await Jt(e);return n.sessionSwitchGen!==t?null:(xs(s),s)}catch{return null}}function v(e){n.busy=e,e?l.prompt.classList.add("busy"):l.prompt.classList.remove("busy"),ae()}function U({cwd:e,inheritFromSessionId:t=n.sessionId}={}){n.awaitingNewSession=!0,Ee({cwd:e,inheritFromSessionId:t}).catch(()=>{})}var ln=[];function cn(e){ln.push(e)}var un=()=>{};function dn(e){un=e}function ae(){un()}function w(){for(let e of ln)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(),v(!1),n.sessionTitle=null,n.sessionCwd=null,n.configOptions=[],rn(),Re(null,null),l.statusBar.textContent=""}function O(){return!n.busy||!n.sessionId?!1:(Yt(n.sessionId).catch(()=>{}),!0)}function le(){n._cancelTimerId!=null&&(clearTimeout(n._cancelTimerId),n._cancelTimerId=null)}function fn(){return location.hash.slice(1)||null}function st(e){history.replaceState(null,"",`#${e}`)}function Re(e,t){l.sessionInfo.textContent=t??(e?e.slice(0,8)+"\u2026":""),document.title=t??">_"}Z("disconnected");function Ne(e,t){let s=document.createElement("div");return s.className=`msg ${e}`,e==="user"?s.innerHTML=$(t).replace(/\n/g,"<br>"):R(s,t),S(s),s}function i(e){let t=document.createElement("div");return t.className="system-msg",t.textContent=e,S(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"),D(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 ee=null,Ls=80;function pe(e){return e.scrollHeight-e.scrollTop-e.clientHeight<Ls}function Cs(){n.followMessages=pe(l.messages)}l.messages.addEventListener("scroll",Cs);function pn(){return n.followMessages||pe(l.messages)}function S(e,t=!1){if(n.replayTarget)return n.replayTarget.appendChild(e),e;let s=t||pn();return l.messages.appendChild(e),b(s),e}function mn(){j(),ee=document.createElement("div"),ee.id="waiting",ee.innerHTML='<span class="cursor">\u258C</span>',S(ee,!0)}function j(){ee&&(ee.remove(),ee=null)}var rt=!1,_e=!1;function ot(e){let t=l.messages;if(e||n.followMessages){t.clientHeight,t.scrollTop=t.scrollHeight,n.followMessages=!0;return}n.followMessages=pe(t)}function As(e){if(!(e||n.followMessages)){n.followMessages=pe(l.messages);return}ot(!0),!(typeof requestAnimationFrame!="function"||_e)&&(_e=!0,requestAnimationFrame(()=>{if(!n.followMessages){_e=!1;return}ot(!0),requestAnimationFrame(()=>{_e=!1,n.followMessages&&ot(!0)})}))}function gn(e){let t=pn();e(),t&&As(!0)}function b(e){let t=l.messages;if(e||n.followMessages){typeof requestAnimationFrame=="function"?rt||(rt=!0,requestAnimationFrame(()=>{rt=!1,t.scrollTop=t.scrollHeight})):t.scrollTop=t.scrollHeight,n.followMessages=!0;return}n.followMessages=pe(t)}function x(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 hn(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")}),S(s),t&&(n.currentBashEl=s),s}function He(e,t,s){if(!e)return;let r=e.querySelector(".bash-cmd");r.classList.remove("running");let o="";if(s?o=`[signal: ${s}]`:t!==0&&t!=null&&(o=`[exit: ${t}]`),o){let a=document.createElement("span");a.className=`bash-exit ${t===0?"ok":"fail"}`,a.textContent=o,r.after(a)}e===n.currentBashEl&&(n.currentBashEl=null)}function it(e,t){let s=e.replace(/^\s+/,"");if(s==="")return{node:t,pathPrefix:"",tailQuery:""};let r=/\s$/.test(s),o=s.split(/\s+/).filter(g=>g.length>0),a=r?o:o.slice(0,-1),c=r?"":o[o.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 yn(e,t,s){let r=[],o=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(o&&!h.name.toLowerCase().includes(o))continue;let hs=(h.children?.length??0)>0||h.fetch||h.freeform;a.push({spec:{primary:h.name,secondary:h.desc},prefix:hs?"\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=(o?s.filter(y=>e.matches?e.matches(y,o):e.toSpec(y).primary.toLowerCase().includes(o)):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 vn(e,t,s){let r=document.createElement("div");r.className="slash-item"+(t?" selected":"");let o=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),o){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 lt={debug:0,info:1,warn:2,error:3,off:99},me=new Set(["off","debug","info","warn","error"]),wn=4096;function bn(e){try{let t=new WeakSet,s=JSON.stringify(e,(r,o)=>{if(o instanceof Error)return{name:o.name,message:o.message,stack:o.stack};if(typeof o=="function")return`[Function ${o.name??"anonymous"}]`;if(typeof o=="bigint")return o.toString()+"n";if(typeof o=="symbol")return o.toString();if(typeof o=="object"&&o!==null){if(t.has(o))return"[Circular]";t.add(o)}return o});return typeof s!="string"?String(e):s.length>wn?s.slice(0,wn)+`\u2026(truncated, ${s.length} bytes)`:s}catch{try{return String(e)}catch{return"[unserializable]"}}}function at(e){return e<10?"0"+e:String(e)}function Ps(e){return e<10?"00"+e:e<100?"0"+e:String(e)}function Sn(e){let t=new Date(e);return`${at(t.getHours())}:${at(t.getMinutes())}:${at(t.getSeconds())}.${Ps(t.getMilliseconds())}`}var ut="off",kn="default",Tn,ct=null;function Oe(e,t="runtime"){me.has(e)&&(ut=e,kn=t)}function dt(){return ut}function In(){return kn}function qe(e){Tn=e;let t=Ln(e);Oe(t.level,t.source)}function En(e){ct=e}function xn(e){try{let s=new URL(e).searchParams.get("debug");return s===null||!me.has(s)?null:s}catch{return null}}function Ms(){return typeof location>"u"?null:xn(location.href)}function $s(){if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(Se);return!e||!me.has(e)?null:e}catch{return null}}function Ln(e,t=typeof location>"u"?null:location.href){let s=t?xn(t):null;if(s)return{level:s,source:"url"};let r=$s();return r?{level:r,source:"local"}:e&&me.has(e)?{level:e,source:"config"}:{level:"off",source:"default"}}function Cn(e){typeof localStorage<"u"&&localStorage.setItem(Se,e);let t={level:e,source:"local"};return Oe(e,"local"),t}function An(){typeof localStorage<"u"&&localStorage.removeItem(Se);let e=Ln(Tn);return Oe(e.level,e.source),e}function Pn(e){let t=(s,r,o)=>{if(lt[s]<lt[ut])return;let a=e?`[${e}] `:"";try{let c=console[s];o!==void 0?c(a+r,o):c(a+r)}catch{}if(ct)try{let c=Sn(Date.now()),u=e?` [${e}]`:"",d=o!==void 0?" "+bn(o):"";ct(`${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=>Pn(e?`${e}.${s}`:s)}}var E=Pn();{let e=Ms();e&&Oe(e)}if(typeof window<"u"){let e=E.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 xe();if(s!==n.sessionSwitchGen)return;let o=r.find(a=>a.id!==e);if(o){w(),n.sessionId=null,st(o.id);let[a,c]=await Promise.all([P(o.id),K(o.id)]);if(s!==n.sessionSwitchGen)return;L({type:"session_created",sessionId:a.id,cwd:a.cwd,title:a.title,configOptions:a.configOptions}),c&&b(!0);return}}catch{}s===n.sessionSwitchGen&&(w(),n.sessionId=null,U({cwd:t??void 0}))}function pt(e){return n.replayTarget?.querySelector(`[id="${e}"]`)??document.getElementById(e)}function Rs(e){return n.replayTarget?.querySelector(e)??document.querySelector(e)}function Rn(e){e.querySelectorAll(".plan[open]").forEach(t=>{t.open=!1})}function Mn(e){(typeof navigator<"u"?navigator.serviceWorker:void 0)?.controller?.postMessage({type:"close-notification",tag:e})}function _s(){if(typeof Notification>"u"||n.replayInProgress)return;let e=Notification.permission;if(e!=="granted"){if(e==="denied"){if(localStorage.getItem(Ye))return;localStorage.setItem(Ye,"1"),i("tip: notifications are blocked \u2014 allow in browser site settings to enable");return}localStorage.getItem(Je)||(localStorage.setItem(Je,"1"),i("tip: use /notify to enable background notifications"))}}function Be(){Dt(n.pendingPromptDone,n.pendingToolCallIds.size,n.pendingPermissionRequestIds.size)&&(j(),M(),V(),v(!1),n.pendingPromptDone=!1,_s())}function Ns(){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 _n=200;async function K(e){Hn(),n.replayInProgress=!0,n.replayQueue=[];try{let t=await fetch(`/api/v1/sessions/${e}/events?limit=${_n}`);if(!t.ok)return!1;let s=await t.json(),{events:r,streaming:o,hasMore:a}=be(s),c=document.createDocumentFragment(),u=wt(r);n.replayTarget=c;for(let d=0;d<r.length;d++){let f=JSON.parse(r[d].data);bt(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&&js(),Nn(),mt(r,o),!0}catch{return!1}finally{n.replayTarget=null,n.replayInProgress=!1,Vn()}}function mt(e,t){if(n.assistantRafToken!=null&&E.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 o=l.messages.querySelectorAll(".thinking");s=o[o.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 o=l.messages.querySelectorAll(".msg.assistant");s=o[o.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 Nn(){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 ft=new Map;function ht(e){let t=ft.get(e);if(t)return t;let s=Os(e);return ft.set(e,s),s.finally(()=>{ft.delete(e)}).catch(()=>{}),s}async function Os(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:o,streaming:a}=be(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),D(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,o.length===0)return mt(o,a),!0;let u=document.createDocumentFragment(),d=wt(o);n.replayTarget=u;for(let p=0;p<o.length;p++){let g=JSON.parse(o[p].data);bt(o[p].type,g,o,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),D(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=o[o.length-1].seq,Nn(),mt(o,a),!0}catch{return!1}finally{n.replayTarget=null,n.replayInProgress=!1,Vn()}}var ne=null,yt=0;function Hn(){yt++}function Fe(e,t){return t===yt&&n.sessionId===e}function De(){return typeof requestAnimationFrame!="function"?Promise.resolve():new Promise(e=>requestAnimationFrame(()=>{e()}))}function On(e){let t=e.getBoundingClientRect();for(let r of Array.from(e.children)){if(!(r instanceof HTMLElement)||r.id==="history-sentinel"||r.id==="history-loading")continue;let o=r.getBoundingClientRect();if(o.bottom>=t.top&&o.top<=t.bottom)return{el:r,top:o.top}}let s=Array.from(e.children).find(r=>r instanceof HTMLElement&&r.id!=="history-sentinel"&&r.id!=="history-loading");return s?{el:s,top:s.getBoundingClientRect().top}:null}function qn(e,t){if(!t?.el.isConnected)return 0;let s=Bn(t);return s!==0&&(e.scrollTop+=s),s}function Bn(e){return e?.el.isConnected?e.el.getBoundingClientRect().top-e.top:0}function qs(e,t){let s=Math.abs(t);return s<=4||s>e.clientHeight}function Dn(e,t){let s=On(e);return t(),qn(e,s)}async function Bs(e){if(!(e.scrollTop>=0)){for(let t=1;t<=20;t++)if(await De(),e.scrollTop>=0){await De();return}e.scrollTop=0,await De()}}async function Ds(e,t){for(let s=1;s<=8;s++){await De();let r=Bn(t);if(r!==0){if(!qs(e,r))return;e.scrollTop+=r}}}function Ve(){ne&&(ne.disconnect(),ne=null)}function vt(){let e=document.getElementById("history-sentinel");!e||typeof IntersectionObserver!="function"||(Ve(),ne=new IntersectionObserver(t=>{t[0].isIntersecting&&!n.loadingOlderEvents&&n.hasMoreHistory&&n.sessionId&&Ks(n.sessionId)},{root:l.messages,rootMargin:"200px 0px 0px 0px"}),ne.observe(e))}function Fs(){let e=document.getElementById("history-sentinel");!e||typeof IntersectionObserver!="function"||(Ve(),ne=new IntersectionObserver(t=>{t[0].isIntersecting||vt()},{root:l.messages,rootMargin:"200px 0px 0px 0px"}),ne.observe(e))}function Us(e=l.messages){document.getElementById("history-loading")||Dn(e,()=>{let t=document.createElement("div");t.id="history-loading",t.className="history-loading",t.setAttribute("role","status"),t.textContent="\u2191 loading\u2026";let s=document.getElementById("history-sentinel");s?s.after(t):e.prepend(t)})}function gt(e=l.messages){let t=document.getElementById("history-loading");t&&Dn(e,()=>{t.remove()})}function Vs(e,t){!n.hasMoreHistory||n.sessionId!==e||(t?vt():Fs())}function js(){Ue();let e=document.createElement("div");e.id="history-sentinel",e.className="history-sentinel",e.setAttribute("aria-hidden","true"),l.messages.prepend(e),vt()}function Ue({invalidateLoads:e=!0}={}){e&&Hn(),Ve(),gt(),document.getElementById("history-sentinel")?.remove()}async function Ws(e,t){let s=await fetch(`/api/v1/sessions/${e}/events?limit=${_n}&before=${n.oldestLoadedSeq}`);if(!Fe(e,t)||!s.ok)return null;let r=await s.json();if(!Fe(e,t))return null;let{events:o,hasMore:a}=be(r);return{events:o,hasMore:a}}cn(Ue);async function Ks(e){if(n.loadingOlderEvents||!n.hasMoreHistory||n.oldestLoadedSeq<=0)return!1;n.loadingOlderEvents=!0;let t=++yt;Ve();let s=l.messages,r=!1;Us(s);try{let o=await Ws(e,t);if(!o)return!1;let{events:a,hasMore:c}=o;if(await Bs(s),!Fe(e,t))return!1;if(a.length===0)return n.hasMoreHistory=!1,Ue({invalidateLoads:!1}),!0;let u=document.createDocumentFragment(),d=wt(a);n.replayTarget=u;for(let p=0;p<a.length;p++){let g=JSON.parse(a[p].data);bt(a[p].type,g,a,p,d)}n.replayTarget=null;let f=On(s);gt(s);let m=document.getElementById("history-sentinel");return m?m.after(u):s.prepend(u),qn(s,f),n.oldestLoadedSeq=a[0].seq,n.hasMoreHistory=c===!0,n.hasMoreHistory||Ue({invalidateLoads:!1}),await Ds(s,f),r=!0,!0}catch{return!1}finally{Fe(e,t)&&(gt(s),n.loadingOlderEvents=!1,Vs(e,r))}}function wt(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 Fn(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 o=t.querySelector(".message-content");o&&R(o,e.body),S(t),o&&D(o)}function bt(e,t,s,r,o){let a=t;if(Ut(e)){zs(e,a,s,r,o);return}switch(e){case"prompt_done":n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,v(!1);break;case"message":Fn(a);break}}function te(){return{findToolCallEl:e=>document.getElementById(`tc-${e}`),findPermissionEl:e=>document.querySelector(`.permission[data-request-id="${e}"]`),findBashEl:()=>n.currentBashEl,enhanceMarkdown:D}}function Gs(e,t,s){return{findToolCallEl:r=>e?e.toolCalls.get(r)??null:pt(`tc-${r}`),findPermissionEl:r=>e?e.permissions.get(r)??null:Rs(`.permission[data-request-id="${r}"]`),findBashEl:()=>e?e.currentBashEl:pt("bash-replay-pending"),isPermissionResolved:r=>e?e.resolvedPermissions.has(r):t.slice(s+1).some(o=>{let a=JSON.parse(o.data);return o.type==="permission_response"&&a.requestId===r}),enhanceMarkdown:D}}function Un(e,t,s,r){e.querySelectorAll("button").forEach(a=>{let c=a.dataset.optionId??"",u=a.dataset.optionKind??"",d=a.textContent||"";a.onclick=()=>{Bt(u).apiAction==="deny"?Xt(n.sessionId,t).catch(()=>{}):Qt(n.sessionId,t,c).catch(()=>{}),e.innerHTML=`<span class="dim">\u26BF ${$(s)} \u2014 ${$(d)}</span>`,r?.()}})}function zs(e,t,s,r,o){let a=Gs(o,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),D(u);break}let f=k(e,t,a);f&&S(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&&S(f);break}case"tool_call":{let c=k(e,t,a);c&&(S(c),o&&o.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)||Un(d,c,u),S(d),o&&o.permissions.set(c,d));break}case"bash_command":{let c=k(e,t,a);c&&(o?o.currentBashEl=c:c.id="bash-replay-pending",S(c));break}case"bash_result":{let c=o?o.currentBashEl:pt("bash-replay-pending");c&&!o&&c.removeAttribute("id"),k(e,t,a),o&&(o.currentBashEl=null);break}case"user_message":case"plan":case"permission_response":{let c=k(e,t,a);c&&(e==="plan"&&Rn(n.replayTarget??l.messages),S(c));break}}}function Vn(){let e=n.replayQueue;n.replayQueue=[];for(let t of e)Js(t)||L(t)}function Js(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 $n(){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=Ft(),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?E.warn("md-render budget",u):E.debug("md-render slow",u)}b();let o=performance.now();try{performance.measure("doAssistantRender",{start:t,end:o}),performance.measure("scrollToBottom",{start:s,end:o})}catch{}}function Ys(){if(n.assistantRafToken==null){if(typeof requestAnimationFrame!="function"){$n();return}n.assistantRafToken=requestAnimationFrame(()=>{n.assistantRafToken=null,$n()})}}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,o=s&&r?`${s} ${r}`:"Agent";i(`${o} reloaded.`),v(!1)}break;case"state_patch":{!an({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&&nt(e.configOptions),T(),N(),st(n.sessionId),n.clientId&&ie(n.clientId,!document.hidden,n.sessionId).catch(()=>{}),Re(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&&i(`Session created: ${n.sessionTitle??e.sessionId.slice(0,8)+"\u2026"}`),N();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,te());s&&S(s)}break}case"message_chunk":if(n.turnEnded)break;j(),M(),n.currentAssistantEl||(n.currentAssistantEl=Ne("assistant",""),n.currentAssistantText=""),n.currentAssistantText+=e.text,Ys();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="",S(n.currentThinkingEl)),n.currentThinkingText+=e.text,n.currentThinkingEl.querySelector(".thinking-content").textContent=n.currentThinkingText,b();break;case"tool_call":{if(n.turnEnded)break;n.pendingToolCallIds.add(e.id),v(!0),j(),M(),V();let s=k("tool_call",e,te());s&&S(s);break}case"tool_call_update":{(e.status==="completed"||e.status==="failed")&&n.pendingToolCallIds.delete(e.id),k("tool_call_update",e,te()),Be(),b();break}case"plan":{M(),V();let s=k("plan",e,te());s&&(Rn(l.messages),S(s));break}case"permission_request":{if(n.turnEnded||document.querySelector(`.permission[data-request-id="${e.requestId}"]`))break;n.pendingPermissionRequestIds.add(e.requestId),v(!0),M();let s=k("permission_request",e,te());if(s){let r=e.requestId;Un(s,r,e.title,()=>{n.pendingPermissionRequestIds.delete(r),Be()}),S(s)}break}case"permission_response":{n.pendingPermissionRequestIds.delete(e.requestId),e.sessionId===n.sessionId&&k("permission_response",e,te()),Be();break}case"bash_command":{if(n.sentBashForSession===e.sessionId){n.sentBashForSession=null;break}if(e.sessionId===n.sessionId){let s=k("bash_command",e,te());s&&(s.querySelector(".bash-cmd").classList.add("running"),S(s),n.currentBashEl=s),v(!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,b()}break}case"bash_done":{if(e.sessionId!==n.sessionId)break;He(n.currentBashEl,e.code,e.signal),e.error&&i(`err: ${e.error}`),v(!1);break}case"prompt_done":{if(le(),e.stopReason==="cancelled"&&n.newTurnStarted){n.newTurnStarted=!1,M(),V();break}n.newTurnStarted=!1,e.stopReason==="cancelled"?Ns():Hs(),n.turnEnded=!0,n.pendingPromptDone=!0,Be();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":{sn(e.configId,e.value);let s=F(e.configId),r=s?.name??e.configId,o=typeof e.value=="string"?s?.options.find(a=>a.value===e.value)?.name??e.value:String(e.value);i(`ok: ${r}: ${o}`),e.configId==="mode"&&T(),N();break}case"config_option_update":e.configOptions.length&&nt(e.configOptions);break;case"session_title_updated":e.sessionId===n.sessionId&&(n.sessionTitle=e.title,Re(n.sessionId,n.sessionTitle));break;case"agent_reloading":n.agentReloading=!0,i("Agent reloading\u2026"),v(!0);break;case"agent_reloading_failed":i(`err: Agent reload failed: ${e.error}`),v(!1);break;case"error":n.awaitingNewSession=!1,n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,j(),M(),V(),i(`err: ${e.message}`),v(!1);break;case"message_created":i(`inbox: new message ${e.messageId} \u2014 /inbox to view`);break;case"message_consumed":i(`inbox: ${e.messageId} consumed \u2192 session ${e.sessionId}`),Mn(`msg-${e.messageId}`);break;case"message_acked":i(`inbox: ${e.messageId} dismissed`),Mn(`msg-${e.messageId}`);break;case"message":e.sessionId===n.sessionId&&(Fn(e),b());break;default:break}}async function ge({cwd:e,showCwd:t=!1}={}){if(!n.sessionId){i("warn: No active session");return}let s=n.sessionId,r=e??n.sessionCwd??void 0;n.busy&&O(),w(),i(t&&r?`Clearing session and starting at ${r}\u2026`:"Clearing session\u2026"),n.awaitingNewSession=!0;try{await Ee({cwd:r,inheritFromSessionId:s})}catch{n.awaitingNewSession=!1,i("err: Failed to clear session");return}re(s).catch(()=>{})}var he=E.scope("share");function Qs(e,t){return e.startsWith("http")?e:e?`${location.origin}${e}`:`${location.origin}/s/${t}`}async function je(){if(!n.sessionId){i("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 o=await t.text();t.status===409?i("share: session busy (agent streaming) \u2014 retry after the response completes"):t.status===403?i("share: forbidden (not owner)"):t.status===400&&o.includes("sanitize")?i(`share: \u2717 sanitize blocked this session \u2014 ${o}`):i(`share: create failed ${t.status} \u2014 ${o.slice(0,200)}`);return}let s=await t.json();n.previewToken=s.token,T();let r=s.reused?"reused":"ready";i(`share: preview ${r} \u2014 ^P publish \xB7 ^C cancel`)}catch(t){he.error("preview create error",{err:t}),i(`share: network error \u2014 ${String(t)}`)}}async function St(){if(!n.sessionId){i("share: no active session");return}if(!n.previewToken){i("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?i("share: forbidden (not owner)"):s.status===404?i("share: token not found (already revoked?)"):i(`share: publish failed ${s.status} \u2014 ${u.slice(0,200)}`);return}let r=await s.json(),o=Qs(r.public_url,r.token);n.previewToken=null,T();let a=i(`share: published
|
|
4
|
+
`),c=document.createElement("a");c.href=o,c.textContent=o,c.target="_blank",c.rel="noopener noreferrer",a.appendChild(c)}catch(s){he.error("publish error",{err:s}),i(`share: network error \u2014 ${String(s)}`)}}function kt(){if(!n.previewToken){i("share: no preview active");return}n.previewToken=null,T(),i("share: preview canceled")}async function Tt(){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 We(e){if(!e){i("share: usage \u2014 /share revoke <token>");return}try{let s=(await Xs()).find(a=>a.token===e);if(!s){i("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?i("share: forbidden (not owner)"):r.status===404?i(`share: ${e} already revoked`):i(`share: revoke failed ${r.status}`);return}let o=await r.json();i(o.revoked?`share: revoked ${e}`:`share: ${e} already revoked`)}catch(t){he.error("revoke error",{err:t}),i(`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 ye(e){let t=`${location.origin}/s/${e}`;window.open(t,"_blank","noopener"),i(`share: opened ${t}`)}async function jn(){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 ve(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();i(`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){he.warn("by: preview patch failed",{err:r})}i(s.value?`share: author set to '${s.value}'`:"share: author cleared (publish anonymously)")}catch(t){he.error("by error",{err:t}),i(`share: network error \u2014 ${String(t)}`)}}var ce=!1;async function Jn(){try{ce=await(await navigator.serviceWorker.ready).pushManager.getSubscription()!==null}catch{ce=!1}}function Zs(e){let t="=".repeat((4-e.length%4)%4),s=(e+t).replace(/-/g,"+").replace(/_/g,"/"),r=atob(s),o=new Uint8Array(r.length);for(let a=0;a<r.length;a++)o[a]=r.charCodeAt(a);return o}async function er(){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(),o=(await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:Zs(s)})).toJSON();await fetch("/api/beta/push/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:o.endpoint,keys:o.keys,clientId:n.clientId})})}catch(e){E.scope("push").error("subscribe failed",{err:e})}}async function tr(){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){E.scope("push").error("unsubscribe failed",{err:e})}}async function nr(){return(await fetch("/api/v1/sessions")).json()}async function Wn(){let e=n.recentPathsLimit,t=e>0?`/api/v1/recent-paths?limit=${e}`:"/api/v1/recent-paths";return(await(await fetch(t)).json()).map(o=>({cwd:o.cwd,time:o.last_used_at}))}var Kn=async()=>{let{messages:e}=await fe();return e},Gn=async()=>Pe();function Et(){return`log: ${dt()} (${In()})`}function Yn(){i(`${Et()} \u2014 use /log <off|debug|info|warn|error|reset>`)}function xt(e){Cn(e),i(`${Et()} saved`),e!=="off"&&E.info("log enabled",{level:e})}function Lt(){An(),i(`${Et()} reset`)}async function Ct(){i("Resetting local state\u2026");let e=await Vt();e.errors.length&&i(`warn: reset had issues: ${e.errors.join("; ")}`),location.reload()}async function Qn(e){n.sessionSwitchGen++;let t=n.sessionSwitchGen;w(),n.sessionId=null;try{let[s,r]=await Promise.all([P(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&&b(!0)}catch{w(),n.sessionId=null,i("err: Failed to switch session")}}async function sr(e,t,s){let r=F(e);r&&(r.currentValue=t),T(),N(),i(`${r?.name??e} \u2192 ${s}`),n.sessionId&&await oe(n.sessionId,e,t).catch(()=>{})}async function At(e){try{let t=await tn(e.id);t.alreadyConsumed?i(`inbox: already consumed \u2192 switching to ${t.sessionId}`):i(`inbox: opened as ${t.sessionId}`),await Qn(t.sessionId)}catch(t){i(`err: consume failed (${t.message})`)}}async function rr(e){try{await Ae(e.id),i(`inbox: ack ${e.id}`)}catch(t){i(`err: ack failed (${t.message})`)}}async function or(e){if(!/^[A-Za-z0-9_-]{1,64}$/.test(e)){i("err: token name must match [A-Za-z0-9_-]{1,64}");return}try{let t=await Me(e);i(`token: created ${t.name} (${t.scope})`),i(`${t.token}`),i("\u2014 save this now; it will never be shown again")}catch(t){let s=t;s.status===409?i(`err: token "${e}" already exists`):s.status===403?i("err: admin scope required to manage tokens"):i(`err: create failed (${s.message})`)}}async function ir(e){try{await $e(e),i(`token: revoked ${e}`)}catch(t){let s=t;s.status===404?i(`err: no token named "${e}"`):s.status===403?i("err: admin scope required to manage tokens"):s.status===400&&/using|yourself|cannot/i.test(s.message)?i("err: can't revoke the token you're signed in with \u2014 use another admin token"):i(`err: revoke failed (${s.message})`)}}async function ar(){if(typeof Notification>"u"){i("err: notifications not supported in this browser");return}if(Notification.permission==="denied"){i("notify: blocked \u2014 allow in browser site settings to enable");return}if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted"){i("notify: blocked \u2014 allow in browser site settings to enable");return}await Jn();let e=ce;await er(),ce=!0,i(e?"notify: already enabled":"notify: enabled")}async function lr(){await tr(),ce=!1,i("notify: disabled")}function zn(e,t){let s=e.shared_at?x(e.shared_at):"\u2014";return{primary:e.token,secondary:e.session_title??void 0,path:`/s/${e.token}`,pathSecondary:s,onSelect:()=>{t==="open"?ye(e.token):We(e.token)}}}var Q={name:"<root>",children:[{name:"/cancel",desc:"Cancel current response",onSelect:()=>{n.busy?(O(),i("^C")):i("Nothing to cancel.")}},{name:"/clear",desc:"Clear current session",fetch:Wn,toSpec:e=>{let t=e,s=t.cwd.toLowerCase()===(n.sessionCwd??"").toLowerCase();return{primary:t.cwd,current:s,onSelect:()=>{ge({cwd:t.cwd,showCwd:!0})}}},freeform:e=>{let t=e.trim();return t?{primary:`clear and start at '${t}'`,onSelect:()=>{ge({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===dt(),onSelect:()=>{if(t.value==="reset"){Lt();return}xt(t.value)}}}},{name:"/reset",desc:"Reset local state",onSelect:()=>{Ct()}},{name:"/exit",desc:"End current session",onSelect:async()=>{if(!n.sessionId){i("warn: No active session");return}let e=n.sessionId;try{n.busy&&O(),re(e).catch(()=>{}),await W(e,n.sessionCwd??void 0)}catch{i("err: Failed to exit session")}}},{name:"/help",desc:"Show help",onSelect:()=>{cr()}},{name:"/inbox",desc:"Manage inbox",fetch:Kn,toSpec:e=>{let t=e,s=t.from_label??t.from_ref,r=x(t.created_at);return{primary:t.title,secondary:r,path:t.cwd??"",pathSecondary:s,onSelect:()=>At(t)}},children:[{name:"dismiss",desc:"Dismiss only",fetch:Kn,toSpec:e=>{let t=e,s=t.from_label??t.from_ref,r=x(t.created_at);return{primary:t.title,secondary:r,path:t.cwd??"",pathSecondary:s,onSelect:()=>rr(t)}}}]},{name:"/logout",desc:"Log out",onSelect:()=>{try{localStorage.removeItem(B)}catch{}try{n.eventSource?.close()}catch{}i("Logged out."),location.replace("/login")}},It("/mode","Switch mode","mode"),It("/model","Switch model","model"),{name:"/new",desc:"Create new session",fetch:Wn,toSpec:e=>{let t=e,s=t.cwd.toLowerCase()===(n.sessionCwd??"").toLowerCase();return{primary:t.cwd,current:s,onSelect:()=>{w(),i("Creating new session\u2026"),U({cwd:t.cwd})}}},freeform:e=>{let t=e.trim();return t?{primary:`create session at '${t}'`,onSelect:()=>{w(),i("Creating new session\u2026"),U({cwd:t})}}:null}},{name:"/notify",desc:"Toggle notifications",fetch:async()=>(await Jn(),[{value:"on",name:"on",desc:"Enable notifications"},{value:"off",name:"off",desc:"Disable notifications"}]),toSpec:e=>{let t=e,s=t.value==="on"===ce;return{primary:t.name,secondary:t.desc,current:s,onSelect:t.value==="on"?ar:lr}}},{name:"/reload",desc:"Reload agent",onSelect:()=>{i("Reloading agent\u2026"),Ce().catch(e=>{i(`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){i("err: No active session");return}try{await Le(n.sessionId,t),i(`Renamed \u2192 ${t}`)}catch{i("err: Failed to rename session")}}}:null}},{name:"/share",desc:"Share a read-only snapshot",fetch:Tt,toSpec:e=>zn(e,"open"),freeform:e=>{let t=e.trim();return t?{primary:`open share '${t}'`,onSelect:()=>{ye(t)}}:{primary:"create new share preview",onSelect:()=>je()}},children:[{name:"by",desc:"Set author",fetch:async()=>[{value:await jn()}],toSpec:e=>{let t=e.value;return{primary:t??"(none)",secondary:t?"current \u2014 Enter to clear":"currently anonymous",onSelect:()=>ve(null)}},freeform:e=>{let t=e.trim();return t?{primary:`set author to '${t}'`,onSelect:()=>ve(t)}:null}},{name:"revoke",desc:"Revoke a share",fetch:Tt,toSpec:e=>zn(e,"revoke")}]},{name:"/switch",desc:"Switch session",fetch:nr,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=x(t.last_active_at);return{primary:s,secondary:r,path:t.cwd,current:t.id===n.sessionId,onSelect:()=>Qn(t.id)}}},It("/think","Set thinking effort","reasoning_effort"),{name:"/token",desc:"Manage API tokens",fetch:Gn,toSpec:e=>{let t=e,s=t.lastUsedAt?x(t.lastUsedAt):"never";return{primary:t.name,secondary:`last used ${s}`,path:`${t.scope} \xB7 created ${x(t.createdAt)}`,current:t.isSelf,onSelect:t.isSelf?void 0:()=>{i(`\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:()=>or(t)}:null},children:[{name:"revoke",desc:"Revoke token",fetch:async()=>(await Gn()).filter(e=>!e.isSelf),toSpec:e=>{let t=e,s=t.lastUsedAt?x(t.lastUsedAt):"never";return{primary:t.name,secondary:`last used ${s}`,path:`${t.scope} \xB7 created ${x(t.createdAt)}`,onSelect:()=>ir(t.name)}}}]}]};function It(e,t,s){return{name:e,desc:t,fetch:()=>{let r=F(s);return r?r.options:[]},toSpec:r=>{let o=r,a=tt(s);return{primary:o.name,current:o.value===a,onSelect:()=>sr(s,o.value,o.name)}}}}function cr(){let e=[];n.serverVersion&&e.push(`WebAgent ${n.serverVersion}`),n.agentName&&n.agentVersion&&e.push(`${n.agentName} ${n.agentVersion}`),e.length&&i(e.join(" \xB7 ")),i("\u203A has next step * current value"),i("Tab completes \xB7 Enter sends raw text"),i("? \u2014 Show help"),i("!<command> \u2014 Run bash command");for(let t of Q.children)i(`${t.name} \u2014 ${t.desc??""}`);i("--- Shortcuts ---");for(let t of ur)i(`${t.key} \u2014 ${t.desc}`);i("--- Tips ---");for(let t of dr)i(t.text)}var ur=[{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)"}],dr=[{text:"Tap \u276F prompt to cycle mode"}];async function fr(){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(),o=(await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:mr(s)})).toJSON();await fetch("/api/beta/push/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:o.endpoint,keys:o.keys,clientId:n.clientId})})}catch(e){E.scope("push").error("subscribe failed",{err:e})}}async function pr(){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){E.scope("push").error("unsubscribe failed",{err:e})}}function mr(e){let t="=".repeat((4-e.length%4)%4),s=(e+t).replace(/-/g,"+").replace(/_/g,"/"),r=atob(s),o=new Uint8Array(r.length);for(let a=0;a<r.length;a++)o[a]=r.charCodeAt(a);return o}async function Xn(){try{return await(await navigator.serviceWorker.ready).pushManager.getSubscription()!==null}catch{return!1}}async function Pt(e){let t=e.split(/\s+/),s=t[0].toLowerCase(),r=t.slice(1).join(" ").trim();switch(s){case"/share":{let o=r.split(/\s+/),a=(o[0]??"").toLowerCase();if(a==="")return await je(),!0;if(a==="revoke"){let u=o[1]??"";return await We(u),!0}if(a==="by"){let u=r.replace(/^by(\s+|$)/i,"").trim();return await ve(u===""?null:u),!0}let c=o[0]??"";return/^[A-Za-z0-9_-]{24}$/.test(c)?(ye(c),!0):(i(`share: unknown subcommand '${a}' \u2014 try /share, /share by <name>, /share <token>, or /share revoke <token>`),!0)}case"/new":{let o=r||n.sessionCwd||void 0,a=n.sessionId;return w(),n.sessionId=null,i("Creating new session\u2026"),U({cwd:o,inheritFromSessionId:a}),!0}case"/rename":{if(!n.sessionId)return i("err: No active session"),!0;if(!r)return i(`Current: ${n.sessionTitle??"(untitled)"}`),i("Usage: /rename <new title>"),!0;try{await Le(n.sessionId,r),i(`Renamed \u2192 ${r}`)}catch{i("err: Failed to rename session")}return!0}case"/sessions":return i("Removed. Use /switch to see all sessions."),!0;case"/clear":return await ge({cwd:r||void 0,showCwd:!!r}),!0;case"/exit":{if(!n.sessionId)return i("warn: No active session"),!0;let o=n.sessionId;try{n.busy&&O(),re(o).catch(()=>{}),await W(o,n.sessionCwd??void 0)}catch{i("err: Failed to exit session")}return!0}case"/logout":{try{localStorage.removeItem(B)}catch{}try{n.eventSource?.close()}catch{}return i("Logged out."),location.replace("/login"),!0}case"/token":{let o=r.trim().split(/\s+/).filter(Boolean),a=o[0];if(!a){try{let u=await Pe();if(u.length===0)return i("token: (none)"),!0;for(let d of u){let f=d.lastUsedAt?x(d.lastUsedAt):"never";i(`${d.name} (${d.scope}) \u2014 created ${x(d.createdAt)}, last used ${f}`)}i("\u2014 /token <name> to create \xB7 /token revoke <name> to revoke")}catch(u){let d=u;d.status===403?i("err: admin scope required to manage tokens"):i(`err: token list failed (${d.message})`)}return!0}if(a==="revoke"){let u=o[1];if(!u)return i("err: usage /token revoke <name>"),!0;try{await $e(u),i(`token: revoked ${u}`)}catch(d){let f=d;f.status===404?i(`err: no token named "${u}"`):f.status===403?i("err: admin scope required to manage tokens"):f.status===400&&/using|yourself|cannot/i.test(f.message)?i("err: can't revoke the token you're signed in with \u2014 use another admin token"):i(`err: revoke failed (${f.message})`)}return!0}let c=a;if(!/^[A-Za-z0-9_-]{1,64}$/.test(c))return i("err: token name must match [A-Za-z0-9_-]{1,64}"),!0;try{let u=await Me(c);i(`token: created ${u.name} (${u.scope})`),i(`${u.token}`),i("\u2014 save this now; it will never be shown again")}catch(u){let d=u;d.status===409?i(`err: token "${c}" already exists`):d.status===403?i("err: admin scope required to manage tokens"):i(`err: create failed (${d.message})`)}return!0}case"/switch":{if(!r)return i("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 i(`err: No session matching "${r}"`),!0;n.sessionSwitchGen++;let d=n.sessionSwitchGen;w(),n.sessionId=null;let[f]=await Promise.all([P(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}),b(!0)}catch{w(),n.sessionId=null,i("err: Failed to switch session")}return!0}case"/cancel":return n.busy?(O(),i("^C")):i("Nothing to cancel."),!0;case"/reload":return i("Reloading agent\u2026"),Ce().then(()=>{}).catch(o=>{i(`err: ${o instanceof Error?o.message:"Failed to reload agent"}`)}),!0;case"/help":case"?":{let o=[];n.serverVersion&&o.push(`WebAgent ${n.serverVersion}`),n.agentName&&n.agentVersion&&o.push(`${n.agentName} ${n.agentVersion}`),o.length&&i(o.join(" \xB7 ")),i("\u203A has next step * current value"),i("Tab completes \xB7 Enter sends raw text"),i("? \u2014 Show help"),i("!<command> \u2014 Run bash command");for(let a of Q.children)i(`${a.name} \u2014 ${a.desc??""}`);return i("--- Shortcuts ---"),i("Enter \u2014 Send message"),i("Shift+Enter \u2014 New line"),i("^C \u2014 Cancel current response"),i("^M \u2014 Cycle mode (Agent \u2192 Plan \u2192 Autopilot)"),i("^U \u2014 Attach file (any type)"),i("--- Tips ---"),i("Tap \u276F prompt to cycle mode"),!0}case"/model":case"/mode":case"/think":{let a={"/model":"model","/mode":"mode","/think":"reasoning_effort"}[s],c=F(a);if(!r){let p=c?.options.find(g=>g.value===c.currentValue)?.name??c?.currentValue??"unknown";return i(`${c?.name??a}: ${p}`),i(`Type ${s} + space to pick from list`),!0}if(!c)return i(`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 i(`err: Ambiguous "${r}". Type ${s} + space to see options.`),!0}return m?(c.currentValue=m.value,T(),N(),i(`${c.name} \u2192 ${m.name}`),await oe(n.sessionId,a,m.value).catch(()=>{}),!0):(i(`err: Unknown "${r}". Type ${s} + space to see options.`),!0)}case"/inbox":{let o=r.trim().split(/\s+/).filter(Boolean),a=o[0];if(!a){try{let{messages:p}=await fe();if(p.length===0)return i("inbox: empty"),!0;for(let g of p){let h=g.from_label??g.from_ref,y=x(g.created_at);i(`${g.id} \xB7 ${g.title} \xB7 ${h} \xB7 ${y}`)}i("\u2014 /inbox <id> to open \xB7 /inbox dismiss <id> to dismiss only")}catch(p){i(`err: inbox list failed (${p.message})`)}return!0}let c=a==="dismiss",u=c?o[1]:a;if(!u)return i("err: usage /inbox <id> | /inbox dismiss <id>"),!0;let d;try{({messages:d}=await fe())}catch(p){return i(`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 i(`err: no inbox message matching "${u}"`),!0;if(c){try{await Ae(m.id),i(`inbox: dismissed ${m.id}`)}catch(p){i(`err: dismiss failed (${p.message})`)}return!0}try{await At(m)}catch(p){i(`err: consume failed (${p.message})`)}return!0}case"/notify":{if(typeof Notification>"u")return i("err: notifications not supported in this browser"),!0;let o=r.toLowerCase();if(o==="on"){if(Notification.permission==="denied")return i("notify: blocked \u2014 allow in browser site settings to enable"),!0;if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted")return i("notify: blocked \u2014 allow in browser site settings to enable"),!0;let c=await Xn();return await fr(),i(c?"notify: already enabled":"notify: enabled"),!0}if(o==="off")return await pr(),i("notify: disabled"),!0;let a=Notification.permission;return a==="denied"?i("notify: blocked \u2014 allow in browser site settings to enable"):a==="granted"&&await Xn()?i("notify: enabled"):i("notify: off \u2014 use /notify on to enable"),!0}case"/log":{let o=r.toLowerCase().trim();return o===""?(Yn(),!0):o==="reset"?(Lt(),!0):["off","debug","info","warn","error"].includes(o)?(xt(o),!0):(i(`err: invalid level '${o}' (use off|debug|info|warn|error|reset)`),!0)}case"/reset":return await Ct(),!0;default:return!1}}var we=null,Ke=Q,se,G=[],X=-1,ue=null;function Rt(){let e=l.input.value;if(ue!==null){if(e===ue)return;ue=null}if(!e.startsWith("/")){q();return}let{node:t,pathPrefix:s,tailQuery:r}=it(e,Q);if(s!==we)if(we=s,Ke=t,t.fetch&&t.toSpec){let o=t.fetch();if(o instanceof Promise){se="loading";let a=s;o.then(c=>{we===a&&(se=c,Mt(Zn(),s))},c=>{if(we!==a)return;se={error:c instanceof Error&&c.message?c.message:"fetch failed"},Mt(Zn(),s)})}else se=o}else se=void 0;else Ke=t;Mt(r,s)}function Zn(){let{tailQuery:e}=it(l.input.value,Q);return e}function Mt(e,t){let s=yn(Ke,e,se);if(G=s,s.length===0){q();return}let r=s.findIndex(o=>o.kind!=="separator"&&o.kind!=="placeholder");X=r>=0?r:0,$t(t),l.slashMenu.classList.add("active")}function $t(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 o=r===X,a=vn(s.spec,o,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 q(){l.slashMenu.classList.remove("active"),l.slashMenu.innerHTML="",X=-1,G=[],we=null,Ke=Q,se=void 0,ue=l.input.value}function gr(){let e=G[X];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;_(`${t}${t?" ":""}${e.node.name}${r?" ":""}`),r?(ue=null,Rt()):q()}else e.kind==="data"?(_(`${t}${t?" ":""}${e.spec.primary}`),q()):e.kind==="freeform"&&q();l.input.focus()}}async function hr(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){_(`${s}${s?" ":""}${t.node.name} `),ue=null,Rt(),l.input.focus();return}q(),_(""),t.node.onSelect&&await t.node.onSelect();return}q(),_(""),t.spec.onSelect?await t.spec.onSelect():i("Read-only entry \u2014 no action.")}}function ts(e){return!l.slashMenu.classList.contains("active")||G.length===0?!1:e.key==="ArrowDown"?(X=es(X,1),$t(l.slashMenu.dataset.pathPrefix??""),!0):e.key==="ArrowUp"?(X=es(X,-1),$t(l.slashMenu.dataset.pathPrefix??""),!0):e.key==="Tab"?(gr(),!0):!1}function es(e,t){let s=G.length;for(let r=1;r<=s;r++){let o=(e+t*r+s)%s;if(G[o].kind!=="separator"&&G[o].kind!=="placeholder")return o}return e}l.slashMenu.addEventListener("mousedown",e=>{e.preventDefault();let s=e.target?.closest(".slash-item");s?.dataset.idx!==void 0&&hr(Number(s.dataset.idx))});l.input.addEventListener("input",()=>{Rt(),l.inputArea.classList.toggle("bash-mode",l.input.value.startsWith("!"))});function yr(e){return new Promise(t=>{let s=new FileReader;s.onload=()=>{t(s.result)},s.readAsDataURL(e)})}async function ns(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 yr(e)),s}function ss(e){n.pendingAttachments.push(e),Ge()}function Ge(){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 o=document.createElement("img");o.src=e.previewUrl,s.appendChild(o)}else{s.classList.add("attach-file");let o=document.createElement("span");o.className="attach-file-name",o.textContent=e.name,s.appendChild(o)}let r=document.createElement("button");r.className="remove",r.textContent="\xD7",r.addEventListener("click",()=>{n.pendingAttachments.splice(t,1),Ge()}),s.appendChild(r),l.attachPreview.appendChild(s)})}l.fileInput.onchange=async()=>{for(let e of l.fileInput.files)ss(await ns(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&&ss(await ns(r))})())});var de={send:()=>{},cancel:()=>{},attach:()=>{},publish:()=>{},cancelPreview:()=>{}};function is(e){de=e}function rs(){let e=l.input.value.trim();return e.startsWith("/")||e.startsWith("!")||e==="?"||e.startsWith("? ")}function vr(){if(n.previewToken)return[{label:"^P",title:"Publish preview (Ctrl+P)",className:"publish",onClick:()=>{de.publish()}},{label:"^C",title:"Cancel preview (Ctrl+C)",className:"cancel",onClick:()=>{de.cancelPreview()}}];let e={label:"^U",title:"Attach file (Ctrl+U)",onClick:()=>{de.attach()}},t=()=>{n.busy&&!rs()?de.cancel():de.send()};return n.busy&&!rs()?[e,{label:"^C",title:"Cancel (Ctrl+C)",className:"cancel",onClick:t}]:[e,{label:"\u21B5",title:"Send (Enter)",onClick:t}]}var wr=["cancel","publish"];function os(e,t){e.textContent=t.label,e.title=t.title,e.disabled=t.disabled??!1,e.onclick=t.onClick;for(let s of wr)e.classList.remove(s);t.className&&e.classList.add(t.className)}function br(){let[e,t]=vr();os(l.attachBtn,e),os(l.sendBtn,t),l.input.disabled=!!n.previewToken}dn(br);function _t(){return n.clientId!==null}n._onCancelTimeout=()=>i("warn: Agent not responding to cancel");function cs(){let e=l.input.value.trim();if(!e&&n.pendingAttachments.length===0)return;if((e.startsWith("/")||e==="?"||e.startsWith("? "))&&n.pendingAttachments.length===0){_(""),l.input.style.height="auto",Pt(e);return}if(e.startsWith("!")&&n.pendingAttachments.length===0){let o=e.slice(1).trim();if(!o)return;if(!n.sessionId){i("warn: Session not ready yet, please wait\u2026");return}if(!_t()){i("warn: Not connected, please retry");return}_(""),l.input.style.height="auto",l.inputArea.classList.remove("bash-mode"),hn(o,!0),n.sentBashForSession=n.sessionId,Zt(n.sessionId,o).catch(()=>{}),v(!0);return}if(n.busy)return;if(_(""),l.input.style.height="auto",l.inputArea.classList.remove("bash-mode"),!n.sessionId){i("warn: Session not ready yet, please wait\u2026");return}if(!_t()){i("warn: Not connected, please retry");return}let t=Ne("user",e||"(attachment)"),s=[];for(let o of n.pendingAttachments)if(o.kind==="image"&&o.previewUrl){let a=document.createElement("img");a.className="user-image",a.src=o.previewUrl,a.alt=o.name,t.appendChild(a),s.push(null)}else{let a=document.createElement("div");a.className="user-attachment",a.textContent=`[${o.kind}: ${o.name}]`,t.appendChild(a),s.push(a)}let r=n.pendingAttachments.slice();n.pendingAttachments.length=0,Ge(),r.length>0?Promise.all(r.map(o=>{let a=new FormData;return a.append("file",o.file,o.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(o=>{if(!_t()){t.remove(),i("warn: Not connected, please retry"),v(!1);return}for(let c=0;c<o.length;c++){let u=s[c];if(!u)continue;let d=o[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=o.map(({kind:c,attachmentId:u,displayName:d,mimeType:f})=>({kind:c,attachmentId:u,displayName:d,mimeType:f}));Ze(n.sessionId,e||"What is in this attachment?",a).catch(as)}):Ze(n.sessionId,e).catch(as),n.turnEnded=!1,n.sentMessageForSession=n.sessionId,v(!0),mn()}function as(e){v(!1),j();let t=e instanceof Error?e.message:String(e);i(`err: ${t}`)}function us(){O()&&i("^C")}is({send:cs,cancel:us,attach:()=>{l.fileInput.click()},publish:()=>{St()},cancelPreview:kt});ae();l.input.addEventListener("keydown",e=>{if(ts(e)){e.preventDefault();return}if(e.key==="Enter"&&!e.shiftKey){e.preventDefault(),q(),cs();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(),kt();return}if(n.busy){e.preventDefault(),us();return}}e.key==="Escape"&&l.slashMenu.classList.contains("active")&&(e.preventDefault(),q(),l.input.focus())});var ls=0;function ds(){let e=F("mode");if(!e?.options.length){Date.now()-ls>3e3&&(i("Mode switcher temporarily unavailable. Try `/new` to start a fresh session."),ls=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,oe(n.sessionId,"mode",s.value).catch(()=>{}),i(`Mode \u2192 ${s.name}`),T()}document.addEventListener("keydown",e=>{e.key==="m"&&(e.ctrlKey||e.metaKey)&&!e.shiftKey&&(e.preventDefault(),ds())});document.addEventListener("keydown",e=>{n.previewToken&&(!(e.ctrlKey||e.metaKey)||e.shiftKey||e.key==="p"&&(e.preventDefault(),St()))});l.prompt.addEventListener("click",ds);l.input.addEventListener("input",ae);l.input.addEventListener("input",()=>{gn(Sr)});function Sr(){l.input.style.height="auto",l.input.style.height=Math.min(l.input.scrollHeight,kr())+"px"}function kr(){let e=Number.parseFloat(window.getComputedStyle(l.input).maxHeight);return Number.isFinite(e)?e:Number.POSITIVE_INFINITY}async function Tr(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 ze(){Z("connecting","connecting"),Ir()}async function Ir(){let e;try{e=(await en()).ticket}catch{setTimeout(ze,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),ie(r.clientId,!document.hidden,n.sessionId??void 0),Tr(r.clientId),!r.agent)||L(r)},t.onerror=()=>{t.close(),xr(),setTimeout(ze,3e3)},t.addEventListener("heartbeat",()=>{n.clientId&&(document.hidden||ie(n.clientId,!0,n.sessionId??void 0))}),Er()}async function Er(){Z("connecting","session loading");let e=n.sessionSwitchGen,t=fn();if(t&&t===n.sessionId&&n.lastEventSeq>0){if(await Nt(t,!0,e),e!==n.sessionSwitchGen)return;b(!1);return}if(t){if(w(),await Nt(t,!1,e),e!==n.sessionSwitchGen)return;b(!0);return}try{let s=await xe();if(e!==n.sessionSwitchGen)return;if(s.length>0){if(w(),await Nt(s[0].id,!1,e),e!==n.sessionSwitchGen)return;b(!0);return}}catch{}e===n.sessionSwitchGen&&U()}async function Nt(e,t,s){if(t){try{let r=await P(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),ht(e)])}else{n.sessionId=null;let r=K(e),o=H(e),a;try{let[c,u]=await Promise.all([P(e),r]);if(await o,s!==n.sessionSwitchGen)return;a=c,u||i("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 xr(){Z("disconnected","disconnected"),n.eventSource=null,n.clientId=null,M(),V(),n.currentBashEl&&He(n.currentBashEl,null,"disconnected"),n.pendingToolCallIds.clear(),n.pendingPermissionRequestIds.clear(),n.pendingPromptDone=!1,n.turnEnded=!1,le(),v(!1)}function fs(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?fs(n.clientId,n.sessionId??null):ie(n.clientId,!0,n.sessionId??void 0)),!document.hidden&&n.sessionId&&n.lastEventSeq>0&&!n.replayInProgress){let e=n.sessionId;Promise.all([H(e),ht(e)]).then(()=>{b(!1)})}});window.addEventListener("pagehide",()=>{n.clientId&&fs(n.clientId,n.sessionId??null)});var Lr=80,Cr=300,Ar=10,ps=!1,z=null;function Pr(){return typeof window.visualViewport>"u"?null:window.visualViewport}function ms(){let e=Pr();return e?e.offsetTop>0||window.innerHeight-e.height>Lr:!0}function Mr(e){return e===l.input}function Ht(e){return typeof e.pointerId=="number"?e.pointerId:1}function $r(e){e.pointerType==="touch"&&(z=null,Mr(e.target)&&document.activeElement===l.input&&(l.input.disabled||ms()||(z={pointerId:Ht(e),startX:e.clientX,startY:e.clientY,startTs:e.timeStamp})))}function Rr(e){if(!z||Ht(e)!==z.pointerId)return;let t=z;z=null;let s=e.timeStamp-t.startTs,r=Math.hypot(e.clientX-t.startX,e.clientY-t.startY);s>Cr||r>Ar||document.activeElement!==l.input||l.input.disabled||ms()||l.input.blur()}function _r(e){z&&Ht(e)===z.pointerId&&(z=null)}function gs(){ps||(ps=!0,document.addEventListener("pointerdown",$r,{capture:!0}),document.addEventListener("pointerup",Rr,{capture:!0}),document.addEventListener("pointercancel",_r,{capture:!0}))}if(!localStorage.getItem(B))throw location.replace("/login"),new Error("redirecting to /login");jt();En(i);gs();l.messages.addEventListener("click",Ot);Qe(qt);ze();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}`),w(),n.sessionId=null,i("Switching\u2026"),Promise.all([P(s),K(s)]).then(([o,a])=>{r===n.sessionSwitchGen&&(L({type:"session_created",sessionId:o.id,cwd:o.cwd,title:o.title,configOptions:o.configOptions}),a&&b(!0))}).catch(()=>{w(),n.sessionId=null,i("err: Failed to switch session")})}}));
|