glimmervoid 0.44.2 → 0.45.1-next.45
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/dist/bin/glimmervoid.js +15 -15
- package/dist/chunks/{adapters-7AfJ6yb3.js → adapters-BE9BKVW0.js} +24 -24
- package/dist/chunks/{adapters-B_ss_kZh.js → adapters-CPaysZkO.js} +1 -1
- package/dist/chunks/{agent-api-cli-prUJ5ZGN.js → agent-api-cli-B0l8uLos.js} +1 -1
- package/dist/chunks/{agent-api-cli-zwuWZlwk.js → agent-api-cli-Bq9J0_D5.js} +148 -15
- package/dist/chunks/{agent-api-core-DQwd2ClI.js → agent-api-core-ClU9-5K3.js} +10 -4
- package/dist/chunks/{agent-setup-cli-7hG401Io.js → agent-setup-cli-BA_1AdhQ.js} +2 -2
- package/dist/chunks/{contracts-lxJ0sQEl.js → build-channel-qgKwNssc.js} +37 -3
- package/dist/chunks/{config-DlKkg6IX.js → config-BqJTnPae.js} +27 -34
- package/dist/chunks/{config-path-core-DFt-TemS.js → config-path-core-DUWk0Lui.js} +5 -1
- package/dist/chunks/config-store-5xpRLHFo.js +1 -0
- package/dist/chunks/{config-store-DIrwF5iQ.js → config-store-BGTg8oKO.js} +77 -78
- package/dist/chunks/{git-version-C3lznLS_.js → git-version-BpdkKH2j.js} +1 -1
- package/dist/chunks/{grok-Di4aQGre.js → grok-7jK8ZNtf.js} +1 -1
- package/dist/chunks/{json-file-DFCTvPjj.js → json-file-BjFK_eSH.js} +2 -7
- package/dist/chunks/{main-BCbulgNv.js → main-x9ygUnoL.js} +1226 -1012
- package/dist/chunks/{pair-cli-B3VRcrHm.js → pair-cli-Cph4TZ2R.js} +2 -2
- package/dist/chunks/{remote-config-C91HwjWq.js → remote-config-CmP36r_s.js} +2 -2
- package/dist/chunks/{rtk-resolver-BDHi6RMv.js → rtk-resolver-C_IReILP.js} +1 -1
- package/dist/chunks/rtk-resolver-DgnNb1or.js +1 -0
- package/dist/chunks/{session-CUc6d7aS.js → session-BwlLY_mv.js} +36 -14
- package/dist/chunks/{session-routes--hrsvv7a.js → session-routes-CviNvxcz.js} +9 -1
- package/dist/chunks/{settings-cli-C9eCc60b.js → settings-cli-Bete5oVk.js} +11 -10
- package/dist/chunks/{settings-readout-core-DK1m5TUq.js → settings-readout-core-CS8MPaIE.js} +14 -8
- package/dist/chunks/shown-files-core-soMzCQ1D.js +145 -0
- package/dist/chunks/{ssh-sign-cli-DCnHgHqo.js → ssh-sign-cli-DXhuqzuy.js} +2 -2
- package/dist/client/assets/action-status-BwqYb9eF.js +1 -0
- package/dist/client/assets/action-status-BwqYb9eF.js.br +0 -0
- package/dist/client/assets/benchmark-panel-BulIdLtq.js +1 -0
- package/dist/client/assets/benchmark-panel-BulIdLtq.js.br +0 -0
- package/dist/client/assets/card-dom-DkZgkeG9.js +1 -0
- package/dist/client/assets/card-dom-DkZgkeG9.js.br +0 -0
- package/dist/client/assets/control-ws-CAcwW-r9.js +4 -0
- package/dist/client/assets/control-ws-CAcwW-r9.js.br +0 -0
- package/dist/client/assets/dialogs-CCP1ipXD.js +79 -0
- package/dist/client/assets/dialogs-CCP1ipXD.js.br +0 -0
- package/dist/client/assets/dom-helpers-xJduxDcc.js +1 -0
- package/dist/client/assets/dom-helpers-xJduxDcc.js.br +0 -0
- package/dist/client/assets/hooks-panel-BWDeSHtM.js +1 -0
- package/dist/client/assets/hooks-panel-BWDeSHtM.js.br +0 -0
- package/dist/client/assets/index-D6m--U7B.js +84 -0
- package/dist/client/assets/index-D6m--U7B.js.br +0 -0
- package/dist/client/assets/index-DF3BLGk9.css +2 -0
- package/dist/client/assets/index-DF3BLGk9.css.br +0 -0
- package/dist/client/assets/issues-panel-B7Y1Lpyx.js +1 -0
- package/dist/client/assets/issues-panel-B7Y1Lpyx.js.br +0 -0
- package/dist/client/assets/modal-mWl2H7A_.js +1 -0
- package/dist/client/assets/modal-mWl2H7A_.js.br +0 -0
- package/dist/client/assets/plan-face-DpzZfVeG.js +3 -0
- package/dist/client/assets/plan-face-DpzZfVeG.js.br +0 -0
- package/dist/client/assets/{poll-ago-Dj148faJ.js → poll-ago-Bc-8mMFj.js} +1 -1
- package/dist/client/assets/poll-ago-Bc-8mMFj.js.br +0 -0
- package/dist/client/assets/pr-scope-tabs-DftvVYU8.js +1 -0
- package/dist/client/assets/pr-scope-tabs-DftvVYU8.js.br +0 -0
- package/dist/client/assets/radar-panel-hxjF7m9Z.js +1 -0
- package/dist/client/assets/radar-panel-hxjF7m9Z.js.br +0 -0
- package/dist/client/assets/review-queue-panel-8bP8Q7RR.js +10 -0
- package/dist/client/assets/review-queue-panel-8bP8Q7RR.js.br +0 -0
- package/dist/client/assets/roving-keys-core-BDobx2It.js +1 -0
- package/dist/client/assets/settings-panel-B50lNcrt.js +4 -0
- package/dist/client/assets/settings-panel-B50lNcrt.js.br +0 -0
- package/dist/client/assets/trace-panel-Dy-fgi9c.js +2 -0
- package/dist/client/assets/trace-panel-Dy-fgi9c.js.br +0 -0
- package/dist/client/assets/ui-prefs-CNf6fId2.js +1 -0
- package/dist/client/assets/ui-prefs-CNf6fId2.js.br +0 -0
- package/dist/client/assets/usage-panel-D2JuiQ4G.js +1 -0
- package/dist/client/assets/usage-panel-D2JuiQ4G.js.br +0 -0
- package/dist/client/assets/visions-panel-CI6CRn42.js +1 -0
- package/dist/client/assets/visions-panel-CI6CRn42.js.br +0 -0
- package/dist/client/index.html +14 -8
- package/dist/client/index.html.br +0 -0
- package/dist/server/index.js +99 -1
- package/dist/session/guardrails-open-launcher.js +28 -16
- package/dist/session/visions-relay.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/config-store-LYSRHNQs.js +0 -1
- package/dist/chunks/rtk-resolver-Dr4iJsiS.js +0 -1
- package/dist/client/assets/action-status-DXcC95xv.js +0 -1
- package/dist/client/assets/action-status-DXcC95xv.js.br +0 -0
- package/dist/client/assets/benchmark-panel-Cssmnd3z.js +0 -1
- package/dist/client/assets/benchmark-panel-Cssmnd3z.js.br +0 -0
- package/dist/client/assets/dom-helpers-CcEFPh-F.js +0 -4
- package/dist/client/assets/dom-helpers-CcEFPh-F.js.br +0 -0
- package/dist/client/assets/hooks-panel-Cli8EeBB.js +0 -1
- package/dist/client/assets/hooks-panel-Cli8EeBB.js.br +0 -0
- package/dist/client/assets/index-C3nOrTwM.css +0 -2
- package/dist/client/assets/index-C3nOrTwM.css.br +0 -0
- package/dist/client/assets/index-C8u3ZjM3.js +0 -173
- package/dist/client/assets/index-C8u3ZjM3.js.br +0 -0
- package/dist/client/assets/issues-panel-Bev1wadi.js +0 -1
- package/dist/client/assets/issues-panel-Bev1wadi.js.br +0 -0
- package/dist/client/assets/modal-CvDX5-_2.js +0 -1
- package/dist/client/assets/modal-CvDX5-_2.js.br +0 -0
- package/dist/client/assets/poll-ago-Dj148faJ.js.br +0 -0
- package/dist/client/assets/pr-queue-columns-Jleg5z3W.js +0 -1
- package/dist/client/assets/pr-queue-columns-Jleg5z3W.js.br +0 -0
- package/dist/client/assets/radar-panel-Dtp4ZzT3.js +0 -1
- package/dist/client/assets/radar-panel-Dtp4ZzT3.js.br +0 -0
- package/dist/client/assets/review-queue-panel-BQvU_-xl.js +0 -2
- package/dist/client/assets/review-queue-panel-BQvU_-xl.js.br +0 -0
- package/dist/client/assets/settings-panel-DegKCsoZ.js +0 -3
- package/dist/client/assets/settings-panel-DegKCsoZ.js.br +0 -0
- package/dist/client/assets/trace-panel-DFqImX92.js +0 -1
- package/dist/client/assets/trace-panel-DFqImX92.js.br +0 -0
- package/dist/client/assets/ui-prefs-CavQQH-s.js +0 -1
- package/dist/client/assets/ui-prefs-CavQQH-s.js.br +0 -0
- package/dist/client/assets/usage-panel-CEJqXYIA.js +0 -1
- package/dist/client/assets/usage-panel-CEJqXYIA.js.br +0 -0
- package/dist/client/assets/visions-panel-Dm3iKlhv.js +0 -1
- package/dist/client/assets/visions-panel-Dm3iKlhv.js.br +0 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{A as e,Cn as t,D as n,E as r,Ft as i,Lt as a,M as o,P as s,Sn as c,T as l,_n as u,an as ee,bn as te,cn as ne,dn as d,fn as re,gn as ie,hn as ae,in as oe,k as se,ln as ce,mn as le,nn as ue,o as f,on as de,pn as fe,rn as p,sn as pe,un as me,vn as he,w as ge,xn as _e,y as ve,yn as ye}from"./dom-helpers-xJduxDcc.js";import{u as be}from"./control-ws-CAcwW-r9.js";import{n as xe}from"./poll-ago-Bc-8mMFj.js";import{$ as Se,A as Ce,B as we,D as Te,Et as Ee,F as De,H as Oe,I as ke,L as Ae,M as je,N as Me,Ot as Ne,P as Pe,T as Fe,V as Ie,X as Le,b as Re,dt as ze,h as Be,i as Ve,j as He,m as Ue,r as We,s as Ge,st as Ke,tt as qe,ut as Je,w as Ye,x as Xe,y as Ze}from"./ui-prefs-CNf6fId2.js";import{c as Qe,i as $e,s as et,t as tt}from"./action-status-BwqYb9eF.js";import{a as nt}from"./modal-mWl2H7A_.js";import{An as rt,C as it,D as at,Dn as ot,E as m,Fn as st,G as ct,Gn as lt,In as ut,K as dt,Ln as ft,Mn as pt,Nn as mt,O as ht,On as gt,Pn as _t,Rn as vt,S as yt,T as h,Un as bt,Wn as xt,_ as St,ar as Ct,b as wt,br as Tt,cr as Et,dr as Dt,f as Ot,fr as kt,g as At,h as jt,i as Mt,jn as Nt,kn as Pt,lr as Ft,m as It,n as Lt,nr as Rt,or as zt,p as Bt,pr as Vt,r as Ht,rr as Ut,sr as Wt,t as Gt,tr as Kt,ur as qt,v as Jt,vr as Yt,w as Xt,x as Zt,xr as Qt,y as $t}from"./index-D6m--U7B.js";import{agentLoginSummary as en,openAgentConnectDialog as tn,openRemoteSetupDialog as nn}from"./dialogs-CCP1ipXD.js";function rn(){let e=f(`div`),t=f(`p`,`flying-animals-status`);t.id=`flying-animals-gallery-status`,t.setAttribute(`role`,`status`);let n=f(`div`,`flying-animals-gallery`);n.setAttribute(`aria-label`,`Animal gallery`);let r=[],i=()=>{let e=It(),n=Ee(Ve().flyingAnimalsExcludedSprites);t.textContent=[e,n?``:`No animals are included, so automatic flights are paused.`].filter(Boolean).join(` `);for(let t of r)t.disabled=e!==null},a=Ve();for(let e of Ne){let o=f(`article`,`flying-animal-tile`),s=Qt(e),c=f(`label`,`flying-animal-include`),l=f(`input`,`settings-view-checkbox`);l.type=`checkbox`,l.checked=!a.flyingAnimalsExcludedSprites.includes(e.sprite),l.setAttribute(`aria-label`,`Include ${e.name}`),l.addEventListener(`change`,()=>{let t=new Set(Ve().flyingAnimalsExcludedSprites);l.checked&&t.delete(e.sprite),l.checked||t.add(e.sprite),He([...t]),Bt(Ze()),i()}),c.append(l,document.createTextNode(`Include`));let u=f(`button`,`btn-dialog btn-dialog-cancel`,`Fly now`);u.type=`button`,u.setAttribute(`aria-describedby`,t.id),u.addEventListener(`click`,()=>jt(e.sprite)),r.push(u),o.append(s,f(`h2`,`flying-animal-name`,e.name),c,u),n.append(o)}return i(),e.append(t,n),e}var an=`johncwaters/glimmervoid`,on=Object.freeze([`auto`,`calculate`,`display`]);Object.freeze([`codex`,`grok`]),Object.freeze([`dailyUsd`,`monthlyUsd`]);var g={scope:`browser`,access:`editable`,takesEffect:`now`},_={scope:`browser`,access:`advanced`,takesEffect:`now`},v={scope:`machine`,access:`editable`,takesEffect:`now`},y={scope:`machine`,access:`editable`,takesEffect:`new-sessions`},b={scope:`machine`,access:`readout`,takesEffect:`now`},x={scope:`machine`,access:`file-only`},sn=1e3,cn=60,ln=60,un=sn*cn,dn=un*ln,fn=dn*24,pn={label:`investigations`,storedPerDisplay:1},mn={label:`sessions`,storedPerDisplay:1},hn={label:`recurrences`,storedPerDisplay:1},gn={label:`actions`,storedPerDisplay:1},S={label:`seconds`,storedPerDisplay:1},_n={label:`minutes`,storedPerDisplay:1},vn={label:`hours`,storedPerDisplay:1},C={label:`days`,storedPerDisplay:1},yn={label:`seconds`,storedPerDisplay:sn,storedLabel:`ms`},bn={label:`minutes`,storedPerDisplay:un,storedLabel:`ms`},xn={label:`minutes`,storedPerDisplay:cn,storedLabel:`seconds`},Sn={label:`hours`,storedPerDisplay:dn,storedLabel:`ms`},Cn={label:`hours`,storedPerDisplay:ln,storedLabel:`minutes`},wn={label:`days`,storedPerDisplay:fn,storedLabel:`ms`},Tn={label:`USD`,storedPerDisplay:1},En={label:`users`,storedPerDisplay:1},Dn={label:`reviews per hour`,storedPerDisplay:1},On={label:`times`,storedPerDisplay:1},w=`A tuning knob kept out of the Settings view; the default suits almost every install.`,T=`A diagnostic switch kept out of the Settings view; change it in config.json while investigating.`,E=`Changes how the server process or its worktrees behave, so it is set in config.json with a restart or new sessions in mind.`,kn=`A structured value with no dashboard control; edit it in config.json.`,An=`Never editable from the dashboard by rule; edit it in config.json.`;function jn(e){return e.map(e=>({value:e,label:e[0].toUpperCase()+e.slice(1)}))}var Mn=Object.freeze({"machine-terminal":{title:`Terminal`,description:`Terminal behavior shared by dashboard clients.`},"machine-detection-sessions":{title:`Detection and sessions`,description:`Config-file-only detection, timing, worktree and process settings.`},"lanes-ingest":{title:`Ingest`,description:`The machine-context sources behind Visions.`}}),Nn=Object.freeze([{id:`browser-appearance`,level:`browser`,title:`Appearance`,description:`How this browser draws the dashboard.`,legacyIds:[`browser-flying-animals`,`animals`,`flying-animals`],settings:[{id:`theme`,path:`pref:themeId`,title:`Theme`,description:`Color scheme for the dashboard.`,control:`select`,optionsFrom:`themes`,keywords:[`color`,`palette`],defaultValue:`phyrexian`,...g},{id:`session-usage-chips`,path:`pref:sessionUsageChips`,title:`Show usage on session cards`,description:`Shows each card's transcript token count and CLI-reported cost when available, otherwise a calculated API list-price estimate.`,control:`toggle`,keywords:[`usage`,`cost`,`tokens`,`card`,`price`],defaultValue:!1,...g},{id:`phone-arrow-pad`,path:`pref:phoneArrowPad`,title:`Swipe arrow pad on phone (experimental)`,description:`Replace the four arrow keys above the phone keyboard with one pad: swipe on it to send arrow keys, one per short drag.`,control:`toggle`,keywords:[`experimental`,`mobile`,`keys`,`arrows`,`swipe`,`gesture`],defaultValue:!1,...g},{id:`flying-animals`,path:`pref:flyingAnimalsEnabled`,title:`Flying animals`,description:`Show animated animals flying across the dashboard.`,control:`toggle`,keywords:[`animation`,`motion`,`animals`],defaultValue:!1,...g},{id:`animals-min-gap`,path:`pref:flyingAnimalsMinGapSeconds`,title:`Time between flights: minimum`,description:`Shortest pause between flights.`,control:`number`,integer:!1,step:.1,range:ee,unit:S,maximumSettingId:`animals-max-gap`,keywords:[`animals`,`frequency`],defaultValue:p.flyingAnimalsMinGapSeconds,..._},{id:`animals-max-gap`,path:`pref:flyingAnimalsMaxGapSeconds`,title:`Time between flights: maximum`,description:`Longest pause between flights.`,control:`number`,integer:!1,step:.1,range:ee,unit:S,keywords:[`animals`,`frequency`],defaultValue:p.flyingAnimalsMaxGapSeconds,..._},{id:`animals-min-duration`,path:`pref:flyingAnimalsMinDurationSeconds`,title:`Flight duration: minimum`,description:`Shortest flight, for faster animals.`,control:`number`,integer:!1,step:.1,range:oe,unit:S,maximumSettingId:`animals-max-duration`,keywords:[`animals`,`speed`],defaultValue:p.flyingAnimalsMinDurationSeconds,..._},{id:`animals-max-duration`,path:`pref:flyingAnimalsMaxDurationSeconds`,title:`Flight duration: maximum`,description:`Longest flight, for slower animals.`,control:`number`,integer:!1,step:.1,range:oe,unit:S,keywords:[`animals`,`speed`],defaultValue:p.flyingAnimalsMaxDurationSeconds,..._},{id:`animals-scale`,path:`pref:flyingAnimalsScale`,title:`Size multiplier`,description:`Scale applied on top of the viewport size.`,control:`number`,integer:!1,step:.1,range:de,unit:On,keywords:[`animals`,`size`],defaultValue:p.flyingAnimalsScale,..._},{id:`animals-on-phone`,path:`pref:flyingAnimalsOnPhone`,title:`Show on phone layout`,description:`Allow flights on the phone layout.`,control:`toggle`,keywords:[`animals`,`mobile`],defaultValue:p.flyingAnimalsOnPhone,..._}]},{id:`browser-notifications`,level:`browser`,title:`Notifications`,description:`How this browser, and the Telegram bot shared by every lane, get your attention.`,settings:[{id:`alert-sounds-enabled`,path:`pref:soundEnabled`,title:`Alert sounds`,legacyIds:[{sectionId:`browser-appearance`,settingId:`alert-sounds-enabled`}],description:`Play sounds when a session needs attention and when a merge celebration plays. The same switch as the note button in the desktop header.`,control:`toggle`,keywords:[`audio`,`mute`,`sound`,`notification`],defaultValue:!0,...g},{id:`alert-sound`,path:`pref:soundId`,title:`Alert sound`,legacyIds:[{sectionId:`browser-appearance`,settingId:`alert-sound`}],description:`Sound played when a session needs attention. Your own .ogg, .mp3, .wav, .m4a or .webm files dropped into the sounds folder of the Glimmervoid home (~/.glimmervoid/sounds/, or $GLIMMERVOID_HOME/sounds/) are listed after the built-in sounds. Glimmervoid never creates that folder, so make it yourself; new files show up the next time Settings opens.`,control:`select`,optionsFrom:`sounds`,keywords:[`audio`,`notification`,`custom`],defaultValue:`chime`,...g},{id:`desktop-notifications`,path:`pref:notificationsEnabled`,title:`Desktop notifications`,legacyIds:[{sectionId:`browser-appearance`,settingId:`desktop-notifications`}],description:`Raise a browser notification when a session needs attention while this dashboard is in the background.`,control:`toggle`,keywords:[`browser`,`attention`],defaultValue:!0,...g}]},{id:`machine-telegram`,level:`machine`,parent:`browser-notifications`,title:`Telegram`,description:`One bot shared by session, PR review and PostHog notifications.`,legacyIds:[`telegram`,`notifications`],settings:[{id:`telegram-bot-token`,path:`telegram.botToken`,title:`Bot token`,description:`Credential used by the shared Telegram bot. Create a bot by messaging @BotFather in Telegram and sending /newbot; it replies with this token. When GLIMMERVOID_TELEGRAM_BOT_TOKEN supplies it, this field is read-only.`,control:`password`,keywords:[`credential`,`api`],defaultValue:``,...v},{id:`telegram-chat-id`,path:`telegram.chatId`,title:`Chat id`,description:`Destination chat for enabled Telegram lanes. Send your bot any message, then open https://api.telegram.org/bot<token>/getUpdates in a browser and copy the number under message.chat.id.`,control:`text`,keywords:[`destination`,`channel`],defaultValue:``,...v},{id:`telegram-session-notifications`,path:`telegramNotifications`,title:`Send session notifications`,description:`Send session completion, input and failure alerts when no dashboard is open. Unacknowledged alerts also escalate after the phone escalation delay while a dashboard remains open.`,control:`toggle`,keywords:[`phone`,`off dashboard`,`test`],defaultValue:!1,status:`telegram-delivery`,...v}]},{id:`machine-sessions`,level:`machine`,title:`Sessions`,description:`How sessions start, where projects are found, and what the dashboard shows for them.`,legacyIds:[`machine-general`,`general`,`machine-repositories`,`repos`,`repositories`],settings:[{id:`auto-resume`,path:`autoResume`,title:`Auto-resume sessions on startup`,description:`Resume conversations that were live when Glimmervoid last shut down or crashed, and tell sessions that were mid-turn, or had a background agent, monitor or scheduled wakeup in flight, to continue.`,control:`toggle`,keywords:[`startup`,`conversation`],defaultValue:!0,...v},{id:`conversation-view`,path:`conversationView`,title:`Conversation view (experimental)`,description:`Let each Claude Code and Codex session turn on a Conversation face from its card menu, which renders the transcript as messages, approvals and a composer. Sessions stay on the terminal until you turn it on for them. A Claude Code session started while this is on can answer its permission prompts and questions there. A Codex session connects on its next start, through a local app-server so approvals can be answered from the dashboard; guarded Codex sessions and those that bypass Codex hook trust keep the terminal only.`,control:`toggle`,keywords:[`experimental`,`transcript`,`chat`,`codex`,`claude`],defaultValue:!1,...v},{id:`tab-order`,path:`viewTabOrder`,title:`Tab order`,description:`The order of the dashboard tabs in every browser: the header on desktop and the More menu on a phone. You can also drag a tab in the desktop header.`,control:`tab-order`,keywords:[`tabs`,`order`,`rearrange`,`reorder`,`header`,`more`,`menu`],defaultValue:[],...v},{id:`remote-sessions`,path:`remoteSessions`,title:`Remote Coder sessions (experimental)`,description:`Offer the Coder environments in config.json when adding a session, so the session runs in its own Coder workspace instead of on this machine. Off refuses new remote sessions; ones already running keep working until closed.`,control:`toggle`,keywords:[`experimental`,`coder`,`remote`,`workspace`,`cloud`],defaultValue:!1,...v},{id:`streamer-mode`,path:`streamerMode`,title:`Streamer mode`,description:`Hide sensitive details in the dashboard while screen sharing or streaming.`,control:`toggle`,keywords:[`streaming`,`screen share`,`privacy`],defaultValue:!1,...v},{id:`repository-roots`,path:`repoRoots`,title:`Repository roots`,description:`Directories scanned for projects when adding sessions.`,control:`list`,keywords:[`folders`,`project discovery`],defaultValue:[],listPlaceholder:`Repository root path`,listEmptyText:`No repository roots configured.`,...v},{id:`custom-agents`,path:`status:custom-agents`,title:`Custom agents`,description:`Extra agent CLIs a session can be spawned with, declared under customAgents in config.json.`,control:`readonly`,keywords:[`adapters`,`cli`],status:`custom-agents`,...b},{id:`agent-logins`,path:`status:agent-logins`,title:`Agent logins`,description:`How Claude Code and Codex sign in inside a Coder workspace. Each uses the login already on this machine; Connect signs one in for Glimmervoid alone when there is none.`,control:`readonly`,keywords:[`claude`,`codex`,`sign in`,`login`,`coder`,`remote`],status:`agent-logins`,...b},{id:`remote-setup`,path:`status:remote-setup`,title:`Remote host setup`,description:`Start a session that walks you through running Glimmervoid on another Linux machine you reach by ssh, as a service you open from your laptop and phone.`,control:`readonly`,keywords:[`remote`,`ssh`,`server`,`devbox`,`tailscale`,`pair`,`host`],status:`remote-setup`,...b}]},{id:`machine-guardrails`,level:`machine`,title:`Guardrails and unattended`,description:`What a guarded session may touch, and which unattended actions automated work may take. Claude Code sessions on Linux and macOS write anywhere this account can, except credentials, Glimmervoid's own state and the blocked folders here.`,legacyIds:[`lanes-unattended`,`unattended`],settings:[{id:`skip-permissions-by-default`,path:`skipPermissionsByDefault`,title:`Skip permission prompts by default`,description:`Start sessions whose project sets no permission choice with the agent CLI permission bypass flag.`,control:`toggle`,keywords:[`permissions`,`yolo`,`dangerously`],danger:!0,warning:`Enabling this control lets agents edit files and run shell commands without asking, and restarts running sessions that inherit it.`,defaultValue:!1,...v},{id:`sane-yolo`,path:`saneYolo`,title:`Sane YOLO`,description:`Block catastrophic commands in sessions that skip permission prompts when the cc-safety-net executable is available and trusted hooks are installed. Missing or untrusted hooks leave a session unprotected.`,control:`toggle`,keywords:[`permissions`,`yolo`,`safety`],defaultValue:!0,...y},{id:`rtk-compression`,path:`rtk`,title:`rtk output compression`,description:`Compress Bash output with the rtk executable.`,control:`toggle`,keywords:[`bash`,`tokens`],danger:!0,status:`rtk-install`,warning:`Enabling this control permits Glimmervoid to install the pinned rtk executable automatically.`,defaultValue:!1,...y},{id:`branch-gc-delete-unmerged`,path:`branchGc.deleteUnmerged`,title:`Delete unmerged branches`,description:`Also delete stale remote branches with no merge proof. Off keeps every unmerged branch.`,control:`toggle`,keywords:[`git`,`cleanup`,`orphan`],danger:!0,warning:`Enabling this control lets branch cleanup delete stale remote branches without merge proof.`,defaultValue:!1,...v},{id:`guardrails-unguarded-repos`,path:`guardrails.unguardedRepos`,title:`Unguarded repositories`,description:`Folders whose sessions run without guardrails. A session started in one of these folders, or below it, is not guarded.`,control:`list`,keywords:[`guardrails`,`opt out`,`dotfiles`],danger:!0,warning:`A session without guardrails can read credentials and write anywhere this account can.`,defaultValue:[],listPlaceholder:`Folder path`,listEmptyText:`Every repository is guarded.`,...y},{id:`guardrails-blocked-paths`,path:`guardrails.blockedPaths`,title:`Blocked folders`,description:`Extra folders and files a guarded session cannot write, on top of credentials and Glimmervoid's own state. A leading ~ means the home folder.`,control:`list`,keywords:[`guardrails`,`block`,`protect`],defaultValue:[],listPlaceholder:`~/folder`,listEmptyText:`Only the built-in list is blocked.`,...y},{id:`guardrails-unreadable-paths`,path:`guardrails.unreadablePaths`,title:`Unreadable folders`,description:`Extra folders and files a guarded session cannot read, on top of the built-in credential list. A leading ~ means the home folder.`,control:`list`,keywords:[`guardrails`,`secrets`,`credentials`],defaultValue:[],listPlaceholder:`~/folder`,listEmptyText:`Only the built-in credential list is unreadable.`,...y}]},{id:`machine-updates`,level:`machine`,title:`Updates`,description:`See which Glimmervoid version is running, which one is newest, and update in one step.`,legacyIds:[`updates`],settings:[{id:`update-actions`,path:`status:update-actions`,title:`Status and actions`,legacyIds:[`update-summary`,`update-installed`,`update-latest`,`update-last-checked`].map(e=>({sectionId:`machine-updates`,settingId:e})),description:`Whether this install is up to date, the running and newest versions, the last check, and the update and restart actions.`,control:`readonly`,keywords:[`version`,`available`,`current`,`check`,`restart`,`commit`,`installed`,`release`,`failure`],status:`update-actions`,...b},{id:`update-channel`,path:`updateChannel`,title:`Channel`,description:`Track stable releases, or Experimental builds published from every change to main before it reaches a release.`,control:`select`,options:jn(a),keywords:[`release`,`prerelease`,`next`,`beta`,`early`],defaultValue:`release`,...v},{id:`check-updates`,path:`checkForUpdates`,title:`Check for updates automatically`,description:`Check for a newer Glimmervoid at launch, while a dashboard is connected, and when this page opens.`,control:`toggle`,keywords:[`release`,`github`],defaultValue:!0,...v}]},{id:`machine-usage`,level:`machine`,title:`Usage`,description:`Local transcript accounting and estimated-cost budgets.`,legacyIds:[`usage`],settings:[{id:`usage-enabled`,path:`usage.enabled`,title:`Track token usage`,description:`Read local CLI transcripts and roll them into the Usage view and session chips.`,control:`toggle`,keywords:[`tokens`,`cost`],defaultValue:!0,status:`usage-last-report`,...v},{id:`usage-retain-days`,path:`usage.retainDays`,title:`Retain transcript detail`,description:`How long live transcript detail stays available. A monthly budget keeps detail from the start of the current month when that is longer.`,control:`number`,range:te,unit:C,keywords:[`history`,`retention`],defaultValue:90,...v},{id:`usage-daily-budget`,path:`usage.budget.dailyUsd`,title:`Daily budget`,description:`Estimated daily spend alert threshold. Alerts at 50%, 75% and 100% do not stop spending. Zero or below disables the threshold.`,control:`number`,range:he,unit:Tn,keywords:[`spend`,`alert`],defaultValue:null,integer:!1,nullable:!0,zeroIsNull:!0,step:.01,...v},{id:`usage-monthly-budget`,path:`usage.budget.monthlyUsd`,title:`Monthly budget`,description:`Estimated monthly spend alert threshold. Alerts at 50%, 75% and 100% do not stop spending. Zero or below disables the threshold.`,control:`number`,range:he,unit:Tn,keywords:[`spend`,`alert`],defaultValue:null,integer:!1,nullable:!0,zeroIsNull:!0,step:.01,...v}]},{id:`lanes-visions`,level:`lanes`,title:`Visions`,description:`Editor-buffer findings, bounded model comments, and the machine-context ingest behind them.`,legacyIds:[`lanes`,`visions`,`lanes-ingest`,`ingest`],settings:[{id:`visions-enabled`,path:`visions.enabled`,title:`Enable Visions`,description:`Set up supported editors detected on this machine, then show their buffer findings in the Visions view.`,control:`toggle`,keywords:[`editor`,`findings`,`lsp`],defaultValue:!1,...v},{id:`visions-dispatch-enabled`,path:`visions.dispatch.enabled`,title:`Enable model comments`,description:`Start bounded review sessions for local editor buffers.`,control:`toggle`,keywords:[`review`,`dispatch`],defaultValue:!1,...v},{id:`visions-max-per-hour`,path:`visions.dispatch.maxPerHour`,title:`Max per hour`,description:`Maximum review sessions dispatched per hour. One slot is reserved for edit reviews; activity-driven reviews take the rest, up to the activity cap set by visions.dispatch.activityMaxPerHour.`,control:`number`,range:d,unit:Dn,keywords:[`rate limit`,`reviews`],defaultValue:6,...v},{id:`visions-model`,path:`visions.dispatch.model`,title:`Model override`,description:`Leave blank to use the opus model alias.`,control:`text`,keywords:[`claude`,`override`],defaultValue:``,...v},{id:`visions-projects`,path:`visions.projects`,title:`Projects`,description:`Clear every selection, including unavailable projects, to accept buffers from every configured project.`,control:`projects`,keywords:[`repositories`,`filter`],defaultValue:[],...v},{id:`visions-auto-fix`,path:`visions.autoFix`,title:`Apply tier 1 fixes`,description:`Allow Visions to edit eligible open Markdown buffers, including inactive buffers, without asking.`,control:`toggle`,keywords:[`automatic`,`edits`],danger:!0,warning:`Enabling this control lets Visions edit eligible buffers without a carbon unit present.`,defaultValue:!1,...v},{id:`ingest-enabled`,path:`ingest.enabled`,title:`Enable machine context ingest`,description:`Enable the local activity feed behind Visions. Turning Visions on enables ingest unless ingest.enabled is explicitly false.`,control:`toggle`,keywords:[`events`,`activity`,`ingest`],defaultValue:!1,...v}]},{id:`lanes-posthog`,level:`lanes`,title:`PostHog`,description:`Error monitoring, investigations and traffic-spike alerts.`,legacyIds:[`posthog`],settings:[{id:`posthog-enabled`,path:`posthog.enabled`,title:`Enable PostHog monitoring`,description:`Poll PostHog error tracking and investigate issues that move.`,control:`toggle`,keywords:[`errors`,`monitoring`],defaultValue:!1,...v},{id:`posthog-host`,path:`posthog.host`,title:`Host`,description:`PostHog cloud or self-hosted HTTP URL.`,control:`text`,keywords:[`url`,`server`],defaultValue:`https://us.posthog.com`,...v},{id:`posthog-api-key`,path:`posthog.apiKey`,title:`Personal API key`,description:`Credential with read access to PostHog projects. When GLIMMERVOID_POSTHOG_API_KEY supplies it, this field is read-only.`,control:`password`,keywords:[`credential`,`token`],defaultValue:``,...v},{id:`posthog-projects`,path:`posthog.projects`,title:`Projects`,description:`PostHog project ids to monitor. config.json holds "all" or an array of ids, and an empty array monitors no project. In Settings that empty array shows as none, and an empty list saves "all".`,control:`list`,keywords:[`project ids`,`filter`],defaultValue:`all`,valueKind:`posthog-projects`,listPlaceholder:`Project id`,listEmptyText:`Every project the key can read.`,...v},{id:`posthog-interval`,path:`posthog.intervalMinutes`,title:`Poll interval`,description:`Delay between PostHog polling passes.`,control:`number`,integer:!1,step:`any`,range:d,unit:_n,keywords:[`refresh`,`schedule`],defaultValue:15,...v},{id:`posthog-max-investigations`,path:`posthog.maxConcurrentInvestigations`,title:`Max concurrent investigations`,description:`Maximum investigation sessions running together.`,control:`number`,range:d,unit:pn,keywords:[`parallel`,`workers`],defaultValue:2,...v},{id:`posthog-min-users`,path:`posthog.minUsersToInvestigate`,title:`Min users to investigate`,description:`Minimum affected users for a new issue investigation. Regressions, worsening issues and eligible error spikes bypass this minimum.`,control:`number`,range:d,unit:En,keywords:[`threshold`,`affected`],defaultValue:1,...v},{id:`posthog-traffic-enabled`,path:`posthog.trafficSpikeEnabled`,title:`Traffic spike alerts`,description:`Ping when recent unique users exceed a project baseline.`,control:`toggle`,keywords:[`analytics`,`alert`],defaultValue:!0,...v},{id:`posthog-auto-fix`,path:`posthog.autoFix`,title:`Attempt fixes for major issues`,description:`Allow an isolated agent to fix an issue, push a branch and open a pull request.`,control:`toggle`,keywords:[`automatic`,`pull request`],danger:!0,warning:`Enabling this control lets PostHog fixes commit, push and open pull requests automatically.`,defaultValue:!1,...v}]},{id:`lanes-team-review`,level:`lanes`,title:`Team review`,description:`Draft reviews of teammates' pull requests for you to post from the Reviews tab.`,legacyIds:[`team-review`,`reviews`],settings:[{id:`team-review-enabled`,path:`teamReview.enabled`,title:`Enable team review`,description:`Poll open pull requests from the team and draft a review of each one. Nothing is posted until you choose Approve or Comment.`,control:`toggle`,keywords:[`pull requests`,`github`],defaultValue:!0,...v},{id:`github-teams`,path:`github.teams`,title:`GitHub teams`,description:`Teams to search for review requests and members, one org/slug per entry. Leave empty to fall back to the legacy teamReview.org and teamReview.team keys in config.json.`,control:`list`,keywords:[`github`,`teams`,`review requests`],defaultValue:[],listPlaceholder:`org/team-slug`,listEmptyText:`No GitHub teams configured.`,...v},{id:`team-review-re-review-after-hours`,path:`teamReview.reReviewAfterHours`,title:`Re-review after`,description:`When a reviewed PR has a new head, review it again after this long since its last review. Re-run review runs it at any time.`,control:`number`,range:d,unit:vn,keywords:[`review`,`delay`],defaultValue:24,integer:!1,step:.5,...v},{id:`team-review-skip-idle-after-days`,path:`teamReview.skipIdleAfterDays`,title:`Skip PRs idle for`,description:`Leave pull requests without GitHub activity for this long out of automatic review.`,control:`number`,range:d,unit:C,keywords:[`idle`,`activity`],defaultValue:14,integer:!1,step:.5,...v},{id:`team-review-skill`,path:`teamReview.skill`,title:`Review skill`,description:`Name of a Claude Code skill installed for the review agent, for example your own PR review skill. Leave empty to let the agent review with whatever skills it has.`,control:`text`,keywords:[`skill`,`claude code`,`pr review`],defaultValue:``,...v},{id:`team-review-auto-rebase-my-prs`,path:`teamReview.autoRebaseMyPrs`,title:`Keep my pull requests rebased`,description:`On each poll, rebase your open, non-draft pull requests that are behind their base branch. A pull request with conflicts or checks still running is left alone, and a failed rebase is not retried until you push again.`,control:`toggle`,keywords:[`rebase`,`update branch`,`behind`,`my prs`],danger:!0,warning:`Enabling this control rewrites your pull request branches on GitHub. Pull before you push from a local checkout of one.`,defaultValue:!1,...v},{id:`team-review-keep-mergeable-enabled`,path:`teamReview.keepMergeableEnabled`,title:`Keep mergeable`,description:`Offer Keep mergeable on your pull requests: a guarded agent repairs conflicts and failing checks and pushes the repair. Off hides the control and starts no repair; the pull requests you chose stay chosen for when you turn it back on.`,control:`toggle`,keywords:[`repair`,`conflicts`,`my prs`],defaultValue:!0,...v},{id:`team-review-keep-mergeable-timeout`,path:`teamReview.keepMergeableTimeoutMinutes`,title:`Keep mergeable deadline`,description:`Longest a Keep mergeable repair session may run before it is stopped and nothing is pushed.`,control:`number`,range:pe,unit:_n,keywords:[`timeout`,`repair`],defaultValue:30,...v},{id:`team-review-merge-queue-enabled`,path:`teamReview.mergeQueueEnabled`,title:`Merge when ready`,description:`Offer Merge when ready on your pull requests: queued pull requests are rebased when behind and merged once ready, one per repository per poll. Off hides the control and merges nothing; the queue is kept for when you turn it back on.`,control:`toggle`,keywords:[`merge queue`,`auto merge`,`my prs`],defaultValue:!0,...v}]},{id:`lanes-workflows`,level:`lanes`,title:`Workflows`,description:`Rules that act on pull request events in the repositories you choose.`,legacyIds:[`workflows`],settings:[{id:`workflows-enabled`,path:`workflows.enabled`,title:`Run workflows`,description:`Poll the repositories your enabled rules watch and run their actions. Off stops polling and every action, whatever each rule says.`,control:`toggle`,keywords:[`pull requests`,`automation`,`master switch`],defaultValue:!0,...v},{id:`workflows-max-concurrent-sessions`,path:`workflows.maxConcurrentSessions`,title:`Concurrent agent sessions`,description:`Most workflow agent sessions running at once. Up to twenty later spawns wait for a free slot; additional spawns are dropped and logged.`,control:`number`,range:t,unit:mn,keywords:[`parallel`,`spawn`],defaultValue:2,...v},{id:`workflows-rules`,path:`status:workflow-rules`,title:`Workflow rules`,description:`Each rule watches repositories for one pull request event (opened, checks-failed, review-requested, approved, commented or merged), narrows it by author, labels, base branch, your own pull requests or a review request to your team, and then notifies you, labels or comments on the pull request, or starts a guarded agent session that pushes nothing. Rules start disabled. Turn each rule on or off here; everything else about a rule is set in config.json under workflows.rules.`,control:`readonly`,keywords:[`pull requests`,`automation`,`github`,`rules`],status:`workflows`,...b}]},{id:`lanes-benchmarks`,level:`lanes`,title:`Benchmarks`,description:`Compare agent setups on frozen cases from the suites in the benchmarks folder of the Glimmervoid home.`,legacyIds:[`benchmarks`],settings:[{id:`benchmarks-enabled`,path:`benchmarks.enabled`,title:`Enable benchmarks`,description:`Show the Bench tab. Nothing runs until you choose Mine or Run there.`,control:`toggle`,keywords:[`eval`,`arms`,`recall`,`compare`],defaultValue:!1,...v}]},{id:`lanes-coherence`,level:`lanes`,title:`Coherence (experimental)`,description:`Per-session Coherence hook status and decision journal for agent sessions.`,settings:[{id:`coherence-enabled`,path:`coherence.enabled`,title:`Show session Coherence`,description:`Shows each session's Coherence hook status and decision journal when the repository installed @posthog/coherence 1.8 or newer. Off by default.`,control:`toggle`,keywords:[`experimental`,`coherence`,`journal`,`decisions`],defaultValue:!1,...v}]},{id:`lanes-issues`,level:`lanes`,title:`Issues (experimental)`,description:`GitHub issues from your projects and teams in their own dashboard tab.`,settings:[{id:`issues-enabled`,path:`issues.enabled`,title:`Show the Issues tab`,description:`Poll GitHub issues for your projects and teams and list them in an Issues tab. Off stops the polling and hides the tab.`,control:`toggle`,keywords:[`experimental`,`issues`,`github`,`tab`],defaultValue:!1,...v}]},{id:`machine-privacy`,level:`machine`,title:`Privacy`,description:`What Glimmervoid sends about itself.`,legacyIds:[`privacy`,`telemetry`],settings:[{id:`telemetry-enabled`,path:`telemetry.enabled`,title:`Send usage data`,description:`Helps us improve Glimmervoid. Sent under a random install id: version, platform, app starts, daily activity, session starts and ends with agent kind, exit kind and duration, errors as their type, error code and scrubbed stack frames, per session token counts, models and estimated costs from the usage scan, and a salted one-way hash of your Claude and Codex account ids so installs of one account count together. Never prompts, project information, error messages, paths, repository or branch names, objectives, terminal output, emails or names. Delete my data asks for everything sent under this install to be erased and starts a new install id. GLIMMERVOID_TELEMETRY=0, DO_NOT_TRACK=1 or CI=true turn it off regardless.`,control:`toggle`,keywords:[`telemetry`,`analytics`,`tracking`,`opt out`],defaultValue:!0,...v}]},{id:`browser-shortcuts`,level:`browser`,title:`Shortcuts`,description:`Keyboard shortcuts and their reference.`,legacyIds:[`shortcuts`],settings:[{id:`next-attention-key`,path:`pref:nextAttentionKeyCode`,title:`Jump to the next session needing you`,description:`The key held with Cmd on a Mac, or Alt elsewhere, that jumps to the next session needing you. Record a new one by pressing the whole shortcut.`,control:`shortcut-key`,keywords:[`shortcut`,`keyboard`,`hotkey`,`jump`,`next`,`attention`],defaultValue:`KeyJ`,...g}]}]),Pn=Object.freeze([{id:`file-debug-mode`,path:`debugMode`,title:`Debug mode`,group:`machine-sessions`,description:`Show session-card diagnostics for state, transitions and detection signals.`,control:`toggle`,keywords:[`diagnostics`,`state`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:T,...x},{id:`file-replay-buffer`,path:`replayBufferKB`,title:`Replay buffer`,group:`machine-terminal`,description:`PTY output retained for clients that reconnect or join late.`,control:`number`,range:ie,unit:{label:`KB`,storedPerDisplay:1},keywords:[`history`,`backfill`],defaultValue:512,takesEffect:`new-sessions`,fileOnlyReason:w,...x},{id:`file-session-memory-reserve`,path:`sessionMemoryReserveMB`,title:`Session memory reserve`,group:`machine-sessions`,description:`Free memory an automatic session start waits for; 0 starts sessions without checking.`,control:`number`,range:ne,unit:{label:`MB`,storedPerDisplay:1},keywords:[`memory`,`headroom`],defaultValue:600,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-cursor-blink`,path:`cursorBlink`,title:`Cursor blink`,group:`machine-terminal`,description:`Blink the cursor in every terminal.`,control:`toggle`,keywords:[`caret`,`terminal`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-detect-background-agents`,path:`detectBackgroundAgents`,title:`Detect background agents`,group:`machine-detection-sessions`,description:`Hold completion while tracked background work is active.`,control:`toggle`,keywords:[`subagents`,`completion`],defaultValue:!0,takesEffect:`new-sessions`,fileOnlyReason:T,...x},{id:`file-record-signals`,path:`recordSignals`,title:`Record structural signals`,group:`machine-detection-sessions`,description:`Keep forensic status and hook recordings for each session. Full capture (capture.enabled) records these signals even when this is off.`,control:`toggle`,keywords:[`recordings`,`diagnostics`],defaultValue:!0,takesEffect:`new-sessions`,fileOnlyReason:T,...x},{id:`file-trace-enabled`,path:`trace.enabled`,title:`Capture session traces`,group:`machine-detection-sessions`,description:`Keep normalized Claude transcript traces for session debugging.`,control:`toggle`,keywords:[`transcripts`,`diagnostics`],defaultValue:!0,takesEffect:`restart`,fileOnlyReason:T,...x},{id:`file-detect-scheduled-wakeups`,path:`detectScheduledWakeups`,title:`Detect scheduled wakeups`,group:`machine-detection-sessions`,description:`Surface advisory wakeup timing for scheduled sessions.`,control:`toggle`,keywords:[`schedule`,`sleep`],defaultValue:!0,takesEffect:`restart`,fileOnlyReason:T,...x},{id:`file-worktree-auto-rebase`,path:`worktreeAutoRebase`,title:`Worktree auto-rebase`,group:`machine-detection-sessions`,description:`Rebase eligible session worktrees when the integration branch moves.`,control:`toggle`,keywords:[`git`,`branch`],defaultValue:!0,takesEffect:`new-sessions`,fileOnlyReason:E,...x},{id:`file-worktree-sync-on-start`,path:`worktreeSyncOnStart`,title:`Worktree sync on start`,group:`machine-detection-sessions`,description:`Fetch origin and fast-forward the local integration branch before a session starts its worktree.`,control:`toggle`,keywords:[`git`,`fetch`,`fast-forward`],defaultValue:!0,takesEffect:`new-sessions`,fileOnlyReason:E,...x},{id:`file-worktree-rerere`,path:`worktreeRerere`,title:`Worktree rerere`,group:`machine-detection-sessions`,description:`Reuse recorded Git conflict resolutions.`,control:`toggle`,keywords:[`git`,`conflicts`],defaultValue:!0,takesEffect:`restart`,fileOnlyReason:E,...x},{id:`file-integration-branch`,path:`integrationBranch`,title:`Integration branch`,group:`machine-detection-sessions`,description:`Base branch for session worktrees. Empty = each repo's default branch. Existing sessions are never retargeted.`,control:`text`,nullable:!0,keywords:[`git`,`merge`],defaultValue:null,takesEffect:`new-sessions`,fileOnlyReason:E,...x},{id:`file-worktree-root`,path:`worktreeRoot`,title:`Worktree root`,group:`machine-detection-sessions`,description:`Directory that contains session worktrees. Existing worktrees are never relocated.`,control:`text`,keywords:[`git`,`directory`],defaultValue:``,takesEffect:`new-sessions`,fileOnlyReason:E,...x},{id:`file-worktree-share`,path:`worktreeShare`,title:`Shared worktree paths`,group:`machine-detection-sessions`,description:`Local paths copied or linked during worktree preparation.`,control:`list`,keywords:[`files`,`context`],defaultValue:[`node_modules`,`.env`,`.env.local`,`.claude`],takesEffect:`new-sessions`,fileOnlyReason:An,...x},{id:`file-port`,path:`port`,title:`Local port`,group:`machine-detection-sessions`,description:`Port used by the local dashboard listener.`,control:`number`,range:me,unit:{label:`port`,storedPerDisplay:1},keywords:[`server`,`listener`],defaultValue:3e3,takesEffect:`restart`,fileOnlyReason:An,...x},{id:`file-notify-debounce-ms`,path:`notifyDebounceMs`,title:`Notification debounce`,group:`machine-detection-sessions`,description:`Delay used to coalesce notification state changes.`,control:`number`,integer:!1,step:`any`,range:d,unit:yn,keywords:[`timer`,`alerts`],defaultValue:3e3,takesEffect:`new-sessions`,fileOnlyReason:w,...x},{id:`file-phone-escalation-ms`,path:`phoneEscalationMs`,title:`Phone escalation delay`,group:`machine-detection-sessions`,description:`Delay before off-dashboard escalation.`,control:`number`,integer:!1,step:`any`,range:d,unit:bn,keywords:[`timer`,`telegram`],defaultValue:3e5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-branch-gc-enabled`,path:`branchGc.enabled`,title:`Branch cleanup`,group:`machine-detection-sessions`,description:`Enable cleanup of eligible session branches.`,control:`toggle`,keywords:[`git`,`cleanup`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:E,...x},{id:`file-branch-gc-worktrees`,path:`branchGc.worktrees`,title:`Local worktree cleanup`,group:`machine-detection-sessions`,description:`Enable cleanup of eligible local worktrees.`,control:`toggle`,keywords:[`git`,`worktree`,`cleanup`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:E,...x},{id:`file-branch-gc-prefixes`,path:`branchGc.prefixes`,title:`Branch cleanup prefixes`,group:`machine-detection-sessions`,description:`Branch prefixes that filter both remote branch cleanup and local worktree cleanup.`,control:`list`,keywords:[`git`,`branch`],defaultValue:[`glimmervoid/session/`,`worktree-agent-`],takesEffect:`now`,fileOnlyReason:E,...x},{id:`file-branch-gc-dry-run`,path:`branchGc.dryRun`,title:`Branch cleanup dry run`,group:`machine-detection-sessions`,description:`Report planned cleanup without deleting remote branches.`,control:`toggle`,keywords:[`git`,`safety`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:E,...x},{id:`file-branch-gc-stale-days`,path:`branchGc.staleDays`,title:`Branch stale days`,group:`machine-detection-sessions`,description:`Age threshold for orphan branch cleanup when unmerged deletion is on.`,control:`number`,integer:!1,step:`any`,range:d,unit:C,keywords:[`git`,`retention`],defaultValue:14,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-branch-gc-interval-ms`,path:`branchGc.intervalMs`,title:`Branch cleanup interval`,group:`machine-detection-sessions`,description:`Delay between branch cleanup passes.`,control:`number`,integer:!1,step:`any`,range:d,unit:Sn,keywords:[`git`,`schedule`],defaultValue:216e5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-custom-agents`,path:`customAgents`,title:`Custom agents`,group:`machine-detection-sessions`,description:`Extra agent CLIs a session can be spawned with. The Sessions section lists the declared agents and whether each command resolves.`,control:`json`,keywords:[`adapters`,`cli`],defaultValue:[],takesEffect:`new-sessions`,fileOnlyReason:An,...x},{id:`file-task-title-refiner-enabled`,path:`taskTitle.refiner.enabled`,title:`Refine task titles`,group:`machine-detection-sessions`,description:`Keep session card titles useful when prompts change topic by asking a model for a short title.`,control:`toggle`,keywords:[`title`,`refiner`,`card`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-task-title-refiner-model`,path:`taskTitle.refiner.model`,title:`Task title model`,group:`machine-detection-sessions`,description:`Claude model alias the title refiner asks.`,control:`text`,keywords:[`title`,`refiner`,`model`],defaultValue:`haiku`,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-task-title-refiner-min-interval`,path:`taskTitle.refiner.minIntervalSeconds`,title:`Task title refresh interval`,group:`machine-detection-sessions`,description:`Shortest pause between two title refinements of one session.`,control:`number`,integer:!1,step:`any`,range:ce,unit:S,keywords:[`title`,`refiner`,`interval`],defaultValue:60,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-task-title-refiner-timeout`,path:`taskTitle.refiner.timeoutSeconds`,title:`Task title timeout`,group:`machine-detection-sessions`,description:`Maximum time allowed for one title refinement.`,control:`number`,integer:!1,step:`any`,range:u,unit:S,keywords:[`title`,`refiner`,`deadline`],defaultValue:60,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-codex`,path:`usage.vendors.codex`,title:`Track Codex usage`,group:`machine-usage`,description:`Include local Codex CLI transcripts in usage reports.`,control:`toggle`,keywords:[`openai`,`vendor`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-grok`,path:`usage.vendors.grok`,title:`Track Grok usage`,group:`machine-usage`,description:`Include local Grok CLI transcripts in usage reports.`,control:`toggle`,keywords:[`xai`,`vendor`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-fetch-pricing`,path:`usage.fetchPricing`,title:`Fetch current model prices`,group:`machine-usage`,description:`Load public model prices when usage tracking starts, using a cached table for up to one day. Falls back to cached or bundled prices if the fetch fails; no daily refresh runs while tracking continues.`,control:`toggle`,keywords:[`rates`,`models`],defaultValue:!0,takesEffect:`restart`,fileOnlyReason:w,...x},{id:`file-usage-plan-limits`,path:`usage.planLimits`,title:`Show plan limits`,group:`machine-usage`,description:`Read the Claude plan limit the CLI reports and show it beside usage.`,control:`toggle`,keywords:[`plan`,`limits`,`quota`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-rtk-savings`,path:`usage.rtkSavings`,title:`Estimate rtk savings`,group:`machine-usage`,description:`Estimate the tokens rtk output compression saved and show it in the Usage view.`,control:`toggle`,keywords:[`rtk`,`savings`,`tokens`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-scan-interval`,path:`usage.scanIntervalMinutes`,title:`Scan interval`,group:`machine-usage`,description:`Periodic transcript polling interval. Session activity can also trigger scans between timer ticks.`,control:`number`,range:_e,unit:_n,keywords:[`poll`,`refresh`],defaultValue:5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-warehouse-retain-days`,path:`usage.warehouseRetainDays`,title:`Retain usage history`,group:`machine-usage`,description:`How long the daily usage warehouse keeps rolled-up totals after transcript detail expires.`,control:`number`,range:ye.warehouseRetainDays,unit:C,keywords:[`history`,`warehouse`,`retention`],defaultValue:365,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-session-block-hours`,path:`usage.sessionBlockHours`,title:`Session block length`,group:`machine-usage`,description:`Length of the rolling block the Usage view groups activity into.`,control:`number`,range:ye.sessionBlockHours,unit:vn,keywords:[`block`,`window`,`hours`],defaultValue:5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-cost-mode`,path:`usage.costMode`,title:`Cost mode`,group:`machine-usage`,description:`Choose whether recorded costs, calculated costs or both can appear.`,control:`select`,options:jn(on),keywords:[`pricing`,`estimate`],defaultValue:`auto`,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-usage-extra-projects-dirs`,path:`usage.extraProjectsDirs`,title:`Extra transcript folders`,group:`machine-usage`,description:`Absolute paths of additional Claude projects folders the usage scan reads.`,control:`list`,keywords:[`transcripts`,`folders`,`scan`],defaultValue:[],takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-visions-quiet-delay`,path:`visions.dispatch.quietMs`,title:`Quiet delay`,group:`lanes-visions`,description:`Editor quiet time before a scheduled review. Saves and blank-line boundaries can dispatch immediately, subject to the other review limits.`,control:`number`,range:d,unit:yn,keywords:[`debounce`,`idle`],defaultValue:3e4,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-visions-cooldown`,path:`visions.dispatch.cooldownMs`,title:`Cooldown`,group:`lanes-visions`,description:`Minimum delay between reviews of the same document. Initial orientation reviews bypass this delay.`,control:`number`,range:d,unit:bn,keywords:[`rate limit`,`delay`],defaultValue:3e5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-visions-activity-max-per-hour`,path:`visions.dispatch.activityMaxPerHour`,title:`Activity max per hour`,group:`lanes-visions`,description:`Maximum activity-driven reviews dispatched per hour, capped at the overall hourly limit minus one to reserve an edit-review slot.`,control:`number`,range:ce,unit:Dn,keywords:[`rate limit`,`events`],defaultValue:2,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-visions-dispatch-timeout`,path:`visions.dispatch.dispatchTimeoutSeconds`,title:`Dispatch timeout`,group:`lanes-visions`,description:`Maximum time allowed for one review session.`,control:`number`,range:d,unit:xn,keywords:[`deadline`,`review`],defaultValue:180,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-visions-intent-thread-ttl`,path:`visions.intent.threadTtlMs`,title:`Intent thread lifetime`,group:`lanes-visions`,description:`How long an intent thread nobody advanced stays live before it retires.`,control:`number`,range:d,unit:wn,keywords:[`intent`,`decay`,`thread`],defaultValue:2592e5,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-terminal`,path:`ingest.sources.terminal.enabled`,title:`Terminal output source`,group:`lanes-ingest`,description:`Include terminal output in the ingest feed.`,control:`toggle`,keywords:[`pty`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-agent-logs`,path:`ingest.sources.agentLogs.enabled`,title:`Agent logs source`,group:`lanes-ingest`,description:`Include local agent logs in the ingest feed.`,control:`toggle`,keywords:[`transcript`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-git`,path:`ingest.sources.git.enabled`,title:`Git activity source`,group:`lanes-ingest`,description:`Include local Git activity in the ingest feed.`,control:`toggle`,keywords:[`commits`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-fs`,path:`ingest.sources.fs.enabled`,title:`File changes source`,group:`lanes-ingest`,description:`Include watched file changes in the ingest feed.`,control:`toggle`,keywords:[`filesystem`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-shell-history`,path:`ingest.sources.shellHistory.enabled`,title:`Shell history source`,group:`lanes-ingest`,description:`Include local shell history in the ingest feed.`,control:`toggle`,keywords:[`commands`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-ingest-editor`,path:`ingest.sources.editor.enabled`,title:`Editor events source`,group:`lanes-ingest`,description:`Include local editor events in the ingest feed.`,control:`toggle`,keywords:[`buffers`,`source`],defaultValue:!1,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-investigation-timeout`,path:`posthog.investigationTimeoutSeconds`,title:`Investigation timeout`,group:`lanes-posthog`,description:`Maximum time allowed for one investigation.`,control:`number`,integer:!1,step:`any`,range:d,unit:xn,keywords:[`deadline`,`session`],defaultValue:900,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-escalation`,path:`posthog.userEscalationThreshold`,title:`Escalation threshold`,group:`lanes-posthog`,description:`Affected-user count that escalates an issue.`,control:`number`,range:d,unit:En,keywords:[`threshold`,`severity`],defaultValue:25,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-fix-timeout`,path:`posthog.fixTimeoutSeconds`,title:`Fix timeout`,group:`lanes-posthog`,description:`Maximum time allowed for one fix session.`,control:`number`,integer:!1,step:`any`,range:re,unit:xn,keywords:[`deadline`,`repair`],defaultValue:1800,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-traffic-multiplier`,path:`posthog.trafficSpikeMultiplier`,title:`Spike multiplier`,group:`lanes-posthog`,description:`Baseline multiplier required to classify a traffic spike.`,control:`number`,integer:!1,step:`any`,range:ae,unit:On,keywords:[`baseline`,`ratio`],defaultValue:3,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-traffic-min-users`,path:`posthog.trafficSpikeMinUsers`,title:`Min users to alert`,group:`lanes-posthog`,description:`Minimum recent unique users for an initial traffic-spike alert. Escalation and recovery alerts bypass this minimum.`,control:`number`,range:le,unit:En,keywords:[`threshold`,`analytics`],defaultValue:10,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-traffic-cooldown`,path:`posthog.trafficSpikeCooldownMinutes`,title:`Spike cooldown`,group:`lanes-posthog`,description:`Cooldown for new traffic spikes. Escalation and recovery alerts bypass it. Zero removes the time delay; repeated active-spike alerts are still suppressed.`,control:`number`,integer:!1,step:`any`,range:ce,unit:Cn,keywords:[`silence`,`delay`],defaultValue:360,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-traffic-baseline`,path:`posthog.trafficSpikeBaselineDays`,title:`Baseline window`,group:`lanes-posthog`,description:`Historical window used to calculate normal hourly traffic.`,control:`number`,range:fe,unit:C,keywords:[`history`,`analytics`],defaultValue:7,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-recurrence-dedupe`,path:`posthog.recurrenceDedupe`,title:`Deduplicate recurring issues`,group:`lanes-posthog`,description:`Treat an issue seen again inside the recurrence window as the same investigation instead of opening a new one.`,control:`toggle`,keywords:[`recurrence`,`dedupe`,`issues`],defaultValue:!0,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-recurrence-window-days`,path:`posthog.recurrenceWindowDays`,title:`Recurrence window`,group:`lanes-posthog`,description:`How far back an issue counts as a recurrence of an investigated one.`,control:`number`,integer:!1,step:`any`,range:d,unit:C,keywords:[`recurrence`,`window`],defaultValue:7,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-transient-recurrence-limit`,path:`posthog.transientRecurrenceLimit`,title:`Transient recurrence limit`,group:`lanes-posthog`,description:`How many times a transient issue may recur before it is investigated again.`,control:`number`,integer:!1,step:`any`,range:d,unit:hn,keywords:[`recurrence`,`transient`,`limit`],defaultValue:3,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-repo-path`,path:`posthog.repoPath`,title:`Repository path`,group:`lanes-posthog`,description:`Absolute path of the local checkout investigations read and fixes branch from, for every project the project map does not name.`,control:`text`,keywords:[`repository`,`checkout`,`path`],defaultValue:``,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-posthog-project-map`,path:`posthog.projectMap`,title:`Project map`,group:`lanes-posthog`,description:`PostHog project id to a label: the name shown for that project, and, when it is an absolute path to a checkout, the repository its issues are investigated in.`,control:`json`,keywords:[`projects`,`repositories`,`map`],defaultValue:{},takesEffect:`now`,fileOnlyReason:kn,...x},{id:`file-team-review-org`,path:`teamReview.org`,title:`GitHub organization (legacy)`,group:`lanes-team-review`,description:`Organization login that owns the team, for example PostHog. Read only when github.teams is empty.`,control:`text`,keywords:[`github`,`owner`,`legacy`],defaultValue:``,takesEffect:`now`,fileOnlyReason:`A legacy key: github.teams names teams as org/slug entries and wins whenever it is set.`,...x},{id:`file-team-review-team`,path:`teamReview.team`,title:`GitHub team (legacy)`,group:`lanes-team-review`,description:`Team slug whose members and review requests are polled. Read only when github.teams is empty.`,control:`text`,keywords:[`github`,`slug`,`legacy`],defaultValue:``,takesEffect:`now`,fileOnlyReason:`A legacy key: github.teams names teams as org/slug entries and wins whenever it is set.`,...x},{id:`file-workflows-max-actions-per-poll`,path:`workflows.maxActionsPerPoll`,title:`Actions per poll`,group:`lanes-workflows`,description:`Most actions run in one poll. The rest are dropped and logged.`,control:`number`,range:c,unit:gn,keywords:[`cap`,`rate limit`],defaultValue:20,takesEffect:`now`,fileOnlyReason:w,...x},{id:`file-workflows-rules`,path:`workflows.rules`,title:`Workflow rule definitions`,group:`lanes-workflows`,description:`The rules the Workflows section switches on and off: each names its repositories, one pull request event, its filters and its actions.`,control:`json`,keywords:[`pull requests`,`automation`,`rules`],defaultValue:[],takesEffect:`now`,fileOnlyReason:`Rule definitions are written in config.json; the Workflows section only switches each rule on or off.`,...x}]),Fn=Object.freeze({sections:Nn,fileOnly:Pn}),In=`experimental`;function Ln(e){return e.keywords.includes(In)}function Rn(e,t){return t?e:e.flatMap(e=>{let t=e.settings.filter(e=>!Ln(e));return t.length===0&&e.settings.length>0?[]:[{...e,settings:t}]})}var zn=Object.freeze(Object.fromEntries(Nn.flatMap(e=>(e.legacyIds??[]).map(t=>[t,e.id])))),Bn=Object.freeze(Nn.reduce((e,t)=>{for(let n of t.settings)for(let r of n.legacyIds??[])e[r.sectionId]={...e[r.sectionId],[r.settingId]:t.id};return e},{}));function Vn(e){let t=[],n=e=>{if(!e||typeof e!=`object`)return e;let n=Array.isArray(e)?[]:{};return t.push([e,n]),n},r=n(e);for(let e=t.pop();e;e=t.pop()){let[t,r]=e;for(let[e,i]of Object.entries(t))Object.defineProperty(r,e,{value:n(i),writable:!0,enumerable:!0,configurable:!0})}return r}function Hn(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n)return;n=n[e]}return n}function Un(e,t){let n=t.split(`.`),r=e;for(let e of n.slice(0,-1)){if(!r||typeof r!=`object`)return;r=r[e]}r&&typeof r==`object`&&delete r[n.at(-1)]}function Wn(e,t,n){let r=t.split(`.`),i=e;for(let e of r.slice(0,-1))(!i[e]||typeof i[e]!=`object`||Array.isArray(i[e]))&&(i[e]={}),i=i[e];i[r.at(-1)]=Vn(n)}function D(e){return e.flatMap(e=>e.settings)}function Gn(e){return e.access===`file-only`||e.control===`readonly`}function Kn(e){let t=String(e??``).trim().toLowerCase();if(!t||t===`all`)return`all`;if(t===`none`)return[];let n=t.split(`,`).map(e=>e.trim());return n.every(e=>/^\d+$/.test(e)&&Number.isSafeInteger(Number(e))&&Number(e)>0)?n.map(Number):null}var qn=6;function O(e,t){return e.control===`number`&&typeof t==`number`?t/(e.unit?.storedPerDisplay??1):e.valueKind===`posthog-projects`?Array.isArray(t)?t.length===0?[`none`]:t.map(String):[]:Vn(t)}function Jn(e){return e.control===`number`&&(e.unit?.storedPerDisplay??1)!==1}function k(e){return String(Number(e.toFixed(qn)))}function Yn(e,t){let n=O(e,t);return e.valueKind===`posthog-projects`&&Array.isArray(n)?n.join(`, `)||`all`:typeof n==`number`&&e.unit?`${k(n)} ${e.unit.label}`:JSON.stringify(n??null)}function A(e,t){if(e.control===`number`){if(e.nullable&&(t==null||String(t).trim()===``))return null;let n=Number(t);if(e.zeroIsNull&&n<=0)return null;let r=n*(e.unit?.storedPerDisplay??1);return e.integer===!1?r:Math.round(r)}if(e.valueKind===`posthog-projects`)return Kn(Array.isArray(t)?t.join(`,`):t);if(e.control===`text`||e.control===`password`){let n=String(t??``).trim();return e.nullable&&!n?null:n}return Vn(t)}function j(e){return String(e||``).toLowerCase().match(/[a-z0-9]+/g)||[]}var Xn=3,Zn=2,Qn=1,$n=3,er=30,tr=16;function nr(e,t){return e===t?Xn:e.startsWith(t)?Zn:t.length>=$n&&e.includes(t)?Qn:0}function M(e,t,n){let r=0;for(let n of t){let t=Math.max(0,...e.map(e=>nr(e,n)));if(t===0)return 0;r+=t}return r*n}function rr(e){return e.options?.map(e=>e.label).join(`, `)??``}function ir(e){return fr(e.group??``)?.title??``}function ar(e,t,n){let r=M(j(e.title),n,1e3),i=M(j(e.keywords.join(` `)),n,100),a=M(t,n,10),o=M(j(e.path),n,10),s=M(j(rr(e)),n,10),c=M(j(e.description),n,1);return r+i+a+o+s+c}function or(e){return e.section?.title??``}function sr(e,t){return Number(e.section===null)-Number(t.section===null)}function cr(e,t,n){return[[`title`,e.title],[`keywords`,e.keywords.join(` `)],[`section`,t?.title??ir(e)],[`description`,e.description],[`path`,e.path],[`options`,rr(e)]].flatMap(([e,t])=>{let r=[];for(let e of t.matchAll(/[a-z0-9]+/gi)){let t=e[0].toLowerCase();for(let i of n){if(nr(t,i)===0)continue;let n=e.index+t.indexOf(i);r.push({start:n,end:n+i.length})}}let i=[];for(let e of r.sort((e,t)=>e.start-t.start||e.end-t.end)){let t=i.at(-1);t&&e.start<=t.end?t.end=Math.max(t.end,e.end):i.push({...e})}return i.length?[{field:e,text:t,spans:i}]:[]})}function lr(e,t,n=[]){let r=j(t).slice(0,tr);if(r.length===0)return[];let i=[];for(let t of e){let e=j(t.title);for(let n of t.settings){let a=ar(n,e,r);a!==0&&i.push({section:t,setting:n,score:a,matches:cr(n,t,r)})}}for(let e of n){let t=ar(e,j(ir(e)),r);t!==0&&i.push({section:null,setting:e,score:t,matches:cr(e,null,r)})}return i.sort((e,t)=>t.score-e.score||sr(e,t)||or(e).localeCompare(or(t))||e.setting.title.localeCompare(t.setting.title)).slice(0,er)}function ur(e,t,n={},r={}){let i=/^#settings\/([^/]+)(?:\/([^/]+))?$/.exec(String(e||``));if(!i)return null;let a,o;try{a=decodeURIComponent(i[1]),o=i[2]?decodeURIComponent(i[2]):null}catch{return null}let s=n[a]||a,c=(o?r[s]?.[o]:void 0)||s,l=t.find(e=>e.id===c);if(!l)return null;let u=o?l.settings.find(e=>e.id===o||e.legacyIds?.some(e=>e.settingId===o&&e.sectionId===s)):null;return o&&!u?null:{sectionId:c,settingId:u?.id||null,hash:`#settings/${c}${u?`/${u.id}`:``}`}}function dr(e){let t=new Map,n=new Map;for(let r of[...D(e.sections),...e.fileOnly])t.set(r.id,r),n.set(r.path,r);return{byId:t,byPath:n}}dr(Fn);function fr(e,t=Fn){let n=t.sections.find(t=>t.id===e);return n?{title:n.title,description:n.description}:Mn[e]??null}function pr({checked:e=[],stored:t=[],rendered:n=[]}={}){let r=new Set(n),i=[...e];for(let e of t)typeof e==`string`&&e.trim()&&(r.has(e)||i.includes(e)||i.push(e));return i}function mr(e,t){let n=new Set(e.map(e=>e.id)),r=[...new Set(t)].filter(e=>!n.has(e));return[...e,...r.map(e=>({id:e,name:`Unavailable project (${e})`}))]}var hr=new WeakMap,gr=`Configured`,_r=`•`.repeat(12),vr=`Each line must be a positive whole-number PostHog project id, or the one word none.`,yr=3,br=new Set([`customAgents`]),xr=1e-9,Sr=`Lanes`,Cr=Object.freeze({now:`Applies now`,"new-sessions":`New sessions`,restart:`After restart`}),wr=Object.freeze({browser:`This browser`,machine:`This machine`});function Tr(e,t){let n=t.secretSources;if(!n||typeof n!=`object`)return null;let r=n[e.path];return typeof r==`string`?r:null}function Er(e){let t=e.rtkInstall;return t?.status===`installing`?`No rtk binary found. Glimmervoid is installing it into ~/.glimmervoid/bin now.`:e.rtkInstallSupported===!1?`No rtk binary found. Automatic installation is unavailable on this server platform; install a compatible binary manually.`:t?.status===`failed`?`No rtk binary found. The last install attempt failed: ${t.reason||`unknown reason`}. A save can retry after the ten-minute failure cooldown; saves during the cooldown skip installation.`:`No rtk binary found. Saving requests installation into ~/.glimmervoid/bin on supported server platforms, subject to installer eligibility.`}function Dr(e){return e.control===`password`}function Or(e){return`${e.path}${gr}`}function N(e,t){if(Object.is(e,t))return!0;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>N(e,t[n]));if(!e||!t||typeof e!=`object`||typeof t!=`object`)return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.hasOwn(t,n)&&N(e[n],t[n]))}function kr(e){return hr.get(e)||null}function Ar(e){return Array.isArray(e)?e.map(e=>String(e)):[]}function jr(e){return e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(e=>e!==``)}function Mr(e){let t=e.range;if(!t)return null;let n={min:Number(O(e,t.min))};return t.max!=null&&(n.max=Number(O(e,t.max))),t.exclusiveMin&&(n.exclusiveMin=!0),n}function Nr(e){let t=`Default ${Yn(e,e.defaultValue)}`;return Jn(e)?`${t}, stored as ${JSON.stringify(e.defaultValue)} ${e.unit?.storedLabel??``}`.trimEnd():t}function Pr(e,t){let n=Nr(e),r=br.has(e.path)?void 0:Hn(t,e.path);if(r===void 0)return{currentText:null,defaultText:n,jsonFragment:null};let i={};return Wn(i,e.path,r),{currentText:`Current ${Yn(e,r)}`,defaultText:n,jsonFragment:JSON.stringify(i,null,2)}}function Fr(e,t,n){let r=t??e.find(e=>e.id===n.group);if(!r)return fr(n.group??``)?.title??`config.json`;let i=e.find(e=>e.id===r.parent);return i?`${i.title} / ${r.title}`:r.level===`lanes`?`${Sr} / ${r.title}`:r.title}function Ir(e,t){return e.filter(e=>e.parent===t)}function Lr(e,t){let n=e.find(e=>e.id===t);return n?n.parent?e.find(e=>e.id===n.parent)??n:n:null}function Rr(e){return e.filter(e=>!e.parent)}function zr(e){let t=e.filter(e=>e.level===`lanes`);return[{heading:null,sections:e.filter(e=>e.level!==`lanes`)},{heading:Sr,sections:t}].filter(e=>e.sections.length>0)}function Br(e,t,n,r){return r?`hidden`:n.trim()?`search`:t&&Lr(e,t)?`section`:`list`}function Vr(e,t={}){let n={};for(let r of D(e)){if(Gn(r))continue;if(r.path.startsWith(`pref:`)){let e=r.path.slice(5),i=t.prefs?.[e]??t[r.path];n[r.path]=O(r,i??r.defaultValue);continue}if(Dr(r)){let e=Hn(t,Or(r))===!0;n[r.path]=e?_r:``;continue}let e=Hn(t,r.path);n[r.path]=O(r,e??r.defaultValue)}return hr.set(n,Vn(t)),n}function Hr(e,t,n){let r=D(e).filter(e=>Gn(e)||e.path.startsWith(`pref:`)||Tr(e,kr(t)||{})||Dr(e)&&n[e.path]===_r?!1:!N(t[e.path],n[e.path]));if(r.length===0)return{};let i=kr(t)||{},a=(Array.isArray(i.projectChoices)?i.projectChoices:[]).map(e=>e.id).filter(e=>typeof e==`string`),o={},s=new Set;for(let e of r){let[r]=e.path.split(`.`);if(!e.path.includes(`.`)){o[r]=A(e,n[e.path]);continue}if(!s.has(r)){let e=i[r];o[r]=e&&typeof e==`object`&&!Array.isArray(e)?Vn(e):{},s.add(r)}let c=A(e,n[e.path]);if(e.control===`projects`){let n=t[e.path];c=pr({checked:Array.isArray(c)?c:[],stored:Array.isArray(n)?n:[],rendered:mr(a.map(e=>({id:e,name:e})),Array.isArray(n)?n:[]).map(e=>e.id)})}Wn(o,e.path,c)}for(let t of D(e))Dr(t)&&Un(o,Or(t));return delete o.secretSources,o}function Ur(e,t,n,r){return vi(Hr(e,t,{...t,[n.path]:r}))}function Wr(e){let t=e.unit?.label;return t?` of ${t}`:``}function P(e){let t=Mr(e);if(!t)return`Allowed range is unavailable.`;let n=`${e.integer!==!1&&!Jn(e)?`whole number`:`number`}${Wr(e)}`;return t.exclusiveMin&&t.min===0?`Must be a positive ${n}.`:t.max==null?`Must be a ${n} ${t.exclusiveMin?`above`:`of at least`} ${k(t.min)}.`:`Must be a ${n} between ${k(t.min)} and ${k(t.max)}.`}function Gr(e){return`Must be a multiple of ${Yn(e,1)}.`}function Kr(e){return Math.abs(e-Math.round(e))<xr&&Number.isSafeInteger(Math.round(e))}function qr(e,t){return Number(A({...e,integer:!1,nullable:!1,zeroIsNull:!1},t))}function Jr(e,t){if(e.nullable&&(t==null||String(t).trim()===``))return null;let n=e.range;if(!n)return`Allowed range is unavailable.`;if(t==null||String(t).trim()===``)return P(e);let r=Number(t);if(!Number.isFinite(r))return P(e);if(e.zeroIsNull&&r<=0)return null;let i=qr(e,r);if(e.integer!==!1&&!Kr(i))return Jn(e)?Gr(e):P(e);let a=Number(A(e,r));return n.exclusiveMin&&a<=n.min||!n.exclusiveMin&&a<n.min||n.max!=null&&a>n.max?P(e):null}function Yr(e,t,n=!1){return n?P(e):Jr(e,t.trim())}function Xr(e,t){let n=t.trim();if(e.nullable&&n===``)return null;let r=Number(n);return e.zeroIsNull&&r<=0?null:r}function Zr(e){if(e==null||e===``)return``;let t=Number(e);return Number.isFinite(t)?k(t):String(e)}function Qr(e,t){return Array.isArray(t)?e.valueKind===`posthog-projects`&&A(e,t)===null?vr:null:`Must be a list.`}function $r(e,t){let n={};for(let r of D(e)){if(Gn(r))continue;let e=null;r.control===`number`&&(e=Jr(r,t[r.path])),r.control===`list`&&(e=Qr(r,t[r.path])),r.control===`select`&&r.options&&!r.options.some(e=>e.value===t[r.path])&&(e=`Choose one of the available options.`),e&&(n[r.id]=e)}return ei(D(e),t,n),n}function ei(e,t,n){for(let r of e){let i=e.find(e=>e.id===r.maximumSettingId);if(!i||n[r.id]||n[i.id])continue;let a=t[r.path],o=t[i.path];Number(A(r,a))>Number(A(i,o))&&(n[r.id]=`Minimum must not exceed the maximum (${Zr(o)}).`,n[i.id]=`Maximum must not be below the minimum (${Zr(a)}).`)}}function ti(e,t){return D(e).find(e=>e.id===t.maximumSettingId||e.maximumSettingId===t.id)}function ni(e,t,n){let r=ti(e,t);return $r([{id:`scoped`,level:`machine`,title:``,description:``,settings:r?[t,r]:[t]}],n)[t.id]??null}function ri(e,t){return e.control===`number`?Xr(e,t):e.control===`list`?jr(t):t}function ii(e,t){return A(e,e.control===`list`?Ar(t):t)}function ai(e){return e?.isDirty===!0}function oi(e,t,n,r,i,a=!1){if(!ai(n))return{kind:`unchanged`};let o=t.control===`number`?Yr(t,r,a):null;if(o)return{kind:`invalid`,error:o};let s=ri(t,r);if(N(A(t,s),ii(t,n.base)))return{kind:`unchanged`};let c=ni(e,t,{...i,[t.path]:s});return c?{kind:`invalid`,error:c}:{kind:`changed`,value:s}}function si(e){return Dr(e)?``:O(e,e.defaultValue)}function ci(e,t){return N(t,si(e))}function li(e){return e.presentation?e.presentation:(e.options?.length??0)<=yr?`segmented`:`select`}function ui(e){return Array.isArray(e)?e.length>0:typeof e==`string`?e.trim()!==``:e===!0}function di(e,t){return e.danger===!0&&!!e.warning&&ui(t)}function fi(e,t){return di(e,t)}function pi(e){return e.title.charAt(0).toLowerCase()+e.title.slice(1)}function mi(e){return Dr(e)?`Reset removes the stored ${pi(e)}. Anything that relies on it stops until a new one is saved.`:fi(e,si(e))?e.warning??``:null}function hi(e){return[e.repos.join(`, `),e.trigger,e.actions.map(e=>e.type).join(`, `)].join(` `)}function gi(e){if(e==null)return[`No rules. Add workflows.rules to config.json.`];let t=ue.safeParse(e);return t.success?t.data.rules.length===0?[`No rules. Add workflows.rules to config.json.`]:t.data.rules.map(e=>[e.name,e.enabled?`enabled`:`disabled`,hi(e)].join(` `)):[`The workflows block is invalid, so no rule runs: ${t.error.issues[0]?.message??`unknown problem`}`]}function _i(e){let t=ue.safeParse(e??{});return t.success?t.data.rules.map(e=>({id:e.id,name:e.name,isEnabled:e.enabled,summary:hi(e)})):[]}function vi(e){let t=e.workflows;return typeof t!=`object`||!t||Array.isArray(t)?e:{...e,workflows:Object.fromEntries(Object.entries(t).filter(([e])=>e!==`rules`))}}var yi=2200,bi=1600,xi=15e3,Si=`https://glimmervoid.dev`,Ci=`browser-appearance`,wi=`flying-animals`,Ti=Object.freeze({ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}),Ei=`lanes-features`,Di=Object.freeze({id:Ei,level:`lanes`,title:`Features`,description:`Optional tabs, each hidden until its own toggle is on.`,settings:[]}),Oi=`browser-shortcuts`,ki=`browser-status-key`,Ai=Object.freeze({id:ki,level:`browser`,title:`Status key and about`,description:`What each session status and pull request icon means, and build information.`,settings:[]}),ji=Object.freeze({sounds:()=>_t(),themes:rt});function Mi(e){if(!e.optionsFrom)return e;let t=ji[e.optionsFrom]?.()??[];return{...e,options:t.map(e=>({value:e.id,label:e.label}))}}function Ni(e){return e.isExperimentalBuild===!0}function Pi(){return Rn(Fn.sections,Ni(h()))}function Fi(){let e=Pi().map(e=>({...e,settings:e.settings.map(Mi)})),t=e.findIndex(e=>e.id===Oi)+1,n=[...e.slice(0,t),Ai,...e.slice(t)],r=n.findIndex(e=>e.level===`lanes`);return Object.freeze([...n.slice(0,r),Di,...n.slice(r)])}var F=Fi(),Ii=Ni(h()),I=!1,Li=null,Ri=null,L=null,R=null,z=null,zi=null,B=null,V=null,H=F[0],U=h(),W={},Bi=new Map,Vi=new Map,G=new Map,K=new WeakMap,Hi=Promise.resolve(),Ui=new Map,q=``,Wi=!1,Gi=new Set,J=new Map;function Ki(){return{themeId:Be(),flyingAnimalsEnabled:Ze(),...We(),soundEnabled:Fe(),soundId:mt(Ue()),notificationsEnabled:Re(),sessionUsageChips:Ye(),phoneArrowPad:Xe(),nextAttentionKeyCode:Ge()}}function qi(e){W=Vr(F,{...e,prefs:Ki()})}function Y(e){return G.has(e.id)?G.get(e.id):W[e.path]}function Ji(e){return[e,...Ir(F,e.id)]}function Yi(e){return Ji(e).flatMap(e=>e.settings)}function Xi(e){return F.find(t=>t.settings.some(t=>t.id===e.id))??H}function Zi(e,t=null){history.replaceState(history.state,``,Ft(e,t))}function Qi(e){requestAnimationFrame(()=>{let t=document.getElementById(e),n=t?.closest(`.settings-view-advanced-panel`);n&&(I=!0,n.hidden=!1,V?.querySelector(`.settings-view-advanced-toggle`)?.setAttribute(`aria-expanded`,`true`));let r=t?.closest(`.settings-view-setting`);r&&(r.scrollIntoView({block:`center`}),r.classList.remove(`settings-view-setting-flash`),requestAnimationFrame(()=>r.classList.add(`settings-view-setting-flash`)))})}function $i(e){e.replaceChildren();for(let t of ze(Kt,zt())){let n=f(`div`,`shortcut-group`);n.appendChild(f(`h2`,`settings-view-subsection-title`,t.title));let r=f(`dl`,`shortcut-rows`);for(let e of t.items){let t=f(`dd`,`shortcut-keys`);e.combos.forEach((e,n)=>{n>0&&t.appendChild(f(`span`,`shortcut-sep`,`/`)),Rt(t,e)}),r.append(f(`dt`,`shortcut-label`,e.label),t)}n.appendChild(r),e.appendChild(n)}}function ea(e){return Xt().find(t=>t.gate!==void 0&&`fromSettings`in t.gate&&t.gate.fromSettings===e)?.label}function ta(e){let t=f(`ul`,`settings-view-stack settings-features`);for(let e of Mt){let n=F.find(t=>t.id===e.sectionId),r=aa(e.settingId),i=ea(Ht[e.rule]);if(!n||!r||!i)continue;let a=Y(r)===!0,o=f(`li`,`settings-feature`),s=f(`div`,`settings-feature-head`);s.append(f(`span`,`settings-feature-name`,i),po(`feature`,a?`On`:`Off`)),o.append(s,f(`p`,`settings-view-section-description`,n.description),Wt(e.sectionId,e.settingId,r.title)),t.appendChild(o)}e.appendChild(t)}function na(e){let t=new URL(e,Si),{telemetryInstallId:n}=U;return typeof n==`string`&&n&&t.searchParams.set(`gv`,n),t.href}function ra(e,t){let n=f(`a`,`settings-about-link`,e);return n.href=t,n.target=`_blank`,n.rel=`noopener`,n}function ia(e){let t=f(`div`,`settings-about`),n=f(`span`,`settings-about-version`,`GLIMMERVOID `);n.appendChild(f(`span`,`settings-about-v`,`v0.45.1-next.45`));let r=f(`span`,`settings-about-links`);r.append(ra(`GitHub`,`https://github.com/${an}`),ra(`Changelog`,`https://github.com/${an}/blob/main/CHANGELOG.md`),ra(`Website`,na(`/`))),t.append(n,r),e.appendChild(t)}function aa(e){return F.flatMap(e=>e.settings).find(t=>t.id===e)??null}function oa(e){if(W[`pref:soundEnabled`]===e)return;W[`pref:soundEnabled`]=e;let t=aa(`alert-sounds-enabled`);t&&$(t)}var sa={"pref:flyingAnimalsMinGapSeconds":e=>De(Number(e)),"pref:flyingAnimalsMaxGapSeconds":e=>Me(Number(e)),"pref:flyingAnimalsMinDurationSeconds":e=>Pe(Number(e)),"pref:flyingAnimalsMaxDurationSeconds":e=>je(Number(e)),"pref:flyingAnimalsScale":e=>Ae(Number(e)),"pref:flyingAnimalsOnPhone":e=>ke(e===!0)};function ca(e,t){if(e.path===`pref:sessionUsageChips`){Le(t===!0),gt(t===!0);return}if(e.path===`pref:phoneArrowPad`){Oe(t===!0),ot(t===!0);return}if(e.path===`pref:nextAttentionKeyCode`){we(String(t)),Ut(Ge());let e=V?.querySelector(`.settings-view-shortcuts`);e&&$i(e);return}if(e.path===`pref:themeId`){qe(String(t)),Pt(String(t));return}if(e.path===`pref:flyingAnimalsEnabled`){Ce(t===!0),Bt(t===!0);return}let n=sa[e.path];n?(n(t),Bt(Ze())):e.path===`pref:soundEnabled`?ct(t===!0):e.path===`pref:soundId`?(Se(String(t)),pt(String(t))):e.path===`pref:notificationsEnabled`&&(Ie(t===!0),t===!0&&kt().then(()=>$(e,{force:!0})))}function X(e,t){let n=Vi.get(e.id);n!==void 0&&clearTimeout(n),Vi.delete(e.id),t&&Bi.set(e.id,t),t||Bi.delete(e.id),Eo(e)}function la(e){X(e,{tone:`saved`,text:`Saved`}),Vi.set(e.id,window.setTimeout(()=>X(e,null),yi))}function Z(e,t){Ui.delete(e.id),e.path.startsWith(`pref:`)?(W[e.path]=t,ca(e,t),$(e),la(e)):G.has(e.id)&&JSON.stringify(G.get(e.id))===JSON.stringify(t)||(G.set(e.id,t),X(e,{tone:`saving`,text:`Saving`}),Hi=Hi.then(()=>ua(e,t)))}async function ua(e,t){let n=Ur(F,W,e,t);if(Object.keys(n).length===0)G.delete(e.id),X(e,null),$(e);else{X(e,{tone:`saving`,text:`Saving`});try{let r=await be(`update-settings`,{settings:n});if(G.get(e.id)===t&&G.delete(e.id),r.type===`settings-error`){X(e,{tone:`error`,text:String(r.message)}),$(e,{force:!0});return}if(r.type!==`settings-updated`){X(e,{tone:`error`,text:`The server did not confirm the save.`}),$(e,{force:!0});return}At(r.settings),la(e)}catch(n){G.get(e.id)===t&&G.delete(e.id),X(e,{tone:`error`,text:n?.message||`Failed to save the setting.`}),$(e,{force:!0})}}}function da(e,t){t&&Ui.set(e.id,t),t||Ui.delete(e.id),Eo(e)}function fa(e,t){if(!t.exclusiveMin)return t.min;if(e.integer!==!1)return t.min+1}function pa(e){return e?`On`:`Off`}function ma(e){let t=f(`div`,`settings-view-toggle-wrap`),n=f(`label`,`settings-view-toggle`),r=f(`input`,`settings-view-checkbox`);r.type=`checkbox`,r.checked=Y(e)===!0,e.id===`desktop-notifications`&&!Vt()&&(r.checked=!1,r.disabled=!0),r.setAttribute(`aria-labelledby`,e.id);let i=f(`span`,`settings-view-toggle-state`,pa(r.checked));return r.addEventListener(`change`,()=>{let t=r.checked;fi(e,t)?(r.checked=!1,i.textContent=pa(!1),nt({title:e.title,message:e.warning??``,confirmLabel:`Turn on`,danger:!0,onConfirm:()=>Z(e,!0)})):(i.textContent=pa(t),Z(e,t))}),n.append(r,i),t.appendChild(n),t}function ha(e){let t=f(`div`,`settings-view-shortcut-key`),n=Ct(Je(`next-attention`,Kt,String(Y(e)))),r=f(`button`,`btn-dialog btn-dialog-cancel`,`Record`);r.type=`button`;let i=f(`span`,`settings-view-shortcut-key-prompt`);return i.setAttribute(`role`,`status`),r.addEventListener(`click`,()=>ga(e,t,r,i)),t.append(n,r,i),t}function ga(e,t,n,r){let i=()=>{window.removeEventListener(`keydown`,o,!0),window.removeEventListener(`pointerdown`,a,!0),window.removeEventListener(`focusin`,a,!0),n.disabled=!1,r.textContent=``},a=e=>{e.target instanceof Node&&t.contains(e.target)||i()},o=t=>{if(!n.isConnected||!n.checkVisibility()){i();return}t.preventDefault(),t.stopImmediatePropagation();let r=Ke(t,Kt);r.kind!==`ignored`&&(r.kind===`refused`?da(e,r.reason):(i(),da(e,null),n.focus(),r.kind===`recorded`&&Z(e,r.keyCode)))};da(e,null),n.disabled=!0,r.textContent=`Press the new shortcut, or Esc to cancel.`,window.addEventListener(`keydown`,o,!0),window.addEventListener(`pointerdown`,a,!0),window.addEventListener(`focusin`,a,!0)}function _a(e,t,n){e.addEventListener(`blur`,t),e.addEventListener(`keydown`,e=>{e.key===`Enter`?(e.preventDefault(),t()):e.key===`Escape`&&(e.preventDefault(),n())})}function va(e){return e instanceof HTMLTextAreaElement||e instanceof HTMLInputElement&&[`text`,`number`,`password`].includes(e.type)}function ya(e,t){K.set(t,{base:Y(e),isDirty:!1}),t.addEventListener(`input`,()=>{let e=K.get(t);e&&(e.isDirty=!0)})}function Q(e,t,n){t.value!==n&&(t.value=n),K.set(t,{base:Y(e),isDirty:!1}),da(e,null)}function ba(e,t,n,r=!1){let i=K.get(t);if(!i)return;let a=oi(F,e,i,t.value,W,r);a.kind===`invalid`?da(e,a.error):a.kind===`unchanged`?Q(e,t,n):fi(e,a.value)?(Q(e,t,n),nt({title:e.title,message:e.warning??``,confirmLabel:`Save`,danger:!0,onConfirm:()=>Z(e,a.value)})):(K.set(t,{base:a.value,isDirty:!1}),Z(e,a.value))}function xa(e){let t=f(`input`,`settings-view-input`);t.type=e.control===`password`?`password`:`text`;let n=()=>String(Y(e)??``);t.value=n(),e.control===`password`&&(t.value=``,t.placeholder=n()?`Configured`:`Not configured`);let r=Tr(e,U);return r&&(t.disabled=!0,t.setAttribute(`aria-description`,`Supplied by ${r}`)),t.autocomplete=`off`,t.spellcheck=!1,t.setAttribute(`aria-labelledby`,e.id),ya(e,t),_a(t,()=>{if(e.control===`password`){let n=t.value;if(n===``)return;Q(e,t,``),Z(e,n)}else ba(e,t,n())},()=>Q(e,t,e.control===`password`?``:n())),t}function Sa(e){let t=f(`input`,`settings-view-input`),n=Mr(e);t.type=`number`;let r=()=>Zr(Y(e));t.value=r(),t.step=e.integer===!1?String(e.step??`any`):`1`;let i=n?fa(e,n):void 0;i!=null&&(t.min=String(i)),n?.max!=null&&(t.max=String(n.max)),t.autocomplete=`off`,t.setAttribute(`aria-labelledby`,e.id),ya(e,t),_a(t,()=>ba(e,t,r(),t.validity.badInput),()=>Q(e,t,r()));let a=e.unit?.label;if(!a)return t;let o=f(`div`,`settings-view-number`),s=f(`span`,`settings-view-unit`,a);return s.setAttribute(`aria-hidden`,`true`),t.setAttribute(`aria-description`,a),o.append(t,s),o}function Ca(e,t){let n=[...e.querySelectorAll(`[role="radio"]`)],r=n.some(e=>e.dataset.value===t);for(let[e,i]of n.entries()){let n=i.dataset.value===t;i.setAttribute(`aria-checked`,String(n)),i.tabIndex=n||!r&&e===0?0:-1}}function wa(e,t,n){n!==String(Y(e))&&(Ca(t,n),Z(e,n),Ca(t,String(Y(e))))}function Ta(e){let t=f(`div`,`settings-view-segmented`);t.setAttribute(`role`,`radiogroup`),t.setAttribute(`aria-labelledby`,e.id);let n=e.options??[];for(let r of n){let n=f(`button`,`settings-view-segment`,r.label);n.type=`button`,n.dataset.value=r.value,n.setAttribute(`role`,`radio`),n.addEventListener(`click`,()=>wa(e,t,r.value)),t.appendChild(n)}return t.addEventListener(`keydown`,r=>{let i=Ti[r.key];if(!i||n.length===0)return;r.preventDefault();let a=Math.max(0,n.findIndex(t=>t.value===String(Y(e)))),o=n[(a+i+n.length)%n.length];wa(e,t,o.value),t.querySelector(`[data-value="${CSS.escape(o.value)}"]`)?.focus()}),Ca(t,String(Y(e))),t}function Ea(e){let t=f(`select`,`settings-view-input`);t.setAttribute(`aria-labelledby`,e.id);for(let n of e.options??[]){let e=f(`option`,null,n.label);e.value=n.value,t.appendChild(e)}return t.value=String(Y(e)),t.addEventListener(`change`,()=>Z(e,t.value)),t}function Da(e,t){let n=e.valueKind===`posthog-projects`?`One project id per line, or none for no project. Shift+Enter adds a line.`:`One entry per line. Shift+Enter adds a line.`;return t.length>0||!e.listEmptyText?n:`${e.listEmptyText} ${n}`}function Oa(e){let t=f(`textarea`,`settings-view-input settings-view-list-input`),n=()=>Ar(Y(e)),r=()=>n().join(`
|
|
3
|
+
`);t.rows=3,t.value=r(),t.autocomplete=`off`,t.spellcheck=!1,t.placeholder=e.listPlaceholder??``,t.setAttribute(`aria-labelledby`,e.id),ya(e,t),t.addEventListener(`blur`,()=>ba(e,t,r())),t.addEventListener(`keydown`,n=>{n.key===`Escape`?(n.preventDefault(),Q(e,t,r())):n.key!==`Enter`||n.shiftKey||(n.preventDefault(),ba(e,t,r()))});let i=f(`div`,`settings-view-list`);return i.append(t,f(`span`,`settings-view-list-hint`,Da(e,n()))),i}var ka=null;function Aa(e){let t=Lt(Xt().map(e=>e.view),Ar(Y(e))),n=f(`ol`,`settings-view-tab-order`);n.setAttribute(`aria-labelledby`,e.id);for(let[r,i]of t.entries()){let a=Xt().find(e=>e.view===i)?.label??i,o=f(`li`,`settings-view-tab-order-item`);o.append(f(`span`,`settings-view-tab-order-label`,a),ja(e,t,i,r-1,`Move up`,`Move ${a} up`),ja(e,t,i,r+1,`Move down`,`Move ${a} down`)),n.append(o)}return n}function ja(e,t,n,r,i,a){let o=`${n}:${i}`,s=f(`button`,`btn-dialog btn-dialog-cancel`,i);return s.type=`button`,s.setAttribute(`aria-label`,a),s.disabled=r<0||r>=t.length,o===ka&&(s.dataset.restoresFocus=`true`),s.addEventListener(`click`,()=>{ka=o,Z(e,Gt(t,n,r))}),s}function Ma(e){let t=f(`div`,`settings-view-projects`),n=Y(e),r=new Set(Array.isArray(n)?n:[]),i=Array.isArray(U.projectChoices)?U.projectChoices:[];i.length===0&&t.appendChild(f(`div`,`settings-empty`,`No configured projects are available.`));for(let n of mr(i,[...r])){let i=f(`label`,`settings-view-project-choice`),a=f(`input`,`settings-view-checkbox`);a.type=`checkbox`,a.checked=r.has(n.id),a.addEventListener(`change`,()=>{let t=Y(e),r=new Set(Array.isArray(t)?t:[]);a.checked&&r.add(n.id),a.checked||r.delete(n.id),Z(e,[...r])}),i.append(a,document.createTextNode(n.name)),t.appendChild(i)}return t}function Na(e,t,{isPrimary:n=!1,isEnabled:r=!0}={}){let i=f(`button`,`btn-dialog ${n?`btn-dialog-confirm`:`btn-dialog-cancel`} settings-update-button`,e);return i.type=`button`,i.disabled=!r,i.addEventListener(`click`,t),i}function Pa(e){let t=f(`span`,`settings-update-action-status`,e??``);return t.setAttribute(`role`,`status`),t}function Fa(){let{isCheckInFlight:e,checkSendFailure:t}=m();return e?`Checking for updates.`:t}function Ia(){let{status:e,lastAutoCheckAt:t}=m();e?(Wi=!1,se({status:e,checkForUpdates:U.checkForUpdates,now:Date.now(),lastAutoCheckAt:t})&&wt()):Wi=!0}function La(e){return e===`update`?Na(`Update`,$t,{isPrimary:!0}):e===`restart`?Na(`Restart`,Zt,{isPrimary:!0}):Na(`Check for updates`,wt,{isEnabled:!m().isCheckInFlight})}function Ra(){let{status:e,journal:t,request:n}=m(),r=o({status:e,journal:t,request:n}),i=f(`div`,`settings-update-actions`);if(r.actions.length>0){let e=f(`div`,`settings-update-buttons`);e.append(...r.actions.map(La)),i.appendChild(e)}let a=Fa();return a&&i.appendChild(Pa(a)),r.note&&i.appendChild(Pa(r.note)),r.command&&i.appendChild(f(`code`,`settings-update-command`,r.command)),i}function za(e,...t){let n=f(`div`,`settings-update-fact`);return n.append(f(`span`,`settings-update-fact-label`,e),...t),n}function Ba(){let e=n(m().journal);if(!e)return null;let t=f(`div`,`settings-update-progress`);t.dataset.state=e.state,t.setAttribute(`role`,`status`),e.terminalLine&&t.appendChild(f(`div`,`settings-update-terminal`,e.terminalLine));let r=f(`ol`,`settings-update-steps`);for(let t of e.steps){let e=f(`li`,`settings-update-step`);e.dataset.status=t.status,e.append(f(`span`,`settings-update-step-state`,t.status),f(`span`,`settings-update-step-label`,t.label)),r.appendChild(e)}if(t.appendChild(r),e.outputTail.length===0)return t;let i=f(`pre`,`settings-update-output`,e.outputTail.join(`
|
|
4
|
+
`));if(e.outputStepId&&(i.dataset.step=e.outputStepId),!e.outputStepLabel)return t.appendChild(i),t;let a=`Output from ${e.outputStepLabel}`;return i.setAttribute(`aria-label`,a),t.append(f(`div`,`settings-update-output-label`,a),i),t}function Va(){let e=r(m().status),t=[e.label];if(e.releaseUrl){let n=f(`a`,`settings-link`,`View release`);n.href=e.releaseUrl,n.target=`_blank`,n.rel=`noopener noreferrer`,t.push(n)}return za(`Latest`,...t)}function Ha(){let t=f(`div`,`settings-view-status-block settings-update-status`),{status:n,journal:r}=m(),i=s(n,r),a=f(`div`,`settings-update-summary`,i.headline);a.dataset.tone=i.tone,t.appendChild(a),t.appendChild(za(`Running`,ge(n))),e(n)&&t.appendChild(Va());let o=typeof n?.lastCheckAt==`number`?n.lastCheckAt:null,c=za(`Last checked`,l({status:n,checkForUpdates:U.checkForUpdates,relativeTime:xe(o)}));o&&(c.title=new Date(o).toLocaleString()),t.appendChild(c),t.appendChild(Ra());let u=Ba();return u&&t.appendChild(u),t}function Ua(e){return e===null?`not probed yet`:e?`resolved`:`not found on PATH`}function Wa(){let e=Array.isArray(U.customAgents)?U.customAgents:[];return e.length===0?[`None declared. Add customAgents to config.json.`]:e.map(e=>{let t=e.args.length>0?`${e.command} ${e.args.join(` `)}`:e.command;return`${e.id} ${e.label} ${t} ${Ua(e.resolvable)}`})}function Ga(){let e=f(`div`,`settings-view-status-block`);e.appendChild(f(`div`,`settings-section-title`,`Declared agents`));for(let t of Wa())e.appendChild(f(`div`,`settings-readonly`,t));return e}function Ka(e){J.set(e,{tone:`ok`,text:`Saved`}),window.setTimeout(()=>{J.get(e)?.tone===`ok`&&(J.delete(e),os())},yi)}async function qa(e,t){Gi.add(e.id),J.delete(e.id),os();try{let n=await be(`update-settings`,{settings:{workflows:{rules:[{id:e.id,enabled:t}]}}},{timeoutMs:tt});if(Gi.delete(e.id),n.type===`settings-error`&&J.set(e.id,{tone:`error`,text:String(n.message)}),n.type===`settings-updated`){Ka(e.id),At(n.settings);return}}catch(t){J.set(e.id,{tone:`error`,text:et(t,tt)})}Gi.delete(e.id),os()}function Ja(e){let t=$e(`settings-workflow-rule-status`);if(Gi.has(e.id))return t.show(`busy`,`Saving`),t.element;let n=J.get(e.id);return n&&t.show(n.tone,n.text),t.element}function Ya(e){let t=f(`div`,`settings-view-toggle-wrap`),n=f(`label`,`settings-view-toggle`),r=f(`input`,`settings-view-checkbox`);return r.type=`checkbox`,r.checked=e.isEnabled,r.disabled=Gi.has(e.id),r.setAttribute(`aria-label`,`Run rule ${e.name}`),r.addEventListener(`change`,()=>{qa(e,r.checked)}),n.append(r,f(`span`,`settings-view-toggle-state`,pa(e.isEnabled)),f(`span`,`settings-readonly`,`${e.name} ${e.summary}`)),t.append(n,Ja(e)),t}function Xa(){let e=f(`div`,`settings-view-status-block`);e.appendChild(f(`div`,`settings-section-title`,`Rules`));let t=_i(U.workflows);if(t.length>0){for(let n of t)e.appendChild(Ya(n));return e}for(let t of gi(U.workflows))e.appendChild(f(`div`,`settings-readonly`,t));return e}function Za(){let e=f(`div`,`settings-view-status-block`);e.appendChild(f(`div`,`settings-section-title`,`Last report`));for(let t of Ot())e.appendChild(f(`div`,`settings-readonly`,t));return e}function Qa(){let e=f(`div`,`settings-view-status-block`);if((G.get(`remote-sessions`)??W.remoteSessions)!==!0)return e.appendChild(f(`div`,`settings-readonly`,`Turn on Remote Coder sessions (experimental) to connect agent logins for them.`)),e;for(let t of[`claude-code`,`codex`]){let n=f(`div`,`settings-telegram-test`),r=f(`button`,`btn-dialog btn-dialog-cancel`,`Connect`);r.type=`button`,r.addEventListener(`click`,()=>tn(t)),n.append(f(`div`,`settings-readonly`,en(Yt(t),t)),r),e.appendChild(n)}return e}function $a(){let e=f(`div`,`settings-view-status-block`),t=f(`button`,`btn-dialog btn-dialog-cancel`,`Set up remote host`);return t.type=`button`,t.addEventListener(`click`,nn),e.appendChild(t),e}function eo(e){return e.status===`agent-logins`?Qa():e.status===`remote-setup`?$a():e.status===`update-actions`?Ha():e.status===`custom-agents`?Ga():e.status===`workflows`?Xa():f(`div`,`settings-readonly`,`Not available`)}function to(e){return e.control===`readonly`?eo(e):e.control===`toggle`?ma(e):e.control===`number`?Sa(e):e.control===`select`?li(e)===`segmented`?Ta(e):Ea(e):e.control===`list`?Oa(e):e.control===`projects`?Ma(e):e.control===`shortcut-key`?ha(e):e.control===`tab-order`?Aa(e):xa(e)}function no(e){let t=Tr(e,U);return t?`Supplied by ${t}. Change the server environment and restart to replace this credential.`:e.status!==`rtk-install`||Y(e)!==!0||U.rtkAvailable?``:Er(U)}function ro(e){if(e.control===`readonly`)return null;if(e.status===`usage-last-report`){let e=Za();return e.classList.add(`settings-view-status-slot`),e}if(e.id===`desktop-notifications`)return fo(e);if(e.id===`telemetry-enabled`)return uo();if(e.status===`telegram-delivery`)return oo();let t=no(e);return t?f(`div`,`settings-view-warning settings-view-status-slot`,t):null}function io(){let e=i.safeParse(U.telegramDelivery);if(!e.success)return[];let{setupWarning:t,lastFailure:n}=e.data,r=t?[t]:[];return n&&r.push(`The last Telegram send failed at ${new Date(n.failedAt).toLocaleString()}: ${n.message}`),r}function ao(e){e.replaceChildren(...io().map(e=>f(`p`,`settings-view-warning`,e)))}function oo(){let e=f(`div`,`settings-view-status-slot settings-telegram-delivery`),t=f(`div`,`settings-telegram-delivery-lines`);ao(t);let n=f(`button`,`btn-dialog btn-dialog-cancel`,`Send test message`);n.type=`button`;let r=$e(`settings-telegram-test-status`);n.addEventListener(`click`,async()=>{n.disabled=!0;let e=await Qe(`telegram-test`,{},r,{busyText:`Sending a test message to Telegram.`});n.disabled=!1,e?.type===`telegram-test-result`&&(U=St({telegramDelivery:e.telegramDelivery}),ao(t),e.ok?r.show(`ok`,`Sent. Check the Telegram chat for the test message.`):r.show(`error`,`Not sent: ${e.error??`Telegram refused the message.`}`))});let i=f(`div`,`settings-telegram-test`);return i.append(n,r.element),e.append(t,i),e}async function so(){co.disabled=!0;let e=await Qe(`request-telemetry-deletion`,{},lo,{busyText:`Sending the deletion request.`,timeoutMs:xi});co.disabled=!1,e?.type===`telemetry-deletion-result`&&(e.ok?lo.show(`ok`,`Deletion requested. New usage starts under a new id.`):lo.show(`error`,`Not sent: PostHog did not take the request. Try again later.`))}var co=f(`button`,`btn-dialog btn-dialog-cancel`,`Delete my data`);co.type=`button`,co.addEventListener(`click`,()=>{nt({title:`Delete your usage data?`,message:`We delete everything collected under this install. New usage starts under a new id.`,confirmLabel:`Delete my data`,danger:!0,onConfirm:()=>{so()}})});var lo=$e(`settings-telemetry-deletion-status`);function uo(){let e=f(`div`,`settings-view-status-slot settings-telemetry-data`);return e.append(ra(`Privacy details`,na(`/privacy`)),co,lo.element),e}function fo(e){let t=Dt(()=>$(e,{force:!0}));return t.element.hidden?null:(t.element.classList.add(`settings-view-status-slot`),t.element)}function po(e,t){let n=f(`span`,`settings-view-chip`,t);return n.dataset.chip=e,n}function mo(e,t){let n=ve(e);return n?n.then(()=>t,()=>`Copy failed`):Promise.resolve(`Copy failed`)}function ho(e,t,{copiedText:n,textToCopy:r}){let i=f(`span`,`settings-view-copy-status`);i.setAttribute(`role`,`status`),t.type=`button`,t.addEventListener(`click`,async()=>{i.textContent=await mo(r(),n),setTimeout(()=>{i.textContent=``},bi)}),e.append(t,i)}function go(e){let t=f(`div`,`settings-view-setting-heading`),n=Xi(e),r=f(`h2`,`settings-view-setting-title`,e.title);r.id=e.id,r.addEventListener(`click`,()=>Zi(n.id,e.id));let i=f(`button`,`settings-view-copy-link`,`#`);return i.setAttribute(`aria-label`,`Copy link`),t.appendChild(r),ho(t,i,{copiedText:`Link copied`,textToCopy:()=>new URL(Ft(n.id,e.id),location.href).href}),t}function _o(e){let t=f(`div`,`settings-view-chips`);return t.append(po(`scope`,wr[e.scope]),po(`effect`,Cr[e.takesEffect])),t}function vo(e){return e.control===`readonly`||Tr(e,U)?!1:!ci(e,Y(e))}function yo(e){let t=f(`div`,`settings-view-control-foot`),n=f(`span`,`settings-view-save-status`);n.setAttribute(`role`,`status`);let r=f(`button`,`settings-view-reset`,`Reset`);return r.type=`button`,r.title=`Reset to the default value`,r.addEventListener(`click`,()=>{let t=si(e),n=mi(e);n===null?Z(e,t):nt({title:e.title,message:n,confirmLabel:`Reset`,danger:!0,onConfirm:()=>Z(e,t)})}),t.append(n,r),t}function bo(e,t){let n=e.querySelector(`.settings-view-save-status`),r=Bi.get(t.id);n&&(n.textContent=r?.text??``,r&&(n.dataset.tone=r.tone),r||delete n.dataset.tone);let i=e.querySelector(`.settings-view-reset`);i&&(i.disabled=!vo(t));let a=e.querySelector(`.settings-view-field-error`),o=Ui.get(t.id);a&&!o&&a.remove(),a&&o&&(a.textContent=o),!a&&o&&e.querySelector(`.settings-view-setting-control`)?.appendChild(f(`div`,`settings-view-field-error`,o))}function xo(e){let t=f(`article`,`settings-view-setting`);t.dataset.settingId=e.id,e.control===`readonly`&&(t.dataset.readout=`true`);let n=f(`div`,`settings-view-setting-text`);n.append(go(e),f(`p`,`settings-view-setting-description`,e.description),_o(e));let r=f(`div`,`settings-view-setting-control`);r.appendChild(to(e)),e.control!==`readonly`&&r.appendChild(yo(e)),t.append(n,r),di(e,Y(e))&&t.appendChild(f(`div`,`settings-view-warning settings-warning`,e.warning));let i=ro(e);return i&&t.appendChild(i),bo(t,e),t}function So(e){return V?.querySelector(`[data-setting-id="${e.id}"]`)??null}function Co(e){let t=e.querySelector(`.settings-view-setting-control`);t&&(t.querySelector(`[data-restores-focus="true"]:not([disabled])`)??t.querySelector(`[role="radio"][aria-checked="true"]`)??t.querySelector(`input:not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled])`))?.focus()}function wo(e,t){if(!va(e)||!va(t))return;e.disabled=t.disabled,e.placeholder=t.placeholder;let n=K.get(t);n&&!ai(K.get(e))&&(K.set(e,{base:n.base,isDirty:!1}),e.value!==t.value&&(e.value=t.value))}function To(e,t,n){if(e===n){wo(e,t);return}let r=[...e.children],i=[...t.children];for(let[t,a]of i.entries()){let i=r[t];i?i.contains(n)?To(i,a,n):i.replaceWith(a):e.appendChild(a)}for(let e of r.slice(i.length))e.remove()}function $(e,{force:t=!1}={}){let n=So(e);if(!n)return;let r=document.activeElement,i=n.contains(r),a=i&&!t&&va(r)?r:null;(!a||!ai(K.get(a)))&&Ui.delete(e.id);let o=xo(e);a?To(n,o,a):(n.replaceWith(o),i&&Co(o))}function Eo(e){let t=So(e);t&&bo(t,e)}function Do(e){So(e)?.querySelector(`.settings-view-setting-control`)?.replaceChildren(eo(e))}function Oo(){for(let e of Yi(H))e.control===`readonly`?Do(e):$(e)}function ko(){let e=f(`button`,`btn-dialog btn-dialog-cancel`,`Reset all to defaults`);return e.type=`button`,e.addEventListener(`click`,()=>{Te(),qi(U),Bt(Ze()),Po()}),e}function Ao(e){let t=f(`div`,`settings-view-advanced`),n=f(`button`,`dialog-advanced-toggle settings-view-advanced-toggle`,`Advanced`);n.type=`button`,n.setAttribute(`aria-expanded`,String(I)),n.setAttribute(`aria-controls`,`settings-view-advanced-panel`);let r=f(`div`,`dialog-advanced-panel settings-view-advanced-panel`);r.id=`settings-view-advanced-panel`,r.hidden=!I,n.addEventListener(`click`,()=>{I=!I,r.hidden=!I,n.setAttribute(`aria-expanded`,String(I))});for(let t of e)r.append(xo(t));return H.id===Ci&&r.append(ko()),t.append(n,r),t}function jo(e){let t=f(`div`,`settings-view-streamer-placeholder`),n=f(`button`,`btn-dialog btn-dialog-confirm`,`Turn off streamer mode`);n.type=`button`;let r=f(`span`,`settings-view-copy-status`,``);r.setAttribute(`role`,`status`),n.addEventListener(`click`,async()=>{n.disabled=!0,r.textContent=``;let e=await lt(!1);n.disabled=!1,r.textContent=e}),t.append(f(`p`,`settings-view-section-description`,`Settings are hidden in streamer mode.`),n,r),e.appendChild(t)}xt(()=>Po());function Mo(e){let t=f(`header`,`settings-view-subsection`),n=f(`h2`,`settings-view-subsection-title`,e.title);return n.addEventListener(`click`,()=>Zi(e.id)),t.append(n,f(`p`,`settings-view-section-description`,e.description)),t}function No(e,t){for(let n of t.settings.filter(e=>e.access!==`advanced`))e.appendChild(xo(n)),n.id===wi&&e.appendChild(rn());let n=t.settings.filter(e=>e.access===`advanced`);n.length>0&&e.append(Ao(n))}function Po(){if(Wo(),q){Ho();return}if(!V)return;if(V.textContent=``,bt()){jo(V);return}let e=f(`header`,`settings-view-section-header`),t=f(`h1`,`settings-view-section-title`,H.title);if(t.tabIndex=-1,t.addEventListener(`click`,()=>Zi(H.id)),e.append(t,f(`p`,`settings-view-section-description`,H.description)),V.appendChild(e),H.id===Oi){let e=f(`div`,`settings-view-stack`);No(e,H),V.appendChild(e);let t=f(`div`,`shortcut-groups settings-view-shortcuts`);$i(t),V.appendChild(t);return}if(H.id===ki){ia(V),V.appendChild(vt()),V.appendChild(ft());return}if(H.id===Ei){ta(V);return}let n=f(`div`,`settings-view-stack`);for(let e of Ji(H))e.id!==H.id&&n.appendChild(Mo(e)),No(n,e);V.appendChild(n)}function Fo(e,{focusContent:t=!1,settingId:n=null,updateHash:r=!0,openPhoneSection:i=!0}={}){r&&q&&(q=``,z&&(z.value=``));let a=Lr(F,e)??H;H.id!==a.id&&(I=!1),H=a;let o=F.find(t=>t.id===e)??a;Io(R),i&&st()&&(zi=o.id),Po(),Zo(H)&&Xo(),H.id===`machine-updates`&&Ia(),r&&Zi(o.id,n),n&&Qi(n),t&&V?.querySelector(`h1`)?.focus()}function Io(e){for(let t of e?.querySelectorAll(`[data-settings-section]`)||[]){let e=t.dataset.settingsSection===H.id;t.setAttribute(`aria-current`,e?`page`:`false`)}}function Lo(e){return e.section!==null}function Ro(e){z&&(z.value=``,q=``,Ko(),Fo(e.section.id,{settingId:e.setting.id}))}function zo(e){return lr(Pi(),e,Fn.fileOnly)}function Bo(e,t,n,r,i){let a=f(e,t),o=r.matches.find(e=>e.field===i),s=o?n.indexOf(o.text):-1;if(!o||s<0)return a.textContent=n,a;let c=0;for(let e of o.spans)a.append(n.slice(c,s+e.start),f(`mark`,`settings-view-search-highlight`,n.slice(s+e.start,s+e.end))),c=s+e.end;return a.append(n.slice(c)),a}function Vo(e,t){let{currentText:n,defaultText:r,jsonFragment:i}=Pr(t.setting,U);if(n!==null&&e.appendChild(f(`span`,`settings-view-search-current`,n)),e.append(f(`span`,`settings-view-search-default`,r),_o(t.setting),f(`p`,`settings-view-list-hint`,`Edit in config.json or with glimmervoid settings set.`)),i===null)return;let a=f(`div`,`settings-view-control-foot`);ho(a,f(`button`,`settings-view-copy-json`,`Copy as JSON`),{copiedText:`JSON copied`,textToCopy:()=>i}),e.appendChild(a)}function Ho(){if(!V)return;if(V.textContent=``,bt()){jo(V);return}let e=zo(q),t=f(`div`,`settings-view-section-header`);if(t.append(f(`h1`,`settings-view-section-title`,`Settings search`),f(`p`,`settings-view-section-description`,`${e.length} ${e.length===1?`result`:`results`} for "${q}"`)),V.appendChild(t),e.length===0){V.appendChild(f(`p`,`settings-empty settings-view-search-empty`,`No settings found.`));return}let n=f(`ol`,`settings-view-search-results`);n.setAttribute(`aria-label`,`Settings search results`);for(let t of e){let e=f(`li`,`settings-view-search-result`);e.tabIndex=-1;let r=Fr(F,t.section,t.setting);e.appendChild(Bo(`p`,`settings-view-search-breadcrumb`,r,t,`section`));let i=Bo(`span`,`settings-view-setting-title`,t.setting.title,t,`title`);if(Lo(t)){let n=f(`button`,`settings-view-search-open`);n.type=`button`,n.appendChild(i),n.addEventListener(`click`,()=>Ro(t)),e.appendChild(n)}Lo(t)||(e.classList.add(`settings-view-search-file-only`),e.appendChild(i)),e.append(Bo(`p`,`settings-view-setting-description`,t.setting.description,t,`description`),Bo(`code`,`settings-view-key-path`,t.setting.path,t,`path`));let a=new Set([`title`,`description`,`path`,`section`]);if(!t.matches.some(e=>a.has(e.field))){let n=t.matches.find(e=>e.field===`options`)??t.matches.find(e=>e.field===`keywords`);n&&e.appendChild(Bo(`p`,`settings-view-list-hint`,n.text,t,n.field))}Lo(t)||Vo(e,t),n.appendChild(e)}V.appendChild(n)}function Uo(){return Br(F,zi,q,bt())}function Wo(){if(!L)return;let e=Uo(),t=L.dataset.settingsScreen!==e;L.dataset.settingsScreen=e,B&&(B.hidden=e!==`section`),t&&Jt()}function Go(){let e=H.id;qo(``),R?.querySelector(`[data-settings-section="${e}"]`)?.focus()}function Ko(){if(R&&L){R.textContent=``;for(let e of zr(Rr(F))){let t=f(`div`,`settings-view-nav-group`);e.heading&&t.appendChild(f(`div`,`settings-view-nav-heading`,e.heading));for(let n of e.sections){let e=f(`button`,`settings-view-nav-item`,n.title);e.type=`button`,e.dataset.settingsSection=n.id,e.addEventListener(`click`,()=>Fo(n.id,{focusContent:st()})),t.appendChild(e)}R.appendChild(t)}q?(Wo(),Ho()):Fo(H.id,{updateHash:!1,openPhoneSection:!1})}}function qo(e,{updateHash:t=!0}={}){q=e.trim(),z&&(z.value=e),zi=null,t&&history.replaceState(history.state,``,qt(q)),Ko()}function Jo(e){if(q&&e.key===`Enter`&&e.target===z){let t=zo(q).find(Lo);if(!t)return;e.preventDefault(),Ro(t);return}if(e.key===`Escape`&&q){if(!z)return;e.preventDefault(),qo(``),z.focus();return}if(e.key!==`ArrowUp`&&e.key!==`ArrowDown`||!R)return;let t=[...R.querySelectorAll(`[data-settings-section]`)].filter(e=>e instanceof HTMLElement),n=document.activeElement;if(!(n instanceof HTMLElement))return;let r=t.indexOf(n);r<0||(e.preventDefault(),t[(r+(e.key===`ArrowDown`?1:-1)+t.length)%t.length].focus())}function Yo(e){dt(oa),Li=e,Li.textContent=``,L=f(`div`,`settings-view-shell`);let t=f(`div`,`settings-view-sidebar`);z=f(`input`,`settings-view-search`),z.type=`search`,z.placeholder=`Search settings`,z.setAttribute(`aria-label`,`Search settings`),R=f(`nav`,`settings-view-nav`),R.setAttribute(`role`,`navigation`),R.setAttribute(`aria-label`,`Settings sections`),B=f(`button`,`settings-view-back`,`Back`),B.type=`button`,B.hidden=!0,B.setAttribute(`aria-label`,`Back to settings sections`),B.addEventListener(`click`,yt),V=f(`div`,`settings-view-content`),V.setAttribute(`aria-live`,`polite`),z.addEventListener(`input`,()=>{let e=z;e&&qo(e.value)}),z.addEventListener(`keydown`,Jo),R.addEventListener(`keydown`,Jo),t.append(z,B,R),L.append(t,V),Li.appendChild(L),U=h(),$o(),qi(U),it(Uo),at(cs),Ko(),Xo(),Ri?.disconnect(),Ri=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&Xo()}),Ri.observe(Li),rs()}function Xo(){Nt().then(es)}function Zo(e){return Yi(e).some(e=>e.path===`pref:soundId`)}function Qo(){F=Fi(),Ii=Ni(h()),H=Lr(F,H.id)??F[0]}function $o(){return Ni(U)!==Ii&&(Qo(),!0)}function es(){if(Qo(),W[`pref:soundId`]=mt(Ue()),q){Ho();return}let e=aa(`alert-sound`);e&&Zo(H)&&$(e)}function ts(e,t,n){let r=Et(e??n);r?qo(r.query):(qo(``,{updateHash:!1}),st()&&!e?history.replaceState(history.state,``,qt(``)):Fo(e||H.id,{settingId:t}))}function ns(e){let t=ur(e,F,zn,Bn);ts(t?.sectionId??null,t?.settingId??null,e)}function rs(){let e=ht();e&&(e.isLink?ns(e.hashAtRequest):ts(e.sectionId,e.settingId,e.hashAtRequest))}function is(){U=h();let e=$o();qi(U),q?Ho():e?(Ko(),Po()):Oo()}function as(e,t){let n=t.querySelector(`.settings-view-status-slot`),r=ro(e);n&&r&&n.replaceWith(r),n&&!r&&n.remove(),!n&&r&&t.appendChild(r)}function os(){for(let e of Yi(H)){if(!e.status)continue;let t=So(e);t&&(e.control===`readonly`?Do(e):as(e,t))}}function ss(){if(H.id!==`machine-updates`)return;let e=aa(`update-actions`);e&&Do(e)}function cs(e){switch(e.kind){case`broadcast`:is();return;case`status`:os();return;case`update`:ss(),e.frame===`status`&&Wi&&H.id===`machine-updates`&&Ia();return;case`activate`:rs();return;case`return-to-list`:Go()}}function ls(){H.id===Ci&&Po()}window.matchMedia(`(prefers-reduced-motion: reduce)`).addEventListener(`change`,ls),ut(()=>{zi=null,Wo(),ls()}),Tt(os);var us={mount:Yo};export{us as view};
|
|
Binary file
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{H as e,V as t,_t as n,m as r,n as i,o as a,u as o,y as s}from"./dom-helpers-xJduxDcc.js";import{g as c,nt as l}from"./ui-prefs-CNf6fId2.js";import{i as u}from"./action-status-BwqYb9eF.js";import{_n as d,dn as ee,fn as f,gn as p,hn as m,mn as h,pn as g,vn as _}from"./index-D6m--U7B.js";function v(e){return e.kind===`prompt`||e.kind===`expansion`||e.kind===`thinking`||e.kind===`assistant`||e.kind===`notice`?e.text:e.kind===`tool_result`?e.content:e.kind===`raw`?e.line:e.kind===`tool_call`?JSON.stringify(e.input,null,2)??String(e.input??``):[`${e.vendor} ${e.vendorSessionId}`,e.transcriptPath,e.reason??``].filter(Boolean).join(`
|
|
2
|
+
`)}var te=[{kind:`thinking`,label:`Thinking`},{kind:`tool_result`,label:`Tool result`},{kind:`raw`,label:`Raw`}];function ne(e){if(e.startedAt===null)return 0;let t=e.head?.record.ts??e.startedAt;for(let n of e.rows)t=Math.max(t,n.record.ts);return Math.max(0,t-e.startedAt)}function y(e){let{rowCount:r,toolCallCount:i,errorCount:a,resultBytes:o}=e.metrics;return`${`${r} ${r===1?`row`:`rows`}`}, ${`${i} ${i===1?`tool`:`tools`}`}, ${`${a} ${a===1?`error`:`errors`}`}, ${n(o,`KB`)}, ${t(ne(e))}`}function b(e){return e.hasSelectionChanged||e.isRenderedTraceStale||!e.hasRenderedOnce}function x(e,t,n){return e!==0||t?null:n?.startedAt??null}function S(e,t){return C(e,t)?e.filter(e=>e!==t):[...e,t]}function C(e,t){return e.includes(t)}function w(e){return e?`No trace has been recorded for ${e.label}.`:`No sessions are available.`}var T=null,E=null,D=null,O=null,k=[],A=!1,j=c(),M=!1,N=null;function P(){return!!T&&!o(T)}function re(){let{sessionOptions:e,selectedSessionId:t}=d();return e.find(e=>e.id===t)??null}function ie(){let e=a(`label`,`trace-session-field`),t=a(`span`,`trace-session-label`,`Session`),n=a(`select`,`trace-session-select`),{sessionOptions:r,selectedSessionId:i}=d();n.disabled=r.length===0;for(let e of r){let t=a(`option`,null,e.label);t.value=e.id,t.selected=e.id===i,n.append(t)}return n.addEventListener(`change`,()=>g(n.value)),e.append(t,n),e}function F(e){e.toggleAttribute(`data-hidden`,C(j,e.dataset.kind??``))}function I(){if(D)for(let e of D.querySelectorAll(`.trace-row`))F(e)}function L(e){if(D)for(let t of D.querySelectorAll(`details`))t.open=e}function R(){let e=a(`div`,`trace-filters`);for(let t of te){let n=a(`button`,`trace-filter`,t.label);n.type=`button`;let r=()=>{n.setAttribute(`aria-pressed`,String(!C(j,t.kind)))};r(),n.addEventListener(`click`,()=>{j=S(j,t.kind),l(j),r(),I()}),e.append(n)}for(let[t,n]of[[`Expand all`,!0],[`Collapse all`,!1]]){let r=a(`button`,`trace-expand-control`,t);r.type=`button`,r.addEventListener(`click`,()=>{L(n)}),e.append(r)}return e}function z(){let e=i(`trace`,`Session trace`,`Bodies load from the local trace file only when requested.`),t=a(`div`,`trace-controls`),{selectedTrace:n,traceFailureText:r}=d();t.append(ie());let o=n?.filePath??``,s=a(`code`,`trace-path`,o);s.title=o,t.append(s);let c=n?x(n.firstOffset,n.hasDroppedEarliestRows,n.grouping.turns[0]):null;if(c!==null&&t.append(a(`span`,`trace-session-start`,`Started ${new Date(c).toLocaleString()}`)),e.append(t,R()),!r)return e;let l=u(`trace-status`);return l.show(`error`,r),e.append(l.element),e}function B(e){let t=a(`div`,`trace-copy-wrap`),n=a(`button`,`trace-copy`,`Copy`);n.type=`button`;let r=a(`span`,`trace-copy-status`);return r.setAttribute(`role`,`status`),n.addEventListener(`click`,()=>{let t=s(e);t?(t.then(()=>{r.textContent=`Copied`}).catch(()=>{r.textContent=`Copy failed`}),setTimeout(()=>{r.textContent=``},1600)):r.textContent=`Copy failed`}),t.append(n,r),t}function V(){let e=a(`div`,`trace-earlier-wrap`),t=a(`button`,`trace-load-earlier`,`Load earlier`);return t.type=`button`,t.addEventListener(`click`,()=>{f()}),e.append(t),e}function H(t,n,r=``){let i=a(`details`,`trace-row${r?` ${r}`:``}`);i.dataset.kind=t.kind,i.dataset.tone=t.tone,F(i);let o=a(`summary`,`trace-row-summary`);o.append(a(`span`,`trace-offset`,e(n,t.record.ts)),a(`span`,`trace-kind`,t.tag),a(`span`,`trace-row-label`,t.text));for(let e of t.badges){let t=a(`span`,`trace-badge`,e);t.dataset.badge=e,o.append(t)}let s=a(`div`,`trace-row-body`);i.append(o,s);let c=!1;return i.addEventListener(`toggle`,()=>{if(!i.open||c)return;c=!0;let e=v(t.record);s.append(B(e),a(`pre`,`trace-row-pre`,e))}),i}function U(e){return a(`span`,`trace-turn-metrics`,y(e))}function W(e,t){e&&t&&(t.textContent=y(e))}function G(t,n){let r=t.children,i=Math.min(n.rows.length,r.length);for(let t=0;t<i;t+=1){let i=r[t]?.querySelector(`.trace-offset`);i&&(i.textContent=e(n.startedAt,n.rows[t].record.ts))}}function K(e,t,n){let i=H(t,e.startedAt,`trace-turn-head`);return r(i,`.trace-row-summary`).append(n),i}function q(e){let t=a(`section`,`trace-turn`),n=U(e);if(e.head&&t.append(K(e,e.head,n)),!e.head){let e=a(`h2`,`trace-leading-title`);e.append(a(`span`,`trace-leading-label`,`Before first prompt`),n),t.append(e)}let r=a(`div`,`trace-rows`);for(let t of e.rows)r.append(H(t,e.startedAt));return e.hasTrimmedRows&&t.append(a(`p`,`trace-trimmed`,`Earlier rows trimmed`)),t.append(r),{section:t,rowsElement:r,metricsElement:n}}function J(e){if(!e)return w(null);let{pendingSessionId:t,selectedTrace:n}=d();return t===e.id&&!n?.hasLoadedOnce?`Loading trace.`:w(e)}function Y(){if(!T)return;let e=a(`div`,`trace-content`);E=z(),e.append(E),D=null,O=null,k=[];let t=re(),n=d().selectedTrace?.grouping.turns??[];if(!t||n.length===0){e.append(a(`p`,`trace-empty`,J(t))),T.replaceChildren(e),A=!1;return}_(p())&&(O=V(),e.append(O));let r=a(`div`,`trace-turns`);for(let e of n){let t=q(e);k.push(t),r.append(t.section)}D=r,I(),e.append(r),T.replaceChildren(e),A=!1}function X(){T&&(P()?Y():A=!0)}function Z(){if(!E||!P())return;let e=z();E.replaceWith(e),E=e}function Q(e){if(!D)return;let t=d().selectedTrace?.grouping.turns[e.turnIndex];if(!t)return;if(e.isNewTurn){let e=q(t);k.push(e),D.append(e.section);return}let n=k[e.turnIndex];if(n){for(let r of e.rows)n.rowsElement.append(H(r,t.startedAt));W(t,n.metricsElement)}}function ae(e){let t=e.parentElement;t&&!t.querySelector(`.trace-trimmed`)&&t.insertBefore(a(`p`,`trace-trimmed`,`Earlier rows trimmed`),e)}function $(){_(p())?!O&&D?.parentElement&&(O=V(),D.parentElement.insertBefore(O,D)):(O?.remove(),O=null)}function oe(e){if(!(e.droppedTurnCount>0||e.droppedRowCount>0)){$();return}if(k=k.slice(e.droppedTurnCount),D)for(let t=0;t<e.droppedTurnCount;t+=1)D.firstElementChild?.remove();let t=k[0];if(t&&e.droppedRowCount>0){for(let n=0;n<e.droppedRowCount;n+=1)t.rowsElement.firstElementChild?.remove();ae(t.rowsElement),W(d().selectedTrace?.grouping.turns[0],t.metricsElement)}e.hasJustDroppedEarliestRows&&Z(),$()}function se(e){if(P()&&!A&&D)for(let t of e)Q(t);else D=null,M=!0}function ce(e){if(!D)return;let t=k[0]??null,n=t?.rowsElement.parentElement??null,r=d().selectedTrace?.grouping.turns[e.newTurns.length]??null;if((e.mergedHead||e.mergedRows.length>0)&&t&&n&&r){let i=t.rowsElement;if(e.mergedHead){n.querySelector(`.trace-leading-title`)?.remove();let a=U(r),o=K(r,e.mergedHead,a);n.insertBefore(o,i),t.metricsElement=a}e.mergedHead||W(r,t.metricsElement);let a=document.createDocumentFragment();for(let t of e.mergedRows)a.append(H(t,r.startedAt));i.prepend(a),G(i,r)}let i=document.createDocumentFragment(),a=[];for(let t of e.newTurns){let e=q(t);a.push(e),i.append(e.section)}D.prepend(i),k.unshift(...a)}function le(e){let t=P()&&!A&&!!D&&!e.needsRerender,n=T?.parentElement??null;N={canPrependInPlace:t,scrollElement:n,previousScrollHeight:n?.scrollHeight??0,previousScrollTop:n?.scrollTop??0},t&&ce(e)}function ue(e){oe(e),M&&(M=!1,X());let t=N;N=null,t&&(t.canPrependInPlace||X(),t.canPrependInPlace&&Z(),t.scrollElement&&(t.scrollElement.scrollTop=t.previousScrollTop+t.scrollElement.scrollHeight-t.previousScrollHeight))}function de(e){switch(e.kind){case`selection-reset`:A=!0;return;case`rebuild`:X();return;case`header`:Z();return;case`sessions`:(e.hasSelectionChanged||!E)&&X(),!e.hasSelectionChanged&&E&&Z();return;case`records-appended`:se(e.appends);return;case`records-prepended`:le(e.prepend);return;case`trimmed`:ue(e.trim);return}}function fe(e){T||(T=a(`div`,`trace-panel`),e.append(T),h(P),m(de),Y())}function pe(){T&&b({hasSelectionChanged:ee(),isRenderedTraceStale:A,hasRenderedOnce:!!E})&&Y()}var me={mount:fe,refresh:pe};export{me as view};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{an as e,in as t,on as n,rn as r}from"./dom-helpers-xJduxDcc.js";var i=[{name:`Nyan cat`,sprite:`is-cat`,trail:`is-rainbow`},{name:`Unicorn`,sprite:`is-unicorn`,trail:`is-sparkles`},{name:`Dragon`,sprite:`is-dragon`,trail:`is-embers`},{name:`Pig`,sprite:`is-pig`,trail:`is-hearts`},{name:`Whale`,sprite:`is-whale`,trail:`is-bubbles`},{name:`Fox`,sprite:`is-fox`,trail:`is-paws`},{name:`Frog`,sprite:`is-frog`,trail:`is-dust`},{name:`Penguin`,sprite:`is-penguin`,trail:`is-snow`},{name:`Bee`,sprite:`is-bee`,trail:`is-honey`},{name:`Owl`,sprite:`is-owl`,trail:`is-stars`},{name:`Cow`,sprite:`is-cow`,trail:`is-daisies`},{name:`Panda`,sprite:`is-panda`,trail:`is-bamboo`},{name:`Red panda`,sprite:`is-red-panda`,trail:`is-leaves`},{name:`Deer`,sprite:`is-deer`,trail:`is-acorns`},{name:`Horse`,sprite:`is-horse`,trail:`is-clover`},{name:`Sheep`,sprite:`is-sheep`,trail:`is-clouds`},{name:`Hamster`,sprite:`is-hamster`,trail:`is-seeds`},{name:`Giraffe`,sprite:`is-giraffe`,trail:`is-acacia`},{name:`Hedgehog`,sprite:`is-hedgehog`,trail:`is-logomarks`}],a=1/25,o=3;function s(e,t,n){return typeof e!=`number`||!Number.isFinite(e)?t:Math.min(n.max,Math.max(n.min,e))}function c(e){if(!Array.isArray(e))return[];let t=new Set(i.map(e=>e.sprite));return[...new Set(e.filter(e=>typeof e==`string`&&t.has(e)))]}function l(i={}){let a=r,o=e,l=t,u=s(i.flyingAnimalsMinGapSeconds,a.flyingAnimalsMinGapSeconds,o),d=s(i.flyingAnimalsMaxGapSeconds,a.flyingAnimalsMaxGapSeconds,o),f=s(i.flyingAnimalsMinDurationSeconds,a.flyingAnimalsMinDurationSeconds,l),p=s(i.flyingAnimalsMaxDurationSeconds,a.flyingAnimalsMaxDurationSeconds,l);return{flyingAnimalsMinGapSeconds:Math.min(u,d),flyingAnimalsMaxGapSeconds:Math.max(u,d),flyingAnimalsMinDurationSeconds:Math.min(f,p),flyingAnimalsMaxDurationSeconds:Math.max(f,p),flyingAnimalsScale:s(i.flyingAnimalsScale,a.flyingAnimalsScale,n),flyingAnimalsOnPhone:typeof i.flyingAnimalsOnPhone==`boolean`?i.flyingAnimalsOnPhone:a.flyingAnimalsOnPhone,flyingAnimalsExcludedSprites:c(i.flyingAnimalsExcludedSprites)}}function u(e){return i.some(t=>!e.includes(t.sprite))}function d(e,t=-1,n=Math.random){let r=i.flatMap((t,n)=>e.includes(t.sprite)?[]:[n]);if(r.length===0)return null;let a=r.length>1?r.filter(e=>e!==t):r,o=Math.min(1,Math.max(0,n()));return a[Math.min(a.length-1,Math.floor(o*a.length))]}function f(e,t,n=Math.random,r){let s=r===void 0?d(e.flyingAnimalsExcludedSprites,t,n):i.findIndex(e=>e.sprite===r);if(s===null||s<0)return null;let c=e.flyingAnimalsMinDurationSeconds+n()*(e.flyingAnimalsMaxDurationSeconds-e.flyingAnimalsMinDurationSeconds),l=1e3*(e.flyingAnimalsMinGapSeconds+n()*(e.flyingAnimalsMaxGapSeconds-e.flyingAnimalsMinGapSeconds)),u=n()*c,f=n(),p=n()<.5,m=n()<a?o:1;return{animalIndex:s,durationSeconds:c,gapMs:l,firstDelaySeconds:u,verticalProgress:f,isRightToLeft:p,arcProgress:(n()*2-1)*m}}function p({isEnabled:e,hasReducedMotion:t,isPhone:n,options:r}){return t?`Flights are disabled because reduced motion is enabled.`:e?n&&!r.flyingAnimalsOnPhone?`Turn on Show on phone layout to use Fly now here.`:null:`Turn on flying animals to use Fly now.`}var m=`chime`,h=`custom:`,g=`/custom-sounds`,_=Object.freeze({chime:{label:`Chime`,peakGain:.12,tones:[{frequency:659.25,startSeconds:0,durationSeconds:.35,waveform:`sine`},{frequency:987.77,startSeconds:.14,durationSeconds:.5,waveform:`sine`}]},ping:{label:`Soft ping`,peakGain:.08,tones:[{frequency:1046.5,startSeconds:0,durationSeconds:.12,waveform:`triangle`},{frequency:1046.5,startSeconds:.13,durationSeconds:.12,waveform:`triangle`},{frequency:1318.51,startSeconds:.26,durationSeconds:.2,waveform:`triangle`}]},beep:{label:`Beep`,peakGain:.15,tones:[{frequency:880,startSeconds:0,durationSeconds:.2,waveform:`sine`}]}}),ee=Object.freeze(Object.entries(_).map(([e,t])=>({id:e,label:t.label})));function te(e){return`${h}${e}`}function ne(e){return`${g}/${encodeURIComponent(e)}`}function v(e){return e.startsWith(h)&&e.slice(7)||null}function re(e){let t=(e??[]).map(e=>({id:te(e),label:e}));return[...ee,...t]}function ie(e,t){if(typeof e!=`string`)return m;if(Object.hasOwn(_,e))return e;let n=v(e);return n&&(t===null||t.includes(n))?e:m}function ae(e){return typeof e!=`object`||!e||!(`sounds`in e)||!Array.isArray(e.sounds)?[]:e.sounds.filter(e=>typeof e==`string`&&e!==``)}function y(e,t){try{let n=localStorage.getItem(e);return n===null?t:JSON.parse(n)}catch{return t}}function b(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch{}}var x=`↑`,S=`↓`,C=`←`,w=`→`,T=`⌘`,oe=`⌥`,se=Array.from({length:9},(e,t)=>[`Digit${t+1}`,t+1]),E=`KeyJ`,ce=new Map([[`Minus`,`-`],[`Equal`,`=`],[`BracketLeft`,`[`],[`BracketRight`,`]`],[`Semicolon`,`;`],[`Quote`,`'`],[`Comma`,`,`],[`Period`,`.`],[`Slash`,`/`],[`Backquote`,"`"],[`Backslash`,`\\`]]),le=new Set([`KeyQ`,`KeyW`,`KeyT`,`KeyN`,`KeyL`,`KeyR`]),D=new Set([`KeyC`,`KeyV`,`KeyX`,`KeyA`,`KeyZ`]);function O(e){let t=/^(?:Key|Digit)([A-Z0-9])$/.exec(e);return t?t[1]:ce.get(e)??null}function k(e){return{action:`next-attention`,keyCaptions:[O(e)??e],label:`Jump to the next session needing you`,stepByCode:new Map([[e,0]])}}var A=[{action:`rail-step`,keyCaptions:[x,S],label:`Previous / next session in the rail`,stepByCode:new Map([[`ArrowUp`,-1],[`ArrowDown`,1]])},{action:`view-step`,keyCaptions:[C,w],label:`Previous / next view tab`,stepByCode:new Map([[`ArrowLeft`,-1],[`ArrowRight`,1]]),unavailablePlatform:`other`},{action:`view-step`,keyCaptions:[`PgUp`,`PgDn`],label:`Previous / next view tab`,stepByCode:new Map([[`PageUp`,-1],[`PageDown`,1]]),unavailablePlatform:`mac`},{action:`session-nth`,keyCaptions:[`1..9`],label:`Jump to session 1 to 9`,stepByCode:new Map(se),isShellChord:!0,needsMacOption:!0},{action:`new-session`,keyCaptions:[`0`],label:`Add a session`,stepByCode:new Map([[`Digit0`,0]]),isShellChord:!0},{action:`quick-session`,keyCaptions:[`0`],label:`Add a session like the one you are in`,stepByCode:new Map([[`Digit0`,0]]),needsMacOption:!0,needsShiftOffMac:!0},{action:`merge`,keyCaptions:[`I`],label:`Merge the selected session`,stepByCode:new Map([[`KeyI`,0]])},{action:`close-session`,keyCaptions:[`K`],label:`Close the selected session`,stepByCode:new Map([[`KeyK`,0]])},{action:`resolve-or-resync`,keyCaptions:[`U`],label:`Resolve a parked merge, or resync the base branch`,stepByCode:new Map([[`KeyU`,0]]),isShellChord:!0},{action:`streamer-mode`,keyCaptions:[`\\`],label:`Turn streamer mode on or off`,stepByCode:new Map([[`Backslash`,0]]),isShellChord:!0}];function j(e,t){return[k(t),...A].filter(t=>t.unavailablePlatform!==e)}function M(e){if(O(e)===null)return`Pick a letter, digit or punctuation key.`;if(le.has(e))return`The browser keeps that shortcut for itself.`;if(D.has(e))return`That shortcut stays with copy, cut, paste, select all and undo.`;let t=A.find(t=>t.stepByCode.has(e));return t?`That key is already used to ${t.label.charAt(0).toLowerCase()}${t.label.slice(1)}.`:null}function ue(e){return typeof e==`string`&&M(e)===null}var de=new Set([`Meta`,`Alt`,`Control`,`Shift`,`OS`]);function fe(e,t){if(e.key===`Escape`)return{kind:`cancelled`};if(de.has(e.key))return{kind:`ignored`};let n=t===`mac`?`Cmd`:`Alt`;if(!N(e,t,k(e.code)))return{kind:`refused`,reason:`Hold ${n} alone while pressing the key.`};let r=M(e.code);return r?{kind:`refused`,reason:r}:{kind:`recorded`,keyCode:e.code}}function pe(e){return/Mac|iPhone|iPad/.test(e)?`mac`:`other`}function N(e,t,n){return e.ctrlKey?!1:t===`mac`?!e.shiftKey&&e.metaKey&&e.altKey===!!n.needsMacOption:e.altKey&&!e.metaKey&&e.shiftKey===!!n.needsShiftOffMac}function me(e,t,n){return n.isTerminalFocused&&t!==`mac`&&!!e.isShellChord}var he=new Set([`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`PageUp`,`PageDown`]);function P(e){return he.has(e.key)?e.key:e.code}function F(e,t,n={isTerminalFocused:!1},r=E){let i=P(e);for(let a of j(t,r)){let r=a.stepByCode.get(i);if(r!==void 0&&N(e,t,a))return me(a,t,n)?null:{action:a.action,step:r}}return null}function I(e,t){return t===`focus`||e.action===`quick-session`}function L(e,t){return e===`mac`?t?.needsMacOption?`${T}${oe}`:T:t?.needsShiftOffMac?`Alt+Shift`:`Alt`}function R(e,t,n){let r=j(t,n).find(t=>t.action===e);if(!r)throw Error(`Unknown dashboard shortcut: ${e}`);return r}function z(e,t,n=E){let r=R(e,t,n);return[L(t,r),r.keyCaptions.join(` `)]}function ge(e,t){let[n,r]=z(e,t);return t===`mac`?`${n}${r}`:`${n}+${r}`}function _e(e){let t=e===`mac`?`Meta`:`Alt`;return`ArrowUp ArrowDown ${t}+ArrowUp ${t}+ArrowDown`}function ve(e){return e===`mac`?`Cmd+Enter`:`Ctrl+Enter`}function ye(e,t=E){let n=e===`mac`?T:`Ctrl`;return[{title:`Dashboard`,items:j(e,t).map(t=>({combos:t.keyCaptions.map(n=>[L(e,t),n]),label:t.label}))},{title:`Navigation`,items:[{combos:[[x],[S]],label:`Move rail highlight (rail focused)`},{combos:[[C],[w]],label:`Switch view tab (tab focused)`}]},{title:`Reviews`,items:[{combos:[[`J`],[`K`]],label:`Next / previous pull request in the queue`},{combos:[[`N`],[`P`]],label:`Next / previous finding`},{combos:[[`X`]],label:`Post or drop the current finding`},{combos:[[`O`]],label:`Open the pull request in a session`},{combos:[[`A`],[`R`],[`C`]],label:`Pick Approve, Request changes or Comment`},{combos:[[n,`Enter`]],label:`Post the picked action, or the leading one from the note`},{combos:[[`Esc`]],label:`Drop the picked action`}]},{title:`Terminal`,items:[{combos:[[n,`C`]],label:`Copy selection`},{combos:[[n,`V`]],label:`Paste`},{combos:[[n,`Backspace`]],label:`Delete previous word`}]},{title:`General`,items:[{combos:[[`Esc`]],label:`Close dialog / cancel rename`}]}]}var B=`glimmervoid-ui-prefs`,V=`glimmervoid:sidebar-width`,H=e=>t=>typeof t==`boolean`?t:e,U=e=>t=>typeof t==`string`?t:e,W=e=>typeof e==`string`&&e?e:null,G=e=>typeof e==`number`&&Number.isFinite(e)?e:null,K=e=>t=>G(t)??e,q=e=>Array.isArray(e)?[...new Set(e.filter(e=>typeof e==`string`&&e!==``))]:[],J={soundEnabled:H(!0),soundId:U(m),themeId:U(`phyrexian`),flyingAnimalsEnabled:H(!1),flyingAnimalsMinGapSeconds:K(r.flyingAnimalsMinGapSeconds),flyingAnimalsMaxGapSeconds:K(r.flyingAnimalsMaxGapSeconds),flyingAnimalsMinDurationSeconds:K(r.flyingAnimalsMinDurationSeconds),flyingAnimalsMaxDurationSeconds:K(r.flyingAnimalsMaxDurationSeconds),flyingAnimalsScale:K(r.flyingAnimalsScale),flyingAnimalsOnPhone:H(r.flyingAnimalsOnPhone),flyingAnimalsExcludedSprites:c,notificationsEnabled:H(!0),sessionUsageChips:H(!1),phoneArrowPad:H(!1),nextAttentionKeyCode:e=>ue(e)?e:E,activeView:U(`focus`),lastFocusedSessionId:W,railWidth:G,reviewSidebarExpanded:H(!1),prsQueueWidth:G,prsQueueCollapsed:H(!1),keptProjects:q,traceHiddenKinds:q,dismissedUpdate:W,telemetryNoticeDismissed:H(!1),radarAttentionAck:U(``),prsAttentionAck:U(``),prsUnseenRows:U(``),usageAttentionAck:U(``),visionsAttentionAck:U(``)};function Y(e,t,n){e[t]=J[t](n)}function X(){let e=y(B,{}),t={};for(let n of Object.keys(J))Y(t,n,e?.[n]);return t}function Z(e){return X()[e]}function Q(e,t){let n=X();Y(n,e,t),b(B,n)}var be=()=>Z(`soundEnabled`),xe=e=>Q(`soundEnabled`,e),Se=()=>Z(`soundId`),Ce=e=>Q(`soundId`,e),we=()=>Z(`notificationsEnabled`),Te=e=>Q(`notificationsEnabled`,e),Ee=()=>Z(`sessionUsageChips`),De=e=>Q(`sessionUsageChips`,e),Oe=()=>Z(`phoneArrowPad`),$=e=>Q(`phoneArrowPad`,e),ke=()=>Z(`nextAttentionKeyCode`),Ae=e=>Q(`nextAttentionKeyCode`,e),je=()=>Z(`themeId`),Me=e=>Q(`themeId`,e),Ne=()=>Z(`flyingAnimalsEnabled`),Pe=e=>Q(`flyingAnimalsEnabled`,e),Fe=()=>Z(`activeView`),Ie=e=>Q(`activeView`,e),Le=()=>Z(`railWidth`),Re=e=>Q(`railWidth`,e),ze=()=>Z(`reviewSidebarExpanded`),Be=e=>Q(`reviewSidebarExpanded`,e),Ve=()=>Z(`prsQueueWidth`),He=e=>Q(`prsQueueWidth`,e),Ue=()=>Z(`prsQueueCollapsed`),We=e=>Q(`prsQueueCollapsed`,e),Ge=()=>Z(`keptProjects`),Ke=e=>Q(`keptProjects`,e),qe=()=>Z(`traceHiddenKinds`),Je=e=>Q(`traceHiddenKinds`,e),Ye=()=>Z(`dismissedUpdate`),Xe=e=>Q(`dismissedUpdate`,e),Ze=()=>Z(`telemetryNoticeDismissed`),Qe=e=>Q(`telemetryNoticeDismissed`,e),$e=()=>Z(`radarAttentionAck`),et=e=>Q(`radarAttentionAck`,e),tt=()=>Z(`prsAttentionAck`),nt=e=>Q(`prsAttentionAck`,e),rt=()=>Z(`prsUnseenRows`),it=e=>Q(`prsUnseenRows`,e),at=()=>Z(`usageAttentionAck`),ot=e=>Q(`usageAttentionAck`,e),st=()=>Z(`visionsAttentionAck`),ct=e=>Q(`visionsAttentionAck`,e),lt=()=>Z(`lastFocusedSessionId`),ut=e=>Q(`lastFocusedSessionId`,e),dt=()=>G(y(V,null)),ft=e=>b(V,G(e)),pt=e=>Q(`flyingAnimalsMinGapSeconds`,e),mt=e=>Q(`flyingAnimalsMaxGapSeconds`,e),ht=e=>Q(`flyingAnimalsMinDurationSeconds`,e),gt=e=>Q(`flyingAnimalsMaxDurationSeconds`,e),_t=e=>Q(`flyingAnimalsScale`,e),vt=e=>Q(`flyingAnimalsOnPhone`,e),yt=e=>Q(`flyingAnimalsExcludedSprites`,e),bt=()=>l(X()),xt=()=>{let e=X();return Object.fromEntries(Object.keys(r).map(t=>[t,e[t]]))},St=()=>b(B,{...X(),...r});export{Ce as $,Pe as A,Ae as B,ze as C,re as Ct,St as D,d as Dt,Ze as E,u as Et,pt as F,He as G,$ as H,vt as I,Re as J,it as K,_t as L,gt as M,mt as N,Ie as O,i as Ot,ht as P,xe as Q,Ke as R,Ue as S,ie as St,be as T,p as Tt,nt as U,Te as V,We as W,De as X,Be as Y,ft as Z,at as _,m as _t,Ge as a,I as at,we as b,ne as bt,tt as c,F as ct,$e as d,ye as dt,Qe as et,Le as f,ge as ft,qe as g,g as gt,je as h,b as ht,bt as i,ct as it,yt as j,Xe as k,Ve as l,ve as lt,Se as m,y as mt,Ye as n,Je as nt,lt as o,_e as ot,dt as p,pe as pt,et as q,xt as r,ot as rt,ke as s,fe as st,Fe as t,Me as tt,rt as u,z as ut,st as v,_ as vt,Ee as w,f as wt,Oe as x,ae as xt,Ne as y,v as yt,ut as z};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Ct as e,St as t,Tt as n,n as r,o as i,u as a,wt as o,xt as s}from"./dom-helpers-xJduxDcc.js";import{n as c,t as l}from"./poll-ago-Bc-8mMFj.js";import{$t as u,Qt as d,a as f,an as p,c as m,cn as h,d as g,en as _,in as v,l as ee,ln as te,nn as ne,o as re,on as ie,rn as y,s as ae,sn as oe,sr as se,tn as ce,u as le,un as ue}from"./index-D6m--U7B.js";var de=`Estimated list prices, not a bill.`,fe=`Enable in Settings.`,pe=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],b=/^(\d{4})-(\d{2})-(\d{2})$/,me=new Set([`day`,`model`,`label`]),he=new Set([`model`,`label`]);function x(e){return typeof e!=`number`||!Number.isFinite(e)?`-`:e>0&&e<.1?`<0.1%`:`${te(e.toFixed(1))}%`}function ge(e){let t=Number(e?.costUSD);return Number.isFinite(t)&&t>0?`costUSD`:`tokens`}function _e(e){return e===`costUSD`?`share of cost`:`share of tokens`}function S(e,t){let n=Number(e),r=Number(t);return!Number.isFinite(n)||!Number.isFinite(r)||r<=0?null:n/r*100}function C(e){let t=b.exec(String(e??``));if(!t)return String(e??``)||`-`;let n=pe[Number(t[2])-1];return n?`${n} ${Number(t[3])}`:String(e)}function ve(e){let t=ye(e);return t.length===0?``:t.length===1?C(t[0]):`${C(t[0])} to ${C(t[t.length-1])}`}function ye(e){return(Array.isArray(e)?e:[]).map(e=>typeof e==`string`?e:e?.day).map(e=>String(e??``)).filter(e=>b.test(e)).sort()}function be(e){let t=Number(e?.ts);return!Number.isFinite(t)||t<=0?``:xe(t,typeof e?.tz==`string`&&e.tz?e.tz:null)}function xe(e,t){let n={year:`numeric`,month:`2-digit`,day:`2-digit`};t&&(n.timeZone=t);let r=Se(e,n);return b.test(r)?r:Se(e,{year:`numeric`,month:`2-digit`,day:`2-digit`})}function Se(e,t){try{return new Intl.DateTimeFormat(`en-CA`,t).format(new Date(e))}catch{return``}}function w(t){return typeof t!=`number`||!Number.isFinite(t)||t<0?`-`:e(Math.round(t)*60,{smallestUnit:`m`,dropsZeroRemainder:!0})}function Ce(e){let n=Number(e);if(!Number.isFinite(n)||n<=0)return`-`;let r=new Date(n),i=pe[r.getMonth()];return i?`${i} ${r.getDate()} ${t(r)}`:`-`}function we(e){if(!e||typeof e!=`object`)return[];let t=[];if(Number.isFinite(e.tokensPerMinute)){let n=Number.isFinite(e.tokensPerMinuteExCache)?`${y(e.tokensPerMinuteExCache)} excluding cache`:``;t.push({label:`tokens per min`,value:y(e.tokensPerMinute),sub:n})}return Number.isFinite(e.costPerHour)&&t.push({label:`cost per hour`,value:v(e.costPerHour),sub:``}),t}function Te(e){if(!e||typeof e!=`object`)return``;let t=[];Number.isFinite(e.projectedTokens)&&t.push(`${y(e.projectedTokens)} tokens`),Number.isFinite(e.projectedCostUSD)&&t.push(v(e.projectedCostUSD));let n=Number.isFinite(e.remainingMinutes)?`${w(e.remainingMinutes)} left in this block`:``;if(t.length===0)return n;let r=`-> ${t.join(`, `)} by block end`;return n?`${r}, ${n}`:r}function Ee(e,t=Date.now()){let n=Number(e?.startTs),r=Number(e?.endTs);if(!Number.isFinite(n)||!Number.isFinite(r)||r<=n)return null;let i=(r-n)/6e4,a=Math.min(Math.max((t-n)/6e4,0),i);return{totalMinutes:i,elapsedMinutes:a,remainingMinutes:Math.max(i-a,0),pct:Math.round(a/i*100)}}function De(e){let t=p(e);return t===null?``:`${Math.round(t)}% of ${y(e?.max)} tokens, the largest completed block seen`}function Oe(e,t){let n=oe(e,t);return n===null?``:n>=100?`On this burn rate the block ends past that reference, at ${Math.round(n)}% of it.`:`On this burn rate the block ends at ${Math.round(n)}% of that reference.`}var ke=Object.freeze([{key:`input`,label:`input`},{key:`output`,label:`output`},{key:`cacheCreate`,label:`cache write`},{key:`cacheRead`,label:`cache read`}]);function Ae(e){let t=ke.map(t=>{let n=Number(e?.[t.key]);return{spec:t,tokens:Number.isFinite(n)&&n>0?n:0}}),n=t.reduce((e,t)=>e+t.tokens,0);return n<=0?[]:t.map(e=>{let t=S(e.tokens,n)??0,r=y(e.tokens);return{key:e.spec.key,label:e.spec.label,value:r,pct:t,title:`${e.spec.label} ${r}, ${x(t)}`}})}var je=Object.freeze({interactive:`Interactive`,"pr-review":`PR review`,"team-review":`PR reviews`,posthog:`PostHog`,"my-prs":`Keep mergeable`,workflows:`Workflows`,"change-map":`Change map`,visions:`Visions`,benchmark:`Benchmarks`,"agent-spawn":`Agent API`,"task-title":`Task titles`,other:`Other`}),Me=`Sessions spawned by Glimmervoid; terminal sessions count as other`,Ne=`Claude sessions Glimmervoid spawned for its own work; plan share is estimated pro rata by cost`;function Pe(e){let t=n(e,``);return t?je[t]||t:je.other}function T(e){let t=e?.byLane;return Array.isArray(t)?t.filter(e=>e&&typeof e.lane==`string`):[]}function Fe(e){if(typeof e!=`string`)return!1;let t=e.trim();return t!==``&&t!==`interactive`&&t!==`other`}function Ie(e){return T(e).some(e=>Fe(e.lane))}var Le=Object.freeze({fiveHour:`This 5 hour block`,sevenDay:`7 day window`});function Re(e,t,n){let r=ie(e,t);return!r||r.resetsAtMs!==null&&r.resetsAtMs<=n?null:r.pct}function ze(e,t,n,r){if(!Array.isArray(t))return null;let i=t.filter(e=>e&&typeof e.lane==`string`),a=i.reduce((e,t)=>e+o(t.costUSD,0),0),s=i.reduce((e,t)=>e+o(t.tokens,0),0),c=i.filter(e=>Fe(e.lane)).map(e=>({lane:String(e.lane),label:Pe(e.lane),tokens:o(e.tokens,0),costUSD:o(e.costUSD,0)})),l=c.reduce((e,t)=>e+t.costUSD,0),u=c.reduce((e,t)=>e+t.tokens,0),d=a>0?S(l,a):S(u,s),f=Re(n,e,r),p=d===null||f===null?null:d/100*f;return{key:e,label:Le[e],tokens:u,costUSD:l,sharePct:d,planPct:p,lanes:c}}function Be(e,t,n=Date.now()){let r=e?.planWindowLanes;return!r||typeof r!=`object`?[]:O.map(e=>ze(e.key,r[e.key],t,n)).filter(e=>e!==null)}function Ve(e){return e.planPct===null?``:`about ${x(e.planPct)} of plan`}function He(e){return e.lanes.filter(e=>e.costUSD>0||e.tokens>0).map(e=>`${e.label} ${e.costUSD>0?v(e.costUSD):y(e.tokens)}`).join(`, `)}var Ue=`team-review`;function We(e){if(!Array.isArray(e?.byLane))return null;let t=T(e).find(e=>e.lane===Ue),n=o(t?.costUSD,0),r=o(t?.tokens,0),i=ge(e?.totals),a=S(i===`costUSD`?n:r,e?.totals?.[i]),s=a===null?``:`${x(a)} of range ${i===`costUSD`?`cost`:`tokens`}`,c=[v(n),s,Ge(t?.sessions)].filter(Boolean).join(`, `);return{label:Pe(Ue),value:y(r),sub:c}}function Ge(e){let t=o(e,null);return t===null||t<=0?``:`${ne(t)} ${t===1?`session`:`sessions`}`}function Ke(e){let t=e?.rtk;return!t||typeof t!=`object`||t.available!==!0?null:t}function qe(e){let t=e?.cache;return!t||typeof t!=`object`?null:t}function Je(e){return Ke(e)!==null||qe(e)!==null}function Ye(e){let t=Ke(e);if(!t)return null;let n=o(t.commands,0),r=n===1?`command`:`commands`;return{value:`${y(o(t.savedTokens,0))} tokens`,sub:`${x(o(t.savingsPct,0))} avg across ${ne(n)} ${r}`}}function Xe(e){let t=qe(e);if(!t)return null;let n=y(o(t.cacheReadTokens,0)),r=(Array.isArray(t.unpricedModels)?t.unpricedModels:[]).filter(e=>e),i=`${n} cache read tokens`;if(r.length===0)return{value:v(o(t.savedUSD,0)),sub:i};let a=r.length===1?`model`:`models`;return{value:v(o(t.savedUSD,0)),sub:`${i}, a floor (${r.length} unpriced ${a})`}}function Ze(e){return e===`monthly`?`this month`:`today`}function Qe(e){return`${v(o(e?.spentUsd,0))} of ${v(o(e?.budgetUsd,0))}`}function $e(e){return`${Ze(e?.scope)} spend against budget`}var et=Object.freeze([{value:`day`,label:`Day`},{value:`week`,label:`Week`},{value:`month`,label:`Month`}]);function tt(e){let t=b.exec(String(e??``));return t?new Date(Number(t[1]),Number(t[2])-1,Number(t[3]),12):null}function nt(e){let t=tt(e);if(!t)return``;let n=(t.getDay()+6)%7;return t.setDate(t.getDate()-n),s(t)}function rt(e){let t=b.exec(String(e??``));return t?`${t[1]}-${t[2]}`:``}function it(e){return{key:e,tokens:0,costUSD:0,input:0,output:0,cacheCreate:0,cacheRead:0,days:0,sources:new Set,vendorSet:new Set,modelByName:new Map}}function at(e,t){e.tokens+=o(t?.tokens,0),e.costUSD+=o(t?.costUSD,0),e.input+=o(t?.input,0),e.output+=o(t?.output,0),e.cacheCreate+=o(t?.cacheCreate,0),e.cacheRead+=o(t?.cacheRead,0),e.days+=1,e.sources.add(t?.source===`history`?`history`:`live`);let n=Array.isArray(t?.vendors)?t.vendors:[];for(let t of n)e.vendorSet.add(t);let r=t?.models||[];for(let t of r){t?.vendor&&e.vendorSet.add(t.vendor);let n=A(t),r=e.modelByName.get(n)||{key:n,model:t?.model??n,vendor:t?.vendor,tokens:0,costUSD:0,input:0,output:0,cacheCreate:0,cacheRead:0};r.tokens+=o(t?.tokens,0),r.costUSD+=o(t?.costUSD,0),r.input+=o(t?.input,0),r.output+=o(t?.output,0),r.cacheCreate+=o(t?.cacheCreate,0),r.cacheRead+=o(t?.cacheRead,0),e.modelByName.set(n,r)}}function ot(e){let{modelByName:t,sources:n,vendorSet:r,...i}=e,a={...i};return a.day=e.key,a.models=Array.from(t.values()).sort((e,t)=>t.tokens-e.tokens),a.source=n.has(`live`)?`live`:`history`,a.vendors=Array.from(r).sort(),a}function st(e,t){let n=new Map,r=Array.isArray(e)?e:[];for(let e of r){let r=t(e?.day);if(!r)continue;let i=n.get(r)||it(r);at(i,e),n.set(r,i)}return Array.from(n.values()).map(ot)}function ct(e){return st(e,nt)}function lt(e){return st(e,rt)}function ut(e,t){return t===`week`?ct(e):t===`month`?lt(e):Array.isArray(e)?[...e]:[]}var dt=/^(\d{4})-(\d{2})$/;function ft(e,t){if(t===`month`){let t=dt.exec(String(e??``));if(!t)return String(e??``)||`-`;let n=pe[Number(t[2])-1];return n?`${n} ${t[1]}`:String(e)}if(t===`week`){let t=C(e);return t===`-`?t:`week of ${t}`}return C(e)}function pt(e){return(Array.isArray(e)?e:[]).some(e=>e?.source===`history`)?`older days from local history`:``}var mt=16,ht=Object.freeze([.05,.25,.5,.75]),gt=Object.freeze([`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`]);function _t(e,t){let n=o(e,0),r=o(t,0);if(n<=0||r<=0)return 0;let i=n/r,a=1;for(let e=0;e<ht.length;e+=1)i>=ht[e]&&(a=e+1);return a}function vt(e,{weeks:t=mt,today:n=new Date}={}){let r=(Array.isArray(e)?e:[]).filter(e=>b.test(String(e?.day??``))),i=new Map(r.map(e=>[String(e.day),e])),a=n instanceof Date?n:new Date(n),c=Number.isFinite(a.getTime())?a:new Date,l=typeof n==`string`&&b.test(n)?n:s(c),u=tt(nt(l));if(!u)return{cells:[],max:0,weeks:0};let d=new Date(u.getFullYear(),u.getMonth(),u.getDate()-(t-1)*7,12),f=s(d),p=[],m=0,h=null;for(let e of r){let t=String(e.day);(h===null||t<h)&&(h=t),!(t<f||t>l)&&(m=Math.max(m,o(e.tokens,0)))}for(let e=0;e<t;e+=1)for(let t=0;t<7;t+=1){let n=new Date(d.getFullYear(),d.getMonth(),d.getDate()+e*7+t,12),r=s(n),a=i.get(r)||null,c=r>l,u=h!==null&&r<h;p.push({day:r,week:e,weekday:t,tokens:o(a?.tokens,0),costUSD:o(a?.costUSD,0),source:a?.source===`history`?`history`:a?`live`:null,noData:c||u||!a&&h===null,tone:_t(a?.tokens,m)})}return{cells:p,max:m,weeks:t}}function yt(e){let t=C(e?.day);if(e?.noData)return`${t}: no data`;let n=o(e?.tokens,0);return n<=0?`${t}: no usage`:`${t}: ${y(n)} tokens, ${v(o(e?.costUSD,0))}`}function bt(e){if(!e)return``;let t=o(e.baselineDays,null),n=t===null?`recent`:`${Math.round(t)} day`;return`Today is ${Tt(e.ratio)} the ${n} average: ${v(e.todayUsd)} against ${v(e.baselineUsd)}.`}function xt(e){return e?`This block is burning ${Tt(e.ratio)} the usual rate: ${y(e.current)} tokens per minute against ${y(e.baseline)}.`:``}function St(e){return[bt(e?.daily),xt(e?.burn)].filter(Boolean).join(` `)}function Ct(e){return e?.daily||e?.burn?`warn`:`ok`}function wt(e){return!!(e?.daily||e?.burn)}function Tt(e){let t=o(e,null);return t===null?`-`:`${te(t.toFixed(1))}x`}var Et=Object.freeze({claude:`Claude`,codex:`Codex`,grok:`Grok`});function Dt(e){let t=n(e,``);return t?Et[t]||t:Et.claude}function Ot(e,t){return E(t)?Dt(e?.vendor):``}function kt(e){let t=e?.byVendor;return!t||typeof t!=`object`?[]:Object.keys(t).filter(e=>t[e]&&typeof t[e]==`object`).sort((e,n)=>o(t[n]?.tokens,0)-o(t[e]?.tokens,0)).map(e=>({vendor:e,label:Dt(e),tokens:o(t[e]?.tokens,0),costUSD:o(t[e]?.costUSD,0)}))}function E(e){let t=e?.byVendor;if(!t||typeof t!=`object`)return!1;let n=Object.keys(t).filter(e=>t[e]&&typeof t[e]==`object`);return n.length>1||n.length===1&&n[0]!==`claude`}var At=`Claude only`;function D(e){return E(e)?At:``}var jt=36e5,O=Object.freeze([{key:`fiveHour`,label:`5 hour`},{key:`sevenDay`,label:`7 day`}]),Mt=Object.freeze([{vendor:`claude`,label:`Claude Code`},{vendor:`codex`,label:`Codex`}]);function Nt(e,t){let n=`official, from ${Mt.filter(({vendor:t})=>e.includes(t)).map(({label:e})=>e).join(` and `)}`,r=e.length===1&&e[0]===`claude`?D(t):``;return r?`${n}, ${r}`:n}function Pt(e){return O.some(t=>ie(e,t.key)!==null)}function Ft(e){return e===`estimated`?`estimated from the largest completed block`:``}function It(e){let t=o(e?.pct,null);return t===null?`-`:`${x(t)} used`}function Lt(e,t=Date.now()){let n=o(e,null);if(n===null||n<=0)return``;let r=(n-t)/6e4;return r<=0?`resetting now`:`resets in ${w(r)}`}function Rt(e,t=Date.now()){let n=o(e,null);return n===null||n<=0?``:`${Math.max(0,Math.round((t-n)/6e4))}m old`}function zt(e,t=Date.now()){let n=o(e,null);return n===null||n<=0||t-n>jt}function Bt(e,t=Date.now()){if(!zt(e,t))return``;let n=Rt(e,t);return n?`showing last-known usage (${n})`:`showing last-known usage`}function Vt(e){let t=(Array.isArray(e)?e:[]).map(e=>String(e)).filter(e=>e);if(t.length===0)return``;let n=t.length===1?`model`:`models`;return`No price for ${t.length} ${n}: ${t.join(`, `)}. Their cost counts as zero here.`}function Ht(e){let t=n(e?.warning,``);return t?`Glimmervoid could not read every transcript location: ${t}`:``}function Ut(e){return ue(e)!==``}function Wt(e){let t=String(e??``).trim();if(!t)return``;let n=t.split(/[\\/]+/).filter(e=>e);return n.length===0?t:n[n.length-1]}function Gt(e){return typeof e?.id==`string`&&e.id!==``}function k(e){let t=n(e?.label,``);return Gt(e)&&t?t:Wt(e?.project)||t||`unknown project`}function A(e){let t=typeof e==`string`?e:e?.model;return n(t,`unknown model`)}function Kt(e){return String(e?.day??``)}function qt(e,t,n){if(!me.has(t)){let n=Number(e?.[t]);return Number.isFinite(n)?n:0}return t===`day`?Kt(e):n(e)}function Jt(e,t,n,r=k){let i=Array.isArray(e)?[...e]:[],a=n===`asc`?1:-1;return i.sort((e,n)=>{let i=qt(e,t,r),o=qt(n,t,r);if(typeof i==`string`||typeof o==`string`)return a*String(i).localeCompare(String(o));if(i!==o)return a*(i-o);let s=Number(e?.tokens),c=Number(n?.tokens),l=Number.isFinite(s)?s:0,u=Number.isFinite(c)?c:0;return l===u?r(e).localeCompare(r(n)):u-l})}function Yt(e){return he.has(e)?`asc`:`desc`}function Xt(e,t){return e?.key===t?{key:t,dir:e.dir===`asc`?`desc`:`asc`}:{key:t,dir:Yt(t)}}function Zt(e,t){return e?.key===t?e.dir===`asc`?`ascending`:`descending`:`none`}var Qt=Object.freeze({key:`lastTs`,dir:`desc`}),$t=Object.freeze({key:`tokens`,dir:`desc`}),en=Object.freeze({key:`day`,dir:`desc`});function tn(e,t=Qt){return Jt(e,t.key,t.dir,k)}function nn(e,t,n=10){if(!Array.isArray(e))return{rows:[],hiddenCount:0};let r=Number.isFinite(n)?Math.max(0,Math.floor(n)):10;return t||e.length<=r?{rows:e,hiddenCount:0}:{rows:e.slice(0,r),hiddenCount:e.length-r}}function rn(e){let t=Number(e);return!Number.isFinite(t)||t<=0?``:`${ne(t)} hidden`}function an(e,t=$t){return Jt(e,t.key,t.dir,A)}function on(e,t=en){return Jt(e,t.key,t.dir,Kt)}function sn(e,t){return(Array.isArray(e)?e:[]).find(e=>String(e?.day??``)===String(t??``))||null}function cn(e,t=8){return(Array.isArray(e)?e:[]).filter(e=>e&&e.isGap!==!0).sort((e,t)=>(Number(t?.startTs)||0)-(Number(e?.startTs)||0)).slice(0,Math.max(0,t)).map(e=>({startTs:Number(e.startTs),tokens:typeof e.tokens==`number`&&Number.isFinite(e.tokens)?e.tokens:0,costUSD:typeof e.costUSD==`number`&&Number.isFinite(e.costUSD)?e.costUSD:0,isActive:e.isActive===!0}))}var j=g(),M=null,N=en,P=$t,F=Qt,I=!1,L=null,R=`day`,z=new Set,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=l(()=>M),J=(e,t)=>r(`usage`,e,t);function Y(e,t,n,r){let a=i(`div`,`usage-tile`);r&&r!==`ok`&&(a.dataset.tone=r);let o=i(`span`,`usage-tile-value`,t);a.append(o,i(`span`,`usage-tile-label`,e));let s=n?i(`span`,`usage-tile-sub`,n):null;return s&&a.append(s),{tile:a,valueEl:o,subEl:s}}function ln(e){let t=Number(e);return Number.isFinite(t)?Math.min(Math.max(t,0),100):0}function X(e,t,n){let r=i(`div`,`usage-meter`);r.dataset.tone=String(t),r.setAttribute(`role`,`progressbar`),r.setAttribute(`aria-valuemin`,`0`),r.setAttribute(`aria-valuemax`,`100`),r.setAttribute(`aria-label`,n);let a=i(`span`,`usage-meter-fill`);return r.append(a),un(r,e),r}function un(e,t){if(!e)return;let n=ln(t);e.setAttribute(`aria-valuenow`,String(Math.round(n)));let r=e.querySelector(`.usage-meter-fill`);r&&(r.style.width=`${n}%`)}function Z(e,t,n,r){let a=i(`div`,`usage-table-scroll`);a.dataset.usageTable=r;let o=i(`table`,`usage-table`),s=i(`thead`),c=i(`tr`);for(let a of e){let e=i(`th`,a.numeric?`usage-num`:null);if(e.scope=`col`,!a.key){e.textContent=a.label,c.append(e);continue}let o=a.key;e.setAttribute(`aria-sort`,Zt(t,o));let s=i(`button`,`usage-sort`,a.label);s.type=`button`,s.dataset.sortKey=o,s.addEventListener(`click`,()=>{f(`sort`),L={kind:`sort`,table:r,key:o},n(o)}),e.append(s),c.append(e)}s.append(c);let l=i(`tbody`);return o.append(s,l),a.append(o),{wrap:a,body:l}}function Q(e,t){for(let n of t){let t=i(`td`,n.numeric?`usage-num`:n.className||null,n.node?null:n.text);n.node&&t.append(n.node),n.title&&(t.title=n.title),n.span&&(t.colSpan=n.span),e.append(t)}}function dn(e){let t=i(`div`,`usage-share`);if(!Number.isFinite(e))return t.append(i(`span`,`usage-share-text`,x(e))),t;let n=i(`span`,`usage-share-bar`),r=i(`span`,`usage-share-fill`);return r.style.width=`${ln(e)}%`,n.append(r),t.append(n,i(`span`,`usage-share-text`,x(e))),t}function fn(){if(!B?.isConnected)return;let e=Number(j.report?.ts);B.textContent=Number.isFinite(e)&&e>0?`Report ${c(e)}`:``}function pn(){if(!V?.isConnected)return;let e=Number(j.sessions?.ts);V.textContent=Number.isFinite(e)&&e>0?`Sessions ${c(e)}`:``}function mn(){let e=Ee(j.report?.activeBlock);e&&(H?.isConnected&&(H.textContent=`${e.pct}%`),U?.isConnected&&(U.textContent=`${w(e.remainingMinutes)} left`),W?.isConnected&&un(W,e.pct))}function hn(){let e=i(`div`,`usage-controls`),t=i(`label`,`usage-control`);t.append(i(`span`,`usage-control-label`,`Range`));let n=i(`select`,`usage-select`);for(let e of d){let t=i(`option`,null,e.label);t.value=e.value,n.append(t)}n.value=j.rangeValue,n.addEventListener(`change`,()=>{f(`range`),m(n.value),re()}),t.append(n);let r=i(`button`,`usage-refresh`,`Refresh`);r.type=`button`,r.title=`Re-read every transcript from the start`,r.addEventListener(`click`,()=>{f(`refresh`),re({force:!0})});let a=i(`span`,`usage-refresh-status`,``);return G=r,K=a,Gn(),e.append(t,r,a),e}function gn(){let e=J(`Usage`,ve(j.report?.daily||[]));e.append(hn()),B=i(`p`,`usage-meta`,``),e.append(B),fn(),q.onTick(fn);let t=Ht(j.report);t&&e.append(i(`p`,`usage-warning`,t));let n=Vt(j.report?.pricing?.missing);return n&&e.append(i(`p`,`usage-warning`,n)),e}function _n(){let e=Mt.filter(({vendor:e})=>Pt(j.planLimitsByVendor[e]));if(e.length===0)return null;let t=J(`Plan limits`,Nt(e.map(({vendor:e})=>e),j.report?.totals)),n=e.length>1,r=i(`div`,`usage-plan-vendors`);for(let{vendor:t,label:i}of e)r.append(vn(j.planLimitsByVendor[t],n?i:null));return t.append(r),t}function vn(e,t){let n=i(`div`,`usage-plan-vendor`);t&&n.append(i(`p`,`usage-plan-vendor-label`,t));let r=Bt(e?.ts);if(r){let e=i(`p`,`usage-meta`,r);e.dataset.tone=`warn`,n.append(e)}let a=i(`div`,`usage-plan`);for(let t of O){let n=ie(e,t.key);n&&a.append(yn(t,n))}let o=i(`p`,`usage-meta`,``);n.append(a,o);let s=()=>{if(!o.isConnected)return;let t=Rt(e?.ts);o.textContent=t?`Plan ${t}`:``};return s(),q.onTick(s),n}function yn(e,t){let n=i(`div`,`usage-plan-window`),r=i(`div`,`usage-plan-head`);r.append(i(`span`,`usage-plan-label`,e.label)),r.append(i(`span`,`usage-plan-used`,It(t)));let a=i(`span`,`usage-plan-reset`,``);r.append(a),n.append(r),Number.isFinite(t.pct)&&n.append(X(t.pct,h(t.pct),`${e.label} plan limit used`));let o=()=>{a.isConnected&&(a.textContent=Lt(t.resetsAtMs))};return o(),q.onTick(o),n}function bn(){let e=Be(j.report,j.planLimitsByVendor.claude),t=xn();if(e.length===0&&!t)return null;let n=J(`Glimmervoid overhead`,e.length>0?Ne:null);if(e.length>0){let t=i(`div`,`usage-tiles`);for(let n of e){let e=[Ve(n),v(n.costUSD)].filter(Boolean).join(`, `);t.append(Y(`${n.label}, share of Claude use`,x(n.sharePct),e).tile)}n.append(t);for(let t of e){let e=He(t);e&&n.append(i(`p`,`usage-meta`,`${t.label}: ${e}`))}}return t&&(n.append(i(`p`,`usage-meta`,`Selected range by lane. ${Me}`)),n.append(t)),n}function xn(){if(!Ie(j.report))return null;let e=T(j.report),t=e.reduce((e,t)=>e+(typeof t.costUSD==`number`&&Number.isFinite(t.costUSD)?t.costUSD:0),0),{wrap:n,body:r}=Z([{label:`Lane`},{label:`Cost`,numeric:!0},{label:`Tokens`,numeric:!0},{label:`Sessions`,numeric:!0},{label:`Share`,numeric:!0}],null,()=>{},`lane`);for(let n of e){let e=i(`tr`,`usage-row`);n.lane===`other`&&(e.dataset.lane=`other`),Q(e,[{text:Pe(n.lane),className:`usage-lane-cell`},{text:v(n.costUSD),numeric:!0},{text:y(n.tokens),numeric:!0},{text:Ge(n.sessions),numeric:!0},{node:dn(S(n.costUSD,t)),className:`usage-share-cell`}]),r.append(e)}return n}function Sn(){let e=j.report?.activeBlock,t=j.report?.blockHours,n=typeof t==`number`&&Number.isFinite(t)?t:5,r=D(j.report?.totals),a=J(`Current block`,r?`${n}h window, ${r}`:`${n}h window`);if(!e){a.append(i(`p`,`usage-empty`,`No active block.`));let e=Cn();return e&&a.append(e),a}let o=u(j.report,j.planLimitsByVendor.claude),s=i(`div`,`usage-tiles`);s.append(Y(`block tokens`,y(e.tokens??0),v(e.costUSD??0),o).tile);for(let t of we(e.burn))s.append(Y(t.label,t.value,t.sub,o).tile);let c=Ee(e);if(c){let e=Y(`elapsed`,`${c.pct}%`,`${w(c.remainingMinutes)} left`);H=e.valueEl,U=e.subEl,s.append(e.tile)}a.append(s),c&&(W=X(c.pct,`ok`,`Elapsed share of the current block window`),a.append(W),q.onTick(mn));let l=Te(e.projection);if(l){let e=i(`p`,`usage-projection`,l);e.dataset.tone=o,a.append(e)}let d=Cn();d&&a.append(d);let f=De(j.report?.tokenLimit);if(!f)return a;let m=p(j.report?.tokenLimit),h=u(j.report);a.append(X(m,h,`Share of the largest completed block seen, estimated`));let g=i(`p`,`usage-meta`,f);g.dataset.tone=h,a.append(g),a.append(i(`p`,`usage-provenance`,Ft(`estimated`)));let _=Oe(e.projection,j.report?.tokenLimit);if(_){let e=i(`p`,`usage-meta`,_);e.dataset.tone=h,a.append(e)}return a}function Cn(){let e=j.report?.anomaly;if(!wt(e))return null;let t=i(`p`,`usage-meta`,St(e));return t.dataset.tone=Ct(e),t}function wn(){let e=cn(j.report?.blocks);if(e.length===0)return null;let t=D(j.report?.totals),n=J(`Recent blocks`,t?`newest first, ${t}`:`newest first`),r=i(`div`,`usage-blocks`),a=e.reduce((e,t)=>Math.max(e,t.tokens),0);for(let t of e){let e=i(`div`,`usage-block`);t.isActive&&(e.dataset.active=`true`),e.append(i(`span`,`usage-block-label`,Ce(t.startTs)));let n=i(`span`,`usage-block-bar`),o=i(`span`,`usage-block-fill`);o.style.width=`${ln(S(t.tokens,a)??0)}%`,n.append(o),e.append(n),e.append(i(`span`,`usage-block-value`,`${y(t.tokens)} ${v(t.costUSD)}`)),r.append(e)}return n.append(r),n}function Tn(){let e=j.report?.totals||{},t=sn(j.report?.daily,be(j.report)),n=J(`Totals`,[de,j.report?.tz?`TZ ${j.report.tz}`:``].filter(Boolean).join(` `)),r=u(j.report,j.planLimitsByVendor.claude),a=i(`div`,`usage-tiles`);a.append(Y(`today`,y(t?.tokens??0),v(t?.costUSD??0),r).tile),a.append(Y(`range total`,y(e.tokens??0),v(e.costUSD??0)).tile);let o=We(j.report);o&&a.append(Y(o.label,o.value,o.sub).tile),n.append(a);let s=En(e);s&&n.append(s);let c=E(e)?kt(e):[];if(c.length>0){let e=i(`div`,`usage-tiles usage-vendor-tiles`);for(let t of c)e.append(Y(t.label,y(t.tokens),v(t.costUSD)).tile);n.append(e)}return V=i(`p`,`usage-meta`,``),n.append(V),pn(),q.onTick(pn),n}function En(e){let t=Ae(e);if(t.length===0)return null;let n=i(`div`,`usage-compo`),r=i(`div`,`usage-compo-bar`);r.setAttribute(`aria-hidden`,`true`);for(let e of t){if(e.pct<=0)continue;let t=i(`span`,`usage-compo-fill`);t.dataset.part=e.key,t.style.width=`${e.pct}%`,t.title=e.title,r.append(t)}let a=i(`div`,`usage-compo-legend`);for(let e of t){let t=i(`span`,`usage-compo-item`),n=i(`span`,`usage-compo-swatch`);n.dataset.part=e.key,t.append(n,i(`span`,`usage-compo-label`,e.label),i(`span`,`usage-compo-value`,e.value)),a.append(t)}return n.append(r,a),n}function Dn(){let e=j.report?.savings;if(!Je(e))return null;let t=J(`Savings`,``),n=i(`div`,`usage-tiles`),r=Ye(e);r&&n.append(Y(`rtk compression`,r.value,r.sub).tile);let a=Xe(e);return a&&n.append(Y(`Prompt cache`,a.value,a.sub).tile),t.append(n),t}function On(){let e=ce(j.report);if(e.length===0)return null;let t=J(`Budgets`,`your own ceilings`),n=i(`div`,`usage-budgets`),r=se(`machine-usage`,`usage-daily-budget`,`Budget settings`);n.appendChild(r);for(let t of e){let e=i(`div`,`usage-budget`),r=i(`div`,`usage-budget-head`);r.append(i(`span`,`usage-budget-label`,Ze(t.scope))),r.append(i(`span`,`usage-budget-value`,Qe(t))),r.append(i(`span`,`usage-budget-pct`,x(_(t)))),e.append(r),e.append(X(_(t),t.tone,$e(t))),n.append(e)}return t.append(n),t}function kn(){let e=j.report?.daily||[],t=R,n=on(ut(e,t),N),r=et.find(e=>e.value===t)?.label||`Day`,a=J(`Over time`,[pt(e)].filter(Boolean).join(`, `));if(a.append(An()),n.length===0)return a.append(i(`p`,`usage-empty`,`No usage.`)),a;let o=Mn(e);o&&a.append(o);let{wrap:s,body:c}=Z([{label:r,key:`day`},{label:`Tokens`,numeric:!0,key:`tokens`},{label:`Cost`,numeric:!0,key:`costUSD`},{label:`Models`}],N,e=>{N=Xt(N,e),$()},`day`);for(let e of n){let n=String(e.day??``),r=i(`tr`,`usage-row`);e.source===`history`&&(r.dataset.source=`history`);let a=an(e.models),o=`${t}:${n}`,s=Nn(o,a.length);Q(r,[{node:jn(e,t),title:n},{text:y(e.tokens),numeric:!0},{text:v(e.costUSD),numeric:!0},{node:s,className:`usage-toggle-cell`}]),c.append(r),a.length!==0&&z.has(o)&&c.append(Pn(a))}return a.append(s),a}function An(){let e=i(`div`,`usage-period`);e.setAttribute(`role`,`group`),e.setAttribute(`aria-label`,`Period`);for(let t of et){let n=i(`button`,`usage-period-button`,t.label);n.type=`button`,n.dataset.periodView=t.value,n.setAttribute(`aria-pressed`,t.value===R?`true`:`false`),n.addEventListener(`click`,()=>{R!==t.value&&(f(`period`),R=t.value,L={kind:`period`,view:t.value},$())}),e.append(n)}return e}function jn(e,t){let n=i(`span`,`usage-period-cell`);return n.append(i(`span`,null,ft(e.day,t))),e.source===`history`&&n.append(i(`span`,`usage-history-tag`,`history`)),n}function Mn(e){let{cells:t,max:n}=vt(e,{today:be(j.report)});if(t.length===0||n<=0)return null;let r=i(`div`,`usage-heatmap-scroll`),a=i(`div`,`usage-heatmap`);a.setAttribute(`role`,`img`),a.setAttribute(`aria-label`,`Daily usage for the trailing ${Math.max(...t.map(e=>e.week))+1} weeks`);let o=i(`div`,`usage-heatmap-days`);for(let e of gt)o.append(i(`span`,`usage-heatmap-day`,e));for(let e of t){let t=i(`span`,`usage-heatmap-cell`);t.dataset.tone=String(e.tone),e.noData&&(t.dataset.noData=`true`),e.source===`history`&&(t.dataset.source=`history`),t.style.gridColumn=String(e.week+1),t.style.gridRow=String(e.weekday+1),t.title=yt(e),a.append(t)}return r.append(o,a),r}function Nn(e,t){if(t===0)return null;let n=i(`button`,`usage-toggle`,`Models`);return n.type=`button`,n.dataset.usageDay=e,n.setAttribute(`aria-expanded`,z.has(e)?`true`:`false`),n.addEventListener(`click`,()=>{f(`expand`),L={kind:`day`,day:e},z.has(e)?(z.delete(e),$()):(z.add(e),$())}),n}function Pn(e){let t=i(`tr`,`usage-row-breakdown`),n=i(`td`,`usage-models`);n.colSpan=4;for(let t of e){let e=i(`span`,`usage-model-chip`);e.append(i(`span`,`usage-model-name`,A(t)),i(`span`,`usage-model-value`,`${y(t.tokens)} ${v(t.costUSD)}`)),n.append(e)}return t.append(n),t}function Fn(e,t){let n=i(`span`,`usage-model-name-wrap`),r=Ot(e,t);return r&&n.append(i(`span`,`usage-vendor-tag`,r)),n.append(i(`span`,null,A(e))),n}function In(){let e=an(j.report?.models,P),t=j.report?.totals||{},n=ge(t),r=J(`By model`,_e(n));if(e.length===0)return r.append(i(`p`,`usage-empty`,`No models.`)),r;let{wrap:a,body:o}=Z([{label:`Model`,key:`model`},{label:`Tokens`,numeric:!0,key:`tokens`},{label:`Cost`,numeric:!0,key:`costUSD`},{label:`Share`,numeric:!0},{label:`Input`,numeric:!0,key:`input`},{label:`Output`,numeric:!0,key:`output`},{label:`Cache write`,numeric:!0,key:`cacheCreate`},{label:`Cache read`,numeric:!0,key:`cacheRead`}],P,e=>{P=Xt(P,e),$()},`model`);for(let r of e){let e=i(`tr`,`usage-row`);Q(e,[{node:Fn(r,t),className:`usage-model-cell`,title:A(r)},{text:y(r.tokens),numeric:!0},{text:v(r.costUSD),numeric:!0},{node:dn(S(r[n],t[n])),className:`usage-share-cell`},{text:y(r.input),numeric:!0},{text:y(r.output),numeric:!0},{text:y(r.cacheCreate),numeric:!0},{text:y(r.cacheRead),numeric:!0}]),o.append(e)}return r.append(a),r}function Ln(){let e=tn(j.report?.sessions,F),t=nn(e,I),n=j.report?.totals||{},r=ge(n),a=J(`By session`,_e(r));if(e.length===0)return a.append(i(`p`,`usage-empty`,`No sessions.`)),a;let{wrap:o,body:s}=Z([{label:`Session`,key:`label`},{label:`Tokens`,numeric:!0,key:`tokens`},{label:`Cost`,numeric:!0,key:`costUSD`},{label:`Share`,numeric:!0},{label:`Last activity`,numeric:!0,key:`lastTs`}],F,e=>{F=Xt(F,e),$()},`session`);for(let e of t.rows){let t=i(`tr`,`usage-row`);Gt(e)&&(t.dataset.managed=`true`);let a=k(e),o=i(`span`,`usage-ago`,``);Q(t,[{text:a,className:`usage-session-cell`,title:e.project?String(e.project):a},{text:y(e.tokens),numeric:!0},{text:v(e.costUSD),numeric:!0},{node:dn(S(e[r],n[r])),className:`usage-share-cell`},{node:o,numeric:!0}]),q.track(o,Number(e.lastTs),c),s.append(t)}return a.append(o),e.length>10&&a.append(Rn(t.hiddenCount)),a}function Rn(e){let t=i(`div`,`usage-overflow`),n=rn(e);n&&t.append(i(`p`,`usage-meta`,n));let r=i(`button`,`usage-toggle`,`All sessions`);return r.type=`button`,r.dataset.usageSessionsToggle=`true`,r.setAttribute(`aria-expanded`,I?`true`:`false`),r.addEventListener(`click`,()=>{f(`expand`),L={kind:`sessions-toggle`},I=!I,$()}),t.append(r),t}function zn(){let e=J(`Not available`,``);return e.append(i(`p`,`usage-empty`,ue(j.report))),e.append(i(`p`,`usage-empty`,fe)),e}function Bn(){B=null,V=null,H=null,U=null,W=null,G=null,K=null}function $({force:e=!1}={}){if(!M||!e&&a(M))return;j=g();let t=M.parentElement,n=t?t.scrollTop:0;q.reset(),Bn(),M.textContent=``,Un(),t&&(t.scrollTop=n),Vn()}function Vn(){let e=L;if(L=null,!e)return;let t=Hn(e);if(!t||!M)return;let n=M.querySelector(t);n instanceof HTMLElement&&n.focus()}function Hn(e){return e.kind===`day`?`.usage-toggle[data-usage-day="${CSS.escape(e.day)}"]`:e.kind===`period`?`.usage-period-button[data-period-view="${CSS.escape(e.view)}"]`:e.kind===`sessions-toggle`?`.usage-toggle[data-usage-sessions-toggle="true"]`:e.kind===`sort`?`[data-usage-table="${CSS.escape(e.table)}"] .usage-sort[data-sort-key="${CSS.escape(e.key)}"]`:null}function Un(){if(!M)return;M.append(gn());let e=_n();if(Ut(j.report)){e&&M.append(e),M.append(zn());return}if(!j.report){e&&M.append(e),M.append(i(`p`,`usage-empty`,`Waiting for scan.`));return}let t=[e,On()].filter(e=>e!==null);M.append(Wn(`usage-band-now`,Sn(),t,{sideFirst:!0}));let n=[Dn()].filter(e=>e!==null);M.append(Wn(`usage-band-spend`,Tn(),n));let r=[wn()].filter(e=>e!==null);M.append(Wn(`usage-band-trend`,kn(),r));let a=bn();a&&M.append(a),M.append(In(),Ln())}function Wn(e,t,n,{sideFirst:r=!1}={}){if(n.length===0)return t;let a=i(`div`,`usage-band ${e}`),o=i(`div`,`usage-band-col`);for(let e of n)o.append(e);return r?(a.append(o,t),a):(a.append(t,o),a)}function Gn(){let e=le();G&&(G.disabled=e.isPending),K&&(K.textContent=e.text,e.hasFailure?K.dataset.tone=`error`:delete K.dataset.tone)}function Kn(e){e===`refresh-status`?Gn():(j=g(),e===`sessions`&&j.report&&!Ut(j.report)&&V?.isConnected?pn():$())}function qn(e){if(M)return;let t=i(`div`,`usage-content`);e.appendChild(t),M=t,ae(()=>!a(M)),ee(Kn),q.ensure(),$({force:!0})}function Jn(e){e===`shown`&&$({force:!0}),re()}var Yn={mount:qn,refresh:Jn};export{Yn as view};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as e,gt as t,o as n,u as r,yt as i}from"./dom-helpers-xJduxDcc.js";import{i as a}from"./action-status-BwqYb9eF.js";import{Gt as o,Ht as s,Jt as c,Kt as l,Ut as u,Vt as d,Wt as f,qt as p,sr as m}from"./index-D6m--U7B.js";var h=`No findings. Open a markdown file in a connected editor.`;function g(e){let t=Number(e?.range?.start?.character);return Number.isFinite(t)?t:0}function _(e){let t=Number(e?.range?.start?.line);return Number.isFinite(t)?t:0}function v(e){let t=typeof e==`string`?e:``;if(!t)return``;let n=t.lastIndexOf(`/`),r=n===-1?t:t.slice(n+1);if(!r)return t;try{return decodeURIComponent(r)}catch{return r}}function y(e){return typeof e==`number`&&Number.isFinite(e)?Math.max(Math.floor(e),0):0}function b(e){let t=y(e);return t===1?`1 finding`:`${t} findings`}function x(e){let t=y(e);return t===1?`1 comment`:`${t} comments`}function S(e){let t=y(e?.findings?.length),n=y(e?.comments?.length),r=typeof e?.hand==`string`&&e.hand?1:0,i=[];return r>0&&i.push(`raised hand`),t>0&&i.push(b(t)),n>0&&i.push(x(n)),i.length>0?i.join(`, `):b(0)}function C(e){let t=typeof e==`string`?e.trim():``;return t?`Raised hand: ${t}`:``}function w(e,t=new Map,n=new Map){let r=[],i=new Set([...e.keys(),...t.keys(),...n.keys()]);for(let a of i){let i=e.get(a),o=t.get(a),s=n.get(a)||null,c=Array.isArray(i)?i:[],l=Array.isArray(o)?o:[];(c.length!==0||l.length!==0||s)&&r.push({uri:a,name:v(a)||a,hand:s,findings:[...c].sort((e,t)=>_(e)-_(t)||g(e)-g(t)),comments:[...l].sort((e,t)=>(Number(e?.line)||0)-(Number(t?.line)||0))})}return r.sort((e,t)=>T(e.name,t.name)||T(e.uri,t.uri)),r}function T(e,t){return e<t?-1:+(e>t)}var E=`No fixes yet. Silent fixes appear here once the lane applies or is refused one.`;function ee(e){let t=y(e);return t===1?`1 fix`:`${t} fixes`}var te=`No activity yet. The ingest lane reports what your sessions and tools are doing.`,ne={terminal:`terminal`,agentLogs:`agent`,git:`git`,fs:`files`,shellHistory:`shell`,editor:`editor`};function D(e){let t=typeof e==`string`?e:``;return ne[t]||t||`source`}function O(e,n=Date.now()){let r=Number(e);return!Number.isFinite(r)||r<=0?``:i(Number(n)-r,t)}function k(e){let t=y(e);return t<=0?``:t===1?`1 more event not shown`:`${t} more events not shown`}function A(e){let t=y(e);return t===1?`1 event`:`${t} events`}function j(e){if(!e?.root)return`machine`;let t=e.root.replace(/[\\/]+$/,``),n=Math.max(t.lastIndexOf(`/`),t.lastIndexOf(`\\`));return n===-1?t:t.slice(n+1)}var M=null,N=null,P=null,F=null,I=null;function L(){let e=n(`section`,`visions-intent`);e.append(n(`h2`,`visions-intent-title`,`Intent`));let t=n(`div`,`visions-intent-list`);return e.append(t),P={list:t},e}function R(e){let t=n(`div`,`visions-intent-item`),r=n(`div`,`visions-intent-head`);r.append(n(`span`,`visions-intent-scope`,e.label),n(`span`,`visions-intent-meta`,e.meta));let i=n(`p`,`visions-intent-text`,e.text);return i.classList.toggle(`visions-intent-none`,!e.hasText),t.classList.toggle(`visions-intent-active`,e.active===!0),t.append(r,i),t}function z(){if(!P)return;let{intent:e,projectNamesById:t}=u();P.list.replaceChildren(...c(e,t).map(R))}function B(e){let t=n(`section`,`visions-doc`),r=n(`div`,`visions-doc-head`),i=n(`h2`,`visions-doc-name`);if(i.textContent=e.name,i.title=e.uri,r.append(i,n(`span`,`visions-doc-count`,S(e))),t.append(r),e.hand&&t.append(V(e.hand)),e.findings.length>0){let r=n(`div`,`visions-findings`);for(let t of e.findings)r.append(U(t));t.append(r)}if(e.comments.length>0){let r=n(`div`,`visions-comments`);for(let t of e.comments)r.append(H(t));t.append(r)}return t}function V(e){let t=n(`div`,`visions-hand`);return t.textContent=C(e),t}function H(e){let t=n(`div`,`visions-comment`),r=n(`div`,`visions-comment-head`);r.append(n(`span`,`visions-comment-chip`,`visions`)),r.append(n(`span`,`visions-comment-line`,f(e))),t.append(r);let i=n(`p`,`visions-comment-message`);return i.textContent=e?.message==null?``:String(e.message),t.append(i),t}function U(e){let t=n(`div`,`visions-finding`);t.append(n(`span`,`visions-finding-line`,o(e)));let r=e?.code==null?``:String(e.code);r&&t.append(n(`span`,`visions-finding-code`,r));let i=n(`span`,`visions-finding-message`);return i.textContent=e?.message==null?``:String(e.message),t.append(i),t}function W({force:e=!1}={}){if(!N||!e&&r(M))return;N.textContent=``;let{findingsByUri:t,commentsByUri:i,handsByUri:a,isEnabled:o}=u(),s=w(t,i,a);if(s.length===0){let e=n(`p`,`visions-empty`,h);if(o===!1){let t=m(`lanes-visions`,`visions-enabled`,`Enable Visions`);e.append(document.createTextNode(` `),t)}N.append(e)}else for(let e of s)N.append(B(e))}function G(){let e=n(`section`,`visions-activity`),t=n(`div`,`visions-activity-head`);t.append(n(`h2`,`visions-activity-title`,`Activity`));let r=n(`span`,`visions-activity-count`);t.append(r),e.append(t);let i=n(`div`,`visions-activity-list`);e.append(i);let a=n(`p`,`visions-activity-overflow`);return e.append(a),F={count:r,list:i,overflow:a},e}function K(e,t){let r=n(`div`,`visions-activity-row`);r.append(n(`span`,`visions-activity-source`,D(e.source))),r.append(n(`span`,`visions-activity-age`,O(e.ts,t))),r.append(n(`span`,`visions-activity-scope`,j(e)));let i=n(`span`,`visions-activity-summary`);return i.textContent=e.summary,r.append(i),r}function q({force:e=!1}={}){if(!F||!e&&r(M))return;let{count:t,list:i,overflow:a}=F,{activityEvents:o,activityOverflow:s}=u();if(t.textContent=A(o.length),i.textContent=``,o.length===0){i.append(n(`p`,`visions-empty`,te)),a.textContent=``;return}let c=Date.now();for(let e of o)i.append(K(e,c));a.textContent=k(s)}function J(){let e=n(`section`,`visions-fixes`),t=n(`div`,`visions-fixes-head`);t.append(n(`h2`,`visions-fixes-title`,`Fixes`));let r=n(`span`,`visions-fixes-count`);t.append(r),e.append(t);let i=n(`div`,`visions-fixes-list`);return e.append(i),I={count:r,list:i},e}function Y(e){let t=n(`div`,`visions-fix-row`);t.dataset.applied=e.applied?`yes`:`no`;let r=n(`span`,`visions-fix-file`);r.textContent=v(e.uri)||e.uri,r.title=e.uri,t.append(r),t.append(n(`span`,`visions-fix-line`,l(e))),t.append(n(`span`,`visions-fix-outcome`,p(e))),t.append(n(`span`,`visions-fix-code`,e.code||``));let i=n(`span`,`visions-fix-message`);return i.textContent=e.message,t.append(i),t}function X({force:e=!1}={}){if(!I||!e&&r(M))return;let{count:t,list:i}=I,{fixEntries:a}=u();if(t.textContent=ee(a.length),i.textContent=``,a.length===0)i.append(n(`p`,`visions-empty`,E));else for(let e of a)i.append(Y(e))}var Z=a(`visions-connection-status`);function Q(){u().isConnected?Z.clear():Z.show(`error`,`${e} What you see below is from before the connection dropped.`)}var re={intent:z,feed:()=>W(),fixes:()=>X(),activity:()=>q(),connection:Q};function $(){z(),W({force:!0}),X({force:!0}),q({force:!0})}function ie(e){if(M)return;let t=n(`div`,`visions-content`);t.append(Z.element,L());let i=n(`div`,`visions-feed`);t.append(i),t.append(J()),t.append(G()),e.appendChild(t),M=t,N=i,d(()=>!r(M)),s(e=>{for(let t of e)re[t]()}),Q(),$()}var ae={mount:ie,refresh:$};export{ae as view};
|
|
Binary file
|
package/dist/client/index.html
CHANGED
|
@@ -5,18 +5,24 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<meta name="color-scheme" content="dark light">
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/assets/favicon-CKygeLwW.svg">
|
|
8
|
+
<link rel="preload" href="/fonts/commit-mono-400-regular-core.woff2" as="font" type="font/woff2" crossorigin>
|
|
9
|
+
<link rel="preload" href="/fonts/commit-mono-700-regular-core.woff2" as="font" type="font/woff2" crossorigin>
|
|
8
10
|
<title>Glimmervoid</title>
|
|
9
11
|
<style>html,body{background:var(--bg,#0a0810);height:100%;color:var(--text,#c8c0e0);font-family:var(--font-mono,"CommitMono", "Cascadia Code", "Fira Code", "Consolas", "Menlo", monospace);margin:0;padding:0}.app-shell{display:none}html:not([data-layout=phone]) .app-ready .app-shell{display:contents}.loading-screen{z-index:9999;background:#0a0810;flex-direction:column;justify-content:center;align-items:center;gap:20px;transition:opacity .3s;display:flex;position:fixed;inset:0}.loading-screen.fade-out{opacity:0;pointer-events:none}.loading-title{letter-spacing:.1em;color:#e8e0ff;text-transform:uppercase;font-family:CommitMono,Cascadia Code,Fira Code,Consolas,Menlo,monospace;font-size:20px;font-weight:700}.loading-title:before{content:"▸";color:#c084fc}.loading-status{color:#8276b0;letter-spacing:.04em;font-family:CommitMono,Cascadia Code,Fira Code,Consolas,Menlo,monospace;font-size:12px}.loading-detail{color:#5e5584;text-align:center;text-wrap:balance;max-width:min(34ch,100vw - 32px);margin-top:-8px;font-family:CommitMono,Cascadia Code,Fira Code,Consolas,Menlo,monospace;font-size:12px;line-height:1.6}.loading-spinner{border:2px solid #2a2440;border-top-color:#c084fc;border-radius:50%;width:28px;height:28px;animation:.8s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.shutdown-screen:not(.active) .loading-spinner{animation:none}.shutdown-screen{z-index:9999;-webkit-backdrop-filter:blur();backdrop-filter:blur();pointer-events:none;opacity:0;background:#0a081000;flex-direction:column;justify-content:center;align-items:center;gap:20px;transition:background .4s,-webkit-backdrop-filter .4s,backdrop-filter .4s,opacity .3s;display:flex;position:fixed;inset:0}.shutdown-screen.active{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);pointer-events:auto;opacity:1;background:#0a0810eb}.shutdown-status{color:#8276b0;letter-spacing:.04em;font-family:CommitMono,Cascadia Code,Fira Code,Consolas,Menlo,monospace;font-size:12px;transition:color .3s}.shutdown-screen.done .loading-spinner{opacity:.3;border-color:#2a2440;animation:none}.shutdown-screen.done .shutdown-status{color:#4a4268}</style>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
+
<script type="module" crossorigin src="/assets/index-D6m--U7B.js"></script>
|
|
11
13
|
<link rel="modulepreload" crossorigin href="/assets/zod-BRLv4KqJ.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/dom-helpers-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
17
|
-
<link rel="
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/dom-helpers-xJduxDcc.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/control-ws-CAcwW-r9.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/poll-ago-Bc-8mMFj.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/ui-prefs-CNf6fId2.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/action-status-BwqYb9eF.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/roving-keys-core-BDobx2It.js">
|
|
20
|
+
<link rel="modulepreload" crossorigin href="/assets/modal-mWl2H7A_.js">
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/card-dom-DkZgkeG9.js">
|
|
22
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DF3BLGk9.css">
|
|
18
23
|
</head>
|
|
19
24
|
<body>
|
|
25
|
+
<a class="sr-only skip-link" href="#app-main">Skip to main content</a>
|
|
20
26
|
<div class="loading-screen" id="loading-screen">
|
|
21
27
|
<div class="loading-title">Glimmervoid</div>
|
|
22
28
|
<div class="loading-spinner"></div>
|
|
@@ -91,7 +97,7 @@
|
|
|
91
97
|
<button class="update-banner-copy telemetry-banner-dismiss" id="telemetry-banner-dismiss" type="button">Dismiss</button>
|
|
92
98
|
</div>
|
|
93
99
|
<div class="app-body" id="app-body">
|
|
94
|
-
<main class="app-main" id="app-main">
|
|
100
|
+
<main class="app-main" id="app-main" tabindex="-1">
|
|
95
101
|
<section class="sessions" id="sessions-container">
|
|
96
102
|
</section>
|
|
97
103
|
<section class="focus-view" id="view-focus" role="tabpanel" aria-labelledby="tab-focus" hidden>
|
|
Binary file
|
package/dist/server/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { a as formatNodePtyBootRefusal, t as probeNodePty } from "../chunks/node-pty-preflight-C8QIlrtU.js";
|
|
2
2
|
import { o as packageRoot } from "../chunks/runtime-paths-ghcH9CeW.js";
|
|
3
|
+
import { n as glimmervoidHomeDir } from "../chunks/config-path-core-DUWk0Lui.js";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { pathToFileURL } from "node:url";
|
|
7
|
+
import os from "node:os";
|
|
6
8
|
//#region scripts/recover-handoff.mjs
|
|
7
9
|
var PREVIOUS_DIST_BACKUP_NAME = "prev-dist";
|
|
8
10
|
var PREVIOUS_DEPENDENCIES_BACKUP_NAME = "prev-node_modules";
|
|
@@ -76,7 +78,103 @@ if (wasRunAsTheRecoveryScript()) {
|
|
|
76
78
|
process.exitCode = 0;
|
|
77
79
|
}
|
|
78
80
|
//#endregion
|
|
81
|
+
//#region server/server-log-file.ts
|
|
82
|
+
var SERVER_LOG_MAX_BYTES = 10485760;
|
|
83
|
+
var SERVER_LOG_KEPT_ROTATIONS = 4;
|
|
84
|
+
function serverLogPath() {
|
|
85
|
+
return path.join(glimmervoidHomeDir(os.homedir(), process.env), "logs", "server.log");
|
|
86
|
+
}
|
|
87
|
+
function existingByteCount(logPath) {
|
|
88
|
+
try {
|
|
89
|
+
return fs.statSync(logPath).size;
|
|
90
|
+
} catch {
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function createRotatingLogFile(logPath) {
|
|
95
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
96
|
+
let byteCount = existingByteCount(logPath);
|
|
97
|
+
let isBroken = false;
|
|
98
|
+
let chunksQueuedDuringRotation = null;
|
|
99
|
+
const chunksNotYetWritten = /* @__PURE__ */ new Set();
|
|
100
|
+
let stream = openStream();
|
|
101
|
+
function openStream() {
|
|
102
|
+
const opened = fs.createWriteStream(logPath, { flags: "a" });
|
|
103
|
+
opened.on("error", () => {
|
|
104
|
+
isBroken = true;
|
|
105
|
+
});
|
|
106
|
+
return opened;
|
|
107
|
+
}
|
|
108
|
+
async function shiftRotations() {
|
|
109
|
+
for (let generation = SERVER_LOG_KEPT_ROTATIONS; generation >= 1; generation -= 1) {
|
|
110
|
+
const olderPath = generation === 1 ? logPath : `${logPath}.${generation - 1}`;
|
|
111
|
+
await fs.promises.rename(olderPath, `${logPath}.${generation}`).catch(() => void 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function rotate() {
|
|
115
|
+
chunksQueuedDuringRotation = [];
|
|
116
|
+
const closing = stream;
|
|
117
|
+
await new Promise((resolve) => {
|
|
118
|
+
closing.end(resolve);
|
|
119
|
+
});
|
|
120
|
+
await shiftRotations();
|
|
121
|
+
stream = openStream();
|
|
122
|
+
byteCount = 0;
|
|
123
|
+
const queuedChunks = chunksQueuedDuringRotation;
|
|
124
|
+
chunksQueuedDuringRotation = null;
|
|
125
|
+
for (const chunk of queuedChunks) write(chunk);
|
|
126
|
+
}
|
|
127
|
+
function write(chunk) {
|
|
128
|
+
if (isBroken) return;
|
|
129
|
+
if (chunksQueuedDuringRotation) {
|
|
130
|
+
chunksQueuedDuringRotation.push(chunk);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const pendingWrite = { chunk };
|
|
134
|
+
chunksNotYetWritten.add(pendingWrite);
|
|
135
|
+
stream.write(chunk, () => {
|
|
136
|
+
chunksNotYetWritten.delete(pendingWrite);
|
|
137
|
+
});
|
|
138
|
+
byteCount += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.byteLength;
|
|
139
|
+
if (byteCount >= SERVER_LOG_MAX_BYTES) rotate();
|
|
140
|
+
}
|
|
141
|
+
function flushBeforeExit() {
|
|
142
|
+
if (isBroken) return;
|
|
143
|
+
const unwrittenChunks = [...[...chunksNotYetWritten].map((pendingWrite) => pendingWrite.chunk), ...chunksQueuedDuringRotation ?? []];
|
|
144
|
+
chunksNotYetWritten.clear();
|
|
145
|
+
chunksQueuedDuringRotation = [];
|
|
146
|
+
try {
|
|
147
|
+
for (const chunk of unwrittenChunks) fs.appendFileSync(logPath, chunk);
|
|
148
|
+
} catch {
|
|
149
|
+
isBroken = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
write,
|
|
154
|
+
flushBeforeExit
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function teeStream(target, logFile) {
|
|
158
|
+
const writeToTarget = target.write.bind(target);
|
|
159
|
+
target.write = ((chunk, ...rest) => {
|
|
160
|
+
logFile.write(chunk);
|
|
161
|
+
return writeToTarget(chunk, ...rest);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function teeProcessOutputToServerLog(logPath = serverLogPath()) {
|
|
165
|
+
const logFile = createRotatingLogFile(logPath);
|
|
166
|
+
teeStream(process.stdout, logFile);
|
|
167
|
+
teeStream(process.stderr, logFile);
|
|
168
|
+
process.on("uncaughtExceptionMonitor", (error) => {
|
|
169
|
+
logFile.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
|
|
170
|
+
});
|
|
171
|
+
process.on("exit", () => {
|
|
172
|
+
logFile.flushBeforeExit();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
79
176
|
//#region server/index.ts
|
|
177
|
+
teeProcessOutputToServerLog();
|
|
80
178
|
recoverHandoff(packageRoot);
|
|
81
179
|
var nodePty = await probeNodePty();
|
|
82
180
|
if (!nodePty.ok) {
|
|
@@ -87,6 +185,6 @@ if (!nodePty.ok) {
|
|
|
87
185
|
}));
|
|
88
186
|
process.exit(1);
|
|
89
187
|
}
|
|
90
|
-
await import("../chunks/main-
|
|
188
|
+
await import("../chunks/main-x9ygUnoL.js");
|
|
91
189
|
//#endregion
|
|
92
190
|
export {};
|