glimmervoid 0.46.2-next.142 → 0.46.2-next.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/bin/glimmervoid.js +9 -9
  2. package/dist/chunks/{adapters-DOoCigIs.js → adapters-CPgK2P8p.js} +2 -2
  3. package/dist/chunks/{adapters-cJnKXyy1.js → adapters-DgiNl-zf.js} +1 -1
  4. package/dist/chunks/{agent-api-cli-DiHxZG8_.js → agent-api-cli-BzXb4vri.js} +1 -1
  5. package/dist/chunks/{agent-api-cli-D1ZbnrPM.js → agent-api-cli-DFru4iHG.js} +1 -1
  6. package/dist/chunks/{agent-api-core-BawLQJDV.js → agent-api-core-CKJxZlWQ.js} +1 -1
  7. package/dist/chunks/{build-channel-C_Wck7sE.js → build-channel-CSLUgL7D.js} +17 -3
  8. package/dist/chunks/{config-DIo8Xkup.js → config-CD0H36oJ.js} +2 -1
  9. package/dist/chunks/{config-store-BIh6L8HP.js → config-store-DWt1yeB_.js} +11 -11
  10. package/dist/chunks/config-store-DZpnt33l.js +1 -0
  11. package/dist/chunks/{main-CR7hWfhj.js → main-BlPPfUFv.js} +16 -8
  12. package/dist/chunks/{node-pty-preflight-C8QIlrtU.js → node-pty-preflight-DbfWP9Rc.js} +19 -1
  13. package/dist/chunks/{pair-cli-Bxm2Hu78.js → pair-cli-D6nkYwvQ.js} +2 -2
  14. package/dist/chunks/{remote-config-C94eeqg1.js → remote-config-Cg2vcQMZ.js} +1 -1
  15. package/dist/chunks/{settings-cli-B941sHbz.js → settings-cli-D_YyLonX.js} +4 -4
  16. package/dist/chunks/{settings-readout-core-BHqZBGaI.js → settings-readout-core-ic6qSZkn.js} +1 -1
  17. package/dist/chunks/{ssh-sign-cli-EL_ZMmK7.js → ssh-sign-cli-CJmnbkMc.js} +1 -1
  18. package/dist/client/assets/{alert-sound-BBr0as6G.js → alert-sound-3XLg0nii.js} +1 -1
  19. package/dist/client/assets/alert-sound-3XLg0nii.js.br +0 -0
  20. package/dist/client/assets/{benchmark-panel-BssD3O2h.js → benchmark-panel-Cc-xCtqT.js} +1 -1
  21. package/dist/client/assets/benchmark-panel-Cc-xCtqT.js.br +0 -0
  22. package/dist/client/assets/{card-registry-DsAFY_8B.js → card-registry-DITW3gYA.js} +1 -1
  23. package/dist/client/assets/card-registry-DITW3gYA.js.br +0 -0
  24. package/dist/client/assets/{celebration-player-CiOlT5n9.js → celebration-player-C_36CmHg.js} +1 -1
  25. package/dist/client/assets/celebration-player-C_36CmHg.js.br +0 -0
  26. package/dist/client/assets/control-ws-DUGWJI0x.js +4 -0
  27. package/dist/client/assets/control-ws-DUGWJI0x.js.br +0 -0
  28. package/dist/client/assets/{dialogs-jfKnZPRt.js → dialogs-Dm0fylYo.js} +3 -3
  29. package/dist/client/assets/dialogs-Dm0fylYo.js.br +0 -0
  30. package/dist/client/assets/{doc-editor-ui-BK6THx6I.js → doc-editor-ui-Der-jLrQ.js} +1 -1
  31. package/dist/client/assets/doc-editor-ui-Der-jLrQ.js.br +0 -0
  32. package/dist/client/assets/{first-run-checklist-DjV8UyhE.js → first-run-checklist-ILiAzZQ9.js} +1 -1
  33. package/dist/client/assets/first-run-checklist-ILiAzZQ9.js.br +0 -0
  34. package/dist/client/assets/{hooks-panel-Cov_E7Nn.js → hooks-panel-BUdr2K_U.js} +1 -1
  35. package/dist/client/assets/hooks-panel-BUdr2K_U.js.br +0 -0
  36. package/dist/client/assets/{index-DkVH8Ze_.js → index-CClbz7ym.js} +5 -5
  37. package/dist/client/assets/index-CClbz7ym.js.br +0 -0
  38. package/dist/client/assets/{index-CVB9CG5c.css → index-CFgGsY9k.css} +1 -1
  39. package/dist/client/assets/index-CFgGsY9k.css.br +0 -0
  40. package/dist/client/assets/{issues-panel-C4xIYyg8.js → issues-panel-BpsqfwHt.js} +1 -1
  41. package/dist/client/assets/issues-panel-BpsqfwHt.js.br +0 -0
  42. package/dist/client/assets/{nyan-cat-SuwqMGt7.js → nyan-cat-D-vTXf4d.js} +1 -1
  43. package/dist/client/assets/nyan-cat-D-vTXf4d.js.br +0 -0
  44. package/dist/client/assets/{phone-shell-LNpqjgav.js → phone-shell-DGkkSFVi.js} +1 -1
  45. package/dist/client/assets/phone-shell-DGkkSFVi.js.br +0 -0
  46. package/dist/client/assets/{plan-face-CVgq55fc.js → plan-face-ohmry9nO.js} +1 -1
  47. package/dist/client/assets/plan-face-ohmry9nO.js.br +0 -0
  48. package/dist/client/assets/{plan-render-CzDoSIwQ.js → plan-render-BK51mWj1.js} +1 -1
  49. package/dist/client/assets/plan-render-BK51mWj1.js.br +0 -0
  50. package/dist/client/assets/{pr-scope-tabs-BWoPol5P.js → pr-scope-tabs-Dz_UJbqT.js} +1 -1
  51. package/dist/client/assets/pr-scope-tabs-Dz_UJbqT.js.br +0 -0
  52. package/dist/client/assets/{radar-panel-Cz4wr8sW.js → radar-panel-COlCPH1w.js} +1 -1
  53. package/dist/client/assets/radar-panel-COlCPH1w.js.br +0 -0
  54. package/dist/client/assets/{repo-roots-adder-CAMr-ApU.js → repo-roots-adder-B4qgw7oP.js} +1 -1
  55. package/dist/client/assets/repo-roots-adder-B4qgw7oP.js.br +0 -0
  56. package/dist/client/assets/{resume-dialog-LCZU0g7P.js → resume-dialog-BekqhS74.js} +1 -1
  57. package/dist/client/assets/resume-dialog-BekqhS74.js.br +0 -0
  58. package/dist/client/assets/{review-queue-panel-Ccex9SGG.js → review-queue-panel-BeQ17ElV.js} +1 -1
  59. package/dist/client/assets/review-queue-panel-BeQ17ElV.js.br +0 -0
  60. package/dist/client/assets/sandboxed-frame-C5WnwN5w.js +1 -0
  61. package/dist/client/assets/{session-tick-XGyxrRw7.js → session-tick-D8pYTYt7.js} +1 -1
  62. package/dist/client/assets/session-tick-D8pYTYt7.js.br +0 -0
  63. package/dist/client/assets/{settings-panel-BYyO60k-.js → settings-panel-C3zGH7v1.js} +2 -2
  64. package/dist/client/assets/settings-panel-C3zGH7v1.js.br +0 -0
  65. package/dist/client/assets/shown-lightbox-BcxqmKL0.js +1 -0
  66. package/dist/client/assets/shown-lightbox-BcxqmKL0.js.br +0 -0
  67. package/dist/client/assets/{trace-panel-Bw6juc09.js → trace-panel-JuB7yi0z.js} +1 -1
  68. package/dist/client/assets/trace-panel-JuB7yi0z.js.br +0 -0
  69. package/dist/client/assets/{updates-view-core-B_e7uWeW.js → updates-view-core-BYoMfzXj.js} +1 -1
  70. package/dist/client/assets/updates-view-core-BYoMfzXj.js.br +0 -0
  71. package/dist/client/assets/{usage-panel-DgfcEHUt.js → usage-panel-DuVi7PQ0.js} +1 -1
  72. package/dist/client/assets/usage-panel-DuVi7PQ0.js.br +0 -0
  73. package/dist/client/assets/{visions-panel-BuuuaLjv.js → visions-panel-DtkT-pV4.js} +1 -1
  74. package/dist/client/assets/visions-panel-DtkT-pV4.js.br +0 -0
  75. package/dist/client/index.html +6 -6
  76. package/dist/client/index.html.br +0 -0
  77. package/dist/server/index.js +2 -2
  78. package/package.json +1 -1
  79. package/dist/chunks/config-store-7CJnu01H.js +0 -1
  80. package/dist/client/assets/alert-sound-BBr0as6G.js.br +0 -0
  81. package/dist/client/assets/benchmark-panel-BssD3O2h.js.br +0 -0
  82. package/dist/client/assets/card-registry-DsAFY_8B.js.br +0 -0
  83. package/dist/client/assets/celebration-player-CiOlT5n9.js.br +0 -0
  84. package/dist/client/assets/control-ws-D_jLoMnn.js +0 -4
  85. package/dist/client/assets/control-ws-D_jLoMnn.js.br +0 -0
  86. package/dist/client/assets/dialogs-jfKnZPRt.js.br +0 -0
  87. package/dist/client/assets/doc-editor-ui-BK6THx6I.js.br +0 -0
  88. package/dist/client/assets/first-run-checklist-DjV8UyhE.js.br +0 -0
  89. package/dist/client/assets/hooks-panel-Cov_E7Nn.js.br +0 -0
  90. package/dist/client/assets/index-CVB9CG5c.css.br +0 -0
  91. package/dist/client/assets/index-DkVH8Ze_.js.br +0 -0
  92. package/dist/client/assets/issues-panel-C4xIYyg8.js.br +0 -0
  93. package/dist/client/assets/nyan-cat-SuwqMGt7.js.br +0 -0
  94. package/dist/client/assets/phone-shell-LNpqjgav.js.br +0 -0
  95. package/dist/client/assets/plan-face-CVgq55fc.js.br +0 -0
  96. package/dist/client/assets/plan-render-CzDoSIwQ.js.br +0 -0
  97. package/dist/client/assets/pr-scope-tabs-BWoPol5P.js.br +0 -0
  98. package/dist/client/assets/radar-panel-Cz4wr8sW.js.br +0 -0
  99. package/dist/client/assets/repo-roots-adder-CAMr-ApU.js.br +0 -0
  100. package/dist/client/assets/resume-dialog-LCZU0g7P.js.br +0 -0
  101. package/dist/client/assets/review-queue-panel-Ccex9SGG.js.br +0 -0
  102. package/dist/client/assets/session-tick-XGyxrRw7.js.br +0 -0
  103. package/dist/client/assets/settings-panel-BYyO60k-.js.br +0 -0
  104. package/dist/client/assets/shown-lightbox-BJoXhjCC.js +0 -1
  105. package/dist/client/assets/shown-lightbox-BJoXhjCC.js.br +0 -0
  106. package/dist/client/assets/trace-panel-Bw6juc09.js.br +0 -0
  107. package/dist/client/assets/updates-view-core-B_e7uWeW.js.br +0 -0
  108. package/dist/client/assets/usage-panel-DgfcEHUt.js.br +0 -0
  109. package/dist/client/assets/visions-panel-BuuuaLjv.js.br +0 -0
@@ -1,4 +1,4 @@
1
- import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-B_e7uWeW.js";import{h as o,m as s,o as c}from"./dom-helpers-C7P3_59O.js";import{d as l}from"./control-ws-D_jLoMnn.js";import{n as u,r as d,t as f}from"./modal-Bh-cVr-I.js";import{n as p}from"./session-tick-XGyxrRw7.js";import{Cn as m,Fr as h,Ir as g,Rr as _,_r as v,cr as y,ei as b,gr as x,m as S,ni as C,ti as w}from"./index-DkVH8Ze_.js";import{d as T,l as E,t as D,u as ee}from"./repo-roots-adder-CAMr-ApU.js";var te=`<h2 class="dialog-title" id="add-session-title">Add Session</h2>
1
+ import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-BYoMfzXj.js";import{h as o,m as s,o as c}from"./dom-helpers-C7P3_59O.js";import{d as l}from"./control-ws-DUGWJI0x.js";import{n as u,r as d,t as f}from"./modal-Bh-cVr-I.js";import{n as p}from"./session-tick-D8pYTYt7.js";import{Cn as m,Fr as h,Ir as g,Rr as _,_r as v,cr as y,ei as b,gr as x,m as S,ni as C,ti as w}from"./index-CClbz7ym.js";import{d as T,l as E,t as D,u as ee}from"./repo-roots-adder-B4qgw7oP.js";import{t as O}from"./sandboxed-frame-C5WnwN5w.js";var te=`<h2 class="dialog-title" id="add-session-title">Add Session</h2>
2
2
  <fieldset class="dialog-mode-controls" aria-label="Session kind">
3
3
  <button type="button" class="dialog-mode-button" id="add-session-single-mode" aria-pressed="true">Single repo</button>
4
4
  <button type="button" class="dialog-mode-button" id="add-session-workspace-mode" aria-pressed="false">Workspace</button>
@@ -63,7 +63,7 @@ import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-B_e7
63
63
  <button type="button" class="btn-dialog btn-dialog-cancel" id="add-session-cancel">Cancel</button>
64
64
  <button type="button" class="btn-dialog btn-dialog-confirm" id="add-session-confirm">Add</button>
65
65
  </div>
66
- `,O=`<h2 class="dialog-title" id="agent-connect-title">Connect</h2>
66
+ `,k=`<h2 class="dialog-title" id="agent-connect-title">Connect</h2>
67
67
  <p class="dialog-hint" id="agent-connect-intro"></p>
68
68
  <p class="dialog-label" id="agent-connect-state" role="status"></p>
69
69
  <div class="dialog-label" id="agent-connect-steps" hidden>
@@ -81,4 +81,4 @@ import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-B_e7
81
81
  <button type="button" class="btn-dialog btn-dialog-confirm" id="agent-connect-submit" hidden>Submit code</button>
82
82
  <button type="button" class="btn-dialog btn-dialog-confirm" id="agent-connect-start">Start sign-in</button>
83
83
  </div>
84
- `;function k(e,{value:t,disabled:n=!1,selected:r=!1}={}){let i=c(`option`,null,e);return t!=null&&(i.value=t),n&&(i.disabled=!0),r&&(i.selected=!0),i}function ne(e){return typeof e!=`object`||!e?!1:`saneYoloAvailable`in e&&e.saneYoloAvailable===!0}function re(e){if(typeof e!=`object`||!e||!(`coderEnvironments`in e))return[];let t=r.safeParse(e.coderEnvironments);return t.success&&t.data?t.data:[]}function ie(e){let t=Object.entries(e.parameters).map(([e,t])=>`${e}=${t}`).join(`, `);return[`Template ${e.template}.`,t?`Parameters: ${t}.`:``,e.hourlyCostUsd===null?``:`Costs $${e.hourlyCostUsd.toFixed(2)} an hour.`,`Stops after ${e.idleStopMinutes} idle minutes.`].filter(Boolean).join(` `)}var A=Object.freeze({"claude-code":`Claude Code`,codex:`Codex`});function ae(e){let t=i.safeParse(e);return t.success?t.data:null}function j(e,t){let n=A[t];return e?e.state===`signed-in`&&e.source===`host`?`${n} uses the login already on this machine.`:e.state===`signed-in`?`${n} uses the login Glimmervoid connected.`:e.state===`connecting`?e.reason??`${n} sign-in is waiting for you.`:e.state===`failed`?e.reason??`${n} sign-in failed.`:`${n} has no login on this machine, so remote ${n} sessions cannot sign in.`:`Checking whether ${n} is signed in.`}function M(){l(`get-agent-logins`,{},{timeoutMs:h}).then(e=>{e.type===`agent-logins`&&w(e.logins)}).catch(()=>{})}function oe(e){let t=A[e],{dialog:n,close:r}=d();n.innerHTML=O,f(n,`agent-connect-title`),s(n,`#agent-connect-title`).textContent=`Connect ${t}`,s(n,`#agent-connect-intro`).textContent=`Glimmervoid signs ${t} in for its own remote sessions and keeps that login in its own folder, apart from any login you already have on this machine. The sign-in runs here and is never recorded.`;let i=s(n,`#agent-connect-state`),a=s(n,`#agent-connect-steps`),c=o(n,`#agent-connect-link`,`a`),u=s(n,`#agent-connect-code-row`),p=s(n,`#agent-connect-code`),m=s(n,`#agent-connect-paste-label`),g=o(n,`#agent-connect-paste`,`input`),v=s(n,`#agent-connect-error`),y=o(n,`#agent-connect-close`,`button`),x=o(n,`#agent-connect-stop`,`button`),S=o(n,`#agent-connect-submit`,`button`),T=o(n,`#agent-connect-start`,`button`);function E(){if(!n.isConnected){ee();return}let t=b(e),r=t?.state===`connecting`;i.textContent=j(t,e),T.hidden=r,x.hidden=!r;let o=r?t.verificationUrl:null;a.hidden=o===null,c.href=o??``,c.textContent=o??``,u.hidden=!t?.userCode,p.textContent=t?.userCode??``;let s=r&&t.needsPastedCode;m.hidden=!s,S.hidden=!s}async function D(t,n,r){r.disabled=!0,v.textContent=``;try{let r=await l(t,{agent:e,...n},{timeoutMs:h});if(r.type!==`agent-logins`)return;w(r.logins),r.error&&(v.textContent=r.error)}catch(e){v.textContent=`The server did not answer (${_(e,h)}).`}finally{r.disabled=!1}}T.addEventListener(`click`,()=>{D(`agent-connect`,{action:`start`},T)}),x.addEventListener(`click`,()=>{D(`agent-connect`,{action:`cancel`},x)}),S.addEventListener(`click`,()=>{let e=g.value;g.value=``,D(`agent-connect-code`,{code:e},S)}),g.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.preventDefault(),S.click())}),y.addEventListener(`click`,r);let ee=C(E);E(),M()}function se(){let{dialog:e,close:t,actions:n,btnCancel:r}=u({title:`Set up a remote host`}),a=c(`p`,`dialog-hint`,`The setup session runs outside the guardrails so it can use your ssh keys. It runs commands on the remote host over ssh and asks before each one. Glimmervoid deletes its working folder when the session ends.`),o=c(`p`,`dialog-label`,`Agent`),s=c(`div`,`hooks-type-row`);s.setAttribute(`role`,`radiogroup`);let d=g(),f=c(`button`,`btn-dialog btn-dialog-confirm`,`Start setup`);f.type=`button`,r.type=`button`,r.addEventListener(`click`,t),n.append(f),e.append(a,o,s,d.element,n);let p=null,m=!1;function v(){if(!e.isConnected){y();return}let t=i.options.filter(e=>b(e)?.state===`signed-in`);(p===null||!t.includes(p))&&(p=t[0]??null),s.replaceChildren(...t.map(e=>{let t=c(`label`,`settings-view-toggle hooks-choice`),n=c(`input`,`settings-view-checkbox`);return n.type=`radio`,n.name=`remote-setup-agent`,n.checked=e===p,n.addEventListener(`change`,()=>{p=e}),t.append(n,c(`span`,null,A[e])),t})),t.length===0&&s.append(c(`span`,``,`Sign in to Claude Code or Codex on this machine first.`)),f.disabled=m||p===null}f.addEventListener(`click`,async()=>{if(p!==null){m=!0,f.disabled=!0,d.show(`busy`,`Starting the setup session.`);try{let e=await l(`start-remote-setup`,{agent:p},{timeoutMs:h});if(e.type===`start-remote-setup-result`&&e.ok){t();return}d.show(`error`,e.type===`start-remote-setup-result`&&e.error?e.error:`The setup session did not start.`)}catch(e){d.show(`error`,`The server did not answer (${_(e,h)}).`)}finally{m=!1,v()}}});let y=C(v);v(),M()}function ce(){let{dialog:e,close:t}=d();e.innerHTML=te,f(e,`add-session-title`);let n=o(e,`#add-session-picker`,`select`),r=s(e,`#add-session-picker-label`),i=s(e,`#add-session-workspace-list`),a=o(e,`#add-session-single-mode`,`button`),u=o(e,`#add-session-workspace-mode`,`button`),p=s(e,`#add-session-agent-label`),S=o(e,`#add-session-agent`,`select`),w=s(e,`#add-session-environment-label`),O=o(e,`#add-session-environment`,`select`),A=s(e,`#add-session-environment-hint`),se=s(e,`#add-session-agent-login`),ce=s(e,`#add-session-agent-login-text`),le=o(e,`#add-session-agent-connect`,`button`),N=s(e,`#add-session-repo-roots`),ue=s(e,`#add-session-repo-roots-title`),P=o(e,`#add-session-advanced-toggle`,`button`),F=s(e,`#add-session-advanced`),I=o(e,`#add-session-name`,`input`),L=o(e,`#add-session-path`,`input`),de=s(e,`#add-session-path-label`),R=o(e,`#add-session-skip-perms`,`input`),z=o(e,`#add-session-unguarded`,`input`),fe=o(e,`#add-session-sane-yolo-help`,`a`),pe=s(e,`#add-session-sane-yolo-unavailable`),me=o(e,`#add-session-safety-toggle`,`button`),he=s(e,`#add-session-safety`),ge=s(e,`#add-session-safety-status`),B=s(e,`#add-session-error`),_e=o(e,`#add-session-cancel`,`button`),V=o(e,`#add-session-confirm`,`button`),H=!1,ve=[],U=null;function W(e){H=e,a.setAttribute(`aria-pressed`,String(!e)),u.setAttribute(`aria-pressed`,String(e)),r.hidden=e,i.hidden=!e,P.hidden=e,P.setAttribute(`aria-expanded`,String(e)),F.hidden=!e,de.hidden=e,e&&requestAnimationFrame(()=>I.focus())}a.addEventListener(`click`,()=>W(!1)),u.addEventListener(`click`,()=>W(!0)),P.setAttribute(`aria-expanded`,`false`),P.addEventListener(`click`,()=>{let e=F.hidden;F.hidden=!e,P.setAttribute(`aria-expanded`,String(e)),e&&requestAnimationFrame(()=>I.focus())}),fe.addEventListener(`click`,()=>t()),me.addEventListener(`click`,()=>{let e=he.hidden;he.hidden=!e,me.setAttribute(`aria-expanded`,String(e))}),z.addEventListener(`change`,()=>{ge.textContent=z.checked?`guardrails off`:`guardrails on`});let ye=D({onAdded:q});N.append(ye.element);let G=g(`dialog-hint`),K=c(`button`,`btn-dialog btn-dialog-cancel`,`Scan again`);K.type=`button`,K.hidden=!0,K.addEventListener(`click`,()=>{q()});let be=c(`div`,`flex items-center gap-2`);be.append(G.element,K),N.before(be);function xe(e){n.textContent=``,n.appendChild(k(`Scan failed`,{disabled:!0,selected:!0})),i.textContent=``,G.show(`error`,`The project scan failed: ${e}`),K.hidden=!1,K.disabled=!1}function Se(e){let t=e.type===`repo-roots-scanned`;ue.textContent=t&&e.directories.length>0?`No projects in your repository roots yet`:`No repository roots yet`,ye.setSuggestions(t?e.suggestions??[]:[]),N.hidden=!1}function q(){return K.disabled=!0,G.show(`busy`,`Scanning your repository roots`),l(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:h}).then(e=>{if(e.type===`repo-roots-scanned`&&e.error){xe(e.error);return}G.clear(),K.hidden=!0,n.textContent=``,i.textContent=``,N.hidden=!0,n.appendChild(k(`-- Select a project --`,{value:``,disabled:!0,selected:!0}));let t=!1,r=e.type===`repo-roots-scanned`?e.directories:[];for(let e of r){if(e.projects.length===0)continue;let r=c(`optgroup`);r.label=e.root;for(let n of e.projects){let e=x(n.name),a=e>0?`${n.name} (${e} open)`:n.name;r.appendChild(k(a,{value:JSON.stringify({name:n.name,path:n.path})})),i.appendChild(m(n.name,n.path)),t=!0}n.appendChild(r)}t||(n.textContent=``,n.appendChild(k(`No projects yet`,{disabled:!0,selected:!0})),i.textContent=`No projects yet.`,Se(e))}).catch(e=>{xe(_(e,h))})}q(),n.addEventListener(`change`,()=>{try{let e=JSON.parse(n.value);I.value=v(e.name),L.value=e.path}catch{}});let J=E,Y=!1;function X(e){let t=c(`p`,`dialog-hint dialog-hint-warning`,e);return t.setAttribute(`role`,`status`),B.before(t),t}function Ce(e){Y=!0,V.disabled=!0,X(e).id=`add-session-agent-guidance`}l(`list-agents`,{},{timeoutMs:h}).then(e=>{let t=ee(e);t.canSpawn||Ce(t.guidance);let n=T(e.type===`agents-listed`?e.agents:[]);if(J=n.selectedId,n.show){S.textContent=``;for(let e of n.options)S.appendChild(k(e.label,{value:e.id,selected:e.id===n.selectedId}));p.hidden=!1}}).catch(e=>{X(`Could not load the agent list (${_(e,h)}), so the session uses the default agent.`)}),S.addEventListener(`change`,()=>{J=S.value,Z()});function Z(){if(!e.isConnected){we();return}let t=ae(J),n=t?b(t):null;se.hidden=U===null||t===null||n===null||n.state===`signed-in`,ce.textContent=t?j(n,t):``}le.addEventListener(`click`,()=>{let e=ae(J);e&&oe(e)});let we=C(Z);M();let Te=!1,Ee=!1;R.addEventListener(`change`,()=>{Te=!0});function Q(){let e=Ee&&U===null;pe.hidden=e,!Te&&(R.checked=e)}l(`get-settings`,{},{timeoutMs:h}).then(e=>{e.type===`settings-error`?(X(`Could not load your settings (${e.message}). Check Sane YOLO mode yourself.`),Q()):(De(re(e.settings)),Ee=ne(e.settings),Q())}).catch(e=>{X(`Could not load your settings (${_(e,h)}). Check Sane YOLO mode yourself.`),Q()});function De(e){if(e.length!==0){ve=e,O.textContent=``,O.appendChild(k(`Local`,{value:``,selected:!0}));for(let t of e)O.appendChild(k(t.name,{value:t.name}));w.hidden=!1}}O.addEventListener(`change`,()=>{U=ve.find(e=>e.name===O.value)??null,u.hidden=U!==null,A.hidden=U===null,A.textContent=U?ie(U):``,Z(),Q(),U!==null&&H&&W(!1)}),I.addEventListener(`input`,()=>{n.selectedIndex=0}),L.addEventListener(`input`,()=>{n.selectedIndex=0});function $(){if(Y)return;let e=I.value.trim(),t=L.value.trim();if(H){let t=[...i.querySelectorAll(`input:checked`)].map(e=>e.value);if(!e||t.length<2){B.textContent=`Enter a name and select at least two repositories.`;return}let n={name:v(e),path:t[0],repos:t,dangerouslySkipPermissions:R.checked,saneYolo:R.checked,unguarded:z.checked};J&&J!==`claude-code`&&(n.agent=J),Oe(n);return}if(!e||!t){B.textContent=`Both fields are required. Select a project or use Advanced options.`;return}let n={name:v(e),path:t,dangerouslySkipPermissions:R.checked,saneYolo:R.checked,unguarded:z.checked};J&&J!==`claude-code`&&(n.agent=J),U&&(n.environment=U.name),Oe(n)}function Oe(e){V.disabled=!0,B.textContent=``,l(`add-session`,e,{timeoutMs:h}).then(e=>{e.type===`add-session-result`&&e.ok?t():B.textContent=y(e)}).catch(e=>{B.textContent=`The session was not added: ${_(e,h)}`}).finally(()=>{V.disabled=Y})}_e.addEventListener(`click`,t),V.addEventListener(`click`,$),I.addEventListener(`keydown`,e=>{e.key===`Enter`&&(H&&$(),H||L.focus())}),L.addEventListener(`keydown`,e=>{e.key===`Enter`&&$()}),requestAnimationFrame(()=>n.focus())}function le({issueId:e,issueTitle:t,format:n,content:r,message:i,error:a}){let{dialog:o,close:s,actions:l,btnCancel:d}=u({title:`Investigation report`,dialogClass:`dialog dialog-report`,cancelLabel:`Close`}),f=c(`div`,`dialog-report-meta`,t||e||``),p=null;if(n===`html`&&!a&&!i){let e=c(`iframe`,`dialog-report-frame`);e.setAttribute(`sandbox`,``),e.srcdoc=r||``,p=e}p||=c(`pre`,a?`dialog-report-body dialog-report-error`:`dialog-report-body`,a||i||r||``),o.append(f,p,l),d.addEventListener(`click`,s),requestAnimationFrame(()=>d.focus())}function N({issueTitle:r,projectLabel:i,onOpenReport:o}){let{dialog:s,close:l,actions:d,btnCancel:f}=u({title:`Investigation`,dialogClass:`dialog dialog-report`,cancelLabel:`Close`}),m=c(`div`,`dialog-report-meta`,i?`${i}: ${r}`:r),h=c(`p`,`dialog-trail-status`),g=c(`p`,`dialog-trail-summary`),_=c(`ol`,`dialog-trail-steps`),v=c(`p`,`dialog-trail-empty`,`No tool calls yet; the session is reading the issue.`),y=c(`button`,`btn-dialog btn-dialog-cancel`,`Open report`);y.type=`button`,y.hidden=!0,y.addEventListener(`click`,()=>{l(),o()}),d.prepend(y),s.append(m,h,g,_,v,d),f.addEventListener(`click`,l),requestAnimationFrame(()=>f.focus());let b=null,x=``;function C(n){let r=_.scrollHeight-_.scrollTop-_.clientHeight<24,i=t(n);if(x!==i){_.textContent=``;for(let t of e(n.steps)){let e=c(`li`,`dialog-trail-step dialog-trail-${t.kind}`),r=t.kind===`note`?t.text:`${t.stepCount} ${t.stepCount===1?`step`:`steps`}`;e.append(c(`span`,`dialog-trail-at`,a(n.startedAt,t.at)),c(`span`,`dialog-trail-detail`,r)),_.append(e)}x=i}v.hidden=n.steps.length>0||!n.inFlight,_.hidden=n.steps.length===0,r&&(_.scrollTop=_.scrollHeight)}function w(e){h.textContent=n(e,S(e.startedAt))}function T(){b&&(w(b),h.dataset.tone=b.inFlight?`live`:`done`,g.textContent=b.summaryLine,g.hidden=!b.summaryLine,y.hidden=b.inFlight||!b.verdict,C(b))}let E=p(()=>{s.isConnected?b?.inFlight&&w(b):E()});return{update(e){b=e,T()},isOpen:()=>s.isConnected,close:()=>{E(),l()}}}export{b as agentLoginOf,j as agentLoginSummary,ce as createAddSessionDialog,N as createInvestigationDialog,le as createRadarReportDialog,C as onAgentLoginsChanged,oe as openAgentConnectDialog,se as openRemoteSetupDialog};
84
+ `;function A(e,{value:t,disabled:n=!1,selected:r=!1}={}){let i=c(`option`,null,e);return t!=null&&(i.value=t),n&&(i.disabled=!0),r&&(i.selected=!0),i}function ne(e){return typeof e!=`object`||!e?!1:`saneYoloAvailable`in e&&e.saneYoloAvailable===!0}function re(e){if(typeof e!=`object`||!e||!(`coderEnvironments`in e))return[];let t=r.safeParse(e.coderEnvironments);return t.success&&t.data?t.data:[]}function ie(e){let t=Object.entries(e.parameters).map(([e,t])=>`${e}=${t}`).join(`, `);return[`Template ${e.template}.`,t?`Parameters: ${t}.`:``,e.hourlyCostUsd===null?``:`Costs $${e.hourlyCostUsd.toFixed(2)} an hour.`,`Stops after ${e.idleStopMinutes} idle minutes.`].filter(Boolean).join(` `)}var j=Object.freeze({"claude-code":`Claude Code`,codex:`Codex`});function ae(e){let t=i.safeParse(e);return t.success?t.data:null}function M(e,t){let n=j[t];return e?e.state===`signed-in`&&e.source===`host`?`${n} uses the login already on this machine.`:e.state===`signed-in`?`${n} uses the login Glimmervoid connected.`:e.state===`connecting`?e.reason??`${n} sign-in is waiting for you.`:e.state===`failed`?e.reason??`${n} sign-in failed.`:`${n} has no login on this machine, so remote ${n} sessions cannot sign in.`:`Checking whether ${n} is signed in.`}function N(){l(`get-agent-logins`,{},{timeoutMs:h}).then(e=>{e.type===`agent-logins`&&w(e.logins)}).catch(()=>{})}function oe(e){let t=j[e],{dialog:n,close:r}=d();n.innerHTML=k,f(n,`agent-connect-title`),s(n,`#agent-connect-title`).textContent=`Connect ${t}`,s(n,`#agent-connect-intro`).textContent=`Glimmervoid signs ${t} in for its own remote sessions and keeps that login in its own folder, apart from any login you already have on this machine. The sign-in runs here and is never recorded.`;let i=s(n,`#agent-connect-state`),a=s(n,`#agent-connect-steps`),c=o(n,`#agent-connect-link`,`a`),u=s(n,`#agent-connect-code-row`),p=s(n,`#agent-connect-code`),m=s(n,`#agent-connect-paste-label`),g=o(n,`#agent-connect-paste`,`input`),v=s(n,`#agent-connect-error`),y=o(n,`#agent-connect-close`,`button`),x=o(n,`#agent-connect-stop`,`button`),S=o(n,`#agent-connect-submit`,`button`),T=o(n,`#agent-connect-start`,`button`);function E(){if(!n.isConnected){ee();return}let t=b(e),r=t?.state===`connecting`;i.textContent=M(t,e),T.hidden=r,x.hidden=!r;let o=r?t.verificationUrl:null;a.hidden=o===null,c.href=o??``,c.textContent=o??``,u.hidden=!t?.userCode,p.textContent=t?.userCode??``;let s=r&&t.needsPastedCode;m.hidden=!s,S.hidden=!s}async function D(t,n,r){r.disabled=!0,v.textContent=``;try{let r=await l(t,{agent:e,...n},{timeoutMs:h});if(r.type!==`agent-logins`)return;w(r.logins),r.error&&(v.textContent=r.error)}catch(e){v.textContent=`The server did not answer (${_(e,h)}).`}finally{r.disabled=!1}}T.addEventListener(`click`,()=>{D(`agent-connect`,{action:`start`},T)}),x.addEventListener(`click`,()=>{D(`agent-connect`,{action:`cancel`},x)}),S.addEventListener(`click`,()=>{let e=g.value;g.value=``,D(`agent-connect-code`,{code:e},S)}),g.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.preventDefault(),S.click())}),y.addEventListener(`click`,r);let ee=C(E);E(),N()}function se(){let{dialog:e,close:t,actions:n,btnCancel:r}=u({title:`Set up a remote host`}),a=c(`p`,`dialog-hint`,`The setup session runs outside the guardrails so it can use your ssh keys. It runs commands on the remote host over ssh and asks before each one. Glimmervoid deletes its working folder when the session ends.`),o=c(`p`,`dialog-label`,`Agent`),s=c(`div`,`hooks-type-row`);s.setAttribute(`role`,`radiogroup`);let d=g(),f=c(`button`,`btn-dialog btn-dialog-confirm`,`Start setup`);f.type=`button`,r.type=`button`,r.addEventListener(`click`,t),n.append(f),e.append(a,o,s,d.element,n);let p=null,m=!1;function v(){if(!e.isConnected){y();return}let t=i.options.filter(e=>b(e)?.state===`signed-in`);(p===null||!t.includes(p))&&(p=t[0]??null),s.replaceChildren(...t.map(e=>{let t=c(`label`,`settings-view-toggle hooks-choice`),n=c(`input`,`settings-view-checkbox`);return n.type=`radio`,n.name=`remote-setup-agent`,n.checked=e===p,n.addEventListener(`change`,()=>{p=e}),t.append(n,c(`span`,null,j[e])),t})),t.length===0&&s.append(c(`span`,``,`Sign in to Claude Code or Codex on this machine first.`)),f.disabled=m||p===null}f.addEventListener(`click`,async()=>{if(p!==null){m=!0,f.disabled=!0,d.show(`busy`,`Starting the setup session.`);try{let e=await l(`start-remote-setup`,{agent:p},{timeoutMs:h});if(e.type===`start-remote-setup-result`&&e.ok){t();return}d.show(`error`,e.type===`start-remote-setup-result`&&e.error?e.error:`The setup session did not start.`)}catch(e){d.show(`error`,`The server did not answer (${_(e,h)}).`)}finally{m=!1,v()}}});let y=C(v);v(),N()}function ce(){let{dialog:e,close:t}=d();e.innerHTML=te,f(e,`add-session-title`);let n=o(e,`#add-session-picker`,`select`),r=s(e,`#add-session-picker-label`),i=s(e,`#add-session-workspace-list`),a=o(e,`#add-session-single-mode`,`button`),u=o(e,`#add-session-workspace-mode`,`button`),p=s(e,`#add-session-agent-label`),S=o(e,`#add-session-agent`,`select`),w=s(e,`#add-session-environment-label`),O=o(e,`#add-session-environment`,`select`),k=s(e,`#add-session-environment-hint`),j=s(e,`#add-session-agent-login`),se=s(e,`#add-session-agent-login-text`),ce=o(e,`#add-session-agent-connect`,`button`),P=s(e,`#add-session-repo-roots`),le=s(e,`#add-session-repo-roots-title`),F=o(e,`#add-session-advanced-toggle`,`button`),I=s(e,`#add-session-advanced`),L=o(e,`#add-session-name`,`input`),R=o(e,`#add-session-path`,`input`),ue=s(e,`#add-session-path-label`),z=o(e,`#add-session-skip-perms`,`input`),B=o(e,`#add-session-unguarded`,`input`),de=o(e,`#add-session-sane-yolo-help`,`a`),fe=s(e,`#add-session-sane-yolo-unavailable`),pe=o(e,`#add-session-safety-toggle`,`button`),me=s(e,`#add-session-safety`),he=s(e,`#add-session-safety-status`),V=s(e,`#add-session-error`),ge=o(e,`#add-session-cancel`,`button`),H=o(e,`#add-session-confirm`,`button`),U=!1,_e=[],W=null;function G(e){U=e,a.setAttribute(`aria-pressed`,String(!e)),u.setAttribute(`aria-pressed`,String(e)),r.hidden=e,i.hidden=!e,F.hidden=e,F.setAttribute(`aria-expanded`,String(e)),I.hidden=!e,ue.hidden=e,e&&requestAnimationFrame(()=>L.focus())}a.addEventListener(`click`,()=>G(!1)),u.addEventListener(`click`,()=>G(!0)),F.setAttribute(`aria-expanded`,`false`),F.addEventListener(`click`,()=>{let e=I.hidden;I.hidden=!e,F.setAttribute(`aria-expanded`,String(e)),e&&requestAnimationFrame(()=>L.focus())}),de.addEventListener(`click`,()=>t()),pe.addEventListener(`click`,()=>{let e=me.hidden;me.hidden=!e,pe.setAttribute(`aria-expanded`,String(e))}),B.addEventListener(`change`,()=>{he.textContent=B.checked?`guardrails off`:`guardrails on`});let ve=D({onAdded:J});P.append(ve.element);let K=g(`dialog-hint`),q=c(`button`,`btn-dialog btn-dialog-cancel`,`Scan again`);q.type=`button`,q.hidden=!0,q.addEventListener(`click`,()=>{J()});let ye=c(`div`,`flex items-center gap-2`);ye.append(K.element,q),P.before(ye);function be(e){n.textContent=``,n.appendChild(A(`Scan failed`,{disabled:!0,selected:!0})),i.textContent=``,K.show(`error`,`The project scan failed: ${e}`),q.hidden=!1,q.disabled=!1}function xe(e){let t=e.type===`repo-roots-scanned`;le.textContent=t&&e.directories.length>0?`No projects in your repository roots yet`:`No repository roots yet`,ve.setSuggestions(t?e.suggestions??[]:[]),P.hidden=!1}function J(){return q.disabled=!0,K.show(`busy`,`Scanning your repository roots`),l(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:h}).then(e=>{if(e.type===`repo-roots-scanned`&&e.error){be(e.error);return}K.clear(),q.hidden=!0,n.textContent=``,i.textContent=``,P.hidden=!0,n.appendChild(A(`-- Select a project --`,{value:``,disabled:!0,selected:!0}));let t=!1,r=e.type===`repo-roots-scanned`?e.directories:[];for(let e of r){if(e.projects.length===0)continue;let r=c(`optgroup`);r.label=e.root;for(let n of e.projects){let e=x(n.name),a=e>0?`${n.name} (${e} open)`:n.name;r.appendChild(A(a,{value:JSON.stringify({name:n.name,path:n.path})})),i.appendChild(m(n.name,n.path)),t=!0}n.appendChild(r)}t||(n.textContent=``,n.appendChild(A(`No projects yet`,{disabled:!0,selected:!0})),i.textContent=`No projects yet.`,xe(e))}).catch(e=>{be(_(e,h))})}J(),n.addEventListener(`change`,()=>{try{let e=JSON.parse(n.value);L.value=v(e.name),R.value=e.path}catch{}});let Y=E,X=!1;function Z(e){let t=c(`p`,`dialog-hint dialog-hint-warning`,e);return t.setAttribute(`role`,`status`),V.before(t),t}function Se(e){X=!0,H.disabled=!0,Z(e).id=`add-session-agent-guidance`}l(`list-agents`,{},{timeoutMs:h}).then(e=>{let t=ee(e);t.canSpawn||Se(t.guidance);let n=T(e.type===`agents-listed`?e.agents:[]);if(Y=n.selectedId,n.show){S.textContent=``;for(let e of n.options)S.appendChild(A(e.label,{value:e.id,selected:e.id===n.selectedId}));p.hidden=!1}}).catch(e=>{Z(`Could not load the agent list (${_(e,h)}), so the session uses the default agent.`)}),S.addEventListener(`change`,()=>{Y=S.value,Q()});function Q(){if(!e.isConnected){Ce();return}let t=ae(Y),n=t?b(t):null;j.hidden=W===null||t===null||n===null||n.state===`signed-in`,se.textContent=t?M(n,t):``}ce.addEventListener(`click`,()=>{let e=ae(Y);e&&oe(e)});let Ce=C(Q);N();let we=!1,Te=!1;z.addEventListener(`change`,()=>{we=!0});function $(){let e=Te&&W===null;fe.hidden=e,!we&&(z.checked=e)}l(`get-settings`,{},{timeoutMs:h}).then(e=>{e.type===`settings-error`?(Z(`Could not load your settings (${e.message}). Check Sane YOLO mode yourself.`),$()):(Ee(re(e.settings)),Te=ne(e.settings),$())}).catch(e=>{Z(`Could not load your settings (${_(e,h)}). Check Sane YOLO mode yourself.`),$()});function Ee(e){if(e.length!==0){_e=e,O.textContent=``,O.appendChild(A(`Local`,{value:``,selected:!0}));for(let t of e)O.appendChild(A(t.name,{value:t.name}));w.hidden=!1}}O.addEventListener(`change`,()=>{W=_e.find(e=>e.name===O.value)??null,u.hidden=W!==null,k.hidden=W===null,k.textContent=W?ie(W):``,Q(),$(),W!==null&&U&&G(!1)}),L.addEventListener(`input`,()=>{n.selectedIndex=0}),R.addEventListener(`input`,()=>{n.selectedIndex=0});function De(){if(X)return;let e=L.value.trim(),t=R.value.trim();if(U){let t=[...i.querySelectorAll(`input:checked`)].map(e=>e.value);if(!e||t.length<2){V.textContent=`Enter a name and select at least two repositories.`;return}let n={name:v(e),path:t[0],repos:t,dangerouslySkipPermissions:z.checked,saneYolo:z.checked,unguarded:B.checked};Y&&Y!==`claude-code`&&(n.agent=Y),Oe(n);return}if(!e||!t){V.textContent=`Both fields are required. Select a project or use Advanced options.`;return}let n={name:v(e),path:t,dangerouslySkipPermissions:z.checked,saneYolo:z.checked,unguarded:B.checked};Y&&Y!==`claude-code`&&(n.agent=Y),W&&(n.environment=W.name),Oe(n)}function Oe(e){H.disabled=!0,V.textContent=``,l(`add-session`,e,{timeoutMs:h}).then(e=>{e.type===`add-session-result`&&e.ok?t():V.textContent=y(e)}).catch(e=>{V.textContent=`The session was not added: ${_(e,h)}`}).finally(()=>{H.disabled=X})}ge.addEventListener(`click`,t),H.addEventListener(`click`,De),L.addEventListener(`keydown`,e=>{e.key===`Enter`&&(U&&De(),U||R.focus())}),R.addEventListener(`keydown`,e=>{e.key===`Enter`&&De()}),requestAnimationFrame(()=>n.focus())}function P({issueId:e,issueTitle:t,format:n,content:r,message:i,error:a}){let{dialog:o,close:s,actions:l,btnCancel:d}=u({title:`Investigation report`,dialogClass:`dialog dialog-report`,cancelLabel:`Close`}),f=c(`div`,`dialog-report-meta`,t||e||``),p=null;n===`html`&&!a&&!i&&(p=O({source:{kind:`srcdoc`,html:r||``},className:`dialog-report-frame`,title:`Investigation report`,allowsScripts:!1})),p||=c(`pre`,a?`dialog-report-body dialog-report-error`:`dialog-report-body`,a||i||r||``),o.append(f,p,l),d.addEventListener(`click`,s),requestAnimationFrame(()=>d.focus())}function le({issueTitle:r,projectLabel:i,onOpenReport:o}){let{dialog:s,close:l,actions:d,btnCancel:f}=u({title:`Investigation`,dialogClass:`dialog dialog-report`,cancelLabel:`Close`}),m=c(`div`,`dialog-report-meta`,i?`${i}: ${r}`:r),h=c(`p`,`dialog-trail-status`),g=c(`p`,`dialog-trail-summary`),_=c(`ol`,`dialog-trail-steps`),v=c(`p`,`dialog-trail-empty`,`No tool calls yet; the session is reading the issue.`),y=c(`button`,`btn-dialog btn-dialog-cancel`,`Open report`);y.type=`button`,y.hidden=!0,y.addEventListener(`click`,()=>{l(),o()}),d.prepend(y),s.append(m,h,g,_,v,d),f.addEventListener(`click`,l),requestAnimationFrame(()=>f.focus());let b=null,x=``;function C(n){let r=_.scrollHeight-_.scrollTop-_.clientHeight<24,i=t(n);if(x!==i){_.textContent=``;for(let t of e(n.steps)){let e=c(`li`,`dialog-trail-step dialog-trail-${t.kind}`),r=t.kind===`note`?t.text:`${t.stepCount} ${t.stepCount===1?`step`:`steps`}`;e.append(c(`span`,`dialog-trail-at`,a(n.startedAt,t.at)),c(`span`,`dialog-trail-detail`,r)),_.append(e)}x=i}v.hidden=n.steps.length>0||!n.inFlight,_.hidden=n.steps.length===0,r&&(_.scrollTop=_.scrollHeight)}function w(e){h.textContent=n(e,S(e.startedAt))}function T(){b&&(w(b),h.dataset.tone=b.inFlight?`live`:`done`,g.textContent=b.summaryLine,g.hidden=!b.summaryLine,y.hidden=b.inFlight||!b.verdict,C(b))}let E=p(()=>{s.isConnected?b?.inFlight&&w(b):E()});return{update(e){b=e,T()},isOpen:()=>s.isConnected,close:()=>{E(),l()}}}export{b as agentLoginOf,M as agentLoginSummary,ce as createAddSessionDialog,le as createInvestigationDialog,P as createRadarReportDialog,C as onAgentLoginsChanged,oe as openAgentConnectDialog,se as openRemoteSetupDialog};
@@ -1 +1 @@
1
- import{o as e}from"./dom-helpers-C7P3_59O.js";import{d as t}from"./control-ws-D_jLoMnn.js";import{a as n,r,t as i}from"./modal-Bh-cVr-I.js";import{Fr as a,Qr as o,Rr as s,pn as c}from"./index-DkVH8Ze_.js";import{i as l,t as u}from"./plan-render-CzDoSIwQ.js";var d=null;function f(t){let n=o(t.sessionId);t.select.replaceChildren(...n.map(n=>{let r=e(`option`,null,n.name);return r.value=n.path,r.selected=n.path===t.docPath,r})),t.select.hidden=n.length<2,t.title.textContent=n.find(e=>e.path===t.docPath)?.name??t.title.textContent}function p(e){let t=o(e.sessionId).some(t=>t.path===e.docPath);e.btnEdit.setAttribute(`aria-pressed`,String(e.mode===`edit`)),e.btnPreview.setAttribute(`aria-pressed`,String(e.mode===`preview`)),e.textarea.hidden=e.mode!==`edit`,e.preview.hidden=e.mode!==`preview`,e.select.disabled=e.isBusy,e.btnReload.disabled=e.isBusy||!t,e.btnSave.disabled=e.isBusy||!t||e.baseHash===null||!e.hasUnsavedChanges}function m(e,t,n=`quiet`){e.status.textContent=t,e.status.dataset.tone=n}function h(e){e.preview.replaceChildren(u(l(e.textarea.value)))}function g(e,t){n({title:e,message:`Your unsaved edits will be lost.`,confirmLabel:`Discard`,danger:!0,onConfirm:t})}function _(e,t,n){e.hasUnsavedChanges?g(t,n):n()}async function v(e,n){try{return{reply:await t(e,n,{timeoutMs:a}),failureText:null}}catch(e){return{reply:null,failureText:s(e,a)}}}async function y(e,t){e.docPath=t,e.isBusy=!0,e.baseHash=null,e.textarea.readOnly=!0,f(e),m(e,`Loading`),p(e);let{reply:n,failureText:r}=await v(`session-doc-read`,{id:e.sessionId,path:t});if(d!==e||e.docPath!==t)return;e.isBusy=!1,e.textarea.readOnly=!1;let i=n?.type===`session-doc-response`?n:null;!i?.ok||i.text===void 0||i.hash===void 0?(m(e,i?.error||r||`Could not open this doc`,`warn`),p(e)):(e.textarea.value=i.text,e.baseHash=i.hash,e.hasUnsavedChanges=!1,e.mode===`preview`&&h(e),m(e,``),p(e))}async function b(e){if(e.btnSave.disabled||e.baseHash===null)return;e.isBusy=!0,m(e,`Saving`),p(e);let t=e.docPath,n=e.textarea.value,{reply:r,failureText:i}=await v(`session-doc-save`,{id:e.sessionId,path:t,text:n,baseHash:e.baseHash});if(d!==e||e.docPath!==t)return;e.isBusy=!1;let a=r?.type===`session-doc-save-result`?r:null;!a?.ok||a.hash===void 0?(m(e,a?.conflict?`The agent changed this file since you opened it. Reload to see its version.`:a?.error||i||`Save failed`,`warn`),p(e)):(e.baseHash=a.hash,e.hasUnsavedChanges=e.textarea.value!==n,m(e,e.hasUnsavedChanges?`Unsaved changes`:`Saved`),p(e))}function x(e,t){e.mode=t,t===`preview`&&h(e),p(e),t===`edit`&&e.textarea.focus()}function S(t,n){let r=e(`button`,`plan-control ${n}`,t);return r.type=`button`,r}function C(t){let n=o(t)[0];if(!n||d)return;let a=()=>_(M,`Close this doc?`,()=>M.close()),s=r({dialogClass:`doc-editor`,closeOnBackdrop:!1,onEscape:a}),l=`doc-editor-title-${t}`,u=e(`h3`,`doc-editor-title`,n.name);u.id=l;let f=e(`select`,`plan-control doc-editor-picker`);f.setAttribute(`aria-label`,`Doc`);let h=e(`span`,`doc-editor-status`);h.setAttribute(`role`,`status`);let g=S(`Edit`,`doc-editor-mode`),v=S(`Preview`,`doc-editor-mode`),C=S(`Reload`,`doc-editor-reload`),w=S(`Save`,`doc-editor-save`),T=S(`Close`,`doc-editor-close`),E=e(`div`,`doc-editor-modes`);E.append(g,v);let D=e(`div`,`doc-editor-actions`);D.append(h,C,w,T);let O=e(`div`,`doc-editor-header`);O.append(u,f,E,D);let k=e(`textarea`,`plan-editor doc-editor-text`);k.spellcheck=!0,k.setAttribute(`aria-labelledby`,l);let A=e(`div`,`doc-editor-preview`),j=e(`div`,`doc-editor-body`);j.append(k,A),s.dialog.append(O,j),i(s.dialog,l);let M={sessionId:t,docPath:n.path,baseHash:null,hasUnsavedChanges:!1,isBusy:!1,mode:c()?`preview`:`edit`,title:u,select:f,textarea:k,preview:A,status:h,btnEdit:g,btnPreview:v,btnReload:C,btnSave:w,close:()=>{d=null,s.close()}};d=M,k.addEventListener(`input`,()=>{M.hasUnsavedChanges||(M.hasUnsavedChanges=!0,m(M,`Unsaved changes`),p(M))}),k.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&(e.preventDefault(),b(M))}),f.addEventListener(`change`,()=>{let e=f.value;f.value=M.docPath,_(M,`Open another doc?`,()=>{y(M,e)})}),g.addEventListener(`click`,()=>x(M,`edit`)),v.addEventListener(`click`,()=>x(M,`preview`)),C.addEventListener(`click`,()=>{_(M,`Reload this doc?`,()=>{y(M,M.docPath)})}),w.addEventListener(`click`,()=>{b(M)}),T.addEventListener(`click`,a),y(M,n.path),M.mode===`edit`&&k.focus()}function w(e){d&&d.sessionId===e&&(f(d),p(d),!o(e).some(e=>e.path===d?.docPath)&&m(d,`This doc is no longer surfaced, so it cannot be saved.`,`warn`))}export{w as applyDocsToOpenEditor,C as openDocEditor};
1
+ import{o as e}from"./dom-helpers-C7P3_59O.js";import{d as t}from"./control-ws-DUGWJI0x.js";import{a as n,r,t as i}from"./modal-Bh-cVr-I.js";import{Fr as a,Qr as o,Rr as s,pn as c}from"./index-CClbz7ym.js";import{i as l,t as u}from"./plan-render-BK51mWj1.js";var d=null;function f(t){let n=o(t.sessionId);t.select.replaceChildren(...n.map(n=>{let r=e(`option`,null,n.name);return r.value=n.path,r.selected=n.path===t.docPath,r})),t.select.hidden=n.length<2,t.title.textContent=n.find(e=>e.path===t.docPath)?.name??t.title.textContent}function p(e){let t=o(e.sessionId).some(t=>t.path===e.docPath);e.btnEdit.setAttribute(`aria-pressed`,String(e.mode===`edit`)),e.btnPreview.setAttribute(`aria-pressed`,String(e.mode===`preview`)),e.textarea.hidden=e.mode!==`edit`,e.preview.hidden=e.mode!==`preview`,e.select.disabled=e.isBusy,e.btnReload.disabled=e.isBusy||!t,e.btnSave.disabled=e.isBusy||!t||e.baseHash===null||!e.hasUnsavedChanges}function m(e,t,n=`quiet`){e.status.textContent=t,e.status.dataset.tone=n}function h(e){e.preview.replaceChildren(u(l(e.textarea.value)))}function g(e,t){n({title:e,message:`Your unsaved edits will be lost.`,confirmLabel:`Discard`,danger:!0,onConfirm:t})}function _(e,t,n){e.hasUnsavedChanges?g(t,n):n()}async function v(e,n){try{return{reply:await t(e,n,{timeoutMs:a}),failureText:null}}catch(e){return{reply:null,failureText:s(e,a)}}}async function y(e,t){e.docPath=t,e.isBusy=!0,e.baseHash=null,e.textarea.readOnly=!0,f(e),m(e,`Loading`),p(e);let{reply:n,failureText:r}=await v(`session-doc-read`,{id:e.sessionId,path:t});if(d!==e||e.docPath!==t)return;e.isBusy=!1,e.textarea.readOnly=!1;let i=n?.type===`session-doc-response`?n:null;!i?.ok||i.text===void 0||i.hash===void 0?(m(e,i?.error||r||`Could not open this doc`,`warn`),p(e)):(e.textarea.value=i.text,e.baseHash=i.hash,e.hasUnsavedChanges=!1,e.mode===`preview`&&h(e),m(e,``),p(e))}async function b(e){if(e.btnSave.disabled||e.baseHash===null)return;e.isBusy=!0,m(e,`Saving`),p(e);let t=e.docPath,n=e.textarea.value,{reply:r,failureText:i}=await v(`session-doc-save`,{id:e.sessionId,path:t,text:n,baseHash:e.baseHash});if(d!==e||e.docPath!==t)return;e.isBusy=!1;let a=r?.type===`session-doc-save-result`?r:null;!a?.ok||a.hash===void 0?(m(e,a?.conflict?`The agent changed this file since you opened it. Reload to see its version.`:a?.error||i||`Save failed`,`warn`),p(e)):(e.baseHash=a.hash,e.hasUnsavedChanges=e.textarea.value!==n,m(e,e.hasUnsavedChanges?`Unsaved changes`:`Saved`),p(e))}function x(e,t){e.mode=t,t===`preview`&&h(e),p(e),t===`edit`&&e.textarea.focus()}function S(t,n){let r=e(`button`,`plan-control ${n}`,t);return r.type=`button`,r}function C(t){let n=o(t)[0];if(!n||d)return;let a=()=>_(M,`Close this doc?`,()=>M.close()),s=r({dialogClass:`doc-editor`,closeOnBackdrop:!1,onEscape:a}),l=`doc-editor-title-${t}`,u=e(`h3`,`doc-editor-title`,n.name);u.id=l;let f=e(`select`,`plan-control doc-editor-picker`);f.setAttribute(`aria-label`,`Doc`);let h=e(`span`,`doc-editor-status`);h.setAttribute(`role`,`status`);let g=S(`Edit`,`doc-editor-mode`),v=S(`Preview`,`doc-editor-mode`),C=S(`Reload`,`doc-editor-reload`),w=S(`Save`,`doc-editor-save`),T=S(`Close`,`doc-editor-close`),E=e(`div`,`doc-editor-modes`);E.append(g,v);let D=e(`div`,`doc-editor-actions`);D.append(h,C,w,T);let O=e(`div`,`doc-editor-header`);O.append(u,f,E,D);let k=e(`textarea`,`plan-editor doc-editor-text`);k.spellcheck=!0,k.setAttribute(`aria-labelledby`,l);let A=e(`div`,`doc-editor-preview`),j=e(`div`,`doc-editor-body`);j.append(k,A),s.dialog.append(O,j),i(s.dialog,l);let M={sessionId:t,docPath:n.path,baseHash:null,hasUnsavedChanges:!1,isBusy:!1,mode:c()?`preview`:`edit`,title:u,select:f,textarea:k,preview:A,status:h,btnEdit:g,btnPreview:v,btnReload:C,btnSave:w,close:()=>{d=null,s.close()}};d=M,k.addEventListener(`input`,()=>{M.hasUnsavedChanges||(M.hasUnsavedChanges=!0,m(M,`Unsaved changes`),p(M))}),k.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&(e.preventDefault(),b(M))}),f.addEventListener(`change`,()=>{let e=f.value;f.value=M.docPath,_(M,`Open another doc?`,()=>{y(M,e)})}),g.addEventListener(`click`,()=>x(M,`edit`)),v.addEventListener(`click`,()=>x(M,`preview`)),C.addEventListener(`click`,()=>{_(M,`Reload this doc?`,()=>{y(M,M.docPath)})}),w.addEventListener(`click`,()=>{b(M)}),T.addEventListener(`click`,a),y(M,n.path),M.mode===`edit`&&k.focus()}function w(e){d&&d.sessionId===e&&(f(d),p(d),!o(e).some(e=>e.path===d?.docPath)&&m(d,`This doc is no longer surfaced, so it cannot be saved.`,`warn`))}export{w as applyDocsToOpenEditor,C as openDocEditor};
@@ -1 +1 @@
1
- import{o as e,y as t}from"./dom-helpers-C7P3_59O.js";import{d as n,u as r}from"./control-ws-D_jLoMnn.js";import{Fr as i,Ir as a,Rr as o,bn as s,or as c,ur as l}from"./index-DkVH8Ze_.js";import{a as u,c as d,i as f,n as p,o as m,r as h,s as g,t as _}from"./repo-roots-adder-CAMr-ApU.js";var v=`npm install -g @anthropic-ai/claude-code`,y={done:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Done"><circle cx="12" cy="12" r="10"></circle><path d="M7.5 12.5l3 3 6-6.5"></path></svg>`,current:`<svg width="18" height="18" viewBox="0 0 24 24" role="img" aria-label="Needed"><path d="M12 3l9 9-9 9-9-9z" fill="currentColor"></path></svg>`,upcoming:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-label="Not started"><circle cx="12" cy="12" r="10"></circle></svg>`},b=null,x=null,S=null,C=null,w={steps:h,agentSummary:``,repoRoots:[]},T=0,E=!1,D=!1,O=new Set,k=a(`first-run-load-status`),A=s();function j(e){r({type:`dashboard-telemetry`,event:`operator_action`,properties:{surface:`onboarding`,action:e}})}function M(e){for(let t of m(O,e))r({type:`dashboard-telemetry`,event:`onboarding_step`,properties:t})&&O.add(g(t))}function N({title:t,state:n,summary:r,badge:i,body:a}){let o=e(`li`,`first-run-step`);o.dataset.state=n,n===`current`&&o.setAttribute(`aria-current`,`step`);let s=e(`div`,`first-run-step-head`),c=e(`span`,`first-run-step-icon`);if(c.innerHTML=y[n],s.append(c,e(`span`,`first-run-step-title`,t)),n===`done`&&r&&s.append(e(`span`,`first-run-step-summary`,r)),n===`current`&&i&&s.append(e(`span`,`first-run-step-badge`,i)),o.append(s),n!==`current`)return o;let l=e(`div`,`first-run-step-body`);return l.append(...a()),o.append(l),o}function P(){return c()?`No supported agent is on PATH of the machine running Glimmervoid. Install Claude Code, Codex or Grok there, then rescan.`:`No supported agent is on PATH. Install Claude Code, Codex or Grok, then rescan.`}function F(){let n=e(`div`,`first-run-command-row`);if(n.append(e(`code`,`first-run-command`,v)),!navigator.clipboard?.writeText)return n;let r=e(`button`,`btn-dialog btn-dialog-cancel`,`Copy`);r.type=`button`;let i=e(`span`,`first-run-copy-status`);return i.setAttribute(`role`,`status`),r.addEventListener(`click`,async()=>{let e=t(v);i.textContent=e?await e.then(()=>`Copied`,()=>`Copy failed`):`Copy failed`}),n.append(r,i),n}function I(){let t=e(`div`,`first-run-step-actions`);S=e(`button`,`btn-dialog btn-dialog-cancel`,`Rescan`),S.type=`button`,S.addEventListener(`click`,()=>{j(`rescan`),B({rescanAgents:!0})}),t.append(S);let n=[e(`p`,`first-run-step-text`,P()),F(),t];return E?[...n,e(`p`,`first-run-step-hint`,`Still missing after a rescan? Restart Glimmervoid from a terminal where the command runs. Other terminal agents go under customAgents.`)]:n}function L(){let t=C??_({onAdded:e=>{j(e===`typed`?`add-root-typed`:`add-root-suggested`),B({rescanAgents:!1})}});return C=t,[e(`p`,`first-run-step-text`,`The folder that holds your git checkouts. Each subfolder becomes a project you can start a session in.`),t.element]}function R(){let t=e(`div`,`first-run-step-actions`),n=e(`button`,`btn-dialog btn-dialog-confirm`,`+ Session`);return n.type=`button`,n.addEventListener(`click`,()=>{j(`add-session`),l()}),t.append(n),[e(`p`,`first-run-step-text`,`Pick a project and an agent. The session runs in its own git worktree, so your checkout is never touched.`),t]}function z(){if(!x)return;let{steps:e,agentSummary:t,repoRoots:n}=w;x.replaceChildren(N({title:`1. Agent CLI`,state:e.agent,summary:t,badge:`MISSING`,body:I}),N({title:`2. Repository roots`,state:e.repoRoots,summary:n.join(`, `),badge:`NEEDED`,body:L}),N({title:`3. First session`,state:e.firstSession,summary:``,badge:``,body:R}))}async function B({rescanAgents:e}){T+=1;let t=T;S&&(S.disabled=!0);try{let[r,a]=await Promise.all([n(`list-agents`,e?{rescan:!0}:{},{timeoutMs:i}),n(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:i})]);if(t!==T)return;let o=a.type===`repo-roots-scanned`,s=o?a.directories.map(e=>e.root):[],c=o?a.suggestions??[]:[],l=d(s,c);if(l.length>0&&!D){D=!0;let e=await p(l).catch(e=>String(e));if(t!==T)return;if(!e){B({rescanAgents:!1});return}}let m=u({agentListing:r,repoRoots:s});e&&(E=m.agent===`current`),w={steps:m,agentSummary:f(r),repoRoots:s},k.clear(),z(),M(w.steps),C?.setSuggestions(c)}catch(e){if(S&&(S.disabled=!1),t!==T)return;k.show(`error`,`The checklist could not load: ${o(e,i)} It loads again once the server answers. If it stays like this, check the terminal running Glimmervoid, or run glimmervoid doctor.`)}}function V(){if(b)return b;let t=e(`section`,`first-run-checklist`);t.setAttribute(`aria-labelledby`,`first-run-title`);let n=e(`h2`,`first-run-title`,`Get to your first session`);n.id=`first-run-title`,x=e(`ol`,`first-run-steps`);let r=e(`div`,`first-run-optional`);return r.append(e(`span`,`first-run-eyebrow`,`OPTIONAL`),A.element),t.append(e(`span`,`first-run-eyebrow`,`FIRST RUN`),n,x,k.element,r),b=t,z(),t}function H(e,t){if(!t){b?.parentElement===e&&!b.hidden&&(b.hidden=!0);return}let n=V(),r=!n.hidden&&n.parentElement===e;n.parentElement!==e&&e.append(n),n.hidden=!1,A.refresh(),r||B({rescanAgents:!1})}function U(){b&&!b.hidden&&b.isConnected&&B({rescanAgents:!1})}export{U as refreshFirstRunChecklist,H as showFirstRunChecklist};
1
+ import{o as e,y as t}from"./dom-helpers-C7P3_59O.js";import{d as n,u as r}from"./control-ws-DUGWJI0x.js";import{Fr as i,Ir as a,Rr as o,bn as s,or as c,ur as l}from"./index-CClbz7ym.js";import{a as u,c as d,i as f,n as p,o as m,r as h,s as g,t as _}from"./repo-roots-adder-B4qgw7oP.js";var v=`npm install -g @anthropic-ai/claude-code`,y={done:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Done"><circle cx="12" cy="12" r="10"></circle><path d="M7.5 12.5l3 3 6-6.5"></path></svg>`,current:`<svg width="18" height="18" viewBox="0 0 24 24" role="img" aria-label="Needed"><path d="M12 3l9 9-9 9-9-9z" fill="currentColor"></path></svg>`,upcoming:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-label="Not started"><circle cx="12" cy="12" r="10"></circle></svg>`},b=null,x=null,S=null,C=null,w={steps:h,agentSummary:``,repoRoots:[]},T=0,E=!1,D=!1,O=new Set,k=a(`first-run-load-status`),A=s();function j(e){r({type:`dashboard-telemetry`,event:`operator_action`,properties:{surface:`onboarding`,action:e}})}function M(e){for(let t of m(O,e))r({type:`dashboard-telemetry`,event:`onboarding_step`,properties:t})&&O.add(g(t))}function N({title:t,state:n,summary:r,badge:i,body:a}){let o=e(`li`,`first-run-step`);o.dataset.state=n,n===`current`&&o.setAttribute(`aria-current`,`step`);let s=e(`div`,`first-run-step-head`),c=e(`span`,`first-run-step-icon`);if(c.innerHTML=y[n],s.append(c,e(`span`,`first-run-step-title`,t)),n===`done`&&r&&s.append(e(`span`,`first-run-step-summary`,r)),n===`current`&&i&&s.append(e(`span`,`first-run-step-badge`,i)),o.append(s),n!==`current`)return o;let l=e(`div`,`first-run-step-body`);return l.append(...a()),o.append(l),o}function P(){return c()?`No supported agent is on PATH of the machine running Glimmervoid. Install Claude Code, Codex or Grok there, then rescan.`:`No supported agent is on PATH. Install Claude Code, Codex or Grok, then rescan.`}function F(){let n=e(`div`,`first-run-command-row`);if(n.append(e(`code`,`first-run-command`,v)),!navigator.clipboard?.writeText)return n;let r=e(`button`,`btn-dialog btn-dialog-cancel`,`Copy`);r.type=`button`;let i=e(`span`,`first-run-copy-status`);return i.setAttribute(`role`,`status`),r.addEventListener(`click`,async()=>{let e=t(v);i.textContent=e?await e.then(()=>`Copied`,()=>`Copy failed`):`Copy failed`}),n.append(r,i),n}function I(){let t=e(`div`,`first-run-step-actions`);S=e(`button`,`btn-dialog btn-dialog-cancel`,`Rescan`),S.type=`button`,S.addEventListener(`click`,()=>{j(`rescan`),B({rescanAgents:!0})}),t.append(S);let n=[e(`p`,`first-run-step-text`,P()),F(),t];return E?[...n,e(`p`,`first-run-step-hint`,`Still missing after a rescan? Restart Glimmervoid from a terminal where the command runs. Other terminal agents go under customAgents.`)]:n}function L(){let t=C??_({onAdded:e=>{j(e===`typed`?`add-root-typed`:`add-root-suggested`),B({rescanAgents:!1})}});return C=t,[e(`p`,`first-run-step-text`,`The folder that holds your git checkouts. Each subfolder becomes a project you can start a session in.`),t.element]}function R(){let t=e(`div`,`first-run-step-actions`),n=e(`button`,`btn-dialog btn-dialog-confirm`,`+ Session`);return n.type=`button`,n.addEventListener(`click`,()=>{j(`add-session`),l()}),t.append(n),[e(`p`,`first-run-step-text`,`Pick a project and an agent. The session runs in its own git worktree, so your checkout is never touched.`),t]}function z(){if(!x)return;let{steps:e,agentSummary:t,repoRoots:n}=w;x.replaceChildren(N({title:`1. Agent CLI`,state:e.agent,summary:t,badge:`MISSING`,body:I}),N({title:`2. Repository roots`,state:e.repoRoots,summary:n.join(`, `),badge:`NEEDED`,body:L}),N({title:`3. First session`,state:e.firstSession,summary:``,badge:``,body:R}))}async function B({rescanAgents:e}){T+=1;let t=T;S&&(S.disabled=!0);try{let[r,a]=await Promise.all([n(`list-agents`,e?{rescan:!0}:{},{timeoutMs:i}),n(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:i})]);if(t!==T)return;let o=a.type===`repo-roots-scanned`,s=o?a.directories.map(e=>e.root):[],c=o?a.suggestions??[]:[],l=d(s,c);if(l.length>0&&!D){D=!0;let e=await p(l).catch(e=>String(e));if(t!==T)return;if(!e){B({rescanAgents:!1});return}}let m=u({agentListing:r,repoRoots:s});e&&(E=m.agent===`current`),w={steps:m,agentSummary:f(r),repoRoots:s},k.clear(),z(),M(w.steps),C?.setSuggestions(c)}catch(e){if(S&&(S.disabled=!1),t!==T)return;k.show(`error`,`The checklist could not load: ${o(e,i)} It loads again once the server answers. If it stays like this, check the terminal running Glimmervoid, or run glimmervoid doctor.`)}}function V(){if(b)return b;let t=e(`section`,`first-run-checklist`);t.setAttribute(`aria-labelledby`,`first-run-title`);let n=e(`h2`,`first-run-title`,`Get to your first session`);n.id=`first-run-title`,x=e(`ol`,`first-run-steps`);let r=e(`div`,`first-run-optional`);return r.append(e(`span`,`first-run-eyebrow`,`OPTIONAL`),A.element),t.append(e(`span`,`first-run-eyebrow`,`FIRST RUN`),n,x,k.element,r),b=t,z(),t}function H(e,t){if(!t){b?.parentElement===e&&!b.hidden&&(b.hidden=!0);return}let n=V(),r=!n.hidden&&n.parentElement===e;n.parentElement!==e&&e.append(n),n.hidden=!1,A.refresh(),r||B({rescanAgents:!1})}function U(){b&&!b.hidden&&b.isConnected&&B({rescanAgents:!1})}export{U as refreshFirstRunChecklist,H as showFirstRunChecklist};
@@ -1 +1 @@
1
- import{_ as e,a as t,f as n,l as r,m as i,n as a,r as o,u as s}from"./zod-BRLv4KqJ.js";import{n as c}from"./updates-view-core-B_e7uWeW.js";import{n as l,o as u,p as d,r as f,u as p}from"./dom-helpers-C7P3_59O.js";import{d as m}from"./control-ws-D_jLoMnn.js";import{a as h}from"./modal-Bh-cVr-I.js";import{Fr as g,Gt as _,Ir as ee,Rr as v,Ut as y,Wt as b}from"./index-DkVH8Ze_.js";var te=n(i(),e());s({glimmervoidId:i().min(1),event:i().min(1),token:i().nullable().optional(),payload:te}),s({id:i().min(1),name:i().min(1),event:i().min(1),matcher:i().optional(),type:a([`command`,`http`]),command:i().optional(),url:i().optional(),timeout:r().int().positive().optional(),enabled:t(),projects:o(i()).optional()}).passthrough();var ne=`Claude Code hooks injected into every session Glimmervoid spawns.`,re=`Loading hooks`,ie=`No hooks yet. A hook runs a command, or calls a URL, when a Claude Code event fires in a Glimmervoid session. Start from one of these, or add your own.`,ae=`Start from`,oe=`Filter by name, event or command`,se=`Nothing matches that filter.`,ce=`Preview`,le=`The entry this becomes in the per-session settings file.`,ue=`Duplicate`,de=`Discard changes`,fe=`Close the editor and lose the unsaved changes?`,pe=`Esc cancels. Ctrl+Enter saves.`,me=4,he=`A change reaches a session at its next start or restart. Claude Code sessions only; Codex and Grok sessions do not read this file.`,ge=`Glimmervoid's own hooks`,_e=`Always present, read-only. Status detection depends on them.`,ve=`Your hooks`,ye=`New hook`,be=`Edit hook`,xe=`Saved to config.json.`,x=`All projects`,Se=`This event takes no matcher.`,Ce=`Blank uses Claude Code's default for the event.`,we=Object.freeze([{value:`command`,label:`Command`,hint:`Run a shell command. It receives the event JSON on stdin.`},{value:`http`,label:`HTTP`,hint:`POST the event JSON to a URL.`}]),Te=Object.freeze([{id:`lint`,label:`Lint after edits`,summary:`PostToolUse on Edit|Write`,draft:{name:`Lint after edits`,event:`PostToolUse`,matcher:`Edit|Write`,type:`command`,command:`npx biome check --write "$(jq -r .tool_input.file_path)"`}},{id:`notify`,label:`Notify on Stop`,summary:`Stop, command`,draft:{name:`Notify on Stop`,event:`Stop`,matcher:``,type:`command`,command:`command -v notify-send >/dev/null 2>&1 && notify-send "Claude finished a turn" || { command -v osascript >/dev/null 2>&1 && osascript -e 'display notification "Claude finished a turn" with title "Claude Code"'; }`}},{id:`guard`,label:`Guard destructive Bash`,summary:`PreToolUse on Bash, exit 2 blocks`,draft:{name:`Guard destructive Bash`,event:`PreToolUse`,matcher:`Bash`,type:`command`,command:`jq -r .tool_input.command | grep -Eq "rm -rf|git push --force" && exit 2 || exit 0`}},{id:`log`,label:`Log every prompt`,summary:`UserPromptSubmit, appends JSON`,draft:{name:`Log every prompt`,event:`UserPromptSubmit`,matcher:``,type:`command`,command:`cat >> ~/.claude/prompts.jsonl`}}]),Ee=Object.freeze({hooks:[],builtin:[],events:[]});function De(e){return!e||typeof e.error==`string`}function Oe(e){return!e||typeof e.error!=`string`?``:e.error}function S(e,t){let n=e?.[t];return Array.isArray(n)?n:Ee[t]}var C=e=>S(e,`hooks`),w=e=>S(e,`builtin`),T=e=>S(e,`events`);function E(e){let t=e?.limits?.maxTimeoutSec;return typeof t==`number`&&Number.isInteger(t)&&t>0?t:600}function ke(e){let t=C(e),n=t.filter(e=>e.enabled!==!1).length;return[{label:`yours`,value:String(t.length),tone:null},{label:`enabled`,value:String(n),tone:t.length>0&&n===0?`warn`:null},{label:`built in`,value:String(w(e).length),tone:null}]}function Ae(e,t){let n=new Map(t.map((e,t)=>[e.name,t])),r=e=>n.get(e.event)??t.length;return[...e].sort((e,t)=>{let n=r(e)-r(t);return n===0?String(e.name).localeCompare(String(t.name)):n})}function je(e,t){let n=String(t||``).trim().toLowerCase();return n?e.filter(e=>[e.name,e.event,e.matcher,e.command,e.url].some(e=>typeof e==`string`&&e.toLowerCase().includes(n))):e}function Me(e){return e.length>=me}function Ne(e){let t=[];for(let n of e){let e=t[t.length-1];e&&e.event===n.event?e.hooks.push(n):t.push({event:n.event,hooks:[n]})}return t}function Pe(e){let t=e.type===`http`?{type:`http`,url:e.url||``}:{type:`command`,command:e.command||``};Number.isInteger(e.timeout)&&Number(e.timeout)>0&&(t.timeout=e.timeout);let n=e.matcher?{matcher:e.matcher,hooks:[t]}:{hooks:[t]};return JSON.stringify({hooks:{[e.event]:[n]}},null,2)}function Fe(e){return`${e} copy`}function D(e,t){return e.find(e=>e.name===t)||null}function O(e,t){let n=D(e,t);return n?n.matcher?`Matches ${n.matcher}. Blank matches every ${n.name}.`:Se:``}function Ie(e){return e.type===`http`?e.url||``:e.command||``}function Le(e){let t=we.find(t=>t.value===e);return t?t.label:String(e||``)}function Re(e){return!Number.isInteger(e.timeout)||Number(e.timeout)<=0?``:`${e.timeout}s timeout`}function ze(e,t){let n=Array.isArray(e.projects)?e.projects:[];return n.length===0?x:n.map(e=>{let n=t.find(t=>t.id===e);return n?n.name:e}).join(`, `)}function Be(e){return e.matcher?`${e.event} / ${e.matcher}`:e.event}function Ve(e){return Be(e)}function He(e,t){let n=Array.isArray(e.projects)?e.projects:[],r=new Set(t.map(e=>e.id));return n.filter(e=>!r.has(e))}function k(e){let t=e[0];return{id:null,name:``,event:t?t.name:``,matcher:``,type:`command`,command:``,url:``,timeout:``,enabled:!0,projects:[]}}function A(e){return{id:e.id??null,name:e.name||``,event:e.event||``,matcher:e.matcher||``,type:e.type===`http`?`http`:`command`,command:e.command||``,url:e.url||``,timeout:Number.isInteger(e.timeout)?String(e.timeout):``,enabled:e.enabled!==!1,projects:Array.isArray(e.projects)?[...e.projects]:[]}}function Ue(e,t,n=600){if(!e.name.trim())return`Give the hook a name.`;let r=D(t,e.event);if(!r)return`Pick an event.`;if(e.matcher.trim()&&!r.matcher)return`${r.name} takes no matcher.`;if(e.type===`http`&&r.http===!1)return`${r.name} does not support HTTP hooks.`;if(e.type===`command`&&!e.command.trim())return`Enter the command to run.`;if(e.type===`http`&&!/^https?:\/\/\S+$/i.test(e.url.trim()))return`Enter a URL starting with http:// or https://.`;if(e.timeout.trim()!==``){let t=Number(e.timeout);if(!Number.isInteger(t)||t<1||t>n)return`Timeout must be a whole number of seconds from 1 to ${n}.`}return null}function j(e){let t={name:e.name.trim(),event:e.event,type:e.type,enabled:e.enabled!==!1};return e.id&&(t.id=e.id),e.matcher.trim()&&(t.matcher=e.matcher.trim()),e.type===`command`&&(t.command=e.command.trim()),e.type===`http`&&(t.url=e.url.trim()),e.timeout.trim()!==``&&(t.timeout=Number(e.timeout)),e.projects.length>0&&(t.projects=[...e.projects]),t}function We(e,t){let n={...k(t),...e.draft};return D(t,n.event)||(n.event=k(t).event),n}function Ge(e,t){return JSON.stringify(j(e))!==JSON.stringify(t)}function Ke(e){return{...e,enabled:e.enabled===!1}}function qe(e){return`Delete the hook "${e.name}"? Sessions already running keep it until they restart.`}var M=y(),N=null,P=null,F=null,I=null,L=null,R=null,z=!1,B=``,V=new Set,H=new Set,U=new Map,W=!1,G=(e,t)=>l(`hooks`,e,t);function K(e,t,n){let r=u(`p`,e,t);return n&&(r.dataset.tone=n),r}function q(e,t,n,r){let i=u(`button`,e,t);return i.type=`button`,r&&i.setAttribute(`aria-label`,r),i.addEventListener(`click`,n),i}async function Je(e,t){try{let n=await m(e,t,{timeoutMs:g});if((n.type===`save-hook-result`||n.type===`delete-hook-result`)&&n.ok)return null;let r=e===`save-hook`?`Could not save the hook.`:`Could not delete the hook.`;return`error`in n&&typeof n.error==`string`&&n.error?n.error:r}catch(e){return v(e,g)}}async function Ye(e,t,n,r){H.add(e),U.set(e,{tone:`busy`,text:r}),$({force:!0});let i=await Je(t,n);H.delete(e),i&&U.set(e,{tone:`error`,text:i}),i||U.delete(e),$({force:!0}),b()}function J(e,t,n){let r=u(`label`,`hooks-field`);return r.append(u(`span`,`hooks-field-label`,e),t),n&&r.append(u(`span`,`hooks-field-hint`,n)),r}function Y(e,t,n){let r=u(`input`,`settings-view-input`);return r.type=`text`,r.value=e,r.autocomplete=`off`,r.spellcheck=!1,t&&(r.placeholder=t),r.addEventListener(`input`,()=>n(r.value)),r}function Xe(e,t){let n=u(`textarea`,`settings-view-input hooks-command`);return n.rows=3,n.value=e,n.spellcheck=!1,n.addEventListener(`input`,()=>t(n.value)),n}function Ze(e,t,n){let r=u(`select`,`settings-view-input hooks-select`);for(let n of t){let t=u(`option`,null,n.name);t.value=n.name,t.title=n.description,n.name===e.event&&(t.selected=!0),r.append(t)}return r.addEventListener(`change`,()=>n(r.value)),r}function Qe(e,t){let n=u(`div`,`hooks-type-row`);n.setAttribute(`role`,`radiogroup`);for(let r of we){let i=u(`label`,`settings-view-toggle hooks-choice`),a=u(`input`,`settings-view-checkbox`);a.type=`radio`,a.name=`hooks-type`,a.value=r.value,a.checked=e.type===r.value,a.title=r.hint,a.addEventListener(`change`,()=>{a.checked&&t(r.value)}),i.append(a,u(`span`,null,r.label)),n.append(i)}return n}function $e(e,t){let n=u(`div`,`hooks-projects`);if(t.length===0)return n.append(u(`span`,`hooks-field-hint`,x)),n;let r=u(`label`,`settings-view-project-choice hooks-choice`),i=u(`input`,`settings-view-checkbox`);i.type=`checkbox`,i.checked=e.projects.length===0,r.append(i,u(`span`,null,x)),n.append(r);let a=[];for(let r of t){let t=u(`label`,`settings-view-project-choice hooks-choice`),o=u(`input`,`settings-view-checkbox`);o.type=`checkbox`,o.value=r.id,o.checked=e.projects.includes(r.id),o.addEventListener(`change`,()=>{e.projects=a.filter(e=>e.checked).map(e=>e.value),i.checked=e.projects.length===0}),a.push(o),t.append(o,u(`span`,null,r.name)),r.agent!==`claude-code`&&(t.append(u(`span`,`hooks-choice-note`,r.agent)),t.title=`Not a Claude Code project: this hook will not reach its sessions.`),n.append(t)}return i.addEventListener(`change`,()=>{if(!i.checked)i.checked=e.projects.length===0;else{for(let e of a)e.checked=!1;e.projects=[]}}),n}function et(e){let t=u(`div`,`hooks-templates`);t.append(u(`span`,`hooks-templates-label`,ae));for(let n of Te){let r=q(`hooks-chip`,n.label,()=>Z(null,We(n,e)));r.title=n.summary,t.append(r)}return t}function X(e){L&&(e?L.show(`error`,e):L.clear())}function tt(e){let t=T(M.report),n=d(M.report),r=G(e.id?be:ye,xe);r.classList.add(`hooks-editor`);let i=u(`form`,`hooks-form`);i.addEventListener(`submit`,e=>{e.preventDefault(),rt()}),i.addEventListener(`keydown`,e=>{e.key===`Escape`?(e.preventDefault(),nt()):e.key===`Enter`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),rt())}),e.id||i.append(et(t));let a=u(`span`,`hooks-field-hint`,O(t,e.event)),o=Y(e.matcher,``,t=>{e.matcher=t}),s=J(`Command`,Xe(e.command,t=>{e.command=t}),`Runs through the shell with the event JSON on stdin. Exit 2 blocks the action where the event allows it.`),c=J(`URL`,Y(e.url,`http://127.0.0.1:8080/hook`,t=>{e.url=t}),`Claude Code POSTs the event JSON to it.`),l=()=>{s.hidden=e.type!==`command`,c.hidden=e.type!==`http`};l();let f=J(`Matcher`,o,null);f.append(a);let p=()=>{let n=t.find(t=>t.name===e.event);a.textContent=O(t,e.event),o.disabled=!!n&&!n.matcher,o.disabled&&(o.value=``,e.matcher=``)};p();let m=u(`input`,`settings-view-input hooks-timeout`);m.type=`number`,m.inputMode=`numeric`,m.min=`1`,m.max=String(E(M.report)),m.value=e.timeout,m.addEventListener(`input`,()=>{e.timeout=m.value});let h=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled,g.addEventListener(`change`,()=>{e.enabled=g.checked}),h.append(g,u(`span`,null,`Enabled`)),i.append(J(`Name`,Y(e.name,`Lint after edits`,t=>{e.name=t}),null),J(`Event`,Ze(e,t,t=>{e.event=t,p()}),null),f,J(`Type`,Qe(e,t=>{e.type=t,l()}),null),s,c,J(`Timeout (seconds)`,m,Ce),J(`Projects`,$e(e,n),null),J(``,h,null)),L=ee(`hooks-editor-status`);let _=u(`div`,`hooks-editor-footer`),v=u(`span`,`hooks-editor-shortcut`,pe),y=q(`btn-dialog btn-dialog-cancel`,`Cancel`,nt),b=u(`button`,`btn-dialog btn-dialog-confirm`,e.id?`Save changes`:`Add hook`);return b.type=`submit`,R=b,_.append(L.element,v,y,b),i.append(_),r.append(i),r}function Z(e,t=null){P=t||(e?A(e):k(T(M.report))),F=j(e?A(e):k(T(M.report))),I=tt(P),$({force:!0}),I.scrollIntoView({block:`nearest`});let n=I.querySelector(`input[type=text]`);n instanceof HTMLInputElement&&n.focus()}function Q(){P=null,F=null,I=null,L=null,R=null,z=!1,W=!0,$({force:!0})}function nt(){!P||!F||!Ge(P,F)?Q():h({title:de,message:fe,confirmLabel:`Discard`,danger:!0,onConfirm:Q})}async function rt(){if(!P||z)return;let e=Ue(P,T(M.report),E(M.report));if(e){X(e);return}let t=L,n=R;z=!0,t?.show(`busy`,`Saving the hook.`),n&&(n.disabled=!0);let r=await Je(`save-hook`,{hook:j(P)});z=!1,n&&(n.disabled=!1),t===L&&(r?X(r):(Q(),b()))}function it(e){let t=u(`details`,`hooks-preview`);t.open=V.has(e.id),t.addEventListener(`toggle`,()=>{t.open?V.add(e.id):V.delete(e.id)});let n=u(`summary`,`hooks-preview-summary`,ce);n.title=le;let r=u(`pre`,`hooks-preview-code`,Pe(e));return t.append(n,r),t}function at(e,{grouped:t=!1}={}){let n=d(M.report),r=u(`article`,`hooks-row`);r.setAttribute(`aria-label`,e.name),e.enabled===!1&&(r.dataset.state=`off`);let i=u(`div`,`hooks-row-main`),a=u(`div`,`hooks-row-head`);a.append(u(`span`,`hooks-row-name`,e.name));let o=t?e.matcher||``:Be(e);o&&a.append(u(`span`,`hooks-row-event`,o));let s=u(`code`,`hooks-row-target`,Ie(e));s.title=Ie(e);let c=u(`p`,`hooks-row-meta`,[Le(e.type),Re(e),ze(e,n)].filter(Boolean).join(` / `));i.append(a,s,c);let l=He(e,n);l.length>0&&i.append(K(`hooks-row-meta`,`Scoped to a project no longer in config: ${l.join(`, `)}`,`warn`)),i.append(it(e));let f=U.get(e.id);if(f){let e=ee(`hooks-row-status`);e.show(f.tone,f.text),i.append(e.element)}let p=u(`div`,`hooks-row-actions`),m=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled!==!1,g.disabled=H.has(e.id),g.setAttribute(`aria-label`,`${e.name} enabled`),g.addEventListener(`change`,()=>{Ye(e.id,`save-hook`,{hook:Ke(e)},g.checked?`Turning the hook on.`:`Turning the hook off.`)}),m.append(g,u(`span`,null,`On`));let _=q(`hooks-btn`,`Edit`,()=>Z(e),`Edit ${e.name}`),v=q(`hooks-btn`,ue,()=>{let t=A({...e,name:Fe(e.name)});t.id=null,Z(null,t)},`Duplicate ${e.name}`),y=q(`hooks-btn hooks-btn-danger`,`Delete`,()=>{h({title:`Delete hook`,message:qe(e),confirmLabel:`Delete`,danger:!0,onConfirm:()=>{Ye(e.id,`delete-hook`,{id:e.id},`Deleting the hook.`)}})},`Delete ${e.name}`);return y.disabled=H.has(e.id),p.append(m,_,v,y),r.append(i,p),r}function ot(e){let t=u(`article`,`hooks-row hooks-row-builtin`),n=u(`div`,`hooks-row-main`);return n.append(u(`span`,`hooks-row-event`,Ve(e)),u(`p`,`hooks-row-meta`,e.purpose)),t.append(n),t}function st(){let e=G(`Hooks`,ne),t=u(`div`,`hooks-stats`);for(let e of ke(M.report))t.append(f(`hooks`,e.label,e.value,e.tone));return e.append(t,K(`hooks-meta`,he)),e}function ct(){let e=u(`input`,`settings-view-input hooks-filter`);return e.type=`search`,e.value=B,e.placeholder=oe,e.setAttribute(`aria-label`,oe),e.addEventListener(`input`,()=>{B=e.value;let t=N?.querySelector(`.hooks-list-yours`);t&&t.replaceWith(ut())}),e}function lt(){let e=u(`div`,`hooks-empty-state`);return e.append(K(`hooks-empty`,ie),et(T(M.report))),e}function ut(){let e=u(`div`,`hooks-list-yours`),t=C(M.report);if(t.length===0)return e.append(lt()),e;let n=je(Ae(t,T(M.report)),B);if(n.length===0)return e.append(K(`hooks-empty`,se)),e;for(let t of Ne(n)){let n=u(`div`,`hooks-group`);n.append(u(`h3`,`hooks-group-title`,t.event));let r=u(`div`,`hooks-list`);for(let e of t.hooks)r.append(at(e,{grouped:!0}));n.append(r),e.append(n)}return e}function dt(){let e=G(ve,null),t=q(`hooks-btn hooks-btn-add`,`+ New hook`,()=>Z(null));t.disabled=!!P;let n=e.querySelector(`.hooks-section-head`);return n&&n.append(t),Me(C(M.report))&&e.append(ct()),e.append(ut()),e}function ft(){let e=u(`details`,`hooks-builtin`),t=u(`summary`,`hooks-builtin-summary`);t.append(u(`span`,`hooks-section-title`,`${ge} (${w(M.report).length})`),u(`span`,`hooks-section-hint`,_e));let n=u(`div`,`hooks-list`);for(let e of w(M.report))n.append(ot(e));return e.append(t,n),e}function pt(){let e=u(`div`,`hooks-content`);return M.report?De(M.report)?(e.append(K(`hooks-warning`,Oe(M.report))),e):(e.append(st()),I&&e.append(I),e.append(dt(),ft()),e):(e.append(M.hasReportSendFailed?K(`hooks-warning`,c):K(`hooks-empty`,re)),e)}function $({force:e=!1}={}){if(!N||!e&&p(N)||(M=y(),N.replaceChildren(pt()),!W))return;W=!1;let t=N.querySelector(`.hooks-btn-add`);t instanceof HTMLButtonElement&&t.focus()}function mt(e){N||(N=u(`div`,`hooks-panel`),e.append(N),_(()=>$()),$({force:!0}))}function ht(e){e===`shown`&&$({force:!0}),b()}var gt={mount:mt,refresh:ht};export{gt as view};
1
+ import{_ as e,a as t,f as n,l as r,m as i,n as a,r as o,u as s}from"./zod-BRLv4KqJ.js";import{n as c}from"./updates-view-core-BYoMfzXj.js";import{n as l,o as u,p as d,r as f,u as p}from"./dom-helpers-C7P3_59O.js";import{d as m}from"./control-ws-DUGWJI0x.js";import{a as h}from"./modal-Bh-cVr-I.js";import{Fr as g,Gt as _,Ir as ee,Rr as v,Ut as y,Wt as b}from"./index-CClbz7ym.js";var te=n(i(),e());s({glimmervoidId:i().min(1),event:i().min(1),token:i().nullable().optional(),payload:te}),s({id:i().min(1),name:i().min(1),event:i().min(1),matcher:i().optional(),type:a([`command`,`http`]),command:i().optional(),url:i().optional(),timeout:r().int().positive().optional(),enabled:t(),projects:o(i()).optional()}).passthrough();var ne=`Claude Code hooks injected into every session Glimmervoid spawns.`,re=`Loading hooks`,ie=`No hooks yet. A hook runs a command, or calls a URL, when a Claude Code event fires in a Glimmervoid session. Start from one of these, or add your own.`,ae=`Start from`,oe=`Filter by name, event or command`,se=`Nothing matches that filter.`,ce=`Preview`,le=`The entry this becomes in the per-session settings file.`,ue=`Duplicate`,de=`Discard changes`,fe=`Close the editor and lose the unsaved changes?`,pe=`Esc cancels. Ctrl+Enter saves.`,me=4,he=`A change reaches a session at its next start or restart. Claude Code sessions only; Codex and Grok sessions do not read this file.`,ge=`Glimmervoid's own hooks`,_e=`Always present, read-only. Status detection depends on them.`,ve=`Your hooks`,ye=`New hook`,be=`Edit hook`,xe=`Saved to config.json.`,x=`All projects`,Se=`This event takes no matcher.`,Ce=`Blank uses Claude Code's default for the event.`,we=Object.freeze([{value:`command`,label:`Command`,hint:`Run a shell command. It receives the event JSON on stdin.`},{value:`http`,label:`HTTP`,hint:`POST the event JSON to a URL.`}]),Te=Object.freeze([{id:`lint`,label:`Lint after edits`,summary:`PostToolUse on Edit|Write`,draft:{name:`Lint after edits`,event:`PostToolUse`,matcher:`Edit|Write`,type:`command`,command:`npx biome check --write "$(jq -r .tool_input.file_path)"`}},{id:`notify`,label:`Notify on Stop`,summary:`Stop, command`,draft:{name:`Notify on Stop`,event:`Stop`,matcher:``,type:`command`,command:`command -v notify-send >/dev/null 2>&1 && notify-send "Claude finished a turn" || { command -v osascript >/dev/null 2>&1 && osascript -e 'display notification "Claude finished a turn" with title "Claude Code"'; }`}},{id:`guard`,label:`Guard destructive Bash`,summary:`PreToolUse on Bash, exit 2 blocks`,draft:{name:`Guard destructive Bash`,event:`PreToolUse`,matcher:`Bash`,type:`command`,command:`jq -r .tool_input.command | grep -Eq "rm -rf|git push --force" && exit 2 || exit 0`}},{id:`log`,label:`Log every prompt`,summary:`UserPromptSubmit, appends JSON`,draft:{name:`Log every prompt`,event:`UserPromptSubmit`,matcher:``,type:`command`,command:`cat >> ~/.claude/prompts.jsonl`}}]),Ee=Object.freeze({hooks:[],builtin:[],events:[]});function De(e){return!e||typeof e.error==`string`}function Oe(e){return!e||typeof e.error!=`string`?``:e.error}function S(e,t){let n=e?.[t];return Array.isArray(n)?n:Ee[t]}var C=e=>S(e,`hooks`),w=e=>S(e,`builtin`),T=e=>S(e,`events`);function E(e){let t=e?.limits?.maxTimeoutSec;return typeof t==`number`&&Number.isInteger(t)&&t>0?t:600}function ke(e){let t=C(e),n=t.filter(e=>e.enabled!==!1).length;return[{label:`yours`,value:String(t.length),tone:null},{label:`enabled`,value:String(n),tone:t.length>0&&n===0?`warn`:null},{label:`built in`,value:String(w(e).length),tone:null}]}function Ae(e,t){let n=new Map(t.map((e,t)=>[e.name,t])),r=e=>n.get(e.event)??t.length;return[...e].sort((e,t)=>{let n=r(e)-r(t);return n===0?String(e.name).localeCompare(String(t.name)):n})}function je(e,t){let n=String(t||``).trim().toLowerCase();return n?e.filter(e=>[e.name,e.event,e.matcher,e.command,e.url].some(e=>typeof e==`string`&&e.toLowerCase().includes(n))):e}function Me(e){return e.length>=me}function Ne(e){let t=[];for(let n of e){let e=t[t.length-1];e&&e.event===n.event?e.hooks.push(n):t.push({event:n.event,hooks:[n]})}return t}function Pe(e){let t=e.type===`http`?{type:`http`,url:e.url||``}:{type:`command`,command:e.command||``};Number.isInteger(e.timeout)&&Number(e.timeout)>0&&(t.timeout=e.timeout);let n=e.matcher?{matcher:e.matcher,hooks:[t]}:{hooks:[t]};return JSON.stringify({hooks:{[e.event]:[n]}},null,2)}function Fe(e){return`${e} copy`}function D(e,t){return e.find(e=>e.name===t)||null}function O(e,t){let n=D(e,t);return n?n.matcher?`Matches ${n.matcher}. Blank matches every ${n.name}.`:Se:``}function Ie(e){return e.type===`http`?e.url||``:e.command||``}function Le(e){let t=we.find(t=>t.value===e);return t?t.label:String(e||``)}function Re(e){return!Number.isInteger(e.timeout)||Number(e.timeout)<=0?``:`${e.timeout}s timeout`}function ze(e,t){let n=Array.isArray(e.projects)?e.projects:[];return n.length===0?x:n.map(e=>{let n=t.find(t=>t.id===e);return n?n.name:e}).join(`, `)}function Be(e){return e.matcher?`${e.event} / ${e.matcher}`:e.event}function Ve(e){return Be(e)}function He(e,t){let n=Array.isArray(e.projects)?e.projects:[],r=new Set(t.map(e=>e.id));return n.filter(e=>!r.has(e))}function k(e){let t=e[0];return{id:null,name:``,event:t?t.name:``,matcher:``,type:`command`,command:``,url:``,timeout:``,enabled:!0,projects:[]}}function A(e){return{id:e.id??null,name:e.name||``,event:e.event||``,matcher:e.matcher||``,type:e.type===`http`?`http`:`command`,command:e.command||``,url:e.url||``,timeout:Number.isInteger(e.timeout)?String(e.timeout):``,enabled:e.enabled!==!1,projects:Array.isArray(e.projects)?[...e.projects]:[]}}function Ue(e,t,n=600){if(!e.name.trim())return`Give the hook a name.`;let r=D(t,e.event);if(!r)return`Pick an event.`;if(e.matcher.trim()&&!r.matcher)return`${r.name} takes no matcher.`;if(e.type===`http`&&r.http===!1)return`${r.name} does not support HTTP hooks.`;if(e.type===`command`&&!e.command.trim())return`Enter the command to run.`;if(e.type===`http`&&!/^https?:\/\/\S+$/i.test(e.url.trim()))return`Enter a URL starting with http:// or https://.`;if(e.timeout.trim()!==``){let t=Number(e.timeout);if(!Number.isInteger(t)||t<1||t>n)return`Timeout must be a whole number of seconds from 1 to ${n}.`}return null}function j(e){let t={name:e.name.trim(),event:e.event,type:e.type,enabled:e.enabled!==!1};return e.id&&(t.id=e.id),e.matcher.trim()&&(t.matcher=e.matcher.trim()),e.type===`command`&&(t.command=e.command.trim()),e.type===`http`&&(t.url=e.url.trim()),e.timeout.trim()!==``&&(t.timeout=Number(e.timeout)),e.projects.length>0&&(t.projects=[...e.projects]),t}function We(e,t){let n={...k(t),...e.draft};return D(t,n.event)||(n.event=k(t).event),n}function Ge(e,t){return JSON.stringify(j(e))!==JSON.stringify(t)}function Ke(e){return{...e,enabled:e.enabled===!1}}function qe(e){return`Delete the hook "${e.name}"? Sessions already running keep it until they restart.`}var M=y(),N=null,P=null,F=null,I=null,L=null,R=null,z=!1,B=``,V=new Set,H=new Set,U=new Map,W=!1,G=(e,t)=>l(`hooks`,e,t);function K(e,t,n){let r=u(`p`,e,t);return n&&(r.dataset.tone=n),r}function q(e,t,n,r){let i=u(`button`,e,t);return i.type=`button`,r&&i.setAttribute(`aria-label`,r),i.addEventListener(`click`,n),i}async function Je(e,t){try{let n=await m(e,t,{timeoutMs:g});if((n.type===`save-hook-result`||n.type===`delete-hook-result`)&&n.ok)return null;let r=e===`save-hook`?`Could not save the hook.`:`Could not delete the hook.`;return`error`in n&&typeof n.error==`string`&&n.error?n.error:r}catch(e){return v(e,g)}}async function Ye(e,t,n,r){H.add(e),U.set(e,{tone:`busy`,text:r}),$({force:!0});let i=await Je(t,n);H.delete(e),i&&U.set(e,{tone:`error`,text:i}),i||U.delete(e),$({force:!0}),b()}function J(e,t,n){let r=u(`label`,`hooks-field`);return r.append(u(`span`,`hooks-field-label`,e),t),n&&r.append(u(`span`,`hooks-field-hint`,n)),r}function Y(e,t,n){let r=u(`input`,`settings-view-input`);return r.type=`text`,r.value=e,r.autocomplete=`off`,r.spellcheck=!1,t&&(r.placeholder=t),r.addEventListener(`input`,()=>n(r.value)),r}function Xe(e,t){let n=u(`textarea`,`settings-view-input hooks-command`);return n.rows=3,n.value=e,n.spellcheck=!1,n.addEventListener(`input`,()=>t(n.value)),n}function Ze(e,t,n){let r=u(`select`,`settings-view-input hooks-select`);for(let n of t){let t=u(`option`,null,n.name);t.value=n.name,t.title=n.description,n.name===e.event&&(t.selected=!0),r.append(t)}return r.addEventListener(`change`,()=>n(r.value)),r}function Qe(e,t){let n=u(`div`,`hooks-type-row`);n.setAttribute(`role`,`radiogroup`);for(let r of we){let i=u(`label`,`settings-view-toggle hooks-choice`),a=u(`input`,`settings-view-checkbox`);a.type=`radio`,a.name=`hooks-type`,a.value=r.value,a.checked=e.type===r.value,a.title=r.hint,a.addEventListener(`change`,()=>{a.checked&&t(r.value)}),i.append(a,u(`span`,null,r.label)),n.append(i)}return n}function $e(e,t){let n=u(`div`,`hooks-projects`);if(t.length===0)return n.append(u(`span`,`hooks-field-hint`,x)),n;let r=u(`label`,`settings-view-project-choice hooks-choice`),i=u(`input`,`settings-view-checkbox`);i.type=`checkbox`,i.checked=e.projects.length===0,r.append(i,u(`span`,null,x)),n.append(r);let a=[];for(let r of t){let t=u(`label`,`settings-view-project-choice hooks-choice`),o=u(`input`,`settings-view-checkbox`);o.type=`checkbox`,o.value=r.id,o.checked=e.projects.includes(r.id),o.addEventListener(`change`,()=>{e.projects=a.filter(e=>e.checked).map(e=>e.value),i.checked=e.projects.length===0}),a.push(o),t.append(o,u(`span`,null,r.name)),r.agent!==`claude-code`&&(t.append(u(`span`,`hooks-choice-note`,r.agent)),t.title=`Not a Claude Code project: this hook will not reach its sessions.`),n.append(t)}return i.addEventListener(`change`,()=>{if(!i.checked)i.checked=e.projects.length===0;else{for(let e of a)e.checked=!1;e.projects=[]}}),n}function et(e){let t=u(`div`,`hooks-templates`);t.append(u(`span`,`hooks-templates-label`,ae));for(let n of Te){let r=q(`hooks-chip`,n.label,()=>Z(null,We(n,e)));r.title=n.summary,t.append(r)}return t}function X(e){L&&(e?L.show(`error`,e):L.clear())}function tt(e){let t=T(M.report),n=d(M.report),r=G(e.id?be:ye,xe);r.classList.add(`hooks-editor`);let i=u(`form`,`hooks-form`);i.addEventListener(`submit`,e=>{e.preventDefault(),rt()}),i.addEventListener(`keydown`,e=>{e.key===`Escape`?(e.preventDefault(),nt()):e.key===`Enter`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),rt())}),e.id||i.append(et(t));let a=u(`span`,`hooks-field-hint`,O(t,e.event)),o=Y(e.matcher,``,t=>{e.matcher=t}),s=J(`Command`,Xe(e.command,t=>{e.command=t}),`Runs through the shell with the event JSON on stdin. Exit 2 blocks the action where the event allows it.`),c=J(`URL`,Y(e.url,`http://127.0.0.1:8080/hook`,t=>{e.url=t}),`Claude Code POSTs the event JSON to it.`),l=()=>{s.hidden=e.type!==`command`,c.hidden=e.type!==`http`};l();let f=J(`Matcher`,o,null);f.append(a);let p=()=>{let n=t.find(t=>t.name===e.event);a.textContent=O(t,e.event),o.disabled=!!n&&!n.matcher,o.disabled&&(o.value=``,e.matcher=``)};p();let m=u(`input`,`settings-view-input hooks-timeout`);m.type=`number`,m.inputMode=`numeric`,m.min=`1`,m.max=String(E(M.report)),m.value=e.timeout,m.addEventListener(`input`,()=>{e.timeout=m.value});let h=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled,g.addEventListener(`change`,()=>{e.enabled=g.checked}),h.append(g,u(`span`,null,`Enabled`)),i.append(J(`Name`,Y(e.name,`Lint after edits`,t=>{e.name=t}),null),J(`Event`,Ze(e,t,t=>{e.event=t,p()}),null),f,J(`Type`,Qe(e,t=>{e.type=t,l()}),null),s,c,J(`Timeout (seconds)`,m,Ce),J(`Projects`,$e(e,n),null),J(``,h,null)),L=ee(`hooks-editor-status`);let _=u(`div`,`hooks-editor-footer`),v=u(`span`,`hooks-editor-shortcut`,pe),y=q(`btn-dialog btn-dialog-cancel`,`Cancel`,nt),b=u(`button`,`btn-dialog btn-dialog-confirm`,e.id?`Save changes`:`Add hook`);return b.type=`submit`,R=b,_.append(L.element,v,y,b),i.append(_),r.append(i),r}function Z(e,t=null){P=t||(e?A(e):k(T(M.report))),F=j(e?A(e):k(T(M.report))),I=tt(P),$({force:!0}),I.scrollIntoView({block:`nearest`});let n=I.querySelector(`input[type=text]`);n instanceof HTMLInputElement&&n.focus()}function Q(){P=null,F=null,I=null,L=null,R=null,z=!1,W=!0,$({force:!0})}function nt(){!P||!F||!Ge(P,F)?Q():h({title:de,message:fe,confirmLabel:`Discard`,danger:!0,onConfirm:Q})}async function rt(){if(!P||z)return;let e=Ue(P,T(M.report),E(M.report));if(e){X(e);return}let t=L,n=R;z=!0,t?.show(`busy`,`Saving the hook.`),n&&(n.disabled=!0);let r=await Je(`save-hook`,{hook:j(P)});z=!1,n&&(n.disabled=!1),t===L&&(r?X(r):(Q(),b()))}function it(e){let t=u(`details`,`hooks-preview`);t.open=V.has(e.id),t.addEventListener(`toggle`,()=>{t.open?V.add(e.id):V.delete(e.id)});let n=u(`summary`,`hooks-preview-summary`,ce);n.title=le;let r=u(`pre`,`hooks-preview-code`,Pe(e));return t.append(n,r),t}function at(e,{grouped:t=!1}={}){let n=d(M.report),r=u(`article`,`hooks-row`);r.setAttribute(`aria-label`,e.name),e.enabled===!1&&(r.dataset.state=`off`);let i=u(`div`,`hooks-row-main`),a=u(`div`,`hooks-row-head`);a.append(u(`span`,`hooks-row-name`,e.name));let o=t?e.matcher||``:Be(e);o&&a.append(u(`span`,`hooks-row-event`,o));let s=u(`code`,`hooks-row-target`,Ie(e));s.title=Ie(e);let c=u(`p`,`hooks-row-meta`,[Le(e.type),Re(e),ze(e,n)].filter(Boolean).join(` / `));i.append(a,s,c);let l=He(e,n);l.length>0&&i.append(K(`hooks-row-meta`,`Scoped to a project no longer in config: ${l.join(`, `)}`,`warn`)),i.append(it(e));let f=U.get(e.id);if(f){let e=ee(`hooks-row-status`);e.show(f.tone,f.text),i.append(e.element)}let p=u(`div`,`hooks-row-actions`),m=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled!==!1,g.disabled=H.has(e.id),g.setAttribute(`aria-label`,`${e.name} enabled`),g.addEventListener(`change`,()=>{Ye(e.id,`save-hook`,{hook:Ke(e)},g.checked?`Turning the hook on.`:`Turning the hook off.`)}),m.append(g,u(`span`,null,`On`));let _=q(`hooks-btn`,`Edit`,()=>Z(e),`Edit ${e.name}`),v=q(`hooks-btn`,ue,()=>{let t=A({...e,name:Fe(e.name)});t.id=null,Z(null,t)},`Duplicate ${e.name}`),y=q(`hooks-btn hooks-btn-danger`,`Delete`,()=>{h({title:`Delete hook`,message:qe(e),confirmLabel:`Delete`,danger:!0,onConfirm:()=>{Ye(e.id,`delete-hook`,{id:e.id},`Deleting the hook.`)}})},`Delete ${e.name}`);return y.disabled=H.has(e.id),p.append(m,_,v,y),r.append(i,p),r}function ot(e){let t=u(`article`,`hooks-row hooks-row-builtin`),n=u(`div`,`hooks-row-main`);return n.append(u(`span`,`hooks-row-event`,Ve(e)),u(`p`,`hooks-row-meta`,e.purpose)),t.append(n),t}function st(){let e=G(`Hooks`,ne),t=u(`div`,`hooks-stats`);for(let e of ke(M.report))t.append(f(`hooks`,e.label,e.value,e.tone));return e.append(t,K(`hooks-meta`,he)),e}function ct(){let e=u(`input`,`settings-view-input hooks-filter`);return e.type=`search`,e.value=B,e.placeholder=oe,e.setAttribute(`aria-label`,oe),e.addEventListener(`input`,()=>{B=e.value;let t=N?.querySelector(`.hooks-list-yours`);t&&t.replaceWith(ut())}),e}function lt(){let e=u(`div`,`hooks-empty-state`);return e.append(K(`hooks-empty`,ie),et(T(M.report))),e}function ut(){let e=u(`div`,`hooks-list-yours`),t=C(M.report);if(t.length===0)return e.append(lt()),e;let n=je(Ae(t,T(M.report)),B);if(n.length===0)return e.append(K(`hooks-empty`,se)),e;for(let t of Ne(n)){let n=u(`div`,`hooks-group`);n.append(u(`h3`,`hooks-group-title`,t.event));let r=u(`div`,`hooks-list`);for(let e of t.hooks)r.append(at(e,{grouped:!0}));n.append(r),e.append(n)}return e}function dt(){let e=G(ve,null),t=q(`hooks-btn hooks-btn-add`,`+ New hook`,()=>Z(null));t.disabled=!!P;let n=e.querySelector(`.hooks-section-head`);return n&&n.append(t),Me(C(M.report))&&e.append(ct()),e.append(ut()),e}function ft(){let e=u(`details`,`hooks-builtin`),t=u(`summary`,`hooks-builtin-summary`);t.append(u(`span`,`hooks-section-title`,`${ge} (${w(M.report).length})`),u(`span`,`hooks-section-hint`,_e));let n=u(`div`,`hooks-list`);for(let e of w(M.report))n.append(ot(e));return e.append(t,n),e}function pt(){let e=u(`div`,`hooks-content`);return M.report?De(M.report)?(e.append(K(`hooks-warning`,Oe(M.report))),e):(e.append(st()),I&&e.append(I),e.append(dt(),ft()),e):(e.append(M.hasReportSendFailed?K(`hooks-warning`,c):K(`hooks-empty`,re)),e)}function $({force:e=!1}={}){if(!N||!e&&p(N)||(M=y(),N.replaceChildren(pt()),!W))return;W=!1;let t=N.querySelector(`.hooks-btn-add`);t instanceof HTMLButtonElement&&t.focus()}function mt(e){N||(N=u(`div`,`hooks-panel`),e.append(N),_(()=>$()),$({force:!0}))}function ht(e){e===`shown`&&$({force:!0}),b()}var gt={mount:mt,refresh:ht};export{gt as view};